int_guild.c 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562
  1. // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
  2. // For more information, see LICENCE in the main folder
  3. #include <string.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <limits.h>
  7. #include "../common/mmo.h"
  8. #include "../common/socket.h"
  9. #include "../common/db.h"
  10. #include "../common/lock.h"
  11. #include "../common/showmsg.h"
  12. #include "char.h"
  13. #include "inter.h"
  14. #include "int_storage.h"
  15. #include "int_guild.h"
  16. char guild_txt[1024] = "save/guild.txt";
  17. char castle_txt[1024] = "save/castle.txt";
  18. static struct dbt *guild_db;
  19. static struct dbt *castle_db;
  20. static int guild_newid = 10000;
  21. static unsigned int guild_exp[100];
  22. int mapif_parse_GuildLeave(int fd, int guild_id, int account_id, int char_id, int flag, const char *mes);
  23. int mapif_guild_broken(int guild_id, int flag);
  24. int guild_check_empty(struct guild *g);
  25. int guild_calcinfo(struct guild *g);
  26. int mapif_guild_basicinfochanged(int guild_id, int type, const void *data, int len);
  27. int mapif_guild_info(int fd, struct guild *g);
  28. int guild_break_sub(DBKey key, void *data, va_list ap);
  29. // ギルドデータの文字列への変換
  30. int inter_guild_tostr(char *str, struct guild *g) {
  31. int i, c, len;
  32. // 基本データ
  33. len = sprintf(str, "%d\t%s\t%s\t%d,%d,%u,%d,%d\t%s#\t%s#\t",
  34. g->guild_id, g->name, g->master,
  35. g->guild_lv, g->max_member, g->exp, g->skill_point, g->castle_id,
  36. g->mes1, g->mes2);
  37. // メンバー
  38. for(i = 0; i < g->max_member; i++) {
  39. struct guild_member *m = &g->member[i];
  40. len += sprintf(str + len, "%d,%d,%d,%d,%d,%d,%d,%u,%d,%d\t%s\t",
  41. m->account_id, m->char_id,
  42. m->hair, m->hair_color, m->gender,
  43. m->class_, m->lv, m->exp, m->exp_payper, m->position,
  44. ((m->account_id > 0) ? m->name : "-"));
  45. }
  46. // 役職
  47. for(i = 0; i < MAX_GUILDPOSITION; i++) {
  48. struct guild_position *p = &g->position[i];
  49. len += sprintf(str + len, "%d,%d\t%s#\t", p->mode, p->exp_mode, p->name);
  50. }
  51. // エンブレム
  52. len += sprintf(str + len, "%d,%d,", g->emblem_len, g->emblem_id);
  53. for(i = 0; i < g->emblem_len; i++) {
  54. len += sprintf(str + len, "%02x", (unsigned char)(g->emblem_data[i]));
  55. }
  56. len += sprintf(str + len, "$\t");
  57. // 同盟リスト
  58. c = 0;
  59. for(i = 0; i < MAX_GUILDALLIANCE; i++)
  60. if (g->alliance[i].guild_id > 0)
  61. c++;
  62. len += sprintf(str + len, "%d\t", c);
  63. for(i = 0; i < MAX_GUILDALLIANCE; i++) {
  64. struct guild_alliance *a = &g->alliance[i];
  65. if (a->guild_id > 0)
  66. len += sprintf(str + len, "%d,%d\t%s\t", a->guild_id, a->opposition, a->name);
  67. }
  68. // 追放リスト
  69. c = 0;
  70. for(i = 0; i < MAX_GUILDEXPULSION; i++)
  71. if (g->expulsion[i].account_id > 0)
  72. c++;
  73. len += sprintf(str + len, "%d\t", c);
  74. for(i = 0; i < MAX_GUILDEXPULSION; i++) {
  75. struct guild_expulsion *e = &g->expulsion[i];
  76. if (e->account_id > 0)
  77. len += sprintf(str + len, "%d,%d,%d,%d\t%s\t%s\t%s#\t",
  78. e->account_id, e->rsv1, e->rsv2, e->rsv3,
  79. e->name, e->acc, e->mes );
  80. }
  81. // ギルドスキル
  82. for(i = 0; i < MAX_GUILDSKILL; i++) {
  83. len += sprintf(str + len, "%d,%d ", g->skill[i].id, g->skill[i].lv);
  84. }
  85. len += sprintf(str + len, "\t");
  86. return 0;
  87. }
  88. // ギルドデータの文字列からの変換
  89. int inter_guild_fromstr(char *str, struct guild *g) {
  90. int i, j, c;
  91. unsigned int exp;
  92. int tmp_int[16];
  93. char tmp_str[4][256];
  94. char tmp_str2[4096];
  95. char *pstr;
  96. // 基本データ
  97. memset(g, 0, sizeof(struct guild));
  98. if (sscanf(str, "%d\t%[^\t]\t%[^\t]\t%d,%d,%u,%d,%d\t%[^\t]\t%[^\t]\t", &tmp_int[0],
  99. tmp_str[0], tmp_str[1],
  100. &tmp_int[1], &tmp_int[2], &exp, &tmp_int[4], &tmp_int[5],
  101. tmp_str[2], tmp_str[3]) < 8)
  102. return 1;
  103. g->guild_id = tmp_int[0];
  104. g->guild_lv = tmp_int[1];
  105. g->max_member = tmp_int[2];
  106. g->exp = exp;
  107. g->skill_point = tmp_int[4];
  108. g->castle_id = tmp_int[5];
  109. memcpy(g->name, tmp_str[0], NAME_LENGTH-1);
  110. memcpy(g->master, tmp_str[1], NAME_LENGTH-1);
  111. memcpy(g->mes1, tmp_str[2], 60);
  112. memcpy(g->mes2, tmp_str[3], 120);
  113. g->mes1[strlen(g->mes1)-1] = 0;
  114. g->mes2[strlen(g->mes2)-1] = 0;
  115. for(j = 0; j < 6 && str != NULL; j++) // 位置スキップ
  116. str = strchr(str + 1, '\t');
  117. // printf("GuildBaseInfo OK\n");
  118. // メンバー
  119. for(i = 0; i < g->max_member; i++) {
  120. struct guild_member *m = &g->member[i];
  121. if (sscanf(str + 1, "%d,%d,%d,%d,%d,%d,%d,%u,%d,%d\t%[^\t]\t",
  122. &tmp_int[0], &tmp_int[1], &tmp_int[2], &tmp_int[3], &tmp_int[4],
  123. &tmp_int[5], &tmp_int[6], &exp, &tmp_int[8], &tmp_int[9],
  124. tmp_str[0]) < 11)
  125. return 1;
  126. m->account_id = tmp_int[0];
  127. m->char_id = tmp_int[1];
  128. m->hair = tmp_int[2];
  129. m->hair_color = tmp_int[3];
  130. m->gender = tmp_int[4];
  131. m->class_ = tmp_int[5];
  132. m->lv = tmp_int[6];
  133. m->exp = exp;
  134. m->exp_payper = tmp_int[8];
  135. m->position = tmp_int[9];
  136. memcpy(m->name, tmp_str[0], NAME_LENGTH-1);
  137. for(j = 0; j < 2 && str != NULL; j++) // 位置スキップ
  138. str = strchr(str + 1, '\t');
  139. }
  140. // printf("GuildMemberInfo OK\n");
  141. // 役職
  142. i = 0;
  143. while (sscanf(str+1, "%d,%d%n", &tmp_int[0], &tmp_int[1], &j) == 2 && str[1+j] == '\t') {
  144. struct guild_position *p = &g->position[i];
  145. if (sscanf(str+1, "%d,%d\t%[^\t]\t", &tmp_int[0], &tmp_int[1], tmp_str[0]) < 3)
  146. return 1;
  147. p->mode = tmp_int[0];
  148. p->exp_mode = tmp_int[1];
  149. tmp_str[0][strlen(tmp_str[0])-1] = 0;
  150. memcpy(p->name, tmp_str[0], NAME_LENGTH-1);
  151. for(j = 0; j < 2 && str != NULL; j++) // 位置スキップ
  152. str = strchr(str+1, '\t');
  153. i++;
  154. }
  155. // printf("GuildPositionInfo OK\n");
  156. // エンブレム
  157. tmp_int[1] = 0;
  158. if (sscanf(str + 1, "%d,%d,%[^\t]\t", &tmp_int[0], &tmp_int[1], tmp_str2)< 3 &&
  159. sscanf(str + 1, "%d,%[^\t]\t", &tmp_int[0], tmp_str2) < 2)
  160. return 1;
  161. g->emblem_len = tmp_int[0];
  162. g->emblem_id = tmp_int[1];
  163. for(i = 0, pstr = tmp_str2; i < g->emblem_len; i++, pstr += 2) {
  164. int c1 = pstr[0], c2 = pstr[1], x1 = 0, x2 = 0;
  165. if (c1 >= '0' && c1 <= '9') x1 = c1 - '0';
  166. if (c1 >= 'a' && c1 <= 'f') x1 = c1 - 'a' + 10;
  167. if (c1 >= 'A' && c1 <= 'F') x1 = c1 - 'A' + 10;
  168. if (c2 >= '0' && c2 <= '9') x2 = c2 - '0';
  169. if (c2 >= 'a' && c2 <= 'f') x2 = c2 - 'a' + 10;
  170. if (c2 >= 'A' && c2 <= 'F') x2 = c2 - 'A' + 10;
  171. g->emblem_data[i] = (x1<<4) | x2;
  172. }
  173. // printf("GuildEmblemInfo OK\n");
  174. str=strchr(str + 1, '\t'); // 位置スキップ
  175. // 同盟リスト
  176. if (sscanf(str + 1, "%d\t", &c) < 1)
  177. return 1;
  178. str = strchr(str + 1, '\t'); // 位置スキップ
  179. for(i = 0; i < c; i++) {
  180. struct guild_alliance *a = &g->alliance[i];
  181. if (sscanf(str + 1, "%d,%d\t%[^\t]\t", &tmp_int[0], &tmp_int[1], tmp_str[0]) < 3)
  182. return 1;
  183. a->guild_id = tmp_int[0];
  184. a->opposition = tmp_int[1];
  185. memcpy(a->name, tmp_str[0], NAME_LENGTH-1);
  186. for(j = 0; j < 2 && str != NULL; j++) // 位置スキップ
  187. str = strchr(str + 1, '\t');
  188. }
  189. // printf("GuildAllianceInfo OK\n");
  190. // 追放リスト
  191. if (sscanf(str+1, "%d\t", &c) < 1)
  192. return 1;
  193. str = strchr(str + 1, '\t'); // 位置スキップ
  194. for(i = 0; i < c; i++) {
  195. struct guild_expulsion *e = &g->expulsion[i];
  196. if (sscanf(str + 1, "%d,%d,%d,%d\t%[^\t]\t%[^\t]\t%[^\t]\t",
  197. &tmp_int[0], &tmp_int[1], &tmp_int[2], &tmp_int[3],
  198. tmp_str[0], tmp_str[1], tmp_str[2]) < 6)
  199. return 1;
  200. e->account_id = tmp_int[0];
  201. e->rsv1 = tmp_int[1];
  202. e->rsv2 = tmp_int[2];
  203. e->rsv3 = tmp_int[3];
  204. memcpy(e->name, tmp_str[0], NAME_LENGTH-1);
  205. memcpy(e->acc, tmp_str[1], 24);
  206. tmp_str[2][strlen(tmp_str[2])-1] = 0;
  207. memcpy(e->mes, tmp_str[2], 40);
  208. for(j = 0; j < 4 && str != NULL; j++) // 位置スキップ
  209. str = strchr(str + 1, '\t');
  210. }
  211. // printf("GuildExplusionInfo OK\n");
  212. // ギルドスキル
  213. for(i = 0; i < MAX_GUILDSKILL; i++) {
  214. if (sscanf(str+1,"%d,%d ", &tmp_int[0], &tmp_int[1]) < 2)
  215. break;
  216. g->skill[i].id = tmp_int[0];
  217. g->skill[i].lv = tmp_int[1];
  218. str = strchr(str + 1, ' ');
  219. }
  220. str = strchr(str + 1, '\t');
  221. // printf("GuildSkillInfo OK\n");
  222. return 0;
  223. }
  224. // ギルド城データの文字列への変換
  225. int inter_guildcastle_tostr(char *str, struct guild_castle *gc) {
  226. int len;
  227. len = sprintf(str, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", // added Guardian HP [Valaris]
  228. gc->castle_id, gc->guild_id, gc->economy, gc->defense, gc->triggerE,
  229. gc->triggerD, gc->nextTime, gc->payTime, gc->createTime, gc->visibleC,
  230. gc->guardian[0].visible, gc->guardian[1].visible, gc->guardian[2].visible, gc->guardian[3].visible,
  231. gc->guardian[4].visible, gc->guardian[5].visible, gc->guardian[6].visible, gc->guardian[7].visible,
  232. gc->guardian[0].hp, gc->guardian[1].hp, gc->guardian[2].hp, gc->guardian[3].hp,
  233. gc->guardian[4].hp, gc->guardian[5].hp, gc->guardian[6].hp, gc->guardian[7].hp);
  234. return 0;
  235. }
  236. // ギルド城データの文字列からの変換
  237. int inter_guildcastle_fromstr(char *str, struct guild_castle *gc) {
  238. int tmp_int[26];
  239. memset(gc, 0, sizeof(struct guild_castle));
  240. // new structure of guild castle
  241. if (sscanf(str, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
  242. &tmp_int[0], &tmp_int[1], &tmp_int[2], &tmp_int[3], &tmp_int[4], &tmp_int[5], &tmp_int[6],
  243. &tmp_int[7], &tmp_int[8], &tmp_int[9], &tmp_int[10], &tmp_int[11], &tmp_int[12], &tmp_int[13],
  244. &tmp_int[14], &tmp_int[15], &tmp_int[16], &tmp_int[17], &tmp_int[18], &tmp_int[19], &tmp_int[20],
  245. &tmp_int[21], &tmp_int[22], &tmp_int[23], &tmp_int[24], &tmp_int[25]) == 26) {
  246. gc->castle_id = tmp_int[0];
  247. gc->guild_id = tmp_int[1];
  248. gc->economy = tmp_int[2];
  249. gc->defense = tmp_int[3];
  250. gc->triggerE = tmp_int[4];
  251. gc->triggerD = tmp_int[5];
  252. gc->nextTime = tmp_int[6];
  253. gc->payTime = tmp_int[7];
  254. gc->createTime = tmp_int[8];
  255. gc->visibleC = tmp_int[9];
  256. gc->guardian[0].visible = tmp_int[10];
  257. gc->guardian[1].visible = tmp_int[11];
  258. gc->guardian[2].visible = tmp_int[12];
  259. gc->guardian[3].visible = tmp_int[13];
  260. gc->guardian[4].visible = tmp_int[14];
  261. gc->guardian[5].visible = tmp_int[15];
  262. gc->guardian[6].visible = tmp_int[16];
  263. gc->guardian[7].visible = tmp_int[17];
  264. gc->guardian[0].hp = tmp_int[18];
  265. gc->guardian[1].hp = tmp_int[19];
  266. gc->guardian[2].hp = tmp_int[20];
  267. gc->guardian[3].hp = tmp_int[21];
  268. gc->guardian[4].hp = tmp_int[22];
  269. gc->guardian[5].hp = tmp_int[23];
  270. gc->guardian[6].hp = tmp_int[24];
  271. gc->guardian[7].hp = tmp_int[25]; // end additions [Valaris]
  272. // old structure of guild castle
  273. } else if (sscanf(str, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
  274. &tmp_int[0], &tmp_int[1], &tmp_int[2], &tmp_int[3], &tmp_int[4], &tmp_int[5], &tmp_int[6],
  275. &tmp_int[7], &tmp_int[8], &tmp_int[9], &tmp_int[10], &tmp_int[11], &tmp_int[12], &tmp_int[13],
  276. &tmp_int[14], &tmp_int[15], &tmp_int[16], &tmp_int[17]) == 18) {
  277. int i;
  278. gc->castle_id = tmp_int[0];
  279. gc->guild_id = tmp_int[1];
  280. gc->economy = tmp_int[2];
  281. gc->defense = tmp_int[3];
  282. gc->triggerE = tmp_int[4];
  283. gc->triggerD = tmp_int[5];
  284. gc->nextTime = tmp_int[6];
  285. gc->payTime = tmp_int[7];
  286. gc->createTime = tmp_int[8];
  287. gc->visibleC = tmp_int[9];
  288. gc->guardian[0].visible = tmp_int[10];
  289. gc->guardian[1].visible = tmp_int[11];
  290. gc->guardian[2].visible = tmp_int[12];
  291. gc->guardian[3].visible = tmp_int[13];
  292. gc->guardian[4].visible = tmp_int[14];
  293. gc->guardian[5].visible = tmp_int[15];
  294. gc->guardian[6].visible = tmp_int[16];
  295. gc->guardian[7].visible = tmp_int[17];
  296. for (i = 0; i < MAX_GUARDIANS; i++)
  297. {
  298. if (gc->guardian[i].visible)
  299. gc->guardian[i].hp = 15000 + 2000 * gc->defense;
  300. else
  301. gc->guardian[i].hp = 0;
  302. }
  303. } else {
  304. return 1;
  305. }
  306. return 0;
  307. }
  308. // ギルド関連データベース読み込み
  309. int inter_guild_readdb(void) {
  310. int i;
  311. FILE *fp;
  312. char line[1024];
  313. char path[1024];
  314. sprintf(path, "%s%s", db_path, "/exp_guild.txt");
  315. fp = fopen(path, "r");
  316. if (fp == NULL) {
  317. ShowError("can't read db/exp_guild.txt\n");
  318. return 1;
  319. }
  320. i = 0;
  321. while(fgets(line, sizeof(line)-1, fp) && i < 100){
  322. if (line[0] == '/' && line[1] == '/')
  323. continue;
  324. guild_exp[i] = (unsigned int)atof(line);
  325. i++;
  326. }
  327. fclose(fp);
  328. return 0;
  329. }
  330. // ギルドデータの読み込み
  331. int inter_guild_init() {
  332. char line[16384];
  333. struct guild *g;
  334. struct guild_castle *gc;
  335. FILE *fp;
  336. int i, j, c = 0;
  337. inter_guild_readdb();
  338. guild_db = db_alloc(__FILE__,__LINE__,DB_INT,DB_OPT_RELEASE_DATA,sizeof(int));
  339. castle_db = db_alloc(__FILE__,__LINE__,DB_INT,DB_OPT_RELEASE_DATA,sizeof(int));
  340. if ((fp = fopen(guild_txt,"r")) == NULL)
  341. return 1;
  342. while(fgets(line, sizeof(line)-1, fp)) {
  343. j = 0;
  344. if (sscanf(line, "%d\t%%newid%%\n%n", &i, &j) == 1 && j > 0 && guild_newid <= i) {
  345. guild_newid = i;
  346. continue;
  347. }
  348. g = (struct guild *) aCalloc(sizeof(struct guild), 1);
  349. if(g == NULL){
  350. ShowFatalError("int_guild: out of memory!\n");
  351. exit(0);
  352. }
  353. // memset(g, 0, sizeof(struct guild)); not needed...
  354. if (inter_guild_fromstr(line, g) == 0 && g->guild_id > 0) {
  355. if (g->guild_id >= guild_newid)
  356. guild_newid = g->guild_id + 1;
  357. idb_put(guild_db, g->guild_id, g);
  358. guild_check_empty(g);
  359. guild_calcinfo(g);
  360. } else {
  361. ShowError("int_guild: broken data [%s] line %d\n", guild_txt, c);
  362. aFree(g);
  363. }
  364. c++;
  365. }
  366. fclose(fp);
  367. // printf("int_guild: %s read done (%d guilds)\n", guild_txt, c);
  368. c = 0;//カウンタ初期化
  369. if ((fp = fopen(castle_txt, "r")) == NULL) {
  370. return 1;
  371. }
  372. while(fgets(line, sizeof(line)-1, fp)) {
  373. gc = (struct guild_castle *) aCalloc(sizeof(struct guild_castle), 1);
  374. if(gc == NULL){
  375. ShowFatalError("int_guild: out of memory!\n");
  376. exit(0);
  377. }
  378. // memset(gc, 0, sizeof(struct guild_castle)); No need...
  379. if (inter_guildcastle_fromstr(line, gc) == 0) {
  380. idb_put(castle_db, gc->castle_id, gc);
  381. } else {
  382. ShowError("int_guild: broken data [%s] line %d\n", castle_txt, c);
  383. aFree(gc);
  384. }
  385. c++;
  386. }
  387. if (!c) {
  388. ShowStatus(" %s - making Default Data...\n", castle_txt);
  389. //デフォルトデータを作成
  390. for(i = 0; i < MAX_GUILDCASTLE; i++) {
  391. gc = (struct guild_castle *) aCalloc(sizeof(struct guild_castle), 1);
  392. if (gc == NULL) {
  393. ShowFatalError("int_guild: out of memory!\n");
  394. exit(0);
  395. }
  396. gc->castle_id = i;
  397. idb_put(castle_db, gc->castle_id, gc);
  398. }
  399. ShowStatus(" %s - making done\n",castle_txt);
  400. return 0;
  401. }
  402. fclose(fp);
  403. return 0;
  404. }
  405. void inter_guild_final() {
  406. castle_db->destroy(castle_db, NULL);
  407. guild_db->destroy(guild_db, NULL);
  408. return;
  409. }
  410. struct guild *inter_guild_search(int guild_id) {
  411. return idb_get(guild_db, guild_id);
  412. }
  413. // ギルドデータのセーブ用
  414. int inter_guild_save_sub(DBKey key,void *data,va_list ap) {
  415. char line[16384];
  416. FILE *fp;
  417. inter_guild_tostr(line,(struct guild *)data);
  418. fp=va_arg(ap,FILE *);
  419. fprintf(fp,"%s" RETCODE,line);
  420. return 0;
  421. }
  422. // ギルド城データのセーブ用
  423. int inter_castle_save_sub(DBKey key, void *data, va_list ap) {
  424. char line[16384];
  425. FILE *fp;
  426. inter_guildcastle_tostr(line, (struct guild_castle *)data);
  427. fp = va_arg(ap, FILE *);
  428. fprintf(fp, "%s" RETCODE, line);
  429. return 0;
  430. }
  431. // ギルドデータのセーブ
  432. int inter_guild_save() {
  433. FILE *fp;
  434. int lock;
  435. if ((fp = lock_fopen(guild_txt, &lock)) == NULL) {
  436. ShowError("int_guild: cant write [%s] !!! data is lost !!!\n", guild_txt);
  437. return 1;
  438. }
  439. guild_db->foreach(guild_db, inter_guild_save_sub, fp);
  440. // fprintf(fp, "%d\t%%newid%%\n", guild_newid);
  441. lock_fclose(fp, guild_txt, &lock);
  442. // printf("int_guild: %s saved.\n", guild_txt);
  443. if ((fp = lock_fopen(castle_txt,&lock)) == NULL) {
  444. ShowError("int_guild: cant write [%s] !!! data is lost !!!\n", castle_txt);
  445. return 1;
  446. }
  447. castle_db->foreach(castle_db, inter_castle_save_sub, fp);
  448. lock_fclose(fp, castle_txt, &lock);
  449. return 0;
  450. }
  451. // ギルド名検索用
  452. int search_guildname_sub(DBKey key, void *data, va_list ap) {
  453. struct guild *g = (struct guild *)data, **dst;
  454. char *str;
  455. str = va_arg(ap, char *);
  456. dst = va_arg(ap, struct guild **);
  457. if (strcmpi(g->name, str) == 0)
  458. *dst = g;
  459. return 0;
  460. }
  461. // ギルド名検索
  462. struct guild* search_guildname(char *str) {
  463. struct guild *g = NULL;
  464. guild_db->foreach(guild_db, search_guildname_sub, str, &g);
  465. return g;
  466. }
  467. // ギルドが空かどうかチェック
  468. int guild_check_empty(struct guild *g) {
  469. int i;
  470. for(i = 0; i < g->max_member; i++) {
  471. if (g->member[i].account_id > 0) {
  472. return 0;
  473. }
  474. }
  475. // 誰もいないので解散
  476. guild_db->foreach(guild_db, guild_break_sub, g->guild_id);
  477. inter_guild_storage_delete(g->guild_id);
  478. mapif_guild_broken(g->guild_id, 0);
  479. idb_remove(guild_db, g->guild_id);
  480. return 1;
  481. }
  482. // キャラの競合がないかチェック用
  483. int guild_check_conflict_sub(DBKey key, void *data, va_list ap) {
  484. struct guild *g = (struct guild *)data;
  485. int guild_id, account_id, char_id, i;
  486. guild_id = va_arg(ap, int);
  487. account_id = va_arg(ap, int);
  488. char_id = va_arg(ap, int);
  489. if (g->guild_id == guild_id) // 本来の所属なので問題なし
  490. return 0;
  491. for(i = 0; i < MAX_GUILD; i++) {
  492. if (g->member[i].account_id == account_id && g->member[i].char_id == char_id) {
  493. // 別のギルドに偽の所属データがあるので脱退
  494. ShowWarning("int_guild: guild conflict! %d,%d %d!=%d\n", account_id, char_id, guild_id, g->guild_id);
  495. mapif_parse_GuildLeave(-1, g->guild_id, account_id, char_id, 0, "**データ競合**");
  496. }
  497. }
  498. return 0;
  499. }
  500. // キャラの競合がないかチェック
  501. int guild_check_conflict(int guild_id, int account_id, int char_id) {
  502. guild_db->foreach(guild_db, guild_check_conflict_sub, guild_id, account_id, char_id);
  503. return 0;
  504. }
  505. unsigned int guild_nextexp (int level)
  506. {
  507. if (level == 0)
  508. return 1;
  509. if (level > 0 && level < 100)
  510. return guild_exp[level-1];
  511. return 0;
  512. }
  513. // ギルドスキルがあるか確認
  514. int guild_checkskill(struct guild *g, int id) {
  515. int idx = id - GD_SKILLBASE;
  516. if(idx < 0 || idx >= MAX_GUILDSKILL)
  517. return 0;
  518. return g->skill[idx].lv;
  519. }
  520. // ギルドの情報の再計算
  521. int guild_calcinfo(struct guild *g) {
  522. int i, c;
  523. unsigned int nextexp;
  524. struct guild before = *g;
  525. // スキルIDの設定
  526. for(i = 0; i < MAX_GUILDSKILL; i++)
  527. g->skill[i].id=i+GD_SKILLBASE;
  528. // ギルドレベル
  529. if (g->guild_lv <= 0)
  530. g->guild_lv = 1;
  531. nextexp = guild_nextexp(g->guild_lv);
  532. if (nextexp > 0) {
  533. while(g->exp >= nextexp && nextexp > 0) { //fixed guild exp overflow [Kevin]
  534. g->exp -= nextexp;
  535. g->guild_lv++;
  536. g->skill_point++;
  537. nextexp = guild_nextexp(g->guild_lv);
  538. }
  539. }
  540. // ギルドの次の経験値
  541. g->next_exp = guild_nextexp(g->guild_lv);
  542. // メンバ上限(ギルド拡張適用)
  543. g->max_member = 16 + guild_checkskill(g, GD_EXTENSION) * 6; //Guild Extention skill - currently adds 6 to max per skill lv.
  544. if(g->max_member > MAX_GUILD)
  545. {
  546. ShowError("Guild %d:%s has capacity for too many guild members (%d), max supported is %d\n", g->guild_id, g->name, g->max_member, MAX_GUILD);
  547. g->max_member = MAX_GUILD;
  548. }
  549. // 平均レベルとオンライン人数
  550. g->average_lv = 0;
  551. g->connect_member = 0;
  552. c = 0;
  553. for(i = 0; i < g->max_member; i++) {
  554. if (g->member[i].account_id > 0) {
  555. g->average_lv += g->member[i].lv;
  556. c++;
  557. if (g->member[i].online > 0)
  558. g->connect_member++;
  559. }
  560. }
  561. if(c) g->average_lv /= c;
  562. // 全データを送る必要がありそう
  563. if (g->max_member != before.max_member ||
  564. g->guild_lv != before.guild_lv ||
  565. g->skill_point != before.skill_point) {
  566. mapif_guild_info(-1, g);
  567. return 1;
  568. }
  569. return 0;
  570. }
  571. //-------------------------------------------------------------------
  572. // map serverへの通信
  573. // ギルド作成可否
  574. int mapif_guild_created(int fd, int account_id, struct guild *g) {
  575. WFIFOHEAD(fd, 10);
  576. WFIFOW(fd,0) = 0x3830;
  577. WFIFOL(fd,2) = account_id;
  578. if (g != NULL) {
  579. WFIFOL(fd,6) = g->guild_id;
  580. ShowInfo("Created Guild (%d %s)\n", g->guild_id, g->name);
  581. }else{
  582. WFIFOL(fd,6) = 0;
  583. }
  584. WFIFOSET(fd,10);
  585. return 0;
  586. }
  587. // ギルド情報見つからず
  588. int mapif_guild_noinfo(int fd, int guild_id) {
  589. WFIFOHEAD(fd, 8);
  590. WFIFOW(fd,0) = 0x3831;
  591. WFIFOW(fd,2) = 8;
  592. WFIFOL(fd,4) = guild_id;
  593. WFIFOSET(fd,8);
  594. ShowNotice("int_guild: info not found %d\n", guild_id);
  595. return 0;
  596. }
  597. // ギルド情報まとめ送り
  598. int mapif_guild_info(int fd, struct guild *g) {
  599. unsigned char buf[8+sizeof(struct guild)];
  600. WBUFW(buf,0) = 0x3831;
  601. memcpy(buf + 4, g, sizeof(struct guild));
  602. WBUFW(buf,2) = 4 + sizeof(struct guild);
  603. // printf("int_guild: sizeof(guild)=%d\n", sizeof(struct guild));
  604. if (fd < 0)
  605. mapif_sendall(buf, WBUFW(buf,2));
  606. else
  607. mapif_send(fd, buf, WBUFW(buf,2));
  608. // printf("int_guild: info %d %s\n", p->guild_id, p->name);
  609. return 0;
  610. }
  611. // メンバ追加可否
  612. int mapif_guild_memberadded(int fd, int guild_id, int account_id, int char_id, int flag) {
  613. WFIFOHEAD(fd, 15);
  614. WFIFOW(fd,0) = 0x3832;
  615. WFIFOL(fd,2) = guild_id;
  616. WFIFOL(fd,6) = account_id;
  617. WFIFOL(fd,10) = char_id;
  618. WFIFOB(fd,14) = flag;
  619. WFIFOSET(fd, 15);
  620. return 0;
  621. }
  622. // 脱退/追放通知
  623. int mapif_guild_leaved(int guild_id, int account_id, int char_id, int flag, const char *name, const char *mes) {
  624. unsigned char buf[79];
  625. WBUFW(buf, 0) = 0x3834;
  626. WBUFL(buf, 2) = guild_id;
  627. WBUFL(buf, 6) = account_id;
  628. WBUFL(buf,10) = char_id;
  629. WBUFB(buf,14) = flag;
  630. memcpy(WBUFP(buf,15), mes, 40);
  631. memcpy(WBUFP(buf,55), name, NAME_LENGTH);
  632. mapif_sendall(buf, 55+NAME_LENGTH);
  633. // mapif_sendall(buf, 79);
  634. ShowInfo("Character left guild (Guild %d, %d - %s: %s)\n", guild_id, account_id, name, mes);
  635. return 0;
  636. }
  637. // オンライン状態とLv更新通知
  638. int mapif_guild_memberinfoshort(struct guild *g, int idx) {
  639. unsigned char buf[19];
  640. WBUFW(buf, 0) = 0x3835;
  641. WBUFL(buf, 2) = g->guild_id;
  642. WBUFL(buf, 6) = g->member[idx].account_id;
  643. WBUFL(buf,10) = g->member[idx].char_id;
  644. WBUFB(buf,14) = (unsigned char)g->member[idx].online;
  645. WBUFW(buf,15) = g->member[idx].lv;
  646. WBUFW(buf,17) = g->member[idx].class_;
  647. mapif_sendall(buf, 19);
  648. return 0;
  649. }
  650. // 解散通知
  651. int mapif_guild_broken(int guild_id, int flag) {
  652. unsigned char buf[7];
  653. WBUFW(buf,0) = 0x3836;
  654. WBUFL(buf,2) = guild_id;
  655. WBUFB(buf,6) = flag;
  656. mapif_sendall(buf, 7);
  657. ShowInfo("Guild Break (%d)\n", guild_id);
  658. return 0;
  659. }
  660. // ギルド内発言
  661. int mapif_guild_message(int guild_id, int account_id, char *mes, int len, int sfd) {
  662. unsigned char buf[2048];
  663. WBUFW(buf,0) = 0x3837;
  664. WBUFW(buf,2) = len + 12;
  665. WBUFL(buf,4) = guild_id;
  666. WBUFL(buf,8) = account_id;
  667. memcpy(WBUFP(buf,12), mes, len);
  668. mapif_sendallwos(sfd, buf, len + 12);
  669. return 0;
  670. }
  671. // ギルド基本情報変更通知
  672. int mapif_guild_basicinfochanged(int guild_id, int type, const void *data, int len) {
  673. unsigned char buf[2048];
  674. WBUFW(buf,0) = 0x3839;
  675. WBUFW(buf,2) = len+10;
  676. WBUFL(buf,4) = guild_id;
  677. WBUFW(buf,8) = type;
  678. memcpy(WBUFP(buf,10),data,len);
  679. mapif_sendall(buf,len+10);
  680. return 0;
  681. }
  682. // ギルドメンバ情報変更通知
  683. int mapif_guild_memberinfochanged(int guild_id, int account_id, int char_id, int type, const void *data, int len) {
  684. unsigned char buf[4096];
  685. WBUFW(buf, 0) = 0x383a;
  686. WBUFW(buf, 2) = len + 18;
  687. WBUFL(buf, 4) = guild_id;
  688. WBUFL(buf, 8) = account_id;
  689. WBUFL(buf,12) = char_id;
  690. WBUFW(buf,16) = type;
  691. memcpy(WBUFP(buf,18), data, len);
  692. mapif_sendall(buf,len+18);
  693. return 0;
  694. }
  695. // ギルドスキルアップ通知
  696. int mapif_guild_skillupack(int guild_id, int skill_num, int account_id) {
  697. unsigned char buf[14];
  698. WBUFW(buf, 0) = 0x383c;
  699. WBUFL(buf, 2) = guild_id;
  700. WBUFL(buf, 6) = skill_num;
  701. WBUFL(buf,10) = account_id;
  702. mapif_sendall(buf, 14);
  703. return 0;
  704. }
  705. // ギルド同盟/敵対通知
  706. int mapif_guild_alliance(int guild_id1, int guild_id2, int account_id1, int account_id2, int flag, const char *name1, const char *name2) {
  707. unsigned char buf[67];
  708. WBUFW(buf, 0) = 0x383d;
  709. WBUFL(buf, 2) = guild_id1;
  710. WBUFL(buf, 6) = guild_id2;
  711. WBUFL(buf,10) = account_id1;
  712. WBUFL(buf,14) = account_id2;
  713. WBUFB(buf,18) = flag;
  714. memcpy(WBUFP(buf,19), name1, NAME_LENGTH);
  715. memcpy(WBUFP(buf,19+NAME_LENGTH), name2, NAME_LENGTH);
  716. mapif_sendall(buf,19+2*NAME_LENGTH);
  717. /*
  718. memcpy(WBUFP(buf,43), name2, NAME_LENGTH);
  719. mapif_sendall(buf, 67);
  720. */
  721. return 0;
  722. }
  723. // ギルド役職変更通知
  724. int mapif_guild_position(struct guild *g, int idx) {
  725. unsigned char buf[2048];
  726. WBUFW(buf,0) = 0x383b;
  727. WBUFW(buf,2) = sizeof(struct guild_position) + 12;
  728. WBUFL(buf,4) = g->guild_id;
  729. WBUFL(buf,8) = idx;
  730. memcpy(WBUFP(buf,12), &g->position[idx], sizeof(struct guild_position));
  731. mapif_sendall(buf, WBUFW(buf,2));
  732. return 0;
  733. }
  734. // ギルド告知変更通知
  735. int mapif_guild_notice(struct guild *g) {
  736. unsigned char buf[186];
  737. WBUFW(buf,0) = 0x383e;
  738. WBUFL(buf,2) = g->guild_id;
  739. memcpy(WBUFP(buf,6), g->mes1, 60);
  740. memcpy(WBUFP(buf,66), g->mes2, 120);
  741. mapif_sendall(buf, 186);
  742. return 0;
  743. }
  744. // ギルドエンブレム変更通知
  745. int mapif_guild_emblem(struct guild *g) {
  746. unsigned char buf[2048];
  747. WBUFW(buf,0) = 0x383f;
  748. WBUFW(buf,2) = g->emblem_len + 12;
  749. WBUFL(buf,4) = g->guild_id;
  750. WBUFL(buf,8) = g->emblem_id;
  751. memcpy(WBUFP(buf,12), g->emblem_data, g->emblem_len);
  752. mapif_sendall(buf, WBUFW(buf,2));
  753. return 0;
  754. }
  755. int mapif_guild_master_changed(struct guild *g, int position)
  756. {
  757. unsigned char buf[12];
  758. WBUFW(buf,0)=0x3843;
  759. WBUFL(buf,2)=g->guild_id;
  760. WBUFL(buf,6)=position;
  761. mapif_sendall(buf,10);
  762. return 0;
  763. }
  764. int mapif_guild_castle_dataload(int castle_id, int index, int value) {
  765. unsigned char buf[9];
  766. WBUFW(buf,0) = 0x3840;
  767. WBUFW(buf,2) = castle_id;
  768. WBUFB(buf,4) = index;
  769. WBUFL(buf,5) = value;
  770. mapif_sendall(buf,9);
  771. return 0;
  772. }
  773. int mapif_guild_castle_datasave(int castle_id, int index, int value) {
  774. unsigned char buf[9];
  775. WBUFW(buf,0) = 0x3841;
  776. WBUFW(buf,2) = castle_id;
  777. WBUFB(buf,4) = index;
  778. WBUFL(buf,5) = value;
  779. mapif_sendall(buf,9);
  780. return 0;
  781. }
  782. int mapif_guild_castle_alldataload_sub(DBKey key, void *data, va_list ap) {
  783. int fd = va_arg(ap, int);
  784. int *p = va_arg(ap, int*);
  785. WFIFOHEAD(fd, sizeof(struct guild_castle));
  786. memcpy(WFIFOP(fd,*p), (struct guild_castle*)data, sizeof(struct guild_castle));
  787. (*p) += sizeof(struct guild_castle);
  788. return 0;
  789. }
  790. int mapif_guild_castle_alldataload(int fd) {
  791. int len = 4;
  792. WFIFOHEAD(fd, 0);
  793. WFIFOW(fd,0) = 0x3842;
  794. castle_db->foreach(castle_db, mapif_guild_castle_alldataload_sub, fd, &len);
  795. WFIFOW(fd,2) = len;
  796. WFIFOSET(fd, len);
  797. return 0;
  798. }
  799. //-------------------------------------------------------------------
  800. // map serverからの通信
  801. // ギルド作成要求
  802. int mapif_parse_CreateGuild(int fd, int account_id, char *name, struct guild_member *master) {
  803. struct guild *g;
  804. int i;
  805. for(i = 0; i < NAME_LENGTH && name[i]; i++) {
  806. if (!(name[i] & 0xe0) || name[i] == 0x7f) {
  807. ShowInfo("Create Guild: illegal guild name [%s]\n", name);
  808. mapif_guild_created(fd, account_id, NULL);
  809. return 0;
  810. }
  811. }
  812. if ((g = search_guildname(name)) != NULL) {
  813. ShowInfo("Create Guild: same name guild exists [%s]\n", name);
  814. mapif_guild_created(fd, account_id, NULL);
  815. return 0;
  816. }
  817. // Check Authorised letters/symbols in the name of the character
  818. if (char_name_option == 1) { // only letters/symbols in char_name_letters are authorised
  819. for (i = 0; i < NAME_LENGTH && name[i]; i++)
  820. if (strchr(char_name_letters, name[i]) == NULL) {
  821. mapif_guild_created(fd,account_id,NULL);
  822. return 0;
  823. }
  824. } else if (char_name_option == 2) { // letters/symbols in char_name_letters are forbidden
  825. for (i = 0; i < NAME_LENGTH && name[i]; i++)
  826. if (strchr(char_name_letters, name[i]) != NULL) {
  827. mapif_guild_created(fd,account_id,NULL);
  828. return 0;
  829. }
  830. }
  831. g = (struct guild *) aCalloc(sizeof(struct guild), 1);
  832. if (g == NULL) {
  833. ShowFatalError("int_guild: CreateGuild: out of memory !\n");
  834. mapif_guild_created(fd, account_id, NULL);
  835. exit(0);
  836. }
  837. // memset(g, 0, sizeof(struct guild)); Meh...
  838. g->guild_id = guild_newid++;
  839. memcpy(g->name, name, NAME_LENGTH-1);
  840. memcpy(g->master, master->name, NAME_LENGTH-1);
  841. memcpy(&g->member[0], master, sizeof(struct guild_member));
  842. g->position[0].mode = 0x11;
  843. strcpy(g->position[ 0].name, "GuildMaster");
  844. strcpy(g->position[MAX_GUILDPOSITION-1].name, "Newbie");
  845. for(i = 1; i < MAX_GUILDPOSITION-1; i++)
  846. sprintf(g->position[i].name, "Position %d", i + 1);
  847. // ここでギルド情報計算が必要と思われる
  848. g->max_member = 16;
  849. g->average_lv = master->lv;
  850. for(i = 0; i < MAX_GUILDSKILL; i++)
  851. g->skill[i].id=i + GD_SKILLBASE;
  852. idb_put(guild_db, g->guild_id, g);
  853. mapif_guild_created(fd, account_id, g);
  854. mapif_guild_info(fd, g);
  855. if(log_inter)
  856. inter_log("guild %s (id=%d) created by master %s (id=%d)" RETCODE,
  857. name, g->guild_id, master->name, master->account_id);
  858. return 0;
  859. }
  860. // ギルド情報要求
  861. int mapif_parse_GuildInfo(int fd, int guild_id) {
  862. struct guild *g;
  863. g = idb_get(guild_db, guild_id);
  864. if (g != NULL){
  865. guild_calcinfo(g);
  866. mapif_guild_info(fd, g);
  867. } else
  868. mapif_guild_noinfo(fd, guild_id);
  869. return 0;
  870. }
  871. // ギルドメンバ追加要求
  872. int mapif_parse_GuildAddMember(int fd, int guild_id, struct guild_member *m) {
  873. struct guild *g;
  874. int i;
  875. g = idb_get(guild_db, guild_id);
  876. if (g == NULL) {
  877. mapif_guild_memberadded(fd, guild_id, m->account_id, m->char_id, 1);
  878. return 0;
  879. }
  880. for(i = 0; i < g->max_member; i++) {
  881. if (g->member[i].account_id == 0) {
  882. memcpy(&g->member[i], m, sizeof(struct guild_member));
  883. mapif_guild_memberadded(fd, guild_id, m->account_id, m->char_id, 0);
  884. guild_calcinfo(g);
  885. mapif_guild_info(-1, g);
  886. return 0;
  887. }
  888. }
  889. mapif_guild_memberadded(fd, guild_id, m->account_id, m->char_id, 1);
  890. return 0;
  891. }
  892. // ギルド脱退/追放要求
  893. int mapif_parse_GuildLeave(int fd, int guild_id, int account_id, int char_id, int flag, const char *mes) {
  894. struct guild *g = NULL;
  895. int i, j;
  896. g = idb_get(guild_db, guild_id);
  897. if (g != NULL) {
  898. for(i = 0; i < MAX_GUILD; i++) {
  899. if (g->member[i].account_id == account_id && g->member[i].char_id == char_id) {
  900. // printf("%d %d\n", i, (int)(&g->member[i]));
  901. // printf("%d %s\n", i, g->member[i].name);
  902. if (flag) { // 追放の場合追放リストに入れる
  903. for(j = 0; j < MAX_GUILDEXPULSION; j++) {
  904. if (g->expulsion[j].account_id == 0)
  905. break;
  906. }
  907. if (j == MAX_GUILDEXPULSION) { // 一杯なので古いのを消す
  908. for(j = 0; j < MAX_GUILDEXPULSION - 1; j++)
  909. g->expulsion[j] = g->expulsion[j+1];
  910. j = MAX_GUILDEXPULSION - 1;
  911. }
  912. g->expulsion[j].account_id = account_id;
  913. memcpy(g->expulsion[j].acc, "dummy", NAME_LENGTH-1);
  914. memcpy(g->expulsion[j].name, g->member[i].name, NAME_LENGTH-1);
  915. memcpy(g->expulsion[j].mes, mes, 40);
  916. }
  917. mapif_guild_leaved(guild_id, account_id, char_id, flag, g->member[i].name, mes);
  918. // printf("%d %d\n", i, (int)(&g->member[i]));
  919. // printf("%d %s\n", i, (&g->member[i])->name);
  920. memset(&g->member[i], 0, sizeof(struct guild_member));
  921. if (guild_check_empty(g) == 0)
  922. mapif_guild_info(-1,g);// まだ人がいるのでデータ送信
  923. return 0;
  924. }
  925. }
  926. }
  927. return 0;
  928. }
  929. // オンライン/Lv更新
  930. int mapif_parse_GuildChangeMemberInfoShort(int fd, int guild_id, int account_id, int char_id, int online, int lv, int class_) {
  931. struct guild *g;
  932. int i, alv, c;
  933. g = idb_get(guild_db, guild_id);
  934. if (g == NULL)
  935. return 0;
  936. g->connect_member = 0;
  937. alv = 0;
  938. c = 0;
  939. for(i = 0; i < MAX_GUILD; i++) {
  940. if (g->member[i].account_id == account_id && g->member[i].char_id == char_id) {
  941. g->member[i].online = online;
  942. g->member[i].lv = lv;
  943. g->member[i].class_ = class_;
  944. mapif_guild_memberinfoshort(g, i);
  945. }
  946. if (g->member[i].account_id > 0) {
  947. alv += g->member[i].lv;
  948. c++;
  949. }
  950. if (g->member[i].online)
  951. g->connect_member++;
  952. }
  953. if (c)
  954. // 平均レベル
  955. g->average_lv = alv / c;
  956. return 0;
  957. }
  958. // ギルド解散処理用(同盟/敵対を解除)
  959. int guild_break_sub(DBKey key, void *data, va_list ap) {
  960. struct guild *g = (struct guild *)data;
  961. int guild_id = va_arg(ap, int);
  962. int i;
  963. for(i = 0; i < MAX_GUILDALLIANCE; i++) {
  964. if (g->alliance[i].guild_id == guild_id)
  965. g->alliance[i].guild_id = 0;
  966. }
  967. return 0;
  968. }
  969. // ギルド解散要求
  970. int mapif_parse_BreakGuild(int fd, int guild_id) {
  971. struct guild *g;
  972. g = idb_get(guild_db, guild_id);
  973. if(g == NULL)
  974. return 0;
  975. guild_db->foreach(guild_db, guild_break_sub, guild_id);
  976. inter_guild_storage_delete(guild_id);
  977. mapif_guild_broken(guild_id, 0);
  978. if(log_inter)
  979. inter_log("guild %s (id=%d) broken" RETCODE, g->name, guild_id);
  980. idb_remove(guild_db, guild_id);
  981. return 0;
  982. }
  983. // ギルドメッセージ送信
  984. int mapif_parse_GuildMessage(int fd, int guild_id, int account_id, char *mes, int len) {
  985. return mapif_guild_message(guild_id, account_id, mes, len, fd);
  986. }
  987. // ギルド基本データ変更要求
  988. int mapif_parse_GuildBasicInfoChange(int fd, int guild_id, int type, const char *data, int len) {
  989. struct guild *g;
  990. short dw = *((short *)data);
  991. g = idb_get(guild_db, guild_id);
  992. if (g == NULL)
  993. return 0;
  994. switch(type) {
  995. case GBI_GUILDLV:
  996. if (dw > 0 && g->guild_lv + dw <= 50) {
  997. g->guild_lv+=dw;
  998. g->skill_point+=dw;
  999. } else if (dw < 0 && g->guild_lv + dw >= 1)
  1000. g->guild_lv += dw;
  1001. mapif_guild_info(-1, g);
  1002. return 0;
  1003. default:
  1004. ShowError("int_guild: GuildBasicInfoChange: Unknown type %d\n", type);
  1005. break;
  1006. }
  1007. mapif_guild_basicinfochanged(guild_id, type, data, len);
  1008. return 0;
  1009. }
  1010. // ギルドメンバデータ変更要求
  1011. int mapif_parse_GuildMemberInfoChange(int fd, int guild_id, int account_id, int char_id, int type, const char *data, int len) {
  1012. int i;
  1013. struct guild *g;
  1014. g = idb_get(guild_db, guild_id);
  1015. if(g == NULL)
  1016. return 0;
  1017. for(i = 0; i < g->max_member; i++)
  1018. if (g->member[i].account_id == account_id && g->member[i].char_id == char_id)
  1019. break;
  1020. if (i == g->max_member) {
  1021. ShowWarning("int_guild: GuildMemberChange: Not found %d,%d in %d[%s]\n", account_id, char_id, guild_id, g->name);
  1022. return 0;
  1023. }
  1024. switch(type) {
  1025. case GMI_POSITION: // 役職
  1026. g->member[i].position = *((int *)data);
  1027. break;
  1028. case GMI_EXP: // EXP
  1029. {
  1030. unsigned int exp, old_exp=g->member[i].exp;
  1031. g->member[i].exp=*((unsigned int *)data);
  1032. if (g->member[i].exp > old_exp)
  1033. {
  1034. exp = g->member[i].exp - old_exp;
  1035. if (guild_exp_rate != 100)
  1036. exp = exp*guild_exp_rate/100;
  1037. if (exp > UINT_MAX - g->exp)
  1038. g->exp = UINT_MAX;
  1039. else
  1040. g->exp+=exp;
  1041. guild_calcinfo(g);
  1042. mapif_guild_basicinfochanged(guild_id,GBI_EXP,&g->exp,4);
  1043. }
  1044. break;
  1045. }
  1046. case GMI_HAIR:
  1047. {
  1048. g->member[i].hair=*((int *)data);
  1049. mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len);
  1050. break;
  1051. }
  1052. case GMI_HAIR_COLOR:
  1053. {
  1054. g->member[i].hair_color=*((int *)data);
  1055. mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len);
  1056. break;
  1057. }
  1058. case GMI_GENDER:
  1059. {
  1060. g->member[i].gender=*((int *)data);
  1061. mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len);
  1062. break;
  1063. }
  1064. case GMI_CLASS:
  1065. {
  1066. g->member[i].class_=*((int *)data);
  1067. mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len);
  1068. break;
  1069. }
  1070. case GMI_LEVEL:
  1071. {
  1072. g->member[i].lv=*((int *)data);
  1073. mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len);
  1074. break;
  1075. }
  1076. default:
  1077. ShowError("int_guild: GuildMemberInfoChange: Unknown type %d\n", type);
  1078. break;
  1079. }
  1080. mapif_guild_memberinfochanged(guild_id, account_id, char_id, type, data, len);
  1081. return 0;
  1082. }
  1083. int inter_guild_sex_changed(int guild_id,int account_id,int char_id, int gender)
  1084. {
  1085. return mapif_parse_GuildMemberInfoChange(0, guild_id, account_id, char_id, GMI_GENDER, (const char*)&gender, sizeof(gender));
  1086. }
  1087. // ギルド役職名変更要求
  1088. int mapif_parse_GuildPosition(int fd, int guild_id, int idx, struct guild_position *p) {
  1089. struct guild *g = idb_get(guild_db, guild_id);
  1090. if (g == NULL || idx < 0 || idx >= MAX_GUILDPOSITION) {
  1091. return 0;
  1092. }
  1093. memcpy(&g->position[idx], p, sizeof(struct guild_position));
  1094. mapif_guild_position(g, idx);
  1095. ShowInfo("int_guild: position [%d] changed\n", idx);
  1096. return 0;
  1097. }
  1098. // ギルドスキルアップ要求
  1099. int mapif_parse_GuildSkillUp(int fd, int guild_id, int skill_num, int account_id) {
  1100. struct guild *g = idb_get(guild_db, guild_id);
  1101. int idx = skill_num - GD_SKILLBASE;
  1102. if (g == NULL || idx < 0 || idx >= MAX_GUILDSKILL)
  1103. return 0;
  1104. if (g->skill_point > 0 && g->skill[idx].id > 0 && g->skill[idx].lv < 10) {
  1105. g->skill[idx].lv++;
  1106. g->skill_point--;
  1107. if (guild_calcinfo(g) == 0)
  1108. mapif_guild_info(-1, g);
  1109. mapif_guild_skillupack(guild_id, skill_num, account_id);
  1110. ShowInfo("int_guild: skill %d up\n", skill_num);
  1111. }
  1112. return 0;
  1113. }
  1114. //Manual deletion of an alliance when partnering guild does not exists. [Skotlex]
  1115. static int mapif_parse_GuildDeleteAlliance(struct guild *g, int guild_id, int account_id1, int account_id2, int flag)
  1116. {
  1117. int i;
  1118. char name[NAME_LENGTH];
  1119. for(i=0;i<MAX_GUILDALLIANCE;i++)
  1120. if(g->alliance[i].guild_id == guild_id)
  1121. {
  1122. strcpy(name, g->alliance[i].name);
  1123. g->alliance[i].guild_id=0;
  1124. break;
  1125. }
  1126. if (i == MAX_GUILDALLIANCE)
  1127. return -1;
  1128. mapif_guild_alliance(g->guild_id,guild_id,account_id1,account_id2,flag,g->name,name);
  1129. return 0;
  1130. }
  1131. // ギルド同盟要求
  1132. int mapif_parse_GuildAlliance(int fd, int guild_id1, int guild_id2, int account_id1, int account_id2, int flag) {
  1133. struct guild *g[2];
  1134. int j, i;
  1135. g[0] = idb_get(guild_db, guild_id1);
  1136. g[1] = idb_get(guild_db, guild_id2);
  1137. if(g[0] && g[1]==NULL && (flag&0x8)) //Requested to remove an alliance with a not found guild.
  1138. return mapif_parse_GuildDeleteAlliance(g[0], guild_id2,
  1139. account_id1, account_id2, flag); //Try to do a manual removal of said guild.
  1140. if (g[0] == NULL || g[1] == NULL)
  1141. return 0;
  1142. if (!(flag & 0x8)) {
  1143. for(i = 0; i < 2 - (flag & 1); i++) {
  1144. for(j = 0; j < MAX_GUILDALLIANCE; j++)
  1145. if (g[i]->alliance[j].guild_id == 0) {
  1146. g[i]->alliance[j].guild_id = g[1-i]->guild_id;
  1147. memcpy(g[i]->alliance[j].name, g[1-i]->name, NAME_LENGTH-1);
  1148. g[i]->alliance[j].opposition = flag & 1;
  1149. break;
  1150. }
  1151. }
  1152. } else { // 関係解消
  1153. for(i = 0; i < 2 - (flag & 1); i++) {
  1154. for(j = 0; j < MAX_GUILDALLIANCE; j++)
  1155. if (g[i]->alliance[j].guild_id == g[1-i]->guild_id && g[i]->alliance[j].opposition == (flag & 1)) {
  1156. g[i]->alliance[j].guild_id = 0;
  1157. break;
  1158. }
  1159. }
  1160. }
  1161. mapif_guild_alliance(guild_id1, guild_id2, account_id1, account_id2, flag, g[0]->name, g[1]->name);
  1162. return 0;
  1163. }
  1164. // ギルド告知変更要求
  1165. int mapif_parse_GuildNotice(int fd, int guild_id, const char *mes1, const char *mes2) {
  1166. struct guild *g;
  1167. g = idb_get(guild_db, guild_id);
  1168. if (g == NULL)
  1169. return 0;
  1170. memcpy(g->mes1, mes1, 60);
  1171. memcpy(g->mes2, mes2, 120);
  1172. return mapif_guild_notice(g);
  1173. }
  1174. // ギルドエンブレム変更要求
  1175. int mapif_parse_GuildEmblem(int fd, int len, int guild_id, int dummy, const char *data) {
  1176. struct guild *g;
  1177. g = idb_get(guild_db, guild_id);
  1178. if (g == NULL)
  1179. return 0;
  1180. memcpy(g->emblem_data, data, len);
  1181. g->emblem_len = len;
  1182. g->emblem_id++;
  1183. return mapif_guild_emblem(g);
  1184. }
  1185. int mapif_parse_GuildCastleDataLoad(int fd, int castle_id, int index) {
  1186. struct guild_castle *gc = idb_get(castle_db, castle_id);
  1187. if (gc == NULL) {
  1188. return mapif_guild_castle_dataload(castle_id, 0, 0);
  1189. }
  1190. switch(index) {
  1191. case 1: return mapif_guild_castle_dataload(gc->castle_id, index, gc->guild_id);
  1192. case 2: return mapif_guild_castle_dataload(gc->castle_id, index, gc->economy);
  1193. case 3: return mapif_guild_castle_dataload(gc->castle_id, index, gc->defense);
  1194. case 4: return mapif_guild_castle_dataload(gc->castle_id, index, gc->triggerE);
  1195. case 5: return mapif_guild_castle_dataload(gc->castle_id, index, gc->triggerD);
  1196. case 6: return mapif_guild_castle_dataload(gc->castle_id, index, gc->nextTime);
  1197. case 7: return mapif_guild_castle_dataload(gc->castle_id, index, gc->payTime);
  1198. case 8: return mapif_guild_castle_dataload(gc->castle_id, index, gc->createTime);
  1199. case 9: return mapif_guild_castle_dataload(gc->castle_id, index, gc->visibleC);
  1200. case 10:
  1201. case 11:
  1202. case 12:
  1203. case 13:
  1204. case 14:
  1205. case 15:
  1206. case 16:
  1207. case 17:
  1208. return mapif_guild_castle_dataload(gc->castle_id, index, gc->guardian[index-10].visible);
  1209. case 18:
  1210. case 19:
  1211. case 20:
  1212. case 21:
  1213. case 22:
  1214. case 23:
  1215. case 24:
  1216. case 25:
  1217. return mapif_guild_castle_dataload(gc->castle_id, index, gc->guardian[index-18].hp); // end additions [Valaris]
  1218. default:
  1219. ShowError("mapif_parse_GuildCastleDataLoad ERROR!! (Not found index=%d)\n", index);
  1220. return 0;
  1221. }
  1222. return 0;
  1223. }
  1224. int mapif_parse_GuildCastleDataSave(int fd, int castle_id, int index, int value) {
  1225. struct guild_castle *gc= idb_get(castle_db, castle_id);
  1226. if (gc == NULL) {
  1227. return mapif_guild_castle_datasave(castle_id, index, value);
  1228. }
  1229. switch(index) {
  1230. case 1:
  1231. if (gc->guild_id != value) {
  1232. int gid = (value) ? value : gc->guild_id;
  1233. struct guild *g = idb_get(guild_db, gid);
  1234. if(log_inter)
  1235. inter_log("guild %s (id=%d) %s castle id=%d" RETCODE,
  1236. (g) ? g->name : "??", gid, (value) ? "occupy" : "abandon", castle_id);
  1237. }
  1238. gc->guild_id = value;
  1239. if(gc->guild_id == 0) {
  1240. //Delete guardians.
  1241. memset(&gc->guardian, 0, sizeof(gc->guardian));
  1242. }
  1243. break;
  1244. case 2: gc->economy = value; break;
  1245. case 3: gc->defense = value; break;
  1246. case 4: gc->triggerE = value; break;
  1247. case 5: gc->triggerD = value; break;
  1248. case 6: gc->nextTime = value; break;
  1249. case 7: gc->payTime = value; break;
  1250. case 8: gc->createTime = value; break;
  1251. case 9: gc->visibleC = value; break;
  1252. case 10:
  1253. case 11:
  1254. case 12:
  1255. case 13:
  1256. case 14:
  1257. case 15:
  1258. case 16:
  1259. case 17:
  1260. gc->guardian[index-10].visible = value; break;
  1261. case 18:
  1262. case 19:
  1263. case 20:
  1264. case 21:
  1265. case 22:
  1266. case 23:
  1267. case 24:
  1268. case 25:
  1269. gc->guardian[index-18].hp = value; break; // end additions [Valaris]
  1270. default:
  1271. ShowError("mapif_parse_GuildCastleDataSave ERROR!! (Not found index=%d)\n", index);
  1272. return 0;
  1273. }
  1274. return mapif_guild_castle_datasave(gc->castle_id, index, value);
  1275. }
  1276. // ギルドチェック要求
  1277. int mapif_parse_GuildCheck(int fd, int guild_id, int account_id, int char_id) {
  1278. return guild_check_conflict(guild_id, account_id, char_id);
  1279. }
  1280. int mapif_parse_GuildMasterChange(int fd, int guild_id, const char* name, int len)
  1281. {
  1282. struct guild *g = idb_get(guild_db, guild_id);
  1283. struct guild_member gm;
  1284. int pos;
  1285. if(g==NULL || g->guild_id<=0 || len > NAME_LENGTH)
  1286. return 0;
  1287. for (pos = 0; pos < g->max_member && strncmp(g->member[pos].name, name, len); pos++);
  1288. if (pos == g->max_member)
  1289. return 0; //Character not found??
  1290. memcpy(&gm, &g->member[pos], sizeof (struct guild_member));
  1291. memcpy(&g->member[pos], &g->member[0], sizeof(struct guild_member));
  1292. memcpy(&g->member[0], &gm, sizeof(struct guild_member));
  1293. g->member[pos].position = g->member[0].position;
  1294. g->member[0].position = 0; //Position 0: guild Master.
  1295. strncpy(g->master, name, len);
  1296. if (len < NAME_LENGTH)
  1297. g->master[len] = '\0';
  1298. ShowInfo("int_guild: Guildmaster Changed to %s (Guild %d - %s)\n",name, guild_id, g->name);
  1299. return mapif_guild_master_changed(g, pos);
  1300. }
  1301. // map server からの通信
  1302. // ・1パケットのみ解析すること
  1303. // ・パケット長データはinter.cにセットしておくこと
  1304. // ・パケット長チェックや、RFIFOSKIPは呼び出し元で行われるので行ってはならない
  1305. // ・エラーなら0(false)、そうでないなら1(true)をかえさなければならない
  1306. int inter_guild_parse_frommap(int fd) {
  1307. RFIFOHEAD(fd);
  1308. switch(RFIFOW(fd,0)) {
  1309. case 0x3030: mapif_parse_CreateGuild(fd, RFIFOL(fd,4), (char*)RFIFOP(fd,8), (struct guild_member *)RFIFOP(fd,32)); break;
  1310. case 0x3031: mapif_parse_GuildInfo(fd, RFIFOL(fd,2)); break;
  1311. case 0x3032: mapif_parse_GuildAddMember(fd, RFIFOL(fd,4), (struct guild_member *)RFIFOP(fd,8)); break;
  1312. case 0x3033: mapif_parse_GuildMasterChange(fd,RFIFOL(fd,4),(const char*)RFIFOP(fd,8),RFIFOW(fd,2)-8); break;
  1313. case 0x3034: mapif_parse_GuildLeave(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOB(fd,14), (const char*)RFIFOP(fd,15)); break;
  1314. case 0x3035: mapif_parse_GuildChangeMemberInfoShort(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOB(fd,14), RFIFOW(fd,15), RFIFOW(fd,17)); break;
  1315. case 0x3036: mapif_parse_BreakGuild(fd, RFIFOL(fd,2)); break;
  1316. case 0x3037: mapif_parse_GuildMessage(fd, RFIFOL(fd,4), RFIFOL(fd,8), (char*)RFIFOP(fd,12), RFIFOW(fd,2)-12); break;
  1317. case 0x3038: mapif_parse_GuildMasterChange(fd,RFIFOL(fd,4),(const char*)RFIFOP(fd,8),RFIFOW(fd,2)-8); break;
  1318. case 0x3039: mapif_parse_GuildBasicInfoChange(fd, RFIFOL(fd,4), RFIFOW(fd,8), (const char*)RFIFOP(fd,10), RFIFOW(fd,2)-10); break;
  1319. case 0x303A: mapif_parse_GuildMemberInfoChange(fd, RFIFOL(fd,4), RFIFOL(fd,8), RFIFOL(fd,12), RFIFOW(fd,16), (const char*)RFIFOP(fd,18), RFIFOW(fd,2)-18); break;
  1320. case 0x303B: mapif_parse_GuildPosition(fd, RFIFOL(fd,4), RFIFOL(fd,8), (struct guild_position *)RFIFOP(fd,12)); break;
  1321. case 0x303C: mapif_parse_GuildSkillUp(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10)); break;
  1322. case 0x303D: mapif_parse_GuildAlliance(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOL(fd,14), RFIFOB(fd,18)); break;
  1323. case 0x303E: mapif_parse_GuildNotice(fd, RFIFOL(fd,2), (const char*)RFIFOP(fd,6), (const char*)RFIFOP(fd,66)); break;
  1324. case 0x303F: mapif_parse_GuildEmblem(fd, RFIFOW(fd,2)-12, RFIFOL(fd,4), RFIFOL(fd,8), (const char*)RFIFOP(fd,12)); break;
  1325. case 0x3040: mapif_parse_GuildCastleDataLoad(fd, RFIFOW(fd,2), RFIFOB(fd,4)); break;
  1326. case 0x3041: mapif_parse_GuildCastleDataSave(fd, RFIFOW(fd,2), RFIFOB(fd,4), RFIFOL(fd,5)); break;
  1327. default:
  1328. return 0;
  1329. }
  1330. return 1;
  1331. }
  1332. // マップサーバーの接続時処理
  1333. int inter_guild_mapif_init(int fd) {
  1334. return mapif_guild_castle_alldataload(fd);
  1335. }
  1336. // サーバーから脱退要求(キャラ削除用)
  1337. int inter_guild_leave(int guild_id, int account_id, int char_id) {
  1338. return mapif_parse_GuildLeave(-1, guild_id, account_id, char_id, 0, "** Character Deleted **");
  1339. }