Advertisement
Guest User

hi

a guest
Feb 24th, 2020
194
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 27.97 KB | None | 0 0
  1. #include "stdafx.h"
  2. #include "constants.h"
  3. #include "config.h"
  4. #include "utils.h"
  5. #include "input.h"
  6. #include "desc_client.h"
  7. #include "desc_manager.h"
  8. #include "char.h"
  9. #include "char_manager.h"
  10. #include "cmd.h"
  11. #include "buffer_manager.h"
  12. #include "protocol.h"
  13. #include "pvp.h"
  14. #include "start_position.h"
  15. #include "messenger_manager.h"
  16. #include "guild_manager.h"
  17. #include "party.h"
  18. #include "dungeon.h"
  19. #include "war_map.h"
  20. #include "questmanager.h"
  21. #include "building.h"
  22. #include "wedding.h"
  23. #include "affect.h"
  24. #include "arena.h"
  25. #include "OXEvent.h"
  26. #include "priv_manager.h"
  27. #include "dev_log.h"
  28. #include "log.h"
  29.  
  30. #ifdef ENABLE_DUNGEON_INFO_SYSTEM
  31.     #include "DungeonInfo.h"
  32. #endif
  33.  
  34. #include "horsename_manager.h"
  35. #include "MarkManager.h"
  36.  
  37. static void _send_bonus_info(LPCHARACTER ch)
  38. {
  39.     int item_drop_bonus = 0;
  40.     int gold_drop_bonus = 0;
  41.     int gold10_drop_bonus   = 0;
  42.     int exp_bonus       = 0;
  43.  
  44.     item_drop_bonus     = CPrivManager::instance().GetPriv(ch, PRIV_ITEM_DROP);
  45.     gold_drop_bonus     = CPrivManager::instance().GetPriv(ch, PRIV_GOLD_DROP);
  46.     gold10_drop_bonus   = CPrivManager::instance().GetPriv(ch, PRIV_GOLD10_DROP);
  47.     exp_bonus           = CPrivManager::instance().GetPriv(ch, PRIV_EXP_PCT);
  48.  
  49.     if (item_drop_bonus)
  50.     {
  51.         ch->ChatPacket(CHAT_TYPE_NOTICE,
  52.                 LC_TEXT("아이템 드롭률  %d%% 추가 이벤트 중입니다."), item_drop_bonus);
  53.     }
  54.     if (gold_drop_bonus)
  55.     {
  56.         ch->ChatPacket(CHAT_TYPE_NOTICE,
  57.                 LC_TEXT("골드 드롭률 %d%% 추가 이벤트 중입니다."), gold_drop_bonus);
  58.     }
  59.     if (gold10_drop_bonus)
  60.     {
  61.         ch->ChatPacket(CHAT_TYPE_NOTICE,
  62.                 LC_TEXT("대박골드 드롭률 %d%% 추가 이벤트 중입니다."), gold10_drop_bonus);
  63.     }
  64.     if (exp_bonus)
  65.     {
  66.         ch->ChatPacket(CHAT_TYPE_NOTICE,
  67.                 LC_TEXT("경험치 %d%% 추가 획득 이벤트 중입니다."), exp_bonus);
  68.     }
  69. }
  70.  
  71. static bool FN_is_battle_zone(LPCHARACTER ch)
  72. {
  73.     switch (ch->GetMapIndex())
  74.     {
  75.         case 1:         // 신수 1차 마을
  76.         case 2:         // 신수 2차 마을
  77.         case 21:        // 천조 1차 마을
  78.         case 23:        // 천조 2차 마을
  79.         case 41:        // 진노 1차 마을
  80.         case 43:        // 진노 2차 마을
  81.         case 113:       // OX 맵
  82.             return false;
  83.     }
  84.  
  85.     return true;
  86. }
  87.  
  88. void CInputLogin::Login(LPDESC d, const char * data)
  89. {
  90.     TPacketCGLogin * pinfo = (TPacketCGLogin *) data;
  91.  
  92.     char login[LOGIN_MAX_LEN + 1];
  93.     trim_and_lower(pinfo->login, login, sizeof(login));
  94.  
  95.     sys_log(0, "InputLogin::Login : %s", login);
  96.  
  97.     TPacketGCLoginFailure failurePacket;
  98.  
  99.     if (g_iUseLocale && !test_server)
  100.     {
  101.         failurePacket.header = HEADER_GC_LOGIN_FAILURE;
  102.         strlcpy(failurePacket.szStatus, "VERSION", sizeof(failurePacket.szStatus));
  103.         d->Packet(&failurePacket, sizeof(TPacketGCLoginFailure));
  104.         return;
  105.     }
  106.  
  107.     if (g_bNoMoreClient)
  108.     {
  109.         failurePacket.header = HEADER_GC_LOGIN_FAILURE;
  110.         strlcpy(failurePacket.szStatus, "SHUTDOWN", sizeof(failurePacket.szStatus));
  111.         d->Packet(&failurePacket, sizeof(TPacketGCLoginFailure));
  112.         return;
  113.     }
  114.  
  115.     if (g_iUserLimit > 0)
  116.     {
  117.         int iTotal;
  118.         int * paiEmpireUserCount;
  119.         int iLocal;
  120.  
  121.         DESC_MANAGER::instance().GetUserCount(iTotal, &paiEmpireUserCount, iLocal);
  122.  
  123.         if (g_iUserLimit <= iTotal)
  124.         {
  125.             failurePacket.header = HEADER_GC_LOGIN_FAILURE;
  126.             strlcpy(failurePacket.szStatus, "FULL", sizeof(failurePacket.szStatus));
  127.             d->Packet(&failurePacket, sizeof(TPacketGCLoginFailure));
  128.             return;
  129.         }
  130.     }
  131.  
  132.     TLoginPacket login_packet;
  133.  
  134.     strlcpy(login_packet.login, login, sizeof(login_packet.login));
  135.     strlcpy(login_packet.passwd, pinfo->passwd, sizeof(login_packet.passwd));
  136.  
  137.     db_clientdesc->DBPacket(HEADER_GD_LOGIN, d->GetHandle(), &login_packet, sizeof(TLoginPacket));
  138. }
  139.  
  140. void CInputLogin::LoginByKey(LPDESC d, const char * data)
  141. {
  142.     TPacketCGLogin2 * pinfo = (TPacketCGLogin2 *) data;
  143.  
  144.     char login[LOGIN_MAX_LEN + 1];
  145.     trim_and_lower(pinfo->login, login, sizeof(login));
  146.  
  147.     if (g_bNoMoreClient)
  148.     {
  149.         TPacketGCLoginFailure failurePacket;
  150.  
  151.         failurePacket.header = HEADER_GC_LOGIN_FAILURE;
  152.         strlcpy(failurePacket.szStatus, "SHUTDOWN", sizeof(failurePacket.szStatus));
  153.         d->Packet(&failurePacket, sizeof(TPacketGCLoginFailure));
  154.         return;
  155.     }
  156.  
  157.     if (g_iUserLimit > 0)
  158.     {
  159.         int iTotal;
  160.         int * paiEmpireUserCount;
  161.         int iLocal;
  162.  
  163.         DESC_MANAGER::instance().GetUserCount(iTotal, &paiEmpireUserCount, iLocal);
  164.  
  165.         if (g_iUserLimit <= iTotal)
  166.         {
  167.             TPacketGCLoginFailure failurePacket;
  168.  
  169.             failurePacket.header = HEADER_GC_LOGIN_FAILURE;
  170.             strlcpy(failurePacket.szStatus, "FULL", sizeof(failurePacket.szStatus));
  171.  
  172.             d->Packet(&failurePacket, sizeof(TPacketGCLoginFailure));
  173.             return;
  174.         }
  175.     }
  176.  
  177.     sys_log(0, "LOGIN_BY_KEY: %s key %u", login, pinfo->dwLoginKey);
  178.  
  179.     d->SetLoginKey(pinfo->dwLoginKey);
  180.     d->SetSecurityKey(pinfo->adwClientKey);
  181.  
  182.     TPacketGDLoginByKey ptod;
  183.  
  184.     strlcpy(ptod.szLogin, login, sizeof(ptod.szLogin));
  185.     ptod.dwLoginKey = pinfo->dwLoginKey;
  186.     thecore_memcpy(ptod.adwClientKey, pinfo->adwClientKey, sizeof(DWORD) * 4);
  187.     strlcpy(ptod.szIP, d->GetHostName(), sizeof(ptod.szIP));
  188.  
  189.     db_clientdesc->DBPacket(HEADER_GD_LOGIN_BY_KEY, d->GetHandle(), &ptod, sizeof(TPacketGDLoginByKey));
  190. }
  191.  
  192. void CInputLogin::ChangeName(LPDESC d, const char * data)
  193. {
  194.     TPacketCGChangeName * p = (TPacketCGChangeName *) data;
  195.     const TAccountTable & c_r = d->GetAccountTable();
  196.  
  197.     if (!c_r.id)
  198.     {
  199.         sys_err("no account table");
  200.         return;
  201.     }
  202.  
  203.     if (!c_r.players[p->index].bChangeName)
  204.         return;
  205.  
  206.     if (!check_name(p->name))
  207.     {
  208.         TPacketGCCreateFailure pack;
  209.         pack.header = HEADER_GC_CHARACTER_CREATE_FAILURE;
  210.         pack.bType = 0;
  211.         d->Packet(&pack, sizeof(pack));
  212.         return;
  213.     }
  214.  
  215.     TPacketGDChangeName pdb;
  216.  
  217.     pdb.pid = c_r.players[p->index].dwID;
  218.     strlcpy(pdb.name, p->name, sizeof(pdb.name));
  219.     db_clientdesc->DBPacket(HEADER_GD_CHANGE_NAME, d->GetHandle(), &pdb, sizeof(TPacketGDChangeName));
  220. }
  221.  
  222. void CInputLogin::CharacterSelect(LPDESC d, const char * data)
  223. {
  224.     struct command_player_select * pinfo = (struct command_player_select *) data;
  225.     const TAccountTable & c_r = d->GetAccountTable();
  226.  
  227.     sys_log(0, "player_select: login: %s index: %d", c_r.login, pinfo->index);
  228.  
  229.     if (!c_r.id)
  230.     {
  231.         sys_err("no account table");
  232.         return;
  233.     }
  234.  
  235.     if (pinfo->index >= PLAYER_PER_ACCOUNT)
  236.     {
  237.         sys_err("index overflow %d, login: %s", pinfo->index, c_r.login);
  238.         return;
  239.     }
  240.  
  241.     if (c_r.players[pinfo->index].bChangeName)
  242.     {
  243.         sys_err("name must be changed idx %d, login %s, name %s",
  244.                 pinfo->index, c_r.login, c_r.players[pinfo->index].szName);
  245.         return;
  246.     }
  247.  
  248.     TPlayerLoadPacket player_load_packet;
  249.  
  250.     player_load_packet.account_id   = c_r.id;
  251.     player_load_packet.player_id    = c_r.players[pinfo->index].dwID;
  252.     player_load_packet.account_index    = pinfo->index;
  253.  
  254.     db_clientdesc->DBPacket(HEADER_GD_PLAYER_LOAD, d->GetHandle(), &player_load_packet, sizeof(TPlayerLoadPacket));
  255. }
  256.  
  257. bool NewPlayerTable(TPlayerTable * table,
  258.         const char * name,
  259.         BYTE job,
  260.         BYTE shape,
  261.         BYTE bEmpire,
  262.         BYTE bCon,
  263.         BYTE bInt,
  264.         BYTE bStr,
  265.         BYTE bDex)
  266. {
  267.     if (job >= JOB_MAX_NUM)
  268.         return false;
  269.  
  270.     memset(table, 0, sizeof(TPlayerTable));
  271.  
  272.     strlcpy(table->name, name, sizeof(table->name));
  273.  
  274.     table->level = 1;
  275.     table->job = job;
  276.     table->voice = 0;
  277.     table->part_base = shape;
  278.    
  279.     table->st = JobInitialPoints[job].st;
  280.     table->dx = JobInitialPoints[job].dx;
  281.     table->ht = JobInitialPoints[job].ht;
  282.     table->iq = JobInitialPoints[job].iq;
  283.  
  284.     table->hp = JobInitialPoints[job].max_hp + table->ht * JobInitialPoints[job].hp_per_ht;
  285.     table->sp = JobInitialPoints[job].max_sp + table->iq * JobInitialPoints[job].sp_per_iq;
  286.     table->stamina = JobInitialPoints[job].max_stamina;
  287.  
  288.     table->x    = CREATE_START_X(bEmpire) + number(-300, 300);
  289.     table->y    = CREATE_START_Y(bEmpire) + number(-300, 300);
  290.     table->z    = 0;
  291.     table->dir  = 0;
  292.     table->playtime = 0;
  293.     table->gold     = 0;
  294.  
  295.     table->skill_group = 0;
  296.  
  297.     if (china_event_server)
  298.     {
  299.         table->level = 35;
  300.  
  301.         for (int i = 1; i < 35; ++i)
  302.         {
  303.             int iHP = number(JobInitialPoints[job].hp_per_lv_begin, JobInitialPoints[job].hp_per_lv_end);
  304.             int iSP = number(JobInitialPoints[job].sp_per_lv_begin, JobInitialPoints[job].sp_per_lv_end);
  305.             table->sRandomHP += iHP;
  306.             table->sRandomSP += iSP;
  307.             table->stat_point += 3;
  308.         }
  309.  
  310.         table->hp += table->sRandomHP;
  311.         table->sp += table->sRandomSP;
  312.  
  313.         table->gold = 1000000;
  314.     }
  315.  
  316.     return true;
  317. }
  318.  
  319. bool RaceToJob(unsigned race, unsigned* ret_job)
  320. {
  321.     *ret_job = 0;
  322.  
  323.     if (race >= MAIN_RACE_MAX_NUM)
  324.         return false;
  325.  
  326.     switch (race)
  327.     {
  328.         case MAIN_RACE_WARRIOR_M:
  329.             *ret_job = JOB_WARRIOR;
  330.             break;
  331.  
  332.         case MAIN_RACE_WARRIOR_W:
  333.             *ret_job = JOB_WARRIOR;
  334.             break;
  335.  
  336.         case MAIN_RACE_ASSASSIN_M:
  337.             *ret_job = JOB_ASSASSIN;
  338.             break;
  339.  
  340.         case MAIN_RACE_ASSASSIN_W:
  341.             *ret_job = JOB_ASSASSIN;
  342.             break;
  343.  
  344.         case MAIN_RACE_SURA_M:
  345.             *ret_job = JOB_SURA;
  346.             break;
  347.  
  348.         case MAIN_RACE_SURA_W:
  349.             *ret_job = JOB_SURA;
  350.             break;
  351.  
  352.         case MAIN_RACE_SHAMAN_M:
  353.             *ret_job = JOB_SHAMAN;
  354.             break;
  355.  
  356.         case MAIN_RACE_SHAMAN_W:
  357.             *ret_job = JOB_SHAMAN;
  358.             break;
  359.  
  360.         default:
  361.             return false;
  362.             break;
  363.     }
  364.     return true;
  365. }
  366.  
  367. // 신규 캐릭터 지원
  368. bool NewPlayerTable2(TPlayerTable * table, const char * name, BYTE race, BYTE shape, BYTE bEmpire)
  369. {
  370.     if (race >= MAIN_RACE_MAX_NUM)
  371.     {
  372.         sys_err("NewPlayerTable2.OUT_OF_RACE_RANGE(%d >= max(%d))\n", race, MAIN_RACE_MAX_NUM);
  373.         return false;
  374.     }
  375.  
  376.     unsigned job;
  377.  
  378.     if (!RaceToJob(race, &job))
  379.     {  
  380.         sys_err("NewPlayerTable2.RACE_TO_JOB_ERROR(%d)\n", race);
  381.         return false;
  382.     }
  383.  
  384.     sys_log(0, "NewPlayerTable2(name=%s, race=%d, job=%d)", name, race, job);
  385.  
  386.     memset(table, 0, sizeof(TPlayerTable));
  387.  
  388.     strlcpy(table->name, name, sizeof(table->name));
  389.  
  390.     table->level        = 1;
  391.     table->job          = race; // 직업대신 종족을 넣는다
  392.     table->voice        = 0;
  393.     table->part_base    = shape;
  394.  
  395.     table->st       = JobInitialPoints[job].st;
  396.     table->dx       = JobInitialPoints[job].dx;
  397.     table->ht       = JobInitialPoints[job].ht;
  398.     table->iq       = JobInitialPoints[job].iq;
  399.  
  400.     table->hp       = JobInitialPoints[job].max_hp + table->ht * JobInitialPoints[job].hp_per_ht;
  401.     table->sp       = JobInitialPoints[job].max_sp + table->iq * JobInitialPoints[job].sp_per_iq;
  402.     table->stamina  = JobInitialPoints[job].max_stamina;
  403.  
  404.     table->x        = CREATE_START_X(bEmpire) + number(-300, 300);
  405.     table->y        = CREATE_START_Y(bEmpire) + number(-300, 300);
  406.     table->z        = 0;
  407.     table->dir      = 0;
  408.     table->playtime = 0;
  409.     table->gold     = 0;
  410.  
  411.     table->skill_group = 0;
  412.  
  413.     return true;
  414. }
  415.  
  416. void CInputLogin::CharacterCreate(LPDESC d, const char * data)
  417. {
  418.     struct command_player_create * pinfo = (struct command_player_create *) data;
  419.     TPlayerCreatePacket player_create_packet;
  420.  
  421.     sys_log(0, "PlayerCreate: name %s pos %d job %d shape %d",
  422.             pinfo->name,
  423.             pinfo->index,
  424.             pinfo->job,
  425.             pinfo->shape);
  426.  
  427.     TPacketGCLoginFailure packFailure;
  428.     memset(&packFailure, 0, sizeof(packFailure));
  429.     packFailure.header = HEADER_GC_CHARACTER_CREATE_FAILURE;
  430.  
  431.     if (true == g_BlockCharCreation)
  432.     {
  433.         d->Packet(&packFailure, sizeof(packFailure));
  434.         return;
  435.     }
  436.  
  437.     // 사용할 수 없는 이름이거나, 잘못된 평상복이면 생설 실패
  438.     if (!check_name(pinfo->name) || pinfo->shape > 1)
  439.     {
  440.         if (LC_IsCanada() == true)
  441.         {
  442.             TPacketGCCreateFailure pack;
  443.             pack.header = HEADER_GC_CHARACTER_CREATE_FAILURE;
  444.             pack.bType = 1;
  445.  
  446.             d->Packet(&pack, sizeof(pack));
  447.             return;
  448.         }
  449.  
  450.         d->Packet(&packFailure, sizeof(packFailure));
  451.         return;
  452.     }
  453.  
  454.     if (LC_IsEurope() == true)
  455.     {
  456.         const TAccountTable & c_rAccountTable = d->GetAccountTable();
  457.  
  458.         if (0 == strcmp(c_rAccountTable.login, pinfo->name))
  459.         {
  460.             TPacketGCCreateFailure pack;
  461.             pack.header = HEADER_GC_CHARACTER_CREATE_FAILURE;
  462.             pack.bType = 1;
  463.  
  464.             d->Packet(&pack, sizeof(pack));
  465.             return;
  466.         }
  467.     }
  468.  
  469.     memset(&player_create_packet, 0, sizeof(TPlayerCreatePacket));
  470.  
  471.     if (!NewPlayerTable2(&player_create_packet.player_table, pinfo->name, pinfo->job, pinfo->shape, d->GetEmpire()))
  472.     {
  473.         sys_err("player_prototype error: job %d face %d ", pinfo->job);
  474.         d->Packet(&packFailure, sizeof(packFailure));
  475.         return;
  476.     }
  477.  
  478.     const TAccountTable & c_rAccountTable = d->GetAccountTable();
  479.  
  480.     trim_and_lower(c_rAccountTable.login, player_create_packet.login, sizeof(player_create_packet.login));
  481.     strlcpy(player_create_packet.passwd, c_rAccountTable.passwd, sizeof(player_create_packet.passwd));
  482.  
  483.     player_create_packet.account_id = c_rAccountTable.id;
  484.     player_create_packet.account_index  = pinfo->index;
  485.  
  486.     sys_log(0, "PlayerCreate: name %s account_id %d, TPlayerCreatePacketSize(%d), Packet->Gold %d",
  487.             pinfo->name,
  488.             pinfo->index,
  489.             sizeof(TPlayerCreatePacket),
  490.             player_create_packet.player_table.gold);
  491.  
  492.     db_clientdesc->DBPacket(HEADER_GD_PLAYER_CREATE, d->GetHandle(), &player_create_packet, sizeof(TPlayerCreatePacket));
  493. }
  494.  
  495. void CInputLogin::CharacterDelete(LPDESC d, const char * data)
  496. {
  497.     struct command_player_delete * pinfo = (struct command_player_delete *) data;
  498.     const TAccountTable & c_rAccountTable = d->GetAccountTable();
  499.  
  500.     if (!c_rAccountTable.id)
  501.     {
  502.         sys_err("PlayerDelete: no login data");
  503.         return;
  504.     }
  505.  
  506.     sys_log(0, "PlayerDelete: login: %s index: %d, social_id %s", c_rAccountTable.login, pinfo->index, pinfo->private_code);
  507.  
  508.     if (pinfo->index >= PLAYER_PER_ACCOUNT)
  509.     {
  510.         sys_err("PlayerDelete: index overflow %d, login: %s", pinfo->index, c_rAccountTable.login);
  511.         return;
  512.     }
  513.  
  514.     if (!c_rAccountTable.players[pinfo->index].dwID)
  515.     {
  516.         sys_err("PlayerDelete: Wrong Social ID index %d, login: %s", pinfo->index, c_rAccountTable.login);
  517.         d->Packet(encode_byte(HEADER_GC_CHARACTER_DELETE_WRONG_SOCIAL_ID), 1);
  518.         return;
  519.     }
  520.  
  521.     TPlayerDeletePacket player_delete_packet;
  522.  
  523.     trim_and_lower(c_rAccountTable.login, player_delete_packet.login, sizeof(player_delete_packet.login));
  524.     player_delete_packet.player_id  = c_rAccountTable.players[pinfo->index].dwID;
  525.     player_delete_packet.account_index  = pinfo->index;
  526.     strlcpy(player_delete_packet.private_code, pinfo->private_code, sizeof(player_delete_packet.private_code));
  527.  
  528.     db_clientdesc->DBPacket(HEADER_GD_PLAYER_DELETE, d->GetHandle(), &player_delete_packet, sizeof(TPlayerDeletePacket));
  529. }
  530.  
  531. #pragma pack(1)
  532. typedef struct SPacketGTLogin
  533. {
  534.     BYTE header;
  535.     WORD empty;
  536.     DWORD id;
  537. } TPacketGTLogin;
  538. #pragma pack()
  539.  
  540. void CInputLogin::Entergame(LPDESC d, const char * data)
  541. {
  542.     LPCHARACTER ch;
  543.  
  544.     if (!(ch = d->GetCharacter()))
  545.     {
  546.         d->SetPhase(PHASE_CLOSE);
  547.         return;
  548.     }
  549.  
  550.     PIXEL_POSITION pos = ch->GetXYZ();
  551.  
  552.     if (!SECTREE_MANAGER::instance().GetMovablePosition(ch->GetMapIndex(), pos.x, pos.y, pos))
  553.     {
  554.         PIXEL_POSITION pos2;
  555.         SECTREE_MANAGER::instance().GetRecallPositionByEmpire(ch->GetMapIndex(), ch->GetEmpire(), pos2);
  556.  
  557.         sys_err("!GetMovablePosition (name %s %dx%d map %d changed to %dx%d)",
  558.                 ch->GetName(),
  559.                 pos.x, pos.y,
  560.                 ch->GetMapIndex(),
  561.                 pos2.x, pos2.y);
  562.         pos = pos2;
  563.     }
  564.  
  565.     CGuildManager::instance().LoginMember(ch);
  566.  
  567.     // 캐릭터를 맵에 추가
  568.     ch->Show(ch->GetMapIndex(), pos.x, pos.y, pos.z);
  569.  
  570.     SECTREE_MANAGER::instance().SendNPCPosition(ch);
  571.     ch->ReviveInvisible(5);
  572.  
  573.     d->SetPhase(PHASE_GAME);
  574.  
  575.     if(ch->GetItemAward_cmd())                                                                      //게임페이즈 들어가면
  576.         quest::CQuestManager::instance().ItemInformer(ch->GetPlayerID(),ch->GetItemAward_vnum());   //questmanager 호출
  577.    
  578.     sys_log(0, "ENTERGAME: %s %dx%dx%d %s map_index %d",
  579.             ch->GetName(), ch->GetX(), ch->GetY(), ch->GetZ(), d->GetHostName(), ch->GetMapIndex());
  580.  
  581.     if (ch->GetHorseLevel() > 0)
  582.     {
  583.         ch->EnterHorse();
  584.     }
  585.  
  586.     // 플레이시간 레코딩 시작
  587.     ch->ResetPlayTime();
  588.  
  589.     // 자동 저장 이벤트 추가
  590.     ch->StartSaveEvent();
  591.     ch->StartRecoveryEvent();
  592.    
  593. #ifdef ENABLE_DUNGEON_INFO_SYSTEM
  594.     DungeonInfo::instance().Update(ch);
  595. #endif 
  596.    
  597.     ch->StartCheckSpeedHackEvent();
  598.    
  599.     CPVPManager::instance().Connect(ch);
  600.     CPVPManager::instance().SendList(d);
  601.  
  602.     MessengerManager::instance().Login(ch->GetName());
  603.  
  604.     CPartyManager::instance().SetParty(ch);
  605.     CGuildManager::instance().SendGuildWar(ch);
  606.  
  607.     building::CManager::instance().SendLandList(d, ch->GetMapIndex());
  608.  
  609.     marriage::CManager::instance().Login(ch);
  610.  
  611.     TPacketGCTime p;
  612.     p.bHeader = HEADER_GC_TIME;
  613.     p.time = get_global_time();
  614.     d->Packet(&p, sizeof(p));
  615.  
  616.     TPacketGCChannel p2;
  617.     p2.header = HEADER_GC_CHANNEL;
  618.     p2.channel = g_bChannel;
  619.     d->Packet(&p2, sizeof(p2));
  620.  
  621.     ch->SendGreetMessage();
  622.  
  623.     _send_bonus_info(ch);
  624.    
  625.     for (int i = 0; i <= PREMIUM_MAX_NUM; ++i)
  626.     {
  627.         int remain = ch->GetPremiumRemainSeconds(i);
  628.  
  629.         if (remain <= 0)
  630.             continue;
  631.  
  632.         ch->AddAffect(AFFECT_PREMIUM_START + i, POINT_NONE, 0, 0, remain, 0, true);
  633.         sys_log(0, "PREMIUM: %s type %d %dmin", ch->GetName(), i, remain);
  634.     }
  635.  
  636.     if (LC_IsEurope())
  637.     {
  638.         ch->block_exp = false;
  639.         if (g_bCheckClientVersion)
  640.         {
  641.             int version = atoi(g_stClientVersion.c_str());
  642.             int date = atoi(d->GetClientVersion());
  643.  
  644.             sys_log(0, "VERSION CHECK %d %d %s %s", version, date, g_stClientVersion.c_str(), d->GetClientVersion());
  645.  
  646.             if (!d->GetClientVersion())
  647.             {
  648.                 d->DelayedDisconnect(10);
  649.             }
  650.             else
  651.             {
  652.                 //if (0 != g_stClientVersion.compare(d->GetClientVersion()))
  653.                 if (version > date)
  654.                 {
  655.                     ch->ChatPacket(CHAT_TYPE_NOTICE, LC_TEXT("클라이언트 버전이 틀려 로그아웃 됩니다. 정상적으로 패치 후 접속하세요."));
  656.                     d->DelayedDisconnect(10);
  657.                     LogManager::instance().HackLog("VERSION_CONFLICT", ch);
  658.  
  659.                     sys_log(0, "VERSION : WRONG VERSION USER : account:%s name:%s hostName:%s server_version:%s client_version:%s",
  660.                             d->GetAccountTable().login,
  661.                             ch->GetName(),
  662.                             d->GetHostName(),
  663.                             g_stClientVersion.c_str(),
  664.                             d->GetClientVersion());
  665.                 }
  666.             }
  667.         }
  668.         else
  669.         {
  670.             sys_log(0, "VERSION : NO CHECK");
  671.         }
  672.     }
  673.     else
  674.     {
  675.         sys_log(0, "VERSION : NO LOGIN");
  676.     }
  677.  
  678.     if (LC_IsEurope() == true)
  679.     {
  680.         if (ch->IsGM() == true)
  681.             ch->ChatPacket(CHAT_TYPE_COMMAND, "ConsoleEnable");
  682.     }
  683.  
  684.     if (ch->GetMapIndex() >= 10000)
  685.     {
  686.         if (CWarMapManager::instance().IsWarMap(ch->GetMapIndex()))
  687.             ch->SetWarMap(CWarMapManager::instance().Find(ch->GetMapIndex()));
  688.         else if (marriage::WeddingManager::instance().IsWeddingMap(ch->GetMapIndex()))
  689.             ch->SetWeddingMap(marriage::WeddingManager::instance().Find(ch->GetMapIndex()));
  690.         else {
  691.             ch->SetDungeon(CDungeonManager::instance().FindByMapIndex(ch->GetMapIndex()));
  692.         }
  693.     }
  694.     else if (CArenaManager::instance().IsArenaMap(ch->GetMapIndex()) == true)
  695.     {
  696.         int memberFlag = CArenaManager::instance().IsMember(ch->GetMapIndex(), ch->GetPlayerID());
  697.         if (memberFlag == MEMBER_OBSERVER)
  698.         {
  699.             ch->SetObserverMode(true);
  700.             ch->SetArenaObserverMode(true);
  701.             if (CArenaManager::instance().RegisterObserverPtr(ch, ch->GetMapIndex(), ch->GetX()/100, ch->GetY()/100))
  702.             {
  703.                 sys_log(0, "ARENA : Observer add failed");
  704.             }
  705.  
  706.             if (ch->IsHorseRiding() == true)
  707.             {
  708.                 ch->StopRiding();
  709.                 ch->HorseSummon(false);
  710.             }
  711.         }
  712.         else if (memberFlag == MEMBER_DUELIST)
  713.         {
  714.             TPacketGCDuelStart duelStart;
  715.             duelStart.header = HEADER_GC_DUEL_START;
  716.             duelStart.wSize = sizeof(TPacketGCDuelStart);
  717.  
  718.             ch->GetDesc()->Packet(&duelStart, sizeof(TPacketGCDuelStart));
  719.  
  720.             if (ch->IsHorseRiding() == true)
  721.             {
  722.                 ch->StopRiding();
  723.                 ch->HorseSummon(false);
  724.             }
  725.  
  726.             LPPARTY pParty = ch->GetParty();
  727.             if (pParty != NULL)
  728.             {
  729.                 if (pParty->GetMemberCount() == 2)
  730.                 {
  731.                     CPartyManager::instance().DeleteParty(pParty);
  732.                 }
  733.                 else
  734.                 {
  735.                     pParty->Quit(ch->GetPlayerID());
  736.                 }
  737.             }
  738.         }
  739.         else if (memberFlag == MEMBER_NO)      
  740.         {
  741.             if (ch->GetGMLevel() == GM_PLAYER)
  742.                 ch->WarpSet(EMPIRE_START_X(ch->GetEmpire()), EMPIRE_START_Y(ch->GetEmpire()));
  743.         }
  744.         else
  745.         {
  746.             // wtf
  747.         }
  748.     }
  749.     else if (ch->GetMapIndex() == 113)
  750.     {
  751.         // ox 이벤트 맵
  752.         if (COXEventManager::instance().Enter(ch) == false)
  753.         {
  754.             // ox 맵 진입 허가가 나지 않음. 플레이어면 마을로 보내자
  755.             if (ch->GetGMLevel() == GM_PLAYER)
  756.                 ch->WarpSet(EMPIRE_START_X(ch->GetEmpire()), EMPIRE_START_Y(ch->GetEmpire()));
  757.         }
  758.     }
  759.     else
  760.     {
  761.         if (CWarMapManager::instance().IsWarMap(ch->GetMapIndex()) ||
  762.                 marriage::WeddingManager::instance().IsWeddingMap(ch->GetMapIndex()))
  763.         {
  764.             if (!test_server)
  765.                 ch->WarpSet(EMPIRE_START_X(ch->GetEmpire()), EMPIRE_START_Y(ch->GetEmpire()));
  766.         }
  767.     }
  768.  
  769.     if (ch->GetHorseLevel() > 0)
  770.     {
  771.         DWORD pid = ch->GetPlayerID();
  772.  
  773.         if (pid != 0 && CHorseNameManager::instance().GetHorseName(pid) == NULL)
  774.             db_clientdesc->DBPacket(HEADER_GD_REQ_HORSE_NAME, 0, &pid, sizeof(DWORD));
  775.     }
  776.  
  777.     // 중립맵에 들어갔을때 안내하기
  778.     if (g_noticeBattleZone)
  779.     {
  780.         if (FN_is_battle_zone(ch))
  781.         {
  782.             ch->ChatPacket(CHAT_TYPE_NOTICE, LC_TEXT("이 맵에선 강제적인 대전이 있을수 도 있습니다."));
  783.             ch->ChatPacket(CHAT_TYPE_NOTICE, LC_TEXT("이 조항에 동의하지 않을시"));
  784.             ch->ChatPacket(CHAT_TYPE_NOTICE, LC_TEXT("본인의 주성 및 부성으로 돌아가시기 바랍니다."));
  785.         }
  786.     }
  787. }
  788.  
  789. void CInputLogin::Empire(LPDESC d, const char * c_pData)
  790. {
  791.     const TPacketCGEmpire* p = reinterpret_cast<const TPacketCGEmpire*>(c_pData);
  792.  
  793.     if (EMPIRE_MAX_NUM <= p->bEmpire)
  794.     {
  795.         d->SetPhase(PHASE_CLOSE);
  796.         return;
  797.     }
  798.  
  799.     const TAccountTable& r = d->GetAccountTable();
  800.  
  801.     if (r.bEmpire != 0)
  802.     {
  803.         for (int i = 0; i < PLAYER_PER_ACCOUNT; ++i)
  804.         {
  805.             if (0 != r.players[i].dwID)
  806.             {
  807.                 sys_err("EmpireSelectFailed %d", r.players[i].dwID);
  808.                 return;
  809.             }
  810.         }
  811.     }
  812.  
  813.     TEmpireSelectPacket pd;
  814.  
  815.     pd.dwAccountID = r.id;
  816.     pd.bEmpire = p->bEmpire;
  817.  
  818.     db_clientdesc->DBPacket(HEADER_GD_EMPIRE_SELECT, d->GetHandle(), &pd, sizeof(pd));
  819. }
  820.  
  821. int CInputLogin::GuildSymbolUpload(LPDESC d, const char* c_pData, size_t uiBytes)
  822. {
  823.     if (uiBytes < sizeof(TPacketCGGuildSymbolUpload))
  824.         return -1;
  825.  
  826.     sys_log(0, "GuildSymbolUpload uiBytes %u", uiBytes);
  827.  
  828.     TPacketCGGuildSymbolUpload* p = (TPacketCGGuildSymbolUpload*) c_pData;
  829.  
  830.     if (uiBytes < p->size)
  831.         return -1;
  832.  
  833.     int iSymbolSize = p->size - sizeof(TPacketCGGuildSymbolUpload);
  834.  
  835.     if (iSymbolSize <= 0 || iSymbolSize > 64 * 1024)
  836.     {
  837.         // 64k 보다 큰 길드 심볼은 올릴수없다
  838.         // 접속을 끊고 무시
  839.         d->SetPhase(PHASE_CLOSE);
  840.         return 0;
  841.     }
  842.  
  843.     // 땅을 소유하지 않은 길드인 경우.
  844.     if (!test_server)
  845.         if (!building::CManager::instance().FindLandByGuild(p->guild_id))
  846.         {
  847.             d->SetPhase(PHASE_CLOSE);
  848.             return 0;
  849.         }
  850.  
  851.     sys_log(0, "GuildSymbolUpload Do Upload %02X%02X%02X%02X %d", c_pData[7], c_pData[8], c_pData[9], c_pData[10], sizeof(*p));
  852.  
  853.     CGuildMarkManager::instance().UploadSymbol(p->guild_id, iSymbolSize, (const BYTE*)(c_pData + sizeof(*p)));
  854.     CGuildMarkManager::instance().SaveSymbol(GUILD_SYMBOL_FILENAME);
  855.     return iSymbolSize;
  856. }
  857.  
  858. void CInputLogin::GuildSymbolCRC(LPDESC d, const char* c_pData)
  859. {
  860.     const TPacketCGSymbolCRC & CGPacket = *((TPacketCGSymbolCRC *) c_pData);
  861.  
  862.     sys_log(0, "GuildSymbolCRC %u %u %u", CGPacket.guild_id, CGPacket.crc, CGPacket.size);
  863.  
  864.     const CGuildMarkManager::TGuildSymbol * pkGS = CGuildMarkManager::instance().GetGuildSymbol(CGPacket.guild_id);
  865.  
  866.     if (!pkGS)
  867.         return;
  868.  
  869.     sys_log(0, "  Server %u %u", pkGS->crc, pkGS->raw.size());
  870.  
  871.     if (pkGS->raw.size() != CGPacket.size || pkGS->crc != CGPacket.crc)
  872.     {
  873.         TPacketGCGuildSymbolData GCPacket;
  874.  
  875.         GCPacket.header = HEADER_GC_SYMBOL_DATA;
  876.         GCPacket.size = sizeof(GCPacket) + pkGS->raw.size();
  877.         GCPacket.guild_id = CGPacket.guild_id;
  878.  
  879.         d->BufferedPacket(&GCPacket, sizeof(GCPacket));
  880.         d->Packet(&pkGS->raw[0], pkGS->raw.size());
  881.  
  882.         sys_log(0, "SendGuildSymbolHead %02X%02X%02X%02X Size %d",
  883.                 pkGS->raw[0], pkGS->raw[1], pkGS->raw[2], pkGS->raw[3], pkGS->raw.size());
  884.     }
  885. }
  886.  
  887. void CInputLogin::GuildMarkUpload(LPDESC d, const char* c_pData)
  888. {
  889.     TPacketCGMarkUpload * p = (TPacketCGMarkUpload *) c_pData;
  890.     CGuildManager& rkGuildMgr = CGuildManager::instance();
  891.     CGuild * pkGuild;
  892.  
  893.     if (!(pkGuild = rkGuildMgr.FindGuild(p->gid)))
  894.     {
  895.         sys_err("MARK_SERVER: GuildMarkUpload: no guild. gid %u", p->gid);
  896.         return;
  897.     }
  898.  
  899.     if (pkGuild->GetLevel() < guild_mark_min_level)
  900.     {
  901.         sys_log(0, "MARK_SERVER: GuildMarkUpload: level < %u (%u)", guild_mark_min_level, pkGuild->GetLevel());
  902.         return;
  903.     }
  904.  
  905.     CGuildMarkManager & rkMarkMgr = CGuildMarkManager::instance();
  906.  
  907.     sys_log(0, "MARK_SERVER: GuildMarkUpload: gid %u", p->gid);
  908.  
  909.     bool isEmpty = true;
  910.  
  911.     for (DWORD iPixel = 0; iPixel < SGuildMark::SIZE; ++iPixel)
  912.         if (*((DWORD *) p->image + iPixel) != 0x00000000)
  913.             isEmpty = false;
  914.  
  915.     if (isEmpty)
  916.         rkMarkMgr.DeleteMark(p->gid);
  917.     else
  918.         rkMarkMgr.SaveMark(p->gid, p->image);
  919. }
  920.  
  921. void CInputLogin::GuildMarkIDXList(LPDESC d, const char* c_pData)
  922. {
  923.     CGuildMarkManager & rkMarkMgr = CGuildMarkManager::instance();
  924.    
  925.     DWORD bufSize = sizeof(WORD) * 2 * rkMarkMgr.GetMarkCount();
  926.     char * buf = NULL;
  927.  
  928.     if (bufSize > 0)
  929.     {
  930.         buf = (char *) malloc(bufSize);
  931.         rkMarkMgr.CopyMarkIdx(buf);
  932.     }
  933.  
  934.     TPacketGCMarkIDXList p;
  935.     p.header = HEADER_GC_MARK_IDXLIST;
  936.     p.bufSize = sizeof(p) + bufSize;
  937.     p.count = rkMarkMgr.GetMarkCount();
  938.  
  939.     if (buf)
  940.     {
  941.         d->BufferedPacket(&p, sizeof(p));
  942.         d->LargePacket(buf, bufSize);
  943.         free(buf);
  944.     }
  945.     else
  946.         d->Packet(&p, sizeof(p));
  947.  
  948.     sys_log(0, "MARK_SERVER: GuildMarkIDXList %d bytes sent.", p.bufSize);
  949. }
  950.  
  951. void CInputLogin::GuildMarkCRCList(LPDESC d, const char* c_pData)
  952. {
  953.     TPacketCGMarkCRCList * pCG = (TPacketCGMarkCRCList *) c_pData;
  954.  
  955.     std::map<BYTE, const SGuildMarkBlock *> mapDiffBlocks;
  956.     CGuildMarkManager::instance().GetDiffBlocks(pCG->imgIdx, pCG->crclist, mapDiffBlocks);
  957.  
  958.     DWORD blockCount = 0;
  959.     TEMP_BUFFER buf(1024 * 1024); // 1M 버퍼
  960.  
  961.     for (auto it = mapDiffBlocks.begin(); it != mapDiffBlocks.end(); ++it)
  962.     {
  963.         BYTE posBlock = it->first;
  964.         const SGuildMarkBlock & rkBlock = *it->second;
  965.  
  966.         buf.write(&posBlock, sizeof(BYTE));
  967.         buf.write(&rkBlock.m_sizeCompBuf, sizeof(DWORD));
  968.         buf.write(rkBlock.m_abCompBuf, rkBlock.m_sizeCompBuf);
  969.  
  970.         ++blockCount;
  971.     }
  972.  
  973.     TPacketGCMarkBlock pGC;
  974.  
  975.     pGC.header = HEADER_GC_MARK_BLOCK;
  976.     pGC.imgIdx = pCG->imgIdx;
  977.     pGC.bufSize = buf.size() + sizeof(TPacketGCMarkBlock);
  978.     pGC.count = blockCount;
  979.  
  980.     sys_log(0, "MARK_SERVER: Sending blocks. (imgIdx %u diff %u size %u)", pCG->imgIdx, mapDiffBlocks.size(), pGC.bufSize);
  981.  
  982.     if (buf.size() > 0)
  983.     {
  984.         d->BufferedPacket(&pGC, sizeof(TPacketGCMarkBlock));
  985.         d->LargePacket(buf.read_peek(), buf.size());
  986.     }
  987.     else
  988.         d->Packet(&pGC, sizeof(TPacketGCMarkBlock));
  989. }
  990.  
  991. int CInputLogin::Analyze(LPDESC d, BYTE bHeader, const char * c_pData)
  992. {
  993.     int iExtraLen = 0;
  994.  
  995.     switch (bHeader)
  996.     {
  997.         case HEADER_CG_PONG:
  998.             Pong(d);
  999.             break;
  1000.  
  1001.         case HEADER_CG_TIME_SYNC:
  1002.             Handshake(d, c_pData);
  1003.             break;
  1004.  
  1005.         case HEADER_CG_LOGIN:
  1006.             Login(d, c_pData);
  1007.             break;
  1008.  
  1009.         case HEADER_CG_LOGIN2:
  1010.             LoginByKey(d, c_pData);
  1011.             break;
  1012.  
  1013.         case HEADER_CG_CHARACTER_SELECT:
  1014.             CharacterSelect(d, c_pData);
  1015.             break;
  1016.  
  1017.         case HEADER_CG_CHARACTER_CREATE:
  1018.             CharacterCreate(d, c_pData);
  1019.             break;
  1020.  
  1021.         case HEADER_CG_CHARACTER_DELETE:
  1022.             CharacterDelete(d, c_pData);
  1023.             break;
  1024.  
  1025.         case HEADER_CG_ENTERGAME:
  1026.             Entergame(d, c_pData);
  1027.             break;
  1028.  
  1029.         case HEADER_CG_EMPIRE:
  1030.             Empire(d, c_pData);
  1031.             break;
  1032.  
  1033.         case HEADER_CG_MOVE:
  1034.             break;
  1035.  
  1036.             ///////////////////////////////////////
  1037.             // Guild Mark
  1038.             /////////////////////////////////////
  1039.         case HEADER_CG_MARK_CRCLIST:
  1040.             GuildMarkCRCList(d, c_pData);
  1041.             break;
  1042.  
  1043.         case HEADER_CG_MARK_IDXLIST:
  1044.             GuildMarkIDXList(d, c_pData);
  1045.             break;
  1046.  
  1047.         case HEADER_CG_MARK_UPLOAD:
  1048.             GuildMarkUpload(d, c_pData);
  1049.             break;
  1050.  
  1051.             //////////////////////////////////////
  1052.             // Guild Symbol
  1053.             /////////////////////////////////////
  1054.         case HEADER_CG_GUILD_SYMBOL_UPLOAD:
  1055.             if ((iExtraLen = GuildSymbolUpload(d, c_pData, m_iBufferLeft)) < 0)
  1056.                 return -1;
  1057.             break;
  1058.  
  1059.         case HEADER_CG_SYMBOL_CRC:
  1060.             GuildSymbolCRC(d, c_pData);
  1061.             break;
  1062.             /////////////////////////////////////
  1063.  
  1064.         case HEADER_CG_HACK:
  1065.             break;
  1066.  
  1067.         case HEADER_CG_CHANGE_NAME:
  1068.             ChangeName(d, c_pData);
  1069.             break;
  1070.        
  1071.         case HEADER_CG_CLIENT_VERSION:
  1072.             Version(d->GetCharacter(), c_pData);
  1073.             break;
  1074.  
  1075.         case HEADER_CG_CLIENT_VERSION2:
  1076.             Version(d->GetCharacter(), c_pData);
  1077.             break;
  1078.  
  1079.         default:
  1080.             sys_err("login phase does not handle this packet! header %d", bHeader);
  1081.             //d->SetPhase(PHASE_CLOSE);
  1082.             return (0);
  1083.     }
  1084.  
  1085.     return (iExtraLen);
  1086. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement