Ciucciamelo 0 Posted May 20, 2021 Share Posted May 20, 2021 (edited) Hi guys, I have a little problem with skill_group. When I choose doctrine I skill_group goes to 110 or 111 and stamina and alignment are busted. I'm checking in all the files and the query breaks in execution for player save, can anyone help me? Thx! Edited August 18, 2022 by Metin2 Dev Core X - External 2 Internal Link to comment Share on other sites More sharing options...
Active Member iMerv3 768 Posted May 20, 2021 Active Member Share Posted May 20, 2021 (edited) @CiucciameloUpload common\tables.h & db\clientmanagerplayer.cpp Edited May 20, 2021 by iMerv3 Link to comment Share on other sites More sharing options...
Ciucciamelo 0 Posted May 21, 2021 Author Share Posted May 21, 2021 (edited) Thx @iMerv3! Tables.h Spoiler #ifndef __INC_TABLES_H__ #define __INC_TABLES_H__ #include "length.h" #include "item_length.h" #include "CommonDefines.h" #include "service.h" typedef DWORD IDENT; enum { HEADER_GD_LOGIN = 1, HEADER_GD_LOGOUT = 2, HEADER_GD_PLAYER_LOAD = 3, HEADER_GD_PLAYER_SAVE = 4, HEADER_GD_PLAYER_CREATE = 5, HEADER_GD_PLAYER_DELETE = 6, HEADER_GD_LOGIN_KEY = 7, // 8 empty HEADER_GD_BOOT = 9, HEADER_GD_PLAYER_COUNT = 10, HEADER_GD_QUEST_SAVE = 11, HEADER_GD_SAFEBOX_LOAD = 12, HEADER_GD_SAFEBOX_SAVE = 13, HEADER_GD_SAFEBOX_CHANGE_SIZE = 14, HEADER_GD_EMPIRE_SELECT = 15, HEADER_GD_SAFEBOX_CHANGE_PASSWORD = 16, HEADER_GD_SAFEBOX_CHANGE_PASSWORD_SECOND = 17, // Not really a packet, used internal HEADER_GD_DIRECT_ENTER = 18, HEADER_GD_GUILD_SKILL_UPDATE = 19, HEADER_GD_GUILD_EXP_UPDATE = 20, HEADER_GD_GUILD_ADD_MEMBER = 21, HEADER_GD_GUILD_REMOVE_MEMBER = 22, HEADER_GD_GUILD_CHANGE_GRADE = 23, HEADER_GD_GUILD_CHANGE_MEMBER_DATA = 24, HEADER_GD_GUILD_DISBAND = 25, HEADER_GD_GUILD_WAR = 26, HEADER_GD_GUILD_WAR_SCORE = 27, HEADER_GD_GUILD_CREATE = 28, HEADER_GD_ITEM_SAVE = 30, HEADER_GD_ITEM_DESTROY = 31, HEADER_GD_ADD_AFFECT = 32, HEADER_GD_REMOVE_AFFECT = 33, HEADER_GD_HIGHSCORE_REGISTER = 34, HEADER_GD_ITEM_FLUSH = 35, HEADER_GD_PARTY_CREATE = 36, HEADER_GD_PARTY_DELETE = 37, HEADER_GD_PARTY_ADD = 38, HEADER_GD_PARTY_REMOVE = 39, HEADER_GD_PARTY_STATE_CHANGE = 40, HEADER_GD_PARTY_HEAL_USE = 41, HEADER_GD_FLUSH_CACHE = 42, HEADER_GD_RELOAD_PROTO = 43, HEADER_GD_CHANGE_NAME = 44, HEADER_GD_SMS = 45, HEADER_GD_GUILD_CHANGE_LADDER_POINT = 46, HEADER_GD_GUILD_USE_SKILL = 47, HEADER_GD_REQUEST_EMPIRE_PRIV = 48, HEADER_GD_REQUEST_GUILD_PRIV = 49, HEADER_GD_MONEY_LOG = 50, HEADER_GD_GUILD_DEPOSIT_MONEY = 51, HEADER_GD_GUILD_WITHDRAW_MONEY = 52, HEADER_GD_GUILD_WITHDRAW_MONEY_GIVE_REPLY = 53, HEADER_GD_REQUEST_CHARACTER_PRIV = 54, HEADER_GD_SET_EVENT_FLAG = 55, HEADER_GD_PARTY_SET_MEMBER_LEVEL = 56, HEADER_GD_GUILD_WAR_BET = 57, HEADER_GD_CREATE_OBJECT = 60, HEADER_GD_DELETE_OBJECT = 61, HEADER_GD_UPDATE_LAND = 62, HEADER_GD_MARRIAGE_ADD = 70, HEADER_GD_MARRIAGE_UPDATE = 71, HEADER_GD_MARRIAGE_REMOVE = 72, HEADER_GD_WEDDING_REQUEST = 73, HEADER_GD_WEDDING_READY = 74, HEADER_GD_WEDDING_END = 75, HEADER_GD_AUTH_LOGIN = 100, HEADER_GD_LOGIN_BY_KEY = 101, HEADER_GD_BILLING_EXPIRE = 104, HEADER_GD_VCARD = 105, HEADER_GD_BILLING_CHECK = 106, HEADER_GD_MALL_LOAD = 107, HEADER_GD_MYSHOP_PRICELIST_UPDATE = 108, HEADER_GD_MYSHOP_PRICELIST_REQ = 109, HEADER_GD_BLOCK_CHAT = 110, // PCBANG_IP_LIST_BY_AUTH HEADER_GD_PCBANG_REQUEST_IP_LIST = 111, HEADER_GD_PCBANG_CLEAR_IP_LIST = 112, HEADER_GD_PCBANG_INSERT_IP = 113, // END_OF_PCBANG_IP_LIST_BY_AUTH HEADER_GD_HAMMER_OF_TOR = 114, HEADER_GD_RELOAD_ADMIN = 115, HEADER_GD_BREAK_MARRIAGE = 116, HEADER_GD_ELECT_MONARCH = 117, HEADER_GD_CANDIDACY = 118, HEADER_GD_ADD_MONARCH_MONEY = 119, HEADER_GD_TAKE_MONARCH_MONEY = 120, HEADER_GD_COME_TO_VOTE = 121, HEADER_GD_RMCANDIDACY = 122, HEADER_GD_SETMONARCH = 123, HEADER_GD_RMMONARCH = 124, HEADER_GD_DEC_MONARCH_MONEY = 125, HEADER_GD_CHANGE_MONARCH_LORD = 126, HEADER_GD_BLOCK_COUNTRY_IP = 127, HEADER_GD_BLOCK_EXCEPTION = 128, HEADER_GD_REQ_CHANGE_GUILD_MASTER = 129, HEADER_GD_REQ_SPARE_ITEM_ID_RANGE = 130, HEADER_GD_UPDATE_HORSE_NAME = 131, HEADER_GD_REQ_HORSE_NAME = 132, HEADER_GD_DC = 133, HEADER_GD_VALID_LOGOUT = 134, HEADER_GD_REQUEST_CHARGE_CASH = 137, HEADER_GD_DELETE_AWARDID = 138, // delete gift notify icon HEADER_GD_UPDATE_CHANNELSTATUS = 139, HEADER_GD_REQUEST_CHANNELSTATUS = 140, #ifdef __ENABLE_NEW_OFFLINESHOP__ HEADER_GD_NEW_OFFLINESHOP = 141, #endif HEADER_GD_SETUP = 0xff, /////////////////////////////////////////////// HEADER_DG_NOTICE = 1, HEADER_DG_LOGIN_SUCCESS = 30, HEADER_DG_LOGIN_NOT_EXIST = 31, HEADER_DG_LOGIN_WRONG_PASSWD = 33, HEADER_DG_LOGIN_ALREADY = 34, HEADER_DG_PLAYER_LOAD_SUCCESS = 35, HEADER_DG_PLAYER_LOAD_FAILED = 36, HEADER_DG_PLAYER_CREATE_SUCCESS = 37, HEADER_DG_PLAYER_CREATE_ALREADY = 38, HEADER_DG_PLAYER_CREATE_FAILED = 39, HEADER_DG_PLAYER_DELETE_SUCCESS = 40, HEADER_DG_PLAYER_DELETE_FAILED = 41, HEADER_DG_ITEM_LOAD = 42, HEADER_DG_BOOT = 43, HEADER_DG_QUEST_LOAD = 44, HEADER_DG_SAFEBOX_LOAD = 45, HEADER_DG_SAFEBOX_CHANGE_SIZE = 46, HEADER_DG_SAFEBOX_WRONG_PASSWORD = 47, HEADER_DG_SAFEBOX_CHANGE_PASSWORD_ANSWER = 48, HEADER_DG_EMPIRE_SELECT = 49, HEADER_DG_AFFECT_LOAD = 50, HEADER_DG_MALL_LOAD = 51, HEADER_DG_DIRECT_ENTER = 55, HEADER_DG_GUILD_SKILL_UPDATE = 56, HEADER_DG_GUILD_SKILL_RECHARGE = 57, HEADER_DG_GUILD_EXP_UPDATE = 58, HEADER_DG_PARTY_CREATE = 59, HEADER_DG_PARTY_DELETE = 60, HEADER_DG_PARTY_ADD = 61, HEADER_DG_PARTY_REMOVE = 62, HEADER_DG_PARTY_STATE_CHANGE = 63, HEADER_DG_PARTY_HEAL_USE = 64, HEADER_DG_PARTY_SET_MEMBER_LEVEL = 65, HEADER_DG_TIME = 90, HEADER_DG_ITEM_ID_RANGE = 91, HEADER_DG_GUILD_ADD_MEMBER = 92, HEADER_DG_GUILD_REMOVE_MEMBER = 93, HEADER_DG_GUILD_CHANGE_GRADE = 94, HEADER_DG_GUILD_CHANGE_MEMBER_DATA = 95, HEADER_DG_GUILD_DISBAND = 96, HEADER_DG_GUILD_WAR = 97, HEADER_DG_GUILD_WAR_SCORE = 98, HEADER_DG_GUILD_TIME_UPDATE = 99, HEADER_DG_GUILD_LOAD = 100, HEADER_DG_GUILD_LADDER = 101, HEADER_DG_GUILD_SKILL_USABLE_CHANGE = 102, HEADER_DG_GUILD_MONEY_CHANGE = 103, HEADER_DG_GUILD_WITHDRAW_MONEY_GIVE = 104, HEADER_DG_SET_EVENT_FLAG = 105, HEADER_DG_GUILD_WAR_RESERVE_ADD = 106, HEADER_DG_GUILD_WAR_RESERVE_DEL = 107, HEADER_DG_GUILD_WAR_BET = 108, HEADER_DG_RELOAD_PROTO = 120, HEADER_DG_CHANGE_NAME = 121, HEADER_DG_AUTH_LOGIN = 122, HEADER_DG_CHANGE_EMPIRE_PRIV = 124, HEADER_DG_CHANGE_GUILD_PRIV = 125, HEADER_DG_MONEY_LOG = 126, HEADER_DG_CHANGE_CHARACTER_PRIV = 127, HEADER_DG_BILLING_REPAIR = 128, HEADER_DG_BILLING_EXPIRE = 129, HEADER_DG_BILLING_LOGIN = 130, HEADER_DG_VCARD = 131, HEADER_DG_BILLING_CHECK = 132, HEADER_DG_CREATE_OBJECT = 140, HEADER_DG_DELETE_OBJECT = 141, HEADER_DG_UPDATE_LAND = 142, HEADER_DG_MARRIAGE_ADD = 150, HEADER_DG_MARRIAGE_UPDATE = 151, HEADER_DG_MARRIAGE_REMOVE = 152, HEADER_DG_WEDDING_REQUEST = 153, HEADER_DG_WEDDING_READY = 154, HEADER_DG_WEDDING_START = 155, HEADER_DG_WEDDING_END = 156, HEADER_DG_MYSHOP_PRICELIST_RES = 157, HEADER_DG_RELOAD_ADMIN = 158, HEADER_DG_BREAK_MARRIAGE = 159, HEADER_DG_ELECT_MONARCH = 160, HEADER_DG_CANDIDACY = 161, HEADER_DG_ADD_MONARCH_MONEY = 162, HEADER_DG_TAKE_MONARCH_MONEY = 163, HEADER_DG_COME_TO_VOTE = 164, HEADER_DG_RMCANDIDACY = 165, HEADER_DG_SETMONARCH = 166, HEADER_DG_RMMONARCH = 167, HEADER_DG_DEC_MONARCH_MONEY = 168, HEADER_DG_CHANGE_MONARCH_LORD_ACK = 169, HEADER_DG_UPDATE_MONARCH_INFO = 170, HEADER_DG_BLOCK_COUNTRY_IP = 171, HEADER_DG_BLOCK_EXCEPTION = 172, HEADER_DG_ACK_CHANGE_GUILD_MASTER = 173, HEADER_DG_ACK_SPARE_ITEM_ID_RANGE = 174, HEADER_DG_UPDATE_HORSE_NAME = 175, HEADER_DG_ACK_HORSE_NAME = 176, HEADER_DG_NEED_LOGIN_LOG = 177, HEADER_DG_RESULT_CHARGE_CASH = 179, HEADER_DG_ITEMAWARD_INFORMER = 180, //gift notify HEADER_DG_RESPOND_CHANNELSTATUS = 181, #ifdef __ENABLE_NEW_OFFLINESHOP__ HEADER_DG_NEW_OFFLINESHOP = 182, #endif HEADER_DG_MAP_LOCATIONS = 0xfe, HEADER_DG_P2P = 0xff, HEADER_GP_CONFIRM_PASSPOD = 1, HEADER_PG_CONFIRM_PASSPOD = 2, }; enum E_PASSPOD { E_PASSPOD_SUCCESS = 0, E_PASSPOD_FAILED_PASSPOD_ERROR, E_PASSPOD_FAILED_USER_NOT_FOUND, E_PASSPOD_FAILED_SYSTEM_NOT_FOUND, E_PASSPOD_FAILED_TOKEN_DISABLED, E_PASSPOD_FAILED_EMPTY, }; typedef struct SRequestConfirmPasspod { int pid; char passpod[MAX_PASSPOD + 1]; char login[LOGIN_MAX_LEN + 1]; } RequestConfirmPasspod; typedef struct SResultConfirmPasspod { int pid; int ret_code; char login[LOGIN_MAX_LEN + 1]; } ResultConfirmPasspod; /* ---------------------------------------------- * table * ---------------------------------------------- */ /* game Server -> DB Server */ #pragma pack(1) enum ERequestChargeType { ERequestCharge_Cash = 0, ERequestCharge_Mileage, }; typedef struct SRequestChargeCash { DWORD dwAID; // id(primary key) - Account Table DWORD dwAmount; ERequestChargeType eChargeType; } TRequestChargeCash; typedef struct SSimplePlayer { DWORD dwID; char szName[CHARACTER_NAME_MAX_LEN + 1]; BYTE byJob; BYTE byLevel; DWORD dwPlayMinutes; BYTE byST, byHT, byDX, byIQ; WORD wMainPart; BYTE bChangeName; WORD wHairPart; #ifdef ENABLE_ACCE_SYSTEM WORD wAccePart; #endif BYTE bDummy[4]; long x, y; long lAddr; WORD wPort; BYTE skill_group; } TSimplePlayer; typedef struct SAccountTable { DWORD id; char login[LOGIN_MAX_LEN + 1]; char passwd[PASSWD_MAX_LEN + 1]; char social_id[SOCIAL_ID_MAX_LEN + 1]; char status[ACCOUNT_STATUS_MAX_LEN + 1]; BYTE bEmpire; TSimplePlayer players[PLAYER_PER_ACCOUNT]; } TAccountTable; typedef struct SPacketDGCreateSuccess { BYTE bAccountCharacterIndex; TSimplePlayer player; } TPacketDGCreateSuccess; typedef struct TPlayerItemAttribute { BYTE bType; short sValue; } TPlayerItemAttribute; typedef struct SPlayerItem { DWORD id; BYTE window; WORD pos; DWORD count; DWORD vnum; #ifdef FREEZE_BONUS DWORD frozen; #endif long alSockets[ITEM_SOCKET_MAX_NUM]; TPlayerItemAttribute aAttr[ITEM_ATTRIBUTE_MAX_NUM]; DWORD owner; } TPlayerItem; typedef struct SQuickslot { BYTE type; BYTE pos; } TQuickslot; typedef struct SPlayerSkill { BYTE bMasterType; BYTE bLevel; time_t tNextRead; } TPlayerSkill; struct THorseInfo { BYTE bLevel; BYTE bRiding; short sStamina; short sHealth; DWORD dwHorseHealthDropTime; }; typedef struct SPlayerTable { DWORD id; char name[CHARACTER_NAME_MAX_LEN + 1]; char ip[IP_ADDRESS_LENGTH + 1]; WORD job; BYTE voice; BYTE level; BYTE level_step; short st, ht, dx, iq; DWORD exp; INT gold; BYTE dir; INT x, y, z; INT lMapIndex; long lExitX, lExitY; long lExitMapIndex; // @fixme301 int hp; int sp; short sRandomHP; short sRandomSP; int playtime; short stat_point; short skill_point; short sub_skill_point; short horse_skill_point; TPlayerSkill skills[SKILL_MAX_NUM]; TQuickslot quickslot[QUICKSLOT_MAX_NUM]; BYTE part_base; WORD parts[PART_MAX_NUM]; short stamina; BYTE skill_group; long lAlignment; char szMobile[MOBILE_MAX_LEN + 1]; short stat_reset_count; THorseInfo horse; DWORD logoff_interval; int aiPremiumTimes[PREMIUM_MAX_NUM]; } TPlayerTable; typedef struct SMobSkillLevel { DWORD dwVnum; BYTE bLevel; } TMobSkillLevel; typedef struct SEntityTable { DWORD dwVnum; } TEntityTable; typedef struct SMobTable : public SEntityTable { char szName[CHARACTER_NAME_MAX_LEN + 1]; char szLocaleName[CHARACTER_NAME_MAX_LEN + 1]; BYTE bType; // Monster, NPC BYTE bRank; // PAWN, KNIGHT, KING BYTE bBattleType; // MELEE, etc.. BYTE bLevel; // Level BYTE bSize; DWORD dwGoldMin; DWORD dwGoldMax; DWORD dwExp; DWORD dwMaxHP; BYTE bRegenCycle; BYTE bRegenPercent; WORD wDef; DWORD dwAIFlag; DWORD dwRaceFlag; DWORD dwImmuneFlag; BYTE bStr, bDex, bCon, bInt; DWORD dwDamageRange[2]; short sAttackSpeed; short sMovingSpeed; BYTE bAggresiveHPPct; WORD wAggressiveSight; WORD wAttackRange; char cEnchants[MOB_ENCHANTS_MAX_NUM]; char cResists[MOB_RESISTS_MAX_NUM]; DWORD dwResurrectionVnum; DWORD dwDropItemVnum; BYTE bMountCapacity; BYTE bOnClickType; BYTE bEmpire; char szFolder[64 + 1]; float fDamMultiply; DWORD dwSummonVnum; DWORD dwDrainSP; DWORD dwMobColor; DWORD dwPolymorphItemVnum; TMobSkillLevel Skills[MOB_SKILL_MAX_NUM]; BYTE bBerserkPoint; BYTE bStoneSkinPoint; BYTE bGodSpeedPoint; BYTE bDeathBlowPoint; BYTE bRevivePoint; } TMobTable; typedef struct SSkillTable { DWORD dwVnum; char szName[32 + 1]; BYTE bType; BYTE bMaxLevel; DWORD dwSplashRange; char szPointOn[64]; char szPointPoly[100 + 1]; char szSPCostPoly[100 + 1]; char szDurationPoly[100 + 1]; char szDurationSPCostPoly[100 + 1]; char szCooldownPoly[100 + 1]; char szMasterBonusPoly[100 + 1]; //char szAttackGradePoly[100 + 1]; char szGrandMasterAddSPCostPoly[100 + 1]; DWORD dwFlag; DWORD dwAffectFlag; // Data for secondary skill char szPointOn2[64]; char szPointPoly2[100 + 1]; char szDurationPoly2[100 + 1]; DWORD dwAffectFlag2; // Data for grand master point char szPointOn3[64]; char szPointPoly3[100 + 1]; char szDurationPoly3[100 + 1]; BYTE bLevelStep; BYTE bLevelLimit; DWORD preSkillVnum; BYTE preSkillLevel; long lMaxHit; char szSplashAroundDamageAdjustPoly[100 + 1]; BYTE bSkillAttrType; DWORD dwTargetRange; } TSkillTable; typedef struct SShopItemTable { DWORD vnum; BYTE count; TItemPos pos; DWORD price; BYTE display_pos; } TShopItemTable; typedef struct SShopTable { DWORD dwVnum; DWORD dwNPCVnum; BYTE byItemCount; TShopItemTable items[SHOP_HOST_ITEM_MAX_NUM]; } TShopTable; #define QUEST_NAME_MAX_LEN 32 #define QUEST_STATE_MAX_LEN 64 typedef struct SQuestTable { DWORD dwPID; char szName[QUEST_NAME_MAX_LEN + 1]; char szState[QUEST_STATE_MAX_LEN + 1]; long lValue; } TQuestTable; typedef struct SItemLimit { BYTE bType; long lValue; } TItemLimit; typedef struct SItemApply { BYTE bType; long lValue; } TItemApply; typedef struct SItemTable : public SEntityTable { DWORD dwVnumRange; char szName[ITEM_NAME_MAX_LEN + 1]; char szLocaleName[ITEM_NAME_MAX_LEN + 1]; BYTE bType; BYTE bSubType; BYTE bWeight; BYTE bSize; DWORD dwAntiFlags; DWORD dwFlags; DWORD dwWearFlags; DWORD dwImmuneFlag; DWORD dwGold; DWORD dwShopBuyPrice; TItemLimit aLimits[ITEM_LIMIT_MAX_NUM]; TItemApply aApplies[ITEM_APPLY_MAX_NUM]; long alValues[ITEM_VALUES_MAX_NUM]; long alSockets[ITEM_SOCKET_MAX_NUM]; DWORD dwRefinedVnum; WORD wRefineSet; BYTE bAlterToMagicItemPct; BYTE bSpecular; BYTE bGainSocketPct; short int sAddonType; char cLimitRealTimeFirstUseIndex; char cLimitTimerBasedOnWearIndex; } TItemTable; struct TItemAttrTable { TItemAttrTable() : dwApplyIndex(0), dwProb(0) { szApply[0] = 0; memset(&lValues, 0, sizeof(lValues)); memset(&bMaxLevelBySet, 0, sizeof(bMaxLevelBySet)); } char szApply[APPLY_NAME_MAX_LEN + 1]; DWORD dwApplyIndex; DWORD dwProb; long lValues[ITEM_ATTRIBUTE_MAX_LEVEL]; BYTE bMaxLevelBySet[ATTRIBUTE_SET_MAX_NUM]; }; typedef struct SConnectTable { char login[LOGIN_MAX_LEN + 1]; IDENT ident; } TConnectTable; typedef struct SLoginPacket { char login[LOGIN_MAX_LEN + 1]; char passwd[PASSWD_MAX_LEN + 1]; } TLoginPacket; typedef struct SPlayerLoadPacket { DWORD account_id; DWORD player_id; BYTE account_index; } TPlayerLoadPacket; typedef struct SPlayerCreatePacket { char login[LOGIN_MAX_LEN + 1]; char passwd[PASSWD_MAX_LEN + 1]; DWORD account_id; BYTE account_index; TPlayerTable player_table; } TPlayerCreatePacket; typedef struct SPlayerDeletePacket { char login[LOGIN_MAX_LEN + 1]; DWORD player_id; BYTE account_index; //char name[CHARACTER_NAME_MAX_LEN + 1]; char private_code[8]; } TPlayerDeletePacket; typedef struct SLogoutPacket { char login[LOGIN_MAX_LEN + 1]; char passwd[PASSWD_MAX_LEN + 1]; } TLogoutPacket; typedef struct SPlayerCountPacket { DWORD dwCount; } TPlayerCountPacket; #define SAFEBOX_MAX_NUM 135 #define SAFEBOX_PASSWORD_MAX_LEN 6 typedef struct SSafeboxTable { DWORD dwID; BYTE bSize; DWORD dwGold; WORD wItemCount; } TSafeboxTable; typedef struct SSafeboxChangeSizePacket { DWORD dwID; BYTE bSize; } TSafeboxChangeSizePacket; typedef struct SSafeboxLoadPacket { DWORD dwID; char szLogin[LOGIN_MAX_LEN + 1]; char szPassword[SAFEBOX_PASSWORD_MAX_LEN + 1]; } TSafeboxLoadPacket; typedef struct SSafeboxChangePasswordPacket { DWORD dwID; char szOldPassword[SAFEBOX_PASSWORD_MAX_LEN + 1]; char szNewPassword[SAFEBOX_PASSWORD_MAX_LEN + 1]; } TSafeboxChangePasswordPacket; typedef struct SSafeboxChangePasswordPacketAnswer { BYTE flag; } TSafeboxChangePasswordPacketAnswer; typedef struct SEmpireSelectPacket { DWORD dwAccountID; BYTE bEmpire; } TEmpireSelectPacket; typedef struct SPacketGDSetup { char szPublicIP[16]; // Public IP which listen to users BYTE bChannel; WORD wListenPort; WORD wP2PPort; long alMaps[MAP_ALLOW_LIMIT]; DWORD dwLoginCount; BYTE bAuthServer; } TPacketGDSetup; typedef struct SPacketDGMapLocations { BYTE bCount; } TPacketDGMapLocations; typedef struct SMapLocation { long alMaps[MAP_ALLOW_LIMIT]; char szHost[MAX_HOST_LENGTH + 1]; WORD wPort; } TMapLocation; typedef struct SPacketDGP2P { char szHost[MAX_HOST_LENGTH + 1]; WORD wPort; BYTE bChannel; } TPacketDGP2P; typedef struct SPacketGDDirectEnter { char login[LOGIN_MAX_LEN + 1]; char passwd[PASSWD_MAX_LEN + 1]; BYTE index; } TPacketGDDirectEnter; typedef struct SPacketDGDirectEnter { TAccountTable accountTable; TPlayerTable playerTable; } TPacketDGDirectEnter; typedef struct SPacketGuildSkillUpdate { DWORD guild_id; int amount; BYTE skill_levels[12]; BYTE skill_point; BYTE save; } TPacketGuildSkillUpdate; typedef struct SPacketGuildExpUpdate { DWORD guild_id; int amount; } TPacketGuildExpUpdate; typedef struct SPacketGuildChangeMemberData { DWORD guild_id; DWORD pid; DWORD offer; BYTE level; BYTE grade; } TPacketGuildChangeMemberData; typedef struct SPacketDGLoginAlready { char szLogin[LOGIN_MAX_LEN + 1]; } TPacketDGLoginAlready; typedef struct TPacketAffectElement { DWORD dwType; BYTE bApplyOn; long lApplyValue; DWORD dwFlag; long lDuration; long lSPCost; } TPacketAffectElement; typedef struct SPacketGDAddAffect { DWORD dwPID; TPacketAffectElement elem; } TPacketGDAddAffect; typedef struct SPacketGDRemoveAffect { DWORD dwPID; DWORD dwType; BYTE bApplyOn; } TPacketGDRemoveAffect; typedef struct SPacketGDHighscore { DWORD dwPID; long lValue; char cDir; char szBoard[21]; } TPacketGDHighscore; typedef struct SPacketPartyCreate { DWORD dwLeaderPID; } TPacketPartyCreate; typedef struct SPacketPartyDelete { DWORD dwLeaderPID; } TPacketPartyDelete; typedef struct SPacketPartyAdd { DWORD dwLeaderPID; DWORD dwPID; BYTE bState; } TPacketPartyAdd; typedef struct SPacketPartyRemove { DWORD dwLeaderPID; DWORD dwPID; } TPacketPartyRemove; typedef struct SPacketPartyStateChange { DWORD dwLeaderPID; DWORD dwPID; BYTE bRole; BYTE bFlag; } TPacketPartyStateChange; typedef struct SPacketPartySetMemberLevel { DWORD dwLeaderPID; DWORD dwPID; BYTE bLevel; } TPacketPartySetMemberLevel; typedef struct SPacketGDBoot { DWORD dwItemIDRange[2]; char szIP[16]; } TPacketGDBoot; typedef struct SPacketGuild { DWORD dwGuild; DWORD dwInfo; } TPacketGuild; typedef struct SPacketGDGuildAddMember { DWORD dwPID; DWORD dwGuild; BYTE bGrade; } TPacketGDGuildAddMember; typedef struct SPacketDGGuildMember { DWORD dwPID; DWORD dwGuild; BYTE bGrade; BYTE isGeneral; BYTE bJob; BYTE bLevel; DWORD dwOffer; char szName[CHARACTER_NAME_MAX_LEN + 1]; } TPacketDGGuildMember; typedef struct SPacketGuildWar { BYTE bType; BYTE bWar; DWORD dwGuildFrom; DWORD dwGuildTo; long lWarPrice; long lInitialScore; } TPacketGuildWar; typedef struct SPacketGuildWarScore { DWORD dwGuildGainPoint; DWORD dwGuildOpponent; long lScore; long lBetScore; } TPacketGuildWarScore; typedef struct SRefineMaterial { DWORD vnum; int count; } TRefineMaterial; typedef struct SRefineTable { //DWORD src_vnum; //DWORD result_vnum; DWORD id; BYTE material_count; int cost; int prob; TRefineMaterial materials[REFINE_MATERIAL_MAX_NUM]; } TRefineTable; typedef struct SBanwordTable { char szWord[BANWORD_MAX_LEN + 1]; } TBanwordTable; typedef struct SPacketGDChangeName { DWORD pid; char name[CHARACTER_NAME_MAX_LEN + 1]; } TPacketGDChangeName; typedef struct SPacketDGChangeName { DWORD pid; char name[CHARACTER_NAME_MAX_LEN + 1]; } TPacketDGChangeName; typedef struct SPacketGuildLadder { DWORD dwGuild; long lLadderPoint; long lWin; long lDraw; long lLoss; } TPacketGuildLadder; typedef struct SPacketGuildLadderPoint { DWORD dwGuild; long lChange; } TPacketGuildLadderPoint; typedef struct SPacketGDSMS { char szFrom[CHARACTER_NAME_MAX_LEN + 1]; char szTo[CHARACTER_NAME_MAX_LEN + 1]; char szMobile[MOBILE_MAX_LEN + 1]; char szMsg[SMS_MAX_LEN + 1]; } TPacketGDSMS; typedef struct SPacketGuildUseSkill { DWORD dwGuild; DWORD dwSkillVnum; DWORD dwCooltime; } TPacketGuildUseSkill; typedef struct SPacketGuildSkillUsableChange { DWORD dwGuild; DWORD dwSkillVnum; BYTE bUsable; } TPacketGuildSkillUsableChange; typedef struct SPacketGDLoginKey { DWORD dwAccountID; DWORD dwLoginKey; } TPacketGDLoginKey; typedef struct SPacketGDAuthLogin { DWORD dwID; DWORD dwLoginKey; char szLogin[LOGIN_MAX_LEN + 1]; char szSocialID[SOCIAL_ID_MAX_LEN + 1]; DWORD adwClientKey[4]; BYTE bBillType; DWORD dwBillID; int iPremiumTimes[PREMIUM_MAX_NUM]; } TPacketGDAuthLogin; typedef struct SPacketGDLoginByKey { char szLogin[LOGIN_MAX_LEN + 1]; DWORD dwLoginKey; DWORD adwClientKey[4]; char szIP[MAX_HOST_LENGTH + 1]; } TPacketGDLoginByKey; typedef struct SPacketGiveGuildPriv { BYTE type; int value; DWORD guild_id; time_t duration_sec; } TPacketGiveGuildPriv; typedef struct SPacketGiveEmpirePriv { BYTE type; int value; BYTE empire; time_t duration_sec; } TPacketGiveEmpirePriv; typedef struct SPacketGiveCharacterPriv { BYTE type; int value; DWORD pid; } TPacketGiveCharacterPriv; typedef struct SPacketRemoveGuildPriv { BYTE type; DWORD guild_id; } TPacketRemoveGuildPriv; typedef struct SPacketRemoveEmpirePriv { BYTE type; BYTE empire; } TPacketRemoveEmpirePriv; typedef struct SPacketDGChangeCharacterPriv { BYTE type; int value; DWORD pid; BYTE bLog; } TPacketDGChangeCharacterPriv; typedef struct SPacketDGChangeGuildPriv { BYTE type; int value; DWORD guild_id; BYTE bLog; time_t end_time_sec; } TPacketDGChangeGuildPriv; typedef struct SPacketDGChangeEmpirePriv { BYTE type; int value; BYTE empire; BYTE bLog; time_t end_time_sec; } TPacketDGChangeEmpirePriv; typedef struct SPacketMoneyLog { BYTE type; DWORD vnum; INT gold; } TPacketMoneyLog; typedef struct SPacketGDGuildMoney { DWORD dwGuild; INT iGold; } TPacketGDGuildMoney; typedef struct SPacketDGGuildMoneyChange { DWORD dwGuild; INT iTotalGold; } TPacketDGGuildMoneyChange; typedef struct SPacketDGGuildMoneyWithdraw { DWORD dwGuild; INT iChangeGold; } TPacketDGGuildMoneyWithdraw; typedef struct SPacketGDGuildMoneyWithdrawGiveReply { DWORD dwGuild; INT iChangeGold; BYTE bGiveSuccess; } TPacketGDGuildMoneyWithdrawGiveReply; typedef struct SPacketSetEventFlag { char szFlagName[EVENT_FLAG_NAME_MAX_LEN + 1]; long lValue; } TPacketSetEventFlag; typedef struct SPacketBillingLogin { DWORD dwLoginKey; BYTE bLogin; } TPacketBillingLogin; typedef struct SPacketBillingRepair { DWORD dwLoginKey; char szLogin[LOGIN_MAX_LEN + 1]; char szHost[MAX_HOST_LENGTH + 1]; } TPacketBillingRepair; typedef struct SPacketBillingExpire { char szLogin[LOGIN_MAX_LEN + 1]; BYTE bBillType; DWORD dwRemainSeconds; } TPacketBillingExpire; typedef struct SPacketLoginOnSetup { DWORD dwID; char szLogin[LOGIN_MAX_LEN + 1]; char szSocialID[SOCIAL_ID_MAX_LEN + 1]; char szHost[MAX_HOST_LENGTH + 1]; DWORD dwLoginKey; DWORD adwClientKey[4]; } TPacketLoginOnSetup; typedef struct SPacketGDCreateObject { DWORD dwVnum; DWORD dwLandID; INT lMapIndex; INT x, y; float xRot; float yRot; float zRot; } TPacketGDCreateObject; typedef struct SPacketGDHammerOfTor { DWORD key; DWORD delay; } TPacketGDHammerOfTor; typedef struct SPacketGDVCard { DWORD dwID; char szSellCharacter[CHARACTER_NAME_MAX_LEN + 1]; char szSellAccount[LOGIN_MAX_LEN + 1]; char szBuyCharacter[CHARACTER_NAME_MAX_LEN + 1]; char szBuyAccount[LOGIN_MAX_LEN + 1]; } TPacketGDVCard; typedef struct SGuildReserve { DWORD dwID; DWORD dwGuildFrom; DWORD dwGuildTo; DWORD dwTime; BYTE bType; long lWarPrice; long lInitialScore; bool bStarted; DWORD dwBetFrom; DWORD dwBetTo; long lPowerFrom; long lPowerTo; long lHandicap; } TGuildWarReserve; typedef struct { DWORD dwWarID; char szLogin[LOGIN_MAX_LEN + 1]; DWORD dwGold; DWORD dwGuild; } TPacketGDGuildWarBet; // Marriage typedef struct { DWORD dwPID1; DWORD dwPID2; time_t tMarryTime; char szName1[CHARACTER_NAME_MAX_LEN + 1]; char szName2[CHARACTER_NAME_MAX_LEN + 1]; } TPacketMarriageAdd; typedef struct { DWORD dwPID1; DWORD dwPID2; INT iLovePoint; BYTE byMarried; } TPacketMarriageUpdate; typedef struct { DWORD dwPID1; DWORD dwPID2; } TPacketMarriageRemove; typedef struct { DWORD dwPID1; DWORD dwPID2; } TPacketWeddingRequest; typedef struct { DWORD dwPID1; DWORD dwPID2; DWORD dwMapIndex; } TPacketWeddingReady; typedef struct { DWORD dwPID1; DWORD dwPID2; } TPacketWeddingStart; typedef struct { DWORD dwPID1; DWORD dwPID2; } TPacketWeddingEnd; typedef struct SPacketMyshopPricelistHeader { DWORD dwOwnerID; BYTE byCount; } TPacketMyshopPricelistHeader; typedef struct SItemPriceInfo { DWORD dwVnum; DWORD dwPrice; } TItemPriceInfo; typedef struct SItemPriceListTable { DWORD dwOwnerID; BYTE byCount; TItemPriceInfo aPriceInfo[SHOP_PRICELIST_MAX_NUM]; } TItemPriceListTable; typedef struct { char szName[CHARACTER_NAME_MAX_LEN + 1]; long lDuration; } TPacketBlockChat; // PCBANG_IP_LIST typedef struct SPacketPCBangIP { DWORD id; DWORD ip; } TPacketPCBangIP; // END_OF_PCBANG_IP_LIST //ADMIN_MANAGER typedef struct TAdminInfo { int m_ID; char m_szAccount[32]; char m_szName[32]; char m_szContactIP[16]; char m_szServerIP[16]; int m_Authority; } tAdminInfo; //END_ADMIN_MANAGER //BOOT_LOCALIZATION struct tLocale { char szValue[32]; char szKey[32]; }; //BOOT_LOCALIZATION //RELOAD_ADMIN typedef struct SPacketReloadAdmin { char szIP[16]; } TPacketReloadAdmin; //END_RELOAD_ADMIN typedef struct TMonarchInfo { DWORD pid[4]; int64_t money[4]; char name[4][32]; char date[4][32]; } MonarchInfo; typedef struct TMonarchElectionInfo { DWORD pid; DWORD selectedpid; char date[32]; } MonarchElectionInfo; typedef struct tMonarchCandidacy { DWORD pid; char name[32]; char date[32]; } MonarchCandidacy; typedef struct tChangeMonarchLord { BYTE bEmpire; DWORD dwPID; } TPacketChangeMonarchLord; typedef struct tChangeMonarchLordACK { BYTE bEmpire; DWORD dwPID; char szName[32]; char szDate[32]; } TPacketChangeMonarchLordACK; // Block Country Ip typedef struct tBlockCountryIp { DWORD ip_from; DWORD ip_to; } TPacketBlockCountryIp; enum EBlockExceptionCommand { BLOCK_EXCEPTION_CMD_ADD = 1, BLOCK_EXCEPTION_CMD_DEL = 2, }; // Block Exception Account typedef struct tBlockException { BYTE cmd; // 1 == add, 2 == delete char login[LOGIN_MAX_LEN + 1]; }TPacketBlockException; typedef struct tChangeGuildMaster { DWORD dwGuildID; DWORD idFrom; DWORD idTo; } TPacketChangeGuildMaster; typedef struct tItemIDRange { DWORD dwMin; DWORD dwMax; DWORD dwUsableItemIDMin; } TItemIDRangeTable; typedef struct tUpdateHorseName { DWORD dwPlayerID; char szHorseName[CHARACTER_NAME_MAX_LEN + 1]; } TPacketUpdateHorseName; typedef struct tDC { char login[LOGIN_MAX_LEN + 1]; } TPacketDC; typedef struct tNeedLoginLogInfo { DWORD dwPlayerID; } TPacketNeedLoginLogInfo; typedef struct tItemAwardInformer { char login[LOGIN_MAX_LEN + 1]; char command[20]; unsigned int vnum; } TPacketItemAwardInfromer; typedef struct tDeleteAwardID { DWORD dwID; } TPacketDeleteAwardID; typedef struct SChannelStatus { short nPort; BYTE bStatus; } TChannelStatus; #ifdef __ENABLE_NEW_OFFLINESHOP__ typedef struct SPacketGDNewOfflineShop { BYTE bSubHeader; } TPacketGDNewOfflineShop; typedef struct SPacketDGNewOfflineShop { BYTE bSubHeader; } TPacketDGNewOfflineShop; namespace offlineshop { enum class ExpirationType { EXPIRE_NONE, EXPIRE_REAL_TIME, EXPIRE_REAL_TIME_FIRST_USE, }; typedef struct SPriceInfo { long long illYang; #ifdef __ENABLE_CHEQUE_SYSTEM__ int iCheque; #endif SPriceInfo() : illYang(0) #ifdef ENABLE_CHEQUE_SYSTEM ,iCheque(0) #endif {} bool operator < (const SPriceInfo& rItem) const { return GetTotalYangAmount() < rItem.GetTotalYangAmount(); } long long GetTotalYangAmount() const { long long total = illYang; #ifdef __ENABLE_CHEQUE_SYSTEM__ total += (long long) YANG_PER_CHEQUE * (long long) iCheque; #endif return total; } } TPriceInfo; typedef struct SItemInfoEx { DWORD dwVnum; DWORD dwCount; long alSockets[ITEM_SOCKET_MAX_NUM]; TPlayerItemAttribute aAttr[ITEM_ATTRIBUTE_MAX_NUM]; #ifdef __ENABLE_CHANGELOOK_SYSTEM__ DWORD dwTransmutation; #endif ExpirationType expiration; } TItemInfoEx; typedef struct SItemInfo { DWORD dwOwnerID, dwItemID; TPriceInfo price; TItemInfoEx item; } TItemInfo; typedef struct SOfferInfo { DWORD dwOfferID, dwOwnerID, dwItemID, dwOffererID; TPriceInfo price; bool bNoticed, bAccepted; char szBuyerName[CHARACTER_NAME_MAX_LEN+1]; } TOfferInfo; typedef struct SAuctionInfo { DWORD dwOwnerID; char szOwnerName[CHARACTER_NAME_MAX_LEN + 1]; DWORD dwDuration; TPriceInfo init_price; TItemInfoEx item; } TAuctionInfo; typedef struct SAuctionOfferInfo { TPriceInfo price; DWORD dwOwnerID; DWORD dwBuyerID; char szBuyerName[CHARACTER_NAME_MAX_LEN + 1]; } TAuctionOfferInfo; typedef struct SValutesInfoa { long long illYang; #ifdef __ENABLE_CHEQUE_SYSTEM__ int iCheque; #endif void operator +=(const SValutesInfoa& r) { illYang += r.illYang; #ifdef __ENABLE_CHEQUE_SYSTEM__ iCheque += r.iCheque; #endif } void operator -=(const SValutesInfoa& r) { illYang -= r.illYang; #ifdef __ENABLE_CHEQUE_SYSTEM__ iCheque -= r.iCheque; #endif } SValutesInfoa() : illYang(0) #ifdef ENABLE_CHEQUE_SYSTEM , iCheque(0) #endif {} } TValutesInfo; typedef struct SShopInfo { DWORD dwOwnerID; DWORD dwDuration; char szName[OFFLINE_SHOP_NAME_MAX_LEN]; DWORD dwCount; } TShopInfo; #ifdef ENABLE_IRA_REWORK typedef struct SShopPosition { long lMapIndex; long x, y; BYTE bChannel; } TShopPosition; #endif enum eNewOfflineshopSubHeaderGD { SUBHEADER_GD_BUY_ITEM = 0, SUBHEADER_GD_BUY_LOCK_ITEM, SUBHEADER_GD_CANNOT_BUY_LOCK_ITEM, SUBHEADER_GD_EDIT_ITEM, SUBHEADER_GD_REMOVE_ITEM, SUBHEADER_GD_ADD_ITEM, SUBHEADER_GD_SHOP_FORCE_CLOSE, SUBHEADER_GD_SHOP_CREATE_NEW, SUBHEADER_GD_SHOP_CHANGE_NAME, SUBHEADER_GD_OFFER_CREATE, SUBHEADER_GD_OFFER_NOTIFIED, SUBHEADER_GD_OFFER_ACCEPT, SUBHEADER_GD_OFFER_CANCEL, SUBHEADER_GD_SAFEBOX_GET_ITEM, SUBHEADER_GD_SAFEBOX_GET_VALUTES, SUBHEADER_GD_SAFEBOX_ADD_ITEM, SUBHEADER_GD_AUCTION_CREATE, SUBHEADER_GD_AUCTION_ADD_OFFER, }; typedef struct SSubPacketGDBuyItem { DWORD dwOwnerID, dwItemID, dwGuestID; } TSubPacketGDBuyItem; typedef struct SSubPacketGDLockBuyItem { DWORD dwOwnerID, dwItemID, dwGuestID; } TSubPacketGDLockBuyItem; typedef struct SSubPacketGDCannotBuyLockItem { DWORD dwOwnerID, dwItemID; } TSubPacketGDCannotBuyLockItem; typedef struct SSubPacketGDEditItem { DWORD dwOwnerID, dwItemID; TPriceInfo priceInfo; } TSubPacketGDEditItem; typedef struct SSubPacketGDRemoveItem { DWORD dwOwnerID; DWORD dwItemID; } TSubPacketGDRemoveItem; typedef struct SSubPacketGDAddItem { DWORD dwOwnerID; TItemInfo itemInfo; } TSubPacketGDAddItem; typedef struct SSubPacketGDShopForceClose { DWORD dwOwnerID; } TSubPacketGDShopForceClose; typedef struct SSubPacketGDShopCreateNew { TShopInfo shop; #ifdef ENABLE_IRA_REWORK TShopPosition pos; #endif } TSubPacketGDShopCreateNew; typedef struct SSubPacketGDShopChangeName { DWORD dwOwnerID; char szName[OFFLINE_SHOP_NAME_MAX_LEN]; } TSubPacketGDShopChangeName; typedef struct SSubPacketGDOfferCreate { DWORD dwOwnerID, dwItemID; TOfferInfo offer; } TSubPacketGDOfferCreate; typedef struct SSubPacketGDOfferCancel { DWORD dwOfferID; DWORD dwOwnerID; }TSubPacketGDOfferCancel; typedef struct SSubPacketGDOfferNotified { DWORD dwOwnerID, dwOfferID; } TSubPacketGDOfferNotified; typedef struct SSubPacketGDOfferAccept { DWORD dwOwnerID, dwOfferID; } TSubPacketGDOfferAccept; typedef struct SSubPacketGDSafeboxGetItem { DWORD dwOwnerID; DWORD dwItemID; } TSubPacketGDSafeboxGetItem; typedef struct SSubPacketGDSafeboxAddItem { DWORD dwOwnerID; TItemInfoEx item; } TSubPacketGDSafeboxAddItem; typedef struct SSubPacketGDSafeboxGetValutes { DWORD dwOwnerID; TValutesInfo valute; } TSubPacketGDSafeboxGetValutes; typedef struct SSubPacketGDAuctionCreate { TAuctionInfo auction; } TSubPacketGDAuctionCreate; typedef struct SSubPacketGDAuctionAddOffer { TAuctionOfferInfo offer; } TSubPacketGDAuctionAddOffer; enum eSubHeaderDGNewOfflineshop { SUBHEADER_DG_BUY_ITEM, SUBHEADER_DG_LOCKED_BUY_ITEM, SUBHEADER_DG_EDIT_ITEM, SUBHEADER_DG_REMOVE_ITEM, SUBHEADER_DG_ADD_ITEM, SUBHEADER_DG_SHOP_FORCE_CLOSE, SUBHEADER_DG_SHOP_CREATE_NEW, SUBHEADER_DG_SHOP_CHANGE_NAME, SUBHEADER_DG_SHOP_EXPIRED, SUBHEADER_DG_OFFER_CREATE, SUBHEADER_DG_OFFER_NOTIFIED, SUBHEADER_DG_OFFER_ACCEPT, SUBHEADER_DG_OFFER_CANCEL, SUBHEADER_DG_LOAD_TABLES, SUBHEADER_DG_SAFEBOX_ADD_ITEM, SUBHEADER_DG_SAFEBOX_ADD_VALUTES, SUBHEADER_DG_SAFEBOX_LOAD, SUBHEADER_DG_SAFEBOX_EXPIRED_ITEM, SUBHEADER_DG_AUCTION_CREATE, SUBHEADER_DG_AUCTION_ADD_OFFER, SUBHEADER_DG_AUCTION_EXPIRED, }; typedef struct SSubPacketDGBuyItem { DWORD dwOwnerID, dwItemID, dwBuyerID; } TSubPacketDGBuyItem; typedef struct SSubPacketDGLockedBuyItem { DWORD dwOwnerID, dwItemID, dwBuyerID; } TSubPacketDGLockedBuyItem; typedef struct SSubPacketDGEditItem { DWORD dwOwnerID, dwItemID; TPriceInfo price; } TSubPacketDGEditItem; typedef struct SSubPacketDGRemoveItem { DWORD dwOwnerID, dwItemID; } TSubPacketDGRemoveItem; typedef struct SSubPacketDGAddItem { DWORD dwOwnerID, dwItemID; TItemInfo item; } TSubPacketDGAddItem; typedef struct SSubPacketDGShopForceClose { DWORD dwOwnerID; } TSubPacketDGShopForceClose; typedef struct SSubPacketDGShopCreateNew { TShopInfo shop; #ifdef ENABLE_IRA_REWORK TShopPosition pos; #endif } TSubPacketDGShopCreateNew; typedef struct SSubPacketDGShopChangeName { DWORD dwOwnerID; char szName[OFFLINE_SHOP_NAME_MAX_LEN]; } TSubPacketDGShopChangeName; typedef struct SSubPacketDGOfferCreate { DWORD dwOwnerID, dwItemID; TOfferInfo offer; } TSubPacketDGOfferCreate; typedef struct SSubPacketDGOfferCancel { DWORD dwOfferID; DWORD dwOwnerID; bool IsRemovingItem; } TSubPacketDGOfferCancel; typedef struct SSubPacketDGOfferNotified { DWORD dwOwnerID, dwOfferID; } TSubPacketDGOfferNotified; typedef struct SSubPacketDGOfferAccept { DWORD dwOwnerID, dwOfferID; } TSubPacketDGOfferAccept; typedef struct SSubPacketDGLoadTables { DWORD dwShopCount; DWORD dwOfferCount; DWORD dwAuctionCount; DWORD dwAuctionOfferCount; } TSubPacketDGLoadTables; typedef struct SSubPacketDGShopExpired { DWORD dwOwnerID; } TSubPacketDGShopExpired; typedef struct SSubPacketDGSafeboxAddItem { DWORD dwOwnerID, dwItemID; TItemInfoEx item; } TSubPacketDGSafeboxAddItem; typedef struct SSubPacketDGSafeboxAddValutes { DWORD dwOwnerID; TValutesInfo valute; } TSubPacketDGSafeboxAddValutes; typedef struct SSubPacketDGSafeboxLoad { DWORD dwOwnerID; TValutesInfo valute; DWORD dwItemCount; } TSubPacketDGSafeboxLoad; typedef struct SSubPacketDGSafeboxExpiredItem { DWORD dwOwnerID; DWORD dwItemID; } TSubPacketDGSafeboxExpiredItem; typedef struct SSubPacketDGAuctionCreate { TAuctionInfo auction; } TSubPacketDGAuctionCreate; typedef struct SSubPacketDGAuctionAddOffer { TAuctionOfferInfo offer; } TSubPacketDGAuctionAddOffer; typedef struct SSubPacketDGAuctionExpired { DWORD dwOwnerID; } TSubPacketDGAuctionExpired; } #endif #pragma pack() #endif ClientManagerPlayer.cpp Spoiler #include "stdafx.h" #include "ClientManager.h" #include "Main.h" #include "QID.h" #include "ItemAwardManager.h" #include "HB.h" #include "Cache.h" extern bool g_bHotBackup; extern std::string g_stLocale; extern int g_test_server; extern int g_log; // // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // !!!!!!!!!!! IMPORTANT !!!!!!!!!!!! // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // // Check all SELECT syntax on item table before change this function!!! // bool CreateItemTableFromRes(MYSQL_RES * res, std::vector<TPlayerItem> * pVec, DWORD dwPID) { if (!res) { pVec->clear(); return true; } int rows; if ((rows = mysql_num_rows(res)) <= 0) { pVec->clear(); return true; } pVec->resize(rows); for (int i = 0; i < rows; ++i) { MYSQL_ROW row = mysql_fetch_row(res); TPlayerItem & item = pVec->at(i); int cur = 0; // Check all SELECT syntax on item table before change this function!!! // Check all SELECT syntax on item table before change this function!!! // Check all SELECT syntax on item table before change this function!!! str_to_number(item.id, row[cur++]); str_to_number(item.window, row[cur++]); str_to_number(item.pos, row[cur++]); str_to_number(item.count, row[cur++]); str_to_number(item.vnum, row[cur++]); str_to_number(item.alSockets[0], row[cur++]); str_to_number(item.alSockets[1], row[cur++]); str_to_number(item.alSockets[2], row[cur++]); for (int j = 0; j < ITEM_ATTRIBUTE_MAX_NUM; j++) { str_to_number(item.aAttr[j].bType, row[cur++]); str_to_number(item.aAttr[j].sValue, row[cur++]); } item.owner = dwPID; } return true; } size_t CreatePlayerSaveQuery(char * pszQuery, size_t querySize, TPlayerTable * pkTab) { size_t queryLen; queryLen = snprintf(pszQuery, querySize, "UPDATE player%s SET " "job = %d, " "voice = %d, " "dir = %d, " "x = %d, " "y = %d, " "z = %d, " "map_index = %d, " "exit_x = %ld, " "exit_y = %ld, " "exit_map_index = %ld, " "hp = %d, " "mp = %d, " "stamina = %d, " "random_hp = %d, " "random_sp = %d, " "playtime = %d, " "level = %d, " "level_step = %d, " "st = %d, " "ht = %d, " "dx = %d, " "iq = %d, " "gold = %d, " "exp = %u, " "stat_point = %d, " "skill_point = %d, " "sub_skill_point = %d, " "stat_reset_count = %d, " "ip = '%s', " "part_main = %d, " "part_hair = %d, " #ifdef ENABLE_ACCE_SYSTEM "part_acce = %d, " #endif "last_play = NOW(), " "skill_group = %d, " "alignment = %ld, " "horse_level = %d, " "horse_riding = %d, " "horse_hp = %d, " "horse_hp_droptime = %u, " "horse_stamina = %d, " "horse_skill_point = %d, " , GetTablePostfix(), pkTab->job, pkTab->voice, pkTab->dir, pkTab->x, pkTab->y, pkTab->z, pkTab->lMapIndex, pkTab->lExitX, pkTab->lExitY, pkTab->lExitMapIndex, pkTab->hp, pkTab->sp, pkTab->stamina, pkTab->sRandomHP, pkTab->sRandomSP, pkTab->playtime, pkTab->level, pkTab->level_step, pkTab->st, pkTab->ht, pkTab->dx, pkTab->iq, pkTab->gold, pkTab->exp, pkTab->stat_point, pkTab->skill_point, pkTab->sub_skill_point, pkTab->stat_reset_count, pkTab->ip, pkTab->parts[PART_MAIN], pkTab->parts[PART_HAIR], #ifdef ENABLE_ACCE_SYSTEM pkTab->parts[PART_ACCE], #endif pkTab->skill_group, pkTab->lAlignment, pkTab->horse.bLevel, pkTab->horse.bRiding, pkTab->horse.sHealth, pkTab->horse.dwHorseHealthDropTime, pkTab->horse.sStamina, pkTab->horse_skill_point); static char text[8192 + 1]; CDBManager::instance().EscapeString(text, pkTab->skills, sizeof(pkTab->skills)); queryLen += snprintf(pszQuery + queryLen, querySize - queryLen, "skill_level = '%s', ", text); CDBManager::instance().EscapeString(text, pkTab->quickslot, sizeof(pkTab->quickslot)); queryLen += snprintf(pszQuery + queryLen, querySize - queryLen, "quickslot = '%s' ", text); queryLen += snprintf(pszQuery + queryLen, querySize - queryLen, " WHERE id=%d", pkTab->id); return queryLen; } CPlayerTableCache * CClientManager::GetPlayerCache(DWORD id) { TPlayerTableCacheMap::iterator it = m_map_playerCache.find(id); if (it == m_map_playerCache.end()) return NULL; TPlayerTable* pTable = it->second->Get(false); pTable->logoff_interval = GetCurrentTime() - it->second->GetLastUpdateTime(); return it->second; } void CClientManager::PutPlayerCache(TPlayerTable * pNew) { CPlayerTableCache * c; c = GetPlayerCache(pNew->id); if (!c) { c = new CPlayerTableCache; m_map_playerCache.insert(TPlayerTableCacheMap::value_type(pNew->id, c)); } if (g_bHotBackup) PlayerHB::instance().Put(pNew->id); c->Put(pNew); } /* * PLAYER LOAD */ void CClientManager::QUERY_PLAYER_LOAD(CPeer * peer, DWORD dwHandle, TPlayerLoadPacket * packet) { CPlayerTableCache * c; TPlayerTable * pTab; // // CLoginData * pLoginData = GetLoginDataByAID(packet->account_id); if (pLoginData) { for (int n = 0; n < PLAYER_PER_ACCOUNT; ++n) if (pLoginData->GetAccountRef().players[n].dwID != 0) DeleteLogoutPlayer(pLoginData->GetAccountRef().players[n].dwID); } //---------------------------------------------------------------- // --------------------------------------------------------------- //---------------------------------- //---------------------------------- if ((c = GetPlayerCache(packet->player_id))) { CLoginData * pkLD = GetLoginDataByAID(packet->account_id); if (!pkLD || pkLD->IsPlay()) { sys_log(0, "PLAYER_LOAD_ERROR: LoginData %p IsPlay %d", pkLD, pkLD ? pkLD->IsPlay() : 0); peer->EncodeHeader(HEADER_DG_PLAYER_LOAD_FAILED, dwHandle, 0); return; } pTab = c->Get(); pkLD->SetPlay(true); SendLoginToBilling(pkLD, true); thecore_memcpy(pTab->aiPremiumTimes, pkLD->GetPremiumPtr(), sizeof(pTab->aiPremiumTimes)); peer->EncodeHeader(HEADER_DG_PLAYER_LOAD_SUCCESS, dwHandle, sizeof(TPlayerTable)); peer->Encode(pTab, sizeof(TPlayerTable)); if (packet->player_id != pkLD->GetLastPlayerID()) { TPacketNeedLoginLogInfo logInfo; logInfo.dwPlayerID = packet->player_id; pkLD->SetLastPlayerID( packet->player_id ); peer->EncodeHeader( HEADER_DG_NEED_LOGIN_LOG, dwHandle, sizeof(TPacketNeedLoginLogInfo) ); peer->Encode( &logInfo, sizeof(TPacketNeedLoginLogInfo) ); } char szQuery[1024] = { 0, }; TItemCacheSet * pSet = GetItemCacheSet(pTab->id); sys_log(0, "[PLAYER_LOAD] ID %s pid %d gold %d ", pTab->name, pTab->id, pTab->gold); //-------------------------------------------- //-------------------------------------------- ///////////////////////////////////////////// ///////////////////////////////////////////// if (pSet) { static std::vector<TPlayerItem> s_items; s_items.resize(pSet->size()); DWORD dwCount = 0; TItemCacheSet::iterator it = pSet->begin(); while (it != pSet->end()) { CItemCache * c = *it++; TPlayerItem * p = c->Get(); if (p->vnum) thecore_memcpy(&s_items[dwCount++], p, sizeof(TPlayerItem)); } if (g_test_server) sys_log(0, "ITEM_CACHE: HIT! %s count: %u", pTab->name, dwCount); peer->EncodeHeader(HEADER_DG_ITEM_LOAD, dwHandle, sizeof(DWORD) + sizeof(TPlayerItem) * dwCount); peer->EncodeDWORD(dwCount); if (dwCount) peer->Encode(&s_items[0], sizeof(TPlayerItem) * dwCount); // Quest snprintf(szQuery, sizeof(szQuery), "SELECT dwPID,szName,szState,lValue FROM quest%s WHERE dwPID=%d AND lValue<>0", GetTablePostfix(), pTab->id); CDBManager::instance().ReturnQuery(szQuery, QID_QUEST, peer->GetHandle(), new ClientHandleInfo(dwHandle,0,packet->account_id)); // Affect snprintf(szQuery, sizeof(szQuery), "SELECT dwPID,bType,bApplyOn,lApplyValue,dwFlag,lDuration,lSPCost FROM affect%s WHERE dwPID=%d", GetTablePostfix(), pTab->id); // @fixme402 ClientHandleInfo+pTab->id CDBManager::instance().ReturnQuery(szQuery, QID_AFFECT, peer->GetHandle(), new ClientHandleInfo(dwHandle, pTab->id)); } ///////////////////////////////////////////// ///////////////////////////////////////////// else { snprintf(szQuery, sizeof(szQuery), "SELECT id,`window`+0,pos,count,vnum,socket0,socket1,socket2,attrtype0,attrvalue0,attrtype1,attrvalue1,attrtype2,attrvalue2,attrtype3,attrvalue3,attrtype4,attrvalue4,attrtype5,attrvalue5,attrtype6,attrvalue6 " "FROM item%s WHERE owner_id=%d AND (`window` in ('INVENTORY','EQUIPMENT','DRAGON_SOUL_INVENTORY','BELT_INVENTORY'))", GetTablePostfix(), pTab->id); CDBManager::instance().ReturnQuery(szQuery, QID_ITEM, peer->GetHandle(), new ClientHandleInfo(dwHandle, pTab->id)); snprintf(szQuery, sizeof(szQuery), "SELECT dwPID, szName, szState, lValue FROM quest%s WHERE dwPID=%d", GetTablePostfix(), pTab->id); CDBManager::instance().ReturnQuery(szQuery, QID_QUEST, peer->GetHandle(), new ClientHandleInfo(dwHandle, pTab->id)); snprintf(szQuery, sizeof(szQuery), "SELECT dwPID, bType, bApplyOn, lApplyValue, dwFlag, lDuration, lSPCost FROM affect%s WHERE dwPID=%d", GetTablePostfix(), pTab->id); CDBManager::instance().ReturnQuery(szQuery, QID_AFFECT, peer->GetHandle(), new ClientHandleInfo(dwHandle, pTab->id)); } //ljw //return; } //---------------------------------- //---------------------------------- else { sys_log(0, "[PLAYER_LOAD] Load from PlayerDB pid[%d]", packet->player_id); char queryStr[QUERY_MAX_LEN]; //-------------------------------------------------------------- //-------------------------------------------------------------- snprintf(queryStr, sizeof(queryStr), "SELECT " "id,name,job,voice,dir,x,y,z,map_index,exit_x,exit_y,exit_map_index,hp,mp,stamina,random_hp,random_sp,playtime," "gold,level,level_step,st,ht,dx,iq,exp," "stat_point,skill_point,sub_skill_point,stat_reset_count,part_base,part_hair," #ifdef ENABLE_ACCE_SYSTEM "part_acce, " #endif "skill_level,quickslot,skill_group,alignment,mobile,horse_level,horse_riding,horse_hp,horse_hp_droptime,horse_stamina," "UNIX_TIMESTAMP(NOW())-UNIX_TIMESTAMP(last_play),horse_skill_point FROM player%s WHERE id=%d", GetTablePostfix(), packet->player_id); ClientHandleInfo * pkInfo = new ClientHandleInfo(dwHandle, packet->player_id); pkInfo->account_id = packet->account_id; CDBManager::instance().ReturnQuery(queryStr, QID_PLAYER, peer->GetHandle(), pkInfo); //-------------------------------------------------------------- //-------------------------------------------------------------- snprintf(queryStr, sizeof(queryStr), "SELECT id,`window`+0,pos,count,vnum,socket0,socket1,socket2,attrtype0,attrvalue0,attrtype1,attrvalue1,attrtype2,attrvalue2,attrtype3,attrvalue3,attrtype4,attrvalue4,attrtype5,attrvalue5,attrtype6,attrvalue6 " "FROM item%s WHERE owner_id=%d AND (`window` in ('INVENTORY','EQUIPMENT','DRAGON_SOUL_INVENTORY','BELT_INVENTORY'))", GetTablePostfix(), packet->player_id); CDBManager::instance().ReturnQuery(queryStr, QID_ITEM, peer->GetHandle(), new ClientHandleInfo(dwHandle, packet->player_id)); //-------------------------------------------------------------- //-------------------------------------------------------------- snprintf(queryStr, sizeof(queryStr), "SELECT dwPID,szName,szState,lValue FROM quest%s WHERE dwPID=%d", GetTablePostfix(), packet->player_id); CDBManager::instance().ReturnQuery(queryStr, QID_QUEST, peer->GetHandle(), new ClientHandleInfo(dwHandle, packet->player_id,packet->account_id)); //-------------------------------------------------------------- //-------------------------------------------------------------- snprintf(queryStr, sizeof(queryStr), "SELECT dwPID,bType,bApplyOn,lApplyValue,dwFlag,lDuration,lSPCost FROM affect%s WHERE dwPID=%d", GetTablePostfix(), packet->player_id); CDBManager::instance().ReturnQuery(queryStr, QID_AFFECT, peer->GetHandle(), new ClientHandleInfo(dwHandle, packet->player_id)); } #ifdef __ENABLE_NEW_OFFLINESHOP__ OfflineshopLoadShopSafebox(peer, packet->player_id); #endif } void CClientManager::ItemAward(CPeer * peer,char* login) { char login_t[LOGIN_MAX_LEN + 1] = ""; strlcpy(login_t,login,LOGIN_MAX_LEN + 1); std::set<TItemAward *> * pSet = ItemAwardManager::instance().GetByLogin(login_t); if(pSet == NULL) return; typeof(pSet->begin()) it = pSet->begin(); while(it != pSet->end() ) { TItemAward * pItemAward = *(it++); char* whyStr = pItemAward->szWhy; char cmdStr[100] = ""; strcpy(cmdStr,whyStr); char command[20] = ""; // @fixme203 directly GetCommand instead of strcpy GetCommand(cmdStr, command); if( !(strcmp(command,"GIFT") )) { TPacketItemAwardInfromer giftData; strcpy(giftData.login, pItemAward->szLogin); strcpy(giftData.command, command); giftData.vnum = pItemAward->dwVnum; ForwardPacket(HEADER_DG_ITEMAWARD_INFORMER,&giftData,sizeof(TPacketItemAwardInfromer)); } } } char* CClientManager::GetCommand(char* str, char* command) // @fixme203 { char* tok; if( str[0] == '[' ) { tok = strtok(str,"]"); strcat(command,&tok[1]); } return command; } bool CreatePlayerTableFromRes(MYSQL_RES * res, TPlayerTable * pkTab) { if (mysql_num_rows(res) == 0) return false; memset(pkTab, 0, sizeof(TPlayerTable)); MYSQL_ROW row = mysql_fetch_row(res); int col = 0; // "id,name,job,voice,dir,x,y,z,map_index,exit_x,exit_y,exit_map_index,hp,mp,stamina,random_hp,random_sp,playtime," // "gold,level,level_step,st,ht,dx,iq,exp," // "stat_point,skill_point,sub_skill_point,stat_reset_count,part_base,part_hair," // "skill_level,quickslot,skill_group,alignment,mobile,horse_level,horse_riding,horse_hp,horse_stamina FROM player%s WHERE id=%d", str_to_number(pkTab->id, row[col++]); strlcpy(pkTab->name, row[col++], sizeof(pkTab->name)); str_to_number(pkTab->job, row[col++]); str_to_number(pkTab->voice, row[col++]); str_to_number(pkTab->dir, row[col++]); str_to_number(pkTab->x, row[col++]); str_to_number(pkTab->y, row[col++]); str_to_number(pkTab->z, row[col++]); str_to_number(pkTab->lMapIndex, row[col++]); str_to_number(pkTab->lExitX, row[col++]); str_to_number(pkTab->lExitY, row[col++]); str_to_number(pkTab->lExitMapIndex, row[col++]); str_to_number(pkTab->hp, row[col++]); str_to_number(pkTab->sp, row[col++]); str_to_number(pkTab->stamina, row[col++]); str_to_number(pkTab->sRandomHP, row[col++]); str_to_number(pkTab->sRandomSP, row[col++]); str_to_number(pkTab->playtime, row[col++]); str_to_number(pkTab->gold, row[col++]); str_to_number(pkTab->level, row[col++]); str_to_number(pkTab->level_step, row[col++]); str_to_number(pkTab->st, row[col++]); str_to_number(pkTab->ht, row[col++]); str_to_number(pkTab->dx, row[col++]); str_to_number(pkTab->iq, row[col++]); str_to_number(pkTab->exp, row[col++]); str_to_number(pkTab->stat_point, row[col++]); str_to_number(pkTab->skill_point, row[col++]); str_to_number(pkTab->sub_skill_point, row[col++]); str_to_number(pkTab->stat_reset_count, row[col++]); str_to_number(pkTab->part_base, row[col++]); str_to_number(pkTab->parts[PART_HAIR], row[col++]); #ifdef ENABLE_ACCE_SYSTEM str_to_number(pkTab->parts[PART_ACCE], row[col++]); #endif if (row[col]) thecore_memcpy(pkTab->skills, row[col], sizeof(pkTab->skills)); else memset(&pkTab->skills, 0, sizeof(pkTab->skills)); col++; if (row[col]) thecore_memcpy(pkTab->quickslot, row[col], sizeof(pkTab->quickslot)); else memset(pkTab->quickslot, 0, sizeof(pkTab->quickslot)); col++; str_to_number(pkTab->skill_group, row[col++]); str_to_number(pkTab->lAlignment, row[col++]); if (row[col]) { strlcpy(pkTab->szMobile, row[col], sizeof(pkTab->szMobile)); } col++; str_to_number(pkTab->horse.bLevel, row[col++]); str_to_number(pkTab->horse.bRiding, row[col++]); str_to_number(pkTab->horse.sHealth, row[col++]); str_to_number(pkTab->horse.dwHorseHealthDropTime, row[col++]); str_to_number(pkTab->horse.sStamina, row[col++]); str_to_number(pkTab->logoff_interval, row[col++]); str_to_number(pkTab->horse_skill_point, row[col++]); // reset sub_skill_point { pkTab->skills[123].bLevel = 0; // SKILL_CREATE if (pkTab->level > 9) { int max_point = pkTab->level - 9; int skill_point = MIN(20, pkTab->skills[121].bLevel) + MIN(20, pkTab->skills[124].bLevel) + MIN(10, pkTab->skills[131].bLevel) + MIN(20, pkTab->skills[141].bLevel) + MIN(20, pkTab->skills[142].bLevel); pkTab->sub_skill_point = max_point - skill_point; } else pkTab->sub_skill_point = 0; } return true; } void CClientManager::RESULT_COMPOSITE_PLAYER(CPeer * peer, SQLMsg * pMsg, DWORD dwQID) { CQueryInfo * qi = (CQueryInfo *) pMsg->pvUserData; std::auto_ptr<ClientHandleInfo> info((ClientHandleInfo *) qi->pvData); MYSQL_RES * pSQLResult = pMsg->Get()->pSQLResult; if (!pSQLResult) { sys_err("null MYSQL_RES QID %u", dwQID); return; } switch (dwQID) { case QID_PLAYER: sys_log(0, "QID_PLAYER %u %u", info->dwHandle, info->player_id); RESULT_PLAYER_LOAD(peer, pSQLResult, info.get()); break; case QID_ITEM: sys_log(0, "QID_ITEM %u", info->dwHandle); RESULT_ITEM_LOAD(peer, pSQLResult, info->dwHandle, info->player_id); break; case QID_QUEST: { sys_log(0, "QID_QUEST %u", info->dwHandle); RESULT_QUEST_LOAD(peer, pSQLResult, info->dwHandle, info->player_id); ClientHandleInfo* temp1 = info.get(); if (temp1 == NULL) break; CLoginData* pLoginData1 = GetLoginDataByAID(temp1->account_id); // if( pLoginData1->GetAccountRef().login == NULL) break; if( pLoginData1 == NULL ) break; sys_log(0,"info of pLoginData1 before call ItemAwardfunction %d",pLoginData1); ItemAward(peer,pLoginData1->GetAccountRef().login); } break; case QID_AFFECT: sys_log(0, "QID_AFFECT %u", info->dwHandle); // @fixme402 RESULT_AFFECT_LOAD+info->player_id RESULT_AFFECT_LOAD(peer, pSQLResult, info->dwHandle, info->player_id); break; /* case QID_PLAYER_ITEM_QUEST_AFFECT: sys_log(0, "QID_PLAYER_ITEM_QUEST_AFFECT %u", info->dwHandle); RESULT_PLAYER_LOAD(peer, pSQLResult, info->dwHandle); if (!pMsg->Next()) { sys_err("RESULT_COMPOSITE_PLAYER: QID_PLAYER_ITEM_QUEST_AFFECT: ITEM FAILED"); return; } case QID_ITEM_QUEST_AFFECT: sys_log(0, "QID_ITEM_QUEST_AFFECT %u", info->dwHandle); RESULT_ITEM_LOAD(peer, pSQLResult, info->dwHandle, info->player_id); if (!pMsg->Next()) { sys_err("RESULT_COMPOSITE_PLAYER: QID_PLAYER_ITEM_QUEST_AFFECT: QUEST FAILED"); return; } case QID_QUEST_AFFECT: sys_log(0, "QID_QUEST_AFFECT %u", info->dwHandle); RESULT_QUEST_LOAD(peer, pSQLResult, info->dwHandle); if (!pMsg->Next()) sys_err("RESULT_COMPOSITE_PLAYER: QID_PLAYER_ITEM_QUEST_AFFECT: AFFECT FAILED"); else RESULT_AFFECT_LOAD(peer, pSQLResult, info->dwHandle); break; */ } } void CClientManager::RESULT_PLAYER_LOAD(CPeer * peer, MYSQL_RES * pRes, ClientHandleInfo * pkInfo) { TPlayerTable tab; if (!CreatePlayerTableFromRes(pRes, &tab)) { peer->EncodeHeader(HEADER_DG_PLAYER_LOAD_FAILED, pkInfo->dwHandle, 0); return; } CLoginData * pkLD = GetLoginDataByAID(pkInfo->account_id); if (!pkLD || pkLD->IsPlay()) { sys_log(0, "PLAYER_LOAD_ERROR: LoginData %p IsPlay %d", pkLD, pkLD ? pkLD->IsPlay() : 0); peer->EncodeHeader(HEADER_DG_PLAYER_LOAD_FAILED, pkInfo->dwHandle, 0); return; } pkLD->SetPlay(true); SendLoginToBilling(pkLD, true); thecore_memcpy(tab.aiPremiumTimes, pkLD->GetPremiumPtr(), sizeof(tab.aiPremiumTimes)); peer->EncodeHeader(HEADER_DG_PLAYER_LOAD_SUCCESS, pkInfo->dwHandle, sizeof(TPlayerTable)); peer->Encode(&tab, sizeof(TPlayerTable)); if (tab.id != pkLD->GetLastPlayerID()) { TPacketNeedLoginLogInfo logInfo; logInfo.dwPlayerID = tab.id; pkLD->SetLastPlayerID( tab.id ); peer->EncodeHeader( HEADER_DG_NEED_LOGIN_LOG, pkInfo->dwHandle, sizeof(TPacketNeedLoginLogInfo) ); peer->Encode( &logInfo, sizeof(TPacketNeedLoginLogInfo) ); } } void CClientManager::RESULT_ITEM_LOAD(CPeer * peer, MYSQL_RES * pRes, DWORD dwHandle, DWORD dwPID) { static std::vector<TPlayerItem> s_items; CreateItemTableFromRes(pRes, &s_items, dwPID); DWORD dwCount = s_items.size(); peer->EncodeHeader(HEADER_DG_ITEM_LOAD, dwHandle, sizeof(DWORD) + sizeof(TPlayerItem) * dwCount); peer->EncodeDWORD(dwCount); CreateItemCacheSet(dwPID); // ITEM_LOAD_LOG_ATTACH_PID sys_log(0, "ITEM_LOAD: count %u pid %u", dwCount, dwPID); // END_OF_ITEM_LOAD_LOG_ATTACH_PID if (dwCount) { peer->Encode(&s_items[0], sizeof(TPlayerItem) * dwCount); for (DWORD i = 0; i < dwCount; ++i) PutItemCache(&s_items[i], true); } } // @fixme402 (RESULT_AFFECT_LOAD +dwRealPID) void CClientManager::RESULT_AFFECT_LOAD(CPeer * peer, MYSQL_RES * pRes, DWORD dwHandle, DWORD dwRealPID) { int iNumRows; if ((iNumRows = mysql_num_rows(pRes)) == 0) { // @fixme402 begin static DWORD dwPID; static DWORD dwCount = 0; //1; static TPacketAffectElement paeTable = {0}; dwPID = dwRealPID; sys_log(0, "AFFECT_LOAD: count %u PID %u RealPID %u", dwCount, dwPID, dwRealPID); peer->EncodeHeader(HEADER_DG_AFFECT_LOAD, dwHandle, sizeof(DWORD) + sizeof(DWORD) + sizeof(TPacketAffectElement) * dwCount); peer->Encode(&dwPID, sizeof(DWORD)); peer->Encode(&dwCount, sizeof(DWORD)); peer->Encode(&paeTable, sizeof(TPacketAffectElement) * dwCount); // @fixme402 end return; } static std::vector<TPacketAffectElement> s_elements; s_elements.resize(iNumRows); DWORD dwPID = 0; MYSQL_ROW row; for (int i = 0; i < iNumRows; ++i) { TPacketAffectElement & r = s_elements[i]; row = mysql_fetch_row(pRes); if (dwPID == 0) str_to_number(dwPID, row[0]); str_to_number(r.dwType, row[1]); str_to_number(r.bApplyOn, row[2]); str_to_number(r.lApplyValue, row[3]); str_to_number(r.dwFlag, row[4]); str_to_number(r.lDuration, row[5]); str_to_number(r.lSPCost, row[6]); } sys_log(0, "AFFECT_LOAD: count %d PID %u", s_elements.size(), dwPID); DWORD dwCount = s_elements.size(); peer->EncodeHeader(HEADER_DG_AFFECT_LOAD, dwHandle, sizeof(DWORD) + sizeof(DWORD) + sizeof(TPacketAffectElement) * dwCount); peer->Encode(&dwPID, sizeof(DWORD)); peer->Encode(&dwCount, sizeof(DWORD)); peer->Encode(&s_elements[0], sizeof(TPacketAffectElement) * dwCount); } void CClientManager::RESULT_QUEST_LOAD(CPeer * peer, MYSQL_RES * pRes, DWORD dwHandle, DWORD pid) { int iNumRows; if ((iNumRows = mysql_num_rows(pRes)) == 0) { DWORD dwCount = 0; peer->EncodeHeader(HEADER_DG_QUEST_LOAD, dwHandle, sizeof(DWORD)); peer->Encode(&dwCount, sizeof(DWORD)); return; } static std::vector<TQuestTable> s_table; s_table.resize(iNumRows); MYSQL_ROW row; for (int i = 0; i < iNumRows; ++i) { TQuestTable & r = s_table[i]; row = mysql_fetch_row(pRes); str_to_number(r.dwPID, row[0]); strlcpy(r.szName, row[1], sizeof(r.szName)); strlcpy(r.szState, row[2], sizeof(r.szState)); str_to_number(r.lValue, row[3]); } sys_log(0, "QUEST_LOAD: count %d PID %u", s_table.size(), s_table[0].dwPID); DWORD dwCount = s_table.size(); peer->EncodeHeader(HEADER_DG_QUEST_LOAD, dwHandle, sizeof(DWORD) + sizeof(TQuestTable) * dwCount); peer->Encode(&dwCount, sizeof(DWORD)); peer->Encode(&s_table[0], sizeof(TQuestTable) * dwCount); } /* * PLAYER SAVE */ void CClientManager::QUERY_PLAYER_SAVE(CPeer * peer, DWORD dwHandle, TPlayerTable * pkTab) { if (g_test_server) sys_log(0, "PLAYER_SAVE: %s", pkTab->name); PutPlayerCache(pkTab); } typedef std::map<DWORD, time_t> time_by_id_map_t; static time_by_id_map_t s_createTimeByAccountID; /* * PLAYER CREATE */ void CClientManager::__QUERY_PLAYER_CREATE(CPeer *peer, DWORD dwHandle, TPlayerCreatePacket* packet) { char queryStr[QUERY_MAX_LEN]; int queryLen; int player_id; time_by_id_map_t::iterator it = s_createTimeByAccountID.find(packet->account_id); if (it != s_createTimeByAccountID.end()) { time_t curtime = time(0); if (curtime - it->second < 30) { peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_FAILED, dwHandle, 0); return; } } queryLen = snprintf(queryStr, sizeof(queryStr), "SELECT pid%u FROM player_index%s WHERE id=%d", packet->account_index + 1, GetTablePostfix(), packet->account_id); std::auto_ptr<SQLMsg> pMsg0(CDBManager::instance().DirectQuery(queryStr)); if (pMsg0->Get()->uiNumRows != 0) { if (!pMsg0->Get()->pSQLResult) { peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_FAILED, dwHandle, 0); return; } MYSQL_ROW row = mysql_fetch_row(pMsg0->Get()->pSQLResult); DWORD dwPID = 0; str_to_number(dwPID, row[0]); if (row[0] && dwPID > 0) { peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_ALREADY, dwHandle, 0); sys_log(0, "ALREADY EXIST AccountChrIdx %d ID %d", packet->account_index, dwPID); return; } } else { peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_FAILED, dwHandle, 0); return; } if (g_stLocale == "sjis") snprintf(queryStr, sizeof(queryStr), "SELECT COUNT(*) as count FROM player%s WHERE name='%s' collate sjis_japanese_ci", GetTablePostfix(), packet->player_table.name); else snprintf(queryStr, sizeof(queryStr), "SELECT COUNT(*) as count FROM player%s WHERE name='%s'", GetTablePostfix(), packet->player_table.name); std::auto_ptr<SQLMsg> pMsg1(CDBManager::instance().DirectQuery(queryStr)); if (pMsg1->Get()->uiNumRows) { if (!pMsg1->Get()->pSQLResult) { peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_FAILED, dwHandle, 0); return; } MYSQL_ROW row = mysql_fetch_row(pMsg1->Get()->pSQLResult); if (*row[0] != '0') { sys_log(0, "ALREADY EXIST name %s, row[0] %s query %s", packet->player_table.name, row[0], queryStr); peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_ALREADY, dwHandle, 0); return; } } else { peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_FAILED, dwHandle, 0); return; } queryLen = snprintf(queryStr, sizeof(queryStr), "INSERT INTO player%s " "(id, account_id, name, level, st, ht, dx, iq, " "job, voice, dir, x, y, z, " "hp, mp, random_hp, random_sp, stat_point, stamina, part_base, part_main, part_hair," #ifdef ENABLE_ACCE_SYSTEM "part_acce, " #endif " gold, playtime, " "skill_level, quickslot) " "VALUES(0, %u, '%s', %d, %d, %d, %d, %d, " "%d, %d, %d, %d, %d, %d, %d, " "%d, %d, %d, %d, %d, %d, %d, 0, " #ifdef ENABLE_ACCE_SYSTEM "0, " #endif "%d, 0, ", GetTablePostfix(), packet->account_id, packet->player_table.name, packet->player_table.level, packet->player_table.st, packet->player_table.ht, packet->player_table.dx, packet->player_table.iq, packet->player_table.job, packet->player_table.voice, packet->player_table.dir, packet->player_table.x, packet->player_table.y, packet->player_table.z, packet->player_table.hp, packet->player_table.sp, packet->player_table.sRandomHP, packet->player_table.sRandomSP, packet->player_table.stat_point, packet->player_table.stamina, packet->player_table.part_base, packet->player_table.part_base, packet->player_table.gold); sys_log(0, "PlayerCreate accountid %d name %s level %d gold %d, st %d ht %d job %d", packet->account_id, packet->player_table.name, packet->player_table.level, packet->player_table.gold, packet->player_table.st, packet->player_table.ht, packet->player_table.job); static char text[4096 + 1]; CDBManager::instance().EscapeString(text, packet->player_table.skills, sizeof(packet->player_table.skills)); queryLen += snprintf(queryStr + queryLen, sizeof(queryStr) - queryLen, "'%s', ", text); if (g_test_server) sys_log(0, "Create_Player queryLen[%d] TEXT[%s]", queryLen, text); CDBManager::instance().EscapeString(text, packet->player_table.quickslot, sizeof(packet->player_table.quickslot)); queryLen += snprintf(queryStr + queryLen, sizeof(queryStr) - queryLen, "'%s')", text); std::auto_ptr<SQLMsg> pMsg2(CDBManager::instance().DirectQuery(queryStr)); if (g_test_server) sys_log(0, "Create_Player queryLen[%d] TEXT[%s]", queryLen, text); if (pMsg2->Get()->uiAffectedRows <= 0) { peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_ALREADY, dwHandle, 0); sys_log(0, "ALREADY EXIST3 query: %s AffectedRows %lu", queryStr, pMsg2->Get()->uiAffectedRows); return; } player_id = pMsg2->Get()->uiInsertID; snprintf(queryStr, sizeof(queryStr), "UPDATE player_index%s SET pid%d=%d WHERE id=%d", GetTablePostfix(), packet->account_index + 1, player_id, packet->account_id); std::auto_ptr<SQLMsg> pMsg3(CDBManager::instance().DirectQuery(queryStr)); if (pMsg3->Get()->uiAffectedRows <= 0) { sys_err("QUERY_ERROR: %s", queryStr); snprintf(queryStr, sizeof(queryStr), "DELETE FROM player%s WHERE id=%d", GetTablePostfix(), player_id); CDBManager::instance().DirectQuery(queryStr); peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_FAILED, dwHandle, 0); return; } TPacketDGCreateSuccess pack; memset(&pack, 0, sizeof(pack)); pack.bAccountCharacterIndex = packet->account_index; pack.player.dwID = player_id; strlcpy(pack.player.szName, packet->player_table.name, sizeof(pack.player.szName)); pack.player.byJob = packet->player_table.job; pack.player.byLevel = 1; pack.player.dwPlayMinutes = 0; pack.player.byST = packet->player_table.st; pack.player.byHT = packet->player_table.ht; pack.player.byDX = packet->player_table.dx; pack.player.byIQ = packet->player_table.iq; pack.player.wMainPart = packet->player_table.part_base; pack.player.x = packet->player_table.x; pack.player.y = packet->player_table.y; peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_SUCCESS, dwHandle, sizeof(TPacketDGCreateSuccess)); peer->Encode(&pack, sizeof(TPacketDGCreateSuccess)); sys_log(0, "7 name %s job %d", pack.player.szName, pack.player.byJob); s_createTimeByAccountID[packet->account_id] = time(0); } /* * PLAYER DELETE */ void CClientManager::__QUERY_PLAYER_DELETE(CPeer* peer, DWORD dwHandle, TPlayerDeletePacket* packet) { if (!packet->login[0] || !packet->player_id || packet->account_index >= PLAYER_PER_ACCOUNT) return; CLoginData * ld = GetLoginDataByLogin(packet->login); if (!ld) { peer->EncodeHeader(HEADER_DG_PLAYER_DELETE_FAILED, dwHandle, 1); peer->EncodeBYTE(packet->account_index); return; } TAccountTable & r = ld->GetAccountRef(); // block for japan if (g_stLocale != "sjis") { if (!IsChinaEventServer()) { if (strlen(r.social_id) < 7 || strncmp(packet->private_code, r.social_id + strlen(r.social_id) - 7, 7)) { sys_log(0, "PLAYER_DELETE FAILED len(%d)", strlen(r.social_id)); peer->EncodeHeader(HEADER_DG_PLAYER_DELETE_FAILED, dwHandle, 1); peer->EncodeBYTE(packet->account_index); return; } CPlayerTableCache * pkPlayerCache = GetPlayerCache(packet->player_id); if (pkPlayerCache) { TPlayerTable * pTab = pkPlayerCache->Get(); if (pTab->level >= m_iPlayerDeleteLevelLimit) { sys_log(0, "PLAYER_DELETE FAILED LEVEL %u >= DELETE LIMIT %d", pTab->level, m_iPlayerDeleteLevelLimit); peer->EncodeHeader(HEADER_DG_PLAYER_DELETE_FAILED, dwHandle, 1); peer->EncodeBYTE(packet->account_index); return; } if (pTab->level < m_iPlayerDeleteLevelLimitLower) { sys_log(0, "PLAYER_DELETE FAILED LEVEL %u < DELETE LIMIT %d", pTab->level, m_iPlayerDeleteLevelLimitLower); peer->EncodeHeader(HEADER_DG_PLAYER_DELETE_FAILED, dwHandle, 1); peer->EncodeBYTE(packet->account_index); return; } } } } #ifdef __ENABLE_NEW_OFFLINESHOP__ if (IsUsingOfflineshopSystem(packet->player_id)) { sys_log(0, "PLAYER_DELETE FAILED %u IS USING OFFLINESHOP SYSTEM", packet->player_id); peer->EncodeHeader(HEADER_DG_PLAYER_DELETE_FAILED, dwHandle, 1); peer->EncodeBYTE(packet->account_index); return; } #endif char szQuery[128]; snprintf(szQuery, sizeof(szQuery), "SELECT p.id, p.level, p.name FROM player_index%s AS i, player%s AS p WHERE pid%u=%u AND pid%u=p.id", GetTablePostfix(), GetTablePostfix(), packet->account_index + 1, packet->player_id, packet->account_index + 1); ClientHandleInfo * pi = new ClientHandleInfo(dwHandle, packet->player_id); pi->account_index = packet->account_index; sys_log(0, "PLAYER_DELETE TRY: %s %d pid%d", packet->login, packet->player_id, packet->account_index + 1); CDBManager::instance().ReturnQuery(szQuery, QID_PLAYER_DELETE, peer->GetHandle(), pi); } // // void CClientManager::__RESULT_PLAYER_DELETE(CPeer *peer, SQLMsg* msg) { CQueryInfo * qi = (CQueryInfo *) msg->pvUserData; ClientHandleInfo * pi = (ClientHandleInfo *) qi->pvData; if (msg->Get() && msg->Get()->uiNumRows) { MYSQL_ROW row = mysql_fetch_row(msg->Get()->pSQLResult); DWORD dwPID = 0; str_to_number(dwPID, row[0]); int deletedLevelLimit = 0; str_to_number(deletedLevelLimit, row[1]); char szName[64]; strlcpy(szName, row[2], sizeof(szName)); if (deletedLevelLimit >= m_iPlayerDeleteLevelLimit && !IsChinaEventServer()) { sys_log(0, "PLAYER_DELETE FAILED LEVEL %u >= DELETE LIMIT %d", deletedLevelLimit, m_iPlayerDeleteLevelLimit); peer->EncodeHeader(HEADER_DG_PLAYER_DELETE_FAILED, pi->dwHandle, 1); peer->EncodeBYTE(pi->account_index); return; } if (deletedLevelLimit < m_iPlayerDeleteLevelLimitLower) { sys_log(0, "PLAYER_DELETE FAILED LEVEL %u < DELETE LIMIT %d", deletedLevelLimit, m_iPlayerDeleteLevelLimitLower); peer->EncodeHeader(HEADER_DG_PLAYER_DELETE_FAILED, pi->dwHandle, 1); peer->EncodeBYTE(pi->account_index); return; } char queryStr[QUERY_MAX_LEN]; snprintf(queryStr, sizeof(queryStr), "INSERT INTO player%s_deleted SELECT * FROM player%s WHERE id=%d", GetTablePostfix(), GetTablePostfix(), pi->player_id); std::auto_ptr<SQLMsg> pIns(CDBManager::instance().DirectQuery(queryStr)); if (pIns->Get()->uiAffectedRows == 0 || pIns->Get()->uiAffectedRows == (uint32_t)-1) { sys_log(0, "PLAYER_DELETE FAILED %u CANNOT INSERT TO player%s_deleted", dwPID, GetTablePostfix()); peer->EncodeHeader(HEADER_DG_PLAYER_DELETE_FAILED, pi->dwHandle, 1); peer->EncodeBYTE(pi->account_index); return; } sys_log(0, "PLAYER_DELETE SUCCESS %u", dwPID); char account_index_string[16]; snprintf(account_index_string, sizeof(account_index_string), "player_id%d", m_iPlayerIDStart + pi->account_index); CPlayerTableCache * pkPlayerCache = GetPlayerCache(pi->player_id); if (pkPlayerCache) { m_map_playerCache.erase(pi->player_id); delete pkPlayerCache; } TItemCacheSet * pSet = GetItemCacheSet(pi->player_id); if (pSet) { TItemCacheSet::iterator it = pSet->begin(); while (it != pSet->end()) { CItemCache * pkItemCache = *it++; DeleteItemCache(pkItemCache->Get()->id); } pSet->clear(); delete pSet; m_map_pkItemCacheSetPtr.erase(pi->player_id); } snprintf(queryStr, sizeof(queryStr), "UPDATE player_index%s SET pid%u=0 WHERE pid%u=%d", GetTablePostfix(), pi->account_index + 1, pi->account_index + 1, pi->player_id); std::auto_ptr<SQLMsg> pMsg(CDBManager::instance().DirectQuery(queryStr)); if (pMsg->Get()->uiAffectedRows == 0 || pMsg->Get()->uiAffectedRows == (uint32_t)-1) { sys_log(0, "PLAYER_DELETE FAIL WHEN UPDATE account table"); peer->EncodeHeader(HEADER_DG_PLAYER_DELETE_FAILED, pi->dwHandle, 1); peer->EncodeBYTE(pi->account_index); return; } snprintf(queryStr, sizeof(queryStr), "DELETE FROM player%s WHERE id=%d", GetTablePostfix(), pi->player_id); delete CDBManager::instance().DirectQuery(queryStr); snprintf(queryStr, sizeof(queryStr), "DELETE FROM item%s WHERE owner_id=%d AND (`window` in ('INVENTORY','EQUIPMENT','DRAGON_SOUL_INVENTORY','BELT_INVENTORY'))", GetTablePostfix(), pi->player_id); delete CDBManager::instance().DirectQuery(queryStr); snprintf(queryStr, sizeof(queryStr), "DELETE FROM quest%s WHERE dwPID=%d", GetTablePostfix(), pi->player_id); CDBManager::instance().AsyncQuery(queryStr); snprintf(queryStr, sizeof(queryStr), "DELETE FROM affect%s WHERE dwPID=%d", GetTablePostfix(), pi->player_id); CDBManager::instance().AsyncQuery(queryStr); snprintf(queryStr, sizeof(queryStr), "DELETE FROM guild_member%s WHERE pid=%d", GetTablePostfix(), pi->player_id); CDBManager::instance().AsyncQuery(queryStr); // MYSHOP_PRICE_LIST snprintf(queryStr, sizeof(queryStr), "DELETE FROM myshop_pricelist%s WHERE owner_id=%d", GetTablePostfix(), pi->player_id); CDBManager::instance().AsyncQuery(queryStr); // END_OF_MYSHOP_PRICE_LIST snprintf(queryStr, sizeof(queryStr), "DELETE FROM messenger_list%s WHERE account='%s' OR companion='%s'", GetTablePostfix(), szName, szName); CDBManager::instance().AsyncQuery(queryStr); peer->EncodeHeader(HEADER_DG_PLAYER_DELETE_SUCCESS, pi->dwHandle, 1); peer->EncodeBYTE(pi->account_index); } else { sys_log(0, "PLAYER_DELETE FAIL NO ROW"); peer->EncodeHeader(HEADER_DG_PLAYER_DELETE_FAILED, pi->dwHandle, 1); peer->EncodeBYTE(pi->account_index); } } void CClientManager::QUERY_ADD_AFFECT(CPeer * peer, TPacketGDAddAffect * p) { char queryStr[QUERY_MAX_LEN]; /* snprintf(queryStr, sizeof(queryStr), "INSERT INTO affect%s (dwPID, bType, bApplyOn, lApplyValue, dwFlag, lDuration, lSPCost) " "VALUES(%u, %u, %u, %d, %u, %d, %d) " "ON DUPLICATE KEY UPDATE lApplyValue=%d, dwFlag=%u, lDuration=%d, lSPCost=%d", GetTablePostfix(), p->dwPID, p->elem.dwType, p->elem.bApplyOn, p->elem.lApplyValue, p->elem.dwFlag, p->elem.lDuration, p->elem.lSPCost, p->elem.lApplyValue, p->elem.dwFlag, p->elem.lDuration, p->elem.lSPCost); */ snprintf(queryStr, sizeof(queryStr), "REPLACE INTO affect%s (dwPID, bType, bApplyOn, lApplyValue, dwFlag, lDuration, lSPCost) " "VALUES(%u, %u, %u, %ld, %u, %ld, %ld)", GetTablePostfix(), p->dwPID, p->elem.dwType, p->elem.bApplyOn, p->elem.lApplyValue, p->elem.dwFlag, p->elem.lDuration, p->elem.lSPCost); CDBManager::instance().AsyncQuery(queryStr); } void CClientManager::QUERY_REMOVE_AFFECT(CPeer * peer, TPacketGDRemoveAffect * p) { char queryStr[QUERY_MAX_LEN]; snprintf(queryStr, sizeof(queryStr), "DELETE FROM affect%s WHERE dwPID=%u AND bType=%u AND bApplyOn=%u", GetTablePostfix(), p->dwPID, p->dwType, p->bApplyOn); CDBManager::instance().AsyncQuery(queryStr); } void CClientManager::QUERY_HIGHSCORE_REGISTER(CPeer* peer, TPacketGDHighscore * data) { char szQuery[128]; snprintf(szQuery, sizeof(szQuery), "SELECT value FROM highscore%s WHERE board='%s' AND pid = %u", GetTablePostfix(), data->szBoard, data->dwPID); sys_log(0, "HEADER_GD_HIGHSCORE_REGISTER: PID %u", data->dwPID); ClientHandleInfo * pi = new ClientHandleInfo(0); strlcpy(pi->login, data->szBoard, sizeof(pi->login)); pi->account_id = (DWORD)data->lValue; pi->player_id = data->dwPID; pi->account_index = (data->cDir > 0); CDBManager::instance().ReturnQuery(szQuery, QID_HIGHSCORE_REGISTER, peer->GetHandle(), pi); } void CClientManager::RESULT_HIGHSCORE_REGISTER(CPeer * pkPeer, SQLMsg * msg) { CQueryInfo * qi = (CQueryInfo *) msg->pvUserData; ClientHandleInfo * pi = (ClientHandleInfo *) qi->pvData; //DWORD dwHandle = pi->dwHandle; char szBoard[21]; strlcpy(szBoard, pi->login, sizeof(szBoard)); int value = (int)pi->account_id; SQLResult * res = msg->Get(); if (res->uiNumRows == 0) { char buf[256]; snprintf(buf, sizeof(buf), "INSERT INTO highscore%s VALUES('%s', %u, %d)", GetTablePostfix(), szBoard, pi->player_id, value); CDBManager::instance().AsyncQuery(buf); } else { if (!res->pSQLResult) { delete pi; return; } MYSQL_ROW row = mysql_fetch_row(res->pSQLResult); if (row && row[0]) { int current_value = 0; str_to_number(current_value, row[0]); if (((pi->account_index)&&(current_value >= value)) || ((!pi->account_index)&&(current_value <= value))) { value = current_value; } else { char buf[256]; snprintf(buf, sizeof(buf), "REPLACE INTO highscore%s VALUES('%s', %u, %d)", GetTablePostfix(), szBoard, pi->player_id, value); CDBManager::instance().AsyncQuery(buf); } } else { char buf[256]; snprintf(buf, sizeof(buf), "INSERT INTO highscore%s VALUES('%s', %u, %d)", GetTablePostfix(), szBoard, pi->player_id, value); CDBManager::instance().AsyncQuery(buf); } } delete pi; } void CClientManager::InsertLogoutPlayer(DWORD pid) { TLogoutPlayerMap::iterator it = m_map_logout.find(pid); if (it != m_map_logout.end()) { if (g_log) sys_log(0, "LOGOUT: Update player time pid(%d)", pid); it->second->time = time(0); return; } TLogoutPlayer * pLogout = new TLogoutPlayer; pLogout->pid = pid; pLogout->time = time(0); m_map_logout.insert(std::make_pair(pid, pLogout)); if (g_log) sys_log(0, "LOGOUT: Insert player pid(%d)", pid); } void CClientManager::DeleteLogoutPlayer(DWORD pid) { TLogoutPlayerMap::iterator it = m_map_logout.find(pid); if (it != m_map_logout.end()) { delete it->second; m_map_logout.erase(it); } } extern int g_iLogoutSeconds; void CClientManager::UpdateLogoutPlayer() { time_t now = time(0); TLogoutPlayerMap::iterator it = m_map_logout.begin(); while (it != m_map_logout.end()) { TLogoutPlayer* pLogout = it->second; if (now - g_iLogoutSeconds > pLogout->time) { FlushItemCacheSet(pLogout->pid); FlushPlayerCacheSet(pLogout->pid); delete pLogout; m_map_logout.erase(it++); } else ++it; } } void CClientManager::FlushPlayerCacheSet(DWORD pid) { TPlayerTableCacheMap::iterator it = m_map_playerCache.find(pid); if (it != m_map_playerCache.end()) { CPlayerTableCache * c = it->second; m_map_playerCache.erase(it); c->Flush(); delete c; } } Edited May 21, 2021 by Ciucciamelo Link to comment Share on other sites More sharing options...
Active Member iMerv3 768 Posted May 21, 2021 Active Member Share Posted May 21, 2021 It seem okay, just try to add as little test inside ClientManagerPlayer.h #define ENABLE_ACCE_SYSTEM or include where it is defined. If still same upload char.cpp too. 1 Link to comment Share on other sites More sharing options...
Ciucciamelo 0 Posted May 21, 2021 Author Share Posted May 21, 2021 I don't have ClientManagerPlayer.h Link to comment Share on other sites More sharing options...
Active Member iMerv3 768 Posted May 21, 2021 Active Member Share Posted May 21, 2021 inside the .cpp #ifndef ENABLE_ACCE_SYSTEM #define ENABLE_ACCE_SYSTEM #endif If will be same after, upload char.cpp Link to comment Share on other sites More sharing options...
Recommended Posts
Please sign in to comment
You will be able to leave a comment after signing in
Sign In Now