/src/char/int_storage.c

https://gitlab.com/wushin/evol-server-code-old · C · 639 lines · 539 code · 68 blank · 32 comment · 113 complexity · 252a9be236cf666cb2787c5309820809 MD5 · raw file

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