1. #include "stdafx.h"
  2. #include "../../common/billing.h"
  3. #include "config.h"
  4. #include "desc_client.h"
  5. #include "desc_manager.h"
  6. #include "char.h"
  7. #include "char_manager.h"
  8. #include "p2p.h"
  9. #include "guild.h"
  10. #include "guild_manager.h"
  11. #include "party.h"
  12. #include "messenger_manager.h"
  13. #include "empire_text_convert.h"
  14. #include "unique_item.h"
  15. #include "xmas_event.h"
  16. #include "affect.h"
  17. #include "castle.h"
  18. #include "dev_log.h"
  19. #include "locale_service.h"
  20. #include "questmanager.h"
  21. #include "pcbang.h"
  22. #include "skill.h"
  23. #include "threeway_war.h"
  24. ////////////////////////////////////////////////////////////////////////////////
  25. // Input Processor
  26. CInputP2P::CInputP2P()
  27. {
  28. BindPacketInfo(&m_packetInfoGG);
  29. }
  30. void CInputP2P::Login(LPDESC d, const char * c_pData)
  31. {
  32. P2P_MANAGER::instance().Login(d, (TPacketGGLogin *) c_pData);
  33. }
  34. void CInputP2P::Logout(LPDESC d, const char * c_pData)
  35. {
  36. TPacketGGLogout * p = (TPacketGGLogout *) c_pData;
  37. P2P_MANAGER::instance().Logout(p->szName);
  38. }
  39. int CInputP2P::Relay(LPDESC d, const char * c_pData, size_t uiBytes)
  40. {
  41. TPacketGGRelay * p = (TPacketGGRelay *) c_pData;
  42. if (uiBytes < sizeof(TPacketGGRelay) + p->lSize)
  43. return -1;
  44. if (p->lSize < 0)
  45. {
  46. sys_err("invalid packet length %d", p->lSize);
  47. d->SetPhase(PHASE_CLOSE);
  48. return -1;
  49. }
  50. sys_log(0, "InputP2P::Relay : %s size %d", p->szName, p->lSize);
  51. LPCHARACTER pkChr = CHARACTER_MANAGER::instance().FindPC(p->szName);
  52. const BYTE* c_pbData = (const BYTE *) (c_pData + sizeof(TPacketGGRelay));
  53. if (!pkChr)
  54. return p->lSize;
  55. if (*c_pbData == HEADER_GC_WHISPER)
  56. {
  57. if (pkChr->IsBlockMode(BLOCK_WHISPER))
  58. {
  59. // 귓속말 거부 상태에서 귓속말 거부.
  60. return p->lSize;
  61. }
  62. char buf[1024];
  63. memcpy(buf, c_pbData, MIN(p->lSize, sizeof(buf)));
  64. TPacketGCWhisper* p2 = (TPacketGCWhisper*) buf;
  65. // bType 상위 4비트: Empire 번호
  66. // bType 하위 4비트: EWhisperType
  67. BYTE bToEmpire = (p2->bType >> 4);
  68. p2->bType = p2->bType & 0x0F;
  69. if(p2->bType == 0x0F) {
  70. // 시스템 메세지 귓속말은 bType의 상위비트까지 모두 사용함.
  71. p2->bType = WHISPER_TYPE_SYSTEM;
  72. } else {
  73. if (!pkChr->IsEquipUniqueGroup(UNIQUE_GROUP_RING_OF_LANGUAGE))
  74. if (bToEmpire >= 1 && bToEmpire <= 3 && pkChr->GetEmpire() != bToEmpire)
  75. {
  76. ConvertEmpireText(bToEmpire,
  77. buf + sizeof(TPacketGCWhisper),
  78. p2->wSize - sizeof(TPacketGCWhisper),
  79. 10+2*pkChr->GetSkillPower(SKILL_LANGUAGE1 + bToEmpire - 1));
  80. }
  81. }
  82. pkChr->GetDesc()->Packet(buf, p->lSize);
  83. }
  84. else
  85. pkChr->GetDesc()->Packet(c_pbData, p->lSize);
  86. return (p->lSize);
  87. }
  88. int CInputP2P::Notice(LPDESC d, const char * c_pData, size_t uiBytes)
  89. {
  90. TPacketGGNotice * p = (TPacketGGNotice *) c_pData;
  91. if (uiBytes < sizeof(TPacketGGNotice) + p->lSize)
  92. return -1;
  93. if (p->lSize < 0)
  94. {
  95. sys_err("invalid packet length %d", p->lSize);
  96. d->SetPhase(PHASE_CLOSE);
  97. return -1;
  98. }
  99. char szBuf[256+1];
  100. strlcpy(szBuf, c_pData + sizeof(TPacketGGNotice), MIN(p->lSize + 1, sizeof(szBuf)));
  101. SendNotice(szBuf);
  102. return (p->lSize);
  103. }
  104. int CInputP2P::MonarchNotice(LPDESC d, const char * c_pData, size_t uiBytes)
  105. {
  106. TPacketGGMonarchNotice * p = (TPacketGGMonarchNotice *) c_pData;
  107. if (uiBytes < p->lSize + sizeof(TPacketGGMonarchNotice))
  108. return -1;
  109. if (p->lSize < 0)
  110. {
  111. sys_err("invalid packet length %d", p->lSize);
  112. d->SetPhase(PHASE_CLOSE);
  113. return -1;
  114. }
  115. char szBuf[256+1];
  116. strlcpy(szBuf, c_pData + sizeof(TPacketGGMonarchNotice), MIN(p->lSize + 1, sizeof(szBuf)));
  117. SendMonarchNotice(p->bEmpire, szBuf);
  118. return (p->lSize);
  119. }
  120. int CInputP2P::MonarchTransfer(LPDESC d, const char* c_pData)
  121. {
  122. TPacketMonarchGGTransfer* p = (TPacketMonarchGGTransfer*) c_pData;
  123. LPCHARACTER pTargetChar = CHARACTER_MANAGER::instance().FindByPID(p->dwTargetPID);
  124. if (pTargetChar != NULL)
  125. {
  126. unsigned int qIndex = quest::CQuestManager::instance().GetQuestIndexByName("monarch_transfer");
  127. if (qIndex != 0)
  128. {
  129. pTargetChar->SetQuestFlag("monarch_transfer.x", p->x);
  130. pTargetChar->SetQuestFlag("monarch_transfer.y", p->y);
  131. quest::CQuestManager::instance().Letter(pTargetChar->GetPlayerID(), qIndex, 0);
  132. }
  133. }
  134. return 0;
  135. }
  136. int CInputP2P::Guild(LPDESC d, const char* c_pData, size_t uiBytes)
  137. {
  138. TPacketGGGuild * p = (TPacketGGGuild *) c_pData;
  139. uiBytes -= sizeof(TPacketGGGuild);
  140. c_pData += sizeof(TPacketGGGuild);
  141. CGuild * g = CGuildManager::instance().FindGuild(p->dwGuild);
  142. switch (p->bSubHeader)
  143. {
  144. case GUILD_SUBHEADER_GG_CHAT:
  145. {
  146. if (uiBytes < sizeof(TPacketGGGuildChat))
  147. return -1;
  148. TPacketGGGuildChat * p = (TPacketGGGuildChat *) c_pData;
  149. if (g)
  150. g->P2PChat(p->szText);
  151. return sizeof(TPacketGGGuildChat);
  152. }
  153. case GUILD_SUBHEADER_GG_SET_MEMBER_COUNT_BONUS:
  154. {
  155. if (uiBytes < sizeof(int))
  156. return -1;
  157. int iBonus = *((int *) c_pData);
  158. CGuild* pGuild = CGuildManager::instance().FindGuild(p->dwGuild);
  159. if (pGuild)
  160. {
  161. pGuild->SetMemberCountBonus(iBonus);
  162. }
  163. return sizeof(int);
  164. }
  165. default:
  166. sys_err ("UNKNOWN GUILD SUB PACKET");
  167. break;
  168. }
  169. return 0;
  170. }
  171. struct FuncShout
  172. {
  173. const char * m_str;
  174. BYTE m_bEmpire;
  175. FuncShout(const char * str, BYTE bEmpire) : m_str(str), m_bEmpire(bEmpire)
  176. {
  177. }
  178. void operator () (LPDESC d)
  179. {
  180. #ifdef ENABLE_NEWSTUFF
  181. if (!d->GetCharacter() || (!g_bGlobalShoutEnable && d->GetCharacter()->GetGMLevel() == GM_PLAYER && d->GetEmpire() != m_bEmpire))
  182. return;
  183. #else
  184. if (!d->GetCharacter() || (d->GetCharacter()->GetGMLevel() == GM_PLAYER && d->GetEmpire() != m_bEmpire))
  185. return;
  186. #endif
  187. d->GetCharacter()->ChatPacket(CHAT_TYPE_SHOUT, "%s", m_str);
  188. }
  189. };
  190. void SendShout(const char * szText, BYTE bEmpire)
  191. {
  192. const DESC_MANAGER::DESC_SET & c_ref_set = DESC_MANAGER::instance().GetClientSet();
  193. std::for_each(c_ref_set.begin(), c_ref_set.end(), FuncShout(szText, bEmpire));
  194. }
  195. void CInputP2P::Shout(const char * c_pData)
  196. {
  197. TPacketGGShout * p = (TPacketGGShout *) c_pData;
  198. SendShout(p->szText, p->bEmpire);
  199. }
  200. void CInputP2P::Disconnect(const char * c_pData)
  201. {
  202. TPacketGGDisconnect * p = (TPacketGGDisconnect *) c_pData;
  203. LPDESC d = DESC_MANAGER::instance().FindByLoginName(p->szLogin);
  204. if (!d)
  205. return;
  206. if (!d->GetCharacter())
  207. {
  208. d->SetPhase(PHASE_CLOSE);
  209. }
  210. else
  211. d->DisconnectOfSameLogin();
  212. }
  213. void CInputP2P::Setup(LPDESC d, const char * c_pData)
  214. {
  215. TPacketGGSetup * p = (TPacketGGSetup *) c_pData;
  216. sys_log(0, "P2P: Setup %s:%d", d->GetHostName(), p->wPort);
  217. d->SetP2P(d->GetHostName(), p->wPort, p->bChannel);
  218. }
  219. void CInputP2P::MessengerAdd(const char * c_pData)
  220. {
  221. TPacketGGMessenger * p = (TPacketGGMessenger *) c_pData;
  222. sys_log(0, "P2P: Messenger Add %s %s", p->szAccount, p->szCompanion);
  223. MessengerManager::instance().__AddToList(p->szAccount, p->szCompanion);
  224. }
  225. void CInputP2P::MessengerRemove(const char * c_pData)
  226. {
  227. TPacketGGMessenger * p = (TPacketGGMessenger *) c_pData;
  228. sys_log(0, "P2P: Messenger Remove %s %s", p->szAccount, p->szCompanion);
  229. MessengerManager::instance().__RemoveFromList(p->szAccount, p->szCompanion);
  230. }
  231. void CInputP2P::FindPosition(LPDESC d, const char* c_pData)
  232. {
  233. TPacketGGFindPosition* p = (TPacketGGFindPosition*) c_pData;
  234. LPCHARACTER ch = CHARACTER_MANAGER::instance().FindByPID(p->dwTargetPID);
  235. #ifdef ENABLE_CMD_WARP_IN_DUNGEON
  236. if (ch)
  237. #else
  238. if (ch && ch->GetMapIndex() < 10000)
  239. #endif
  240. {
  241. TPacketGGWarpCharacter pw;
  242. pw.header = HEADER_GG_WARP_CHARACTER;
  243. pw.pid = p->dwFromPID;
  244. pw.x = ch->GetX();
  245. pw.y = ch->GetY();
  246. #ifdef ENABLE_CMD_WARP_IN_DUNGEON
  247. pw.mapIndex = (ch->GetMapIndex() < 10000) ? 0 : ch->GetMapIndex();
  248. #endif
  249. d->Packet(&pw, sizeof(pw));
  250. }
  251. }
  252. void CInputP2P::WarpCharacter(const char* c_pData)
  253. {
  254. TPacketGGWarpCharacter* p = (TPacketGGWarpCharacter*) c_pData;
  255. LPCHARACTER ch = CHARACTER_MANAGER::instance().FindByPID(p->pid);
  256. #ifdef ENABLE_CMD_WARP_IN_DUNGEON
  257. if (ch)
  258. ch->WarpSet(p->x, p->y, p->mapIndex);
  259. #else
  260. if (ch)
  261. ch->WarpSet(p->x, p->y);
  262. #endif
  263. }
  264. void CInputP2P::GuildWarZoneMapIndex(const char* c_pData)
  265. {
  266. TPacketGGGuildWarMapIndex * p = (TPacketGGGuildWarMapIndex*) c_pData;
  267. CGuildManager & gm = CGuildManager::instance();
  268. sys_log(0, "P2P: GuildWarZoneMapIndex g1(%u) vs g2(%u), mapIndex(%d)", p->dwGuildID1, p->dwGuildID2, p->lMapIndex);
  269. CGuild * g1 = gm.FindGuild(p->dwGuildID1);
  270. CGuild * g2 = gm.FindGuild(p->dwGuildID2);
  271. if (g1 && g2)
  272. {
  273. g1->SetGuildWarMapIndex(p->dwGuildID2, p->lMapIndex);
  274. g2->SetGuildWarMapIndex(p->dwGuildID1, p->lMapIndex);
  275. }
  276. }
  277. void CInputP2P::Transfer(const char * c_pData)
  278. {
  279. TPacketGGTransfer * p = (TPacketGGTransfer *) c_pData;
  280. LPCHARACTER ch = CHARACTER_MANAGER::instance().FindPC(p->szName);
  281. if (ch)
  282. ch->WarpSet(p->lX, p->lY);
  283. }
  284. void CInputP2P::XmasWarpSanta(const char * c_pData)
  285. {
  286. TPacketGGXmasWarpSanta * p =(TPacketGGXmasWarpSanta *) c_pData;
  287. if (p->bChannel == g_bChannel && map_allow_find(p->lMapIndex))
  288. {
  289. int iNextSpawnDelay = 50 * 60;
  290. xmas::SpawnSanta(p->lMapIndex, iNextSpawnDelay); // 50분있다가 새로운 산타가 나타남 (한국은 20분)
  291. TPacketGGXmasWarpSantaReply pack_reply;
  292. pack_reply.bHeader = HEADER_GG_XMAS_WARP_SANTA_REPLY;
  293. pack_reply.bChannel = g_bChannel;
  294. P2P_MANAGER::instance().Send(&pack_reply, sizeof(pack_reply));
  295. }
  296. }
  297. void CInputP2P::XmasWarpSantaReply(const char* c_pData)
  298. {
  299. TPacketGGXmasWarpSantaReply* p = (TPacketGGXmasWarpSantaReply*) c_pData;
  300. if (p->bChannel == g_bChannel)
  301. {
  302. CharacterVectorInteractor i;
  303. if (CHARACTER_MANAGER::instance().GetCharactersByRaceNum(xmas::MOB_SANTA_VNUM, i))
  304. {
  305. CharacterVectorInteractor::iterator it = i.begin();
  306. while (it != i.end()) {
  307. M2_DESTROY_CHARACTER(*it++);
  308. }
  309. }
  310. }
  311. }
  312. void CInputP2P::LoginPing(LPDESC d, const char * c_pData)
  313. {
  314. TPacketGGLoginPing * p = (TPacketGGLoginPing *) c_pData;
  315. SendBillingExpire(p->szLogin, BILLING_DAY, 0, NULL);
  316. if (!g_pkAuthMasterDesc) // If I am master, I have to broadcast
  317. P2P_MANAGER::instance().Send(p, sizeof(TPacketGGLoginPing), d);
  318. }
  319. // BLOCK_CHAT
  320. void CInputP2P::BlockChat(const char * c_pData)
  321. {
  322. TPacketGGBlockChat * p = (TPacketGGBlockChat *) c_pData;
  323. LPCHARACTER ch = CHARACTER_MANAGER::instance().FindPC(p->szName);
  324. if (ch)
  325. {
  326. sys_log(0, "BLOCK CHAT apply name %s dur %d", p->szName, p->lBlockDuration);
  327. ch->AddAffect(AFFECT_BLOCK_CHAT, POINT_NONE, 0, AFF_NONE, p->lBlockDuration, 0, true);
  328. }
  329. else
  330. {
  331. sys_log(0, "BLOCK CHAT fail name %s dur %d", p->szName, p->lBlockDuration);
  332. }
  333. }
  334. // END_OF_BLOCK_CHAT
  335. //
  336. void CInputP2P::PCBangUpdate(const char* c_pData)
  337. {
  338. TPacketPCBangUpdate* p = (TPacketPCBangUpdate*)c_pData;
  339. CPCBangManager::instance().RequestUpdateIPList(p->ulPCBangID);
  340. }
  341. void CInputP2P::IamAwake(LPDESC d, const char * c_pData)
  342. {
  343. std::string hostNames;
  344. P2P_MANAGER::instance().GetP2PHostNames(hostNames);
  345. sys_log(0, "P2P Awakeness check from %s. My P2P connection number is %d. and details...\n%s", d->GetHostName(), P2P_MANAGER::instance().GetDescCount(), hostNames.c_str());
  346. }
  347. int CInputP2P::Analyze(LPDESC d, BYTE bHeader, const char * c_pData)
  348. {
  349. if (test_server)
  350. sys_log(0, "CInputP2P::Anlayze[Header %d]", bHeader);
  351. int iExtraLen = 0;
  352. switch (bHeader)
  353. {
  354. case HEADER_GG_SETUP:
  355. Setup(d, c_pData);
  356. break;
  357. case HEADER_GG_LOGIN:
  358. Login(d, c_pData);
  359. break;
  360. case HEADER_GG_LOGOUT:
  361. Logout(d, c_pData);
  362. break;
  363. case HEADER_GG_RELAY:
  364. if ((iExtraLen = Relay(d, c_pData, m_iBufferLeft)) < 0)
  365. return -1;
  366. break;
  367. case HEADER_GG_NOTICE:
  368. if ((iExtraLen = Notice(d, c_pData, m_iBufferLeft)) < 0)
  369. return -1;
  370. break;
  371. case HEADER_GG_SHUTDOWN:
  372. sys_err("Accept shutdown p2p command from %s.", d->GetHostName());
  373. Shutdown(10);
  374. break;
  375. case HEADER_GG_GUILD:
  376. if ((iExtraLen = Guild(d, c_pData, m_iBufferLeft)) < 0)
  377. return -1;
  378. break;
  379. case HEADER_GG_SHOUT:
  380. Shout(c_pData);
  381. break;
  382. case HEADER_GG_DISCONNECT:
  383. Disconnect(c_pData);
  384. break;
  385. case HEADER_GG_MESSENGER_ADD:
  386. MessengerAdd(c_pData);
  387. break;
  388. case HEADER_GG_MESSENGER_REMOVE:
  389. MessengerRemove(c_pData);
  390. break;
  391. case HEADER_GG_FIND_POSITION:
  392. FindPosition(d, c_pData);
  393. break;
  394. case HEADER_GG_WARP_CHARACTER:
  395. WarpCharacter(c_pData);
  396. break;
  397. case HEADER_GG_GUILD_WAR_ZONE_MAP_INDEX:
  398. GuildWarZoneMapIndex(c_pData);
  399. break;
  400. case HEADER_GG_TRANSFER:
  401. Transfer(c_pData);
  402. break;
  403. case HEADER_GG_XMAS_WARP_SANTA:
  404. XmasWarpSanta(c_pData);
  405. break;
  406. case HEADER_GG_XMAS_WARP_SANTA_REPLY:
  407. XmasWarpSantaReply(c_pData);
  408. break;
  409. case HEADER_GG_RELOAD_CRC_LIST:
  410. LoadValidCRCList();
  411. break;
  412. case HEADER_GG_CHECK_CLIENT_VERSION:
  413. CheckClientVersion();
  414. break;
  415. case HEADER_GG_LOGIN_PING:
  416. LoginPing(d, c_pData);
  417. break;
  418. case HEADER_GG_BLOCK_CHAT:
  419. BlockChat(c_pData);
  420. break;
  421. case HEADER_GG_SIEGE:
  422. {
  423. TPacketGGSiege* pSiege = (TPacketGGSiege*)c_pData;
  424. castle_siege(pSiege->bEmpire, pSiege->bTowerCount);
  425. }
  426. break;
  427. case HEADER_GG_MONARCH_NOTICE:
  428. if ((iExtraLen = MonarchNotice(d, c_pData, m_iBufferLeft)) < 0)
  429. return -1;
  430. break;
  431. case HEADER_GG_MONARCH_TRANSFER :
  432. MonarchTransfer(d, c_pData);
  433. break;
  434. case HEADER_GG_PCBANG_UPDATE :
  435. PCBangUpdate(c_pData);
  436. break;
  437. case HEADER_GG_CHECK_AWAKENESS:
  438. IamAwake(d, c_pData);
  439. break;
  440. }
  441. return (iExtraLen);
  442. }