int_storage.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500
  1. // $Id: int_storage.c,v 1.1.1.1 2004/09/10 17:26:51 MagicalTux Exp $
  2. #include "inter.h"
  3. #include "int_storage.h"
  4. #include "int_pet.h"
  5. #include "int_guild.h"
  6. #include "mmo.h"
  7. #include "char.h"
  8. #include "socket.h"
  9. #include "db.h"
  10. #include "lock.h"
  11. #include <string.h>
  12. #include <stdlib.h>
  13. // ファイル名のデフォルト
  14. // inter_config_read()で再設定される
  15. char storage_txt[1024]="save/storage.txt";
  16. char guild_storage_txt[1024]="save/g_storage.txt";
  17. static struct dbt *storage_db;
  18. static struct dbt *guild_storage_db;
  19. // 倉庫データを文字列に変換
  20. int storage_tostr(char *str,struct storage *p)
  21. {
  22. int i,f=0;
  23. char *str_p = str;
  24. str_p += sprintf(str_p,"%d,%d\t",p->account_id,p->storage_amount);
  25. for(i=0;i<MAX_STORAGE;i++)
  26. if( (p->storage[i].nameid) && (p->storage[i].amount) ){
  27. str_p += sprintf(str_p,"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d ",
  28. p->storage[i].id,p->storage[i].nameid,p->storage[i].amount,p->storage[i].equip,
  29. p->storage[i].identify,p->storage[i].refine,p->storage[i].attribute,
  30. p->storage[i].card[0],p->storage[i].card[1],p->storage[i].card[2],p->storage[i].card[3]);
  31. f++;
  32. }
  33. *(str_p++)='\t';
  34. *str_p='\0';
  35. if(!f)
  36. str[0]=0;
  37. return 0;
  38. }
  39. // 文字列を倉庫データに変換
  40. int storage_fromstr(char *str,struct storage *p)
  41. {
  42. int tmp_int[256];
  43. int set,next,len,i;
  44. set=sscanf(str,"%d,%d%n",&tmp_int[0],&tmp_int[1],&next);
  45. p->storage_amount=tmp_int[1];
  46. if(set!=2)
  47. return 1;
  48. if(str[next]=='\n' || str[next]=='\r')
  49. return 0;
  50. next++;
  51. for(i=0;str[next] && str[next]!='\t';i++){
  52. if(sscanf(str + next, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d%n",
  53. &tmp_int[0], &tmp_int[1], &tmp_int[2], &tmp_int[3],
  54. &tmp_int[4], &tmp_int[5], &tmp_int[6],
  55. &tmp_int[7], &tmp_int[8], &tmp_int[9], &tmp_int[10], &tmp_int[10], &len) == 12) {
  56. p->storage[i].id = tmp_int[0];
  57. p->storage[i].nameid = tmp_int[1];
  58. p->storage[i].amount = tmp_int[2];
  59. p->storage[i].equip = tmp_int[3];
  60. p->storage[i].identify = tmp_int[4];
  61. p->storage[i].refine = tmp_int[5];
  62. p->storage[i].attribute = tmp_int[6];
  63. p->storage[i].card[0] = tmp_int[7];
  64. p->storage[i].card[1] = tmp_int[8];
  65. p->storage[i].card[2] = tmp_int[9];
  66. p->storage[i].card[3] = tmp_int[10];
  67. next += len;
  68. if (str[next] == ' ')
  69. next++;
  70. }
  71. else if(sscanf(str + next, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d%n",
  72. &tmp_int[0], &tmp_int[1], &tmp_int[2], &tmp_int[3],
  73. &tmp_int[4], &tmp_int[5], &tmp_int[6],
  74. &tmp_int[7], &tmp_int[8], &tmp_int[9], &tmp_int[10], &len) == 11) {
  75. p->storage[i].id = tmp_int[0];
  76. p->storage[i].nameid = tmp_int[1];
  77. p->storage[i].amount = tmp_int[2];
  78. p->storage[i].equip = tmp_int[3];
  79. p->storage[i].identify = tmp_int[4];
  80. p->storage[i].refine = tmp_int[5];
  81. p->storage[i].attribute = tmp_int[6];
  82. p->storage[i].card[0] = tmp_int[7];
  83. p->storage[i].card[1] = tmp_int[8];
  84. p->storage[i].card[2] = tmp_int[9];
  85. p->storage[i].card[3] = tmp_int[10];
  86. next += len;
  87. if (str[next] == ' ')
  88. next++;
  89. }
  90. else return 1;
  91. }
  92. return 0;
  93. }
  94. int guild_storage_tostr(char *str,struct guild_storage *p)
  95. {
  96. int i,f=0;
  97. char *str_p = str;
  98. str_p+=sprintf(str,"%d,%d\t",p->guild_id,p->storage_amount);
  99. for(i=0;i<MAX_GUILD_STORAGE;i++)
  100. if( (p->storage[i].nameid) && (p->storage[i].amount) ){
  101. str_p += sprintf(str_p,"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d ",
  102. p->storage[i].id,p->storage[i].nameid,p->storage[i].amount,p->storage[i].equip,
  103. p->storage[i].identify,p->storage[i].refine,p->storage[i].attribute,
  104. p->storage[i].card[0],p->storage[i].card[1],p->storage[i].card[2],p->storage[i].card[3]);
  105. f++;
  106. }
  107. *(str_p++)='\t';
  108. *str_p='\0';
  109. if(!f)
  110. str[0]=0;
  111. return 0;
  112. }
  113. int guild_storage_fromstr(char *str,struct guild_storage *p)
  114. {
  115. int tmp_int[256];
  116. int set,next,len,i;
  117. set=sscanf(str,"%d,%d%n",&tmp_int[0],&tmp_int[1],&next);
  118. p->storage_amount=tmp_int[1];
  119. if(set!=2)
  120. return 1;
  121. if(str[next]=='\n' || str[next]=='\r')
  122. return 0;
  123. next++;
  124. for(i=0;str[next] && str[next]!='\t';i++){
  125. if(sscanf(str + next, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d%n",
  126. &tmp_int[0], &tmp_int[1], &tmp_int[2], &tmp_int[3],
  127. &tmp_int[4], &tmp_int[5], &tmp_int[6],
  128. &tmp_int[7], &tmp_int[8], &tmp_int[9], &tmp_int[10], &tmp_int[10], &len) == 12) {
  129. p->storage[i].id = tmp_int[0];
  130. p->storage[i].nameid = tmp_int[1];
  131. p->storage[i].amount = tmp_int[2];
  132. p->storage[i].equip = tmp_int[3];
  133. p->storage[i].identify = tmp_int[4];
  134. p->storage[i].refine = tmp_int[5];
  135. p->storage[i].attribute = tmp_int[6];
  136. p->storage[i].card[0] = tmp_int[7];
  137. p->storage[i].card[1] = tmp_int[8];
  138. p->storage[i].card[2] = tmp_int[9];
  139. p->storage[i].card[3] = tmp_int[10];
  140. next += len;
  141. if (str[next] == ' ')
  142. next++;
  143. }
  144. else if(sscanf(str + next, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d%n",
  145. &tmp_int[0], &tmp_int[1], &tmp_int[2], &tmp_int[3],
  146. &tmp_int[4], &tmp_int[5], &tmp_int[6],
  147. &tmp_int[7], &tmp_int[8], &tmp_int[9], &tmp_int[10], &len) == 11) {
  148. p->storage[i].id = tmp_int[0];
  149. p->storage[i].nameid = tmp_int[1];
  150. p->storage[i].amount = tmp_int[2];
  151. p->storage[i].equip = tmp_int[3];
  152. p->storage[i].identify = tmp_int[4];
  153. p->storage[i].refine = tmp_int[5];
  154. p->storage[i].attribute = tmp_int[6];
  155. p->storage[i].card[0] = tmp_int[7];
  156. p->storage[i].card[1] = tmp_int[8];
  157. p->storage[i].card[2] = tmp_int[9];
  158. p->storage[i].card[3] = tmp_int[10];
  159. next += len;
  160. if (str[next] == ' ')
  161. next++;
  162. }
  163. else return 1;
  164. }
  165. return 0;
  166. }
  167. // アカウントから倉庫データインデックスを得る(新規倉庫追加可能)
  168. struct storage *account2storage(int account_id)
  169. {
  170. struct storage *s;
  171. s=numdb_search(storage_db,account_id);
  172. if(s == NULL) {
  173. s = aCalloc(sizeof(struct storage), 1);
  174. if(s==NULL){
  175. printf("int_storage: out of memory!\n");
  176. exit(0);
  177. }
  178. memset(s,0,sizeof(struct storage));
  179. s->account_id=account_id;
  180. numdb_insert(storage_db,s->account_id,s);
  181. }
  182. return s;
  183. }
  184. struct guild_storage *guild2storage(int guild_id)
  185. {
  186. struct guild_storage *gs = NULL;
  187. if(inter_guild_search(guild_id) != NULL) {
  188. gs=numdb_search(guild_storage_db,guild_id);
  189. if(gs == NULL) {
  190. gs = aCalloc(sizeof(struct guild_storage), 1);
  191. if(gs==NULL){
  192. printf("int_storage: out of memory!\n");
  193. exit(0);
  194. }
  195. memset(gs,0,sizeof(struct guild_storage));
  196. gs->guild_id=guild_id;
  197. numdb_insert(guild_storage_db,gs->guild_id,gs);
  198. }
  199. }
  200. return gs;
  201. }
  202. //---------------------------------------------------------
  203. // 倉庫データを読み込む
  204. int inter_storage_init()
  205. {
  206. char line[65536];
  207. int c=0,tmp_int;
  208. struct storage *s;
  209. struct guild_storage *gs;
  210. FILE *fp;
  211. storage_db = numdb_init();
  212. fp=fopen(storage_txt,"r");
  213. if(fp==NULL){
  214. printf("cant't read : %s\n",storage_txt);
  215. return 1;
  216. }
  217. while(fgets(line,65535,fp)){
  218. sscanf(line,"%d",&tmp_int);
  219. s = (struct storage*)aCalloc(sizeof(struct storage), 1);
  220. if(s==NULL){
  221. printf("int_storage: out of memory!\n");
  222. exit(0);
  223. }
  224. memset(s,0,sizeof(struct storage));
  225. s->account_id=tmp_int;
  226. if(s->account_id > 0 && storage_fromstr(line,s) == 0) {
  227. numdb_insert(storage_db,s->account_id,s);
  228. }
  229. else{
  230. printf("int_storage: broken data [%s] line %d\n",storage_txt,c);
  231. aFree(s);
  232. }
  233. c++;
  234. }
  235. fclose(fp);
  236. c = 0;
  237. guild_storage_db = numdb_init();
  238. fp=fopen(guild_storage_txt,"r");
  239. if(fp==NULL){
  240. printf("cant't read : %s\n",guild_storage_txt);
  241. return 1;
  242. }
  243. while(fgets(line,65535,fp)){
  244. sscanf(line,"%d",&tmp_int);
  245. gs = (struct guild_storage*)aCalloc(sizeof(struct guild_storage), 1);
  246. if(gs==NULL){
  247. printf("int_storage: out of memory!\n");
  248. exit(0);
  249. }
  250. memset(gs,0,sizeof(struct guild_storage));
  251. gs->guild_id=tmp_int;
  252. if(gs->guild_id > 0 && guild_storage_fromstr(line,gs) == 0) {
  253. numdb_insert(guild_storage_db,gs->guild_id,gs);
  254. }
  255. else{
  256. printf("int_storage: broken data [%s] line %d\n",guild_storage_txt,c);
  257. aFree(gs);
  258. }
  259. c++;
  260. }
  261. fclose(fp);
  262. return 0;
  263. }
  264. int inter_storage_save_sub(void *key,void *data,va_list ap)
  265. {
  266. char line[65536];
  267. FILE *fp;
  268. storage_tostr(line,(struct storage *)data);
  269. fp=va_arg(ap,FILE *);
  270. if(*line)
  271. fprintf(fp,"%s" RETCODE,line);
  272. return 0;
  273. }
  274. //---------------------------------------------------------
  275. // 倉庫データを書き込む
  276. int inter_storage_save()
  277. {
  278. FILE *fp;
  279. int lock;
  280. if( (fp=lock_fopen(storage_txt,&lock))==NULL ){
  281. printf("int_storage: cant write [%s] !!! data is lost !!!\n",storage_txt);
  282. return 1;
  283. }
  284. numdb_foreach(storage_db,inter_storage_save_sub,fp);
  285. lock_fclose(fp,storage_txt,&lock);
  286. // printf("int_storage: %s saved.\n",storage_txt);
  287. return 0;
  288. }
  289. int inter_guild_storage_save_sub(void *key,void *data,va_list ap)
  290. {
  291. char line[65536];
  292. FILE *fp;
  293. if(inter_guild_search(((struct guild_storage *)data)->guild_id) != NULL) {
  294. guild_storage_tostr(line,(struct guild_storage *)data);
  295. fp=va_arg(ap,FILE *);
  296. if(*line)
  297. fprintf(fp,"%s" RETCODE,line);
  298. }
  299. return 0;
  300. }
  301. //---------------------------------------------------------
  302. // 倉庫データを書き込む
  303. int inter_guild_storage_save()
  304. {
  305. FILE *fp;
  306. int lock;
  307. if( (fp=lock_fopen(guild_storage_txt,&lock))==NULL ){
  308. printf("int_storage: cant write [%s] !!! data is lost !!!\n",guild_storage_txt);
  309. return 1;
  310. }
  311. numdb_foreach(guild_storage_db,inter_guild_storage_save_sub,fp);
  312. lock_fclose(fp,guild_storage_txt,&lock);
  313. // printf("int_storage: %s saved.\n",guild_storage_txt);
  314. return 0;
  315. }
  316. // 倉庫データ削除
  317. int inter_storage_delete(int account_id)
  318. {
  319. struct storage *s = numdb_search(storage_db,account_id);
  320. if(s) {
  321. int i;
  322. for(i=0;i<s->storage_amount;i++){
  323. if(s->storage[i].card[0] == (short)0xff00)
  324. inter_pet_delete(*((long *)(&s->storage[i].card[2])));
  325. }
  326. numdb_erase(storage_db,account_id);
  327. aFree(s);
  328. }
  329. return 0;
  330. }
  331. // ギルド倉庫データ削除
  332. int inter_guild_storage_delete(int guild_id)
  333. {
  334. struct guild_storage *gs = numdb_search(guild_storage_db,guild_id);
  335. if(gs) {
  336. int i;
  337. for(i=0;i<gs->storage_amount;i++){
  338. if(gs->storage[i].card[0] == (short)0xff00)
  339. inter_pet_delete(*((long *)(&gs->storage[i].card[2])));
  340. }
  341. numdb_erase(guild_storage_db,guild_id);
  342. aFree(gs);
  343. }
  344. return 0;
  345. }
  346. //---------------------------------------------------------
  347. // map serverへの通信
  348. // 倉庫データの送信
  349. int mapif_load_storage(int fd,int account_id)
  350. {
  351. struct storage *s=account2storage(account_id);
  352. WFIFOW(fd,0)=0x3810;
  353. WFIFOW(fd,2)=sizeof(struct storage)+8;
  354. WFIFOL(fd,4)=account_id;
  355. memcpy(WFIFOP(fd,8),s,sizeof(struct storage));
  356. WFIFOSET(fd,WFIFOW(fd,2));
  357. return 0;
  358. }
  359. // 倉庫データ保存完了送信
  360. int mapif_save_storage_ack(int fd,int account_id)
  361. {
  362. WFIFOW(fd,0)=0x3811;
  363. WFIFOL(fd,2)=account_id;
  364. WFIFOB(fd,6)=0;
  365. WFIFOSET(fd,7);
  366. return 0;
  367. }
  368. int mapif_load_guild_storage(int fd,int account_id,int guild_id)
  369. {
  370. struct guild_storage *gs=guild2storage(guild_id);
  371. WFIFOW(fd,0)=0x3818;
  372. if(gs) {
  373. WFIFOW(fd,2)=sizeof(struct guild_storage)+12;
  374. WFIFOL(fd,4)=account_id;
  375. WFIFOL(fd,8)=guild_id;
  376. memcpy(WFIFOP(fd,12),gs,sizeof(struct guild_storage));
  377. }
  378. else {
  379. WFIFOW(fd,2)=12;
  380. WFIFOL(fd,4)=account_id;
  381. WFIFOL(fd,8)=0;
  382. }
  383. WFIFOSET(fd,WFIFOW(fd,2));
  384. return 0;
  385. }
  386. int mapif_save_guild_storage_ack(int fd,int account_id,int guild_id,int fail)
  387. {
  388. WFIFOW(fd,0)=0x3819;
  389. WFIFOL(fd,2)=account_id;
  390. WFIFOL(fd,6)=guild_id;
  391. WFIFOB(fd,10)=fail;
  392. WFIFOSET(fd,11);
  393. return 0;
  394. }
  395. //---------------------------------------------------------
  396. // map serverからの通信
  397. // 倉庫データ要求受信
  398. int mapif_parse_LoadStorage(int fd)
  399. {
  400. mapif_load_storage(fd,RFIFOL(fd,2));
  401. return 0;
  402. }
  403. // 倉庫データ受信&保存
  404. int mapif_parse_SaveStorage(int fd)
  405. {
  406. struct storage *s;
  407. int account_id=RFIFOL(fd,4);
  408. int len=RFIFOW(fd,2);
  409. if(sizeof(struct storage)!=len-8){
  410. printf("inter storage: data size error %d %d\n",sizeof(struct storage),len-8);
  411. }
  412. else {
  413. s=account2storage(account_id);
  414. memcpy(s,RFIFOP(fd,8),sizeof(struct storage));
  415. mapif_save_storage_ack(fd,account_id);
  416. }
  417. return 0;
  418. }
  419. int mapif_parse_LoadGuildStorage(int fd)
  420. {
  421. mapif_load_guild_storage(fd,RFIFOL(fd,2),RFIFOL(fd,6));
  422. return 0;
  423. }
  424. int mapif_parse_SaveGuildStorage(int fd)
  425. {
  426. struct guild_storage *gs;
  427. int guild_id=RFIFOL(fd,8);
  428. int len=RFIFOW(fd,2);
  429. if(sizeof(struct guild_storage)!=len-12){
  430. printf("inter storage: data size error %d %d\n",sizeof(struct guild_storage),len-12);
  431. }
  432. else {
  433. gs=guild2storage(guild_id);
  434. if(gs) {
  435. memcpy(gs,RFIFOP(fd,12),sizeof(struct guild_storage));
  436. mapif_save_guild_storage_ack(fd,RFIFOL(fd,4),guild_id,0);
  437. }
  438. else
  439. mapif_save_guild_storage_ack(fd,RFIFOL(fd,4),guild_id,1);
  440. }
  441. return 0;
  442. }
  443. // map server からの通信
  444. // ・1パケットのみ解析すること
  445. // ・パケット長データはinter.cにセットしておくこと
  446. // ・パケット長チェックや、RFIFOSKIPは呼び出し元で行われるので行ってはならない
  447. // ・エラーなら0(false)、そうでないなら1(true)をかえさなければならない
  448. int inter_storage_parse_frommap(int fd)
  449. {
  450. switch(RFIFOW(fd,0)){
  451. case 0x3010: mapif_parse_LoadStorage(fd); break;
  452. case 0x3011: mapif_parse_SaveStorage(fd); break;
  453. case 0x3018: mapif_parse_LoadGuildStorage(fd); break;
  454. case 0x3019: mapif_parse_SaveGuildStorage(fd); break;
  455. default:
  456. return 0;
  457. }
  458. return 1;
  459. }