GuildDB.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615
  1. /*
  2. EQ2Emulator: Everquest II Server Emulator
  3. Copyright (C) 2007 EQ2EMulator Development Team (http://www.eq2emulator.net)
  4. This file is part of EQ2Emulator.
  5. EQ2Emulator is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9. EQ2Emulator is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with EQ2Emulator. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #ifdef WIN32
  17. #include <WinSock2.h>
  18. #include <windows.h>
  19. #endif
  20. #include <math.h>
  21. #include <iostream>
  22. #include <sstream>
  23. #include <iomanip>
  24. #include <ios>
  25. #include <mysql.h>
  26. #include <assert.h>
  27. #include "../../common/Log.h"
  28. #include "../WorldDatabase.h"
  29. #include "Guild.h"
  30. extern GuildList guild_list;
  31. extern RuleManager rule_manager;
  32. void WorldDatabase::LoadGuilds() {
  33. int32 num_guilds = 0;
  34. Query query;
  35. MYSQL_ROW row;
  36. MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT `id`, `name`, `motd`, `level`, `xp`, `xp_needed`, `formed_on` FROM `guilds`");
  37. while (result && (row = mysql_fetch_row(result))) {
  38. LogWrite(GUILD__DEBUG, 1, "Guilds", "%u. %s", atoul(row[0]), row[1]);
  39. Guild* guild = new Guild;
  40. guild->SetID(atoul(row[0]));
  41. guild->SetName(row[1]);
  42. if (row[2])
  43. guild->SetMOTD(row[2], false);
  44. guild->SetLevel(atoi(row[3]), false);
  45. guild->SetEXPCurrent(atoul(row[4]), false);
  46. guild->SetEXPToNextLevel(atoul(row[5]), false);
  47. guild->SetFormedDate(atoul(row[6]));
  48. LogWrite(GUILD__DEBUG, 3, "Guilds", "\tLoaded %i guild members.", LoadGuildMembers(guild));
  49. LogWrite(GUILD__DEBUG, 3, "Guilds", "\tLoading Guild Ranks...");
  50. LoadGuildRanks(guild);
  51. LogWrite(GUILD__DEBUG, 3, "Guilds", "\tLoading Guild Event Filters...");
  52. LoadGuildEventFilters(guild);
  53. LogWrite(GUILD__DEBUG, 3, "Guilds", "\tLoading Guild Events...");
  54. LoadGuildEvents(guild);
  55. LogWrite(GUILD__DEBUG, 3, "Guilds", "\tLoading Guild Recruiting...");
  56. LoadGuildRecruiting(guild);
  57. guild_list.AddGuild(guild);
  58. num_guilds++;
  59. }
  60. LogWrite(GUILD__INFO, 0, "Guilds", "\tLoaded %u Guild(s)", num_guilds);
  61. }
  62. void WorldDatabase::LoadGuild(int32 guild_id) {
  63. Query query;
  64. MYSQL_ROW row;
  65. Guild* tmpGuild = guild_list.GetGuild(guild_id);
  66. if(tmpGuild) // already loaded
  67. return;
  68. MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT `id`, `name`, `motd`, `level`, `xp`, `xp_needed`, `formed_on` FROM `guilds` where id=%u", guild_id);
  69. if (result && (row = mysql_fetch_row(result))) {
  70. LogWrite(GUILD__DEBUG, 1, "Guilds", "%u. %s", atoul(row[0]), row[1]);
  71. Guild* guild = new Guild;
  72. guild->SetID(atoul(row[0]));
  73. guild->SetName(row[1]);
  74. if (row[2])
  75. guild->SetMOTD(row[2], false);
  76. guild->SetLevel(atoi(row[3]), false);
  77. guild->SetEXPCurrent(atoul(row[4]), false);
  78. guild->SetEXPToNextLevel(atoul(row[5]), false);
  79. guild->SetFormedDate(atoul(row[6]));
  80. LogWrite(GUILD__DEBUG, 3, "Guilds", "\tLoaded %i guild members.", LoadGuildMembers(guild));
  81. LogWrite(GUILD__DEBUG, 3, "Guilds", "\tLoading Guild Ranks...");
  82. LoadGuildRanks(guild);
  83. LogWrite(GUILD__DEBUG, 3, "Guilds", "\tLoading Guild Event Filters...");
  84. LoadGuildEventFilters(guild);
  85. LogWrite(GUILD__DEBUG, 3, "Guilds", "\tLoading Guild Events...");
  86. LoadGuildEvents(guild);
  87. LogWrite(GUILD__DEBUG, 3, "Guilds", "\tLoading Guild Recruiting...");
  88. LoadGuildRecruiting(guild);
  89. guild_list.AddGuild(guild);
  90. }
  91. }
  92. int32 WorldDatabase::LoadGuildMembers(Guild* guild) {
  93. int32 num_members = 0;
  94. Query query;
  95. MYSQL_ROW row;
  96. char *name;
  97. int32 char_id;
  98. MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT `char_id`, `recruiter_id`, `guild_status`, `points`, `rank_id`, `member_flags`, `join_date`, `note`, `officer_note`, `recruiting_message`, `recruiter_picture_data` FROM `guild_members` WHERE `guild_id`=%u", guild->GetID());
  99. while (result && (row = mysql_fetch_row(result))) {
  100. char_id = atoul(row[0]);
  101. if (!(name = GetCharacterName(char_id))) {
  102. LogWrite(GUILD__ERROR, 0, "Guilds", "WorldDatabase::LoadGuildMembers Cannot find guild member with character id %u.", char_id);
  103. continue;
  104. }
  105. GuildMember* gm = new GuildMember;
  106. gm->character_id = char_id;
  107. gm->recruiter_id = atoul(row[1]);
  108. gm->guild_status = atoul(row[2]);
  109. gm->points = atof(row[3]);
  110. gm->rank = atoi(row[4]);
  111. gm->member_flags = atoi(row[5]);
  112. gm->join_date = atoul(row[6]);
  113. if (row[7])
  114. gm->note = string(row[7]);
  115. if (row[8])
  116. gm->officer_note = string(row[8]);
  117. if (row[9])
  118. gm->recruiter_description = string(row[9]);
  119. int16 recruiter_picture_data_size = 0;
  120. if (row[10] && (recruiter_picture_data_size = strlen(row[10])) > 0) {
  121. gm->recruiter_picture_data_size = recruiter_picture_data_size / 2;
  122. gm->recruiter_picture_data = new unsigned char[gm->recruiter_picture_data_size];
  123. unsigned char* cpy = gm->recruiter_picture_data;
  124. const char* str = row[10];
  125. char high, low;
  126. for (const char* ptr = str; *ptr; ptr += 2) {
  127. high = tolower(*ptr);
  128. low = tolower(*(ptr+1));
  129. if (isdigit(high))
  130. high = high - '0';
  131. else if (high >= 'a' && high <= 'f')
  132. high = (high - 'a') + 10;
  133. else {
  134. LogWrite(GUILD__ERROR, 0, "Guilds", "Guild mate with id %u has corrupt picture data. Data not loading.", gm->character_id);
  135. safe_delete_array(gm->recruiter_picture_data);
  136. gm->recruiter_picture_data_size = 0;
  137. break;
  138. }
  139. if (isdigit(low))
  140. low = low - '0';
  141. else if (low >= 'a' && low <= 'f')
  142. low = (low - 'a') + 10;
  143. else {
  144. LogWrite(GUILD__ERROR, 0, "Guilds", "Guild mate with id %u has corrupt picture data. Data not loading.", gm->character_id);
  145. safe_delete_array(gm->recruiter_picture_data);
  146. gm->recruiter_picture_data_size = 0;
  147. break;
  148. }
  149. *cpy++ = low | (high << 4);
  150. }
  151. /*for (int16 i = 0; i < gm->recruiter_picture_data_size; i++)
  152. if (i<10)
  153. printf("int:%u hex:%x\n", gm->recruiter_picture_data[i], gm->recruiter_picture_data[i]);*/
  154. }
  155. else {
  156. gm->recruiter_picture_data_size = 0;
  157. gm->recruiter_picture_data = 0;
  158. }
  159. strncpy(gm->name, name, sizeof(gm->name));
  160. gm->account_id = GetCharacterAccountID(char_id);
  161. gm->adventure_class = GetCharacterClass(char_id);
  162. gm->adventure_level = GetCharacterLevel(char_id);
  163. gm->tradeskill_class = 0;
  164. gm->tradeskill_level = 0;
  165. gm->last_login_date = GetCharacterTimeStamp(char_id);
  166. gm->zone = GetZoneDescription(GetCharacterCurrentZoneID(char_id));
  167. gm->recruiting_show_adventure_class = 1;
  168. LoadGuildPointsHistory(guild, gm);
  169. guild->AddGuildMember(gm);
  170. safe_delete_array(name);
  171. num_members++;
  172. }
  173. return num_members;
  174. }
  175. void WorldDatabase::LoadGuildEvents(Guild* guild) {
  176. if (guild) {
  177. Query query;
  178. MYSQL_ROW row;
  179. MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT `event_id`, `event_date`, `event_type`, `description`, `locked` FROM `guild_events` WHERE `guild_id`=%u AND `display`=1 AND `archived`=0 ORDER BY `event_date` DESC LIMIT 0, %u", guild->GetID(), GUILD_MAX_EVENTS);
  180. while (result && (row = mysql_fetch_row(result)))
  181. guild->AddGuildEvent(atoi64(row[0]), atoul(row[2]), row[3], atoul(row[1]), atoi(row[4]));
  182. }
  183. }
  184. void WorldDatabase::LoadGuildRanks(Guild* guild) {
  185. if (guild) {
  186. LogWrite(GUILD__DEBUG, 3, "Guilds", "Loading Ranks for guild id: %u", guild->GetID());
  187. Query query;
  188. MYSQL_ROW row;
  189. MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT `rank_id`, `rank_name`, `permission1`, `permission2` FROM `guild_ranks` WHERE `guild_id`=%u", guild->GetID());
  190. while (result && (row = mysql_fetch_row(result))) {
  191. int8 rank_id = atoi(row[0]);
  192. int32 permission1 = atoul(row[2]);
  193. int32 permission2 = atoul(row[3]);
  194. guild->SetRankName(rank_id, row[1], false);
  195. LogWrite(GUILD__DEBUG, 5, "Guilds", "\tLoading rank_id: %i", rank_id);
  196. LogWrite(GUILD__DEBUG, 5, "Guilds", "\tPermission1: %ul, Permission2: %ul", permission1, permission2);
  197. for (int32 i = 0; i <= 44; i++) {
  198. int32 bitwise_val;
  199. if (i < 32) {
  200. bitwise_val = (int32)pow(2.0, (double)(i));
  201. guild->SetPermission(rank_id, i, permission1 & bitwise_val ? 1 : 0, false);
  202. LogWrite(GUILD__DEBUG, 5, "Guilds", "\tSetting Permission %u to %u", i, permission1 & bitwise_val ? 1 : 0);
  203. }
  204. else {
  205. bitwise_val = (int32)pow(2.0, (double)(i - 32));
  206. guild->SetPermission(rank_id, i, permission2 & bitwise_val ? 1 : 0, false);
  207. LogWrite(GUILD__DEBUG, 5, "Guilds", "\tSetting Permission %u to %u", i, permission2 & bitwise_val ? 1 : 0);
  208. }
  209. }
  210. }
  211. }
  212. }
  213. void WorldDatabase::LoadGuildEventFilters(Guild* guild) {
  214. if (guild) {
  215. Query query;
  216. MYSQL_ROW row;
  217. bool event_filter_added = false;
  218. MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT `event_id`, `retain`, `broadcast` FROM `guild_event_filters` WHERE `guild_id`=%u", guild->GetID());
  219. while (result && (row = mysql_fetch_row(result))) {
  220. guild->SetEventFilter(atoi(row[0]), GUILD_EVENT_FILTER_CATEGORY_RETAIN_HISTORY, atoi(row[1]), false);
  221. guild->SetEventFilter(atoi(row[0]), GUILD_EVENT_FILTER_CATEGORY_BROADCAST, atoi(row[2]), false);
  222. if (!event_filter_added)
  223. event_filter_added = true;
  224. }
  225. if (!event_filter_added)
  226. LoadGuildDefaultEventFilters(guild);
  227. }
  228. }
  229. void WorldDatabase::LoadGuildPointsHistory(Guild* guild, GuildMember* guild_member) {
  230. Query query;
  231. MYSQL_ROW row;
  232. MYSQL_RES* result;
  233. assert(guild);
  234. assert(guild_member);
  235. result = query.RunQuery2(Q_SELECT, "SELECT `points_date`, `modified_by`, `comment`, `points` FROM `guild_points_history` WHERE `guild_id`=%u AND `char_id`=%u ORDER BY `points_date` DESC", guild->GetID(), guild_member->character_id);
  236. while (result && (row = mysql_fetch_row(result)))
  237. guild->AddPointHistory(guild_member, atoul(row[0]), row[1], atof(row[3]), row[2], false);
  238. }
  239. void WorldDatabase::LoadGuildRecruiting(Guild* guild) {
  240. if (guild) {
  241. Query query;
  242. MYSQL_ROW row;
  243. MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT `short_desc`, `full_desc`, `min_level`, `play_style`, `looking_for`, `descriptive_tag1`, `descriptive_tag2`, `descriptive_tag3`, `descriptive_tag4` FROM `guild_recruiting` WHERE `guild_id`=%u", guild->GetID());
  244. while (result && (row = mysql_fetch_row(result))) {
  245. if (row[0])
  246. guild->SetRecruitingShortDesc(row[0], false);
  247. if (row[1])
  248. guild->SetRecruitingFullDesc(row[1], false);
  249. guild->SetRecruitingMinLevel(atoi(row[2]), false);
  250. guild->SetRecruitingPlayStyle(atoi(row[3]), false);
  251. for (int32 i = 0; i <= 5; i++) {
  252. int32 bitwise_val = (int32)pow(2.0, (double)i);
  253. guild->SetRecruitingFlag(i, atoi(row[4]) & bitwise_val ? 1 : 0, false);
  254. }
  255. guild->SetRecruitingDescTag(0, atoi(row[5]), false);
  256. guild->SetRecruitingDescTag(1, atoi(row[6]), false);
  257. guild->SetRecruitingDescTag(2, atoi(row[7]), false);
  258. guild->SetRecruitingDescTag(3, atoi(row[8]), false);
  259. }
  260. }
  261. }
  262. void WorldDatabase::SaveGuild(Guild* guild, bool new_guild) {
  263. Query query;
  264. assert(guild);
  265. if (new_guild) {
  266. LogWrite(GUILD__DEBUG, 3, "Guilds", "Saving NEW Guild '%s' (%u) data...", guild->GetName(), guild->GetID());
  267. query.RunQuery2(Q_INSERT, "INSERT INTO `guilds` (`name`, `motd`, `level`, `xp`, `xp_needed`, `formed_on`) "
  268. "VALUES ('%s', '%s', %i, %llu, %llu, %u)",
  269. getSafeEscapeString(guild->GetName()).c_str(), getSafeEscapeString(guild->GetMOTD()).c_str(), guild->GetLevel(), guild->GetEXPCurrent(), guild->GetEXPToNextLevel(), guild->GetFormedDate());
  270. guild->SetID(query.GetLastInsertedID());
  271. }
  272. else {
  273. LogWrite(GUILD__DEBUG, 3, "Guilds", "Saving Guild '%s' (%u) data...", guild->GetName(), guild->GetID());
  274. query.RunQuery2(Q_UPDATE, "UPDATE `guilds` "
  275. "SET `name`='%s', `motd`='%s', `level`=%i, `xp`=%llu, `xp_needed`=%llu, `formed_on`=%u WHERE `id`=%u",
  276. getSafeEscapeString(guild->GetName()).c_str(), getSafeEscapeString(guild->GetMOTD()).c_str(), guild->GetLevel(), guild->GetEXPCurrent(), guild->GetEXPToNextLevel(), guild->GetFormedDate(), guild->GetID());
  277. }
  278. guild->SetSaveNeeded(false);
  279. }
  280. void WorldDatabase::SaveGuildMembers(Guild* guild) {
  281. map<int32, GuildMember *>* members;
  282. map<int32, GuildMember *>::iterator itr;
  283. Mutex *mMembers;
  284. GuildMember *gm;
  285. Query query, query2;
  286. assert(guild);
  287. members = guild->GetGuildMembers();
  288. mMembers = guild->GetGuildMembersMutex();
  289. mMembers->readlock(__FUNCTION__, __LINE__);
  290. for (itr = members->begin(); itr != members->end(); itr++) {
  291. gm = itr->second;
  292. LogWrite(GUILD__DEBUG, 5, "Guilds", "Saving Guild Member '%s' (%u) data...", gm->name, gm->character_id);
  293. query.RunQuery2(Q_INSERT, "INSERT INTO `guild_members` (`guild_id`, `char_id`, `recruiter_id`, `guild_status`, `points`, `rank_id`, `member_flags`, `join_date`, `note`, `officer_note`, `recruiting_message`, `recruiter_picture_data`) VALUES (%u, %u, %u, %u, %f, %u, %u, %u, '%s', '%s', '%s', NULL) ON DUPLICATE KEY UPDATE `guild_id`=%u, `recruiter_id`=%u, `guild_status`=%u, `points`=%f, `rank_id`=%u, `member_flags`=%u, `join_date`=%u, `note`='%s', `officer_note`='%s', `recruiting_message`='%s', `recruiter_picture_data`=NULL", guild->GetID(), gm->character_id, gm->recruiter_id, gm->guild_status, gm->points, gm->rank, gm->member_flags, gm->join_date, getSafeEscapeString(gm->note.c_str()).c_str(), getSafeEscapeString(gm->officer_note.c_str()).c_str(), getSafeEscapeString(gm->recruiter_description.c_str()).c_str(), guild->GetID(), gm->recruiter_id, gm->guild_status, gm->points, gm->rank, gm->member_flags, gm->join_date, getSafeEscapeString(gm->note.c_str()).c_str(), getSafeEscapeString(gm->officer_note.c_str()).c_str(), getSafeEscapeString(gm->recruiter_description.c_str()).c_str());
  294. if (gm && gm->recruiter_picture_data_size > 0 && gm->recruiter_picture_data) {
  295. stringstream ss_hex;
  296. stringstream ss_query;
  297. ss_hex.flags(ios::hex);
  298. for (int16 i = 0; i < gm->recruiter_picture_data_size; i++)
  299. ss_hex << setfill('0') << setw(2) << (int)gm->recruiter_picture_data[i];
  300. ss_query << "UPDATE `guild_members` SET `recruiter_picture_data`='" << ss_hex.str() << "' WHERE `char_id`=" << gm->character_id;
  301. query2.RunQuery2(ss_query.str(), Q_UPDATE);
  302. }
  303. }
  304. guild->SetMemberSaveNeeded(false);
  305. mMembers->releasereadlock(__FUNCTION__, __LINE__);
  306. }
  307. void WorldDatabase::SaveGuildEvents(Guild* guild) {
  308. if (guild) {
  309. deque<GuildEvent*>* guild_events = guild->GetGuildEvents();
  310. deque<GuildEvent*>::iterator itr;
  311. for (itr = guild_events->begin(); itr != guild_events->end(); itr++) {
  312. GuildEvent* ge = *itr;
  313. if (!ge->save_needed)
  314. continue;
  315. LogWrite(GUILD__DEBUG, 5, "Guilds", "Saving Guild Events for guild '%s' (%u)...", guild->GetName(), guild->GetID());
  316. Query query;
  317. query.RunQuery2(Q_INSERT, "INSERT INTO `guild_events` (`guild_id`, `event_id`, `event_date`, `event_type`, `description`, `display`, `locked`, `archived`) "
  318. "VALUES (%u, %llu, %u, %u, '%s', 1, %u, 0) "
  319. "ON DUPLICATE KEY UPDATE `locked`=%i",
  320. guild->GetID(), ge->event_id, ge->date, ge->type, getSafeEscapeString(ge->description.c_str()).c_str(), ge->locked, ge->locked);
  321. ge->save_needed = false;
  322. }
  323. guild->SetEventsSaveNeeded(false);
  324. }
  325. }
  326. void WorldDatabase::SaveGuildRanks(Guild* guild) {
  327. if (guild) {
  328. MutexMap<int8, MutexMap<int8, int8>*>* permissions = guild->GetPermissions();
  329. MutexMap<int8, string>* ranks = guild->GetGuildRanks();
  330. MutexMap<int8, string>::iterator ranks_itr = ranks->begin();
  331. while (ranks_itr.Next()) {
  332. int32 permission1 = 0;
  333. int32 permission2 = 0;
  334. for (int32 i = 0; i <= 44; i++) {
  335. if (permissions->count(ranks_itr.first) > 0 && permissions->Get(ranks_itr.first)->count(i) > 0 && permissions->Get(ranks_itr.first)->Get(i)) {
  336. if (i < 32)
  337. permission1 += (int32)pow(2.0, (double)i);
  338. else
  339. permission2 += (int32)pow(2.0, (double)(i - 32));
  340. }
  341. }
  342. LogWrite(GUILD__DEBUG, 5, "Guilds", "Saving Guild Ranks for guild '%s' (%u)...", guild->GetName(), guild->GetID());
  343. Query query;
  344. query.RunQuery2(Q_INSERT, "INSERT INTO `guild_ranks` (`guild_id`, `rank_id`, `rank_name`, `permission1`, `permission2`) "
  345. "VALUES (%u, %u, '%s', %u, %u) "
  346. "ON DUPLICATE KEY UPDATE `rank_name`='%s', `permission1`=%u, permission2=%u",
  347. guild->GetID(), ranks_itr.first, getSafeEscapeString(ranks_itr.second.c_str()).c_str(), permission1, permission2, getSafeEscapeString(ranks_itr.second.c_str()).c_str(), permission1, permission2);
  348. }
  349. guild->SetRanksSaveNeeded(false);
  350. }
  351. }
  352. void WorldDatabase::SaveGuildEventFilters(Guild* guild) {
  353. int32 i;
  354. assert(guild);
  355. for (i = 0; i < 93; i++) {
  356. LogWrite(GUILD__DEBUG, 5, "Guilds", "Saving Guild EventFilters for guild '%s' (%u)...", guild->GetName(), guild->GetID());
  357. Query query;
  358. query.RunQuery2(Q_INSERT, "INSERT INTO `guild_event_filters` (`guild_id`, `event_id`, `retain`, `broadcast`) "
  359. "VALUES (%u, %u, %u, %u) "
  360. "ON DUPLICATE KEY UPDATE `retain`=%u, `broadcast`=%u",
  361. guild->GetID(), i, guild->GetEventFilter(i, GUILD_EVENT_FILTER_CATEGORY_RETAIN_HISTORY), guild->GetEventFilter(i, GUILD_EVENT_FILTER_CATEGORY_BROADCAST), guild->GetEventFilter(i, GUILD_EVENT_FILTER_CATEGORY_RETAIN_HISTORY), guild->GetEventFilter(i, GUILD_EVENT_FILTER_CATEGORY_BROADCAST));
  362. }
  363. guild->SetEventFiltersSaveNeeded(false);
  364. }
  365. void WorldDatabase::SaveGuildPointsHistory(Guild* guild) {
  366. map<int32, GuildMember *> *members;
  367. map<int32, GuildMember *>::iterator itr;
  368. Mutex *mMembers;
  369. deque<PointHistory *> *ph_list;
  370. deque<PointHistory*>::iterator ph_itr;
  371. PointHistory* ph;
  372. assert (guild);
  373. members = guild->GetGuildMembers();
  374. mMembers = guild->GetGuildMembersMutex();
  375. mMembers->readlock(__FUNCTION__, __LINE__);
  376. for (itr = members->begin(); itr != members->end(); itr++) {
  377. ph_list = &itr->second->point_history;
  378. for (ph_itr = ph_list->begin(); ph_itr != ph_list->end(); ph_itr++) {
  379. ph = *ph_itr;
  380. if (!ph->saved_needed)
  381. continue;
  382. LogWrite(GUILD__DEBUG, 5, "Guilds", "Saving Guild Point History for guild '%s' (%u)...", guild->GetName(), guild->GetID());
  383. Query query;
  384. query.RunQuery2(Q_INSERT, "INSERT INTO `guild_points_history` (`guild_id`, `char_id`, `points_date`, `modified_by`, `comment`, `points`) "
  385. "VALUES (%u, %u, %u, '%s', '%s', %f)",
  386. guild->GetID(), itr->first, ph->date, getSafeEscapeString(ph->modified_by.c_str()).c_str(), getSafeEscapeString(ph->comment.c_str()).c_str(), ph->points);
  387. ph->saved_needed = false;
  388. }
  389. }
  390. guild->SetPointsHistorySaveNeeded(false);
  391. mMembers->releasereadlock(__FUNCTION__, __LINE__);
  392. }
  393. void WorldDatabase::SaveGuildRecruiting(Guild* guild) {
  394. if (guild) {
  395. LogWrite(GUILD__DEBUG, 3, "Guilds", "Saving Recruiting info for guild '%s' (%u)...", guild->GetName(), guild->GetID());
  396. Query query;
  397. query.RunQuery2(Q_INSERT, "INSERT INTO `guild_recruiting` (`guild_id`, `short_desc`, `full_desc`, `min_level`, `play_style`, `looking_for`, `descriptive_tag1`, `descriptive_tag2`, `descriptive_tag3`, `descriptive_tag4`) VALUES (%u, '%s', '%s', %u, %u, %u, %u, %u, %u, %u) ON DUPLICATE KEY UPDATE `short_desc`='%s', `full_desc`='%s', `min_level`=%u, `play_style`=%u, `looking_for`=%u, `descriptive_tag1`=%u, `descriptive_tag2`=%u, `descriptive_tag3`=%u, `descriptive_tag4`=%u", guild->GetID(), getSafeEscapeString(guild->GetRecruitingShortDesc().c_str()).c_str(), getSafeEscapeString(guild->GetRecruitingFullDesc().c_str()).c_str(), guild->GetRecruitingMinLevel(), guild->GetRecruitingPlayStyle(), guild->GetRecruitingLookingForPacketValue(), guild->GetRecruitingDescTag(0), guild->GetRecruitingDescTag(1), guild->GetRecruitingDescTag(2), guild->GetRecruitingDescTag(3), getSafeEscapeString(guild->GetRecruitingShortDesc().c_str()).c_str(), getSafeEscapeString(guild->GetRecruitingFullDesc().c_str()).c_str(), guild->GetRecruitingMinLevel(), guild->GetRecruitingPlayStyle(), guild->GetRecruitingLookingForPacketValue(), guild->GetRecruitingDescTag(0), guild->GetRecruitingDescTag(1), guild->GetRecruitingDescTag(2), guild->GetRecruitingDescTag(3));
  398. guild->SetRecruitingSaveNeeded(false);
  399. }
  400. }
  401. void WorldDatabase::DeleteGuild(Guild* guild) {
  402. if (guild) {
  403. LogWrite(GUILD__DEBUG, 3, "Guilds", "Deleting Guild '%s' (%u)...", guild->GetName(), guild->GetID());
  404. Query query;
  405. query.RunQuery2(Q_DELETE, "DELETE FROM `guilds` WHERE `id`=%u", guild->GetID());
  406. }
  407. }
  408. void WorldDatabase::DeleteGuildMember(Guild* guild, int32 character_id) {
  409. if (guild) {
  410. LogWrite(GUILD__DEBUG, 3, "Guilds", "Deleting Character (%u) from guild '%s' (%u)...", character_id, guild->GetName(), guild->GetID());
  411. Query query;
  412. query.RunQuery2(Q_DELETE, "DELETE FROM `guild_members` WHERE `guild_id`=%u AND `char_id`=%u", guild->GetID(), character_id);
  413. }
  414. }
  415. void WorldDatabase::DeleteGuildEvent(Guild* guild, int64 event_id) {
  416. if (guild) {
  417. LogWrite(GUILD__DEBUG, 3, "Guilds", "Deleting Event (%u) from guild '%s' (%u)...", event_id, guild->GetName(), guild->GetID());
  418. Query query;
  419. query.RunQuery2(Q_DELETE, "DELETE FROM `guild_events` WHERE `guild_id`=%u AND `event_id`=%u", guild->GetID(), event_id);
  420. }
  421. }
  422. void WorldDatabase::DeleteGuildPointHistory(Guild* guild, int32 character_id, PointHistory* point_history) {
  423. if (guild && point_history) {
  424. LogWrite(GUILD__DEBUG, 3, "Guilds", "Deleting PointHistory for Character (%u) from guild '%s' (%u)...", character_id, guild->GetName(), guild->GetID());
  425. Query query;
  426. query.RunQuery2(Q_DELETE, "DELETE FROM `guild_points_history` WHERE `guild_id`=%u AND `char_id`=%u AND `points_date`=%u", guild->GetID(), character_id, point_history->date);
  427. }
  428. }
  429. void WorldDatabase::ArchiveGuildEvent(Guild* guild, GuildEvent* guild_event) {
  430. if (guild && guild_event) {
  431. LogWrite(GUILD__DEBUG, 3, "Guilds", "Archiving Event (%u) for guild '%s' (%u)...", guild_event->event_id, guild->GetName(), guild->GetID());
  432. Query query;
  433. query.RunQuery2(Q_UPDATE, "UPDATE `guild_events` SET `archived`=1 WHERE `guild_id`=%u AND `event_id`=%u", guild->GetID(), guild_event->event_id);
  434. }
  435. }
  436. void WorldDatabase::SaveHiddenGuildEvent(Guild* guild, GuildEvent* guild_event) {
  437. if (guild && guild_event) {
  438. LogWrite(GUILD__DEBUG, 3, "Guilds", "Saving Hidden Event (%u) for guild '%s' (%u)...", guild_event->event_id, guild->GetName(), guild->GetID());
  439. Query query;
  440. query.RunQuery2(Q_INSERT, "INSERT INTO `guild_events` (`guild_id`, `event_id`, `event_date`, `event_type`, `description`, `display`, `locked`, `archived`) VALUES (%u, %u, %u, %u, '%s', 0, %u, 0)", guild->GetID(), guild_event->event_id, guild_event->type, guild_event->date, getSafeEscapeString(guild_event->description.c_str()).c_str(), guild_event->locked);
  441. }
  442. }
  443. int32 WorldDatabase::GetGuildIDByCharacterID(int32 char_id) {
  444. if(char_id > 0)
  445. {
  446. LogWrite(GUILD__DEBUG, 3, "Guilds", "Look up guild ID for player ID: '%u'...", char_id);
  447. Query query;
  448. MYSQL_ROW row;
  449. MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT name FROM guilds, guild_members WHERE guilds.id = guild_members.guild_id AND char_id = %u ", char_id);
  450. while (result && (row = mysql_fetch_row(result))) {
  451. if( row[0] )
  452. return atoul(row[0]);
  453. }
  454. }
  455. return 0;
  456. }
  457. void WorldDatabase::LoadGuildDefaultRanks(Guild* guild) {
  458. if (guild) {
  459. LogWrite(GUILD__DEBUG, 3, "Guilds", "Load/Set Default Ranks for guild '%s' (%u)...", guild->GetName(), guild->GetID());
  460. Query query;
  461. MYSQL_ROW row;
  462. MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT DISTINCT `rank_id`, `rank_name`, `permission1`, `permission2` FROM `guild_ranks_defaults`");
  463. while (result && (row = mysql_fetch_row(result))) {
  464. int8 rank_id = atoi(row[0]);
  465. int32 permission1 = atoul(row[2]);
  466. int32 permission2 = atoul(row[3]);
  467. LogWrite(GUILD__DEBUG, 3, "Guilds", "\tSetting RankID %i, permission1: %u, permission2: %u", rank_id, permission1, permission2);
  468. guild->SetRankName(rank_id, row[1], false);
  469. for (int32 i = 0; i <= 44; i++) {
  470. int32 bitwise_val;
  471. if (i < 32) {
  472. bitwise_val = (int32)pow(2.0, (double)i);
  473. guild->SetPermission(rank_id, i, permission1 & bitwise_val ? 1 : 0, false);
  474. }
  475. else {
  476. bitwise_val = (int32)pow(2.0, (double)(i - 32));
  477. guild->SetPermission(rank_id, i, permission2 & bitwise_val ? 1 : 0, false);
  478. }
  479. }
  480. }
  481. }
  482. }
  483. void WorldDatabase::LoadGuildDefaultEventFilters(Guild* guild) {
  484. if (guild) {
  485. LogWrite(GUILD__DEBUG, 3, "Guilds", "Load/Set Default Event Filters for guild '%s' (%u)...", guild->GetName(), guild->GetID());
  486. Query query;
  487. MYSQL_ROW row;
  488. MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT DISTINCT `event_id`, `retain`, `broadcast` FROM `guild_event_defaults`");
  489. while (result && (row = mysql_fetch_row(result))) {
  490. LogWrite(GUILD__DEBUG, 3, "Guilds", "\tSetting Event Filter %i, retain: %i, broadcast: %i", atoi(row[0]), atoi(row[1]), atoi(row[2]));
  491. guild->SetEventFilter(atoi(row[0]), GUILD_EVENT_FILTER_CATEGORY_RETAIN_HISTORY, atoi(row[1]), false);
  492. guild->SetEventFilter(atoi(row[0]), GUILD_EVENT_FILTER_CATEGORY_BROADCAST, atoi(row[2]), false);
  493. }
  494. }
  495. }
  496. bool WorldDatabase::AddNewPlayerToServerGuild(int32 account_id, int32 char_id)
  497. {
  498. // Check if this servers rule allow auto-joining Server guild
  499. int8 autojoin = rule_manager.GetGlobalRule(R_World, GuildAutoJoin)->GetInt8();
  500. if( autojoin )
  501. {
  502. // if so, what is the guild ID of the default server guild?
  503. int32 guild_id = rule_manager.GetGlobalRule(R_World, GuildAutoJoinID)->GetInt32();
  504. Guild* guild = 0;
  505. guild = guild_list.GetGuild(guild_id);
  506. if (!guild)
  507. {
  508. // guild was not valid, abort!
  509. LogWrite(GUILD__ERROR, 1, "Guilds", "Guild ID %u not found! Cannot autojoin members!", guild_id);
  510. return false;
  511. }
  512. else
  513. {
  514. // guild was found, so what default Rank to make the players? if not set, use 7 (recruit)
  515. int8 rank_id = rule_manager.GetGlobalRule(R_World, GuildAutoJoinDefaultRankID)->GetInt8();
  516. if(!rank_id)
  517. rank_id = 7;
  518. // assuming all is good, insert the new guild member here...
  519. GuildMember *gm = new GuildMember();
  520. gm->account_id = account_id;
  521. gm->character_id = char_id;
  522. char* name = GetCharacterName(gm->character_id);
  523. strncpy(gm->name, name, sizeof(gm->name));
  524. gm->guild_status = 0;
  525. gm->points = 0.0;
  526. //gm->adventure_class = player->GetAdventureClass();
  527. //gm->adventure_level = player->GetLevel();
  528. //gm->tradeskill_class = player->GetTradeskillClass();
  529. //gm->tradeskill_level = player->GetTSLevel();
  530. gm->rank = rank_id;
  531. gm->zone = string("");
  532. gm->join_date = Timer::GetUnixTimeStamp();
  533. gm->last_login_date = gm->join_date;
  534. gm->recruiter_id = 0;
  535. gm->member_flags = GUILD_MEMBER_FLAGS_NOTIFY_LOGINS;
  536. gm->recruiting_show_adventure_class = 1;
  537. gm->recruiter_picture_data_size = 0;
  538. gm->recruiter_picture_data = 0;
  539. guild->AddGuildMember(gm);
  540. Query query;
  541. query.RunQuery2(Q_INSERT, "INSERT INTO `guild_members` (`guild_id`, `char_id`, `join_date`, `rank_id`) VALUES (%u, %u, %u, %i)",
  542. guild_id, char_id, gm->join_date, rank_id);
  543. LogWrite(GUILD__DEBUG, 3, "Guilds", "Auto-join player (%u) to server guild '%s' (%u) at rank %i...", char_id, guild->GetName(), guild_id, rank_id);
  544. // success!
  545. return true;
  546. }
  547. }
  548. // do not auto-join server guild
  549. return false;
  550. }