From 871beba9096bd2e597238525f3dd59a2d5dbf46a Mon Sep 17 00:00:00 2001 From: hzqst <113660872@qq.com> Date: Thu, 27 Jun 2019 18:22:02 +0800 Subject: [PATCH] add new --- CGALib/CGALib.vcxproj | 13 +- CGALib/gameinterface.cpp | 702 +++++++---- CGALib/gameinterface.h | 362 +++++- CGALib/packdata.h | 584 ++++++++- CGANode/async.h | 16 +- CGANode/binding.gyp | 8 +- CGANode/chat.cc | 171 +-- CGANode/connect.cc | 8 + CGANode/info.cc | 116 +- CGANode/item.cc | 1021 +++++++++++++++- CGANode/item.h | 9 +- CGANode/main.cc | 62 +- CGANode/map.cc | 570 +++++++-- CGANode/map.h | 12 +- CGANode/npc.cc | 119 +- CGANode/work.cc | 198 +-- CGANode/work.h | 3 +- cgahook/cgahook.vcxproj | 10 +- cgahook/dump.cpp | 27 + cgahook/gameservice.cpp | 2497 +++++++++++++++++++++++++++++++++----- cgahook/gameservice.h | 283 ++++- cgahook/main.cpp | 44 +- cgahook/server.cpp | 47 +- 23 files changed, 5784 insertions(+), 1098 deletions(-) create mode 100644 cgahook/dump.cpp diff --git a/CGALib/CGALib.vcxproj b/CGALib/CGALib.vcxproj index e18ee6f..b2aa106 100644 --- a/CGALib/CGALib.vcxproj +++ b/CGALib/CGALib.vcxproj @@ -29,7 +29,6 @@ {85FCBAC1-6F19-4754-B277-97E6386F6D51} Win32Proj CGALib - 10.0.17763.0 @@ -84,7 +83,7 @@ Level3 Disabled WIN32;_DEBUG;_LIB;CGA_EXPORT;%(PreprocessorDefinitions) - ../boost;../rest_rpc/;../rest_rpc/spdlog/include;../rest_rpc/iguana;../rest_rpc/iguana/third_party/msgpack/include + ../boost_1_63_0;../rest_rpc/;../rest_rpc/spdlog/include;../rest_rpc/iguana;../rest_rpc/iguana/third_party/msgpack/include MultiThreadedDebugDLL true 4101 @@ -93,7 +92,7 @@ Windows - ../boost/stage/lib + ../boost_1_63_0/stage/lib @@ -117,7 +116,7 @@ true true WIN32;NDEBUG;_LIB;CGA_EXPORT;%(PreprocessorDefinitions) - ../boost;../rest_rpc/;../rest_rpc/spdlog/include;../rest_rpc/iguana;../rest_rpc/iguana/third_party/msgpack/include + ../boost_1_63_0;../rest_rpc/;../rest_rpc/spdlog/include;../rest_rpc/iguana;../rest_rpc/iguana/third_party/msgpack/include MultiThreadedDLL true 4101 @@ -128,7 +127,7 @@ true - ../boost/stage/lib + ../boost_1_63_0/stage/lib @@ -140,7 +139,7 @@ true true NDEBUG;_LIB;%(PreprocessorDefinitions) - ../boost;../rest_rpc/;../rest_rpc/spdlog/include;../rest_rpc/iguana;../rest_rpc/iguana/third_party/msgpack/include + ../boost_1_63_0;../rest_rpc/;../rest_rpc/spdlog/include;../rest_rpc/iguana;../rest_rpc/iguana/third_party/msgpack/include Windows @@ -148,7 +147,7 @@ true - ../boost/stage/lib + ../boost_1_63_0/stage/lib diff --git a/CGALib/gameinterface.cpp b/CGALib/gameinterface.cpp index 5439fdd..a778354 100644 --- a/CGALib/gameinterface.cpp +++ b/CGALib/gameinterface.cpp @@ -32,11 +32,15 @@ namespace CGAServiceProtocol TIMAX_DEFINE_PROTOCOL(DropItem, bool(int)); TIMAX_DEFINE_PROTOCOL(UseItem, bool(int)); TIMAX_DEFINE_PROTOCOL(MoveItem, bool(int, int, int)); + TIMAX_DEFINE_PROTOCOL(DropPet, bool(int)); + TIMAX_DEFINE_PROTOCOL(GetMapIndex, std::tuple()); TIMAX_DEFINE_PROTOCOL(GetMapXY, std::tuple()); TIMAX_DEFINE_PROTOCOL(GetMapXYFloat, std::tuple()); TIMAX_DEFINE_PROTOCOL(GetMoveSpeed, std::tuple()); TIMAX_DEFINE_PROTOCOL(GetMapName, std::string()); TIMAX_DEFINE_PROTOCOL(GetMapUnits, cga_map_units_t()); + TIMAX_DEFINE_PROTOCOL(GetMapCollisionTable, cga_map_cells_t(bool)); + TIMAX_DEFINE_PROTOCOL(GetMapObjectTable, cga_map_cells_t(bool)); TIMAX_DEFINE_PROTOCOL(WalkTo, void(int,int)); TIMAX_DEFINE_PROTOCOL(TurnTo, void(int, int)); TIMAX_DEFINE_PROTOCOL(ForceMove, bool(int, bool)); @@ -49,15 +53,12 @@ namespace CGAServiceProtocol TIMAX_DEFINE_PROTOCOL(ClickNPCDialog, bool(int, int)); TIMAX_DEFINE_PROTOCOL(SellNPCStore, bool(cga_sell_items_t)); TIMAX_DEFINE_PROTOCOL(BuyNPCStore, bool(cga_buy_items_t)); - TIMAX_DEFINE_PROTOCOL(PlayerMenuSelect, bool(int)); + TIMAX_DEFINE_PROTOCOL(PlayerMenuSelect, bool(int, std::string)); TIMAX_DEFINE_PROTOCOL(UnitMenuSelect, bool(int)); TIMAX_DEFINE_PROTOCOL(IsBattleUnitValid, bool(int)); TIMAX_DEFINE_PROTOCOL(GetBattleUnit, cga_battle_unit_t(int)); TIMAX_DEFINE_PROTOCOL(GetBattleUnits, cga_battle_units_t()); - TIMAX_DEFINE_PROTOCOL(GetBattleRoundCount, int()); - TIMAX_DEFINE_PROTOCOL(GetBattlePlayerPosition, int()); - TIMAX_DEFINE_PROTOCOL(GetBattlePlayerStatus, int()); - TIMAX_DEFINE_PROTOCOL(GetBattlePetId, int()); + TIMAX_DEFINE_PROTOCOL(GetBattleContext, cga_battle_context_t()); TIMAX_DEFINE_PROTOCOL(BattleNormalAttack, bool(int)); TIMAX_DEFINE_PROTOCOL(BattleSkillAttack, bool(int, int, int)); TIMAX_DEFINE_PROTOCOL(BattleDefense, bool()); @@ -72,11 +73,21 @@ namespace CGAServiceProtocol TIMAX_DEFINE_PROTOCOL(SetBattleEndTick, void(int)); TIMAX_DEFINE_PROTOCOL(SetWorkDelay, void(int)); TIMAX_DEFINE_PROTOCOL(SetWorkAcceleration, void(int)); + TIMAX_DEFINE_PROTOCOL(SetImmediateDoneWork, void(bool)); TIMAX_DEFINE_PROTOCOL(StartWork, bool(int,int)); TIMAX_DEFINE_PROTOCOL(CraftItem, bool(cga_craft_item_t)); TIMAX_DEFINE_PROTOCOL(AssessItem, bool(int,int)); TIMAX_DEFINE_PROTOCOL(GetCraftInfo, cga_craft_info_t(int,int)); TIMAX_DEFINE_PROTOCOL(GetCraftsInfo, cga_crafts_info_t(int)); + TIMAX_DEFINE_PROTOCOL(DoRequest, bool(int)); + TIMAX_DEFINE_PROTOCOL(EnableFlags, bool(int, bool)); + TIMAX_DEFINE_PROTOCOL(TradeAddStuffs, void(cga_sell_items_t, cga_sell_pets_t, int)); + TIMAX_DEFINE_PROTOCOL(GetTeamPlayerInfo, cga_team_players_t()); + TIMAX_DEFINE_PROTOCOL(FixMapWarpStuck, void(int)); + TIMAX_DEFINE_PROTOCOL(SetNoSwitchAnim, void(bool)); + TIMAX_DEFINE_PROTOCOL(GetMoveHistory, std::vector()); + TIMAX_DEFINE_PROTOCOL(SetWindowResolution, void(int, int)); + TIMAX_DEFINE_PROTOCOL(RequestDownloadMap, void(int, int, int, int)); TIMAX_DEFINE_FORWARD(NotifyServerShutdown, int); TIMAX_DEFINE_FORWARD(NotifyBattleAction, int); TIMAX_DEFINE_FORWARD(NotifyPlayerMenu, cga_player_menu_items_t); @@ -84,6 +95,9 @@ namespace CGAServiceProtocol TIMAX_DEFINE_FORWARD(NotifyNPCDialog, cga_npc_dialog_t); TIMAX_DEFINE_FORWARD(NotifyWorkingResult, cga_working_result_t); TIMAX_DEFINE_FORWARD(NotifyChatMsg, cga_chat_msg_t); + TIMAX_DEFINE_FORWARD(NotifyTradeStuffs, cga_trade_stuff_info_t); + TIMAX_DEFINE_FORWARD(NotifyTradeDialog, cga_trade_dialog_t); + TIMAX_DEFINE_FORWARD(NotifyTradeState, int); } namespace CGA @@ -116,793 +130,930 @@ namespace CGA { try { - m_connected = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::Connect); + m_connected = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::Connect); } catch (timax::rpc::exception const &e) { m_connected = false; } - catch (msgpack::parse_error &e) {} + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return m_connected; } virtual bool Initialize(cga_game_data_t &data) { if (m_connected) { try { - m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::Initialize, data); + m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::Initialize, data); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool IsInGame(int &ingame) { if (m_connected) { try { - ingame = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::IsInGame); + ingame = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::IsInGame); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool GetWorldStatus(int &status) { if (m_connected) { try { - status = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::GetWorldStatus); + status = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::GetWorldStatus); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool GetGameStatus(int &status) { if (m_connected) { try { - status = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::GetGameStatus); + status = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::GetGameStatus); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool GetPlayerInfo(cga_player_info_t &info){ if (m_connected) { try { - info = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::GetPlayerInfo); + info = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::GetPlayerInfo); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool SetPlayerFlagEnabled(int index, bool enable) { if (m_connected) { try { - m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::SetPlayerFlagEnabled, index, enable); + m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::SetPlayerFlagEnabled, index, enable); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool IsPlayerFlagEnabled(int index, bool &enable) { if (m_connected) { try { - enable = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::IsPlayerFlagEnabled, index); + enable = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::IsPlayerFlagEnabled, index); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool IsPetValid(int petid, bool &valid) { if (m_connected) { try { - valid = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::IsPetValid, petid); + valid = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::IsPetValid, petid); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool GetPetInfo(int petid, cga_pet_info_t &info) { if (m_connected) { try { - info = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::GetPetInfo, petid); + info = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::GetPetInfo, petid); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool GetPetsInfo(cga_pets_info_t &info) { if (m_connected) { try { - info = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::GetPetsInfo); + info = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::GetPetsInfo); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool IsPetSkillValid(int petid, int skillid, bool &valid) { if (m_connected) { try { - valid = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::IsPetSkillValid, petid, skillid); + valid = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::IsPetSkillValid, petid, skillid); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool GetPetSkillInfo(int petid, int skillpos, cga_pet_skill_info_t &skill) { if (m_connected) { try { - skill = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::GetPetSkillInfo, petid, skillpos); + skill = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::GetPetSkillInfo, petid, skillpos); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool GetPetSkillsInfo(int petid, cga_pet_skills_info_t &skills) { if (m_connected) { try { - skills = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::GetPetSkillsInfo, petid); + skills = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::GetPetSkillsInfo, petid); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool IsSkillValid(int skillid, bool &valid) { if (m_connected) { try { - valid = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::IsSkillValid, skillid); + valid = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::IsSkillValid, skillid); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool GetSkillInfo(int skillid, cga_skill_info_t &info) { if (m_connected) { try { - info = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::GetSkillInfo, skillid); + info = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::GetSkillInfo, skillid); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool GetSkillsInfo(cga_skills_info_t &info) { if (m_connected) { try { - info = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::GetSkillsInfo); + info = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::GetSkillsInfo); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool GetSubSkillInfo(int skillid, int stage, cga_subskill_info_t &info) { if (m_connected) { try { - info = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::GetSubSkillInfo, skillid, stage); + info = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::GetSubSkillInfo, skillid, stage); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return 0; } virtual bool GetSubSkillsInfo(int skillid, cga_subskills_info_t &info) { if (m_connected) { try { - info = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::GetSubSkillsInfo, skillid); + info = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::GetSubSkillsInfo, skillid); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return 0; } virtual bool IsItemValid(int itempos, bool &valid) { if (m_connected) { try { - valid = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::IsItemValid, itempos); + valid = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::IsItemValid, itempos); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool GetItemInfo(int itempos, cga_item_info_t &info) { if (m_connected) { try { - info = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::GetItemInfo, itempos); + info = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::GetItemInfo, itempos); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool GetItemsInfo(cga_items_info_t &info) { if (m_connected) { try { - info = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::GetItemsInfo); + info = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::GetItemsInfo); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool GetBankItemsInfo(cga_items_info_t &info) { if (m_connected) { try { - info = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::GetBankItemsInfo); + info = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::GetBankItemsInfo); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool DropItem(int itempos, bool &result) { if (m_connected) { try { - result = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::DropItem, itempos); + result = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::DropItem, itempos); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool UseItem(int itempos, bool &result) { if (m_connected) { try { - result = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::UseItem, itempos); + result = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::UseItem, itempos); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool MoveItem(int itempos, int dstpos, int count, bool &result) { if (m_connected) { try { - result = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::MoveItem, itempos, dstpos, count); + result = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::MoveItem, itempos, dstpos, count); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } + } + return false; + } + virtual bool DropPet(int petpos, bool &result) { + if (m_connected) { + try { + result = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::DropPet, petpos); + return true; + } + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } + } + return false; + } + virtual bool GetMapIndex(int &index1, int &index2, int &index3) { + if (m_connected) { + try { + std::tuple tup = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::GetMapIndex); + index1 = std::get<0>(tup); + index2 = std::get<1>(tup); + index3 = std::get<2>(tup); + return true; + } + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool GetMapXY(int &x, int &y) { if (m_connected) { try { - std::tuple tup = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::GetMapXY); + std::tuple tup = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::GetMapXY); x = std::get<0>(tup); y = std::get<1>(tup); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool GetMapXYFloat(float &x, float &y) { if (m_connected) { try { - std::tuple tup = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::GetMapXYFloat); + std::tuple tup = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::GetMapXYFloat); x = std::get<0>(tup); y = std::get<1>(tup); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool GetMoveSpeed(float &x, float &y) { if (m_connected) { try { - std::tuple tup = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::GetMoveSpeed); + std::tuple tup = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::GetMoveSpeed); x = std::get<0>(tup); y = std::get<1>(tup); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool GetMapName(std::string &name) { if (m_connected) { try { - name = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::GetMapName); + name = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::GetMapName); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool GetMapUnits(cga_map_units_t &units) { if (m_connected) { try { - units = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::GetMapUnits); + units = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::GetMapUnits); + return true; + } + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } + } + return false; + } + virtual bool GetMapCollisionTable(bool loadall, cga_map_cells_t &cells) { + if (m_connected) { + try { + cells = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::GetMapCollisionTable, loadall); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } + } + return false; + } + virtual bool GetMapObjectTable(bool loadall, cga_map_cells_t &cells) { + if (m_connected) { + try { + cells = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::GetMapObjectTable, loadall); + return true; + } + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool WalkTo(int x, int y) { if (m_connected) { try { - m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::WalkTo, x, y); + m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::WalkTo, x, y); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool TurnTo(int x, int y) { if (m_connected) { try { - m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::TurnTo, x, y); + m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::TurnTo, x, y); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool ForceMove(int dir, bool show, bool &result) { if (m_connected) { try { - result = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::ForceMove, dir, show); + result = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::ForceMove, dir, show); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool ForceMoveTo(int x, int y, bool show, bool &result) { if (m_connected) { try { - result = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::ForceMoveTo, x, y, show); + result = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::ForceMoveTo, x, y, show); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool IsMapCellPassable(int x, int y, bool &result) { if (m_connected) { try { - result = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::IsMapCellPassable, x, y); + result = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::IsMapCellPassable, x, y); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool SetMoveSpeed(int speed) { if (m_connected) { try { - m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::SetMoveSpeed, speed); + m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::SetMoveSpeed, speed); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool LogBack() { if (m_connected) { try { - m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::LogBack); + m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::LogBack); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool LogOut() { if (m_connected) { try { - m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::LogOut); + m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::LogOut); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool SayWords(std::string &str, int color , int range, int size) { if (m_connected) { try { - m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::SayWords, str, color, range, size); + m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::SayWords, str, color, range, size); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool ClickNPCDialog(int option, int index, bool &result) { if (m_connected) { try { - result = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::ClickNPCDialog, option, index); + result = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::ClickNPCDialog, option, index); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool SellNPCStore(cga_sell_items_t &items, bool &result) { if (m_connected) { try { - result = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::SellNPCStore, items); + result = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::SellNPCStore, items); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool BuyNPCStore(cga_buy_items_t &items, bool &result) { if (m_connected) { try { - result = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::BuyNPCStore, items); + result = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::BuyNPCStore, items); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } - virtual bool PlayerMenuSelect(int menuindex, bool &result) { + virtual bool PlayerMenuSelect(int menuindex, std::string &menustring, bool &result) { if (m_connected) { try { - result = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::PlayerMenuSelect, menuindex); + result = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::PlayerMenuSelect, menuindex, menustring); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool UnitMenuSelect(int menuindex, bool &result) { if (m_connected) { try { - result = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::UnitMenuSelect, menuindex); + result = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::UnitMenuSelect, menuindex); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool IsBattleUnitValid(int pos, bool &valid) { if (m_connected) { try { - valid = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::IsBattleUnitValid, pos); + valid = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::IsBattleUnitValid, pos); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool GetBattleUnit(int pos, cga_battle_unit_t &unit) { if (m_connected) { try { - unit = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::GetBattleUnit, pos); + unit = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::GetBattleUnit, pos); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } virtual bool GetBattleUnits(cga_battle_units_t &units) { if (m_connected) { try { - units = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::GetBattleUnits); + units = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::GetBattleUnits); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } - virtual bool GetBattleRoundCount(int &count) { + virtual bool GetBattleContext(cga_battle_context_t &ctx) { if (m_connected) { try { - count = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::GetBattleRoundCount); + ctx = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::GetBattleContext); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } - virtual bool GetBattlePlayerPosition(int &pos) { + virtual bool BattleNormalAttack(int target, bool &result) { if (m_connected) { try { - pos = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::GetBattlePlayerPosition); + result = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::BattleNormalAttack, target); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } - virtual bool GetBattlePlayerStatus(int &status) { + virtual bool BattleSkillAttack(int skillpos, int skilllv, int target, bool &result) { if (m_connected) { try { - status = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::GetBattlePlayerStatus); + result = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::BattleSkillAttack, skillpos, skilllv, target); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } - virtual bool GetBattlePetId(int &petid) { + virtual bool BattleDefense(bool &result) { if (m_connected) { try { - petid = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::GetBattlePetId); + result = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::BattleDefense); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } - virtual bool BattleNormalAttack(int target, bool &result) { + virtual bool BattleEscape(bool &result) { if (m_connected) { try { - result = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::BattleNormalAttack, target); + result = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::BattleEscape); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } - virtual bool BattleSkillAttack(int skillpos, int skilllv, int target, bool &result) { + virtual bool BattleExchangePosition(bool &result) { if (m_connected) { try { - result = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::BattleSkillAttack, skillpos, skilllv, target); + result = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::BattleExchangePosition); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } - virtual bool BattleDefense(bool &result) { + virtual bool BattleChangePet(int petid, bool &result) { if (m_connected) { try { - result = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::BattleDefense); + result = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::BattleChangePet, petid); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } - virtual bool BattleEscape(bool &result) { + virtual bool BattleUseItem(int itempos, int target, bool &result) { if (m_connected) { try { - result = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::BattleEscape); + result = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::BattleUseItem, itempos, target); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } - virtual bool BattleExchangePosition(bool &result) { + virtual bool BattlePetSkillAttack(int skillpos, int target, bool &result) { if (m_connected) { try { - result = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::BattleExchangePosition); + result = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::BattlePetSkillAttack, skillpos, target); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } - virtual bool BattleChangePet(int petid, bool &result) { + virtual bool BattleSetHighSpeedEnabled(bool enable) { if (m_connected) { try { - result = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::BattleChangePet, petid); + m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::BattleSetHighSpeedEnabled, enable); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } - virtual bool BattleUseItem(int itempos, int target, bool &result) { + virtual bool BattleSetShowHPMPEnabled(bool enable) { if (m_connected) { try { - result = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::BattleUseItem, itempos, target); + m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::BattleSetShowHPMPEnabled, enable); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } - virtual bool BattlePetSkillAttack(int skillpos, int target, bool &result) { + virtual bool GetBattleEndTick(int &msec) { if (m_connected) { try { - result = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::BattlePetSkillAttack, skillpos, target); + msec = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::GetBattleEndTick); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } - virtual bool BattleSetHighSpeedEnabled(bool enable) { + virtual bool SetBattleEndTick(int msec) { if (m_connected) { try { - m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::BattleSetHighSpeedEnabled, enable); + m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::SetBattleEndTick, msec); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } - virtual bool BattleSetShowHPMPEnabled(bool enable) { + virtual bool SetWorkDelay(int delay) + { if (m_connected) { try { - m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::BattleSetShowHPMPEnabled, enable); + m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::SetWorkDelay, delay); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } - virtual bool GetBattleEndTick(int &msec) { + virtual bool SetWorkAcceleration(int percent) + { if (m_connected) { try { - msec = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::GetBattleEndTick); + m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::SetWorkAcceleration, percent); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } - virtual bool SetBattleEndTick(int msec) { + virtual bool SetImmediateDoneWork(bool enable) + { if (m_connected) { try { - m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::SetBattleEndTick, msec); + m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::SetImmediateDoneWork, enable); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } - virtual bool SetWorkDelay(int delay) + virtual bool StartWork(int skill_index, int sub_index, bool &result) { if (m_connected) { try { - m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::SetWorkDelay, delay); + result = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::StartWork, skill_index, sub_index); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } - virtual bool SetWorkAcceleration(int percent) + virtual bool CraftItem(cga_craft_item_t &craft, bool &result) { if (m_connected) { try { - m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::SetWorkAcceleration, percent); + result = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::CraftItem, craft); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { + OutputDebugStringA(e.what()); + } } return false; } - virtual bool StartWork(int skill_index, int sub_index, bool &result) + virtual bool AssessItem(int skill_index, int itempos, bool &result) { if (m_connected) { try { - result = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::StartWork, skill_index, sub_index); + result = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::AssessItem, skill_index, itempos); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } - virtual bool CraftItem(cga_craft_item_t &craft, bool &result) + virtual bool GetCraftInfo(int skill_index, int sub_index, cga_craft_info_t &info) { if (m_connected) { try { - result = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::CraftItem, craft); + info = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::GetCraftInfo, skill_index, sub_index); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } - virtual bool AssessItem(int skill_index, int itempos, bool &result) + virtual bool GetCraftsInfo(int skill_index, cga_crafts_info_t &info) { if (m_connected) { try { - result = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::AssessItem, skill_index, itempos); + info = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::GetCraftsInfo, skill_index); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } - virtual bool GetCraftInfo(int skill_index, int sub_index, cga_craft_info_t &info) + + virtual bool DoRequest(int request_type, bool &result) { if (m_connected) { try { - info = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::GetCraftInfo, skill_index, sub_index); + result = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::DoRequest, request_type); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } - virtual bool GetCraftsInfo(int skill_index, cga_crafts_info_t &info) + virtual bool EnableFlags(int type, bool enable, bool &result) { if (m_connected) { try { - info = m_client.call(std::chrono::milliseconds(1000), m_endpoint, CGAServiceProtocol::GetCraftsInfo, skill_index); + result = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::EnableFlags, type, enable); return true; } - catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA(__FUNCTION__); } - catch (msgpack::parse_error &e) {} + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } + } + return false; + } + virtual bool TradeAddStuffs(cga_sell_items_t items, cga_sell_pets_t pets, int gold) + { + if (m_connected) { + try { + m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::TradeAddStuffs, items, pets, gold); + return true; + } + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } + } + return false; + } + virtual bool GetTeamPlayerInfo(cga_team_players_t &result) + { + if (m_connected) { + try { + result = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::GetTeamPlayerInfo); + return true; + } + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } + } + return false; + } + virtual bool FixMapWarpStuck(int type) + { + if (m_connected) { + try { + m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::FixMapWarpStuck, type); + return true; + } + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } + } + return false; + } + virtual bool SetNoSwitchAnim(bool enable) + { + if (m_connected) { + try { + m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::SetNoSwitchAnim, enable); + return true; + } + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } + } + return false; + } + virtual bool GetMoveHistory(std::vector &v) + { + if (m_connected) { + try { + v = m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::GetMoveHistory); + return true; + } + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } + } + return false; + } + virtual bool SetWindowResolution(int w, int h) + { + if (m_connected) { + try { + m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::SetWindowResolution, w, h); + return true; + } + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } + } + return false; + } + virtual bool RequestDownloadMap(int xbottom, int ybottom, int xsize, int ysize) + { + if (m_connected) { + try { + m_client.call(std::chrono::milliseconds(5000), m_endpoint, CGAServiceProtocol::RequestDownloadMap, xbottom, ybottom, xsize, ysize); + return true; + } + catch (timax::rpc::exception const &e) { if (e.get_error_code() != timax::rpc::error_code::TIMEOUT) m_connected = false; OutputDebugStringA("rpc exception from " __FUNCTION__); OutputDebugStringA(e.get_error_message().c_str()); } + catch (msgpack::parse_error &e) { OutputDebugStringA("parse exception from " __FUNCTION__); OutputDebugStringA(e.what()); } } return false; } @@ -1048,6 +1199,75 @@ namespace CGA } return false; } + virtual bool RegisterTradeStuffsNotify(const std::function &callback) + { + if (m_connected) + { + try + { + m_async_client.sub(m_endpoint, CGAServiceProtocol::NotifyTradeStuffs, + [callback](cga_trade_stuff_info_t rs) { + if (callback) + callback(rs); + }, + [](auto const& e) { + OutputDebugStringA(e.get_error_message().c_str()); + } + ); + return true; + } + catch (timax::rpc::exception const& e) { + OutputDebugStringA(e.get_error_message().c_str()); + } + } + return false; + } + virtual bool RegisterTradeDialogNotify(const std::function &callback) + { + if (m_connected) + { + try + { + m_async_client.sub(m_endpoint, CGAServiceProtocol::NotifyTradeDialog, + [callback](cga_trade_dialog_t rs) { + if (callback) + callback(rs); + }, + [](auto const& e) { + OutputDebugStringA(e.get_error_message().c_str()); + } + ); + return true; + } + catch (timax::rpc::exception const& e) { + OutputDebugStringA(e.get_error_message().c_str()); + } + } + return false; + } + virtual bool RegisterTradeStateNotify(const std::function &callback) + { + if (m_connected) + { + try + { + m_async_client.sub(m_endpoint, CGAServiceProtocol::NotifyTradeState, + [callback](int rs) { + if (callback) + callback(rs); + }, + [](auto const& e) { + OutputDebugStringA(e.get_error_message().c_str()); + } + ); + return true; + } + catch (timax::rpc::exception const& e) { + OutputDebugStringA(e.get_error_message().c_str()); + } + } + return false; + } }; CGAInterface *CreateInterface() diff --git a/CGALib/gameinterface.h b/CGALib/gameinterface.h index 462a8c8..03a5dc3 100644 --- a/CGALib/gameinterface.h +++ b/CGALib/gameinterface.h @@ -14,6 +14,74 @@ namespace CGA cg_item_6000, }; + typedef struct cga_playerpet_detail_info_s + { + cga_playerpet_detail_info_s() + { + points_remain = 0; + points_endurance = 0; + points_strength = 0; + points_defense = 0; + points_agility = 0; + points_magical = 0; + value_attack = 0; + value_defensive = 0; + value_agility = 0; + value_spirit = 0; + value_recovery = 0; + resist_poison = 0; + resist_sleep = 0; + resist_medusa = 0; + resist_drunk = 0; + resist_chaos = 0; + resist_forget = 0; + fix_critical = 0; + fix_strikeback = 0; + fix_accurancy = 0; + fix_dodge = 0; + element_earth = 0; + element_water = 0; + element_fire = 0; + element_wind = 0; + } + cga_playerpet_detail_info_s(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10, + int a11, int a12, int a13, int a14, int a15, int a16, int a17, int a18, int a19, int a20, + int a21, int a22, int a23, int a24, int a25) : + points_remain(a1), points_endurance(a2), points_strength(a3), points_defense(a4), points_agility(a5), points_magical(a6), + value_attack(a7), value_defensive(a8), value_agility(a9), value_spirit(a10), value_recovery(a11), + resist_poison(a12), resist_sleep(a13), resist_medusa(a14), resist_drunk(a15), resist_chaos(a16), resist_forget(a17), + fix_critical(a18), fix_strikeback(a19), fix_accurancy(a20), fix_dodge(a21), + element_earth(a22), element_water(a23), element_fire(a24), element_wind(a25) + { + + } + int points_remain; + int points_endurance; + int points_strength; + int points_defense; + int points_agility; + int points_magical; + int value_attack; + int value_defensive; + int value_agility; + int value_spirit; + int value_recovery; + int resist_poison; + int resist_sleep; + int resist_medusa; + int resist_drunk; + int resist_chaos; + int resist_forget; + int fix_critical; + int fix_strikeback; + int fix_accurancy; + int fix_dodge; + int element_earth; + int element_water; + int element_fire; + int element_wind; + }cga_playerpet_detail_info_t; + typedef struct cga_player_info_s { cga_player_info_s() @@ -25,6 +93,7 @@ namespace CGA xp = 0; maxxp = 0; health = 0; + souls = 0; level = 0; gold = 0; unitid = 0; @@ -33,8 +102,8 @@ namespace CGA usingpunchclock = false; } - cga_player_info_s(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10, int a11, int a12, int a13, std::string &a14, std::string &a15) - : hp(a1), maxhp(a2), mp(a3), maxmp(a4), xp(a5), maxxp(a6), health(a7), level(a8), gold(a9), unitid(a10), petid(a11), punchclock(a12), usingpunchclock(a13 ? true : false), name(a14), job(a15) + cga_player_info_s(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10, int a11, int a12, int a13, int a14, std::string &a15, std::string &a16, const cga_playerpet_detail_info_t &a17, int a18, int a19, int a20) + : hp(a1), maxhp(a2), mp(a3), maxmp(a4), xp(a5), maxxp(a6), health(a7), souls(a8), level(a9), gold(a10), unitid(a11), petid(a12), punchclock(a13), usingpunchclock(a14 ? true : false), name(a15), job(a16), detail(a17), manu_endurance(a18), manu_skillful(a19), manu_intelligence(a20) { } @@ -46,6 +115,7 @@ namespace CGA int xp; int maxxp; int health; + int souls; int level; int gold; int unitid; @@ -54,6 +124,11 @@ namespace CGA bool usingpunchclock; std::string name; std::string job; + std::vector titles; + cga_playerpet_detail_info_t detail; + int manu_endurance; + int manu_skillful; + int manu_intelligence; }cga_player_info_t; typedef struct cga_pet_info_s @@ -70,11 +145,14 @@ namespace CGA level = 0; flags = 0; race = 0; + loyality = 0; battle_flags = 0; index = 0; } - cga_pet_info_s(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10, int a11, int a12, std::string &a13, std::string &a14) - : hp(a1), maxhp(a2), mp(a3), maxmp(a4), xp(a5), maxxp(a6), health(a7), level(a8), flags(a9), race(a10), battle_flags(a11), index(a12), name(a13), realname(a14) + cga_pet_info_s(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10, + int a11, int a12, int a13, std::string &a14, std::string &a15, const cga_playerpet_detail_info_t &a16) + : hp(a1), maxhp(a2), mp(a3), maxmp(a4), xp(a5), maxxp(a6), health(a7), level(a8), flags(a9), race(a10), + loyality(a11), battle_flags(a12), index(a13), name(a14), realname(a15), detail(a16) { } @@ -88,14 +166,63 @@ namespace CGA int level; int flags; int race; + int loyality; int battle_flags; int index; std::string name; std::string realname; + cga_playerpet_detail_info_t detail; }cga_pet_info_t; typedef std::vector cga_pets_info_t; + typedef struct cga_trade_pet_info_s + { + cga_trade_pet_info_s() + { + level = 0; + race = 0; + maxhp = 0; + maxmp = 0; + loyality = 0; + skill_count = 0; + image_id = 0; + index = 0; + } + cga_trade_pet_info_s(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, + std::string &a9, std::string &a10, const cga_playerpet_detail_info_t &a11) + : level(a1), race(a2), maxhp(a3), maxmp(a4), loyality(a5), skill_count(a6), image_id(a7), index(a8), + name(a9), realname(a10), detail(a11) + { + + } + int level; + int race; + int maxhp; + int maxmp; + int loyality; + int skill_count; + int image_id; + int index; + std::string name; + std::string realname; + cga_playerpet_detail_info_t detail; + }cga_trade_pet_info_t; + + typedef struct cga_trade_pet_skill_info_s + { + cga_trade_pet_skill_info_s() + { + index = 0; + } + cga_trade_pet_skill_info_s(int a1) + { + + } + int index; + std::vector skills; + }cga_trade_pet_skill_info_t; + typedef struct cga_pet_skill_info_s { cga_pet_skill_info_s() @@ -129,9 +256,10 @@ namespace CGA skill_id = 0; pos = 0; index = 0; + slotsize = 0; } - cga_skill_info_s(std::string &a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9) - : name(a1), lv(a2), maxlv(a3), xp(a4), maxxp(a5), skill_id(a6), type(a7), pos(a8), index(a9) + cga_skill_info_s(std::string &a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10) + : name(a1), lv(a2), maxlv(a3), xp(a4), maxxp(a5), skill_id(a6), type(a7), pos(a8), index(a9), slotsize(a10) { } std::string name; @@ -143,6 +271,7 @@ namespace CGA int type; int pos; int index; + int slotsize; }cga_skill_info_t; typedef std::vector cga_skills_info_t; @@ -154,9 +283,10 @@ namespace CGA cost = 0; flags = 0; level = 0; + available = false; } - cga_subskill_info_s(std::string &a1, std::string &a2, int a3, int a4, int a5) - : name(a1), info(a2), cost(a3), flags(a4), level(a5) + cga_subskill_info_s(std::string &a1, std::string &a2, int a3, int a4, int a5, bool a6) + : name(a1), info(a2), cost(a3), flags(a4), level(a5), available(a6) { } @@ -165,6 +295,7 @@ namespace CGA int cost; int flags; int level; + bool available; }cga_subskill_info_t; typedef std::vector cga_subskills_info_t; @@ -209,11 +340,12 @@ namespace CGA maxhp = 0; curmp = 0; maxmp = 0; + flags = 0; pos = 0; } - cga_battle_unit_s(std::string &a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) : - name(a1), modelid(a2), level(a3), curhp(a4), maxhp(a5), curmp(a6), maxmp(a7), pos(a8) + cga_battle_unit_s(std::string &a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9) : + name(a1), modelid(a2), level(a3), curhp(a4), maxhp(a5), curmp(a6), maxmp(a7), flags(a8), pos(a9) { } @@ -224,6 +356,7 @@ namespace CGA int maxhp; int curmp; int maxmp; + int flags; int pos; }cga_battle_unit_t; @@ -304,9 +437,11 @@ namespace CGA xpos = 0; ypos = 0; item_count = 0; + injury = 0; + level = 0; } - cga_map_unit_s(int a1, int a2, int a3, int a4, int a5, int a6, int a7, std::string &a8, std::string &a9, std::string &a10) - : valid(a1), type(a2), unit_id(a3), model_id(a4), xpos(a5), ypos(a6), item_count(a7), unit_name(a8), nick_name(a9), item_name(a10) + cga_map_unit_s(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10, std::string &a11, std::string &a12, std::string &a13, std::string &a14) + : valid(a1), type(a2), unit_id(a3), model_id(a4), xpos(a5), ypos(a6), item_count(a7), injury(a8), level(a9), flags(a10), unit_name(a11), nick_name(a12), title_name(a13), item_name(a14) { } @@ -317,8 +452,12 @@ namespace CGA int xpos; int ypos; int item_count; + int injury; + int level; + int flags; std::string unit_name; std::string nick_name; + std::string title_name; std::string item_name; }cga_map_unit_t; @@ -342,6 +481,8 @@ namespace CGA typedef std::vector cga_sell_items_t; + typedef std::vector cga_sell_pets_t; + typedef struct cga_buy_item_s { cga_buy_item_s() @@ -377,7 +518,7 @@ namespace CGA int skill_index; int subskill_index; int sub_type; - int itempos[5]; + int itempos[6]; }cga_craft_item_t; typedef struct cga_working_result_s @@ -479,6 +620,116 @@ namespace CGA int size; }cga_chat_msg_t; + typedef struct cga_trade_stuff_s + { + cga_trade_stuff_s() + { + gold = 0; + } + + cga_sell_items_t items; + cga_sell_pets_t pets; + int gold; + }cga_trade_stuff_t; + + typedef struct cga_trade_stuff_info_s + { + cga_trade_stuff_info_s() + { + gold = 0; + type = 0; + } + cga_trade_stuff_info_s(int a1) : type (a1) + { + gold = 0; + } + + cga_items_info_t items; + cga_trade_pet_info_t pet; + cga_trade_pet_skill_info_t petskills; + int gold; + int type; + }cga_trade_stuff_info_t; + + typedef struct cga_team_player_s + { + cga_team_player_s() + { + unit_id = 0; + hp = 0; + mp = 0; + maxhp = 0; + } + cga_team_player_s(int a1, int a2, int a3, int a4, const std::string &a5) : unit_id(a1), hp(a2), mp(a3), maxhp(a4), name(a5) + { + + } + int unit_id; + int hp; + int mp; + int maxhp; + std::string name; + }cga_team_player_t; + + typedef std::vector cga_team_players_t; + + typedef struct cga_map_cells_s + { + cga_map_cells_s() + { + x_bottom = 0; + y_bottom = 0; + x_size = 0; + y_size = 0; + } + cga_map_cells_s(int a1, int a2, int a3, int a4, short *a5) : x_bottom(a1), y_bottom(a2), x_size(a3), y_size(a4) + { + cell.resize(a3 * a4); + memcpy(cell.data(), a5, sizeof(short) * a3 * a4); + } + int x_bottom; + int y_bottom; + int x_size; + int y_size; + std::vector cell; + }cga_map_cells_t; + + typedef struct cga_trade_dialog_s + { + cga_trade_dialog_s() + { + level = 0; + } + cga_trade_dialog_s(std::string &a1, int a2) + : name(a1), level(a2) + { + } + std::string name; + int level; + }cga_trade_dialog_t; + + typedef struct cga_battle_context_s + { + cga_battle_context_s() { + + + } + cga_battle_context_s(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9) : + round_count(a1), player_pos(a2), player_status(a3), skill_performed(a4), skill_allowbit(a5), petskill_allowbit(a6), weapon_allowbit(a7), petid(a8), effect_flags(a9) + { + + } + int round_count; + int player_pos; + int player_status; + int skill_performed; + int skill_allowbit; + int petskill_allowbit; + int weapon_allowbit; + int petid; + int effect_flags; + }cga_battle_context_t; + typedef struct CGAShare_s { int ProcessId; @@ -492,27 +743,70 @@ namespace CGA int reserved; }cga_game_data_t; +#define TRADE_STUFFS_ITEM 1 +#define TRADE_STUFFS_PET 2 +#define TRADE_STUFFS_PETSKILL 3 +#define TRADE_STUFFS_GOLD 4 + +#define TRADE_STATE_CANCEL 0 +#define TRADE_STATE_READY 1 +#define TRADE_STATE_CONFIRM 2 +#define TRADE_STATE_SUCCEED 3 + #define FL_BATTLE_ACTION_ISPLAYER 1 #define FL_BATTLE_ACTION_ISDOUBLE 2 #define FL_BATTLE_ACTION_ISSKILLPERFORMED 4 - +#define FL_BATTLE_ACTION_END 8 + +#define FL_SKILL_SELECT_TARGET 0x1 +#define FL_SKILL_SELECT_DEAD 0x2 +#define FL_SKILL_TO_PET 0x4 +#define FL_SKILL_TO_SELF 0x8 +#define FL_SKILL_TO_TEAMMATE 0x10 +#define FL_SKILL_TO_ENEMY 0x20 #define FL_SKILL_SINGLE 0x40 #define FL_SKILL_MULTI 0x80 #define FL_SKILL_ALL 0x100 #define FL_SKILL_BOOM 0x200 - -#define PLAYER_ENABLE_FLAG_PK 0 -#define PLAYER_ENABLE_FLAG_TEAMCHAT 1 -#define PLAYER_ENABLE_FLAG_JOINTEAM 2 -#define PLAYER_ENABLE_FLAG_CARD 3 -#define PLAYER_ENABLE_FLAG_TRADE 4 -#define PLAYER_ENABLE_FLAG_FAMILY 5 +#define FL_SKILL_FRONT_ONLY 0x400 + +#define FL_DEBUFF_SLEEP 0x20 +#define FL_DEBUFF_MEDUSA 0x40 +#define FL_DEBUFF_DRUNK 0x80 +#define FL_DEBUFF_CHAOS 0x100 +#define FL_DEBUFF_FORGET 0x200 +#define FL_DEBUFF_POISON 0x400 +#define FL_DEBUFF_ANY (FL_DEBUFF_SLEEP | FL_DEBUFF_MEDUSA | FL_DEBUFF_DRUNK | FL_DEBUFF_CHAOS | FL_DEBUFF_FORGET | FL_DEBUFF_POISON) + +#define ENABLE_FLAG_PK 0 +#define ENABLE_FLAG_TEAMCHAT 1 +#define ENABLE_FLAG_JOINTEAM 2 +#define ENABLE_FLAG_CARD 3 +#define ENABLE_FLAG_TRADE 4 +#define ENABLE_FLAG_FAMILY 5 #define WORK_TYPE_CRAFTING 1 #define WORK_TYPE_ASSESSING 2 #define WORK_TYPE_HEALING 3 #define WORK_TYPE_GATHERING 4 +#define REQUEST_TYPE_PK 1 +#define REQUEST_TYPE_JOINTEAM 3 +#define REQUEST_TYPE_EXCAHNGECARD 4 +#define REQUEST_TYPE_TRADE 5 +#define REQUEST_TYPE_KICKTEAM 11 +#define REQUEST_TYPE_LEAVETEAM 12 +#define REQUEST_TYPE_TRADE_CONFIRM 13 +#define REQUEST_TYPE_TRADE_REFUSE 14 +#define REQUEST_TYPE_TEAM_CHAT 15 + +#define PLAYER_MENU_HEAL 1 +#define PLAYER_MENU_ITEM 2 +#define PLAYER_MENU_TRADE 3 + +#define UNIT_MENU_HEAL 1 +#define UNIT_MENU_ITEM 2 + class CGAInterface { public: @@ -547,11 +841,15 @@ namespace CGA virtual bool GetBankItemsInfo(cga_items_info_t &info) = 0; virtual bool DropItem(int itempos, bool &result) = 0; virtual bool MoveItem(int itempos, int dstpos, int count, bool &result) = 0; + virtual bool DropPet(int petpos, bool &result) = 0; + virtual bool GetMapIndex(int &index1, int &index2, int &index3) = 0; virtual bool GetMapXY(int &x, int &y) = 0; virtual bool GetMapXYFloat(float &x, float &y) = 0; virtual bool GetMoveSpeed(float &x, float &y) = 0; virtual bool GetMapName(std::string &name) = 0; virtual bool GetMapUnits(cga_map_units_t &units) = 0; + virtual bool GetMapCollisionTable(bool loadall, cga_map_cells_t &cells) = 0; + virtual bool GetMapObjectTable(bool loadall, cga_map_cells_t &cells) = 0; virtual bool WalkTo(int x, int y) = 0; virtual bool TurnTo(int x, int y) = 0; @@ -567,16 +865,13 @@ namespace CGA virtual bool ClickNPCDialog(int option, int index, bool &result) = 0; virtual bool SellNPCStore(cga_sell_items_t &items, bool &result) = 0; virtual bool BuyNPCStore(cga_buy_items_t &items, bool &result) = 0; - virtual bool PlayerMenuSelect(int menuindex, bool &result) = 0; + virtual bool PlayerMenuSelect(int menuindex, std::string &menustring, bool &result) = 0; virtual bool UnitMenuSelect(int menuindex, bool &result) = 0; virtual bool IsBattleUnitValid(int pos, bool &valid) = 0; virtual bool GetBattleUnit(int pos, cga_battle_unit_t &unit) = 0; virtual bool GetBattleUnits(cga_battle_units_t &units) = 0; - virtual bool GetBattleRoundCount(int &count) = 0; - virtual bool GetBattlePlayerPosition(int &pos) = 0; - virtual bool GetBattlePlayerStatus(int &status) = 0; - virtual bool GetBattlePetId(int &petid) = 0; + virtual bool GetBattleContext(cga_battle_context_t &ctx) = 0; virtual bool BattleNormalAttack(int target, bool &result) = 0; virtual bool BattleSkillAttack(int skillpos, int skilllv, int target, bool &result) = 0; @@ -592,12 +887,24 @@ namespace CGA virtual bool SetBattleEndTick(int msec) = 0; virtual bool SetWorkDelay(int delay) = 0; virtual bool SetWorkAcceleration(int percent) = 0; + virtual bool SetImmediateDoneWork(bool enable) = 0; virtual bool StartWork(int skill_index, int sub_index, bool &result) = 0; virtual bool CraftItem(cga_craft_item_t &craft, bool &result) = 0; virtual bool AssessItem(int skill_index, int itempos, bool &result) = 0; virtual bool GetCraftInfo(int skill_index, int sub_index, cga_craft_info_t &info) = 0; virtual bool GetCraftsInfo(int skill_index, cga_crafts_info_t &info) = 0; + virtual bool DoRequest(int request_type, bool &result) = 0; + virtual bool EnableFlags(int type, bool enable, bool &result) = 0; + virtual bool TradeAddStuffs(cga_sell_items_t items, cga_sell_pets_t pets, int gold) = 0; + virtual bool GetTeamPlayerInfo(cga_team_players_t &result) = 0; + + virtual bool FixMapWarpStuck(int type) = 0; + virtual bool SetNoSwitchAnim(bool enable) = 0; + virtual bool GetMoveHistory(std::vector &v) = 0; + virtual bool SetWindowResolution(int w, int h) = 0; + virtual bool RequestDownloadMap(int xbottom, int ybottom, int xsize, int ysize) = 0; + virtual bool RegisterServerShutdownNotify(const std::function &callback) = 0; virtual bool RegisterBattleActionNotify(const std::function &callback) = 0; virtual bool RegisterPlayerMenuNotify(const std::function &callback) = 0; @@ -605,6 +912,9 @@ namespace CGA virtual bool RegisterNPCDialogNotify(const std::function &callback) = 0; virtual bool RegisterWorkingResultNotify(const std::function &callback) = 0; virtual bool RegisterChatMsgNotify(const std::function &callback) = 0; + virtual bool RegisterTradeStuffsNotify(const std::function &callback) = 0; + virtual bool RegisterTradeDialogNotify(const std::function &callback) = 0; + virtual bool RegisterTradeStateNotify(const std::function &callback) = 0; }; extern "C" CGAInterface *CreateInterface(); diff --git a/CGALib/packdata.h b/CGALib/packdata.h index 563e307..7299687 100644 --- a/CGALib/packdata.h +++ b/CGALib/packdata.h @@ -13,7 +13,7 @@ namespace msgpack { struct convert { msgpack::object const& operator()(msgpack::object const& o, cga_player_info_t& v) const { if (o.type != msgpack::type::ARRAY) throw msgpack::type_error(); - if (o.via.array.size != 15) throw msgpack::type_error(); + if (o.via.array.size != 21) throw msgpack::type_error(); v.hp = o.via.array.ptr[0].as(); v.maxhp = o.via.array.ptr[1].as(); v.mp = o.via.array.ptr[2].as(); @@ -21,14 +21,20 @@ namespace msgpack { v.xp = o.via.array.ptr[4].as(); v.maxxp = o.via.array.ptr[5].as(); v.health = o.via.array.ptr[6].as(); - v.level = o.via.array.ptr[7].as(); - v.gold = o.via.array.ptr[8].as(); - v.unitid = o.via.array.ptr[9].as(); - v.petid = o.via.array.ptr[10].as(); - v.punchclock = o.via.array.ptr[11].as(); - v.usingpunchclock = o.via.array.ptr[12].as(); - v.name = o.via.array.ptr[13].as(); - v.job = o.via.array.ptr[14].as(); + v.souls = o.via.array.ptr[7].as(); + v.level = o.via.array.ptr[8].as(); + v.gold = o.via.array.ptr[9].as(); + v.unitid = o.via.array.ptr[10].as(); + v.petid = o.via.array.ptr[11].as(); + v.punchclock = o.via.array.ptr[12].as(); + v.usingpunchclock = o.via.array.ptr[13].as(); + v.name = o.via.array.ptr[14].as(); + v.job = o.via.array.ptr[15].as(); + v.titles = o.via.array.ptr[16].as>(); + v.detail = o.via.array.ptr[17].as(); + v.manu_endurance = o.via.array.ptr[18].as(); + v.manu_skillful = o.via.array.ptr[19].as(); + v.manu_intelligence = o.via.array.ptr[20].as(); return o; } }; @@ -38,7 +44,7 @@ namespace msgpack { template packer& operator()(msgpack::packer& o, cga_player_info_t const& v) const { // packing member variables as an array. - o.pack_array(15); + o.pack_array(21); o.pack(v.hp); o.pack(v.maxhp); o.pack(v.mp); @@ -46,6 +52,7 @@ namespace msgpack { o.pack(v.xp); o.pack(v.maxxp); o.pack(v.health); + o.pack(v.souls); o.pack(v.level); o.pack(v.gold); o.pack(v.unitid); @@ -54,6 +61,11 @@ namespace msgpack { o.pack(v.usingpunchclock); o.pack(v.name); o.pack(v.job); + o.pack(v.titles); + o.pack(v.detail); + o.pack(v.manu_endurance); + o.pack(v.manu_skillful); + o.pack(v.manu_intelligence); return o; } }; @@ -62,7 +74,7 @@ namespace msgpack { struct object_with_zone { void operator()(msgpack::object::with_zone& o, cga_player_info_t const& v) const { o.type = type::ARRAY; - o.via.array.size = 15; + o.via.array.size = 21; o.via.array.ptr = static_cast(o.zone.allocate_align(sizeof(msgpack::object) * o.via.array.size)); o.via.array.ptr[0] = msgpack::object(v.hp, o.zone); o.via.array.ptr[1] = msgpack::object(v.maxhp, o.zone); @@ -71,14 +83,20 @@ namespace msgpack { o.via.array.ptr[4] = msgpack::object(v.xp, o.zone); o.via.array.ptr[5] = msgpack::object(v.maxxp, o.zone); o.via.array.ptr[6] = msgpack::object(v.health, o.zone); - o.via.array.ptr[7] = msgpack::object(v.level, o.zone); - o.via.array.ptr[8] = msgpack::object(v.gold, o.zone); - o.via.array.ptr[9] = msgpack::object(v.unitid, o.zone); - o.via.array.ptr[10] = msgpack::object(v.petid, o.zone); - o.via.array.ptr[11] = msgpack::object(v.punchclock, o.zone); - o.via.array.ptr[12] = msgpack::object(v.usingpunchclock, o.zone); - o.via.array.ptr[13] = msgpack::object(v.name, o.zone); - o.via.array.ptr[14] = msgpack::object(v.job, o.zone); + o.via.array.ptr[7] = msgpack::object(v.souls, o.zone); + o.via.array.ptr[8] = msgpack::object(v.level, o.zone); + o.via.array.ptr[9] = msgpack::object(v.gold, o.zone); + o.via.array.ptr[10] = msgpack::object(v.unitid, o.zone); + o.via.array.ptr[11] = msgpack::object(v.petid, o.zone); + o.via.array.ptr[12] = msgpack::object(v.punchclock, o.zone); + o.via.array.ptr[13] = msgpack::object(v.usingpunchclock, o.zone); + o.via.array.ptr[14] = msgpack::object(v.name, o.zone); + o.via.array.ptr[15] = msgpack::object(v.job, o.zone); + o.via.array.ptr[16] = msgpack::object(v.titles, o.zone); + o.via.array.ptr[17] = msgpack::object(v.detail, o.zone); + o.via.array.ptr[18] = msgpack::object(v.manu_endurance, o.zone); + o.via.array.ptr[19] = msgpack::object(v.manu_skillful, o.zone); + o.via.array.ptr[20] = msgpack::object(v.manu_intelligence, o.zone); } }; @@ -88,7 +106,7 @@ namespace msgpack { struct convert { msgpack::object const& operator()(msgpack::object const& o, cga_pet_info_t& v) const { if (o.type != msgpack::type::ARRAY) throw msgpack::type_error(); - if (o.via.array.size != 14) throw msgpack::type_error(); + if (o.via.array.size != 16) throw msgpack::type_error(); v.hp = o.via.array.ptr[0].as(); v.maxhp = o.via.array.ptr[1].as(); v.mp = o.via.array.ptr[2].as(); @@ -99,10 +117,12 @@ namespace msgpack { v.level = o.via.array.ptr[7].as(); v.flags = o.via.array.ptr[8].as(); v.race = o.via.array.ptr[9].as(); - v.battle_flags = o.via.array.ptr[10].as(); - v.index = o.via.array.ptr[11].as(); - v.name = o.via.array.ptr[12].as(); - v.realname = o.via.array.ptr[13].as(); + v.loyality = o.via.array.ptr[10].as(); + v.battle_flags = o.via.array.ptr[11].as(); + v.index = o.via.array.ptr[12].as(); + v.name = o.via.array.ptr[13].as(); + v.realname = o.via.array.ptr[14].as(); + v.detail = o.via.array.ptr[15].as(); return o; } }; @@ -112,7 +132,7 @@ namespace msgpack { template packer& operator()(msgpack::packer& o, cga_pet_info_t const& v) const { // packing member variables as an array. - o.pack_array(14); + o.pack_array(16); o.pack(v.hp); o.pack(v.maxhp); o.pack(v.mp); @@ -123,10 +143,12 @@ namespace msgpack { o.pack(v.level); o.pack(v.flags); o.pack(v.race); + o.pack(v.loyality); o.pack(v.battle_flags); o.pack(v.index); o.pack(v.name); o.pack(v.realname); + o.pack(v.detail); return o; } }; @@ -135,7 +157,7 @@ namespace msgpack { struct object_with_zone { void operator()(msgpack::object::with_zone& o, cga_pet_info_t const& v) const { o.type = type::ARRAY; - o.via.array.size = 14; + o.via.array.size = 16; o.via.array.ptr = static_cast(o.zone.allocate_align(sizeof(msgpack::object) * o.via.array.size)); o.via.array.ptr[0] = msgpack::object(v.hp, o.zone); o.via.array.ptr[1] = msgpack::object(v.maxhp, o.zone); @@ -147,10 +169,112 @@ namespace msgpack { o.via.array.ptr[7] = msgpack::object(v.level, o.zone); o.via.array.ptr[8] = msgpack::object(v.flags, o.zone); o.via.array.ptr[9] = msgpack::object(v.race, o.zone); - o.via.array.ptr[10] = msgpack::object(v.battle_flags, o.zone); - o.via.array.ptr[11] = msgpack::object(v.index, o.zone); - o.via.array.ptr[12] = msgpack::object(v.name, o.zone); - o.via.array.ptr[13] = msgpack::object(v.realname, o.zone); + o.via.array.ptr[10] = msgpack::object(v.loyality, o.zone); + o.via.array.ptr[11] = msgpack::object(v.battle_flags, o.zone); + o.via.array.ptr[12] = msgpack::object(v.index, o.zone); + o.via.array.ptr[13] = msgpack::object(v.name, o.zone); + o.via.array.ptr[14] = msgpack::object(v.realname, o.zone); + o.via.array.ptr[15] = msgpack::object(v.detail, o.zone); + } + }; + + //trade_pet_info + + template<> + struct convert { + msgpack::object const& operator()(msgpack::object const& o, cga_trade_pet_info_t& v) const { + if (o.type != msgpack::type::ARRAY) throw msgpack::type_error(); + if (o.via.array.size != 10) throw msgpack::type_error(); + + v.level = o.via.array.ptr[0].as(); + v.race = o.via.array.ptr[1].as(); + v.maxhp = o.via.array.ptr[2].as(); + v.maxmp = o.via.array.ptr[3].as(); + v.skill_count = o.via.array.ptr[4].as(); + v.image_id = o.via.array.ptr[5].as(); + v.index = o.via.array.ptr[6].as(); + v.name = o.via.array.ptr[7].as(); + v.realname = o.via.array.ptr[8].as(); + v.detail = o.via.array.ptr[9].as(); + + return o; + } + }; + + template<> + struct pack { + template + packer& operator()(msgpack::packer& o, cga_trade_pet_info_t const& v) const { + // packing member variables as an array. + o.pack_array(10); + o.pack(v.level); + o.pack(v.race); + o.pack(v.maxhp); + o.pack(v.maxmp); + o.pack(v.skill_count); + o.pack(v.image_id); + o.pack(v.index); + o.pack(v.name); + o.pack(v.realname); + o.pack(v.detail); + return o; + } + }; + + template <> + struct object_with_zone { + void operator()(msgpack::object::with_zone& o, cga_trade_pet_info_t const& v) const { + o.type = type::ARRAY; + o.via.array.size = 10; + o.via.array.ptr = static_cast(o.zone.allocate_align(sizeof(msgpack::object) * o.via.array.size)); + o.via.array.ptr[0] = msgpack::object(v.level, o.zone); + o.via.array.ptr[1] = msgpack::object(v.race, o.zone); + o.via.array.ptr[2] = msgpack::object(v.maxhp, o.zone); + o.via.array.ptr[3] = msgpack::object(v.maxmp , o.zone); + o.via.array.ptr[4] = msgpack::object(v.skill_count, o.zone); + o.via.array.ptr[5] = msgpack::object(v.image_id, o.zone); + o.via.array.ptr[6] = msgpack::object(v.index, o.zone); + o.via.array.ptr[7] = msgpack::object(v.name, o.zone); + o.via.array.ptr[8] = msgpack::object(v.realname, o.zone); + o.via.array.ptr[9] = msgpack::object(v.detail, o.zone); + } + }; + + //cga_trade_pet_skill_info_t + + template<> + struct convert { + msgpack::object const& operator()(msgpack::object const& o, cga_trade_pet_skill_info_t& v) const { + if (o.type != msgpack::type::ARRAY) throw msgpack::type_error(); + if (o.via.array.size != 2) throw msgpack::type_error(); + + v.index = o.via.array.ptr[0].as(); + v.skills = o.via.array.ptr[1].as>(); + + return o; + } + }; + + template<> + struct pack { + template + packer& operator()(msgpack::packer& o, cga_trade_pet_skill_info_t const& v) const { + // packing member variables as an array. + o.pack_array(2); + o.pack(v.index); + o.pack(v.skills); + return o; + } + }; + + template <> + struct object_with_zone { + void operator()(msgpack::object::with_zone& o, cga_trade_pet_skill_info_t const& v) const { + o.type = type::ARRAY; + o.via.array.size = 2; + o.via.array.ptr = static_cast(o.zone.allocate_align(sizeof(msgpack::object) * o.via.array.size)); + o.via.array.ptr[0] = msgpack::object(v.index, o.zone); + o.via.array.ptr[1] = msgpack::object(v.skills, o.zone); } }; @@ -205,7 +329,7 @@ namespace msgpack { struct convert { msgpack::object const& operator()(msgpack::object const& o, cga_skill_info_t& v) const { if (o.type != msgpack::type::ARRAY) throw msgpack::type_error(); - if (o.via.array.size != 9) throw msgpack::type_error(); + if (o.via.array.size != 10) throw msgpack::type_error(); v.name = o.via.array.ptr[0].as(); v.lv = o.via.array.ptr[1].as(); v.maxlv = o.via.array.ptr[2].as(); @@ -215,6 +339,7 @@ namespace msgpack { v.type = o.via.array.ptr[6].as(); v.pos = o.via.array.ptr[7].as(); v.index = o.via.array.ptr[8].as(); + v.slotsize = o.via.array.ptr[9].as(); return o; } }; @@ -224,7 +349,7 @@ namespace msgpack { template packer& operator()(msgpack::packer& o, cga_skill_info_t const& v) const { // packing member variables as an array. - o.pack_array(9); + o.pack_array(10); o.pack(v.name); o.pack(v.lv); o.pack(v.maxlv); @@ -234,6 +359,7 @@ namespace msgpack { o.pack(v.type); o.pack(v.pos); o.pack(v.index); + o.pack(v.slotsize); return o; } }; @@ -242,7 +368,7 @@ namespace msgpack { struct object_with_zone { void operator()(msgpack::object::with_zone& o, cga_skill_info_t const& v) const { o.type = type::ARRAY; - o.via.array.size = 9; + o.via.array.size = 10; o.via.array.ptr = static_cast(o.zone.allocate_align(sizeof(msgpack::object) * o.via.array.size)); o.via.array.ptr[0] = msgpack::object(v.name, o.zone); o.via.array.ptr[1] = msgpack::object(v.lv, o.zone); @@ -253,6 +379,7 @@ namespace msgpack { o.via.array.ptr[6] = msgpack::object(v.type, o.zone); o.via.array.ptr[7] = msgpack::object(v.pos, o.zone); o.via.array.ptr[8] = msgpack::object(v.index, o.zone); + o.via.array.ptr[9] = msgpack::object(v.slotsize, o.zone); } }; @@ -262,12 +389,13 @@ namespace msgpack { struct convert { msgpack::object const& operator()(msgpack::object const& o, cga_subskill_info_t& v) const { if (o.type != msgpack::type::ARRAY) throw msgpack::type_error(); - if (o.via.array.size != 5) throw msgpack::type_error(); + if (o.via.array.size != 6) throw msgpack::type_error(); v.name = o.via.array.ptr[0].as(); v.info = o.via.array.ptr[1].as(); v.cost = o.via.array.ptr[2].as(); v.flags = o.via.array.ptr[3].as(); v.level = o.via.array.ptr[4].as(); + v.available = o.via.array.ptr[5].as(); return o; } }; @@ -277,12 +405,13 @@ namespace msgpack { template packer& operator()(msgpack::packer& o, cga_subskill_info_t const& v) const { // packing member variables as an array. - o.pack_array(5); + o.pack_array(6); o.pack(v.name); o.pack(v.info); o.pack(v.cost); o.pack(v.flags); o.pack(v.level); + o.pack(v.available); return o; } }; @@ -291,13 +420,14 @@ namespace msgpack { struct object_with_zone { void operator()(msgpack::object::with_zone& o, cga_subskill_info_t const& v) const { o.type = type::ARRAY; - o.via.array.size = 5; + o.via.array.size = 6; o.via.array.ptr = static_cast(o.zone.allocate_align(sizeof(msgpack::object) * o.via.array.size)); o.via.array.ptr[0] = msgpack::object(v.name, o.zone); o.via.array.ptr[1] = msgpack::object(v.info, o.zone); o.via.array.ptr[2] = msgpack::object(v.cost, o.zone); o.via.array.ptr[3] = msgpack::object(v.flags, o.zone); o.via.array.ptr[4] = msgpack::object(v.level, o.zone); + o.via.array.ptr[5] = msgpack::object(v.available, o.zone); } }; @@ -370,7 +500,7 @@ namespace msgpack { struct convert { msgpack::object const& operator()(msgpack::object const& o, cga_battle_unit_t& v) const { if (o.type != msgpack::type::ARRAY) throw msgpack::type_error(); - if (o.via.array.size != 8) throw msgpack::type_error(); + if (o.via.array.size != 9) throw msgpack::type_error(); v.name = o.via.array.ptr[0].as(); v.modelid = o.via.array.ptr[1].as(); v.level = o.via.array.ptr[2].as(); @@ -378,7 +508,8 @@ namespace msgpack { v.maxhp = o.via.array.ptr[4].as(); v.curmp = o.via.array.ptr[5].as(); v.maxmp = o.via.array.ptr[6].as(); - v.pos = o.via.array.ptr[7].as(); + v.flags = o.via.array.ptr[7].as(); + v.pos = o.via.array.ptr[8].as(); return o; } }; @@ -388,7 +519,7 @@ namespace msgpack { template packer& operator()(msgpack::packer& o, cga_battle_unit_t const& v) const { // packing member variables as an array. - o.pack_array(8); + o.pack_array(9); o.pack(v.name); o.pack(v.modelid); o.pack(v.level); @@ -396,6 +527,7 @@ namespace msgpack { o.pack(v.maxhp); o.pack(v.curmp); o.pack(v.maxmp); + o.pack(v.flags); o.pack(v.pos); return o; } @@ -405,7 +537,7 @@ namespace msgpack { struct object_with_zone { void operator()(msgpack::object::with_zone& o, cga_battle_unit_t const& v) const { o.type = type::ARRAY; - o.via.array.size = 8; + o.via.array.size = 9; o.via.array.ptr = static_cast(o.zone.allocate_align(sizeof(msgpack::object) * o.via.array.size)); o.via.array.ptr[0] = msgpack::object(v.name, o.zone); o.via.array.ptr[1] = msgpack::object(v.modelid, o.zone); @@ -414,7 +546,8 @@ namespace msgpack { o.via.array.ptr[4] = msgpack::object(v.maxhp, o.zone); o.via.array.ptr[5] = msgpack::object(v.curmp, o.zone); o.via.array.ptr[6] = msgpack::object(v.maxmp, o.zone); - o.via.array.ptr[7] = msgpack::object(v.pos, o.zone); + o.via.array.ptr[7] = msgpack::object(v.flags, o.zone); + o.via.array.ptr[8] = msgpack::object(v.pos, o.zone); } }; @@ -565,7 +698,7 @@ namespace msgpack { struct convert { msgpack::object const& operator()(msgpack::object const& o, cga_map_unit_t& v) const { if (o.type != msgpack::type::ARRAY) throw msgpack::type_error(); - if (o.via.array.size != 10) throw msgpack::type_error(); + if (o.via.array.size != 14) throw msgpack::type_error(); v.valid = o.via.array.ptr[0].as(); v.type = o.via.array.ptr[1].as(); v.model_id = o.via.array.ptr[2].as(); @@ -573,9 +706,13 @@ namespace msgpack { v.xpos = o.via.array.ptr[4].as(); v.ypos = o.via.array.ptr[5].as(); v.item_count = o.via.array.ptr[6].as(); - v.unit_name = o.via.array.ptr[7].as(); - v.nick_name = o.via.array.ptr[8].as(); - v.item_name = o.via.array.ptr[9].as(); + v.injury = o.via.array.ptr[7].as(); + v.level = o.via.array.ptr[8].as(); + v.flags = o.via.array.ptr[9].as(); + v.unit_name = o.via.array.ptr[10].as(); + v.nick_name = o.via.array.ptr[11].as(); + v.title_name = o.via.array.ptr[12].as(); + v.item_name = o.via.array.ptr[13].as(); return o; } }; @@ -585,7 +722,7 @@ namespace msgpack { template packer& operator()(msgpack::packer& o, cga_map_unit_t const& v) const { // packing member variables as an array. - o.pack_array(10); + o.pack_array(14); o.pack(v.valid); o.pack(v.type); o.pack(v.model_id); @@ -593,8 +730,12 @@ namespace msgpack { o.pack(v.xpos); o.pack(v.ypos); o.pack(v.item_count); + o.pack(v.injury); + o.pack(v.level); + o.pack(v.flags); o.pack(v.unit_name); o.pack(v.nick_name); + o.pack(v.title_name); o.pack(v.item_name); return o; } @@ -604,7 +745,7 @@ namespace msgpack { struct object_with_zone { void operator()(msgpack::object::with_zone& o, cga_map_unit_t const& v) const { o.type = type::ARRAY; - o.via.array.size = 10; + o.via.array.size = 14; o.via.array.ptr = static_cast(o.zone.allocate_align(sizeof(msgpack::object) * o.via.array.size)); o.via.array.ptr[0] = msgpack::object(v.valid, o.zone); o.via.array.ptr[1] = msgpack::object(v.type, o.zone); @@ -613,9 +754,58 @@ namespace msgpack { o.via.array.ptr[4] = msgpack::object(v.xpos, o.zone); o.via.array.ptr[5] = msgpack::object(v.ypos, o.zone); o.via.array.ptr[6] = msgpack::object(v.item_count, o.zone); - o.via.array.ptr[7] = msgpack::object(v.unit_name, o.zone); - o.via.array.ptr[8] = msgpack::object(v.nick_name, o.zone); - o.via.array.ptr[9] = msgpack::object(v.item_name, o.zone); + o.via.array.ptr[7] = msgpack::object(v.injury, o.zone); + o.via.array.ptr[8] = msgpack::object(v.level, o.zone); + o.via.array.ptr[9] = msgpack::object(v.flags, o.zone); + o.via.array.ptr[10] = msgpack::object(v.unit_name, o.zone); + o.via.array.ptr[11] = msgpack::object(v.nick_name, o.zone); + o.via.array.ptr[12] = msgpack::object(v.title_name, o.zone); + o.via.array.ptr[13] = msgpack::object(v.item_name, o.zone); + } + }; + + //cga_map_cells_t + + template<> + struct convert { + msgpack::object const& operator()(msgpack::object const& o, cga_map_cells_t& v) const { + if (o.type != msgpack::type::ARRAY) throw msgpack::type_error(); + if (o.via.array.size != 5) throw msgpack::type_error(); + v.x_bottom = o.via.array.ptr[0].as(); + v.y_bottom = o.via.array.ptr[1].as(); + v.x_size = o.via.array.ptr[2].as(); + v.y_size = o.via.array.ptr[3].as(); + v.cell = o.via.array.ptr[4].as>(); + return o; + } + }; + + template<> + struct pack { + template + packer& operator()(msgpack::packer& o, cga_map_cells_t const& v) const { + // packing member variables as an array. + o.pack_array(5); + o.pack(v.x_bottom); + o.pack(v.y_bottom); + o.pack(v.x_size); + o.pack(v.y_size); + o.pack(v.cell); + return o; + } + }; + + template <> + struct object_with_zone { + void operator()(msgpack::object::with_zone& o, cga_map_cells_t const& v) const { + o.type = type::ARRAY; + o.via.array.size = 5; + o.via.array.ptr = static_cast(o.zone.allocate_align(sizeof(msgpack::object) * o.via.array.size)); + o.via.array.ptr[0] = msgpack::object(v.x_bottom, o.zone); + o.via.array.ptr[1] = msgpack::object(v.y_bottom, o.zone); + o.via.array.ptr[2] = msgpack::object(v.x_size, o.zone); + o.via.array.ptr[3] = msgpack::object(v.y_size, o.zone); + o.via.array.ptr[4] = msgpack::object(v.cell, o.zone); } }; @@ -700,11 +890,11 @@ namespace msgpack { struct convert { msgpack::object const& operator()(msgpack::object const& o, cga_craft_item_t& v) const { if (o.type != msgpack::type::ARRAY) throw msgpack::type_error(); - if (o.via.array.size != 8) throw msgpack::type_error(); + if (o.via.array.size != 9) throw msgpack::type_error(); v.skill_index = o.via.array.ptr[0].as(); v.subskill_index = o.via.array.ptr[1].as(); v.sub_type = o.via.array.ptr[2].as(); - for(int i = 0;i < 5; ++i) + for(int i = 0;i < 6; ++i) v.itempos[i] = o.via.array.ptr[3 + i].as(); return o; } @@ -715,11 +905,11 @@ namespace msgpack { template packer& operator()(msgpack::packer& o, cga_craft_item_t const& v) const { // packing member variables as an array. - o.pack_array(8); + o.pack_array(9); o.pack(v.skill_index); o.pack(v.subskill_index); o.pack(v.sub_type); - for (int i = 0; i < 5; ++i) + for (int i = 0; i < 6; ++i) o.pack(v.itempos[i]); return o; } @@ -729,12 +919,12 @@ namespace msgpack { struct object_with_zone { void operator()(msgpack::object::with_zone& o, cga_craft_item_t const& v) const { o.type = type::ARRAY; - o.via.array.size = 8; + o.via.array.size = 9; o.via.array.ptr = static_cast(o.zone.allocate_align(sizeof(msgpack::object) * o.via.array.size)); o.via.array.ptr[0] = msgpack::object(v.skill_index, o.zone); o.via.array.ptr[1] = msgpack::object(v.subskill_index, o.zone); o.via.array.ptr[2] = msgpack::object(v.sub_type, o.zone); - for (int i = 0; i < 5; ++i) + for (int i = 0; i < 6; ++i) o.via.array.ptr[3 + i] = msgpack::object(v.itempos[i], o.zone); } }; @@ -967,6 +1157,288 @@ namespace msgpack { } }; + //cga_trade_stuff_info_t + template<> + struct convert { + msgpack::object const& operator()(msgpack::object const& o, cga_trade_stuff_info_t& v) const { + if (o.type != msgpack::type::ARRAY) throw msgpack::type_error(); + if (o.via.array.size != 5) throw msgpack::type_error(); + v.items = o.via.array.ptr[0].as(); + v.pet = o.via.array.ptr[1].as(); + v.petskills = o.via.array.ptr[2].as(); + v.gold = o.via.array.ptr[3].as(); + v.type = o.via.array.ptr[4].as(); + return o; + } + }; + + template<> + struct pack { + template + packer& operator()(msgpack::packer& o, cga_trade_stuff_info_t const& v) const { + // packing member variables as an array. + o.pack_array(5); + o.pack(v.items); + o.pack(v.pet); + o.pack(v.petskills); + o.pack(v.gold); + o.pack(v.type); + return o; + } + }; + + template <> + struct object_with_zone { + void operator()(msgpack::object::with_zone& o, cga_trade_stuff_info_t const& v) const { + o.type = type::ARRAY; + o.via.array.size = 5; + o.via.array.ptr = static_cast(o.zone.allocate_align(sizeof(msgpack::object) * o.via.array.size)); + o.via.array.ptr[0] = msgpack::object(v.items, o.zone); + o.via.array.ptr[1] = msgpack::object(v.pet, o.zone); + o.via.array.ptr[2] = msgpack::object(v.petskills, o.zone); + o.via.array.ptr[3] = msgpack::object(v.gold, o.zone); + o.via.array.ptr[4] = msgpack::object(v.type, o.zone); + } + }; + + //cga_team_player_t + template<> + struct convert { + msgpack::object const& operator()(msgpack::object const& o, cga_team_player_t& v) const { + if (o.type != msgpack::type::ARRAY) throw msgpack::type_error(); + if (o.via.array.size != 5) throw msgpack::type_error(); + v.unit_id = o.via.array.ptr[0].as(); + v.hp = o.via.array.ptr[1].as(); + v.mp = o.via.array.ptr[2].as(); + v.maxhp = o.via.array.ptr[3].as(); + v.name = o.via.array.ptr[4].as(); + return o; + } + }; + + template<> + struct pack { + template + packer& operator()(msgpack::packer& o, cga_team_player_t const& v) const { + // packing member variables as an array. + o.pack_array(5); + o.pack(v.unit_id); + o.pack(v.hp); + o.pack(v.mp); + o.pack(v.maxhp); + o.pack(v.name); + return o; + } + }; + + template <> + struct object_with_zone { + void operator()(msgpack::object::with_zone& o, cga_team_player_t const& v) const { + o.type = type::ARRAY; + o.via.array.size = 5; + o.via.array.ptr = static_cast(o.zone.allocate_align(sizeof(msgpack::object) * o.via.array.size)); + o.via.array.ptr[0] = msgpack::object(v.unit_id, o.zone); + o.via.array.ptr[1] = msgpack::object(v.hp, o.zone); + o.via.array.ptr[2] = msgpack::object(v.mp, o.zone); + o.via.array.ptr[3] = msgpack::object(v.maxhp, o.zone); + o.via.array.ptr[4] = msgpack::object(v.name, o.zone); + } + }; + + //cga_trade_dialog_t + template<> + struct convert { + msgpack::object const& operator()(msgpack::object const& o, cga_trade_dialog_t& v) const { + if (o.type != msgpack::type::ARRAY) throw msgpack::type_error(); + if (o.via.array.size != 2) throw msgpack::type_error(); + v.name = o.via.array.ptr[0].as(); + v.level = o.via.array.ptr[1].as(); + return o; + } + }; + + template<> + struct pack { + template + packer& operator()(msgpack::packer& o, cga_trade_dialog_t const& v) const { + // packing member variables as an array. + o.pack_array(2); + o.pack(v.name); + o.pack(v.level); + return o; + } + }; + + template <> + struct object_with_zone { + void operator()(msgpack::object::with_zone& o, cga_trade_dialog_t const& v) const { + o.type = type::ARRAY; + o.via.array.size = 2; + o.via.array.ptr = static_cast(o.zone.allocate_align(sizeof(msgpack::object) * o.via.array.size)); + o.via.array.ptr[0] = msgpack::object(v.name, o.zone); + o.via.array.ptr[1] = msgpack::object(v.level, o.zone); + } + }; + + //cga_battle_context_t + template<> + struct convert { + msgpack::object const& operator()(msgpack::object const& o, cga_battle_context_t& v) const { + if (o.type != msgpack::type::ARRAY) throw msgpack::type_error(); + if (o.via.array.size != 9) throw msgpack::type_error(); + v.round_count = o.via.array.ptr[0].as(); + v.player_pos = o.via.array.ptr[1].as(); + v.player_status = o.via.array.ptr[2].as(); + v.skill_performed = o.via.array.ptr[3].as(); + v.skill_allowbit = o.via.array.ptr[4].as(); + v.petskill_allowbit = o.via.array.ptr[5].as(); + v.weapon_allowbit = o.via.array.ptr[6].as(); + v.petid = o.via.array.ptr[7].as(); + v.effect_flags = o.via.array.ptr[8].as(); + return o; + } + }; + + template<> + struct pack { + template + packer& operator()(msgpack::packer& o, cga_battle_context_t const& v) const { + // packing member variables as an array. + o.pack_array(9); + o.pack(v.round_count); + o.pack(v.player_pos); + o.pack(v.player_status); + o.pack(v.skill_performed); + o.pack(v.skill_allowbit); + o.pack(v.petskill_allowbit); + o.pack(v.weapon_allowbit); + o.pack(v.petid); + o.pack(v.effect_flags); + return o; + } + }; + + template <> + struct object_with_zone { + void operator()(msgpack::object::with_zone& o, cga_battle_context_t const& v) const { + o.type = type::ARRAY; + o.via.array.size = 8; + o.via.array.ptr = static_cast(o.zone.allocate_align(sizeof(msgpack::object) * o.via.array.size)); + o.via.array.ptr[0] = msgpack::object(v.round_count, o.zone); + o.via.array.ptr[1] = msgpack::object(v.player_pos, o.zone); + o.via.array.ptr[2] = msgpack::object(v.player_status, o.zone); + o.via.array.ptr[3] = msgpack::object(v.skill_performed, o.zone); + o.via.array.ptr[4] = msgpack::object(v.skill_allowbit, o.zone); + o.via.array.ptr[5] = msgpack::object(v.petskill_allowbit, o.zone); + o.via.array.ptr[6] = msgpack::object(v.weapon_allowbit, o.zone); + o.via.array.ptr[7] = msgpack::object(v.petid, o.zone); + o.via.array.ptr[8] = msgpack::object(v.effect_flags, o.zone); + } + }; + + //cga_playerpet_detail_info_t + template<> + struct convert { + msgpack::object const& operator()(msgpack::object const& o, cga_playerpet_detail_info_t& v) const { + if (o.type != msgpack::type::ARRAY) throw msgpack::type_error(); + if (o.via.array.size != 25) throw msgpack::type_error(); + v.points_remain = o.via.array.ptr[0].as(); + v.points_endurance = o.via.array.ptr[1].as(); + v.points_strength = o.via.array.ptr[2].as(); + v.points_defense = o.via.array.ptr[3].as(); + v.points_agility = o.via.array.ptr[4].as(); + v.points_magical = o.via.array.ptr[5].as(); + v.value_attack = o.via.array.ptr[6].as(); + v.value_defensive = o.via.array.ptr[7].as(); + v.value_agility = o.via.array.ptr[8].as(); + v.value_spirit = o.via.array.ptr[9].as(); + v.value_recovery = o.via.array.ptr[10].as(); + v.resist_poison = o.via.array.ptr[11].as(); + v.resist_sleep = o.via.array.ptr[12].as(); + v.resist_medusa = o.via.array.ptr[13].as(); + v.resist_drunk = o.via.array.ptr[14].as(); + v.resist_chaos = o.via.array.ptr[15].as(); + v.resist_forget = o.via.array.ptr[16].as(); + v.fix_critical = o.via.array.ptr[17].as(); + v.fix_strikeback = o.via.array.ptr[18].as(); + v.fix_accurancy = o.via.array.ptr[19].as(); + v.fix_dodge = o.via.array.ptr[20].as(); + v.element_earth = o.via.array.ptr[21].as(); + v.element_water = o.via.array.ptr[22].as(); + v.element_fire = o.via.array.ptr[23].as(); + v.element_wind = o.via.array.ptr[24].as(); + return o; + } + }; + + template<> + struct pack { + template + packer& operator()(msgpack::packer& o, cga_playerpet_detail_info_t const& v) const { + // packing member variables as an array. + o.pack_array(25); + o.pack(v.points_remain); + o.pack(v.points_endurance); + o.pack(v.points_strength); + o.pack(v.points_defense); + o.pack(v.points_agility); + o.pack(v.points_magical); + o.pack(v.value_attack); + o.pack(v.value_defensive); + o.pack(v.value_agility); + o.pack(v.value_spirit); + o.pack(v.value_recovery); + o.pack(v.resist_poison); + o.pack(v.resist_sleep); + o.pack(v.resist_medusa); + o.pack(v.resist_drunk); + o.pack(v.resist_chaos); + o.pack(v.resist_forget); + o.pack(v.fix_critical); + o.pack(v.fix_strikeback); + o.pack(v.fix_accurancy); + o.pack(v.fix_dodge); + o.pack(v.element_earth); + o.pack(v.element_water); + o.pack(v.element_fire); + o.pack(v.element_wind); + return o; + } + }; + + template <> + struct object_with_zone { + void operator()(msgpack::object::with_zone& o, cga_playerpet_detail_info_t const& v) const { + o.type = type::ARRAY; + o.via.array.size = 25; + o.via.array.ptr = static_cast(o.zone.allocate_align(sizeof(msgpack::object) * o.via.array.size)); + o.via.array.ptr[0] = msgpack::object(v.points_remain, o.zone); + o.via.array.ptr[1] = msgpack::object(v.points_endurance, o.zone); + o.via.array.ptr[2] = msgpack::object(v.points_strength, o.zone); + o.via.array.ptr[3] = msgpack::object(v.points_defense, o.zone); + o.via.array.ptr[4] = msgpack::object(v.points_agility, o.zone); + o.via.array.ptr[5] = msgpack::object(v.points_magical, o.zone); + o.via.array.ptr[6] = msgpack::object(v.value_attack, o.zone); + o.via.array.ptr[7] = msgpack::object(v.value_defensive, o.zone); + o.via.array.ptr[8] = msgpack::object(v.value_agility, o.zone); + o.via.array.ptr[9] = msgpack::object(v.value_spirit, o.zone); + o.via.array.ptr[10] = msgpack::object(v.value_recovery, o.zone); + o.via.array.ptr[11] = msgpack::object(v.resist_poison, o.zone); + o.via.array.ptr[12] = msgpack::object(v.resist_sleep, o.zone); + o.via.array.ptr[13] = msgpack::object(v.resist_medusa, o.zone); + o.via.array.ptr[14] = msgpack::object(v.resist_drunk, o.zone); + o.via.array.ptr[15] = msgpack::object(v.resist_chaos, o.zone); + o.via.array.ptr[16] = msgpack::object(v.resist_forget, o.zone); + o.via.array.ptr[17] = msgpack::object(v.fix_critical, o.zone); + o.via.array.ptr[18] = msgpack::object(v.fix_strikeback, o.zone); + o.via.array.ptr[19] = msgpack::object(v.fix_accurancy, o.zone); + o.via.array.ptr[20] = msgpack::object(v.fix_dodge, o.zone); + o.via.array.ptr[21] = msgpack::object(v.element_earth, o.zone); + o.via.array.ptr[22] = msgpack::object(v.element_water, o.zone); + o.via.array.ptr[23] = msgpack::object(v.element_fire, o.zone); + o.via.array.ptr[24] = msgpack::object(v.element_wind, o.zone); + } + }; } // namespace adaptor } // MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS) } // namespace msgpack \ No newline at end of file diff --git a/CGANode/async.h b/CGANode/async.h index 8989015..a0cd322 100644 --- a/CGANode/async.h +++ b/CGANode/async.h @@ -6,12 +6,18 @@ class CBaseNotifyData CBaseNotifyData(const uv_async_cb async_cb) { m_result = false; - uv_timer_init(uv_default_loop(), &m_timer); - uv_async_init(uv_default_loop(), &m_async, async_cb); + m_async = new uv_async_t; + m_timer = new uv_timer_t; + uv_timer_init(uv_default_loop(), m_timer); + uv_async_init(uv_default_loop(), m_async, async_cb); } bool m_result; Persistent m_callback; - uv_async_t m_async; - uv_timer_t m_timer; -}; \ No newline at end of file + uv_async_t *m_async; + uv_timer_t *m_timer; +}; + +void FreeUVHandleCallBack(uv_handle_t *handle); + +#define CGA_NOTIFY_MAX_CACHE_TIME 3000 \ No newline at end of file diff --git a/CGANode/binding.gyp b/CGANode/binding.gyp index 770eca6..68713f3 100644 --- a/CGANode/binding.gyp +++ b/CGANode/binding.gyp @@ -2,7 +2,7 @@ "targets": [ { "target_name": "node_cga", - "sources": [ "main.cc", "connect.cc", "item.cc", "info.cc", "map.cc", "npc.cc", "work.cc", "chat.cc" ], + "sources": [ "main.cc", "connect.cc", "item.cc", "info.cc", "map.cc", "npc.cc", "work.cc", "chat.cc", "battle.cc" ], "include_dirs": [ " g_ChatMsg_Asyncs; -/* -static bool is_removable(ChatMsgNotifyData *data) +class ChatMsgCacheData { - return (data->m_sent && !data->m_permanent); -} -*/ -void ChatMsgNotify(CGA::cga_chat_msg_t msg) +public: + ChatMsgCacheData(const CGA::cga_chat_msg_t &msg, uint64_t time) : m_msg(msg), m_time(time) + { + + } + CGA::cga_chat_msg_t m_msg; + uint64_t m_time; +}; + +boost::shared_mutex g_ChatMsg_Lock; +std::vector g_ChatMsg_Asyncs; +std::vector g_ChatMsg_Caches; + +void ChatMsgDoAsyncCall(const CGA::cga_chat_msg_t &msg) { - boost::unique_lock lock(g_ChatMsg_Lock); - for (size_t i = 0; i < g_ChatMsg_Asyncs.size(); ++i) + if (g_ChatMsg_Asyncs.size()) { - const auto data = g_ChatMsg_Asyncs[i]; - //if (!data->m_sent) - //{ + for (size_t i = 0; i < g_ChatMsg_Asyncs.size(); ++i) + { + const auto data = g_ChatMsg_Asyncs[i]; + data->m_msg = msg; data->m_result = true; - //data->m_sent = true; - uv_async_send(&data->m_async); - //} + uv_async_send(data->m_async); + } + g_ChatMsg_Asyncs.clear(); + } + else + { + auto hrtime = uv_hrtime(); + for (auto &p = g_ChatMsg_Caches.begin(); p != g_ChatMsg_Caches.end(); ) + { + if (hrtime - (*p)->m_time > CGA_NOTIFY_MAX_CACHE_TIME) + { + delete *p; + p = g_ChatMsg_Caches.erase(p); + } + else + { + p++; + } + } + g_ChatMsg_Caches.emplace_back(new ChatMsgCacheData(msg, uv_hrtime())); } - g_ChatMsg_Asyncs.clear(); - //g_ChatMsg_Asyncs.erase(std::remove_if(std::begin(g_ChatMsg_Asyncs), std::end(g_ChatMsg_Asyncs), is_removable), std::end(g_ChatMsg_Asyncs)); +} + +void ChatMsgNotify(CGA::cga_chat_msg_t msg) +{ + boost::unique_lock lock(g_ChatMsg_Lock); + ChatMsgDoAsyncCall(msg); } void ChatMsgAsyncCallBack(uv_async_t *handle) @@ -76,19 +99,13 @@ void ChatMsgAsyncCallBack(uv_async_t *handle) } Local::New(isolate, data->m_callback)->Call(isolate->GetCurrentContext()->Global(), 1, argv); - //if (!data->m_permanent) - //{ - data->m_callback.Reset(); - uv_timer_stop(&data->m_timer); - uv_close((uv_handle_t*)handle, NULL); - uv_close((uv_handle_t*)&data->m_timer, NULL); - delete handle->data; - /*} - else - { - data->m_sent = false; - }*/ + data->m_callback.Reset(); + + uv_timer_stop(data->m_timer); + uv_close((uv_handle_t*)handle, FreeUVHandleCallBack); + uv_close((uv_handle_t*)data->m_timer, FreeUVHandleCallBack); + delete handle->data; } void ChatMsgTimerCallBack(uv_timer_t *handle) @@ -98,39 +115,35 @@ void ChatMsgTimerCallBack(uv_timer_t *handle) auto data = (ChatMsgNotifyData *)handle->data; - Handle argv[1]; - argv[0] = Nan::TypeError("Async callback timeout."); - - Local::New(isolate, data->m_callback)->Call(isolate->GetCurrentContext()->Global(), 1, argv); - //if (!data->m_permanent) - //{ - data->m_callback.Reset(); + bool asyncNotCalled = false; + { + boost::unique_lock lock(g_ChatMsg_Lock); + for (size_t i = 0; i < g_ChatMsg_Asyncs.size(); ++i) { - boost::unique_lock lock(g_ChatMsg_Lock); - for (size_t i = 0; i < g_ChatMsg_Asyncs.size(); ++i) + if (g_ChatMsg_Asyncs[i] == data) { - if (g_ChatMsg_Asyncs[i] == data) - { - g_ChatMsg_Asyncs.erase(g_ChatMsg_Asyncs.begin() + i); - break; - } + asyncNotCalled = true; + g_ChatMsg_Asyncs.erase(g_ChatMsg_Asyncs.begin() + i); + break; } } + } + + if (asyncNotCalled) + { + Handle argv[1]; + argv[0] = Nan::TypeError("Async callback timeout."); + + Local::New(isolate, data->m_callback)->Call(isolate->GetCurrentContext()->Global(), 1, argv); + + data->m_callback.Reset(); uv_timer_stop(handle); - uv_close((uv_handle_t*)&data->m_async, NULL); - uv_close((uv_handle_t*)handle, NULL); + uv_close((uv_handle_t*)data->m_async, FreeUVHandleCallBack); + uv_close((uv_handle_t*)handle, FreeUVHandleCallBack); delete handle->data; - /*} - else - { - if (data->m_timeout > 0) - { - uv_timer_start(&data->m_timer, ChatMsgTimerCallBack, data->m_timeout, 0); - data->m_sent = false; - } - }*/ + } } void AsyncWaitChatMsg(const Nan::FunctionCallbackInfo& info) @@ -149,23 +162,35 @@ void AsyncWaitChatMsg(const Nan::FunctionCallbackInfo& info) if (timeout < 0) timeout = 0; } - /*bool permanent = false; - if (info.Length() >= 3 && info[2]->IsBoolean()) - { - permanent = info[2]->BooleanValue(); - }*/ auto callback = Local::Cast(info[0]); ChatMsgNotifyData *data = new ChatMsgNotifyData(); data->m_callback.Reset(isolate, callback); - data->m_async.data = data; - data->m_timer.data = data; - //data->m_timeout = timeout; - //data->m_permanent = permanent; + data->m_async->data = data; + data->m_timer->data = data; - boost::unique_lock lock(g_ChatMsg_Lock); - g_ChatMsg_Asyncs.push_back(data); + { + boost::unique_lock lock(g_ChatMsg_Lock); + g_ChatMsg_Asyncs.push_back(data); + + auto hrtime = uv_hrtime(); + for (auto &p = g_ChatMsg_Caches.begin(); p != g_ChatMsg_Caches.end(); ) + { + if (hrtime - (*p)->m_time > CGA_NOTIFY_MAX_CACHE_TIME) + { + delete *p; + p = g_ChatMsg_Caches.erase(p); + } + else + { + ChatMsgDoAsyncCall((*p)->m_msg); + delete *p; + g_ChatMsg_Caches.erase(p); + break; + } + } + } if(timeout) - uv_timer_start(&data->m_timer, ChatMsgTimerCallBack, timeout, 0); + uv_timer_start(data->m_timer, ChatMsgTimerCallBack, timeout, 0); } \ No newline at end of file diff --git a/CGANode/connect.cc b/CGANode/connect.cc index 207bf78..ef6f541 100644 --- a/CGANode/connect.cc +++ b/CGANode/connect.cc @@ -5,6 +5,10 @@ using namespace v8; extern CGA::CGAInterface *g_CGAInterface; +void BattleActionNotify(int flags); +void TradeStateNotify(int state); +void TradeDialogNotify(CGA::cga_trade_dialog_t info); +void TradeStuffsNotify(CGA::cga_trade_stuff_info_t info); void PlayerMenuNotify(CGA::cga_player_menu_items_t players); void UnitMenuNotify(CGA::cga_unit_menu_items_t units); void NPCDialogNotify(CGA::cga_npc_dialog_t dlg); @@ -34,6 +38,10 @@ void ConnectWorker(uv_work_t* req) if (data->m_result) { + g_CGAInterface->RegisterBattleActionNotify(std::bind(&BattleActionNotify, std::placeholders::_1)); + g_CGAInterface->RegisterTradeStateNotify(std::bind(&TradeStateNotify, std::placeholders::_1)); + g_CGAInterface->RegisterTradeDialogNotify(std::bind(&TradeDialogNotify, std::placeholders::_1)); + g_CGAInterface->RegisterTradeStuffsNotify(std::bind(&TradeStuffsNotify, std::placeholders::_1)); g_CGAInterface->RegisterPlayerMenuNotify(std::bind(&PlayerMenuNotify, std::placeholders::_1)); g_CGAInterface->RegisterUnitMenuNotify(std::bind(&UnitMenuNotify, std::placeholders::_1)); g_CGAInterface->RegisterNPCDialogNotify(std::bind(&NPCDialogNotify, std::placeholders::_1)); diff --git a/CGANode/info.cc b/CGANode/info.cc index 2c5f3a2..73d9254 100644 --- a/CGANode/info.cc +++ b/CGANode/info.cc @@ -71,6 +71,7 @@ void GetPlayerInfo(const Nan::FunctionCallbackInfo& info) obj->Set(String::NewFromUtf8(isolate, "maxxp"), Integer::New(isolate, myinfo.maxxp)); obj->Set(String::NewFromUtf8(isolate, "level"), Integer::New(isolate, myinfo.level)); obj->Set(String::NewFromUtf8(isolate, "health"), Integer::New(isolate, myinfo.health)); + obj->Set(String::NewFromUtf8(isolate, "souls"), Integer::New(isolate, myinfo.souls)); obj->Set(String::NewFromUtf8(isolate, "gold"), Integer::New(isolate, myinfo.gold)); obj->Set(String::NewFromUtf8(isolate, "unitid"), Integer::New(isolate, myinfo.unitid)); obj->Set(String::NewFromUtf8(isolate, "petid"), Integer::New(isolate, myinfo.petid)); @@ -78,6 +79,46 @@ void GetPlayerInfo(const Nan::FunctionCallbackInfo& info) obj->Set(String::NewFromUtf8(isolate, "usingpunchclock"), Boolean::New(isolate, myinfo.usingpunchclock)); obj->Set(String::NewFromUtf8(isolate, "name"), Nan::New(myinfo.name).ToLocalChecked()); obj->Set(String::NewFromUtf8(isolate, "job"), Nan::New(myinfo.job).ToLocalChecked()); + Local arr = Array::New(isolate); + for (size_t i = 0; i < myinfo.titles.size(); ++i) + { + arr->Set(i, Nan::New(myinfo.titles[i]).ToLocalChecked()); + } + obj->Set(String::NewFromUtf8(isolate, "titles"), arr); + + Local objd = Object::New(isolate); + objd->Set(String::NewFromUtf8(isolate, "points_remain"), Integer::New(isolate, myinfo.detail.points_remain)); + objd->Set(String::NewFromUtf8(isolate, "points_endurance"), Integer::New(isolate, myinfo.detail.points_endurance)); + objd->Set(String::NewFromUtf8(isolate, "points_strength"), Integer::New(isolate, myinfo.detail.points_strength)); + objd->Set(String::NewFromUtf8(isolate, "points_defense"), Integer::New(isolate, myinfo.detail.points_defense)); + objd->Set(String::NewFromUtf8(isolate, "points_agility"), Integer::New(isolate, myinfo.detail.points_agility)); + objd->Set(String::NewFromUtf8(isolate, "points_magical"), Integer::New(isolate, myinfo.detail.points_magical)); + objd->Set(String::NewFromUtf8(isolate, "value_attack"), Integer::New(isolate, myinfo.detail.value_attack)); + objd->Set(String::NewFromUtf8(isolate, "value_defensive"), Integer::New(isolate, myinfo.detail.value_defensive)); + objd->Set(String::NewFromUtf8(isolate, "value_agility"), Integer::New(isolate, myinfo.detail.value_agility)); + objd->Set(String::NewFromUtf8(isolate, "value_spirit"), Integer::New(isolate, myinfo.detail.value_spirit)); + objd->Set(String::NewFromUtf8(isolate, "value_recovery"), Integer::New(isolate, myinfo.detail.value_recovery)); + objd->Set(String::NewFromUtf8(isolate, "resist_poison"), Integer::New(isolate, myinfo.detail.resist_poison)); + objd->Set(String::NewFromUtf8(isolate, "resist_sleep"), Integer::New(isolate, myinfo.detail.resist_sleep)); + objd->Set(String::NewFromUtf8(isolate, "resist_medusa"), Integer::New(isolate, myinfo.detail.resist_medusa)); + objd->Set(String::NewFromUtf8(isolate, "resist_drunk"), Integer::New(isolate, myinfo.detail.resist_drunk)); + objd->Set(String::NewFromUtf8(isolate, "resist_chaos"), Integer::New(isolate, myinfo.detail.resist_chaos)); + objd->Set(String::NewFromUtf8(isolate, "resist_forget"), Integer::New(isolate, myinfo.detail.resist_forget)); + objd->Set(String::NewFromUtf8(isolate, "fix_critical"), Integer::New(isolate, myinfo.detail.fix_critical)); + objd->Set(String::NewFromUtf8(isolate, "fix_strikeback"), Integer::New(isolate, myinfo.detail.fix_strikeback)); + objd->Set(String::NewFromUtf8(isolate, "fix_accurancy"), Integer::New(isolate, myinfo.detail.fix_accurancy)); + objd->Set(String::NewFromUtf8(isolate, "fix_dodge"), Integer::New(isolate, myinfo.detail.fix_dodge)); + objd->Set(String::NewFromUtf8(isolate, "element_earth"), Integer::New(isolate, myinfo.detail.element_earth)); + objd->Set(String::NewFromUtf8(isolate, "element_water"), Integer::New(isolate, myinfo.detail.element_water)); + objd->Set(String::NewFromUtf8(isolate, "element_fire"), Integer::New(isolate, myinfo.detail.element_fire)); + objd->Set(String::NewFromUtf8(isolate, "element_wind"), Integer::New(isolate, myinfo.detail.element_wind)); + + objd->Set(String::NewFromUtf8(isolate, "manu_endurance"), Integer::New(isolate, myinfo.manu_endurance)); + objd->Set(String::NewFromUtf8(isolate, "manu_skillful"), Integer::New(isolate, myinfo.manu_skillful)); + objd->Set(String::NewFromUtf8(isolate, "manu_intelligence"), Integer::New(isolate, myinfo.manu_intelligence)); + + obj->Set(String::NewFromUtf8(isolate, "detail"), objd); + info.GetReturnValue().Set(obj); } @@ -182,6 +223,7 @@ void GetSkillInfo(const Nan::FunctionCallbackInfo& info) obj->Set(String::NewFromUtf8(isolate, "type"), Integer::New(isolate, myinfo.type)); obj->Set(String::NewFromUtf8(isolate, "pos"), Integer::New(isolate, myinfo.pos)); obj->Set(String::NewFromUtf8(isolate, "index"), Integer::New(isolate, myinfo.index)); + obj->Set(String::NewFromUtf8(isolate, "slotsize"), Integer::New(isolate, myinfo.slotsize)); info.GetReturnValue().Set(obj); } @@ -211,6 +253,7 @@ void GetSkillsInfo(const Nan::FunctionCallbackInfo& info) obj->Set(String::NewFromUtf8(isolate, "type"), Integer::New(isolate, myinfo.type)); obj->Set(String::NewFromUtf8(isolate, "pos"), Integer::New(isolate, myinfo.pos)); obj->Set(String::NewFromUtf8(isolate, "index"), Integer::New(isolate, myinfo.index)); + obj->Set(String::NewFromUtf8(isolate, "slotsize"), Integer::New(isolate, myinfo.slotsize)); arr->Set(i, obj); } info.GetReturnValue().Set(arr); @@ -351,6 +394,7 @@ void GetSubSkillInfo(const Nan::FunctionCallbackInfo& info) obj->Set(String::NewFromUtf8(isolate, "level"), Integer::New(isolate, myinfo.level)); obj->Set(String::NewFromUtf8(isolate, "cost"), Integer::New(isolate, myinfo.cost)); obj->Set(String::NewFromUtf8(isolate, "flags"), Integer::New(isolate, myinfo.flags)); + obj->Set(String::NewFromUtf8(isolate, "available"), Boolean::New(isolate, myinfo.available)); info.GetReturnValue().Set(obj); } @@ -382,6 +426,7 @@ void GetSubSkillsInfo(const Nan::FunctionCallbackInfo& info) obj->Set(String::NewFromUtf8(isolate, "level"), Integer::New(isolate, myinfo.level)); obj->Set(String::NewFromUtf8(isolate, "cost"), Integer::New(isolate, myinfo.cost)); obj->Set(String::NewFromUtf8(isolate, "flags"), Integer::New(isolate, myinfo.flags)); + obj->Set(String::NewFromUtf8(isolate, "available"), Boolean::New(isolate, myinfo.available)); arr->Set(i, obj); } info.GetReturnValue().Set(arr); @@ -550,6 +595,7 @@ void GetPetInfo(const Nan::FunctionCallbackInfo& info) obj->Set(String::NewFromUtf8(isolate, "realname"), Nan::New(myinfo.realname).ToLocalChecked()); obj->Set(String::NewFromUtf8(isolate, "level"), Integer::New(isolate, myinfo.level)); obj->Set(String::NewFromUtf8(isolate, "race"), Integer::New(isolate, myinfo.race)); + obj->Set(String::NewFromUtf8(isolate, "loyality"), Integer::New(isolate, myinfo.loyality)); obj->Set(String::NewFromUtf8(isolate, "health"), Integer::New(isolate, myinfo.health)); obj->Set(String::NewFromUtf8(isolate, "hp"), Integer::New(isolate, myinfo.hp)); obj->Set(String::NewFromUtf8(isolate, "maxhp"), Integer::New(isolate, myinfo.maxhp)); @@ -559,6 +605,36 @@ void GetPetInfo(const Nan::FunctionCallbackInfo& info) obj->Set(String::NewFromUtf8(isolate, "maxxp"), Integer::New(isolate, myinfo.maxxp)); obj->Set(String::NewFromUtf8(isolate, "flags"), Integer::New(isolate, myinfo.flags)); obj->Set(String::NewFromUtf8(isolate, "battle_flags"), Integer::New(isolate, myinfo.battle_flags)); + obj->Set(String::NewFromUtf8(isolate, "index"), Integer::New(isolate, myinfo.index)); + + Local objd = Object::New(isolate); + objd->Set(String::NewFromUtf8(isolate, "points_remain"), Integer::New(isolate, myinfo.detail.points_remain)); + objd->Set(String::NewFromUtf8(isolate, "points_endurance"), Integer::New(isolate, myinfo.detail.points_endurance)); + objd->Set(String::NewFromUtf8(isolate, "points_strength"), Integer::New(isolate, myinfo.detail.points_strength)); + objd->Set(String::NewFromUtf8(isolate, "points_defense"), Integer::New(isolate, myinfo.detail.points_defense)); + objd->Set(String::NewFromUtf8(isolate, "points_agility"), Integer::New(isolate, myinfo.detail.points_agility)); + objd->Set(String::NewFromUtf8(isolate, "points_magical"), Integer::New(isolate, myinfo.detail.points_magical)); + objd->Set(String::NewFromUtf8(isolate, "value_attack"), Integer::New(isolate, myinfo.detail.value_attack)); + objd->Set(String::NewFromUtf8(isolate, "value_defensive"), Integer::New(isolate, myinfo.detail.value_defensive)); + objd->Set(String::NewFromUtf8(isolate, "value_agility"), Integer::New(isolate, myinfo.detail.value_agility)); + objd->Set(String::NewFromUtf8(isolate, "value_spirit"), Integer::New(isolate, myinfo.detail.value_spirit)); + objd->Set(String::NewFromUtf8(isolate, "value_recovery"), Integer::New(isolate, myinfo.detail.value_recovery)); + objd->Set(String::NewFromUtf8(isolate, "resist_poison"), Integer::New(isolate, myinfo.detail.resist_poison)); + objd->Set(String::NewFromUtf8(isolate, "resist_sleep"), Integer::New(isolate, myinfo.detail.resist_sleep)); + objd->Set(String::NewFromUtf8(isolate, "resist_medusa"), Integer::New(isolate, myinfo.detail.resist_medusa)); + objd->Set(String::NewFromUtf8(isolate, "resist_drunk"), Integer::New(isolate, myinfo.detail.resist_drunk)); + objd->Set(String::NewFromUtf8(isolate, "resist_chaos"), Integer::New(isolate, myinfo.detail.resist_chaos)); + objd->Set(String::NewFromUtf8(isolate, "resist_forget"), Integer::New(isolate, myinfo.detail.resist_forget)); + objd->Set(String::NewFromUtf8(isolate, "fix_critical"), Integer::New(isolate, myinfo.detail.fix_critical)); + objd->Set(String::NewFromUtf8(isolate, "fix_strikeback"), Integer::New(isolate, myinfo.detail.fix_strikeback)); + objd->Set(String::NewFromUtf8(isolate, "fix_accurancy"), Integer::New(isolate, myinfo.detail.fix_accurancy)); + objd->Set(String::NewFromUtf8(isolate, "fix_dodge"), Integer::New(isolate, myinfo.detail.fix_dodge)); + objd->Set(String::NewFromUtf8(isolate, "element_earth"), Integer::New(isolate, myinfo.detail.element_earth)); + objd->Set(String::NewFromUtf8(isolate, "element_water"), Integer::New(isolate, myinfo.detail.element_water)); + objd->Set(String::NewFromUtf8(isolate, "element_fire"), Integer::New(isolate, myinfo.detail.element_fire)); + objd->Set(String::NewFromUtf8(isolate, "element_wind"), Integer::New(isolate, myinfo.detail.element_wind)); + obj->Set(String::NewFromUtf8(isolate, "detail"), objd); + info.GetReturnValue().Set(obj); } @@ -567,11 +643,6 @@ void GetPetsInfo(const Nan::FunctionCallbackInfo& info) Isolate* isolate = info.GetIsolate(); HandleScope handle_scope(isolate); - if (info.Length() < 1) { - Nan::ThrowTypeError("Arg[0] must be petid."); - return; - } - CGA::cga_pets_info_t myinfos; if (!g_CGAInterface->GetPetsInfo(myinfos)) { @@ -587,6 +658,7 @@ void GetPetsInfo(const Nan::FunctionCallbackInfo& info) obj->Set(String::NewFromUtf8(isolate, "realname"), Nan::New(myinfo.realname).ToLocalChecked()); obj->Set(String::NewFromUtf8(isolate, "level"), Integer::New(isolate, myinfo.level)); obj->Set(String::NewFromUtf8(isolate, "race"), Integer::New(isolate, myinfo.race)); + obj->Set(String::NewFromUtf8(isolate, "loyality"), Integer::New(isolate, myinfo.loyality)); obj->Set(String::NewFromUtf8(isolate, "health"), Integer::New(isolate, myinfo.health)); obj->Set(String::NewFromUtf8(isolate, "hp"), Integer::New(isolate, myinfo.hp)); obj->Set(String::NewFromUtf8(isolate, "maxhp"), Integer::New(isolate, myinfo.maxhp)); @@ -596,6 +668,36 @@ void GetPetsInfo(const Nan::FunctionCallbackInfo& info) obj->Set(String::NewFromUtf8(isolate, "maxxp"), Integer::New(isolate, myinfo.maxxp)); obj->Set(String::NewFromUtf8(isolate, "flags"), Integer::New(isolate, myinfo.flags)); obj->Set(String::NewFromUtf8(isolate, "battle_flags"), Integer::New(isolate, myinfo.battle_flags)); + obj->Set(String::NewFromUtf8(isolate, "index"), Integer::New(isolate, myinfo.index)); + + Local objd = Object::New(isolate); + objd->Set(String::NewFromUtf8(isolate, "points_remain"), Integer::New(isolate, myinfo.detail.points_remain)); + objd->Set(String::NewFromUtf8(isolate, "points_endurance"), Integer::New(isolate, myinfo.detail.points_endurance)); + objd->Set(String::NewFromUtf8(isolate, "points_strength"), Integer::New(isolate, myinfo.detail.points_strength)); + objd->Set(String::NewFromUtf8(isolate, "points_defense"), Integer::New(isolate, myinfo.detail.points_defense)); + objd->Set(String::NewFromUtf8(isolate, "points_agility"), Integer::New(isolate, myinfo.detail.points_agility)); + objd->Set(String::NewFromUtf8(isolate, "points_magical"), Integer::New(isolate, myinfo.detail.points_magical)); + objd->Set(String::NewFromUtf8(isolate, "value_attack"), Integer::New(isolate, myinfo.detail.value_attack)); + objd->Set(String::NewFromUtf8(isolate, "value_defensive"), Integer::New(isolate, myinfo.detail.value_defensive)); + objd->Set(String::NewFromUtf8(isolate, "value_agility"), Integer::New(isolate, myinfo.detail.value_agility)); + objd->Set(String::NewFromUtf8(isolate, "value_spirit"), Integer::New(isolate, myinfo.detail.value_spirit)); + objd->Set(String::NewFromUtf8(isolate, "value_recovery"), Integer::New(isolate, myinfo.detail.value_recovery)); + objd->Set(String::NewFromUtf8(isolate, "resist_poison"), Integer::New(isolate, myinfo.detail.resist_poison)); + objd->Set(String::NewFromUtf8(isolate, "resist_sleep"), Integer::New(isolate, myinfo.detail.resist_sleep)); + objd->Set(String::NewFromUtf8(isolate, "resist_medusa"), Integer::New(isolate, myinfo.detail.resist_medusa)); + objd->Set(String::NewFromUtf8(isolate, "resist_drunk"), Integer::New(isolate, myinfo.detail.resist_drunk)); + objd->Set(String::NewFromUtf8(isolate, "resist_chaos"), Integer::New(isolate, myinfo.detail.resist_chaos)); + objd->Set(String::NewFromUtf8(isolate, "resist_forget"), Integer::New(isolate, myinfo.detail.resist_forget)); + objd->Set(String::NewFromUtf8(isolate, "fix_critical"), Integer::New(isolate, myinfo.detail.fix_critical)); + objd->Set(String::NewFromUtf8(isolate, "fix_strikeback"), Integer::New(isolate, myinfo.detail.fix_strikeback)); + objd->Set(String::NewFromUtf8(isolate, "fix_accurancy"), Integer::New(isolate, myinfo.detail.fix_accurancy)); + objd->Set(String::NewFromUtf8(isolate, "fix_dodge"), Integer::New(isolate, myinfo.detail.fix_dodge)); + objd->Set(String::NewFromUtf8(isolate, "element_earth"), Integer::New(isolate, myinfo.detail.element_earth)); + objd->Set(String::NewFromUtf8(isolate, "element_water"), Integer::New(isolate, myinfo.detail.element_water)); + objd->Set(String::NewFromUtf8(isolate, "element_fire"), Integer::New(isolate, myinfo.detail.element_fire)); + objd->Set(String::NewFromUtf8(isolate, "element_wind"), Integer::New(isolate, myinfo.detail.element_wind)); + obj->Set(String::NewFromUtf8(isolate, "detail"), objd); + arr->Set(i, obj); } info.GetReturnValue().Set(arr); @@ -611,7 +713,7 @@ void IsPetSkillValid(const Nan::FunctionCallbackInfo& info) return; } if (info.Length() < 2) { - Nan::ThrowTypeError("Arg[1] must be skillid."); + Nan::ThrowTypeError("Arg[1] must be skill index."); return; } @@ -655,6 +757,7 @@ void GetPetSkillInfo(const Nan::FunctionCallbackInfo& info) obj->Set(String::NewFromUtf8(isolate, "info"), Nan::New(myinfo.info).ToLocalChecked()); obj->Set(String::NewFromUtf8(isolate, "cost"), Integer::New(isolate, myinfo.cost)); obj->Set(String::NewFromUtf8(isolate, "flags"), Integer::New(isolate, myinfo.flags)); + obj->Set(String::NewFromUtf8(isolate, "index"), Integer::New(isolate, myinfo.index)); info.GetReturnValue().Set(obj); } @@ -684,6 +787,7 @@ void GetPetSkillsInfo(const Nan::FunctionCallbackInfo& info) obj->Set(String::NewFromUtf8(isolate, "info"), Nan::New(myinfo.info).ToLocalChecked()); obj->Set(String::NewFromUtf8(isolate, "cost"), Integer::New(isolate, myinfo.cost)); obj->Set(String::NewFromUtf8(isolate, "flags"), Integer::New(isolate, myinfo.flags)); + obj->Set(String::NewFromUtf8(isolate, "index"), Integer::New(isolate, myinfo.index)); arr->Set(i, obj); } info.GetReturnValue().Set(arr); diff --git a/CGANode/item.cc b/CGANode/item.cc index aed87d6..30fb1fa 100644 --- a/CGANode/item.cc +++ b/CGANode/item.cc @@ -9,9 +9,75 @@ using namespace v8; extern CGA::CGAInterface *g_CGAInterface; +void TradeStateAsyncCallBack(uv_async_t *handle); +void TradeDialogAsyncCallBack(uv_async_t *handle); +void TradeStuffsAsyncCallBack(uv_async_t *handle); void PlayerMenuAsyncCallBack(uv_async_t *handle); void UnitMenuAsyncCallBack(uv_async_t *handle); +class TradeStateNotifyData : public CBaseNotifyData +{ +public: + TradeStateNotifyData() : CBaseNotifyData(TradeStateAsyncCallBack) + { + } + + int m_info; +}; + +class TradeStateCacheData +{ +public: + TradeStateCacheData(int info, uint64_t time) : m_info(info), m_time(time) + { + + } + int m_info; + uint64_t m_time; +}; + +class TradeDialogNotifyData : public CBaseNotifyData +{ +public: + TradeDialogNotifyData() : CBaseNotifyData(TradeDialogAsyncCallBack) + { + } + + CGA::cga_trade_dialog_t m_info; +}; + +class TradeDialogCacheData +{ +public: + TradeDialogCacheData(const CGA::cga_trade_dialog_t &info, uint64_t time) : m_info(info), m_time(time) + { + + } + CGA::cga_trade_dialog_t m_info; + uint64_t m_time; +}; + +class TradeStuffsNotifyData : public CBaseNotifyData +{ +public: + TradeStuffsNotifyData() : CBaseNotifyData(TradeStuffsAsyncCallBack) + { + } + + CGA::cga_trade_stuff_info_t m_info; +}; + +class TradeStuffsCacheData +{ +public: + TradeStuffsCacheData(const CGA::cga_trade_stuff_info_t &info, uint64_t time) : m_info(info), m_time(time) + { + + } + CGA::cga_trade_stuff_info_t m_info; + uint64_t m_time; +}; + class PlayerMenuNotifyData : public CBaseNotifyData { public: @@ -22,6 +88,17 @@ class PlayerMenuNotifyData : public CBaseNotifyData CGA::cga_player_menu_items_t m_players; }; +class PlayerMenuCacheData +{ +public: + PlayerMenuCacheData(const CGA::cga_player_menu_items_t &info, uint64_t time) : m_info(info), m_time(time) + { + + } + CGA::cga_player_menu_items_t m_info; + uint64_t m_time; +}; + class UnitMenuNotifyData : public CBaseNotifyData { public: @@ -32,11 +109,57 @@ class UnitMenuNotifyData : public CBaseNotifyData CGA::cga_unit_menu_items_t m_units; }; +class UnitMenuCacheData +{ +public: + UnitMenuCacheData(const CGA::cga_unit_menu_items_t &info, uint64_t time) : m_info(info), m_time(time) + { + + } + CGA::cga_unit_menu_items_t m_info; + uint64_t m_time; +}; + +boost::shared_mutex g_TradeState_Lock; +std::vector g_TradeState_Asyncs; +std::vector g_TradeState_Caches; + +boost::shared_mutex g_TradeDialog_Lock; +std::vector g_TradeDialog_Asyncs; +std::vector g_TradeDialog_Caches; + +boost::shared_mutex g_TradeStuffs_Lock; +std::vector g_TradeStuffs_Asyncs; +std::vector g_TradeStuffs_Caches; + boost::shared_mutex g_PlayerMenu_Lock; std::vector g_PlayerMenu_Asyncs; +std::vector g_PlayerMenu_Caches; -boost::shared_mutex g_UnitMenu_Lock; +boost::shared_mutex g_UnitMenu_Lock; std::vector g_UnitMenu_Asyncs; +std::vector g_UnitMenu_Caches; + +void DropPet(const Nan::FunctionCallbackInfo& info) +{ + Isolate* isolate = info.GetIsolate(); + HandleScope handle_scope(isolate); + + if (info.Length() < 1) { + Nan::ThrowTypeError("Arg[0] must be petpos."); + return; + } + + int petpos = (int)info[0]->IntegerValue(); + bool result = false; + if (!g_CGAInterface->DropPet(petpos, result)) + { + Nan::ThrowError("RPC Invocation failed."); + return; + } + + info.GetReturnValue().Set(result); +} void DropItem(const Nan::FunctionCallbackInfo& info) { @@ -47,29 +170,453 @@ void DropItem(const Nan::FunctionCallbackInfo& info) Nan::ThrowTypeError("Arg[0] must be itempos."); return; } - - int itempos = (int)info[0]->IntegerValue(); - bool result = false; - if (!g_CGAInterface->DropItem(itempos, result)) + + int itempos = (int)info[0]->IntegerValue(); + bool result = false; + if (!g_CGAInterface->DropItem(itempos, result)) + { + Nan::ThrowError("RPC Invocation failed."); + return; + } + + info.GetReturnValue().Set(result); +} + +void TradeStateDoAsyncCall(int state) +{ + if (g_TradeState_Asyncs.size()) + { + for (size_t i = 0; i < g_TradeState_Asyncs.size(); ++i) + { + const auto data = g_TradeState_Asyncs[i]; + data->m_info = state; + data->m_result = true; + uv_async_send(data->m_async); + } + g_TradeState_Asyncs.clear(); + } + else + { + auto hrtime = uv_hrtime(); + for (auto &p = g_TradeState_Caches.begin(); p != g_TradeState_Caches.end(); ) + { + if (hrtime - (*p)->m_time > CGA_NOTIFY_MAX_CACHE_TIME) + { + delete *p; + p = g_TradeState_Caches.erase(p); + } + else + { + p++; + } + } + g_TradeState_Caches.emplace_back(new TradeStateCacheData(state, uv_hrtime())); + } +} + +void TradeStateNotify(int state) +{ + boost::unique_lock lock(g_TradeState_Lock); + TradeStateDoAsyncCall(state); +} + +void TradeStateAsyncCallBack(uv_async_t *handle) +{ + Isolate* isolate = Isolate::GetCurrent(); + HandleScope handle_scope(isolate); + + auto data = (TradeStateNotifyData *)handle->data; + + Handle argv[1]; + if (data->m_result) + { + argv[0] = Integer::New(isolate, data->m_info); + } + else + { + argv[0] = Nan::New(false); + } + + Local::New(isolate, data->m_callback)->Call(isolate->GetCurrentContext()->Global(), 1, argv); + + data->m_callback.Reset(); + + uv_timer_stop(data->m_timer); + uv_close((uv_handle_t*)handle, FreeUVHandleCallBack); + uv_close((uv_handle_t*)data->m_timer, FreeUVHandleCallBack); + delete handle->data; +} + +void TradeStateTimerCallBack(uv_timer_t *handle) +{ + Isolate* isolate = Isolate::GetCurrent(); + HandleScope handle_scope(isolate); + + auto data = (TradeStateNotifyData *)handle->data; + + bool asyncNotCalled = false; + + { + boost::unique_lock lock(g_TradeState_Lock); + for (size_t i = 0; i < g_TradeState_Asyncs.size(); ++i) + { + if (g_TradeState_Asyncs[i] == data) + { + asyncNotCalled = true; + g_TradeState_Asyncs.erase(g_TradeState_Asyncs.begin() + i); + break; + } + } + } + + if (asyncNotCalled) + { + Handle argv[1]; + argv[0] = Nan::TypeError("Async callback timeout."); + + Local::New(isolate, data->m_callback)->Call(isolate->GetCurrentContext()->Global(), 1, argv); + + data->m_callback.Reset(); + + uv_timer_stop(handle); + uv_close((uv_handle_t*)data->m_async, FreeUVHandleCallBack); + uv_close((uv_handle_t*)handle, FreeUVHandleCallBack); + delete handle->data; + } +} + +void TradeDialogDoAsyncCall(const CGA::cga_trade_dialog_t &info) +{ + if (g_TradeDialog_Asyncs.size()) + { + for (size_t i = 0; i < g_TradeDialog_Asyncs.size(); ++i) + { + const auto data = g_TradeDialog_Asyncs[i]; + data->m_info = info; + data->m_result = true; + uv_async_send(data->m_async); + } + g_TradeDialog_Asyncs.clear(); + } + else + { + auto hrtime = uv_hrtime(); + for (auto &p = g_TradeDialog_Caches.begin(); p != g_TradeDialog_Caches.end(); ) + { + if (hrtime - (*p)->m_time > CGA_NOTIFY_MAX_CACHE_TIME) + { + delete *p; + p = g_TradeDialog_Caches.erase(p); + } + else + { + p++; + } + } + g_TradeDialog_Caches.emplace_back(new TradeDialogCacheData(info, uv_hrtime())); + } +} + +void TradeDialogNotify(CGA::cga_trade_dialog_t info) +{ + boost::unique_lock lock(g_TradeDialog_Lock); + TradeDialogDoAsyncCall(info); +} + +void TradeDialogAsyncCallBack(uv_async_t *handle) +{ + Isolate* isolate = Isolate::GetCurrent(); + HandleScope handle_scope(isolate); + + auto data = (TradeDialogNotifyData *)handle->data; + + Handle argv[2]; + if (data->m_result) + { + argv[0] = Nan::New(data->m_info.name).ToLocalChecked(); + argv[1] = Integer::New(isolate, data->m_info.level); + Local::New(isolate, data->m_callback)->Call(isolate->GetCurrentContext()->Global(), 2, argv); + } + else + { + argv[0] = Nan::New(false); + Local::New(isolate, data->m_callback)->Call(isolate->GetCurrentContext()->Global(), 1, argv); + } + + data->m_callback.Reset(); + + uv_timer_stop(data->m_timer); + uv_close((uv_handle_t*)handle, FreeUVHandleCallBack); + uv_close((uv_handle_t*)data->m_timer, FreeUVHandleCallBack); + delete handle->data; +} + +void TradeDialogTimerCallBack(uv_timer_t *handle) +{ + Isolate* isolate = Isolate::GetCurrent(); + HandleScope handle_scope(isolate); + + auto data = (TradeDialogNotifyData *)handle->data; + + bool asyncNotCalled = false; + + { + boost::unique_lock lock(g_TradeDialog_Lock); + for (size_t i = 0; i < g_TradeDialog_Asyncs.size(); ++i) + { + if (g_TradeDialog_Asyncs[i] == data) + { + asyncNotCalled = true; + g_TradeDialog_Asyncs.erase(g_TradeDialog_Asyncs.begin() + i); + break; + } + } + } + + if (asyncNotCalled) + { + Handle argv[1]; + argv[0] = Nan::TypeError("Async callback timeout."); + + Local::New(isolate, data->m_callback)->Call(isolate->GetCurrentContext()->Global(), 1, argv); + + data->m_callback.Reset(); + + uv_timer_stop(handle); + uv_close((uv_handle_t*)data->m_async, FreeUVHandleCallBack); + uv_close((uv_handle_t*)handle, FreeUVHandleCallBack); + delete handle->data; + } +} + +void TradeStuffsDoAsyncCall(const CGA::cga_trade_stuff_info_t &info) +{ + if (g_TradeStuffs_Asyncs.size()) + { + for (size_t i = 0; i < g_TradeStuffs_Asyncs.size(); ++i) + { + const auto data = g_TradeStuffs_Asyncs[i]; + data->m_info = info; + data->m_result = true; + uv_async_send(data->m_async); + } + g_TradeStuffs_Asyncs.clear(); + } + else + { + auto hrtime = uv_hrtime(); + for (auto &p = g_TradeStuffs_Caches.begin(); p != g_TradeStuffs_Caches.end(); ) + { + if (hrtime - (*p)->m_time > CGA_NOTIFY_MAX_CACHE_TIME) + { + delete *p; + p = g_TradeStuffs_Caches.erase(p); + } + else + { + p++; + } + } + g_TradeStuffs_Caches.emplace_back(new TradeStuffsCacheData(info, uv_hrtime())); + } +} + +void TradeStuffsNotify(CGA::cga_trade_stuff_info_t info) +{ + boost::unique_lock lock(g_TradeStuffs_Lock); + TradeStuffsDoAsyncCall(info); +} + +void TradeStuffsAsyncCallBack(uv_async_t *handle) +{ + Isolate* isolate = Isolate::GetCurrent(); + HandleScope handle_scope(isolate); + + auto data = (TradeStuffsNotifyData *)handle->data; + + Handle argv[2]; + if (data->m_result) + { + if(data->m_info.type == TRADE_STUFFS_ITEM) + { + argv[0] = Nan::New(TRADE_STUFFS_ITEM); + Local arr = Array::New(isolate); + for (size_t i = 0; i < data->m_info.items.size(); ++i) + { + Local obj = Object::New(isolate); + obj->Set(String::NewFromUtf8(isolate, "name"), Nan::New(data->m_info.items[i].name).ToLocalChecked()); + obj->Set(String::NewFromUtf8(isolate, "attr"), Nan::New(data->m_info.items[i].attr).ToLocalChecked()); + obj->Set(String::NewFromUtf8(isolate, "itemid"), Integer::New(isolate, data->m_info.items[i].itemid)); + obj->Set(String::NewFromUtf8(isolate, "count"), Integer::New(isolate, data->m_info.items[i].count)); + obj->Set(String::NewFromUtf8(isolate, "pos"), Integer::New(isolate, data->m_info.items[i].pos)); + obj->Set(String::NewFromUtf8(isolate, "level"), Integer::New(isolate, data->m_info.items[i].level)); + obj->Set(String::NewFromUtf8(isolate, "type"), Integer::New(isolate, data->m_info.items[i].type)); + arr->Set(i, obj); + } + argv[1] = arr; + Local::New(isolate, data->m_callback)->Call(isolate->GetCurrentContext()->Global(), 2, argv); + } + else if(data->m_info.type == TRADE_STUFFS_PET) + { + argv[0] = Nan::New(TRADE_STUFFS_PET); + Local obj = Object::New(isolate); + obj->Set(String::NewFromUtf8(isolate, "index"), Integer::New(isolate, data->m_info.pet.index)); + obj->Set(String::NewFromUtf8(isolate, "name"), Nan::New(data->m_info.pet.name).ToLocalChecked()); + obj->Set(String::NewFromUtf8(isolate, "realname"), Nan::New(data->m_info.pet.realname).ToLocalChecked()); + obj->Set(String::NewFromUtf8(isolate, "level"), Integer::New(isolate, data->m_info.pet.level)); + obj->Set(String::NewFromUtf8(isolate, "race"), Integer::New(isolate, data->m_info.pet.race)); + obj->Set(String::NewFromUtf8(isolate, "maxhp"), Integer::New(isolate, data->m_info.pet.maxhp)); + obj->Set(String::NewFromUtf8(isolate, "maxmp"), Integer::New(isolate, data->m_info.pet.maxmp)); + obj->Set(String::NewFromUtf8(isolate, "loyality"), Integer::New(isolate, data->m_info.pet.loyality)); + obj->Set(String::NewFromUtf8(isolate, "skill_count"), Integer::New(isolate, data->m_info.pet.skill_count)); + obj->Set(String::NewFromUtf8(isolate, "image_id"), Integer::New(isolate, data->m_info.pet.image_id)); + + Local objd = Object::New(isolate); + objd->Set(String::NewFromUtf8(isolate, "points_remain"), Integer::New(isolate, data->m_info.pet.detail.points_remain)); + objd->Set(String::NewFromUtf8(isolate, "points_endurance"), Integer::New(isolate, data->m_info.pet.detail.points_endurance)); + objd->Set(String::NewFromUtf8(isolate, "points_strength"), Integer::New(isolate, data->m_info.pet.detail.points_strength)); + objd->Set(String::NewFromUtf8(isolate, "points_defense"), Integer::New(isolate, data->m_info.pet.detail.points_defense)); + objd->Set(String::NewFromUtf8(isolate, "points_agility"), Integer::New(isolate, data->m_info.pet.detail.points_agility)); + objd->Set(String::NewFromUtf8(isolate, "points_magical"), Integer::New(isolate, data->m_info.pet.detail.points_magical)); + objd->Set(String::NewFromUtf8(isolate, "value_attack"), Integer::New(isolate, data->m_info.pet.detail.value_attack)); + objd->Set(String::NewFromUtf8(isolate, "value_defensive"), Integer::New(isolate, data->m_info.pet.detail.value_defensive)); + objd->Set(String::NewFromUtf8(isolate, "value_agility"), Integer::New(isolate, data->m_info.pet.detail.value_agility)); + objd->Set(String::NewFromUtf8(isolate, "value_spirit"), Integer::New(isolate, data->m_info.pet.detail.value_spirit)); + objd->Set(String::NewFromUtf8(isolate, "value_recovery"), Integer::New(isolate, data->m_info.pet.detail.value_recovery)); + objd->Set(String::NewFromUtf8(isolate, "resist_poison"), Integer::New(isolate, data->m_info.pet.detail.resist_poison)); + objd->Set(String::NewFromUtf8(isolate, "resist_sleep"), Integer::New(isolate, data->m_info.pet.detail.resist_sleep)); + objd->Set(String::NewFromUtf8(isolate, "resist_medusa"), Integer::New(isolate, data->m_info.pet.detail.resist_medusa)); + objd->Set(String::NewFromUtf8(isolate, "resist_drunk"), Integer::New(isolate, data->m_info.pet.detail.resist_drunk)); + objd->Set(String::NewFromUtf8(isolate, "resist_chaos"), Integer::New(isolate, data->m_info.pet.detail.resist_chaos)); + objd->Set(String::NewFromUtf8(isolate, "resist_forget"), Integer::New(isolate, data->m_info.pet.detail.resist_forget)); + objd->Set(String::NewFromUtf8(isolate, "fix_critical"), Integer::New(isolate, data->m_info.pet.detail.fix_critical)); + objd->Set(String::NewFromUtf8(isolate, "fix_strikeback"), Integer::New(isolate, data->m_info.pet.detail.fix_strikeback)); + objd->Set(String::NewFromUtf8(isolate, "fix_accurancy"), Integer::New(isolate, data->m_info.pet.detail.fix_accurancy)); + objd->Set(String::NewFromUtf8(isolate, "fix_dodge"), Integer::New(isolate, data->m_info.pet.detail.fix_dodge)); + objd->Set(String::NewFromUtf8(isolate, "element_earth"), Integer::New(isolate, data->m_info.pet.detail.element_earth)); + objd->Set(String::NewFromUtf8(isolate, "element_water"), Integer::New(isolate, data->m_info.pet.detail.element_water)); + objd->Set(String::NewFromUtf8(isolate, "element_fire"), Integer::New(isolate, data->m_info.pet.detail.element_fire)); + objd->Set(String::NewFromUtf8(isolate, "element_wind"), Integer::New(isolate, data->m_info.pet.detail.element_wind)); + + obj->Set(String::NewFromUtf8(isolate, "detail"), objd); + + argv[1] = obj; + Local::New(isolate, data->m_callback)->Call(isolate->GetCurrentContext()->Global(), 2, argv); + } + else if (data->m_info.type == TRADE_STUFFS_PETSKILL) + { + argv[0] = Nan::New(TRADE_STUFFS_PETSKILL); + + Local obj = Object::New(isolate); + obj->Set(String::NewFromUtf8(isolate, "index"), Integer::New(isolate, data->m_info.petskills.index)); + Local arr = Array::New(isolate); + for (size_t i = 0; i < data->m_info.petskills.skills.size(); ++i) + { + arr->Set(i, Nan::New(data->m_info.petskills.skills[i]).ToLocalChecked()); + } + obj->Set(String::NewFromUtf8(isolate, "skills"), arr); + + argv[1] = obj; + + Local::New(isolate, data->m_callback)->Call(isolate->GetCurrentContext()->Global(), 2, argv); + } + else if(data->m_info.type == TRADE_STUFFS_GOLD) + { + argv[0] = Nan::New(TRADE_STUFFS_GOLD); + argv[1] = Integer::New(isolate, data->m_info.gold); + Local::New(isolate, data->m_callback)->Call(isolate->GetCurrentContext()->Global(), 2, argv); + } else { + argv[0] = Nan::New(false); + Local::New(isolate, data->m_callback)->Call(isolate->GetCurrentContext()->Global(), 1, argv); + } + } + else + { + argv[0] = Nan::New(false); + Local::New(isolate, data->m_callback)->Call(isolate->GetCurrentContext()->Global(), 2, argv); + } + data->m_callback.Reset(); + + uv_timer_stop(data->m_timer); + uv_close((uv_handle_t*)handle, FreeUVHandleCallBack); + uv_close((uv_handle_t*)data->m_timer, FreeUVHandleCallBack); + delete handle->data; +} + +void TradeStuffsTimerCallBack(uv_timer_t *handle) +{ + Isolate* isolate = Isolate::GetCurrent(); + HandleScope handle_scope(isolate); + + auto data = (TradeStuffsNotifyData *)handle->data; + + bool asyncNotCalled = false; + + { + boost::unique_lock lock(g_TradeStuffs_Lock); + for (size_t i = 0; i < g_TradeStuffs_Asyncs.size(); ++i) + { + if (g_TradeStuffs_Asyncs[i] == data) + { + asyncNotCalled = true; + g_TradeStuffs_Asyncs.erase(g_TradeStuffs_Asyncs.begin() + i); + break; + } + } + } + + if (asyncNotCalled) + { + Handle argv[1]; + argv[0] = Nan::TypeError("Async callback timeout."); + + Local::New(isolate, data->m_callback)->Call(isolate->GetCurrentContext()->Global(), 1, argv); + + data->m_callback.Reset(); + + uv_timer_stop(handle); + uv_close((uv_handle_t*)data->m_async, FreeUVHandleCallBack); + uv_close((uv_handle_t*)handle, FreeUVHandleCallBack); + delete handle->data; + } +} + +void PlayerMenuDoAsyncCall(const CGA::cga_player_menu_items_t &players) +{ + if (g_PlayerMenu_Asyncs.size()) + { + for (size_t i = 0; i < g_PlayerMenu_Asyncs.size(); ++i) + { + const auto data = g_PlayerMenu_Asyncs[i]; + data->m_players = players; + data->m_result = true; + uv_async_send(data->m_async); + } + g_PlayerMenu_Asyncs.clear(); + } + else { - Nan::ThrowError("RPC Invocation failed."); - return; + auto hrtime = uv_hrtime(); + for (auto &p = g_PlayerMenu_Caches.begin(); p != g_PlayerMenu_Caches.end(); ) + { + if (hrtime - (*p)->m_time > CGA_NOTIFY_MAX_CACHE_TIME) + { + delete *p; + p = g_PlayerMenu_Caches.erase(p); + } + else + { + p++; + } + } + g_PlayerMenu_Caches.emplace_back(new PlayerMenuCacheData(players, uv_hrtime())); } - - info.GetReturnValue().Set(result); } void PlayerMenuNotify(CGA::cga_player_menu_items_t players) { boost::unique_lock lock(g_PlayerMenu_Lock); - for (size_t i = 0; i < g_PlayerMenu_Asyncs.size(); ++i) - { - const auto data = g_PlayerMenu_Asyncs[i]; - data->m_players = players; - data->m_result = true; - uv_async_send(&data->m_async); - } - g_PlayerMenu_Asyncs.clear(); + PlayerMenuDoAsyncCall(players); } void PlayerMenuAsyncCallBack(uv_async_t *handle) @@ -102,9 +649,9 @@ void PlayerMenuAsyncCallBack(uv_async_t *handle) data->m_callback.Reset(); - uv_timer_stop(&data->m_timer); - uv_close((uv_handle_t*)handle, NULL); - uv_close((uv_handle_t*)&data->m_timer, NULL); + uv_timer_stop(data->m_timer); + uv_close((uv_handle_t*)handle, FreeUVHandleCallBack); + uv_close((uv_handle_t*)data->m_timer, FreeUVHandleCallBack); delete handle->data; } @@ -115,12 +662,7 @@ void PlayerMenuTimerCallBack(uv_timer_t *handle) auto data = (PlayerMenuNotifyData *)handle->data; - Handle argv[1]; - argv[0] = Nan::TypeError("Async callback timeout."); - - Local::New(isolate, data->m_callback)->Call(isolate->GetCurrentContext()->Global(), 1, argv); - - data->m_callback.Reset(); + bool asyncNotCalled = false; { boost::unique_lock lock(g_PlayerMenu_Lock); @@ -128,29 +670,65 @@ void PlayerMenuTimerCallBack(uv_timer_t *handle) { if (g_PlayerMenu_Asyncs[i] == data) { + asyncNotCalled = true; g_PlayerMenu_Asyncs.erase(g_PlayerMenu_Asyncs.begin() + i); break; } } } - uv_timer_stop(handle); - uv_close((uv_handle_t*)&data->m_async, NULL); - uv_close((uv_handle_t*)handle, NULL); - delete handle->data; + if (asyncNotCalled) + { + Handle argv[1]; + argv[0] = Nan::TypeError("Async callback timeout."); + + Local::New(isolate, data->m_callback)->Call(isolate->GetCurrentContext()->Global(), 1, argv); + + data->m_callback.Reset(); + + uv_timer_stop(handle); + uv_close((uv_handle_t*)data->m_async, FreeUVHandleCallBack); + uv_close((uv_handle_t*)handle, FreeUVHandleCallBack); + delete handle->data; + } } -void UnitMenuNotify(CGA::cga_unit_menu_items_t units) +void UnitMenuDoAsyncCall(const CGA::cga_unit_menu_items_t &units) { - boost::unique_lock lock(g_UnitMenu_Lock); - for (size_t i = 0; i < g_UnitMenu_Asyncs.size(); ++i) + if (g_UnitMenu_Asyncs.size()) + { + for (size_t i = 0; i < g_UnitMenu_Asyncs.size(); ++i) + { + const auto data = g_UnitMenu_Asyncs[i]; + data->m_units = units; + data->m_result = true; + uv_async_send(data->m_async); + } + g_UnitMenu_Asyncs.clear(); + } + else { - const auto data = g_UnitMenu_Asyncs[i]; - data->m_units = units; - data->m_result = true; - uv_async_send(&data->m_async); + auto hrtime = uv_hrtime(); + for (auto &p = g_UnitMenu_Caches.begin(); p != g_UnitMenu_Caches.end(); ) + { + if (hrtime - (*p)->m_time > CGA_NOTIFY_MAX_CACHE_TIME) + { + delete *p; + p = g_UnitMenu_Caches.erase(p); + } + else + { + p++; + } + } + g_UnitMenu_Caches.emplace_back(new UnitMenuCacheData(units, uv_hrtime())); } - g_UnitMenu_Asyncs.clear(); +} + +void UnitMenuNotify(CGA::cga_unit_menu_items_t units) +{ + boost::unique_lock lock(g_UnitMenu_Lock); + UnitMenuDoAsyncCall(units); } void UnitMenuAsyncCallBack(uv_async_t *handle) @@ -189,9 +767,9 @@ void UnitMenuAsyncCallBack(uv_async_t *handle) data->m_callback.Reset(); - uv_timer_stop(&data->m_timer); - uv_close((uv_handle_t*)handle, NULL); - uv_close((uv_handle_t*)&data->m_timer, NULL); + uv_timer_stop(data->m_timer); + uv_close((uv_handle_t*)handle, FreeUVHandleCallBack); + uv_close((uv_handle_t*)data->m_timer, FreeUVHandleCallBack); delete handle->data; } @@ -202,12 +780,7 @@ void UnitMenuTimerCallBack(uv_timer_t *handle) auto data = (UnitMenuNotifyData *)handle->data; - Handle argv[1]; - argv[0] = Nan::TypeError("Async callback timeout."); - - Local::New(isolate, data->m_callback)->Call(isolate->GetCurrentContext()->Global(), 1, argv); - - data->m_callback.Reset(); + bool asyncNotCalled = false; { boost::unique_lock lock(g_UnitMenu_Lock); @@ -215,16 +788,27 @@ void UnitMenuTimerCallBack(uv_timer_t *handle) { if (g_UnitMenu_Asyncs[i] == data) { + asyncNotCalled = true; g_UnitMenu_Asyncs.erase(g_UnitMenu_Asyncs.begin() + i); break; } } } - uv_timer_stop(handle); - uv_close((uv_handle_t*)&data->m_async, NULL); - uv_close((uv_handle_t*)handle, NULL); - delete handle->data; + if (asyncNotCalled) + { + Handle argv[1]; + argv[0] = Nan::TypeError("Async callback timeout."); + + Local::New(isolate, data->m_callback)->Call(isolate->GetCurrentContext()->Global(), 1, argv); + + data->m_callback.Reset(); + + uv_timer_stop(handle); + uv_close((uv_handle_t*)data->m_async, FreeUVHandleCallBack); + uv_close((uv_handle_t*)handle, FreeUVHandleCallBack); + delete handle->data; + } } void UseItem(const Nan::FunctionCallbackInfo& info) @@ -297,17 +881,36 @@ void AsyncWaitPlayerMenu(const Nan::FunctionCallbackInfo& info) timeout = 0; } - boost::unique_lock lock(g_PlayerMenu_Lock); - auto callback = Local::Cast(info[0]); PlayerMenuNotifyData *data = new PlayerMenuNotifyData(); data->m_callback.Reset(isolate, callback); - data->m_async.data = data; - data->m_timer.data = data; + data->m_async->data = data; + data->m_timer->data = data; + + { + boost::unique_lock lock(g_PlayerMenu_Lock); + g_PlayerMenu_Asyncs.push_back(data); + + auto hrtime = uv_hrtime(); + for (auto &p = g_PlayerMenu_Caches.begin(); p != g_PlayerMenu_Caches.end(); ) + { + if (hrtime - (*p)->m_time > CGA_NOTIFY_MAX_CACHE_TIME) + { + delete *p; + p = g_PlayerMenu_Caches.erase(p); + } + else + { + PlayerMenuDoAsyncCall((*p)->m_info); + delete *p; + g_PlayerMenu_Caches.erase(p); + break; + } + } + } - g_PlayerMenu_Asyncs.push_back(data); if(timeout) - uv_timer_start(&data->m_timer, PlayerMenuTimerCallBack, timeout, 0); + uv_timer_start(data->m_timer, PlayerMenuTimerCallBack, timeout, 0); } void PlayerMenuSelect(const Nan::FunctionCallbackInfo& info) @@ -321,8 +924,19 @@ void PlayerMenuSelect(const Nan::FunctionCallbackInfo& info) } int menuindex = (int)info[0]->IntegerValue(); + + std::string menustring; + + if (info.Length() >= 2) { + if (info[1]->IsString()) + { + v8::String::Utf8Value str(info[0]->ToString()); + menustring.assign(*str); + } + } + bool bResult = false; - if (!g_CGAInterface->PlayerMenuSelect(menuindex, bResult)) + if (!g_CGAInterface->PlayerMenuSelect(menuindex, menustring, bResult)) { Nan::ThrowError("RPC Invocation failed."); return; @@ -348,17 +962,36 @@ void AsyncWaitUnitMenu(const Nan::FunctionCallbackInfo& info) timeout = 0; } - boost::unique_lock lock(g_UnitMenu_Lock); - auto callback = Local::Cast(info[0]); UnitMenuNotifyData *data = new UnitMenuNotifyData(); data->m_callback.Reset(isolate, callback); - data->m_async.data = data; - data->m_timer.data = data; + data->m_async->data = data; + data->m_timer->data = data; + + { + boost::unique_lock lock(g_UnitMenu_Lock); + g_UnitMenu_Asyncs.push_back(data); + + auto hrtime = uv_hrtime(); + for (auto &p = g_UnitMenu_Caches.begin(); p != g_UnitMenu_Caches.end(); ) + { + if (hrtime - (*p)->m_time > CGA_NOTIFY_MAX_CACHE_TIME) + { + delete *p; + p = g_UnitMenu_Caches.erase(p); + } + else + { + UnitMenuDoAsyncCall((*p)->m_info); + delete *p; + g_UnitMenu_Caches.erase(p); + break; + } + } + } - g_UnitMenu_Asyncs.push_back(data); if(timeout) - uv_timer_start(&data->m_timer, UnitMenuTimerCallBack, timeout, 0); + uv_timer_start(data->m_timer, UnitMenuTimerCallBack, timeout, 0); } void UnitMenuSelect(const Nan::FunctionCallbackInfo& info) @@ -380,4 +1013,264 @@ void UnitMenuSelect(const Nan::FunctionCallbackInfo& info) } info.GetReturnValue().Set(bResult); +} + +void DoRequest(const Nan::FunctionCallbackInfo& info) +{ + Isolate* isolate = info.GetIsolate(); + HandleScope handle_scope(isolate); + + if (info.Length() < 1) { + Nan::ThrowTypeError("Arg[0] must be request type."); + return; + } + + int request_type = (int)info[0]->IntegerValue(); + bool result = false; + if (!g_CGAInterface->DoRequest(request_type, result)) + { + Nan::ThrowError("RPC Invocation failed."); + return; + } + + info.GetReturnValue().Set(result); +} + +void EnableFlags(const Nan::FunctionCallbackInfo& info) +{ + Isolate* isolate = info.GetIsolate(); + HandleScope handle_scope(isolate); + + if (info.Length() < 1) { + Nan::ThrowTypeError("Arg[0] must be type."); + return; + } + + if (info.Length() < 2) { + Nan::ThrowTypeError("Arg[1] must be boolean."); + return; + } + + int type = (int)info[0]->IntegerValue(); + bool enable = info[1]->BooleanValue(); + bool result = false; + if (!g_CGAInterface->EnableFlags(type, enable, result)) + { + Nan::ThrowError("RPC Invocation failed."); + return; + } + + info.GetReturnValue().Set(result); +} + +void TradeAddStuffs(const Nan::FunctionCallbackInfo& info) +{ + Isolate* isolate = info.GetIsolate(); + HandleScope handle_scope(isolate); + + if (info.Length() < 1 || !info[0]->IsArray()) { + Nan::ThrowTypeError("Arg[0] must be item object array."); + return; + } + + if (info.Length() < 2 || !info[0]->IsArray()) { + Nan::ThrowTypeError("Arg[1] must be pet id array."); + return; + } + + if (info.Length() < 3) { + Nan::ThrowTypeError("Arg[2] must be gold."); + return; + } + + Local objarr = Local::Cast(info[0]); + uint32_t length = objarr->Get(Nan::New("length").ToLocalChecked())->Uint32Value(); + + Local arr = Local::Cast(info[0]); + CGA::cga_sell_items_t items; + for (uint32_t i = 0; i < length; ++i) + { + Local obj = Local::Cast(arr->Get(i)); + Local obj_itemid = obj->Get(Nan::New("itemid").ToLocalChecked()); + Local obj_itempos = obj->Get(Nan::New("itempos").ToLocalChecked()); + Local obj_count = obj->Get(Nan::New("count").ToLocalChecked()); + int itemid = 0; + int itempos = 0; + int count = 0; + if(!obj_itemid->IsUndefined()) + itemid = (int)obj_itemid->IntegerValue(); + if (!obj_itempos->IsUndefined()) + itempos = (int)obj_itempos->IntegerValue(); + if (!obj_count->IsUndefined()) + count = (int)obj_count->IntegerValue(); + if (count > 0) + items.emplace_back(itemid, itempos, count); + } + + Local objarr2 = Local::Cast(info[1]); + uint32_t length2 = objarr2->Get(Nan::New("length").ToLocalChecked())->Uint32Value(); + + Local arr2 = Local::Cast(info[1]); + CGA::cga_sell_pets_t pets; + for (uint32_t i = 0; i < length2; ++i) + { + auto val = (int)Local::Cast(arr2->Get(i))->IntegerValue(); + pets.emplace_back(val); + } + + int gold = (int)info[2]->IntegerValue(); + if (!g_CGAInterface->TradeAddStuffs(items, pets, gold)) + { + Nan::ThrowError("RPC Invocation failed."); + return; + } +} + +void AsyncWaitTradeStuffs(const Nan::FunctionCallbackInfo& info) +{ + Isolate* isolate = info.GetIsolate(); + HandleScope handle_scope(isolate); + + int timeout = 3000; + if (info.Length() < 1 || !info[0]->IsFunction()) { + Nan::ThrowTypeError("Arg[0] must be a function."); + return; + } + if (info.Length() >= 2 && !info[1]->IsUndefined()) + { + timeout = (int)info[1]->IntegerValue(); + if (timeout < 0) + timeout = 0; + } + + auto callback = Local::Cast(info[0]); + TradeStuffsNotifyData *data = new TradeStuffsNotifyData(); + data->m_callback.Reset(isolate, callback); + data->m_async->data = data; + data->m_timer->data = data; + + { + boost::unique_lock lock(g_TradeStuffs_Lock); + g_TradeStuffs_Asyncs.push_back(data); + + auto hrtime = uv_hrtime(); + for (auto &p = g_TradeStuffs_Caches.begin(); p != g_TradeStuffs_Caches.end(); ) + { + if (hrtime - (*p)->m_time > CGA_NOTIFY_MAX_CACHE_TIME) + { + delete *p; + p = g_TradeStuffs_Caches.erase(p); + } + else + { + TradeStuffsDoAsyncCall((*p)->m_info); + delete *p; + g_TradeStuffs_Caches.erase(p); + break; + } + } + } + + if(timeout) + uv_timer_start(data->m_timer, TradeStuffsTimerCallBack, timeout, 0); +} + +void AsyncWaitTradeDialog(const Nan::FunctionCallbackInfo& info) +{ + Isolate* isolate = info.GetIsolate(); + HandleScope handle_scope(isolate); + + int timeout = 3000; + if (info.Length() < 1 || !info[0]->IsFunction()) { + Nan::ThrowTypeError("Arg[0] must be a function."); + return; + } + if (info.Length() >= 2 && !info[1]->IsUndefined()) + { + timeout = (int)info[1]->IntegerValue(); + if (timeout < 0) + timeout = 0; + } + + auto callback = Local::Cast(info[0]); + TradeDialogNotifyData *data = new TradeDialogNotifyData(); + data->m_callback.Reset(isolate, callback); + data->m_async->data = data; + data->m_timer->data = data; + + { + boost::unique_lock lock(g_TradeDialog_Lock); + + g_TradeDialog_Asyncs.push_back(data); + + auto hrtime = uv_hrtime(); + for (auto &p = g_TradeDialog_Caches.begin(); p != g_TradeDialog_Caches.end(); ) + { + if (hrtime - (*p)->m_time > CGA_NOTIFY_MAX_CACHE_TIME) + { + delete *p; + p = g_TradeDialog_Caches.erase(p); + } + else + { + TradeDialogDoAsyncCall((*p)->m_info); + delete *p; + g_TradeDialog_Caches.erase(p); + break; + } + } + } + + if (timeout) + uv_timer_start(data->m_timer, TradeDialogTimerCallBack, timeout, 0); +} + +void AsyncWaitTradeState(const Nan::FunctionCallbackInfo& info) +{ + Isolate* isolate = info.GetIsolate(); + HandleScope handle_scope(isolate); + + int timeout = 3000; + if (info.Length() < 1 || !info[0]->IsFunction()) { + Nan::ThrowTypeError("Arg[0] must be a function."); + return; + } + if (info.Length() >= 2 && !info[1]->IsUndefined()) + { + timeout = (int)info[1]->IntegerValue(); + if (timeout < 0) + timeout = 0; + } + + auto callback = Local::Cast(info[0]); + TradeStateNotifyData *data = new TradeStateNotifyData(); + data->m_callback.Reset(isolate, callback); + data->m_async->data = data; + data->m_timer->data = data; + + { + boost::unique_lock lock(g_TradeState_Lock); + + g_TradeState_Asyncs.push_back(data); + + auto hrtime = uv_hrtime(); + for (auto &p = g_TradeState_Caches.begin(); p != g_TradeState_Caches.end(); ) + { + if (hrtime - (*p)->m_time > CGA_NOTIFY_MAX_CACHE_TIME) + { + delete *p; + p = g_TradeState_Caches.erase(p); + } + else + { + TradeStateDoAsyncCall((*p)->m_info); + delete *p; + g_TradeState_Caches.erase(p); + break; + } + } + } + + if (timeout) + uv_timer_start(data->m_timer, TradeStateTimerCallBack, timeout, 0); } \ No newline at end of file diff --git a/CGANode/item.h b/CGANode/item.h index fdaa1b0..ed9dc43 100644 --- a/CGANode/item.h +++ b/CGANode/item.h @@ -1,9 +1,16 @@ #pragma once +void DropPet(const Nan::FunctionCallbackInfo& info); void DropItem(const Nan::FunctionCallbackInfo& info); void UseItem(const Nan::FunctionCallbackInfo& info); void MoveItem(const Nan::FunctionCallbackInfo& info); void AsyncWaitPlayerMenu(const Nan::FunctionCallbackInfo& info); void AsyncWaitUnitMenu(const Nan::FunctionCallbackInfo& info); void PlayerMenuSelect(const Nan::FunctionCallbackInfo& info); -void UnitMenuSelect(const Nan::FunctionCallbackInfo& info); \ No newline at end of file +void UnitMenuSelect(const Nan::FunctionCallbackInfo& info); +void DoRequest(const Nan::FunctionCallbackInfo& info); +void EnableFlags(const Nan::FunctionCallbackInfo& info); +void TradeAddStuffs(const Nan::FunctionCallbackInfo& info); +void AsyncWaitTradeStuffs(const Nan::FunctionCallbackInfo& info); +void AsyncWaitTradeDialog(const Nan::FunctionCallbackInfo& info); +void AsyncWaitTradeState(const Nan::FunctionCallbackInfo& info); \ No newline at end of file diff --git a/CGANode/main.cc b/CGANode/main.cc index 6cddad4..4639133 100644 --- a/CGANode/main.cc +++ b/CGANode/main.cc @@ -12,6 +12,12 @@ CGA::CGAInterface *g_CGAInterface = NULL; #include "npc.h" #include "work.h" #include "chat.h" +#include "battle.h" + +void FreeUVHandleCallBack(uv_handle_t *handle) +{ + delete handle; +} void LogBack(const Nan::FunctionCallbackInfo& info) { @@ -127,10 +133,18 @@ void Init(v8::Local exports) { Nan::New(GetMapXY)->GetFunction()); exports->Set(Nan::New("GetMapXYFloat").ToLocalChecked(), Nan::New(GetMapXYFloat)->GetFunction()); + exports->Set(Nan::New("GetMapIndex").ToLocalChecked(), + Nan::New(GetMapIndex)->GetFunction()); + exports->Set(Nan::New("GetMoveSpeed").ToLocalChecked(), + Nan::New(GetMoveSpeed)->GetFunction()); exports->Set(Nan::New("GetMapName").ToLocalChecked(), Nan::New(GetMapName)->GetFunction()); exports->Set(Nan::New("GetMapUnits").ToLocalChecked(), Nan::New(GetMapUnits)->GetFunction()); + exports->Set(Nan::New("GetMapCollisionTable").ToLocalChecked(), + Nan::New(GetMapCollisionTable)->GetFunction()); + exports->Set(Nan::New("GetMapObjectTable").ToLocalChecked(), + Nan::New(GetMapObjectTable)->GetFunction()); exports->Set(Nan::New("WalkTo").ToLocalChecked(), Nan::New(WalkTo)->GetFunction()); exports->Set(Nan::New("TurnTo").ToLocalChecked(), @@ -149,6 +163,8 @@ void Init(v8::Local exports) { Nan::New(LogBack)->GetFunction()); exports->Set(Nan::New("LogOut").ToLocalChecked(), Nan::New(LogOut)->GetFunction()); + exports->Set(Nan::New("DropPet").ToLocalChecked(), + Nan::New(DropPet)->GetFunction()); exports->Set(Nan::New("DropItem").ToLocalChecked(), Nan::New(DropItem)->GetFunction()); exports->Set(Nan::New("UseItem").ToLocalChecked(), @@ -175,6 +191,8 @@ void Init(v8::Local exports) { Nan::New(SayWords)->GetFunction()); exports->Set(Nan::New("AsyncWaitWorkingResult").ToLocalChecked(), Nan::New(AsyncWaitWorkingResult)->GetFunction()); + exports->Set(Nan::New("SetImmediateDoneWork").ToLocalChecked(), + Nan::New(SetImmediateDoneWork)->GetFunction()); exports->Set(Nan::New("StartWork").ToLocalChecked(), Nan::New(StartWork)->GetFunction()); exports->Set(Nan::New("CraftItem").ToLocalChecked(), @@ -186,7 +204,49 @@ void Init(v8::Local exports) { exports->Set(Nan::New("GetCraftsInfo").ToLocalChecked(), Nan::New(GetCraftsInfo)->GetFunction()); exports->Set(Nan::New("AsyncWaitChatMsg").ToLocalChecked(), - Nan::New(AsyncWaitChatMsg)->GetFunction()); + Nan::New(AsyncWaitChatMsg)->GetFunction()); + exports->Set(Nan::New("DoRequest").ToLocalChecked(), + Nan::New(DoRequest)->GetFunction()); + exports->Set(Nan::New("EnableFlags").ToLocalChecked(), + Nan::New(EnableFlags)->GetFunction()); + exports->Set(Nan::New("TradeAddStuffs").ToLocalChecked(), + Nan::New(TradeAddStuffs)->GetFunction()); + exports->Set(Nan::New("AsyncWaitTradeStuffs").ToLocalChecked(), + Nan::New(AsyncWaitTradeStuffs)->GetFunction()); + exports->Set(Nan::New("AsyncWaitTradeDialog").ToLocalChecked(), + Nan::New(AsyncWaitTradeDialog)->GetFunction()); + exports->Set(Nan::New("AsyncWaitTradeState").ToLocalChecked(), + Nan::New(AsyncWaitTradeState)->GetFunction()); + exports->Set(Nan::New("GetTeamPlayerInfo").ToLocalChecked(), + Nan::New(GetTeamPlayerInfo)->GetFunction()); + exports->Set(Nan::New("FixMapWarpStuck").ToLocalChecked(), + Nan::New(FixMapWarpStuck)->GetFunction()); + exports->Set(Nan::New("GetMoveHistory").ToLocalChecked(), + Nan::New(GetMoveHistory)->GetFunction()); + exports->Set(Nan::New("RequestDownloadMap").ToLocalChecked(), + Nan::New(RequestDownloadMap)->GetFunction()); + exports->Set(Nan::New("AsyncWaitBattleAction").ToLocalChecked(), + Nan::New(AsyncWaitBattleAction)->GetFunction()); + exports->Set(Nan::New("GetBattleUnits").ToLocalChecked(), + Nan::New(GetBattleUnits)->GetFunction()); + exports->Set(Nan::New("GetBattleContext").ToLocalChecked(), + Nan::New(GetBattleContext)->GetFunction()); + exports->Set(Nan::New("BattleNormalAttack").ToLocalChecked(), + Nan::New(BattleNormalAttack)->GetFunction()); + exports->Set(Nan::New("BattleSkillAttack").ToLocalChecked(), + Nan::New(BattleSkillAttack)->GetFunction()); + exports->Set(Nan::New("BattleDefense").ToLocalChecked(), + Nan::New(BattleDefense)->GetFunction()); + exports->Set(Nan::New("BattleEscape").ToLocalChecked(), + Nan::New(BattleEscape)->GetFunction()); + exports->Set(Nan::New("BattleExchangePosition").ToLocalChecked(), + Nan::New(BattleExchangePosition)->GetFunction()); + exports->Set(Nan::New("BattleChangePet").ToLocalChecked(), + Nan::New(BattleChangePet)->GetFunction()); + exports->Set(Nan::New("BattleUseItem").ToLocalChecked(), + Nan::New(BattleUseItem)->GetFunction()); + exports->Set(Nan::New("BattlePetSkillAttack").ToLocalChecked(), + Nan::New(BattlePetSkillAttack)->GetFunction()); } NODE_MODULE(node_cga, Init) diff --git a/CGANode/map.cc b/CGANode/map.cc index 726512a..ce6d8c3 100644 --- a/CGANode/map.cc +++ b/CGANode/map.cc @@ -1,3 +1,4 @@ +#include #include #include "../CGALib/gameinterface.h" @@ -5,6 +6,81 @@ using namespace v8; extern CGA::CGAInterface *g_CGAInterface; +void RequestDownloadMap(const Nan::FunctionCallbackInfo& info) +{ + Isolate* isolate = info.GetIsolate(); + HandleScope handle_scope(isolate); + + if (info.Length() < 1) { + Nan::ThrowTypeError("Arg[0] must be xbottom."); + return; + } + + if (info.Length() < 2) { + Nan::ThrowTypeError("Arg[1] must be ybottom."); + return; + } + + if (info.Length() < 3) { + Nan::ThrowTypeError("Arg[2] must be xsize."); + return; + } + + if (info.Length() < 4) { + Nan::ThrowTypeError("Arg[3] must be ysize."); + return; + } + + int xbottom = (int)info[0]->IntegerValue(); + int ybottom = (int)info[1]->IntegerValue(); + int xsize = (int)info[2]->IntegerValue(); + int ysize = (int)info[3]->IntegerValue(); + + if (!g_CGAInterface->RequestDownloadMap(xbottom, ybottom, xsize, ysize)) + { + Nan::ThrowError("RPC Invocation failed."); + return; + } +} + +void FixMapWarpStuck(const Nan::FunctionCallbackInfo& info) +{ + Isolate* isolate = info.GetIsolate(); + HandleScope handle_scope(isolate); + + if (info.Length() < 1) { + Nan::ThrowTypeError("Arg[0] must be type."); + return; + } + + int type = (int)info[0]->IntegerValue(); + + if (!g_CGAInterface->FixMapWarpStuck(type)) + { + Nan::ThrowError("RPC Invocation failed."); + return; + } +} + +void GetMapIndex(const Nan::FunctionCallbackInfo& info) +{ + Isolate* isolate = info.GetIsolate(); + HandleScope handle_scope(isolate); + + int index1, index2, index3; + if (!g_CGAInterface->GetMapIndex(index1, index2, index3)) + { + Nan::ThrowError("RPC Invocation failed."); + return; + } + + Local obj = Object::New(isolate); + obj->Set(String::NewFromUtf8(isolate, "index1"), Integer::New(isolate, index1)); + obj->Set(String::NewFromUtf8(isolate, "index2"), Integer::New(isolate, index2)); + obj->Set(String::NewFromUtf8(isolate, "index3"), Integer::New(isolate, index3)); + info.GetReturnValue().Set(obj); +} + void GetMapXY(const Nan::FunctionCallbackInfo& info) { Isolate* isolate = info.GetIsolate(); @@ -41,6 +117,24 @@ void GetMapXYFloat(const Nan::FunctionCallbackInfo& info) info.GetReturnValue().Set(obj); } +void GetMoveSpeed(const Nan::FunctionCallbackInfo& info) +{ + Isolate* isolate = info.GetIsolate(); + HandleScope handle_scope(isolate); + + float x, y; + if (!g_CGAInterface->GetMoveSpeed(x, y)) + { + Nan::ThrowError("RPC Invocation failed."); + return; + } + + Local obj = Object::New(isolate); + obj->Set(String::NewFromUtf8(isolate, "x"), Number::New(isolate, x)); + obj->Set(String::NewFromUtf8(isolate, "y"), Number::New(isolate, y)); + info.GetReturnValue().Set(obj); +} + void GetMapName(const Nan::FunctionCallbackInfo& info) { Isolate* isolate = info.GetIsolate(); @@ -77,8 +171,13 @@ void GetMapUnits(const Nan::FunctionCallbackInfo& info) obj->Set(String::NewFromUtf8(isolate, "unit_id"), Integer::New(isolate, units[i].unit_id)); obj->Set(String::NewFromUtf8(isolate, "xpos"), Integer::New(isolate, units[i].xpos)); obj->Set(String::NewFromUtf8(isolate, "ypos"), Integer::New(isolate, units[i].ypos)); + obj->Set(String::NewFromUtf8(isolate, "item_count"), Integer::New(isolate, units[i].item_count)); + obj->Set(String::NewFromUtf8(isolate, "injury"), Integer::New(isolate, units[i].injury)); + obj->Set(String::NewFromUtf8(isolate, "level"), Integer::New(isolate, units[i].level)); + obj->Set(String::NewFromUtf8(isolate, "flags"), Integer::New(isolate, units[i].flags)); obj->Set(String::NewFromUtf8(isolate, "unit_name"), Nan::New(units[i].unit_name).ToLocalChecked()); obj->Set(String::NewFromUtf8(isolate, "nick_name"), Nan::New(units[i].nick_name).ToLocalChecked()); + obj->Set(String::NewFromUtf8(isolate, "title_name"), Nan::New(units[i].title_name).ToLocalChecked()); obj->Set(String::NewFromUtf8(isolate, "item_name"), Nan::New(units[i].item_name).ToLocalChecked()); arr->Set(i, obj); } @@ -86,6 +185,96 @@ void GetMapUnits(const Nan::FunctionCallbackInfo& info) info.GetReturnValue().Set(arr); } +void GetMapCollisionTable(const Nan::FunctionCallbackInfo& info) +{ + Isolate* isolate = info.GetIsolate(); + HandleScope handle_scope(isolate); + + if (info.Length() < 1) { + Nan::ThrowTypeError("Arg[0] must be boolean."); + return; + } + + bool loadall = info[0]->BooleanValue(); + + CGA::cga_map_cells_t cells; + if (!g_CGAInterface->GetMapCollisionTable(loadall, cells)) + { + Nan::ThrowError("RPC Invocation failed."); + return; + } + Local obj = Object::New(isolate); + obj->Set(String::NewFromUtf8(isolate, "x_bottom"), Integer::New(isolate, cells.x_bottom)); + obj->Set(String::NewFromUtf8(isolate, "y_bottom"), Integer::New(isolate, cells.y_bottom)); + obj->Set(String::NewFromUtf8(isolate, "x_size"), Integer::New(isolate, cells.x_size)); + obj->Set(String::NewFromUtf8(isolate, "y_size"), Integer::New(isolate, cells.y_size)); + Local arr = Array::New(isolate); + for (size_t i = 0; i < cells.cell.size(); ++i) + { + arr->Set(i, Integer::New(isolate, cells.cell[i])); + } + obj->Set(String::NewFromUtf8(isolate, "cell"), arr); + + info.GetReturnValue().Set(obj); +} + +void GetMapObjectTable(const Nan::FunctionCallbackInfo& info) +{ + Isolate* isolate = info.GetIsolate(); + HandleScope handle_scope(isolate); + + if (info.Length() < 1) { + Nan::ThrowTypeError("Arg[0] must be boolean."); + return; + } + + bool loadall = info[0]->BooleanValue(); + + CGA::cga_map_cells_t cells; + if (!g_CGAInterface->GetMapObjectTable(loadall, cells)) + { + Nan::ThrowError("RPC Invocation failed."); + return; + } + Local obj = Object::New(isolate); + obj->Set(String::NewFromUtf8(isolate, "x_bottom"), Integer::New(isolate, cells.x_bottom)); + obj->Set(String::NewFromUtf8(isolate, "y_bottom"), Integer::New(isolate, cells.y_bottom)); + obj->Set(String::NewFromUtf8(isolate, "x_size"), Integer::New(isolate, cells.x_size)); + obj->Set(String::NewFromUtf8(isolate, "y_size"), Integer::New(isolate, cells.y_size)); + Local arr = Array::New(isolate); + for (size_t i = 0; i < cells.cell.size(); ++i) + { + arr->Set(i, Integer::New(isolate, cells.cell[i])); + } + obj->Set(String::NewFromUtf8(isolate, "cell"), arr); + + info.GetReturnValue().Set(obj); +} + +void GetMoveHistory(const Nan::FunctionCallbackInfo& info) +{ + Isolate* isolate = info.GetIsolate(); + HandleScope handle_scope(isolate); + + std::vector v; + if (!g_CGAInterface->GetMoveHistory(v)) + { + Nan::ThrowError("RPC Invocation failed."); + return; + } + + Local arr = Array::New(isolate); + for (size_t i = 0; i < v.size(); ++i) + { + Local arr2 = Array::New(isolate); + arr2->Set(0, Integer::New(isolate, (v[i] >> 16) & 0xFFFF )); + arr2->Set(1, Integer::New(isolate, v[i] & 0xFFFF)); + arr->Set(i, arr2); + } + + info.GetReturnValue().Set(arr); +} + void WalkTo(const Nan::FunctionCallbackInfo& info) { Isolate* isolate = info.GetIsolate(); @@ -143,7 +332,7 @@ void IsMapCellPassable(const Nan::FunctionCallbackInfo& info) Nan::ThrowTypeError("Arg[0] must be x."); return; } - if (info.Length() < 2 || !info[1]->IsUndefined()) { + if (info.Length() < 2 || info[1]->IsUndefined()) { Nan::ThrowTypeError("Arg[1] must be y."); return; } @@ -223,7 +412,13 @@ class WalkToWorkerData m_y = y; m_fx = x * 64.0f; m_fy = y * 64.0f; - m_result = false; + m_dfx = x * 64.0f; + m_dfy = y * 64.0f; + m_mapindex = 0; + m_waitmapname = false; + m_waitmapindex = false; + m_waitxy = false; + m_result = false; m_reason = 0; m_worker.data = this; } @@ -232,6 +427,12 @@ class WalkToWorkerData int m_reason; int m_x, m_y; float m_fx, m_fy; + float m_dfx, m_dfy; + std::string m_map; + int m_mapindex; + bool m_waitmapname; + bool m_waitmapindex; + bool m_waitxy; Persistent m_callback; uv_work_t m_worker; }; @@ -240,23 +441,29 @@ void WalkToWorker(uv_work_t* req) { auto data = (WalkToWorkerData *)req->data; - std::string map, curmap; - if (!g_CGAInterface->GetMapName(map)) + std::string initmap, curmap; + + __time64_t lastStay = 0; + __time64_t lastStay2 = 0; + bool prevEnableWarpState = true; + float lastX = 0, lastY = 0; + float fx = 0, fy = 0; + + if (!g_CGAInterface->GetMapName(initmap)) { + data->m_reason = -1; return; + } - while (1) - { - if (!g_CGAInterface->GetMapName(curmap)) { - data->m_reason = -1; - return; - } + int initmap_index1 = 0, initmap_index2 = 0, initmap_index3 = 0; + int curmap_index1 = 0, curmap_index2 = 0, curmap_index3 = 0; - if (curmap != map) - { - data->m_result = true; - return; - } + if (!g_CGAInterface->GetMapIndex(initmap_index1, initmap_index2, initmap_index3)) { + data->m_reason = -1; + return; + } + while (1) + { float sx, sy; if (!g_CGAInterface->GetMoveSpeed(sx, sy)) { data->m_reason = -2; @@ -281,15 +488,83 @@ void WalkToWorker(uv_work_t* req) return; } - float fx, fy; - if (!g_CGAInterface->GetMapXYFloat(fx, fy)) { - data->m_reason = -5; - return; + if(data->m_waitmapname || data->m_waitmapindex) + { + //enable map warp entrance so that we can get in it + if (!prevEnableWarpState && !g_CGAInterface->FixMapWarpStuck(2)) { + data->m_reason = -8; + return; + } + prevEnableWarpState = true; } - - if (worldStatus == 9 && gameStatus == 3) + else { - if (sx == 0.0f && sy == 0.0f && fabs(fx - data->m_fx) < 0.001f && fabs(fy - data->m_fy) < 0.001f) + //disable map warp entrance so that we will never get in wrong map + if (prevEnableWarpState && !g_CGAInterface->FixMapWarpStuck(3)) { + data->m_reason = -8; + return; + } + prevEnableWarpState = false; + } + + //We are switching map + if (gameStatus != 3) { + Sleep(100); + continue; + } + + if (worldStatus == 9 && gameStatus == 3 && sx == 0.0f && sy == 0.0f) + { + if (!g_CGAInterface->GetMapXYFloat(fx, fy)) { + data->m_reason = -5; + return; + } + + if (!g_CGAInterface->GetMapName(curmap)) { + data->m_reason = -1; + return; + } + + if (!g_CGAInterface->GetMapIndex(curmap_index1, curmap_index2, curmap_index3)) { + data->m_reason = -1; + return; + } + + bool waiting_for_new_map = false; + + if(data->m_waitmapname) + { + waiting_for_new_map = true; + if (!data->m_map.empty() && curmap == data->m_map && !data->m_waitxy) + { + data->m_result = true; + return; + } + //for empty mapname, any new map is ok + else if (data->m_map.empty() && !(curmap_index3 == initmap_index3)) + { + data->m_result = true; + return; + } + } + else if (data->m_waitmapindex) + { + waiting_for_new_map = true; + if (curmap_index3 == data->m_mapindex) + { + data->m_result = true; + return; + } + } + + //we are not waiting for any new map, but the map has been changed, wtf... + if (!(curmap_index1 == initmap_index1 && curmap_index2 == initmap_index2 && curmap_index3 == initmap_index3)) + { + data->m_reason = 4; + return; + } + + if (fabs(fx - data->m_dfx) < 0.001f && fabs(fy - data->m_dfy) < 0.001f && (!waiting_for_new_map || data->m_waitxy)) { data->m_result = true; return; @@ -298,6 +573,27 @@ void WalkToWorker(uv_work_t* req) data->m_reason = -6; return; } + auto cur = _time64(NULL); + if(fx != lastX || fy != lastY) + { + lastX = fx; + lastY = fy; + lastStay = cur; + lastStay2 = cur; + } + else if (lastStay2 > 0 && cur - lastStay2 > 30) + { + data->m_reason = 3; + return; + } + else if(lastStay > 0 && cur - lastStay > 5) + { + lastStay = cur; + if (!g_CGAInterface->FixMapWarpStuck(1)) { + data->m_reason = -7; + return; + } + } } Sleep(100); @@ -309,6 +605,9 @@ void WalkToAfterWorker(uv_work_t* req, int status) Isolate* isolate = Isolate::GetCurrent(); HandleScope handle_scope(isolate); + //enable map warp entrance, that is, restore it to default... + g_CGAInterface->FixMapWarpStuck(2); + auto data = (WalkToWorkerData *)req->data; Handle argv[2]; @@ -326,30 +625,55 @@ void AsyncWalkTo(const Nan::FunctionCallbackInfo& info) Isolate* isolate = info.GetIsolate(); HandleScope handle_scope(isolate); - if (info.Length() < 1) { + if (info.Length() < 1 || !info[0]->IsInt32()) { Nan::ThrowTypeError("Arg[0] must be x."); return; } - if (info.Length() < 2) { + if (info.Length() < 2 || !info[1]->IsInt32()) { Nan::ThrowTypeError("Arg[1] must be y."); return; } - if (info.Length() < 3 || !info[2]->IsFunction()) { - Nan::ThrowTypeError("Arg[2] must be a function."); + if (info.Length() < 3) { + Nan::ThrowTypeError("Arg[2] must be desired map name(string) or mapindex (array) or null."); + return; + } + if (info.Length() < 4) { + Nan::ThrowTypeError("Arg[3] must be desired target x or null ."); + return; + } + if (info.Length() < 5) { + Nan::ThrowTypeError("Arg[4] must be desired target x or null."); + return; + } + if (info.Length() < 6 || !info[5]->IsFunction()) { + Nan::ThrowTypeError("Arg[5] must be a function."); return; } int x = (int)info[0]->IntegerValue(); int y = (int)info[1]->IntegerValue(); - if (!g_CGAInterface->WalkTo(x, y)) + auto callback = Local::Cast(info[5]); + + auto data = new WalkToWorkerData(x, y); + + if(info[2]->IsString()) { - Nan::ThrowError("RPC Invocation failed."); - return; + v8::String::Utf8Value str(info[2]->ToString()); + data->m_map = std::string(*str); + data->m_waitmapname = true; + } + else if(info[2]->IsInt32()) + { + data->m_mapindex = (int)info[2]->IntegerValue(); + data->m_waitmapindex = true; + } + if(info[3]->IsInt32() && info[4]->IsInt32()) + { + data->m_dfx = (int)info[3]->IntegerValue() * 64.0f; + data->m_dfy = (int)info[4]->IntegerValue() * 64.0f; + data->m_waitxy = true; } - auto callback = Local::Cast(info[2]); - - auto data = new WalkToWorkerData(x, y); data->m_callback.Reset(isolate, callback); uv_queue_work(uv_default_loop(), &data->m_worker, WalkToWorker, WalkToAfterWorker); @@ -360,10 +684,13 @@ class WaitMoveWorkerData public: WaitMoveWorkerData() { - m_flags = 0; + m_waitmapname = false; + m_waitmapindex = false; + m_waitxy = false; + m_fx = 0; m_fy = 0; - m_retry = 0; + m_timestart = 0; m_timeout = 0; m_delay = 0; m_result = false; @@ -374,13 +701,19 @@ class WaitMoveWorkerData { m_fx = x * 64.0f; m_fy = y * 64.0f; - m_flags |= 2; + m_waitxy = true; } void AddMapName(const std::string &mapname) { m_mapnames.push_back(mapname); - m_flags |= 1; + m_waitmapname = true; + } + + void AddMapIndex(int mapindex) + { + m_mapindices.push_back(mapindex); + m_waitmapindex = true; } void SetTimeout(int ms) @@ -394,12 +727,15 @@ class WaitMoveWorkerData } bool m_result; - int m_retry; int m_reason; - int m_flags; + bool m_waitmapname; + bool m_waitmapindex; + bool m_waitxy; + __time64_t m_timestart; int m_timeout, m_delay; float m_fx, m_fy; std::vector m_mapnames; + std::vector m_mapindices; Persistent m_callback; uv_work_t m_worker; }; @@ -408,63 +744,17 @@ void WaitMoveWorker(uv_work_t* req) { auto data = (WaitMoveWorkerData *)req->data; - std::string map, curmap; - if (!g_CGAInterface->GetMapName(map)) { - data->m_reason = -1; - return; - } + float fx = 0, fy = 0; + std::string curmap; + int curmap_index1, curmap_index2, curmap_index3; - float curfx, curfy; - if (!g_CGAInterface->GetMapXYFloat(curfx, curfy)) { - data->m_reason = -2; - return; - } + data->m_timestart = _time64(NULL); if(data->m_delay > 0) Sleep(data->m_delay); while (1) { - int flags = 0; - if (!g_CGAInterface->GetMapName(curmap)) { - data->m_reason = -3; - return; - } - - if (data->m_flags & 1) - { - for (size_t j = 0; j < data->m_mapnames.size(); ++j) - { - if (data->m_mapnames[j] == curmap) - { - flags |= 1; - break; - } - } - } - else - { - if (curmap != map) - flags |= 1; - } - - float fx, fy; - if (!g_CGAInterface->GetMapXYFloat(fx, fy)) { - data->m_reason = -4; - return; - } - - if (data->m_flags & 2) - { - if (fabs(fx - data->m_fx) < 0.01f && fabs(fy - data->m_fy) < 0.01f) - flags |= 2; - } - else - { - if (curfx != fx || curfy != fy) - flags |= 2; - } - float sx, sy; if (!g_CGAInterface->GetMoveSpeed(sx, sy)) { data->m_reason = -5; @@ -487,23 +777,59 @@ void WaitMoveWorker(uv_work_t* req) data->m_reason = 2; return; } - + if (worldStatus == 9 && gameStatus == 3 && sx == 0.0f && sy == 0.0f) { - if ((data->m_flags > 0 && (flags & data->m_flags) == data->m_flags)) - { - data->m_result = true; + if (!g_CGAInterface->GetMapXYFloat(fx, fy)) { + data->m_reason = -5; return; } - else if (data->m_flags == 0 && flags > 0) - { - data->m_result = true; + + if (!g_CGAInterface->GetMapName(curmap)) { + data->m_reason = -1; return; } + + if (!g_CGAInterface->GetMapIndex(curmap_index1, curmap_index2, curmap_index3)) { + data->m_reason = -1; + return; + } + + if(data->m_waitmapname) + { + for (size_t j = 0; j < data->m_mapnames.size(); ++j) + { + if (data->m_mapnames[j] == curmap) + { + data->m_result = true; + return; + } + } + } + else if (data->m_waitmapindex) + { + for (size_t j = 0; j < data->m_mapindices.size(); ++j) + { + if (data->m_mapindices[j] == curmap_index3) + { + data->m_result = true; + return; + } + } + } + else if (data->m_waitxy) + { + if (fabs(fx - data->m_fx) < 0.001f && fabs(fy - data->m_fy) < 0.001f) + { + data->m_result = true; + return; + } + } } - data->m_retry++; - if (data->m_timeout > 0 && data->m_retry * 100 > data->m_timeout) { + auto curtime = _time64(NULL); + + if (data->m_timeout > 0 && curtime > data->m_timestart + data->m_timeout) { data->m_reason = 3; return; } @@ -542,8 +868,6 @@ void AsyncWaitMovement(const Nan::FunctionCallbackInfo& info) Nan::ThrowTypeError("Arg[1] must be a function."); return; } - - int delay = 0, timeout = 0; Local obj = Local::Cast(info[0]); @@ -564,12 +888,26 @@ void AsyncWaitMovement(const Nan::FunctionCallbackInfo& info) std::string mapname(*str); data->AddMapName(mapname); } + else if (v_map_name->IsInt32()) { + int mapindex = (int)v_map_name->IntegerValue(); + data->AddMapIndex(mapindex); + } } } - + else if (v_map->IsString()) + { + v8::String::Utf8Value str(v_map->ToString()); + std::string mapname(*str); + data->AddMapName(mapname); + } + else if (v_map->IsInt32()) { + int mapindex = (int)v_map->IntegerValue(); + data->AddMapIndex(mapindex); + } + Local v_x = obj->Get(String::NewFromUtf8(isolate, "x")); Local v_y = obj->Get(String::NewFromUtf8(isolate, "y")); - if (!v_x->IsUndefined() && !v_x->IsUndefined()) + if (v_x->IsInt32() && v_y->IsInt32()) { int x = (int)v_x->IntegerValue(); int y = (int)v_y->IntegerValue(); @@ -577,12 +915,38 @@ void AsyncWaitMovement(const Nan::FunctionCallbackInfo& info) } Local v_delay = obj->Get(String::NewFromUtf8(isolate, "delay")); - if (!v_delay->IsUndefined()) + if (v_delay->IsInt32()) data->SetDelay((int)v_delay->IntegerValue()); Local v_timeout = obj->Get(String::NewFromUtf8(isolate, "timeout")); - if (!v_timeout->IsUndefined()) + if (v_timeout->IsInt32()) data->SetTimeout((int)v_timeout->IntegerValue()); uv_queue_work(uv_default_loop(), &data->m_worker, WaitMoveWorker, WaitMoveAfterWorker); +} + +void GetTeamPlayerInfo(const Nan::FunctionCallbackInfo& info) +{ + Isolate* isolate = info.GetIsolate(); + HandleScope handle_scope(isolate); + + CGA::cga_team_players_t plinfo; + if (!g_CGAInterface->GetTeamPlayerInfo(plinfo)) + { + Nan::ThrowError("RPC Invocation failed."); + return; + } + + Local arr = Array::New(isolate); + for (size_t i = 0; i < plinfo.size(); ++i) + { + Local obj = Object::New(isolate); + obj->Set(String::NewFromUtf8(isolate, "unit_id"), Integer::New(isolate, plinfo[i].unit_id)); + obj->Set(String::NewFromUtf8(isolate, "hp"), Integer::New(isolate, plinfo[i].hp)); + obj->Set(String::NewFromUtf8(isolate, "mp"), Integer::New(isolate, plinfo[i].mp)); + obj->Set(String::NewFromUtf8(isolate, "maxhp"), Integer::New(isolate, plinfo[i].maxhp)); + arr->Set(i, obj); + } + + info.GetReturnValue().Set(arr); } \ No newline at end of file diff --git a/CGANode/map.h b/CGANode/map.h index 2c26613..dffb4b8 100644 --- a/CGANode/map.h +++ b/CGANode/map.h @@ -1,13 +1,21 @@ #pragma once +void FixMapWarpStuck(const Nan::FunctionCallbackInfo& info); void GetMapXY(const Nan::FunctionCallbackInfo& info); void GetMapXYFloat(const Nan::FunctionCallbackInfo& info); +void GetMapIndex(const Nan::FunctionCallbackInfo& info); +void GetMoveSpeed(const Nan::FunctionCallbackInfo& info); void GetMapName(const Nan::FunctionCallbackInfo& info); +void GetMapUnits(const Nan::FunctionCallbackInfo& info); +void GetMapCollisionTable(const Nan::FunctionCallbackInfo& info); +void GetMapObjectTable(const Nan::FunctionCallbackInfo& info); +void GetMoveHistory(const Nan::FunctionCallbackInfo& info); void WalkTo(const Nan::FunctionCallbackInfo& info); void TurnTo(const Nan::FunctionCallbackInfo& info); void AsyncWalkTo(const Nan::FunctionCallbackInfo& info); -void GetMapUnits(const Nan::FunctionCallbackInfo& info); void AsyncWaitMovement(const Nan::FunctionCallbackInfo& info); void IsMapCellPassable(const Nan::FunctionCallbackInfo& info); void ForceMove(const Nan::FunctionCallbackInfo& info); -void ForceMoveTo(const Nan::FunctionCallbackInfo& info); \ No newline at end of file +void ForceMoveTo(const Nan::FunctionCallbackInfo& info); +void GetTeamPlayerInfo(const Nan::FunctionCallbackInfo& info); +void RequestDownloadMap(const Nan::FunctionCallbackInfo& info); \ No newline at end of file diff --git a/CGANode/npc.cc b/CGANode/npc.cc index 3d9cbd5..f1ca851 100644 --- a/CGANode/npc.cc +++ b/CGANode/npc.cc @@ -21,20 +21,57 @@ class NPCDialogNotifyData : public CBaseNotifyData CGA::cga_npc_dialog_t m_dlg; }; -boost::shared_mutex g_NPCDialog_Lock; +class NPCDialogCacheData +{ +public: + NPCDialogCacheData(const CGA::cga_npc_dialog_t &dlg, uint64_t time) : m_dlg(dlg), m_time(time) + { + + } + CGA::cga_npc_dialog_t m_dlg; + uint64_t m_time; +}; + +boost::shared_mutex g_NPCDialog_Lock; std::vector g_NPCDialog_Asyncs; +std::vector g_NPCDialog_Caches; -void NPCDialogNotify(CGA::cga_npc_dialog_t dlg) +void NPCDialogNotifyDoAsyncCall(const CGA::cga_npc_dialog_t &dlg) { - boost::unique_lock lock(g_NPCDialog_Lock); - for (size_t i = 0; i < g_NPCDialog_Asyncs.size(); ++i) + if (g_NPCDialog_Asyncs.size()) + { + for (size_t i = 0; i < g_NPCDialog_Asyncs.size(); ++i) + { + const auto data = g_NPCDialog_Asyncs[i]; + data->m_dlg = dlg; + data->m_result = true; + uv_async_send(data->m_async); + } + g_NPCDialog_Asyncs.clear(); + } + else { - const auto data = g_NPCDialog_Asyncs[i]; - data->m_dlg = dlg; - data->m_result = true; - uv_async_send(&data->m_async); + auto hrtime = uv_hrtime(); + for (auto &p = g_NPCDialog_Caches.begin(); p != g_NPCDialog_Caches.end(); ) + { + if (hrtime - (*p)->m_time > CGA_NOTIFY_MAX_CACHE_TIME) + { + delete *p; + p = g_NPCDialog_Caches.erase(p); + } + else + { + p++; + } + } + g_NPCDialog_Caches.emplace_back(new NPCDialogCacheData(dlg, uv_hrtime())); } - g_NPCDialog_Asyncs.clear(); +} + +void NPCDialogNotify(CGA::cga_npc_dialog_t dlg) +{ + boost::unique_lock lock(g_NPCDialog_Lock); + NPCDialogNotifyDoAsyncCall(dlg); } void NPCDialogAsyncCallBack(uv_async_t *handle) @@ -64,9 +101,9 @@ void NPCDialogAsyncCallBack(uv_async_t *handle) data->m_callback.Reset(); - uv_timer_stop(&data->m_timer); - uv_close((uv_handle_t*)handle, NULL); - uv_close((uv_handle_t*)&data->m_timer, NULL); + uv_timer_stop(data->m_timer); + uv_close((uv_handle_t*)handle, FreeUVHandleCallBack); + uv_close((uv_handle_t*)data->m_timer, FreeUVHandleCallBack); delete handle->data; } @@ -77,12 +114,7 @@ void NPCDialogTimerCallBack(uv_timer_t *handle) auto data = (NPCDialogNotifyData *)handle->data; - Handle argv[1]; - argv[0] = Nan::TypeError("Async callback timeout."); - - Local::New(isolate, data->m_callback)->Call(isolate->GetCurrentContext()->Global(), 1, argv); - - data->m_callback.Reset(); + bool asyncNotCalled = false; { boost::unique_lock lock(g_NPCDialog_Lock); @@ -90,16 +122,27 @@ void NPCDialogTimerCallBack(uv_timer_t *handle) { if (g_NPCDialog_Asyncs[i] == data) { + asyncNotCalled = true; g_NPCDialog_Asyncs.erase(g_NPCDialog_Asyncs.begin() + i); break; } } } - uv_timer_stop(handle); - uv_close((uv_handle_t*)&data->m_async, NULL); - uv_close((uv_handle_t*)handle, NULL); - delete handle->data; + if (asyncNotCalled) + { + Handle argv[1]; + argv[0] = Nan::TypeError("Async callback timeout."); + + Local::New(isolate, data->m_callback)->Call(isolate->GetCurrentContext()->Global(), 1, argv); + + data->m_callback.Reset(); + + uv_timer_stop(handle); + uv_close((uv_handle_t*)data->m_async, FreeUVHandleCallBack); + uv_close((uv_handle_t*)handle, FreeUVHandleCallBack); + delete handle->data; + } } void AsyncWaitNPCDialog(const Nan::FunctionCallbackInfo& info) @@ -112,6 +155,7 @@ void AsyncWaitNPCDialog(const Nan::FunctionCallbackInfo& info) Nan::ThrowTypeError("Arg[0] must be a function."); return; } + if (info.Length() >= 2 && !info[1]->IsUndefined()) { timeout = (int)info[1]->IntegerValue(); @@ -119,18 +163,37 @@ void AsyncWaitNPCDialog(const Nan::FunctionCallbackInfo& info) timeout = 0; } - boost::unique_lock lock(g_NPCDialog_Lock); - auto callback = Local::Cast(info[0]); NPCDialogNotifyData *data = new NPCDialogNotifyData(); data->m_callback.Reset(isolate, callback); - data->m_async.data = data; - data->m_timer.data = data; + data->m_async->data = data; + data->m_timer->data = data; + + { + boost::unique_lock lock(g_NPCDialog_Lock); - g_NPCDialog_Asyncs.push_back(data); + g_NPCDialog_Asyncs.emplace_back(data); + + auto hrtime = uv_hrtime(); + for (auto &p = g_NPCDialog_Caches.begin(); p != g_NPCDialog_Caches.end(); ) + { + if (hrtime - (*p)->m_time > CGA_NOTIFY_MAX_CACHE_TIME) + { + delete *p; + p = g_NPCDialog_Caches.erase(p); + } + else + { + NPCDialogNotifyDoAsyncCall((*p)->m_dlg); + delete *p; + g_NPCDialog_Caches.erase(p); + break; + } + } + } if(timeout) - uv_timer_start(&data->m_timer, NPCDialogTimerCallBack, timeout, 0); + uv_timer_start(data->m_timer, NPCDialogTimerCallBack, timeout, 0); } void ClickNPCDialog(const Nan::FunctionCallbackInfo& info) diff --git a/CGANode/work.cc b/CGANode/work.cc index b25830a..f82def4 100644 --- a/CGANode/work.cc +++ b/CGANode/work.cc @@ -16,41 +16,63 @@ class WorkingResultNotifyData : public CBaseNotifyData public: WorkingResultNotifyData() : CBaseNotifyData(WorkingResultAsyncCallBack) { - //m_permanent = false; - //m_sent = false; - //m_timeout = 0; } - //int m_timeout; - //bool m_sent; - //bool m_permanent; CGA::cga_working_result_t m_results; }; -boost::shared_mutex g_WorkingResult_Lock; -std::vector g_WorkingResult_Asyncs; -/* -static bool is_removable(WorkingResultNotifyData *data) +class WorkingResultCacheData { - return (data->m_sent && !data->m_permanent); -} -*/ -void WorkingResultNotify(CGA::cga_working_result_t results) +public: + WorkingResultCacheData(const CGA::cga_working_result_t &result, uint64_t time) : m_result(result), m_time(time) + { + + } + CGA::cga_working_result_t m_result; + uint64_t m_time; +}; + +boost::shared_mutex g_WorkingResult_Lock; +std::vector g_WorkingResult_Asyncs; +std::vector g_WorkingResult_Caches; + +void WorkingResultDoAsyncCall(const CGA::cga_working_result_t &results) { - boost::unique_lock lock(g_WorkingResult_Lock); - for (size_t i = 0; i < g_WorkingResult_Asyncs.size(); ++i) + if (g_WorkingResult_Asyncs.size()) { - const auto data = g_WorkingResult_Asyncs[i]; - //if (!data->m_sent) - //{ + for (size_t i = 0; i < g_WorkingResult_Asyncs.size(); ++i) + { + const auto data = g_WorkingResult_Asyncs[i]; + data->m_results = results; data->m_result = true; - //data->m_sent = true; - uv_async_send(&data->m_async); - //} + uv_async_send(data->m_async); + } + g_WorkingResult_Asyncs.clear(); + } + else + { + auto hrtime = uv_hrtime(); + for (auto &p = g_WorkingResult_Caches.begin(); p != g_WorkingResult_Caches.end(); ) + { + if (hrtime - (*p)->m_time > CGA_NOTIFY_MAX_CACHE_TIME) + { + delete *p; + p = g_WorkingResult_Caches.erase(p); + } + else + { + p++; + } + } + g_WorkingResult_Caches.emplace_back(new WorkingResultCacheData(results, uv_hrtime())); } - g_WorkingResult_Asyncs.clear(); - //g_WorkingResult_Asyncs.erase(std::remove_if(std::begin(g_WorkingResult_Asyncs), std::end(g_WorkingResult_Asyncs), is_removable), std::end(g_WorkingResult_Asyncs)); +} + +void WorkingResultNotify(CGA::cga_working_result_t results) +{ + boost::unique_lock lock(g_WorkingResult_Lock); + WorkingResultDoAsyncCall(results); } void WorkingResultAsyncCallBack(uv_async_t *handle) @@ -96,19 +118,12 @@ void WorkingResultAsyncCallBack(uv_async_t *handle) Local::New(isolate, data->m_callback)->Call(isolate->GetCurrentContext()->Global(), 1, argv); -// if (!data->m_permanent) -// { - data->m_callback.Reset(); + data->m_callback.Reset(); - uv_timer_stop(&data->m_timer); - uv_close((uv_handle_t*)handle, NULL); - uv_close((uv_handle_t*)&data->m_timer, NULL); - delete handle->data; -/* } - else - { - data->m_sent = false; - }*/ + uv_timer_stop(data->m_timer); + uv_close((uv_handle_t*)handle, FreeUVHandleCallBack); + uv_close((uv_handle_t*)data->m_timer, FreeUVHandleCallBack); + delete handle->data; } void WorkingResultTimerCallBack(uv_timer_t *handle) @@ -118,40 +133,35 @@ void WorkingResultTimerCallBack(uv_timer_t *handle) auto data = (WorkingResultNotifyData *)handle->data; - Handle argv[1]; - argv[0] = Nan::TypeError("Async callback timeout."); - - Local::New(isolate, data->m_callback)->Call(isolate->GetCurrentContext()->Global(), 1, argv); - - //if (!data->m_permanent) - //{ - data->m_callback.Reset(); + bool asyncNotCalled = false; + { + boost::unique_lock lock(g_WorkingResult_Lock); + for (size_t i = 0; i < g_WorkingResult_Asyncs.size(); ++i) { - boost::unique_lock lock(g_WorkingResult_Lock); - for (size_t i = 0; i < g_WorkingResult_Asyncs.size(); ++i) + if (g_WorkingResult_Asyncs[i] == data) { - if (g_WorkingResult_Asyncs[i] == data) - { - g_WorkingResult_Asyncs.erase(g_WorkingResult_Asyncs.begin() + i); - break; - } + asyncNotCalled = true; + g_WorkingResult_Asyncs.erase(g_WorkingResult_Asyncs.begin() + i); + break; } } + } + + if (asyncNotCalled) + { + Handle argv[1]; + argv[0] = Nan::TypeError("Async callback timeout."); + + Local::New(isolate, data->m_callback)->Call(isolate->GetCurrentContext()->Global(), 1, argv); + + data->m_callback.Reset(); uv_timer_stop(handle); - uv_close((uv_handle_t*)&data->m_async, NULL); - uv_close((uv_handle_t*)handle, NULL); + uv_close((uv_handle_t*)data->m_async, FreeUVHandleCallBack); + uv_close((uv_handle_t*)handle, FreeUVHandleCallBack); delete handle->data; -/* } - else - { - if (data->m_timeout > 0) - { - uv_timer_start(&data->m_timer, WorkingResultTimerCallBack, data->m_timeout, 0); - data->m_sent = false; - } - }*/ + } } void AsyncWaitWorkingResult(const Nan::FunctionCallbackInfo& info) @@ -170,25 +180,38 @@ void AsyncWaitWorkingResult(const Nan::FunctionCallbackInfo& info) if (timeout < 0) timeout = 0; } - /*bool permanent = false; - if (info.Length() >= 3 && info[2]->IsBoolean()) - { - permanent = info[2]->BooleanValue(); - }*/ - - boost::unique_lock lock(g_WorkingResult_Lock); auto callback = Local::Cast(info[0]); WorkingResultNotifyData *data = new WorkingResultNotifyData(); data->m_callback.Reset(isolate, callback); - data->m_async.data = data; - data->m_timer.data = data; - //data->m_timeout = timeout; - //data->m_permanent = permanent; + data->m_async->data = data; + data->m_timer->data = data; + + { + boost::unique_lock lock(g_WorkingResult_Lock); + + g_WorkingResult_Asyncs.push_back(data); + + auto hrtime = uv_hrtime(); + for (auto &p = g_WorkingResult_Caches.begin(); p != g_WorkingResult_Caches.end(); ) + { + if (hrtime - (*p)->m_time > CGA_NOTIFY_MAX_CACHE_TIME) + { + delete *p; + p = g_WorkingResult_Caches.erase(p); + } + else + { + WorkingResultDoAsyncCall((*p)->m_result); + delete *p; + g_WorkingResult_Caches.erase(p); + break; + } + } + } - g_WorkingResult_Asyncs.push_back(data); if (timeout) - uv_timer_start(&data->m_timer, WorkingResultTimerCallBack, timeout, 0); + uv_timer_start(data->m_timer, WorkingResultTimerCallBack, timeout, 0); } void StartWork(const Nan::FunctionCallbackInfo& info) @@ -230,11 +253,11 @@ void CraftItem(const Nan::FunctionCallbackInfo& info) return; } if (info.Length() < 2 || info[1]->IsUndefined()) { - Nan::ThrowTypeError("Arg[1] must be sub_index."); + Nan::ThrowTypeError("Arg[1] must be subskill_index."); return; } if (info.Length() < 3 || info[2]->IsUndefined()) { - Nan::ThrowTypeError("Arg[2] must be sub_index."); + Nan::ThrowTypeError("Arg[2] must be sub_type."); return; } if (info.Length() < 4 || !info[3]->IsArray()) { @@ -247,7 +270,7 @@ void CraftItem(const Nan::FunctionCallbackInfo& info) craft.sub_type = (int)info[2]->IntegerValue(); Local arr = Local::Cast(info[3]); - for (uint32_t i = 0; i < arr->Length(); ++i) + for (uint32_t i = 0; i < min(arr->Length(), 6); ++i) { Local v_itempos = arr->Get(i); craft.itempos[i] = (int)v_itempos->IntegerValue(); @@ -288,4 +311,23 @@ void AssessItem(const Nan::FunctionCallbackInfo& info) } info.GetReturnValue().Set(result); +} + +void SetImmediateDoneWork(const Nan::FunctionCallbackInfo& info) +{ + Isolate* isolate = info.GetIsolate(); + HandleScope handle_scope(isolate); + + if (info.Length() < 1 || !info[0]->IsBoolean()) { + Nan::ThrowTypeError("Arg[0] must be boolean."); + return; + } + + bool enable = (int)info[0]->BooleanValue(); + + if (!g_CGAInterface->SetImmediateDoneWork(enable)) + { + Nan::ThrowError("RPC Invocation failed."); + return; + } } \ No newline at end of file diff --git a/CGANode/work.h b/CGANode/work.h index 3603014..731b1d9 100644 --- a/CGANode/work.h +++ b/CGANode/work.h @@ -3,4 +3,5 @@ void StartWork(const Nan::FunctionCallbackInfo& info); void CraftItem(const Nan::FunctionCallbackInfo& info); void AssessItem(const Nan::FunctionCallbackInfo& info); -void AsyncWaitWorkingResult(const Nan::FunctionCallbackInfo& info); \ No newline at end of file +void AsyncWaitWorkingResult(const Nan::FunctionCallbackInfo& info); +void SetImmediateDoneWork(const Nan::FunctionCallbackInfo& info); \ No newline at end of file diff --git a/cgahook/cgahook.vcxproj b/cgahook/cgahook.vcxproj index 36d836b..fb114e2 100644 --- a/cgahook/cgahook.vcxproj +++ b/cgahook/cgahook.vcxproj @@ -14,7 +14,6 @@ {1159C2B4-D6BA-4167-9B7E-FB6C75004394} Win32Proj cgahook - 10.0.17763.0 CGAHook @@ -56,7 +55,7 @@ Level3 Disabled _CRT_SECURE_NO_WARNINGS;DETOURS_32BIT;DETOURS_X86;WIN32;_DEBUG;_WINDOWS;_USRDLL;CGAHOOK_EXPORTS;%(PreprocessorDefinitions) - ../boost;../rest_rpc/;../rest_rpc/spdlog/include;../rest_rpc/iguana;../rest_rpc/iguana/third_party/msgpack/include;../Detours/ + ../boost_1_63_0;../rest_rpc/;../rest_rpc/spdlog/include;../rest_rpc/iguana;../rest_rpc/iguana/third_party/msgpack/include;../Detours/ -D_SCL_SECURE_NO_WARNINGS %(AdditionalOptions) MultiThreadedDebug 4091 @@ -64,7 +63,7 @@ Windows true - ../boost/stage/lib + ../boost_1_63_0/stage/lib @@ -76,7 +75,7 @@ true true _CRT_SECURE_NO_WARNINGS;DETOURS_32BIT;DETOURS_X86;WIN32;NDEBUG;_WINDOWS;_USRDLL;CGAHOOK_EXPORTS;%(PreprocessorDefinitions) - ../boost;../rest_rpc/;../rest_rpc/spdlog/include;../rest_rpc/iguana;../rest_rpc/iguana/third_party/msgpack/include;../Detours/ + ../boost_1_63_0;../rest_rpc/;../rest_rpc/spdlog/include;../rest_rpc/iguana;../rest_rpc/iguana/third_party/msgpack/include;../Detours/ -D_SCL_SECURE_NO_WARNINGS %(AdditionalOptions) MultiThreaded 4091 @@ -86,7 +85,7 @@ true true true - ../boost/stage/lib + ../boost_1_63_0/stage/lib copy $(OutDir)$(TargetName)$(TargetExt) "..\build\CGAHook.dll" @@ -95,6 +94,7 @@ + diff --git a/cgahook/dump.cpp b/cgahook/dump.cpp new file mode 100644 index 0000000..a492199 --- /dev/null +++ b/cgahook/dump.cpp @@ -0,0 +1,27 @@ +extern "C" +{ +#pragma warning (disable:4005) +#include +} + +#include +#pragma comment(lib,"dbghelp.lib") + +LONG WINAPI MinidumpCallback(EXCEPTION_POINTERS* pException) +{ + HANDLE hDumpFile = CreateFile(L"minidump.mdmp", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (hDumpFile != INVALID_HANDLE_VALUE) { + + MINIDUMP_EXCEPTION_INFORMATION dumpInfo; + dumpInfo.ExceptionPointers = pException; + dumpInfo.ThreadId = GetCurrentThreadId(); + dumpInfo.ClientPointers = TRUE; + + MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, (MINIDUMP_TYPE)(MiniDumpNormal | MiniDumpWithFullMemory), &dumpInfo, NULL, NULL); + CloseHandle(hDumpFile); + } + + //MessageBox(NULL, L"A fatal error occured, sorry but we have to terminate this program.\nSee minidump for more information.", L"Fatal Error", MB_ICONWARNING); + + return EXCEPTION_EXECUTE_HANDLER; +} diff --git a/cgahook/gameservice.cpp b/cgahook/gameservice.cpp index a11f98a..2fbbdb2 100644 --- a/cgahook/gameservice.cpp +++ b/cgahook/gameservice.cpp @@ -17,7 +17,7 @@ const int index2player_flags[] = { void WriteLog(LPCSTR fmt, ...) { - char buffer[256]; + char buffer[4096]; va_list argptr; int cnt; va_start(argptr, fmt); @@ -28,6 +28,27 @@ void WriteLog(LPCSTR fmt, ...) if (fp) { setlocale(LC_ALL, "chs"); + + SYSTEMTIME tm; + GetLocalTime(&tm); + fprintf(fp, "%02d:%02d:%02d.%03d\t", tm.wHour, tm.wMinute, tm.wSecond, tm.wMilliseconds); + + fputs(buffer, fp); + fclose(fp); + } +} + +void WriteLog2(LPCSTR buffer) +{ + FILE *fp = fopen("D:\\cga_log.txt", "a+"); + if (fp) + { + setlocale(LC_ALL, "chs"); + + SYSTEMTIME tm; + GetLocalTime(&tm); + fprintf(fp, "%02d:%02d:%02d.%03d\t", tm.wHour, tm.wMinute, tm.wSecond, tm.wMilliseconds); + fputs(buffer, fp); fclose(fp); } @@ -56,20 +77,159 @@ void CXorValue::set(int value) key2 = value ^ key1; } +char *NET_FindDelimeter(const char *src, char deli) +{ + char *p2; + for (auto p = (char *)src; ; p = p2 + 1) + { + while (1) + { + if (!*p) + return 0; + if (*p >= 128 || *p == 255) + break; + if (*p == deli) + return p + 1; + ++p; + } + p2 = p + 1; + if (!*(char *)p2) + break; + } + return NULL; +} + +int NET_SubStrDelimeter(const char *src, char deli, int len, char *buf) +{ + int i; + + for (i = 0; i < len; ++i) + { + if (src[i] >= 128 || src[i] == 255) + { + buf[i] = src[i]; + ++i; + if (i >= len) + break; + buf[i] = src[i]; + if (!buf[i]) + return 1; + } + else + { + if (src[i] == deli) + { + buf[i] = 0; + return 0; + } + buf[i] = src[i]; + if (!buf[i]) + return 1; + } + } + buf[i] = 0; + return 1; +} + +int NET_ParseDelimeter(const char *src, char deli, int position, int buflen, char *buf) +{ + auto p = (char *)src; + for (int i = 0; i < position - 1 && p; ++i) + p = NET_FindDelimeter(p, deli); + + if (p) + return NET_SubStrDelimeter(p, deli, buflen, buf); + + *buf = 0; + return 1; +} + +int NET_ParseInteger(const char *src, char deli, int position) +{ + char buf[128] = {0}; + + NET_ParseDelimeter(src, deli, position, 127, buf); + if (buf[0]) + return atoi((const char *)buf); + + return -1; +} + +int NET_ParseHexInteger(const char *src, char deli, int position) +{ + char buf[128] = { 0 }; + + NET_ParseDelimeter(src, deli, position, 127, buf); + if (buf[0]) { + int res; + if(1 == sscanf(buf, "%X", &res)) + return res; + } + + return -1; +} + +char NET_EscapeCharFromTable(char ch) +{ + static char table[] = "n\nc,z|y\\"; + + for (int i = 0; i < 4; ++i) + { + if (table[2 * i] == ch) + return table[2 * i + 1]; + } + return ch; +} + +char *NET_EscapeStringEx(char *src) +{ + size_t len; // kr00_4@1 + int v2; // ST18_4@4 + int v4; // [sp+14h] [bp-8h]@1 + + len = strlen(src); + v4 = 0; + for (size_t i = 0; i < len; ++i) + { + if (src[i] & 0x80) + { + src[v4] = src[i]; + v2 = v4 + 1; + ++i; + src[v2] = src[i]; + v4 = v2 + 1; + } + else if (src[i] == '\\') + { + ++i; + src[v4++] = NET_EscapeCharFromTable(src[i]); + } + else + { + src[v4++] = src[i]; + } + } + src[v4] = 0; + return src; +} + void CGA_NotifyBattleAction(int flags); void CGA_NotifyPlayerMenu(const cga_player_menu_items_t &players); void CGA_NotifyUnitMenu(const cga_unit_menu_items_t &units); void CGA_NotifyNPCDialog(const cga_npc_dialog_t &dlg); void CGA_NotifyWorkingResult(const CGA::cga_working_result_t &result); void CGA_NotifyChatMsg(const CGA::cga_chat_msg_t &msg); +void CGA_NotifyTradeStuffs(const CGA::cga_trade_stuff_info_t &msg); +void CGA_NotifyTradeDialog(const CGA::cga_trade_dialog_t &msg); +void CGA_NotifyTradeState(int state); void CGAService::NewBATTLE_PlayerAction() { - int prevPlayerStatus = GetBattlePlayerStatus(); + int prevPlayerStatus = *g_btl_player_status; BATTLE_PlayerAction(); - int playerStatus = GetBattlePlayerStatus(); + int playerStatus = *g_btl_player_status; if (prevPlayerStatus == 2 && playerStatus == 0) { @@ -81,7 +241,7 @@ void CGAService::NewBATTLE_PlayerAction() int flags = FL_BATTLE_ACTION_ISPLAYER; if (m_btl_double_action) flags |= FL_BATTLE_ACTION_ISDOUBLE; - if (GetBattleSkillPerformed()) + if (*g_btl_skill_performed) flags |= FL_BATTLE_ACTION_ISSKILLPERFORMED; CGA_NotifyBattleAction(flags); @@ -92,7 +252,7 @@ void CGAService::NewBATTLE_PlayerAction() int flags = 0; if (m_btl_double_action) flags |= FL_BATTLE_ACTION_ISDOUBLE; - if (GetBattleSkillPerformed()) + if (*g_btl_skill_performed) flags |= FL_BATTLE_ACTION_ISSKILLPERFORMED; CGA_NotifyBattleAction(flags); @@ -104,8 +264,699 @@ void __cdecl NewBATTLE_PlayerAction() g_CGAService.NewBATTLE_PlayerAction(); } +void CGAService::NewNET_ParseTradeItemsPackets(int a1, const char *buf) +{ + WriteLog("NewNET_ParseTradeItemsPackets\n"); + + NET_ParseTradeItemsPackets(a1, buf); + + cga_trade_stuff_info_t info(TRADE_STUFFS_ITEM); + + char buffer[1024]; + + for (int i = 0; ; ++i) + { + int position = 14 * i + 1; + int itempos = NET_ParseInteger(buf, '|', position); + + if (NET_ParseDelimeter(buf, 124, position + 1, 255, buffer) == 1) + break; + NET_EscapeStringEx(buffer); + std::string itemname = boost::locale::conv::to_utf(buffer, "GBK"); + + NET_ParseDelimeter(buf, 124, position + 3, 767, buffer); + NET_EscapeStringEx(buffer); + std::string itemattr = boost::locale::conv::to_utf(buffer, "GBK"); + + NET_ParseDelimeter(buf, 124, position + 13, 255, buffer); + NET_EscapeStringEx(buffer); + std::string itemattr2 = boost::locale::conv::to_utf(buffer, "GBK"); + + int image_id = NET_ParseInteger(buf, '|', position + 4); + int level = NET_ParseInteger(buf, '|', position + 8); + int type = NET_ParseInteger(buf, '|', position + 9); + int item_id = NET_ParseInteger(buf, '|', position + 10); + int count = NET_ParseInteger(buf, '|', position + 12); + + info.items.emplace_back( + itemname, + itemattr, + itemattr2, + std::string(), + std::string(), + item_id, + count, + itempos, + level, + type, + false + ); + } + + CGA_NotifyTradeStuffs(info); +} + +void __cdecl NewNET_ParseTradeItemsPackets(int a1, const char *buf) +{ + g_CGAService.NewNET_ParseTradeItemsPackets(a1, buf); +} + +void CGAService::NewNET_ParseTradePetPackets(int a1, int index, const char *buf) +{ + NET_ParseTradePetPackets(a1, index, buf); + + WriteLog("NewNET_ParseTradePetPackets\n"); + + WriteLog2(buf); + + char name[256]; + + if (0 == NET_ParseDelimeter(buf, '|', 1, 255, name)) + { + cga_trade_stuff_info_t info(TRADE_STUFFS_PET); + + NET_EscapeStringEx(name); + info.pet.index = index; + info.pet.name = boost::locale::conv::to_utf(name, "GBK"); + info.pet.level = NET_ParseInteger(buf, '|', 2); + info.pet.detail.points_remain = NET_ParseInteger(buf, '|', 3); + info.pet.race = NET_ParseInteger(buf, '|', 4); + info.pet.maxhp = NET_ParseInteger(buf, '|', 5); + info.pet.maxmp = NET_ParseInteger(buf, '|', 6); + info.pet.detail.points_endurance = NET_ParseInteger(buf, '|', 7); + info.pet.detail.points_strength = NET_ParseInteger(buf, '|', 8); + info.pet.detail.points_defense = NET_ParseInteger(buf, '|', 9); + info.pet.detail.points_agility = NET_ParseInteger(buf, '|', 10); + info.pet.detail.points_magical = NET_ParseInteger(buf, '|', 11); + info.pet.loyality = NET_ParseInteger(buf, '|', 12); + info.pet.skill_count = NET_ParseInteger(buf, '|', 13); + if (0 == NET_ParseDelimeter(buf, '|', 14, 255, name)) + { + NET_EscapeStringEx(name); + info.pet.realname = boost::locale::conv::to_utf(name, "GBK"); + } + info.pet.image_id = NET_ParseInteger(buf, '|', 15); + info.pet.detail.value_attack = NET_ParseInteger(buf, '|', 16); + info.pet.detail.value_defensive = NET_ParseInteger(buf, '|', 17); + info.pet.detail.value_agility = NET_ParseInteger(buf, '|', 18); + info.pet.detail.value_spirit = NET_ParseInteger(buf, '|', 19); + info.pet.detail.value_recovery = NET_ParseInteger(buf, '|', 20); + info.pet.detail.element_earth = NET_ParseInteger(buf, '|', 21); + info.pet.detail.element_water = NET_ParseInteger(buf, '|', 22); + info.pet.detail.element_fire = NET_ParseInteger(buf, '|', 23); + info.pet.detail.element_wind = NET_ParseInteger(buf, '|', 24); + + CGA_NotifyTradeStuffs(info); + } +} + +void __cdecl NewNET_ParseTradePetPackets(int a1, int index, const char *buf) +{ + g_CGAService.NewNET_ParseTradePetPackets(a1, index, buf); +} + +void CGAService::NewNET_ParseTradePetSkillPackets(int a1, int index, const char *buf) +{ + NET_ParseTradePetSkillPackets(a1, index, buf); + + WriteLog("NewNET_ParseTradePetSkillPackets\n"); + + WriteLog2(buf); + + cga_trade_stuff_info_t info(TRADE_STUFFS_PETSKILL); + + char name[256]; + + info.petskills.index = index; + + for (int i = 0; i < 10; ++i) + { + if (1 != NET_ParseDelimeter(buf, '|', i + 1, 255, name)) + { + NET_EscapeStringEx(name); + + info.petskills.skills.emplace_back(boost::locale::conv::to_utf(name, "GBK")); + } + } + + CGA_NotifyTradeStuffs(info); +} + +void __cdecl NewNET_ParseTradePetSkillPackets(int a1, int index, const char *buf) +{ + g_CGAService.NewNET_ParseTradePetSkillPackets(a1, index, buf); +} + +void CGAService::NewNET_ParseTradeGoldPackets(int a1, int gold) +{ + WriteLog("NewNET_ParseTradeGoldPackets\n"); + + NET_ParseTradeGoldPackets(a1, gold); + + cga_trade_stuff_info_t info(TRADE_STUFFS_GOLD); + + info.gold = gold; + + CGA_NotifyTradeStuffs(info); +} + +void __cdecl NewNET_ParseTradeGoldPackets(int a1, int gold) +{ + g_CGAService.NewNET_ParseTradeGoldPackets(a1, gold); +} + +void CGAService::NewNET_ParseTradePlayers(int a1, const char *src, char *src2) +{ + WriteLog("NewNET_ParseTradePlayers\n"); + + NET_ParseTradePlayers(a1, src, src2); + + char buf[256]; + int numplayers = 0; + int position = 1; + + cga_player_menu_items_t players; + + for (int i = 0; i < 10; ++i) + { + if (numplayers >= 10) + break; + if (NET_ParseDelimeter(src, '|', position, 255, buf) == 1) + break; + NET_EscapeStringEx(buf); + + std::string playername = boost::locale::conv::to_utf(buf, "GBK"); + + if (NET_ParseDelimeter(src2, '|', position, 255, buf) == 1) + break; + NET_EscapeStringEx(buf); + + int playerlevel = atoi(buf); + + players.emplace_back( + playername, + playerlevel, + i + ); + + ++position; + ++numplayers; + } + + m_player_menu_type = PLAYER_MENU_TRADE; + + CGA_NotifyPlayerMenu(players); +} + +void __cdecl NewNET_ParseTradePlayers(int a1, const char *src, char *src2) +{ + g_CGAService.NewNET_ParseTradePlayers(a1, src, src2); +} + +void CGAService::NewNET_ParseHealPlayers(int a1, const char *src) +{ + WriteLog("NewNET_ParseHealPlayers %s\n", src); + + NET_ParseHealPlayers(a1, src); + + char buf[256]; + int numplayers = 0; + int position = 1; + + cga_player_menu_items_t players; + + std::string playername; + + playername = boost::locale::conv::to_utf((*g_playerBase)->name, "GBK"); + + players.emplace_back( + playername, + 0, + numplayers + ); + + numplayers++; + + for (int i = 0; i < 5; ++i) + { + if (g_team_player_base[i].valid && + g_team_player_base[i].unit_id != (*g_playerBase)->unitid) + { + playername = boost::locale::conv::to_utf(g_team_player_base[i].name, "GBK"); + if (playername.empty()) + { + if (g_team_player_base[i].actor) { + playername = boost::locale::conv::to_utf((char *)g_team_player_base[i].actor + 196, "GBK"); + } + + /*for (int j = 0; j < *g_unit_count; ++j) + { + if (g_map_units[j].valid && g_map_units[j].unit_id == g_team_player_base[i].unit_id) + { + playername = boost::locale::conv::to_utf(g_map_units[j].unit_name, "GBK"); + break; + } + }*/ + } + + players.emplace_back( + playername, + 1, + numplayers + ); + numplayers++; + } + } + + for (int i = 0; i < 10; ++i) + { + if (numplayers >= 10) + break; + if (NET_ParseDelimeter(src, '|', position, 255, buf) == 1) + break; + NET_EscapeStringEx(buf); + + playername = boost::locale::conv::to_utf(buf, "GBK"); + + int type = NET_ParseInteger(src, '|', position); + if (type == 1) + break; + + players.emplace_back( + playername, + type ? 3 : 2, + numplayers + ); + + ++position; + ++numplayers; + } + + m_player_menu_type = PLAYER_MENU_HEAL; + + CGA_NotifyPlayerMenu(players); +} + +void __cdecl NewNET_ParseHealPlayers(int a1, const char *src) +{ + g_CGAService.NewNET_ParseHealPlayers(a1, src); +} + +void CGAService::NewNET_ParseHealUnits(int a1, const char *src) +{ + WriteLog("NewNET_ParseHealUnits\n"); + + NET_ParseHealUnits(a1, src); + + char buf[128]; + int numunits = 0; + std::string unitname; + + cga_unit_menu_items_t units; + + if (g_heal_player_menu_type[*g_heal_player_menu_select]) + { + int i = 0; + int position = 1; + while (i < 6) + { + if (NET_ParseDelimeter(src, '|', position++, 127, buf) == 1) + break; + if (*g_heal_menu_type != 1 || i) + { + NET_EscapeStringEx(buf); + unitname = boost::locale::conv::to_utf(buf, "GBK"); + int level = NET_ParseInteger(src, '|', position++); + int health = NET_ParseInteger(src, '|', position++); + int hp = NET_ParseInteger(src, '|', position++); + int maxhp = NET_ParseInteger(src, '|', position++); + int mp = NET_ParseInteger(src, '|', position++); + int maxmp = NET_ParseInteger(src, '|', position++); + int color = 0; + switch (g_heal_player_menu_type[*g_heal_player_menu_select]) + { + case 1: + if (i) + color = 5; + else + color = 1; + break; + case 2: + if (i) + color = 6; + else + color = 2; + break; + case 3: + color = 3; + break; + } + + units.emplace_back( + unitname, + level, + health, + hp, + maxhp, + mp, + maxmp, + color, + numunits + ); + numunits++; + } + else + { + position += 6; + ++numunits; + } + } + } + else + { + if (*g_heal_menu_type != 1) + { + unitname = boost::locale::conv::to_utf((*g_playerBase)->name, "GBK"); + units.emplace_back( + unitname, + (*g_playerBase)->level, + (*g_playerBase)->health, + (*g_playerBase)->hp.decode(), + (*g_playerBase)->maxhp.decode(), + (*g_playerBase)->mp.decode(), + (*g_playerBase)->maxmp.decode(), + 0, + numunits + ); + numunits++; + } + for (int i = 0; i < 5; ++i) + { + if (g_pet_base[i].level) + { + unitname = boost::locale::conv::to_utf(g_pet_base[i].name, "GBK"); + if (unitname.empty()) + unitname = boost::locale::conv::to_utf(g_pet_base[i].realname, "GBK"); + units.emplace_back( + unitname, + g_pet_base[i].level, + g_pet_base[i].health, + g_pet_base[i].hp.decode(), + g_pet_base[i].maxhp.decode(), + g_pet_base[i].mp.decode(), + g_pet_base[i].maxmp.decode(), + 4, + numunits + ); + numunits++; + } + } + } + + m_unit_menu_type = UNIT_MENU_HEAL; + + CGA_NotifyUnitMenu(units); +} + +void __cdecl NewNET_ParseHealUnits(int a1, const char *src) +{ + g_CGAService.NewNET_ParseHealUnits(a1, src); +} + +void CGAService::NewNET_ParseItemPlayers(int a1, const char *src) +{ + WriteLog("NewNET_ParseItemPlayers\n"); + + NET_ParseItemPlayers(a1, src); + + char buf[256]; + int numplayers = 0; + int position = 1; + + cga_player_menu_items_t players; + + std::string playername; + + playername = boost::locale::conv::to_utf((*g_playerBase)->name, "GBK"); + + players.emplace_back( + playername, + 0, + numplayers + ); + + numplayers++; + + for (int i = 0; i < 5; ++i) + { + if (g_team_player_base[i].valid && + g_team_player_base[i].unit_id != (*g_playerBase)->unitid) + { + playername = boost::locale::conv::to_utf(g_team_player_base[i].name, "GBK"); + + if (playername.empty()) + { + if (g_team_player_base[i].actor) { + playername = boost::locale::conv::to_utf((char *)g_team_player_base[i].actor + 196, "GBK"); + } + /*for (int j = 0; j < *g_unit_count; ++j) + { + if (g_map_units[j].valid && g_map_units[j].unit_id == g_team_player_base[i].unit_id) + { + playername = boost::locale::conv::to_utf(g_map_units[j].unit_name, "GBK"); + break; + } + }*/ + } + + players.emplace_back( + playername, + 1, + numplayers + ); + numplayers++; + } + } + + for (int i = 0; i < 10; ++i) + { + if (numplayers >= 10) + break; + if (NET_ParseDelimeter(src, '|', position, 255, buf) == 1) + break; + NET_EscapeStringEx(buf); + + playername = boost::locale::conv::to_utf(buf, "GBK"); + + int type = NET_ParseInteger(src, '|', position); + if (type == 1) + break; + + players.emplace_back( + playername, + type ? 3 : 2, + numplayers + ); + + ++position; + ++numplayers; + } + + m_player_menu_type = PLAYER_MENU_ITEM; + + CGA_NotifyPlayerMenu(players); +} + +void __cdecl NewNET_ParseItemPlayers(int a1, const char *src) +{ + g_CGAService.NewNET_ParseItemPlayers(a1, src); +} + +void CGAService::NewNET_ParseItemUnits(int a1, const char *src) +{ + WriteLog("NewNET_ParseItemUnits\n"); + + NET_ParseItemUnits(a1, src); + + char buf[128]; + int numunits = 0; + std::string unitname; + + cga_unit_menu_items_t units; + + if (g_item_player_menu_type[10 * (*g_item_player_select)]) + { + int i = 0; + int position = 1; + while (i < 6) + { + if (NET_ParseDelimeter(src, '|', position++, 127, buf) == 1) + break; + + NET_EscapeStringEx(buf); + unitname = boost::locale::conv::to_utf(buf, "GBK"); + int level = NET_ParseInteger(src, '|', position++); + int health = NET_ParseInteger(src, '|', position++); + int hp = NET_ParseInteger(src, '|', position++); + int maxhp = NET_ParseInteger(src, '|', position++); + int mp = NET_ParseInteger(src, '|', position++); + int maxmp = NET_ParseInteger(src, '|', position++); + int color = 0; + switch (g_heal_player_menu_type[*g_heal_player_menu_select]) + { + case 1: + if (i) + color = 5; + else + color = 1; + break; + case 2: + if (i) + color = 6; + else + color = 2; + break; + case 3: + color = 3; + break; + } + + units.emplace_back( + unitname, + level, + health, + hp, + maxhp, + mp, + maxmp, + color, + numunits + ); + numunits++; + } + } + else + { + unitname = boost::locale::conv::to_utf((*g_playerBase)->name, "GBK"); + units.emplace_back( + unitname, + (*g_playerBase)->level, + (*g_playerBase)->health, + (*g_playerBase)->hp.decode(), + (*g_playerBase)->maxhp.decode(), + (*g_playerBase)->mp.decode(), + (*g_playerBase)->maxmp.decode(), + 0, + numunits + ); + numunits++; + + for (int i = 0; i < 5; ++i) + { + if (g_pet_base[i].level) + { + unitname = boost::locale::conv::to_utf(g_pet_base[i].name, "GBK"); + if(unitname.empty()) + unitname = boost::locale::conv::to_utf(g_pet_base[i].realname, "GBK"); + units.emplace_back( + unitname, + g_pet_base[i].level, + g_pet_base[i].health, + g_pet_base[i].hp.decode(), + g_pet_base[i].maxhp.decode(), + g_pet_base[i].mp.decode(), + g_pet_base[i].maxmp.decode(), + 4, + numunits + ); + numunits++; + } + } + } + + m_unit_menu_type = UNIT_MENU_ITEM; + + CGA_NotifyUnitMenu(units); +} + +void __cdecl NewNET_ParseItemUnits(int a1, const char *src) +{ + g_CGAService.NewNET_ParseItemUnits(a1, src); +} + +bool CGAService::ParseIsKnockout(const char *buf) +{ + return false; + + char *p = (char *)buf + 2; + + while (p) + { + p = strstr(p, "SKL|"); + if (p) + { + p += 4; + char *src = strstr(p, "|a"); + char *dst = strstr(p, "|d"); + if (src && dst) + { + int srcpos = -1, dstpos = -1; + sscanf(src + 2, "%X", &srcpos); + sscanf(dst + 2, "%X", &dstpos); + + if (dstpos >= 0 && dstpos < 20 && m_battle_units[dstpos].exist + && dstpos == *g_btl_player_pos)//0 == strcmp(m_battle_units[dstpos].name, (*g_playerBase)->name)) + { + char temp[32]; + sprintf(temp, "|d%X|", dstpos); + char *flags = dst + strlen(temp); + int flagsv = -1; + sscanf(flags, "%X", &flagsv); + if (flagsv != -1 && (flagsv & 0x20060) == 0x20060) { + WriteLog("knockout %X\n", flagsv); + return true; + } + } + } + } + } + return false; +} + +bool CGAService::ParseIsEscape(const char *buf) +{ + char *p = (char *)buf + 2; + + while (p) + { + p = strstr(p, "ESC|"); + if (p) + { + p += 4; + char *pos = strstr(p, "|e"); + char *sta = strstr(p, "|f"); + if (pos && sta) + { + int srcpos = -1, status = -1; + sscanf(pos + 2, "%X", &srcpos); + sscanf(sta + 2, "%X", &status); + + if (srcpos >= 0 && srcpos < 20 && m_battle_units[srcpos].exist + && srcpos == *g_btl_player_pos)//0 == strcmp(m_battle_units[srcpos].name, (*g_playerBase)->name) && status == 1) + { + WriteLog("escaped %X\n", srcpos); + return true; + } + } + } + } + return false; +} + void CGAService::NewNET_ParseBattlePackets(int a1, const char *buf) { + WriteLog("NewNET_ParseBattlePackets %s\n", buf); + if (*buf == 'M') { if (m_btl_highspeed_enable) @@ -113,9 +964,18 @@ void CGAService::NewNET_ParseBattlePackets(int a1, const char *buf) if (strstr(buf, "END|"))//battle end { NET_ParseBattlePackets(a1, "M|END|"); + + CGA_NotifyBattleAction(FL_BATTLE_ACTION_END); } else { + if (ParseIsKnockout(buf) || ParseIsEscape(buf)) + { + NET_ParseBattlePackets(a1, "M|END|"); + CGA_NotifyBattleAction(FL_BATTLE_ACTION_END); + return; + } + NET_ParseBattlePackets(a1, "M|"); } return; @@ -291,7 +1151,7 @@ void __cdecl NewNET_ParseWorkingResult(int a1, int success, int type, const char void CGAService::NewNET_ParseChatMsg(int a1, int unitid, const char *buf, int color, int size) { - WriteLog("u=%d, buf=%s, color=%d, size=%d\n", unitid, buf, color, size); + WriteLog("NewNET_ParseChatMsg u=%d, buf=%s, color=%d, size=%d\n", unitid, buf, color, size); if (buf[0] == 'P' && buf[1] == '|') { @@ -307,16 +1167,105 @@ void __cdecl NewNET_ParseChatMsg(int a1, int unitid, const char *buf, int color, g_CGAService.NewNET_ParseChatMsg(a1, unitid, buf, color, size); } +void CGAService::NewNET_ParseSysMsg(int a1, const char *buf) +{ + char temp[4096]; + strcpy(temp, buf); + NET_EscapeStringEx(temp); + cga_chat_msg_t msg(-1, boost::locale::conv::to_utf(temp, "GBK"), 0, 0); + CGA_NotifyChatMsg(msg); + + WriteLog("NewNET_ParseSysMsg %s\n", temp); + + NET_ParseSysMsg(a1, buf); +} + +void __cdecl NewNET_ParseSysMsg(int a1, const char *buf) +{ + g_CGAService.NewNET_ParseSysMsg(a1, buf); +} + +void CGAService::NewNET_ParseReadyTrade() +{ + WriteLog("NewNET_ParseConfirmTrade\n"); + + NET_ParseReadyTrade(); + + CGA_NotifyTradeState(TRADE_STATE_READY); +} + +void __cdecl NewNET_ParseReadyTrade() +{ + g_CGAService.NewNET_ParseReadyTrade(); +} + + +void CGAService::NewNET_ParseConfirmTrade(int a1, int a2) +{ + WriteLog("NewNET_ParseConfirmTrade\n"); + + NET_ParseConfirmTrade(a1, a2); + + if(a2 == 1) + CGA_NotifyTradeState(TRADE_STATE_CONFIRM); + else if (a2 == 0) + CGA_NotifyTradeState(TRADE_STATE_CANCEL); + else if (a2 == 2) + CGA_NotifyTradeState(TRADE_STATE_SUCCEED); +} + +void __cdecl NewNET_ParseConfirmTrade(int a1, int a2) +{ + g_CGAService.NewNET_ParseConfirmTrade(a1, a2); +} + +void __cdecl NewNET_ParseMeetEnemy(int a1, int a2, int a3) +{ + g_CGAService.NET_ParseMeetEnemy(a1, a2, a3); + + WriteLog("NewNET_ParseMeetEnemy %d %d %d\n", a1, a2, a3); +} + void __cdecl NewR_DrawText(int a1) { g_CGAService.R_DrawText(a1); - g_CGAService.DrawBattleInfo(); + g_CGAService.DrawCustomText(); } void CGAService::NewMove_Player() { (*g_playerBase)->move_speed = m_move_speed; + auto x = g_player_xpos->decode(); + auto y = g_player_ypos->decode(); + + if (*g_disable_move == 0 && + *g_map_xf == x * 64.0 && + *g_map_yf == y * 64.0) + { + DWORD xy = ((x & 0xFFFF) << 16) | (y & 0xFFFF); + bool bAddToHistory = false; + if (!m_move_history.empty()) + { + if (xy != m_move_history.back()) + { + bAddToHistory = true; + } + } + else + { + bAddToHistory = true; + } + + if (bAddToHistory) + { + if (m_move_history.size() > 128) + m_move_history.pop_front(); + + m_move_history.push_back(xy); + } + } + if (m_move_to & 2) { m_move_to &= ~2; @@ -370,97 +1319,6 @@ void __cdecl NewMove_Player() g_CGAService.NewMove_Player(); } -void CGAService::NewUI_PlayerMenuShowup(int a1) -{ - UI_PlayerMenuShowup(a1); - - if (a1 == -1) - { - cga_player_menu_items_t players; - - int count = *g_player_menu_count - *g_player_menu_begin; - players.reserve(count); - for (int i = 0; i < count; ++i) - { - players.emplace_back( - boost::locale::conv::to_utf((*g_player_menu_name)[i], "GBK"), - (*g_player_menu_color)[i], - *g_player_menu_begin + i - ); - } - - CGA_NotifyPlayerMenu(players); - } -} - -void __cdecl NewUI_PlayerMenuShowup(int a1) -{ - g_CGAService.NewUI_PlayerMenuShowup(a1); -} - -int CGAService::NewUI_PlayerMenuMouseEvent(int widget_index, char flags) -{ - if (m_menu_item_selected == 1 && m_menu_item_select_index + 14 == widget_index) - { - flags = 2; - m_menu_item_selected = 0; - } - return UI_PlayerMenuMouseEvent(widget_index, flags); -} - -int __cdecl NewUI_PlayerMenuMouseEvent(int widget_index, char flags) -{ - return g_CGAService.NewUI_PlayerMenuMouseEvent(widget_index, flags); -} - -void CGAService::NewUI_UnitMenuShowup(int a1) -{ - UI_UnitMenuShowup(a1); - - if (a1 == -1) - { - cga_unit_menu_items_t units; - int count = *g_unit_menu_count; - units.reserve(count); - for (int i = 0; i < count; ++i) - { - units.emplace_back( - boost::locale::conv::to_utf((*g_unit_menu_base)[i].name, "GBK"), - (*g_unit_menu_base)[i].level, - (*g_unit_menu_base)[i].health, - (*g_unit_menu_base)[i].hp, - (*g_unit_menu_base)[i].maxhp, - (*g_unit_menu_base)[i].mp, - (*g_unit_menu_base)[i].maxmp, - (*g_unit_menu_base)[i].color, - *g_unit_menu_begin + i - ); - } - - CGA_NotifyUnitMenu(units); - } -} - -void __cdecl NewUI_UnitMenuShowup(int a1) -{ - g_CGAService.NewUI_UnitMenuShowup(a1); -} - -int CGAService::NewUI_UnitMenuMouseEvent(int widget_index, char flags) -{ - if (m_menu_item_selected == 2 && m_menu_item_select_index + 16 == widget_index) - { - flags = 2; - m_menu_item_selected = 0; - } - return UI_UnitMenuMouseEvent(widget_index, flags); -} - -int __cdecl NewUI_UnitMenuMouseEvent(int widget_index, char flags) -{ - return g_CGAService.NewUI_UnitMenuMouseEvent(widget_index, flags); -} - void CGAService::NewNPC_ShowDialogInternal(int type, int options, int dlgid, int objid, const char *message) { NPC_ShowDialogInternal(type, options, dlgid, objid, message); @@ -541,13 +1399,27 @@ int __cdecl NewUI_IsMouseInRect(int a1, int a2, int a3, int a4, int a5) int __cdecl NewUI_HandleLearnSkillConfirmMouseEvent(int index, char flags) { - if (g_CGAService.m_ui_learn_skill_confirm == 1) + if (g_CGAService.m_ui_learn_skill_confirm == 1) + { + flags = 2; + g_CGAService.m_ui_learn_skill_confirm = -1; + } + + return g_CGAService.UI_HandleLearnSkillConfirmMouseEvent(index, flags); +} + +int __cdecl NewUI_HandleForgetSkillMouseEvent(int index, char flags) +{ + if (g_CGAService.m_ui_forget_skill_index != -1) { flags = 2; - g_CGAService.m_ui_learn_skill_confirm = -1; + index = g_CGAService.m_ui_forget_skill_index + 0x45; + g_CGAService.m_ui_forget_skill_index = -1; + + return g_CGAService.UI_HandleForgetSkillMouseEvent(index, flags); } - return g_CGAService.UI_HandleLearnSkillConfirmMouseEvent(index, flags); + return g_CGAService.UI_HandleForgetSkillMouseEvent(index, flags); } int CGAService::NewUI_HandleEnablePlayerFlagsMouseEvent(int index, char flags) @@ -584,7 +1456,7 @@ int CGAService::NewUI_HandleCraftItemSlotMouseEvent(int index, char flags) --m_ui_craftdialog_additemcount; - for (int i = 0; i < 5; ++i) + for (int i = 0; i < 6; ++i) { if (m_ui_craftdialog_additem[i] != -1) { @@ -631,18 +1503,24 @@ int CGAService::NewUI_HandleCraftItemButtonMouseEvent(int index, char flags) if (m_ui_craftdialog_click_begin && (*g_craft_step == 0 || *g_craft_step == 3)) { m_ui_craftdialog_click_begin = false; - flags |= 2; + flags |= 2; char backup_acc = *g_work_accelerate; char backup_percent = g_work_accelerate_percent[0]; - *g_work_accelerate = 1; - g_work_accelerate_percent[0] = m_work_acceleration; + if (m_work_acceleration) + { + *g_work_accelerate = 1; + g_work_accelerate_percent[0] = m_work_acceleration; + } int result = UI_HandleCraftItemButtonMouseEvent(index, flags); - *g_work_accelerate = backup_acc; - g_work_accelerate_percent[0] = backup_percent; + if (m_work_acceleration) + { + *g_work_accelerate = backup_acc; + g_work_accelerate_percent[0] = backup_percent; + } return result; } @@ -655,6 +1533,72 @@ int __cdecl NewUI_HandleCraftItemButtonMouseEvent(int index, char flags) return g_CGAService.NewUI_HandleCraftItemButtonMouseEvent(index, flags); } +int __cdecl NewUI_PlaySwitchAnim(int a1, char a2, float a3) +{ + if (g_CGAService.m_ui_noswitchanim) + return 1; + + return g_CGAService.UI_PlaySwitchAnim(a1, a2, a3); +} + +void CGAService::NewUI_OpenTradeDialog(const char *playerName, int playerLevel) +{ + UI_OpenTradeDialog(playerName, playerLevel); + + auto name = boost::locale::conv::to_utf(playerName, "GBK"); + + cga_trade_dialog_t dlg(name, playerLevel); + + CGA_NotifyTradeDialog(dlg); +} + +void __cdecl NewUI_OpenTradeDialog(const char *playerName, int playerLevel) +{ + g_CGAService.NewUI_OpenTradeDialog(playerName, playerLevel); +} + +void __cdecl NewActor_SetAnimation(void *actor, int anim, int a3) +{ + auto v3 = *(void **)((char *)actor + 12); + if (v3 == NULL || IsBadReadPtr(v3, 0x38))//crash fix + return; + + g_CGAService.Actor_SetAnimation(actor, anim, a3); +} + +int __cdecl NewIsMapObjectEntrance(int xpos, int ypos) +{ + if(g_CGAService.m_move_checkwarp) + return g_CGAService.IsMapObjectEntrance(xpos, ypos); + + return 0; +} + +void CGAService::NewNET_WritePrepareCraftItemPacket_cgitem(int a1, int a2) +{ + if (m_work_immediate == true) + { + *g_craft_done_tick = 0; + } + else + { + NET_WritePrepareCraftItemPacket_cgitem(a1, a2); + } +} + +void __cdecl NewNET_WritePrepareCraftItemPacket_cgitem(int a1, int a2) +{ + g_CGAService.NewNET_WritePrepareCraftItemPacket_cgitem(a1, a2); +} + +int __cdecl NewGetBattleUnitDistance(void *a1, float a2, float a3) +{ + if (g_CGAService.m_ui_noswitchanim) + return 0; + + return g_CGAService.GetBattleUnitDistance(a1, a2, a3); +} + ULONG MH_GetModuleSize(HMODULE hModule) { return ((IMAGE_NT_HEADERS *)((DWORD)hModule + ((IMAGE_DOS_HEADER *)hModule)->e_lfanew))->OptionalHeader.SizeOfImage; @@ -731,15 +1675,16 @@ void CGAService::Initialize(game_type type) g_logback = CONVERT_GAMEVAR(int *, 0x957160); g_item_cur_using = CONVERT_GAMEVAR(int *, 0x8E3ACC); - g_item_menu_players = CONVERT_GAMEVAR(item_menu_player_t *, 0x94C2F8); + /*g_item_menu_players = CONVERT_GAMEVAR(item_menu_player_t *, 0x94C2F8); g_item_menu_player_count = CONVERT_GAMEVAR(int *, 0x8E3C38); g_item_menu_units = CONVERT_GAMEVAR(item_menu_unit_t *, 0x946870); g_item_menu_unit_count = CONVERT_GAMEVAR(int *, 0x94BAC8); g_player_menu_clickable = CONVERT_GAMEVAR(char *, 0x8C3909); - g_unit_menu_clickable = CONVERT_GAMEVAR(char *, 0x8B9187); + g_unit_menu_clickable = CONVERT_GAMEVAR(char *, 0x8B9187);*/ g_unit_count = CONVERT_GAMEVAR(int *, 0x245774); g_map_units = CONVERT_GAMEVAR(map_unit_t *, 0x245B34); + g_npc_dialog_show = CONVERT_GAMEVAR(int *, 0x90162C); g_npc_dialog_type = CONVERT_GAMEVAR(int *, 0x2130FC); g_npc_dialog_option = CONVERT_GAMEVAR(int *, 0x95520C); @@ -753,7 +1698,6 @@ void CGAService::Initialize(game_type type) g_map_x_size = CONVERT_GAMEVAR(short *, 0x81EF14); g_map_y_size = CONVERT_GAMEVAR(short *, 0x806164); g_map_collision_table = CONVERT_GAMEVAR(short *, 0x5D6178); - g_mutex = CONVERT_GAMEVAR(HANDLE *, 0x5D5D1C); Sys_CheckModify = CONVERT_GAMEVAR(char(__cdecl *)(const char *), 0x1448B0); @@ -771,13 +1715,13 @@ void CGAService::Initialize(game_type type) NET_WriteLogbackPacket_cgse = CONVERT_GAMEVAR(void(__cdecl *)(void *, int, const char *), 0x6ACD0); Move_Player = CONVERT_GAMEVAR(void(__cdecl *)(), 0x89070); CL_MoveItemEx = CONVERT_GAMEVAR(void(__cdecl *)(int), 0);//TODO - UI_ClickLogout = CONVERT_GAMEVAR(void(__cdecl *)(int, int), 0x40E0); - UI_PlayerMenuSelect = CONVERT_GAMEVAR(int(__cdecl **)(int, int), 0);//TODO - UI_UnitMenuSelect = CONVERT_GAMEVAR(int(__cdecl **)(int, int), 0);//TODO - UI_PlayerMenuShowup = CONVERT_GAMEVAR(int(__cdecl *)(int), 0x1A190); - UI_PlayerMenuMouseEvent = CONVERT_GAMEVAR(int(__cdecl *)(int, char), 0);//TODO - UI_UnitMenuShowup = CONVERT_GAMEVAR(int(__cdecl *)(int), 0x8B5F0); - UI_UnitMenuMouseEvent = CONVERT_GAMEVAR(int(__cdecl *)(int, char), 0x8B7C0); + UI_HandleLogoutMouseEvent = CONVERT_GAMEVAR(int(__cdecl *)(int, char), 0x40E0); + //UI_PlayerMenuSelect = CONVERT_GAMEVAR(int(__cdecl **)(int, int), 0);//TODO + //UI_UnitMenuSelect = CONVERT_GAMEVAR(int(__cdecl **)(int, int), 0);//TODO + //UI_PlayerMenuShowup = CONVERT_GAMEVAR(int(__cdecl *)(int), 0x1A190); + //UI_PlayerMenuMouseEvent = CONVERT_GAMEVAR(int(__cdecl *)(int, char), 0);//TODO + //UI_UnitMenuShowup = CONVERT_GAMEVAR(int(__cdecl *)(int), 0x8B5F0); + //UI_UnitMenuMouseEvent = CONVERT_GAMEVAR(int(__cdecl *)(int, char), 0x8B7C0); NPC_ShowDialogInternal = CONVERT_GAMEVAR(void(__cdecl *)(int, int, int, int, const char *), 0xED060); NPC_ClickDialog = CONVERT_GAMEVAR(int(__cdecl *)(int, int, int, char), 0x28A0); NPC_ClickExchangeDialog = CONVERT_GAMEVAR(void(__cdecl *)(int), 0);//TODO @@ -792,8 +1736,10 @@ void CGAService::Initialize(game_type type) g_playerBase_cgitem = CONVERT_GAMEVAR(playerbase_t *, 0xE12C30);//ok g_playerBase = &g_playerBase_cgitem; g_bank_item_base = CONVERT_GAMEVAR(bank_item_info_t *, 0x8E4C38);//ok + g_npcdlg_item_base = CONVERT_GAMEVAR(npcdlg_item_info_t *, 0x8D3198);//ok g_player_name = CONVERT_GAMEVAR(char *, 0xBDB998);//ok g_pet_base = CONVERT_GAMEVAR(pet_t *, 0xE109F8);//ok + g_player_remain_points = CONVERT_GAMEVAR(int *, 0x8E3C50);//ok g_pet_id = CONVERT_GAMEVAR(int *, 0x8B4164);//ok g_job_name = CONVERT_GAMEVAR(char *, 0xC1CD48);//ok g_skill_base = CONVERT_GAMEVAR(skill_t *, 0xC1CD64);//ok @@ -822,36 +1768,30 @@ void CGAService::Initialize(game_type type) g_btl_buffer_index = CONVERT_GAMEVAR(int *, 0x23B828);//ok g_btl_round_count = CONVERT_GAMEVAR(int *, 0x23FA1C);//ok g_btl_player_pos = CONVERT_GAMEVAR(int *, 0x23FA94);//ok + g_btl_petskill_allowbit = CONVERT_GAMEVAR(int *, 0x23F9BC);//ok g_btl_skill_allowbit = CONVERT_GAMEVAR(int *, 0x23FA28);//ok + g_btl_weapon_allowbit = CONVERT_GAMEVAR(int *, 0x23FA9C);//ok g_btl_player_status = CONVERT_GAMEVAR(int *, 0x23FA44);//ok g_btl_petid = CONVERT_GAMEVAR(int *, 0x23F9C0);//ok g_btl_action_done = CONVERT_GAMEVAR(int *, 0x23F924);//ok g_btl_skill_performed = CONVERT_GAMEVAR(int *, 0x23F9F8);//ok g_btl_round_endtick = CONVERT_GAMEVAR(unsigned int *, 0x23F92C);//ok + g_btl_unit_base = CONVERT_GAMEVAR(char *, 0x235798);//ok g_net_socket = CONVERT_GAMEVAR(int *, 0xBD7108);//ok g_item_base = CONVERT_GAMEVAR(item_t *, 0x8C70B0);//ok g_item_info_base = CONVERT_GAMEVAR(item_info_t *, 0xE12DCC);//ok + g_trade_item_base = CONVERT_GAMEVAR(item_t *, 0x8BF2C0);//ok g_logback = CONVERT_GAMEVAR(int *, 0xB12AA4);//ok g_item_cur_using = CONVERT_GAMEVAR(int *, 0x8CEFFC);//ok - g_item_menu_players = CONVERT_GAMEVAR(item_menu_player_t *, 0x92F638);//ok - g_item_menu_player_count = CONVERT_GAMEVAR(int *, 0x8CF00C);//ok - g_item_menu_units = CONVERT_GAMEVAR(item_menu_unit_t *, 0x929BA0);//ok - g_item_menu_unit_count = CONVERT_GAMEVAR(int *, 0x92EE00);//ok - g_player_menu_clickable = CONVERT_GAMEVAR(char *, 0x8BE8C1);//ok - g_unit_menu_clickable = CONVERT_GAMEVAR(char *, 0x8B415F);//ok - - g_unit_menu_base = CONVERT_GAMEVAR(unit_menu_t **, 0xD38E60 - 0x400000);//ok - g_unit_menu_count = CONVERT_GAMEVAR(int *, 0xCB4140 - 0x400000);//ok - g_unit_menu_begin = CONVERT_GAMEVAR(int *, 0xCE4C34 - 0x400000);//ok - g_unit_count = CONVERT_GAMEVAR(int *, 0x23FB0C);//ok - g_player_menu_name = CONVERT_GAMEVAR(char ***, 0xD29734 - 0x400000);//ok - g_player_menu_color = CONVERT_GAMEVAR(char **, 0xCE4AA0 - 0x400000);//ok - g_player_menu_count = CONVERT_GAMEVAR(int *, 0xCE4C28 - 0x400000);//ok - g_player_menu_begin = CONVERT_GAMEVAR(int *, 0xCDBB24 - 0x400000);//ok + g_trade_item_array = CONVERT_GAMEVAR(char *, 0x8CF6B0); + g_trade_pet_array = CONVERT_GAMEVAR(char *, 0x8BE8BC); + g_trade_gold = CONVERT_GAMEVAR(int *, 0x938570); + + g_unit_count = CONVERT_GAMEVAR(int *, 0x23FB0C);//ok g_map_units = CONVERT_GAMEVAR(map_unit_t *, 0x240008);//ok g_npc_dialog_show = CONVERT_GAMEVAR(int *, 0x8E4A98);//ok @@ -861,28 +1801,68 @@ void CGAService::Initialize(game_type type) g_npc_dialog_npcid = CONVERT_GAMEVAR(int *, 0x8CF6A0);//ok g_work_basedelay = CONVERT_GAMEVAR(int *, 0x8B4190);//ok + g_disable_move = CONVERT_GAMEVAR(short *, 0x801144);//ok + g_is_moving = CONVERT_GAMEVAR(int *, 0x8AB2F4);//ok + g_do_switch_map = CONVERT_GAMEVAR(int *, 0x8AB2F8);//ok + g_switch_map_frames = CONVERT_GAMEVAR(int *, 0x8AB2FC);//ok + g_switch_map_type = CONVERT_GAMEVAR(int *, 0x8AB300);//ok g_map_x_bottom = CONVERT_GAMEVAR(short *, 0x819ED4);//ok g_map_y_bottom = CONVERT_GAMEVAR(short *, 0x819ED0);//ok g_map_x_size = CONVERT_GAMEVAR(short *, 0x801134);//ok g_map_y_size = CONVERT_GAMEVAR(short *, 0x819EE4);//ok g_map_collision_table = CONVERT_GAMEVAR(short *, 0x5D1148);//ok - + g_map_index1 = CONVERT_GAMEVAR(int *, 0x81B344); + g_map_index2 = CONVERT_GAMEVAR(int *, 0x5D1130); + g_map_index3 = CONVERT_GAMEVAR(int *, 0x80114C); + g_map_object_table = CONVERT_GAMEVAR(short *, 0x835370); + g_healing_skill_index = CONVERT_GAMEVAR(int *, 0x8E481C);//ok g_healing_subskill_index = CONVERT_GAMEVAR(int *, 0x8E3C44);//ok g_ui_craftdialog_additem_count = CONVERT_GAMEVAR(char *, 0xF12880-0x400000);//ok + g_heal_player_menu_type = CONVERT_GAMEVAR(int *, 0x8E3C54);//ok + g_heal_player_menu_select = CONVERT_GAMEVAR(int *, 0x929D48);//ok + g_heal_menu_type = CONVERT_GAMEVAR(int *, 0x92DA00);//ok + g_item_player_menu_type = CONVERT_GAMEVAR(short *, 0x92F638);//ok + g_item_player_select = CONVERT_GAMEVAR(int *, 0x9298B0);//ok + g_craft_step = CONVERT_GAMEVAR(int *, 0xCBF15E - 0x400000);//ok g_work_accelerate = CONVERT_GAMEVAR(char *, 0x63FFFE - 0x400000);//ok; g_work_accelerate_percent = CONVERT_GAMEVAR(char *, 0x627E8C - 0x400000);//ok; + g_craft_done_tick = CONVERT_GAMEVAR(int *, 0xCCF858 - 0x400000);//ok g_mutex = CONVERT_GAMEVAR(HANDLE *, 0x5D0D00);//ok + g_resolution_width = CONVERT_GAMEVAR(int *, 0x2091EC);//ok + g_resolution_height = CONVERT_GAMEVAR(int *, 0x2091F0);//ok + + g_is_in_team = CONVERT_GAMEVAR(short *, 0xE109F0);//ok + g_team_flags = CONVERT_GAMEVAR(short *, 0xE12DB2);//ok + g_team_player_base = CONVERT_GAMEVAR(team_player_t *, 0xCC25B0);//ok + g_title_table = CONVERT_GAMEVAR(char *, 0xCBFFF0);//ok + + g_enableflags = CONVERT_GAMEVAR(short *, 0xE12DBC);//ok Sys_CheckModify = CONVERT_GAMEVAR(char(__cdecl *)(const char *), 0x1BD030);//ok COMMON_PlaySound = CONVERT_GAMEVAR(void(__cdecl *)(int, int, int), 0x1B1570);//ok BATTLE_PlayerAction = CONVERT_GAMEVAR(void(__cdecl *)(), 0xD83A0);//ok + NET_ParseTradeItemsPackets = CONVERT_GAMEVAR(void(__cdecl *)(int, const char *), 0x183CD0);//ok + NET_ParseTradePetPackets = CONVERT_GAMEVAR(void(__cdecl *)(int, int, const char *), 0x183D00);//ok + NET_ParseTradePetSkillPackets = CONVERT_GAMEVAR(void(__cdecl *)(int, int, const char *), 0x183D30);//ok + NET_ParseTradeGoldPackets = CONVERT_GAMEVAR(void(__cdecl *)(int, int), 0x183CA0);//ok + NET_ParseTradePlayers = CONVERT_GAMEVAR(void(__cdecl *)(int , const char *, char *), 0x183BE0);//ok + NET_ParseHealPlayers = CONVERT_GAMEVAR(void (__cdecl *)(int , const char *), 0x183B10); + NET_ParseHealUnits = CONVERT_GAMEVAR(void(__cdecl *)(int, const char *), 0x183B40); + NET_ParseItemPlayers = CONVERT_GAMEVAR(void (__cdecl *)(int , const char *), 0x183B70); + NET_ParseItemUnits = CONVERT_GAMEVAR(void(__cdecl *)(int, const char *), 0x183BA0); + NET_ParseMeetEnemy = CONVERT_GAMEVAR(void(__cdecl *)(int a1, int a2, int a3), 0x181FB0); + NET_ParseBattlePackets = CONVERT_GAMEVAR(void(__cdecl *)(int, const char *), 0x1822A0);//ok NET_ParseWorkingResult = CONVERT_GAMEVAR(void(__cdecl *)(int , int , int , const char *), 0x181140);//ok NET_ParseChatMsg = CONVERT_GAMEVAR(void(__cdecl *)(int, int, const char *, int, int), 0x1814F0);//ok + NET_ParseSysMsg = CONVERT_GAMEVAR(void(__cdecl *)(int a1, const char *buf), 0x181AA0);//ok + NET_ParseReadyTrade = CONVERT_GAMEVAR(void(__cdecl *)(), 0x183C70); + NET_ParseConfirmTrade = CONVERT_GAMEVAR(void(__cdecl *)(int a1, int a2), 0x183DB0); + R_DrawText = CONVERT_GAMEVAR(void(__cdecl *)(int), 0x79490);//ok g_pGameBase = CONVERT_GAMEVAR(void *, 0x2BBA7C);//ok NET_WritePacket3_cgitem = CONVERT_GAMEVAR(void(__cdecl *)(int, int, int, int, int, int, const char *), 0x189530);//ok @@ -893,16 +1873,25 @@ void CGAService::Initialize(game_type type) NET_WriteDropItemPacket_cgitem = CONVERT_GAMEVAR(void(__cdecl *)(int, int, int, int), 0x187950);//ok NET_WriteMovePacket_cgitem = CONVERT_GAMEVAR(void(__cdecl *)(int, int, const char *), 0x181240);//ok NET_WriteWorkPacket_cgitem = CONVERT_GAMEVAR(void(__cdecl *)(int, int, int, int, const char *), 0x188E50);//ok - + NET_WriteJoinTeamPacket_cgitem = CONVERT_GAMEVAR(void(__cdecl *)(int, int, int, int), 0x1888B0);//ok + NET_WriteKickTeamPacket_cgitem = CONVERT_GAMEVAR(void(__cdecl *)(int), 0x1912E0);//ok + NET_WriteTradePacket_cgitem = CONVERT_GAMEVAR(void(__cdecl *)(int), 0x188F10);//ok + //trade arg2=itemlist 8|0|10|1, arg3=petlist 3|0|4|1 arg4=gold + NET_WriteTraceAddItemPacket_cgitem = CONVERT_GAMEVAR(void(__cdecl *)(int, const char *, const char *, int), 0x188FB0);//ok + NET_WriteTradeConfirmPacket_cgitem = CONVERT_GAMEVAR(void(__cdecl *)(int), 0x1890A0);//ok + NET_WriteTradeRefusePacket_cgitem = CONVERT_GAMEVAR(void(__cdecl *)(int), 0x189050);//ok + NET_WriteExchangeCardPacket_cgitem = CONVERT_GAMEVAR(void(__cdecl *)(int, int, int), 0x187E90);//ok + NET_WritePKPacket_cgitem = CONVERT_GAMEVAR(void(__cdecl *)(int, int, int), 0x187540);//ok + NET_WriteOpenHealDialog_cgitem = CONVERT_GAMEVAR(void(__cdecl *)(int, int), 0x188AA0);//ok + NET_WriteMoveItemPacket_cgitem = CONVERT_GAMEVAR(void(__cdecl *)(int, int, int, int), 0x187B30); + NET_WriteRequestDownloadMapPacket_cgitem = CONVERT_GAMEVAR(void(__cdecl *)(int, int, int, int , int , int , int), 0x1873D0); + NET_WritePrepareCraftItemPacket_cgitem = CONVERT_GAMEVAR(void(__cdecl *)(int, int), 0x189E20); + NET_WriteDropPetPacket_cgitem = CONVERT_GAMEVAR(void(__cdecl *)(int, int, int, int), 0x187A90); + Move_Player = CONVERT_GAMEVAR(void(__cdecl *)(), 0x98280);//ok - UI_ClickLogout = CONVERT_GAMEVAR(void(__cdecl *)(int, int), 0xD2CD0);//ok + UI_HandleLogbackMouseEvent = CONVERT_GAMEVAR(int(__cdecl *)(int, char), 0xD2BF0);//ok + UI_HandleLogoutMouseEvent = CONVERT_GAMEVAR(int(__cdecl *)(int, char), 0xD2CD0);//ok CL_MoveItemEx = CONVERT_GAMEVAR(void(__cdecl *)(int), 0xC0EC0);//ok - UI_PlayerMenuSelect = CONVERT_GAMEVAR(int(__cdecl **)(int, int), 0xCB4144-0x400000);//ok - UI_UnitMenuSelect = CONVERT_GAMEVAR(int(__cdecl **)(int, int), 0xCCF014-0x400000);//ok - UI_PlayerMenuShowup = CONVERT_GAMEVAR(int(__cdecl *)(int), 0xE0FE0);//ok - UI_UnitMenuShowup = CONVERT_GAMEVAR(int(__cdecl *)(int), 0xE18F0);//ok - UI_PlayerMenuMouseEvent = CONVERT_GAMEVAR(int(__cdecl *)(int, char), 0xE17A0);//ok - UI_UnitMenuMouseEvent = CONVERT_GAMEVAR(int(__cdecl *)(int, char), 0xE1E40);//ok NPC_ShowDialogInternal = CONVERT_GAMEVAR(void(__cdecl *)(int, int, int, int, const char *), 0xDE390);//ok NPC_ClickDialog = CONVERT_GAMEVAR(int(__cdecl *)(int, int, int, char), 0xDEC00);//ok NPC_ClickExchangeDialog = CONVERT_GAMEVAR(void(__cdecl *)(int), 0xE2880);//ok @@ -912,10 +1901,25 @@ void CGAService::Initialize(game_type type) UI_HandleMiniDialogMouseEvent = CONVERT_GAMEVAR(int(__cdecl *)(int, char), 0xE22E0);//ok UI_IsMouseInRect = CONVERT_GAMEVAR(int(__cdecl *)(int, int, int, int, int), 0x174160);//ok UI_HandleLearnSkillConfirmMouseEvent = CONVERT_GAMEVAR(int(__cdecl *)(int, char), 0x111F20);//ok + UI_HandleForgetSkillMouseEvent = CONVERT_GAMEVAR(int(__cdecl *)(int, char), 0x113130);//ok UI_HandleEnablePlayerFlagsMouseEvent = CONVERT_GAMEVAR(int(__cdecl *)(int, char), 0xA9320);//ok UI_HandleCraftItemSlotMouseEvent = CONVERT_GAMEVAR(int(__cdecl *)(int, char), 0xBACA0);//ok - UI_HandleCraftItemButtonMouseEvent = CONVERT_GAMEVAR(int(__cdecl *)(int, char), 0xB9BC0);//ok - NET_WriteOpenHealDialog_cgitem = CONVERT_GAMEVAR(void(__cdecl *)(int, int), 0x188AA0);//ok + UI_HandleCraftItemButtonMouseEvent = CONVERT_GAMEVAR(int(__cdecl *)(int, char), 0xB9BC0);//ok + IsMapObjectEntrance = CONVERT_GAMEVAR(decltype(IsMapObjectEntrance), 0x99800);//ok + UI_PlaySwitchAnim = CONVERT_GAMEVAR(int(__cdecl *)(int, char, float), 0x1A07F0);//ok + UI_HandleEnableFlags = CONVERT_GAMEVAR(int(__cdecl *)(int, char), 0xA9320);//ok + UI_SelectHealPlayer = CONVERT_GAMEVAR(int(__cdecl *)(int, const char *), 0xBF800);//ok + UI_SelectItemPlayer = CONVERT_GAMEVAR(int(__cdecl *)(int, const char *), 0xC5280);//ok + UI_SelectTradePlayer = CONVERT_GAMEVAR(int(__cdecl *)(int, const char *), 0x1479F0);//ok + UI_SelectHealUnit = CONVERT_GAMEVAR(int(__cdecl *)(int), 0xBFB50); + UI_SelectItemUnit = CONVERT_GAMEVAR(int(__cdecl *)(int), 0xC5450); + UI_SelectTradeAddStuffs = CONVERT_GAMEVAR(int(__cdecl *)(int a1, char a2), 0xFA8F6); + UI_OpenTradeDialog = CONVERT_GAMEVAR(void(__cdecl *)(const char *, int), 0x148840); + SYS_ResetWindow = CONVERT_GAMEVAR(void(__cdecl *)(), 0x93E10); + format_mapname = CONVERT_GAMEVAR(void(__cdecl *)(char *, int , int , int ), 0x95920); + BuildMapCollisionTable = CONVERT_GAMEVAR(decltype(BuildMapCollisionTable), 0x9E670); + Actor_SetAnimation = CONVERT_GAMEVAR(void(__cdecl *)(void *, int , int), 0x4FCA0); + GetBattleUnitDistance = CONVERT_GAMEVAR(int(__cdecl *)(void *a1, float a2, float a3), 0x1A680); } m_hFont = CreateFontW(16, 0, 0, 0, FW_THIN, false, false, false, @@ -925,12 +1929,12 @@ void CGAService::Initialize(game_type type) m_btl_showhpmp_enable = false; m_btl_highspeed_enable = false; - m_menu_item_selected = 0; - m_menu_item_select_index = -1; for (int i = 0; i < 20; ++i) m_battle_units[i].exist = false; + m_btl_effect_flags = 0; + if (IsInGame() && GetWorldStatus() == 10) { char *battle_buffer = g_btl_buffers + 4096 * ((*g_btl_buffer_index == 0) ? 3 : (*g_btl_buffer_index - 1)); ParseBattleUnits(battle_buffer, strlen(battle_buffer)); @@ -940,10 +1944,13 @@ void CGAService::Initialize(game_type type) m_move_to_x = 0; m_move_to_y = 0; m_move_speed = 100; + m_move_checkwarp = true; + m_ui_minidialog_loop = false; m_ui_minidialog_loop_index = -1; m_ui_minidialog_click_index = -1; m_ui_learn_skill_confirm = -1; + m_ui_forget_skill_index = -1; m_desired_player_enable_flags = 0; m_change_player_enable_flags = 0; m_ui_craftdialog_click_begin = false; @@ -954,26 +1961,46 @@ void CGAService::Initialize(game_type type) m_ui_craftdialog_additem[i] = -1; m_ui_craftdialog_additemcount = 0; m_work_acceleration = 100; + m_work_immediate = false; + m_ui_noswitchanim = false; + m_player_menu_type = 0; + m_unit_menu_type = 0; DetourTransactionBegin(); DetourAttach(&(void *&)BATTLE_PlayerAction, ::NewBATTLE_PlayerAction); + DetourAttach(&(void *&)NET_ParseTradeItemsPackets, ::NewNET_ParseTradeItemsPackets); + DetourAttach(&(void *&)NET_ParseTradePetPackets, ::NewNET_ParseTradePetPackets); + DetourAttach(&(void *&)NET_ParseTradePetSkillPackets, ::NewNET_ParseTradePetSkillPackets); + DetourAttach(&(void *&)NET_ParseTradeGoldPackets, ::NewNET_ParseTradeGoldPackets); + DetourAttach(&(void *&)NET_ParseTradePlayers, ::NewNET_ParseTradePlayers); + DetourAttach(&(void *&)NET_ParseHealPlayers, ::NewNET_ParseHealPlayers); + DetourAttach(&(void *&)NET_ParseHealUnits, ::NewNET_ParseHealUnits); + DetourAttach(&(void *&)NET_ParseItemPlayers, ::NewNET_ParseItemPlayers); + DetourAttach(&(void *&)NET_ParseItemUnits, ::NewNET_ParseItemUnits); DetourAttach(&(void *&)NET_ParseBattlePackets, ::NewNET_ParseBattlePackets); DetourAttach(&(void *&)NET_ParseWorkingResult, ::NewNET_ParseWorkingResult); DetourAttach(&(void *&)NET_ParseChatMsg, ::NewNET_ParseChatMsg); + DetourAttach(&(void *&)NET_ParseSysMsg, ::NewNET_ParseSysMsg); + DetourAttach(&(void *&)NET_ParseReadyTrade, ::NewNET_ParseReadyTrade); + DetourAttach(&(void *&)NET_ParseConfirmTrade, ::NewNET_ParseConfirmTrade); + DetourAttach(&(void *&)NET_ParseMeetEnemy, ::NewNET_ParseMeetEnemy); DetourAttach(&(void *&)R_DrawText, NewR_DrawText); DetourAttach(&(void *&)Move_Player, ::NewMove_Player); - DetourAttach(&(void *&)UI_PlayerMenuShowup, ::NewUI_PlayerMenuShowup); - DetourAttach(&(void *&)UI_PlayerMenuMouseEvent, ::NewUI_PlayerMenuMouseEvent); - DetourAttach(&(void *&)UI_UnitMenuShowup, ::NewUI_UnitMenuShowup); - DetourAttach(&(void *&)UI_UnitMenuMouseEvent, ::NewUI_UnitMenuMouseEvent); DetourAttach(&(void *&)NPC_ShowDialogInternal, ::NewNPC_ShowDialogInternal); DetourAttach(&(void *&)Sys_CheckModify, ::NewSys_CheckModify); DetourAttach(&(void *&)UI_HandleMiniDialogMouseEvent, ::NewUI_HandleMiniDialogMouseEvent); DetourAttach(&(void *&)UI_IsMouseInRect, ::NewUI_IsMouseInRect); DetourAttach(&(void *&)UI_HandleLearnSkillConfirmMouseEvent, ::NewUI_HandleLearnSkillConfirmMouseEvent); + DetourAttach(&(void *&)UI_HandleForgetSkillMouseEvent, ::NewUI_HandleForgetSkillMouseEvent); DetourAttach(&(void *&)UI_HandleEnablePlayerFlagsMouseEvent, ::NewUI_HandleEnablePlayerFlagsMouseEvent); DetourAttach(&(void *&)UI_HandleCraftItemSlotMouseEvent, ::NewUI_HandleCraftItemSlotMouseEvent); DetourAttach(&(void *&)UI_HandleCraftItemButtonMouseEvent, ::NewUI_HandleCraftItemButtonMouseEvent); + DetourAttach(&(void *&)UI_PlaySwitchAnim, ::NewUI_PlaySwitchAnim); + DetourAttach(&(void *&)UI_OpenTradeDialog, ::NewUI_OpenTradeDialog); + DetourAttach(&(void *&)Actor_SetAnimation, ::NewActor_SetAnimation); + DetourAttach(&(void *&)IsMapObjectEntrance, ::NewIsMapObjectEntrance); + DetourAttach(&(void *&)NET_WritePrepareCraftItemPacket_cgitem, ::NewNET_WritePrepareCraftItemPacket_cgitem); + DetourAttach(&(void *&)GetBattleUnitDistance, ::NewGetBattleUnitDistance); DetourTransactionCommit(); if (*g_mutex) @@ -991,11 +2018,12 @@ void CGAService::Uninitialize() return; m_initialized = false; - DetourTransactionBegin(); + /*DetourTransactionBegin(); DetourDetach(&(void *&)BATTLE_PlayerAction, ::NewBATTLE_PlayerAction); DetourDetach(&(void *&)NET_ParseBattlePackets, ::NewNET_ParseBattlePackets); DetourDetach(&(void *&)NET_ParseWorkingResult, ::NewNET_ParseWorkingResult); DetourDetach(&(void *&)NET_ParseChatMsg, ::NewNET_ParseChatMsg); + DetourDetach(&(void *&)NET_ParseSysMsg, ::NewNET_ParseSysMsg); DetourDetach(&(void *&)R_DrawText, NewR_DrawText); DetourDetach(&(void *&)Move_Player, ::NewMove_Player); DetourDetach(&(void *&)UI_PlayerMenuShowup, ::NewUI_PlayerMenuShowup); @@ -1010,7 +2038,8 @@ void CGAService::Uninitialize() DetourDetach(&(void *&)UI_HandleEnablePlayerFlagsMouseEvent, ::NewUI_HandleEnablePlayerFlagsMouseEvent); DetourDetach(&(void *&)UI_HandleCraftItemSlotMouseEvent, ::NewUI_HandleCraftItemSlotMouseEvent); DetourDetach(&(void *&)UI_HandleCraftItemButtonMouseEvent, ::NewUI_HandleCraftItemButtonMouseEvent); - DetourTransactionCommit(); + DetourDetach(&(void *&)UI_PlaySwitchAnim, ::NewUI_PlaySwitchAnim); + DetourTransactionCommit();*/ if (m_hFont) { @@ -1021,112 +2050,132 @@ void CGAService::Uninitialize() const int s_UnitPosToXY[][2] = { - { 480, 370 },{ 480 + 60, 370 - 50 },{ 480 - 60, 370 + 50 },{ 480 + 120, 370 - 100 },{ 480 - 120, 370 + 100 }, + { 480, 370 },{ 480 + 60, 370 - 50 },{ 480 - 60, 370 + 50 },{ 480 + 120, 370 - 100 },{ 480 - 120, 330 + 100 },//370 too large { 420, 327 },{ 420 + 60, 327 - 50 },{ 420 - 60, 327 + 50 },{ 420 + 120, 327 - 100 },{ 420 - 120, 317 + 100 }, - { 158, 188 },{ 158 + 60, 188 - 50 },{ 158 - 60, 188 + 50 },{ 158 + 120, 158 - 100 },{ 158 - 120, 158 + 100 }, + { 158, 188 },{ 158 + 60, 188 - 50 },{ 158 - 60, 188 + 50 },{ 158 + 120, 188 - 100 },{ 180 - 120, 188 + 100 },//158 too small { 210, 240 },{ 210 + 60, 240 - 50 },{ 210 - 60, 240 + 50 },{ 210 + 120, 240 - 100 },{ 210 - 120, 240 + 100 }, }; -void CGAService::DrawBattleInfo() +void CGAService::DrawCustomText() { - if (!m_btl_showhpmp_enable) - return; + if (m_btl_showhpmp_enable) + { + LPDIRECTDRAWSURFACE pSurface = GetDirectDrawBackSurface(); + + if (GetWorldStatus() == 10) + { + HDC hDC; + if (S_OK == pSurface->GetDC(&hDC)) + { + SetBkMode(hDC, TRANSPARENT); + SelectObject(hDC, g_CGAService.m_hFont); + + int x, y; + char buf[64]; + for (int i = 0; i < 20; ++i) + { + if (m_battle_units[i].exist) + { + x = s_UnitPosToXY[i][0]; + y = s_UnitPosToXY[i][1]; + + sprintf(buf, "%d / %d", m_battle_units[i].curhp, m_battle_units[i].maxhp); + int len = strlen(buf); + + ABC abc[1]; + int width = 0; + for (int j = 0; j < len; ++j) { + GetCharABCWidthsA(hDC, buf[j], buf[j], abc); + width += abc[0].abcA + abc[0].abcB + abc[0].abcC; + } + SetTextColor(hDC, RGB(0, 0, 0)); + TextOutA(hDC, x - width / 2, y, buf, len); + SetTextColor(hDC, RGB(255, 200, 0)); + TextOutA(hDC, x - width / 2 - 1, y - 1, buf, len); + + sprintf(buf, "%d / %d", m_battle_units[i].curmp, m_battle_units[i].maxmp); + len = strlen(buf); + + width = 0; + for (int j = 0; j < len; ++j) { + GetCharABCWidthsA(hDC, buf[j], buf[j], abc); + width += abc[0].abcA + abc[0].abcB + abc[0].abcC; + } + SetTextColor(hDC, RGB(0, 0, 0)); + TextOutA(hDC, x - width / 2, y + 20, buf, len); + SetTextColor(hDC, RGB(0, 200, 255)); + TextOutA(hDC, x - width / 2 - 1, y - 1 + 20, buf, len); + } + } - LPDIRECTDRAWSURFACE pSurface = GetDirectDrawBackSurface(); + pSurface->ReleaseDC(hDC); + } + } + } - if (GetWorldStatus() == 10) + if (m_btl_showhpmp_enable) { - HDC hDC; - if (S_OK == pSurface->GetDC(&hDC)) + if (GetWorldStatus() == 9 && GetGameStatus() == 3) { - SetBkMode(hDC, TRANSPARENT); - SelectObject(hDC, g_CGAService.m_hFont); - - int x, y; - char buf[64]; - for (int i = 0; i < 20; ++i) + LPDIRECTDRAWSURFACE pSurface = GetDirectDrawBackSurface(); + HDC hDC; + if (S_OK == pSurface->GetDC(&hDC)) { - if (m_battle_units[i].exist) - { - x = s_UnitPosToXY[i][0]; - y = s_UnitPosToXY[i][1]; + SetBkMode(hDC, TRANSPARENT); + SelectObject(hDC, g_CGAService.m_hFont); - sprintf(buf, "%d / %d", m_battle_units[i].curhp, m_battle_units[i].maxhp); - int len = strlen(buf); + int x = 640-64; + int y = 480-64; - ABC abc[1]; - int width = 0; - for (int j = 0; j < len; ++j) { - GetCharABCWidthsA(hDC, buf[j], buf[j], abc); - width += abc[0].abcA + abc[0].abcB + abc[0].abcC; - } - SetTextColor(hDC, RGB(0, 0, 0)); - TextOutA(hDC, x - width / 2, y, buf, len); - SetTextColor(hDC, RGB(255, 200, 0)); - TextOutA(hDC, x - width / 2 - 1, y - 1, buf, len); - - sprintf(buf, "%d / %d", m_battle_units[i].curmp, m_battle_units[i].maxmp); - len = strlen(buf); - - width = 0; - for (int j = 0; j < len; ++j) { - GetCharABCWidthsA(hDC, buf[j], buf[j], abc); - width += abc[0].abcA + abc[0].abcB + abc[0].abcC; - } - SetTextColor(hDC, RGB(0, 0, 0)); - TextOutA(hDC, x - width / 2, y + 20, buf, len); - SetTextColor(hDC, RGB(0, 200, 255)); - TextOutA(hDC, x - width / 2 - 1, y - 1 + 20, buf, len); + char buf[32]; + sprintf(buf, "(%d, %d)", *g_move_xdest, *g_move_ydest); + int len = strlen(buf); + + ABC abc[1]; + int width = 0; + for (int j = 0; j < len; ++j) { + GetCharABCWidthsA(hDC, buf[j], buf[j], abc); + width += abc[0].abcA + abc[0].abcB + abc[0].abcC; } - } + SetTextColor(hDC, RGB(0, 0, 0)); + TextOutA(hDC, x - width / 2, y, buf, len); + SetTextColor(hDC, RGB(255, 200, 0)); + TextOutA(hDC, x - width / 2 - 1, y - 1, buf, len); - pSurface->ReleaseDC(hDC); + pSurface->ReleaseDC(hDC); + } } } } void CGAService::ParseBattleUnits(const char *buf, size_t len) { - if (len < 4) - return; - - char *p = (char *)buf + 4; - int unitdata[11]; - char unitname[32]; - char buf2[256]; - for (int i = 0; i < 20; ++i) m_battle_units[i].exist = false; - while (*p) - { - int parsed = sscanf(p, "%x|%[^|]|%x|%x|%x|%x|%x|%x|%x|%x|%x|%x|", - &unitdata[0], unitname, &unitdata[1], &unitdata[2], - &unitdata[3], &unitdata[4], &unitdata[5], &unitdata[6], - &unitdata[7], &unitdata[8], &unitdata[9], &unitdata[10]); - if (parsed < 12) - break; + m_btl_effect_flags = NET_ParseHexInteger(buf, '|', 2); - sprintf(buf2, "%x|%s|%x|%x|%x|%x|%x|%x|%x|%x|%x|%x|", - unitdata[0], unitname, unitdata[1], unitdata[2], - unitdata[3], unitdata[4], unitdata[5], unitdata[6], - unitdata[7], unitdata[8], unitdata[9], unitdata[10]); - p += strlen(buf2); + int position = 3; - int pos = unitdata[0]; + while (1) + { + int pos = NET_ParseHexInteger(buf, '|', position); if (pos < 0 || pos > 19) break; - m_battle_units[pos].modelid = unitdata[1]; - m_battle_units[pos].level = unitdata[3]; - m_battle_units[pos].curhp = unitdata[4]; - m_battle_units[pos].maxhp = unitdata[5]; - m_battle_units[pos].curmp = unitdata[6]; - m_battle_units[pos].maxmp = unitdata[7]; + NET_ParseDelimeter(buf, '|', position + 1, 31, m_battle_units[pos].name); + m_battle_units[pos].pos = pos; - strcpy(m_battle_units[pos].name, unitname); + m_battle_units[pos].modelid = NET_ParseHexInteger(buf, '|', position + 2); + m_battle_units[pos].level = NET_ParseHexInteger(buf, '|', position + 4); + m_battle_units[pos].curhp = NET_ParseHexInteger(buf, '|', position + 5); + m_battle_units[pos].maxhp = NET_ParseHexInteger(buf, '|', position + 6); + m_battle_units[pos].curmp = NET_ParseHexInteger(buf, '|', position + 7); + m_battle_units[pos].maxmp = NET_ParseHexInteger(buf, '|', position + 8); + m_battle_units[pos].flags = NET_ParseHexInteger(buf, '|', position + 9); m_battle_units[pos].exist = true; + position += 12; } } @@ -1197,6 +2246,7 @@ void CGAService::WM_GetPlayerInfo(cga_player_info_t *info) info->xp = (*g_playerBase)->xp.decode(); info->maxxp = (*g_playerBase)->maxxp.decode(); info->health = (*g_playerBase)->health; + info->souls = (*g_playerBase)->souls; info->level = (*g_playerBase)->level; info->gold = (*g_playerBase)->gold; info->unitid = (*g_playerBase)->unitid; @@ -1205,6 +2255,41 @@ void CGAService::WM_GetPlayerInfo(cga_player_info_t *info) info->petid = *g_pet_id; info->name = boost::locale::conv::to_utf(g_player_name, "GBK"); info->job = boost::locale::conv::to_utf(g_job_name, "GBK"); + for (size_t i = 0; i < 96; ++i) + { + if (*(g_title_table + 28 * i) != 0) + info->titles.emplace_back(boost::locale::conv::to_utf((g_title_table + 28 * i), "GBK")); + else + break; + } + info->detail.points_remain = *g_player_remain_points; + info->detail.points_endurance = (*g_playerBase)->points_endurance; + info->detail.points_strength = (*g_playerBase)->points_strength; + info->detail.points_defense = (*g_playerBase)->points_defense; + info->detail.points_agility = (*g_playerBase)->points_agility; + info->detail.points_magical = (*g_playerBase)->points_magical; + info->detail.value_attack = (*g_playerBase)->value_attack; + info->detail.value_defensive = (*g_playerBase)->value_defensive; + info->detail.value_agility = (*g_playerBase)->value_agility; + info->detail.value_spirit = (*g_playerBase)->value_spirit; + info->detail.value_recovery = (*g_playerBase)->value_recovery; + info->detail.resist_poison = (*g_playerBase)->resist_poison; + info->detail.resist_sleep = (*g_playerBase)->resist_sleep; + info->detail.resist_medusa = (*g_playerBase)->resist_medusa; + info->detail.resist_drunk = (*g_playerBase)->resist_drunk; + info->detail.resist_chaos = (*g_playerBase)->resist_chaos; + info->detail.resist_forget = (*g_playerBase)->resist_forget; + info->detail.fix_critical = (*g_playerBase)->fix_critical; + info->detail.fix_strikeback = (*g_playerBase)->fix_strikeback; + info->detail.fix_accurancy = (*g_playerBase)->fix_accurancy; + info->detail.element_earth = (*g_playerBase)->element_earth; + info->detail.element_water = (*g_playerBase)->element_water; + info->detail.element_fire = (*g_playerBase)->element_fire; + info->detail.element_wind = (*g_playerBase)->element_wind; + + info->manu_endurance = (*g_playerBase)->manu_endurance; + info->manu_skillful = (*g_playerBase)->manu_skillful; + info->manu_intelligence = (*g_playerBase)->manu_intelligence; } cga_player_info_t CGAService::GetPlayerInfo() @@ -1238,9 +2323,10 @@ bool CGAService::IsPlayerFlagEnabled(int index) bool CGAService::IsSkillValid(int skillid) { - if (skillid < 0 || skillid > 9) + if (skillid < 0 || skillid >= 15) return false; - return g_skill_base[skillid].valid ? true : false; + + return g_skill_base[skillid].name[0] ? true : false; } void CGAService::WM_GetSkillInfo(int index, cga_skill_info_t *info) @@ -1259,6 +2345,7 @@ void CGAService::WM_GetSkillInfo(int index, cga_skill_info_t *info) info->pos = g_skill_base[index].pos; info->skill_id = g_skill_base[index].skill_id; info->index = index; + info->slotsize = g_skill_base[index].slotsize; } } @@ -1274,7 +2361,7 @@ void CGAService::WM_GetSkillsInfo(cga_skills_info_t *info) if (!IsInGame()) return; - for (int i = 0; i < 10; ++i) + for (int i = 0; i < 15; ++i) { if (IsSkillValid(i)) { @@ -1287,7 +2374,8 @@ void CGAService::WM_GetSkillsInfo(cga_skills_info_t *info) g_skill_base[i].skill_id, g_skill_base[i].type, g_skill_base[i].pos, - i + i, + g_skill_base[i].slotsize ); } } @@ -1313,6 +2401,7 @@ void CGAService::WM_GetSubSkillInfo(int index, int stage, cga_subskill_info_t *i info->cost = g_skill_base[index].sub[stage].cost; info->level = g_skill_base[index].sub[stage].level; info->flags = g_skill_base[index].sub[stage].flags; + info->available = g_skill_base[index].sub[stage].available ? true : false; } } @@ -1341,7 +2430,8 @@ void CGAService::WM_GetSubSkillsInfo(int index, cga_subskills_info_t *info) boost::locale::conv::to_utf(g_skill_base[index].sub[i].info, "GBK"), g_skill_base[index].sub[i].cost, g_skill_base[index].sub[i].flags, - g_skill_base[index].sub[i].level + g_skill_base[index].sub[i].level, + g_skill_base[index].sub[i].available ? true : false ); } } @@ -1381,10 +2471,37 @@ void CGAService::WM_GetPetInfo(int index, cga_pet_info_t *info) info->level = g_pet_base[index].level; info->flags = g_pet_base[index].flags; info->race = g_pet_base[index].race; + info->loyality = g_pet_base[index].value_loyality; info->battle_flags = g_pet_base[index].battle_flags; info->index = index; info->name = boost::locale::conv::to_utf(g_pet_base[index].name, "GBK"); - info->realname = boost::locale::conv::to_utf(g_pet_base[index].realname, "GBK");; + info->realname = boost::locale::conv::to_utf(g_pet_base[index].realname, "GBK"); + + info->detail.points_remain = g_pet_base[index].points_remain; + info->detail.points_endurance = g_pet_base[index].points_endurance; + info->detail.points_strength = g_pet_base[index].points_strength; + info->detail.points_defense = g_pet_base[index].points_defense; + info->detail.points_agility = g_pet_base[index].points_agility; + info->detail.points_magical = g_pet_base[index].points_magical; + info->detail.value_attack = g_pet_base[index].value_attack; + info->detail.value_defensive = g_pet_base[index].value_defensive; + info->detail.value_agility = g_pet_base[index].value_agility; + info->detail.value_spirit = g_pet_base[index].value_spirit; + info->detail.value_recovery = g_pet_base[index].value_recovery; + info->detail.resist_poison = g_pet_base[index].resist_poison; + info->detail.resist_sleep = g_pet_base[index].resist_sleep; + info->detail.resist_medusa = g_pet_base[index].resist_medusa; + info->detail.resist_drunk = g_pet_base[index].resist_drunk; + info->detail.resist_chaos = g_pet_base[index].resist_chaos; + info->detail.resist_forget = g_pet_base[index].resist_forget; + info->detail.fix_critical = g_pet_base[index].fix_critical; + info->detail.fix_strikeback = g_pet_base[index].fix_strikeback; + info->detail.fix_accurancy = g_pet_base[index].fix_accurancy; + info->detail.fix_dodge = g_pet_base[index].fix_dodge; + info->detail.element_earth = g_pet_base[index].element_earth; + info->detail.element_water = g_pet_base[index].element_water; + info->detail.element_fire = g_pet_base[index].element_fire; + info->detail.element_wind = g_pet_base[index].element_wind; } } @@ -1417,10 +2534,38 @@ void CGAService::WM_GetPetsInfo(cga_pets_info_t *info) g_pet_base[i].level, g_pet_base[i].flags, g_pet_base[i].race, + g_pet_base[i].value_loyality, g_pet_base[i].battle_flags, i, boost::locale::conv::to_utf(g_pet_base[i].name, "GBK"), - boost::locale::conv::to_utf(g_pet_base[i].realname, "GBK") + boost::locale::conv::to_utf(g_pet_base[i].realname, "GBK"), + cga_playerpet_detail_info_t( + g_pet_base[i].points_remain, + g_pet_base[i].points_endurance, + g_pet_base[i].points_strength, + g_pet_base[i].points_defense, + g_pet_base[i].points_agility, + g_pet_base[i].points_magical, + g_pet_base[i].value_attack, + g_pet_base[i].value_defensive, + g_pet_base[i].value_agility, + g_pet_base[i].value_spirit, + g_pet_base[i].value_recovery, + g_pet_base[i].resist_poison, + g_pet_base[i].resist_sleep, + g_pet_base[i].resist_medusa, + g_pet_base[i].resist_drunk, + g_pet_base[i].resist_chaos, + g_pet_base[i].resist_forget, + g_pet_base[i].fix_critical, + g_pet_base[i].fix_strikeback, + g_pet_base[i].fix_accurancy, + g_pet_base[i].fix_dodge, + g_pet_base[i].element_earth, + g_pet_base[i].element_water, + g_pet_base[i].element_fire, + g_pet_base[i].element_wind + ) ); } } @@ -1535,8 +2680,18 @@ void CGAService::WM_GetItemInfo(int itempos, cga_item_info_t *info) else { info->name = boost::locale::conv::to_utf((*g_playerBase)->iteminfos[itempos].name, "GBK"); - info->attr = boost::locale::conv::to_utf((*g_playerBase)->iteminfos[itempos].attr, "GBK"); - info->attr2 = boost::locale::conv::to_utf((*g_playerBase)->iteminfos[itempos].attr2, "GBK"); + //info->attr = boost::locale::conv::to_utf((*g_playerBase)->iteminfos[itempos].attr, "GBK"); + //info->attr2 = boost::locale::conv::to_utf((*g_playerBase)->iteminfos[itempos].attr2, "GBK"); + std::string attrs; + for (int j = 0; j < 8; ++j) { + if ((*g_playerBase)->iteminfos[itempos].attrs[j][0]) + { + if (j != 0) + attrs += "\n"; + attrs += boost::locale::conv::to_utf((*g_playerBase)->iteminfos[itempos].attrs[j], "GBK"); + } + } + info->attr = attrs; info->info = boost::locale::conv::to_utf((*g_playerBase)->iteminfos[itempos].info, "GBK"); info->info2 = boost::locale::conv::to_utf((*g_playerBase)->iteminfos[itempos].info2, "GBK"); info->itemid = (*g_playerBase)->iteminfos[itempos].item_id; @@ -1573,10 +2728,19 @@ void CGAService::WM_GetItemsInfo(cga_items_info_t *info) { if (IsItemValid(itempos)) { + std::string attrs; + for (int j = 0; j < 8; ++j) { + if ((*g_playerBase)->iteminfos[itempos].attrs[j][0]) + { + if (j != 0) + attrs += "\n"; + attrs += boost::locale::conv::to_utf((*g_playerBase)->iteminfos[itempos].attrs[j], "GBK"); + } + } info->emplace_back( boost::locale::conv::to_utf((*g_playerBase)->iteminfos[itempos].name, "GBK"), - boost::locale::conv::to_utf((*g_playerBase)->iteminfos[itempos].attr, "GBK"), - boost::locale::conv::to_utf((*g_playerBase)->iteminfos[itempos].attr2, "GBK"), + attrs, + std::string(),//boost::locale::conv::to_utf((*g_playerBase)->iteminfos[itempos].attr, "GBK"), boost::locale::conv::to_utf((*g_playerBase)->iteminfos[itempos].info, "GBK"), boost::locale::conv::to_utf((*g_playerBase)->iteminfos[itempos].info2, "GBK"), (*g_playerBase)->iteminfos[itempos].item_id, @@ -1641,6 +2805,12 @@ bool CGAService::WM_DropItem(int itempos) if (!IsInGame()) return false; + if (GetWorldStatus() != 9 || GetGameStatus() != 3) + return false; + + if (*g_move_xspeed != 0 || *g_move_yspeed != 0) + return false; + if (!IsItemValid(itempos)) return false; @@ -1657,27 +2827,67 @@ bool CGAService::DropItem(int itempos) return SendMessageA(g_MainHwnd, WM_CGA_DROP_ITEM, itempos, 0) ? true : false; } -bool CGAService::WM_MoveItem(cga_move_item_t *mov) +bool CGAService::WM_DropPet(int petpos) { if (!IsInGame()) return false; - if (!IsItemValid(mov->itempos)) + if (GetWorldStatus() != 9 || GetGameStatus() != 3) + return false; + + if (*g_move_xspeed != 0 || *g_move_yspeed != 0) return false; - char buffer[64]; - sprintf(buffer, "I\\z%d\\z%d\\z%d", mov->itempos, mov->dstpos, mov->count); + if (!IsPetValid(petpos)) + return false; if (m_game_type == cg_item_6000) - NET_WritePacket3_cgitem(*g_net_socket, - g_player_xpos->decode(), g_player_ypos->decode(), - *g_npc_dialog_dlgid, *g_npc_dialog_npcid, 0, buffer); + NET_WriteDropPetPacket_cgitem(*g_net_socket, g_player_xpos->decode(), g_player_ypos->decode(), petpos); //else //NET_WritePacket1(*g_net_buffer, *g_net_socket, net_header_dropitem, g_player_xpos->decode(), g_player_ypos->decode(), itempos); return true; } +bool CGAService::DropPet(int petpos) +{ + return SendMessageA(g_MainHwnd, WM_CGA_DROP_PET, petpos, 0) ? true : false; +} + +bool CGAService::WM_MoveItem(cga_move_item_t *mov) +{ + if (!IsInGame()) + return false; + + if (GetWorldStatus() != 9 || GetGameStatus() != 3) + return false; + + if (*g_move_xspeed != 0 || *g_move_yspeed != 0) + return false; + + if (!IsItemValid(mov->itempos)) + return false; + + if (mov->itempos >= 100 || mov->dstpos >= 100) + { + char buffer[64]; + sprintf(buffer, "I\\z%d\\z%d\\z%d", mov->itempos, mov->dstpos, mov->count); + + if (m_game_type == cg_item_6000) + NET_WritePacket3_cgitem(*g_net_socket, + g_player_xpos->decode(), g_player_ypos->decode(), + *g_npc_dialog_dlgid, *g_npc_dialog_npcid, 0, buffer); + //else + //NET_WritePacket1(*g_net_buffer, *g_net_socket, net_header_dropitem, g_player_xpos->decode(), g_player_ypos->decode(), itempos); + } + else + { + NET_WriteMoveItemPacket_cgitem(*g_net_socket, mov->itempos, mov->dstpos, mov->count); + } + + return true; +} + bool CGAService::MoveItem(int itempos, int dstpos, int count) { cga_move_item_t mov; @@ -1687,6 +2897,11 @@ bool CGAService::MoveItem(int itempos, int dstpos, int count) return SendMessageA(g_MainHwnd, WM_CGA_MOVE_ITEM, (WPARAM)&mov, 0) ? true : false; } +std::tuple CGAService::GetMapIndex() +{ + return std::tuple(*g_map_index1, *g_map_index2, *g_map_index3); +} + std::tuple CGAService::GetMapXY() { return std::tuple(g_player_xpos->decode(), g_player_ypos->decode()); @@ -1702,9 +2917,40 @@ std::tuple CGAService::GetMoveSpeed() return std::tuple(*g_move_xspeed, *g_move_yspeed); } +void CGAService::WM_GetMapName(std::string *name) +{ + try + { + *name = boost::locale::conv::to_utf(g_map_name, "GBK"); + } + catch (std::exception &e) + { + *name = ""; + } +} + std::string CGAService::GetMapName() { - return boost::locale::conv::to_utf(g_map_name, "GBK"); + std::string name; + + /* + SendMessageA(g_MainHwnd, WM_CGA_GET_MAP_NAME, (WPARAM)&name, 0);*/ + + char mapname[32]; + + strncpy(mapname, g_map_name, 31); + mapname[31] = 0; + + try + { + name = boost::locale::conv::to_utf(mapname, "GBK"); + } + catch (std::exception &e) + { + name = ""; + } + + return name; } cga_map_units_t CGAService::GetMapUnits() @@ -1718,6 +2964,9 @@ cga_map_units_t CGAService::GetMapUnits() void CGAService::WalkTo(int x, int y) { + if (g_player_xpos->decode() == x && g_player_ypos->decode() == y) + return; + m_move_to |= 1; m_move_to_x = x; m_move_to_y = y; @@ -1736,6 +2985,22 @@ void CGAService::SetMoveSpeed(int speed) m_move_speed = speed; } +void CGAService::WM_GetMoveHistory(std::vector *v) +{ + v->reserve(m_move_history.size()); + for (auto itor = m_move_history.rbegin(); itor != m_move_history.rend(); ++itor) + { + v->emplace_back(*itor); + } +} + +std::vector CGAService::GetMoveHistory(void) +{ + std::vector v; + SendMessageA(g_MainHwnd, WM_CGA_GET_MOVE_HISTORY, (WPARAM)&v, NULL); + return v; +} + bool CGAService::IsBattleUnitValid(int pos) { return (pos >= 0 && pos < 20 && m_battle_units[pos].exist) ? true : false; @@ -1755,6 +3020,7 @@ void CGAService::WM_GetBattleUnit(int pos, cga_battle_unit_t *u) u->maxhp = m_battle_units[pos].maxhp; u->curmp = m_battle_units[pos].curmp; u->maxmp = m_battle_units[pos].maxmp; + u->flags = m_battle_units[pos].flags; u->pos = m_battle_units[pos].pos; } } @@ -1783,6 +3049,7 @@ void CGAService::WM_GetBattleUnits(cga_battle_units_t *u) m_battle_units[i].maxhp, m_battle_units[i].curmp, m_battle_units[i].maxmp, + m_battle_units[i].flags, m_battle_units[i].pos ); } @@ -1796,29 +3063,21 @@ cga_battle_units_t CGAService::GetBattleUnits() return u; } -int CGAService::GetBattleRoundCount() -{ - return *g_btl_round_count; -} - -int CGAService::GetBattlePlayerPosition() -{ - return *g_btl_player_pos; -} - -int CGAService::GetBattlePlayerStatus() -{ - return *g_btl_player_status; -} - -int CGAService::GetBattleSkillPerformed() +cga_battle_context_t CGAService::GetBattleContext() { - return *g_btl_skill_performed; -} + cga_battle_context_t ctx( + *g_btl_round_count, + *g_btl_player_pos, + *g_btl_player_status, + *g_btl_skill_performed, + *g_btl_skill_allowbit, + *g_btl_petskill_allowbit, + *g_btl_weapon_allowbit, + *g_btl_petid, + m_btl_effect_flags + ); -int CGAService::GetBattlePetId() -{ - return *g_btl_petid; + return ctx; } bool CGAService::WM_BattleNormalAttack(int target) @@ -1835,7 +3094,8 @@ bool CGAService::WM_BattleNormalAttack(int target) NET_WritePacket(*g_net_buffer, *g_net_socket, net_header_battle, buf); *g_btl_action_done = 1; COMMON_PlaySound(57, 320, 240); - //Battle_EndSelect(); + + WriteLog("BattleNormalAttack %d\n", target); return true; } @@ -1851,14 +3111,66 @@ bool CGAService::WM_BattleSkillAttack(int skillpos, int skilllv, int target) return false; if (*g_btl_player_status != 1) return false; - if (!g_skill_base[skillpos].valid) + if (!g_skill_base[skillpos].name[0]) + { + WriteLog("skill %d not valid\n", skillpos); return false; + } if (!(*g_btl_skill_allowbit & (1 << skillpos)))//skill not allowed!!! + { + WriteLog("skill %d not allowed\n", skillpos); return false; + } if (g_skill_base[skillpos].level < skilllv) + { + WriteLog("skill lv%d not enough\n", skilllv); return false; - if (g_skill_base[skillpos].sub[skilllv - 1].cost > m_battle_units[*g_btl_player_pos].curmp) - return false; + } + + WriteLog("skill %d %d\n", skillpos, skilllv); + + if (g_skill_base[skillpos].sub[skilllv].available == 0) + { + WriteLog("skill lv%d not available, downgrade\n", skilllv); + bool available = false; + for (int lv = skilllv - 1; lv >= 0; --lv) + { + if (g_skill_base[skillpos].sub[lv].available == 1) + { + skilllv = lv; + available = true; + break; + } + } + + if (!available) + { + WriteLog("skill lv%d not available\n", skilllv); + return false; + } + } + + if (g_skill_base[skillpos].sub[skilllv].cost > m_battle_units[*g_btl_player_pos].curmp) + { + bool available = false; + for (int lv = skilllv - 1; lv >= 0; --lv) + { + if (g_skill_base[skillpos].sub[lv].cost <= m_battle_units[*g_btl_player_pos].curmp) + { + skilllv = lv; + available = true; + break; + } + } + + if (!available) + { + WriteLog("skill lv%d no enough mp\n", skilllv); + return false; + } + } + + WriteLog("fixed skill %d %d\n", skillpos, skilllv); char buf[32]; sprintf(buf, "S|%X|%X|%X", skillpos, skilllv, target); @@ -1869,6 +3181,8 @@ bool CGAService::WM_BattleSkillAttack(int skillpos, int skilllv, int target) *g_btl_action_done = 1; COMMON_PlaySound(57, 320, 240); + WriteLog("BattleSkillAttack %d %d %d\n", skillpos, skilllv, target); + return true; } @@ -2000,8 +3314,29 @@ bool CGAService::WM_BattlePetSkillAttack(int skillpos, int target) return false; if (*g_btl_player_status != 4) return false; - //if (g_pet_base[*g_btl_petid].skills[skillpos].cost> m_battle_units[*g_btl_player_pos].curmp) - // return false; + + if (skillpos == -1 || skillpos == 0xFF) + { + char buf[32]; + sprintf(buf, "W|FF"); + if (m_game_type == cg_item_6000) + NET_WriteBattlePacket_cgitem(*g_net_socket, buf); + else + NET_WritePacket(*g_net_buffer, *g_net_socket, net_header_battle, buf); + *g_btl_action_done = 1; + COMMON_PlaySound(57, 320, 240); + + WriteLog("BattlePetSkillAttack FF\n"); + return true; + } + + if (!(*g_btl_petskill_allowbit & (1 << skillpos)))//skill not allowed!!! + { + WriteLog("pet skill %d not allowed\n", skillpos); + return false; + } + //if (g_pet_base[*g_btl_petid].skills[skillpos].cost > m_battle_units[*g_btl_player_pos].curmp) + // return false; char buf[32]; sprintf(buf, "W|%X|%X", skillpos, target); if (m_game_type == cg_item_6000) @@ -2011,6 +3346,8 @@ bool CGAService::WM_BattlePetSkillAttack(int skillpos, int target) *g_btl_action_done = 1; COMMON_PlaySound(57, 320, 240); + WriteLog("BattlePetSkillAttack %d %d\n", skillpos, target); + return true; } @@ -2053,13 +3390,20 @@ void CGAService::WM_LogBack() if (!IsInGame() || *g_logback) return; - if (m_game_type == cg_item_6000) - NET_WriteLogbackPacket_cgitem(*g_net_socket); - else if (m_game_type == cg_se_3000) - NET_WriteLogbackPacket_cgse(*g_net_buffer, *g_net_socket, net_header_logback); + if (*g_world_status_cgitem == 10) + { + UI_HandleLogbackMouseEvent(8, 2); + } + else + { + if (m_game_type == cg_item_6000) + NET_WriteLogbackPacket_cgitem(*g_net_socket); + else if (m_game_type == cg_se_3000) + NET_WriteLogbackPacket_cgse(*g_net_buffer, *g_net_socket, net_header_logback); - COMMON_PlaySound(60, 320, 240); - *g_logback = 1; + COMMON_PlaySound(60, 320, 240); + *g_logback = 1; + } } void CGAService::LogOut() @@ -2072,7 +3416,7 @@ void CGAService::WM_LogOut() if (!IsInGame()) return; - UI_ClickLogout(9, 2); + UI_HandleLogoutMouseEvent(9, 2); COMMON_PlaySound(60, 320, 240); } @@ -2115,11 +3459,21 @@ bool CGAService::WM_ClickNPCDialog(int option, int index) return false; } - if (*g_npc_dialog_type == 17) + if (*g_npc_dialog_type == 17) + { + if (option == 0) + { + m_ui_learn_skill_confirm = 1; + return true; + } + return false; + } + + if (*g_npc_dialog_type == 18) { if (option == 0) { - m_ui_learn_skill_confirm = 1; + m_ui_forget_skill_index = index; return true; } return false; @@ -2142,18 +3496,63 @@ bool CGAService::WM_SellNPCStore(cga_sell_items_t *items) std::string buffer; char buf[32]; - if (*g_npc_dialog_type != 7) + if (*g_npc_dialog_type != 7 && *g_npc_dialog_type != 6 && *g_npc_dialog_type != 22 && *g_npc_dialog_type != 20) + { + //WriteLog("type mismatch %d\n", *g_npc_dialog_type); return false; + } - for (size_t i = 0; i < items->size(); ++i) + if (*g_npc_dialog_type == 22 || *g_npc_dialog_type == 20) { - if (items->at(i).itemid != 0 && g_item_base[items->at(i).itempos].item_id != items->at(i).itemid) - return false; - if (g_item_base[items->at(i).itempos].count < items->at(i).count) - return false; - sprintf(buf, "%d\\z%d\\z", items->at(i).itempos, items->at(i).count); - buffer += buf; + for (size_t i = 0; i < items->size(); ++i) + { + if (items->at(i).itemid != 0 && (*g_playerBase)->iteminfos[items->at(i).itempos].item_id != items->at(i).itemid) + { + //WriteLog("id mismatch %d %d\n", items->at(i).itemid, (*g_playerBase)->iteminfos[items->at(i).itempos].item_id); + return false; + } + bool allow = false; + for (size_t j = 0; j < 20; ++j) + { + if (g_npcdlg_item_base[j].valid && g_npcdlg_item_base[j].itempos == items->at(i).itempos) + { + //WriteLog("j=%d g_npcdlg_item_base[j].itempos=%d\n", j, g_npcdlg_item_base[j].itempos); + allow = true; + break; + } + } + if (allow) + { + sprintf(buf, "%d", items->at(i).itempos); + buffer += buf; + if (i != items->size() - 1) + buffer += "\\z"; + } + } + } + else + { + for (size_t i = 0; i < items->size(); ++i) + { + if (items->at(i).itemid != 0 && (*g_playerBase)->iteminfos[items->at(i).itempos].item_id != items->at(i).itemid) + { + //WriteLog("id mismatch %d %d %d\n", items->at(i).itemid, (*g_playerBase)->iteminfos[items->at(i).itempos].item_id, items->at(i).itemid); + return false; + } + if ((*g_playerBase)->iteminfos[items->at(i).itempos].count != 0 && (*g_playerBase)->iteminfos[items->at(i).itempos].count < items->at(i).count) { + //WriteLog("count mismatch %d %d\n", (*g_playerBase)->iteminfos[items->at(i).itempos].count, items->at(i).count); + return false; + } + sprintf(buf, "%d\\z%d", items->at(i).itempos, items->at(i).count); + buffer += buf; + if (i != items->size() - 1) + buffer += "\\z"; + } } + + if (buffer.empty()) + return false; + if(m_game_type == cg_item_6000) NET_WritePacket3_cgitem(*g_net_socket, g_player_xpos->decode(), g_player_ypos->decode(), @@ -2164,6 +3563,7 @@ bool CGAService::WM_SellNPCStore(cga_sell_items_t *items) *g_npc_dialog_dlgid, *g_npc_dialog_npcid, 0, buffer.c_str()); COMMON_PlaySound(79, 320, 240); + return true; } @@ -2214,29 +3614,57 @@ bool CGAService::BuyNPCStore(cga_buy_items_t items) return SendMessageA(g_MainHwnd, WM_CGA_BUY_NPC_STORE, (WPARAM)&items, 0) ? true : false; } -bool CGAService::PlayerMenuSelect(int menuindex) +bool CGAService::WM_PlayerMenuSelect(int menuindex, const char *menustring) { - if (menuindex >= 0 && menuindex < *g_player_menu_count) + if (m_player_menu_type == PLAYER_MENU_HEAL) { - m_menu_item_selected = 1; - m_menu_item_select_index = menuindex; - return true; + m_player_menu_type = 0; + return UI_SelectHealPlayer(menuindex, menustring) ? true : false; + } + else if (m_player_menu_type == PLAYER_MENU_ITEM) + { + m_player_menu_type = 0; + return UI_SelectItemPlayer(menuindex, menustring) ? true : false; + } + else if (m_player_menu_type == PLAYER_MENU_TRADE) + { + m_player_menu_type = 0; + return UI_SelectTradePlayer(menuindex, menustring) ? true : false; } - return false; } -bool CGAService::UnitMenuSelect(int menuindex) +bool CGAService::PlayerMenuSelect(int menuindex, const std::string &menustring) { - if (menuindex >= 0 && menuindex < *g_unit_menu_count) + return SendMessageA(g_MainHwnd, WM_CGA_PLAYER_MENU_SELECT, (WPARAM)menuindex, (LPARAM)menustring.c_str()) ? true : false; +} + +bool CGAService::WM_UnitMenuSelect(int menuindex) +{ + if (m_unit_menu_type == UNIT_MENU_HEAL) { - m_menu_item_selected = 2; - m_menu_item_select_index = menuindex; - return true; + m_unit_menu_type = 0; + return UI_SelectHealUnit(menuindex) ? true : false; + } + else if (m_unit_menu_type == UNIT_MENU_ITEM) + { + m_unit_menu_type = 0; + return UI_SelectItemUnit(menuindex) ? true : false; } return false; } +bool CGAService::UnitMenuSelect(int menuindex) +{ + return SendMessageA(g_MainHwnd, WM_CGA_UNIT_MENU_SELECT, (WPARAM)menuindex, 0) ? true : false; +} + +inline void GetActorPosition(void *actor, int &x, int &y) +{ + x = *(int *)((char *)actor + 4 * (*(unsigned short *)((char *)actor + 624)) + 544); + y = *(int *)((char *)actor + 4 * (*(unsigned short *)((char *)actor + 624)) + 584); +} + void CGAService::WM_GetMapUnits(cga_map_units_t *units) { if (!IsInGame()) @@ -2247,27 +3675,35 @@ void CGAService::WM_GetMapUnits(cga_map_units_t *units) if (g_map_units[i].valid == 0) continue; + int xpos = g_map_units[i].xpos.decode(), ypos = g_map_units[i].ypos.decode(); + + if (g_map_units[i].actor && g_map_units[i].type == 8) + { + int x, y; + GetActorPosition(g_map_units[i].actor, x, y); + if (x != 0 && y != 0) + { + xpos = x; + ypos = y; + } + } + units->emplace_back( g_map_units[i].valid, g_map_units[i].type, g_map_units[i].unit_id, g_map_units[i].model_id, - g_map_units[i].xpos.decode(), - g_map_units[i].ypos.decode(), + xpos, + ypos, g_map_units[i].item_count, + g_map_units[i].injury, + g_map_units[i].level, + g_map_units[i].flags, boost::locale::conv::to_utf(g_map_units[i].unit_name, "GBK"), boost::locale::conv::to_utf(g_map_units[i].nick_name, "GBK"), + boost::locale::conv::to_utf(g_map_units[i].title_name, "GBK"), boost::locale::conv::to_utf(g_map_units[i].item_name, "GBK") ); - - WriteLog("name1=%s, name2=%s, name3=%s, unk10=%d, unk11=%d, unk12=%d", - g_map_units[i].unit_name, - g_map_units[i].nick_name, - g_map_units[i].item_name, - g_map_units[i].unk10, - g_map_units[i].unk11, - g_map_units[i].item_count - ); } } @@ -2295,12 +3731,16 @@ void CGAService::SetWorkDelay(int delay) { if (delay < 0) delay = 0; + *g_work_basedelay = delay - 4500; } void CGAService::SetWorkAcceleration(int percent) { - m_work_acceleration = percent; + if (percent > 0) + { + m_work_acceleration = percent; + } } bool CGAService::WM_StartWork(int skill_index, int sub_index) @@ -2426,21 +3866,20 @@ bool CGAService::WM_CraftItem(cga_craft_item_t *craft) return false; m_ui_craftdialog_additemcount = 0; - int x = 0; for (int i = 0; i < 5; ++i) { m_ui_craftdialog_additem[i] = -1; if (!skill_craft.mats[i].name[0]) continue; - bool found = false; - int itemid = skill_craft.mats[i].itemid; + bool found_this_mat = false; + int desireditemid = skill_craft.mats[i].itemid; int desiredcount = skill_craft.mats[i].count; for (size_t j = 0; j < 5; ++j) { int itempos = craft->itempos[j]; if (itempos >= 8 && IsItemValid(itempos)) { - if (itemid == (*g_playerBase)->iteminfos[itempos].item_id) + if (desireditemid == (*g_playerBase)->iteminfos[itempos].item_id) { int itemcount = (*g_playerBase)->iteminfos[itempos].count; if (!itemcount) @@ -2449,16 +3888,23 @@ bool CGAService::WM_CraftItem(cga_craft_item_t *craft) { m_ui_craftdialog_additem[m_ui_craftdialog_additemcount] = itempos - 8; ++m_ui_craftdialog_additemcount; - found = true; + found_this_mat = true; break; } } } } - if (!found) + if (!found_this_mat) return false; } + int itempos = craft->itempos[5]; + if (itempos >= 8 && IsItemValid(itempos)) + { + m_ui_craftdialog_additem[m_ui_craftdialog_additemcount] = itempos - 8; + ++m_ui_craftdialog_additemcount; + } + return true; } @@ -2477,7 +3923,147 @@ bool CGAService::WM_IsMapCellPassable(int x, int y) bool CGAService::IsMapCellPassable(int x, int y) { - return SendMessageA(g_MainHwnd, WM_CGA_IS_MAP_CELL_PASSABLE, x, y) ? true : false; + int offsetX = x - *g_map_x_bottom; + int offsetY = y - *g_map_y_bottom; + + return (offsetX >= 0 && offsetX < *g_map_x_size && offsetY >= 0 && offsetY < *g_map_y_size && (g_map_collision_table[offsetX + offsetY * (*g_map_x_size)] != 1)) ? true : false; + + //return SendMessageA(g_MainHwnd, WM_CGA_IS_MAP_CELL_PASSABLE, x, y) ? true : false; +} + +void CGAService::WM_GetMapCollisionTable(bool loadall, cga_map_cells_t *cells) +{ + if (loadall) + { + char mapname[1024]; + format_mapname(mapname, *g_map_index1, *g_map_index2, *g_map_index3); + auto fp = fopen(mapname, "rb"); + if (fp) + { + fseek(fp, 12, SEEK_SET); + int xsize = 0, ysize = 0; + fread(&xsize, 4, 1, fp); + fread(&ysize, 4, 1, fp); + + if (xsize > 0 && ysize > 0 && xsize < 10000 && ysize < 10000) + { + short *celldata = (short *)malloc(2 * xsize * ysize); + short *collisiondata = (short *)malloc(2 * xsize * ysize); + short *objectdata = (short *)malloc(2 * xsize * ysize); + int bufferSize = std::max(2*51*51, 2 * xsize * ysize); + short *collisiontable = (short *)malloc(bufferSize); + + memset(collisiontable, 0, bufferSize); + + fseek(fp, 20, SEEK_SET); + fread(celldata, 2 * xsize * ysize, 1, fp); + + fseek(fp, 20 + 2 * xsize * ysize, SEEK_SET); + fread(collisiondata, 2 * xsize * ysize, 1, fp); + + fseek(fp, 20 + 2 * xsize * ysize + 2 * xsize * ysize, SEEK_SET); + fread(objectdata, 2 * xsize * ysize, 1, fp); + + BuildMapCollisionTable(0, 0, xsize, ysize, celldata, collisiondata, objectdata, collisiontable); + + cells->x_bottom = 0; + cells->y_bottom = 0; + cells->x_size = xsize; + cells->y_size = ysize; + + cells->cell.resize(xsize * ysize); + memcpy(cells->cell.data(), collisiontable, 2 * xsize * ysize); + + free(celldata); + free(collisiondata); + free(objectdata); + free(collisiontable); + + fclose(fp); + + return; + } + + fclose(fp); + } + } + + cells->x_bottom = *g_map_x_bottom; + cells->y_bottom = *g_map_y_bottom; + cells->x_size = *g_map_x_size; + cells->y_size = *g_map_y_size; + cells->cell.resize(cells->x_size*cells->y_size); + memcpy(cells->cell.data(), g_map_collision_table, 2 * cells->x_size*cells->y_size); +} + +cga_map_cells_t CGAService::GetMapCollisionTable(bool loadall) +{ + cga_map_cells_t cells; + + SendMessageA(g_MainHwnd, WM_CGA_GET_COLLISION_TABLE, loadall ? 1 : 0, (LPARAM)&cells); + + return cells; +} + +void CGAService::WM_GetMapObjectTable(bool loadall, cga_map_cells_t *cells) +{ + if (loadall) + { + char mapname[1024]; + format_mapname(mapname, *g_map_index1, *g_map_index2, *g_map_index3); + auto fp = fopen(mapname, "rb"); + if (fp) + { + fseek(fp, 12, SEEK_SET); + int xsize = 0, ysize = 0; + fread(&xsize, 4, 1, fp); + fread(&ysize, 4, 1, fp); + + if (xsize > 0 && ysize > 0 && xsize < 10000 && ysize < 10000) + { + fseek(fp, 20 + 2 * xsize * ysize + 2 * xsize * ysize, SEEK_SET); + + int bufferSize = std::max(2 * 51 * 51, 2 * xsize * ysize); + + short *buffer = (short *)malloc(bufferSize); + memset(buffer, 0, bufferSize); + + fread(buffer, 2 * xsize * ysize, 1, fp); + + cells->x_bottom = 0; + cells->y_bottom = 0; + cells->x_size = xsize; + cells->y_size = ysize; + + cells->cell.resize(xsize * ysize); + memcpy(cells->cell.data(), buffer, 2 * xsize * ysize); + + free(buffer); + + fclose(fp); + + return; + } + + fclose(fp); + } + } + + cells->x_bottom = *g_map_x_bottom; + cells->y_bottom = *g_map_y_bottom; + cells->x_size = *g_map_x_size; + cells->y_size = *g_map_y_size; + cells->cell.resize(cells->x_size*cells->y_size); + memcpy(cells->cell.data(), g_map_object_table, 2 * cells->x_size*cells->y_size); +} + +cga_map_cells_t CGAService::GetMapObjectTable(bool loadall) +{ + cga_map_cells_t cells; + + SendMessageA(g_MainHwnd, WM_CGA_GET_OBJECT_TABLE, loadall ? 1 : 0, (LPARAM)&cells); + + return cells; } bool CGAService::WM_ForceMove(int dir, bool show) @@ -2588,6 +4174,167 @@ bool CGAService::ForceMoveTo(int x, int y, bool show) return SendMessageA(g_MainHwnd, WM_CGA_FORCE_MOVE_TO, (x & 0xFFFF) | ((y & 0xFFFF) << 16) , show ? 1 : 0) ? true : false; } +bool CGAService::DoRequest(int request_type) +{ + return SendMessageA(g_MainHwnd, WM_CGA_DO_REQUEST, request_type, 0) ? true : false; +} + +bool CGAService::WM_DoRequest(int request_type) +{ + if (!IsInGame()) + return false; + + if (GetWorldStatus() != 9 || GetGameStatus() != 3) + return false; + + if (request_type == REQUEST_TYPE_JOINTEAM) { + if (*g_is_in_team) + return false; + + NET_WriteJoinTeamPacket_cgitem(*g_net_socket, g_player_xpos->decode(), g_player_ypos->decode(), 1); + } + else if (request_type == REQUEST_TYPE_LEAVETEAM) { + if (!(*g_is_in_team)) + return false; + //if(!(*g_team_flags & 100)) + // return false; + + NET_WriteJoinTeamPacket_cgitem(*g_net_socket, g_player_xpos->decode(), g_player_ypos->decode(), 0); + } + else if (request_type == REQUEST_TYPE_KICKTEAM) { + if (!(*g_is_in_team)) + return false; + + NET_WriteKickTeamPacket_cgitem(*g_net_socket); + } + else if (request_type == REQUEST_TYPE_TRADE) { + NET_WriteTradePacket_cgitem(*g_net_socket); + } + else if (request_type == REQUEST_TYPE_EXCAHNGECARD) { + NET_WriteExchangeCardPacket_cgitem(*g_net_socket, g_player_xpos->decode(), g_player_ypos->decode()); + } + else if (request_type == REQUEST_TYPE_PK) { + NET_WritePKPacket_cgitem(*g_net_socket, g_player_xpos->decode(), g_player_ypos->decode()); + } + else if (request_type == REQUEST_TYPE_TRADE_CONFIRM) { + NET_WriteTradeConfirmPacket_cgitem(*g_net_socket); + } + else if (request_type == REQUEST_TYPE_TRADE_REFUSE) { + NET_WriteTradeRefusePacket_cgitem(*g_net_socket); + } + else { + return false; + } + + return true; +} + +bool CGAService::EnableFlags(int type, bool enable) +{ + return SendMessageA(g_MainHwnd, WM_CGA_ENABLE_FLAGS, type, enable ? 1 : 0) ? true : false; +} + +bool CGAService::WM_EnableFlags(int type, bool enable) +{ + if (!IsInGame()) + return false; + + if (GetWorldStatus() != 9 || GetGameStatus() != 3) + return false; + + if (type == ENABLE_FLAG_JOINTEAM) { + if(((*g_enableflags) & PLAYER_ENABLE_FLAGS_JOINTEAM) && !enable) + UI_HandleEnableFlags(19, 2); + else if (!((*g_enableflags) & PLAYER_ENABLE_FLAGS_JOINTEAM) && enable) + UI_HandleEnableFlags(19, 2); + } + else if (type == ENABLE_FLAG_TRADE) { + if (((*g_enableflags) & PLAYER_ENABLE_FLAGS_TRADE) && !enable) + UI_HandleEnableFlags(21, 2); + else if (!((*g_enableflags) & PLAYER_ENABLE_FLAGS_TRADE) && enable) + UI_HandleEnableFlags(21, 2); + } + else if (type == ENABLE_FLAG_CARD) { + if (((*g_enableflags) & PLAYER_ENABLE_FLAGS_CARD) && !enable) + UI_HandleEnableFlags(20, 2); + else if (!((*g_enableflags) & PLAYER_ENABLE_FLAGS_CARD) && enable) + UI_HandleEnableFlags(20, 2); + } + else if (type == ENABLE_FLAG_PK) { + if (((*g_enableflags) & PLAYER_ENABLE_FLAGS_PK) && !enable) + UI_HandleEnableFlags(17, 2); + else if (!((*g_enableflags) & PLAYER_ENABLE_FLAGS_PK) && enable) + UI_HandleEnableFlags(17, 2); + } + else if (type == ENABLE_FLAG_TEAMCHAT) { + if (((*g_enableflags) & PLAYER_ENABLE_FLAGS_TEAMCHAT) && !enable) + UI_HandleEnableFlags(18, 2); + else if (!((*g_enableflags) & PLAYER_ENABLE_FLAGS_TEAMCHAT) && enable) + UI_HandleEnableFlags(18, 2); + } + else if (type == ENABLE_FLAG_FAMILY) { + if (((*g_enableflags) & PLAYER_ENABLE_FLAGS_FAMILY) && !enable) + UI_HandleEnableFlags(22, 2); + else if (!((*g_enableflags) & PLAYER_ENABLE_FLAGS_FAMILY) && enable) + UI_HandleEnableFlags(22, 2); + } + else { + return false; + } + + return true; +} + +void CGAService::TradeAddStuffs(cga_sell_items_t items, cga_sell_pets_t pets, int gold) +{ + cga_trade_stuff_t stuff; + + stuff.items = items; + stuff.pets = pets; + stuff.gold = gold; + + SendMessageA(g_MainHwnd, WM_CGA_TRADE_ADD_STUFFS, (WPARAM)&stuff, 0); +} + +void CGAService::WM_TradeAddStuffs(cga_trade_stuff_t *stuffs) +{ + std::string itembuffer, petbuffer; + char buf[32]; + + for (size_t i = 0; i < stuffs->items.size(); ++i) + { + sprintf(buf, "%d|%d", stuffs->items.at(i).itempos, i); + itembuffer += buf; + if (i != stuffs->items.size() - 1) + itembuffer += "|"; + } + + for (size_t i = 0; i < stuffs->pets.size(); ++i) + { + sprintf(buf, "%d|%d", stuffs->pets.at(i), i); + petbuffer += buf; + if (i != stuffs->pets.size() - 1) + petbuffer += "|"; + } + + NET_WriteTraceAddItemPacket_cgitem(*g_net_socket, itembuffer.c_str(), petbuffer.c_str(), stuffs->gold); + /*for (size_t i = 0; i < 20; ++i) + g_trade_item_array[i] = -1; + + for (size_t i = 0; i < stuffs->items.size() && i < 20; ++i) + g_trade_item_array[i] = stuffs->items.at(i).itempos; + + for (size_t i = 0; i < 5; ++i) + g_trade_pet_array[i] = -1; + + for (size_t i = 0; i < stuffs->pets.size() && i < 5; ++i) + g_trade_pet_array[i] = stuffs->pets.at(i); + + *g_trade_gold = stuffs->gold; + + UI_SelectTradeAddStuffs(2, 2);*/ +} + void CGAService::WM_GetCraftInfo(cga_craft_item_t *craft, cga_craft_info_t *info) { if (!IsInGame()) @@ -2662,12 +4409,120 @@ void CGAService::WM_GetCraftsInfo(int skill_index, cga_crafts_info_t *info) } } } - } + } } cga_crafts_info_t CGAService::GetCraftsInfo(int skill_index) { cga_crafts_info_t info; - SendMessageA(g_MainHwnd, WM_CGA_GET_CRAFTS_INFO, skill_index, (LPARAM)&info) ? true : false; + SendMessageA(g_MainHwnd, WM_CGA_GET_CRAFTS_INFO, skill_index, (LPARAM)&info); + return info; +} + +void CGAService::WM_GetTeamPlayerInfo(cga_team_players_t *info) +{ + if (!IsInGame()) + return; + + if (!*g_is_in_team) + return; + + for (int i = 0; i < 5; ++i) + { + if (g_team_player_base[i].valid) + { + std::string name; + + if (g_team_player_base[i].unit_id == (*g_playerBase)->unitid) + name = boost::locale::conv::to_utf((*g_playerBase)->name, "GBK"); + else if (g_team_player_base[i].actor) + name = boost::locale::conv::to_utf((char *)g_team_player_base[i].actor + 196, "GBK"); + + info->emplace_back( + g_team_player_base[i].unit_id, + g_team_player_base[i].hp, + g_team_player_base[i].mp, + g_team_player_base[i].maxhp, + name + ); + } + } +} + +cga_team_players_t CGAService::GetTeamPlayerInfo(void) +{ + cga_team_players_t info; + SendMessageA(g_MainHwnd, WM_CGA_GET_TEAM_PLAYERS_INFO, (WPARAM)&info, 0); return info; +} + +void CGAService::WM_FixMapWarpStuck(int type) +{ + if (type == 0) + { + WriteLog("FixMapWarpStuck type 0\n"); + + *g_disable_move = 0; + *g_game_status_cgitem = 1; + } + else if (type == 1) + { + WriteLog("FixMapWarpStuck type 1\n"); + + if (IsMapObjectEntrance(g_player_xpos->decode(), g_player_ypos->decode())) + { + *g_do_switch_map = 1; + *g_switch_map_frames = 1; + *g_switch_map_type = 1; + *g_is_moving = 1; + } + } +} + +void CGAService::FixMapWarpStuck(int type) +{ + if (type == 2) + { + m_move_checkwarp = true; + } + else if (type == 3) + { + m_move_checkwarp = false; + } + else + { + SendMessageA(g_MainHwnd, WM_CGA_FIX_WARP_STUCK, (WPARAM)type, 0); + } +} + +void CGAService::SetNoSwitchAnim(bool enable) +{ + m_ui_noswitchanim = enable; +} + +void CGAService::SetImmediateDoneWork(bool enable) +{ + m_work_immediate = enable; +} + +void CGAService::WM_SetWindowResolution(int w, int h) +{ + *g_resolution_width = w; + *g_resolution_height = h; + SYS_ResetWindow(); +} + +void CGAService::SetWindowResolution(int w, int h) +{ + SendMessageA(g_MainHwnd, WM_CGA_SET_WINDOW_RESOLUTION, w, h); +} + +void CGAService::WM_RequestDownloadMap(int xbottom, int ybottom, int xsize, int ysize) +{ + NET_WriteRequestDownloadMapPacket_cgitem(*g_net_socket, *g_map_index1, *g_map_index3, xbottom, ybottom, xsize, ysize); +} + +void CGAService::RequestDownloadMap(int xbottom, int ybottom, int xsize, int ysize) +{ + SendMessageA(g_MainHwnd, WM_CGA_REQUEST_DOWNLOAD_MAP, xbottom & 0xffff | ((xsize & 0xffff) << 16), ybottom & 0xffff | ((ysize & 0xffff) << 16)); } \ No newline at end of file diff --git a/cgahook/gameservice.h b/cgahook/gameservice.h index cf8eb3c..975a2c2 100644 --- a/cgahook/gameservice.h +++ b/cgahook/gameservice.h @@ -3,6 +3,8 @@ #include "../CGALib/gameinterface.h" #include "../CGALib/packdata.h" +#include + struct IDirectDraw; struct IDirectDrawSurface; @@ -52,8 +54,7 @@ namespace CGA { short valid; char name[46]; - char attr[96]; - char attr2[672]; + char attrs[8][96]; char info[192]; char info2[576]; int flags;//2=right clickable @@ -89,6 +90,26 @@ namespace CGA static_assert(sizeof(bank_item_info_t) == 0x644, "Size check"); + typedef struct npcdlg_item_info_s + { + char valid;//CD3198 + char name[29];//CD3199 + char attr[1538];//CD31B6 + int image_id;//CD37B8 + int cost;//CD37BC + int selected;//CD37C0 + int itempos;//CD37C4 + int unk; + int unk2;//init to 1 + int unk3; + char unk4; + char padding[3]; + int unk5; + char info[20];//CD37DC + }npcdlg_item_info_t; + + static_assert(sizeof(npcdlg_item_info_t) == 0x658, "Size check"); + #define PLAYER_ENABLE_FLAGS_PK (1<<2) #define PLAYER_ENABLE_FLAGS_TEAMCHAT (1<<3) #define PLAYER_ENABLE_FLAGS_JOINTEAM (1<<0) @@ -124,11 +145,11 @@ namespace CGA int value_agility;//+160 int value_spirit;//+164 int value_recovery;//+168 - int value_enchantment;//+172 + int value_charisma;//+172 int unk3;//+176 int resist_poison;//+180 - int resist_hypnosis;//+184 - int resist_petrify;//+188 + int resist_sleep;//+184 + int resist_medusa;//+188 int resist_drunk;//+192 int resist_chaos;//+196 int resist_forget;//+200 @@ -143,7 +164,7 @@ namespace CGA int health;//+236 int souls;//+240 int gold;//+244 - int special_nick;//+248 + int special_nick;//+248 //使用第几个称号 int score;//+252 char name[17];//+256 char player_nick[17];//+273 @@ -152,8 +173,8 @@ namespace CGA int skill_maxrows;//+356 int move_speed;//+360 int unk int unk4;//+364 - int unk5;//+368 - int unk6;//+372 + int image_id;//+368 + int avatar_id;//+372 int unitid;//+376 int direction;//+380 short unk7;//+384 @@ -174,14 +195,14 @@ namespace CGA //size = 148 typedef struct skill_sub_s { - char name[25]; - char info[99]; - int cost; - int unk1; - int flags; - int unk3; - int available; - int level; + char name[25];//0 + char info[99];//25 + int cost;//124 + int unk1;//128 + int flags;//132 + int unk3;//136 + int available;//140 + int level;//144 }skill_sub_t; static_assert(sizeof(skill_sub_t) == 148, "Size check"); @@ -213,7 +234,7 @@ namespace CGA typedef struct skill_s { char name[25]; - char valid; + char slotsize; char padding[2]; int level; int maxlevel; @@ -273,8 +294,8 @@ namespace CGA int value_recovery; int value_loyality; int resist_poison; - int resist_hypnosis; - int resist_petrify; + int resist_sleep; + int resist_medusa; int resist_drunk; int resist_chaos; int resist_forget; @@ -349,6 +370,7 @@ namespace CGA int maxhp; int curmp; int maxmp; + int flags; int pos; }battle_unit_t; @@ -361,13 +383,13 @@ namespace CGA typedef struct map_unit_s { - short valid;// if 0 invalid + short valid;// if 0 invalid 640144 short type;//+2 int unit_id;//+4 int model_id;//+8 CXorValue xpos;//+12 CXorValue ypos;//+28 - int unk1;//1 //+44 + int level;//1 //+44 int unk2;//0 //+48 int unk3;//-1? //+52 int unk4;//0 //+56 @@ -383,19 +405,35 @@ namespace CGA char nick_name[17];//+101 char unk13[33];//+118 char unk14[33];//+151 - char unk15[17];//+184 + char title_name[17];//+184 char item_name[67];//+201 - int unk17; - int unk18;//0x1000 - short unk19;//1 - short padding2; - void *actor; - short unk20; - short padding3; - int unk21;//0x124 + int unk17;//+268 + int unk18;//+272 0x1000 //64118 + short flags;//+276 1 //6411C + short padding2;//+278 + int unk20; //640120 + void *actor;//+284 640124 + int injury;//+288 char unk22[24]; }map_unit_t; + static_assert(sizeof(map_unit_t) == 0x13c, "Size check"); + + typedef struct team_player_s + { + short valid; + short padding; + int unit_id; + int maxhp; + int mp; + int hp; + int unk; + char name[20]; + void *actor; + }team_player_t; + + static_assert(sizeof(team_player_t) == 0x30, "Size check"); + #pragma pack() class CGAService @@ -435,7 +473,9 @@ namespace CGA virtual bool DropItem(int itempos); virtual bool UseItem(int itempos); virtual bool MoveItem(int itempos, int dstpos, int count); + virtual bool DropPet(int petpos); + virtual std::tuple GetMapIndex(); virtual std::tuple GetMapXY(); virtual std::tuple GetMapXYFloat(); virtual std::tuple GetMoveSpeed(); @@ -444,22 +484,19 @@ namespace CGA virtual void WalkTo(int x, int y); virtual void TurnTo(int x, int y); virtual void SetMoveSpeed(int speed); + virtual std::vector GetMoveHistory(void); virtual void LogBack(); virtual void LogOut(); virtual bool ClickNPCDialog(int option, int flags); virtual bool SellNPCStore(cga_sell_items_t items); virtual bool BuyNPCStore(cga_buy_items_t items); - virtual bool PlayerMenuSelect(int menuindex); + virtual bool PlayerMenuSelect(int menuindex, const std::string &menustring); virtual bool UnitMenuSelect(int menuindex); virtual bool IsBattleUnitValid(int pos); virtual cga_battle_unit_t GetBattleUnit(int pos); virtual cga_battle_units_t GetBattleUnits(); - virtual int GetBattleRoundCount(); - virtual int GetBattlePlayerPosition(); - virtual int GetBattlePlayerStatus(); - virtual int GetBattleSkillPerformed(); - virtual int GetBattlePetId(); + virtual cga_battle_context_t GetBattleContext(); virtual int GetBattleEndTick(); virtual void SetBattleEndTick(int msec); virtual bool BattleNormalAttack(int target); @@ -482,8 +519,19 @@ namespace CGA virtual cga_craft_info_t GetCraftInfo(int skill_index, int subskill_index); virtual cga_crafts_info_t GetCraftsInfo(int skill_index); virtual bool IsMapCellPassable(int x, int y); + virtual cga_map_cells_t GetMapCollisionTable(bool loadall); + virtual cga_map_cells_t GetMapObjectTable(bool loadall); virtual bool ForceMove(int dir, bool show); virtual bool ForceMoveTo(int x, int y, bool show); + virtual bool DoRequest(int request_type); + virtual void TradeAddStuffs(cga_sell_items_t items, cga_sell_pets_t pets, int gold); + virtual cga_team_players_t GetTeamPlayerInfo(void); + virtual void FixMapWarpStuck(int type); + virtual void SetNoSwitchAnim(bool enable); + virtual void SetImmediateDoneWork(bool enable); + virtual bool EnableFlags(int type, bool enable); + virtual void SetWindowResolution(int w, int h); + virtual void RequestDownloadMap(int xbottom, int ybottom, int xsize, int ysize); private: int *g_world_status_cgitem; int *g_game_status_cgitem; @@ -495,7 +543,9 @@ namespace CGA playerbase_t **g_playerBase; playerbase_t *g_playerBase_cgitem; bank_item_info_t *g_bank_item_base; + npcdlg_item_info_t *g_npcdlg_item_base; char *g_player_name; + int *g_player_remain_points; pet_t *g_pet_base; int *g_pet_id; char *g_job_name; @@ -520,17 +570,25 @@ namespace CGA int *g_mouse_states; int *g_is_ingame; int *g_work_basedelay; + short *g_disable_move; + int *g_is_moving; + int *g_do_switch_map; + int *g_switch_map_frames; + int *g_switch_map_type; char *g_btl_buffers; int *g_btl_buffer_index; int *g_btl_round_count; int *g_btl_player_pos; int *g_btl_player_status; + int *g_btl_petskill_allowbit; int *g_btl_skill_allowbit; + int *g_btl_weapon_allowbit; int *g_btl_petid; int *g_btl_action_done; int *g_btl_skill_performed; unsigned int *g_btl_round_endtick; + char *g_btl_unit_base; char **g_net_buffer; int *g_net_socket; @@ -548,30 +606,27 @@ namespace CGA //todo item_t *g_item_base; item_info_t *g_item_info_base; + item_t *g_trade_item_base; void *g_pGameBase; int *g_logback; int *g_item_cur_using; - item_menu_player_t *g_item_menu_players; - int *g_item_menu_player_count; - item_menu_unit_t *g_item_menu_units; - int *g_item_menu_unit_count; - - unit_menu_t **g_unit_menu_base;//D38E60 - int *g_unit_menu_count;//CB4140 - int *g_unit_menu_begin;//CE4C34 - char ***g_player_menu_name;//D29734 - char **g_player_menu_color;//CE4AA0 - int *g_player_menu_count;//CE4C28 - int *g_player_menu_begin;//CDBB24 - char *g_player_menu_clickable; - char *g_unit_menu_clickable; + char *g_trade_item_array; + char *g_trade_pet_array; + int *g_trade_gold; char *g_ui_craftdialog_additem_count; char *g_work_accelerate;//63FFFE char *g_work_accelerate_percent;//627E8C int *g_craft_step;//CBF15E + int *g_craft_done_tick; + int *g_heal_player_menu_type; + int *g_heal_player_menu_select; + int *g_heal_menu_type; + + short *g_item_player_menu_type; + int *g_item_player_select; //int *g_ret_address; int *g_unit_count; @@ -587,23 +642,48 @@ namespace CGA short *g_map_x_size; short *g_map_y_size; short *g_map_collision_table; + short *g_map_object_table; + int *g_map_index1; + int *g_map_index2; + int *g_map_index3; int *g_healing_skill_index; int *g_healing_subskill_index; + short *g_is_in_team; + short *g_team_flags; + team_player_t *g_team_player_base; + char *g_title_table; + + short *g_enableflags; + HANDLE *g_mutex; + int *g_resolution_width; + int *g_resolution_height; public: char(__cdecl *Sys_CheckModify)(const char *a1); void(__cdecl *COMMON_PlaySound)(int a1, int a2, int a3); void(__cdecl *BATTLE_PlayerAction)(); + void(__cdecl *NET_ParseTradeItemsPackets)(int a1, const char *buf); + void(__cdecl *NET_ParseTradePetPackets)(int a1, int index, const char *buf); + void(__cdecl *NET_ParseTradePetSkillPackets)(int a1, int index, const char *buf); + void(__cdecl *NET_ParseTradeGoldPackets)(int a1, int gold); + void(__cdecl *NET_ParseTradePlayers)(int a1, const char *src, char *src2); + void(__cdecl *NET_ParseHealPlayers)(int a1, const char *src); + void(__cdecl *NET_ParseHealUnits)(int a1, const char *src); + void(__cdecl *NET_ParseItemPlayers)(int a1, const char *src); + void(__cdecl *NET_ParseItemUnits)(int a1, const char *src); void(__cdecl *NET_ParseBattlePackets)(int a1, const char *buf); void(__cdecl *NET_ParseWorkingResult)(int a1, int success, int type, const char *buf); void(__cdecl *NET_ParseChatMsg)(int a1, int unitid, const char *buf, int a4, int a5); + void(__cdecl *NET_ParseSysMsg)(int a1, const char *buf); + void(__cdecl *NET_ParseReadyTrade)(); + void(__cdecl *NET_ParseConfirmTrade)(int a1, int a2); + void(__cdecl *NET_ParseMeetEnemy)(int a1, int a2, int a3); void(_cdecl *R_DrawText)(int a1); void(__cdecl *Move_Player)(); void(__cdecl *CL_MoveItemEx)(int);//C0EC0 - void(__cdecl *UI_ClickLogout)(int a1, int a2); void(__cdecl *NET_WritePacket)(void *net_buffer, int net_socket, const char *header, const char *buf); void(__cdecl *NET_WritePacket1)(void *net_buffer, int net_socket, const char *header, int a4, int a5, int a6); @@ -621,13 +701,19 @@ namespace CGA void(__cdecl *NET_WriteMovePacket_cgitem)(int, int, const char *); void(__cdecl *NET_WriteOpenHealDialog_cgitem)(int, int); void (__cdecl *NET_WriteWorkPacket_cgitem)(int, int, int, int, const char *); + void(__cdecl *NET_WriteJoinTeamPacket_cgitem)(int, int, int, int); + void(__cdecl *NET_WriteTradePacket_cgitem)(int); + void(__cdecl *NET_WriteKickTeamPacket_cgitem)(int); + void(__cdecl *NET_WriteTraceAddItemPacket_cgitem)(int, const char *, const char *, int); + void(__cdecl *NET_WriteTradeConfirmPacket_cgitem)(int); + void(__cdecl *NET_WriteTradeRefusePacket_cgitem)(int); + void(__cdecl *NET_WriteExchangeCardPacket_cgitem)(int, int, int); + void(__cdecl *NET_WritePKPacket_cgitem)(int, int, int); + void(__cdecl *NET_WriteMoveItemPacket_cgitem)(int, int, int, int); + void (__cdecl *NET_WriteRequestDownloadMapPacket_cgitem)(int a1, int index1, int index3, int xbot, int ybot, int xsize, int ysize); + void(__cdecl *NET_WritePrepareCraftItemPacket_cgitem)(int, int); + void(__cdecl *NET_WriteDropPetPacket_cgitem)(int, int, int , int); - int(__cdecl **UI_PlayerMenuSelect)(int, int ); - int(__cdecl **UI_UnitMenuSelect)(int, int ); - int(__cdecl *UI_PlayerMenuShowup)(int); - int(__cdecl *UI_UnitMenuShowup)(int); - int(__cdecl *UI_PlayerMenuMouseEvent)(int, char); - int(__cdecl *UI_UnitMenuMouseEvent)(int, char); void(__cdecl *NPC_ShowDialogInternal)(int type, int options, int dlgid, int objid, const char *message); int(__cdecl *NPC_ClickDialog)(int option, int index, int a3, char a4); void(__cdecl *NPC_ClickExchangeDialog)(int option); @@ -638,34 +724,66 @@ namespace CGA int(__cdecl *UI_HandleMiniDialogMouseEvent)(int widget, char flags); int(__cdecl *UI_IsMouseInRect)(int a1, int a2, int a3, int a4, int a5); int(__cdecl *UI_HandleLearnSkillConfirmMouseEvent)(int index, char flags); + int(__cdecl *UI_HandleForgetSkillMouseEvent)(int index, char flags); int(__cdecl *UI_HandleEnablePlayerFlagsMouseEvent)(int index, char flags); int(__cdecl *UI_HandleCraftItemSlotMouseEvent)(int a1, char flags); int( __cdecl *UI_HandleCraftItemButtonMouseEvent)(int a1, char flags); + int(__cdecl *UI_HandleLogbackMouseEvent)(int a1, char a2); + int(__cdecl *UI_HandleLogoutMouseEvent)(int a1, char a2); + int(__cdecl *IsMapObjectEntrance)(int xpos, int ypos); + int(__cdecl *UI_PlaySwitchAnim)(int ,char, float); + int(__cdecl *UI_HandleEnableFlags)(int a1, char a2); + int(__cdecl *UI_SelectHealPlayer)(int menuindex, const char *menustring); + int(__cdecl *UI_SelectItemPlayer)(int menuindex, const char *menustring); + int(__cdecl *UI_SelectTradePlayer)(int menuindex, const char *menustring); + int(__cdecl *UI_SelectHealUnit)(int menuindex); + int(__cdecl *UI_SelectItemUnit)(int menuindex); + int(__cdecl *UI_SelectTradeAddStuffs)(int a1, char a2); + void(__cdecl *UI_OpenTradeDialog)(const char *playerName, int playerLevel); + void(__cdecl *SYS_ResetWindow)(); + void(__cdecl *format_mapname)(char *a1, int index1, int index2, int index3); + void(__cdecl *BuildMapCollisionTable)(int xbase, int ybase, int xtop, int ytop, void *celldata, void *collisiondata, void *objectdata, void *collisiontable); + void(__cdecl *Actor_SetAnimation)(void *actor, int anim, int a3); + int(__cdecl *GetBattleUnitDistance)(void *a1, float a2, float a3); void NewBATTLE_PlayerAction(); + void NewNET_ParseTradeItemsPackets(int a1, const char *buf); + void NewNET_ParseTradePetPackets(int a1, int index, const char *buf); + void NewNET_ParseTradePetSkillPackets(int a1, int index, const char *buf); + void NewNET_ParseTradeGoldPackets(int a1, int gold); + void NewNET_ParseTradePlayers(int a1, const char *src, char *src2); + void NewNET_ParseHealPlayers(int a1, const char *src); + void NewNET_ParseHealUnits(int a1, const char *src); + void NewNET_ParseItemPlayers(int a1, const char *src); + void NewNET_ParseItemUnits(int a1, const char *src); void NewNET_ParseBattlePackets(int a1, const char *buf); void NewNET_ParseWorkingResult(int a1, int success, int type, const char *buf); void NewNET_ParseChatMsg(int a1, int unitid, const char *buf, int color, int size); + void NewNET_ParseSysMsg(int a1, const char *buf); + void NewNET_ParseReadyTrade(); + void NewNET_ParseConfirmTrade(int a1, int a2); + void NewMove_Player(); - void NewUI_PlayerMenuShowup(int a1); - void NewUI_UnitMenuShowup(int a1); - int NewUI_PlayerMenuMouseEvent(int widget_index, char flags); - int NewUI_UnitMenuMouseEvent(int widget_index, char flags); void NewNPC_ShowDialogInternal(int type, int options, int dlgid, int objid, const char *message); int NewUI_IsMouseInRect(int a1, int a2, int a3, int a4, int a5); int NewUI_HandleMiniDialogMouseEvent(int widget, char flags); int NewUI_HandleEnablePlayerFlagsMouseEvent(int index, char flags); int NewUI_HandleCraftItemSlotMouseEvent(int index, char flags); int NewUI_HandleCraftItemButtonMouseEvent(int index, char flags); + void NewUI_OpenTradeDialog(const char *playerName, int playerLevel); + void NewNET_WritePrepareCraftItemPacket_cgitem(int a1, int a2); + void ParseGatheringResult(int success, const char *buf); void ParseHealingResult(int success, const char *buf); void ParseAssessingResult(int success, const char *buf); void ParseCraftingResult(int success, const char *buf); + bool ParseIsKnockout(const char *buf); + bool ParseIsEscape(const char *buf); IDirectDraw *GetDirectDraw(); IDirectDrawSurface *GetDirectDrawBackSurface(); void ParseBattleUnits(const char *buf, size_t len); - void DrawBattleInfo(); + void DrawCustomText(); int IsItemTypeAssessable(int type); bool WM_BattleNormalAttack(int target); @@ -678,6 +796,7 @@ namespace CGA bool WM_BattlePetSkillAttack(int skillpos, int target); void WM_LogBack(); void WM_LogOut(); + bool WM_DropPet(int petpos); bool WM_DropItem(int itempos); bool WM_UseItem(int itempos); bool WM_MoveItem(cga_move_item_t *mov); @@ -699,6 +818,7 @@ namespace CGA void WM_GetBattleUnit(int pos, cga_battle_unit_t *u); void WM_GetBattleUnits(cga_battle_units_t *u); void WM_GetMapUnits(cga_map_units_t *units); + void WM_GetMapName(std::string *name); void WM_SayWords(const char *str, int color, int range, int size); bool WM_StartWork(int skill_index, int sub_index); bool WM_CraftItem(cga_craft_item_t *craft); @@ -708,29 +828,48 @@ namespace CGA bool WM_ForceMoveTo(int x, int y, bool show); void WM_GetCraftInfo(cga_craft_item_t *craft, cga_craft_info_t *info); void WM_GetCraftsInfo(int skill_index, cga_crafts_info_t *info); + bool WM_DoRequest(int request_type); + void WM_TradeAddStuffs(cga_trade_stuff_t *stuffs); + void WM_GetTeamPlayerInfo(cga_team_players_t *info); + void WM_FixMapWarpStuck(int type); + void WM_GetMoveHistory(std::vector *v); + bool WM_EnableFlags(int type, bool enable); + bool WM_PlayerMenuSelect(int menuindex, const char *menustring); + bool WM_UnitMenuSelect(int menuindex); + void WM_SetWindowResolution(int w, int h); + void WM_RequestDownloadMap(int xbottom, int ybottom, int xsize, int ysize); + void WM_GetMapCollisionTable(bool loadall, cga_map_cells_t *cells); + void WM_GetMapObjectTable(bool loadall, cga_map_cells_t *cells); + bool m_initialized; bool m_btl_highspeed_enable; bool m_btl_showhpmp_enable; bool m_btl_double_action; + int m_btl_effect_flags; battle_unit_t m_battle_units[20]; int m_move_to; int m_move_to_x, m_move_to_y; - int m_menu_item_selected; - int m_menu_item_select_index; + std::list m_move_history; int m_move_speed; + bool m_move_checkwarp; bool m_ui_minidialog_loop; int m_ui_minidialog_loop_index; int m_ui_minidialog_click_index; int m_ui_learn_skill_confirm; + int m_ui_forget_skill_index; int m_desired_player_enable_flags; int m_change_player_enable_flags; bool m_ui_craftdialog_click_begin; bool m_ui_craftdialog_loop; int m_ui_craftdialog_loop_index; int m_ui_craftdialog_click_index; - int m_ui_craftdialog_additem[5]; + int m_ui_craftdialog_additem[6]; int m_ui_craftdialog_additemcount; int m_work_acceleration; + bool m_ui_noswitchanim; + int m_player_menu_type; + int m_unit_menu_type; + bool m_work_immediate; game_type m_game_type; @@ -780,5 +919,19 @@ namespace CGA #define WM_CGA_GET_CRAFTS_INFO WM_USER+10039 #define WM_CGA_ASSESS_ITEM WM_USER+10040 #define WM_CGA_GET_BANK_ITEMS_INFO WM_USER+10041 +#define WM_CGA_DO_REQUEST WM_USER+10042 +#define WM_CGA_TRADE_ADD_STUFFS WM_USER+10043 +#define WM_CGA_GET_TEAM_PLAYERS_INFO WM_USER+10044 +#define WM_CGA_FIX_WARP_STUCK WM_USER+10045 +#define WM_CGA_GET_MOVE_HISTORY WM_USER+10046 +#define WM_CGA_ENABLE_FLAGS WM_USER+10047 +#define WM_CGA_PLAYER_MENU_SELECT WM_USER+10048 +#define WM_CGA_UNIT_MENU_SELECT WM_USER+10049 +#define WM_CGA_SET_WINDOW_RESOLUTION WM_USER+10050 +#define WM_CGA_REQUEST_DOWNLOAD_MAP WM_USER+10051 +#define WM_CGA_GET_COLLISION_TABLE WM_USER+10052 +#define WM_CGA_GET_OBJECT_TABLE WM_USER+10053 +#define WM_CGA_GET_MAP_NAME WM_USER+10054 +#define WM_CGA_DROP_PET WM_USER+10055 #define CGA_PORT_BASE 4396 \ No newline at end of file diff --git a/cgahook/main.cpp b/cgahook/main.cpp index 69e8b41..3682f25 100644 --- a/cgahook/main.cpp +++ b/cgahook/main.cpp @@ -3,6 +3,7 @@ DWORD WINAPI CGAServerThread(LPVOID); LRESULT CALLBACK NewWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); +LONG WINAPI MinidumpCallback(EXCEPTION_POINTERS* pException); extern CGA::CGAService g_CGAService; int g_MainPort = 0; @@ -94,14 +95,12 @@ LRESULT CALLBACK NewWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPara return g_CGAService.WM_BattlePetSkillAttack(wParam, lParam) ? 1 : 0; case WM_CGA_DROP_ITEM: return g_CGAService.WM_DropItem(wParam) ? 1 : 0; + case WM_CGA_DROP_PET: + return g_CGAService.WM_DropPet(wParam) ? 1 : 0; case WM_CGA_USE_ITEM: return g_CGAService.WM_UseItem(wParam) ? 1 : 0; case WM_CGA_MOVE_ITEM: return g_CGAService.WM_MoveItem((CGA::cga_move_item_t *)wParam) ? 1 : 0; - //case WM_CGA_PLAYER_MENU_SELECT: - // return g_CGAService.WM_PlayerMenuSelect(wParam) ? 1 : 0; - //case WM_CGA_UNIT_MENU_SELECT: - // return g_CGAService.WM_UnitMenuSelect(wParam) ? 1 : 0; case WM_CGA_LOG_BACK: g_CGAService.WM_LogBack(); return 1; @@ -111,6 +110,9 @@ LRESULT CALLBACK NewWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPara case WM_CGA_GET_MAP_UNITS: g_CGAService.WM_GetMapUnits((CGA::cga_map_units_t *)wParam); return 1; + case WM_CGA_GET_MAP_NAME: + g_CGAService.WM_GetMapName((std::string *)wParam); + return 1; case WM_CGA_GET_PET_INFO: g_CGAService.WM_GetPetInfo(wParam, (CGA::cga_pet_info_t *)lParam); return 1; @@ -180,6 +182,38 @@ LRESULT CALLBACK NewWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPara return g_CGAService.WM_ForceMoveTo(wParam & 0xFFFF, (wParam >> 16) & 0xFFFF, lParam ? true : false) ? 1 : 0; case WM_CGA_ASSESS_ITEM: return g_CGAService.WM_AssessItem(wParam, lParam); + case WM_CGA_DO_REQUEST: + return g_CGAService.WM_DoRequest((int)wParam) ? true : false; + case WM_CGA_TRADE_ADD_STUFFS: + g_CGAService.WM_TradeAddStuffs((CGA::cga_trade_stuff_t *)wParam); + return 1; + case WM_CGA_GET_TEAM_PLAYERS_INFO: + g_CGAService.WM_GetTeamPlayerInfo((CGA::cga_team_players_t *)wParam); + return 1; + case WM_CGA_FIX_WARP_STUCK: + g_CGAService.WM_FixMapWarpStuck((int)wParam); + return 1; + case WM_CGA_GET_MOVE_HISTORY: + g_CGAService.WM_GetMoveHistory((std::vector *)wParam); + return 1; + case WM_CGA_ENABLE_FLAGS: + return g_CGAService.WM_EnableFlags((int)wParam, lParam ? true : false) ? true : false; + case WM_CGA_PLAYER_MENU_SELECT: + return g_CGAService.WM_PlayerMenuSelect((int)wParam, (const char *)lParam) ? true : false; + case WM_CGA_UNIT_MENU_SELECT: + return g_CGAService.WM_UnitMenuSelect((int)wParam) ? true : false; + case WM_CGA_SET_WINDOW_RESOLUTION: + g_CGAService.WM_SetWindowResolution((int)wParam, (int)lParam); + return 1; + case WM_CGA_REQUEST_DOWNLOAD_MAP: + g_CGAService.WM_RequestDownloadMap((int)wParam & 0xffff, (int)lParam & 0xffff, (int)(wParam >> 16) & 0xffff, (int)(lParam >> 16) & 0xffff); + return 1; + case WM_CGA_GET_COLLISION_TABLE: + g_CGAService.WM_GetMapCollisionTable(wParam ? true : false, (CGA::cga_map_cells_t *)lParam); + return 1; + case WM_CGA_GET_OBJECT_TABLE: + g_CGAService.WM_GetMapObjectTable(wParam ? true : false, (CGA::cga_map_cells_t *)lParam); + return 1; } return CallWindowProcA(g_OldProc, hWnd, message, wParam, lParam); @@ -190,6 +224,8 @@ void InitializeHooks(int ThreadId, HWND hWnd, CGA::game_type type) g_MainThreadId = ThreadId; g_MainHwnd = hWnd; + SetUnhandledExceptionFilter(MinidumpCallback); + g_CGAService.Initialize(type); g_OldProc = (WNDPROC)GetWindowLongPtrA(hWnd, GWL_WNDPROC); diff --git a/cgahook/server.cpp b/cgahook/server.cpp index c8bd2c1..81bee2e 100644 --- a/cgahook/server.cpp +++ b/cgahook/server.cpp @@ -8,7 +8,7 @@ using server_t = timax::rpc::server; -size_t pool_size = std::thread::hardware_concurrency(); +size_t pool_size = 8; std::shared_ptr server; extern CGA::CGAService g_CGAService; @@ -65,6 +65,27 @@ void CGA_NotifyChatMsg(const CGA::cga_chat_msg_t &msg) } } +void CGA_NotifyTradeStuffs(const CGA::cga_trade_stuff_info_t &msg) +{ + if (server && server.get()) { + server->pub("NotifyTradeStuffs", msg); + } +} + +void CGA_NotifyTradeDialog(const CGA::cga_trade_dialog_t &msg) +{ + if (server && server.get()) { + server->pub("NotifyTradeDialog", msg); + } +} + +void CGA_NotifyTradeState(int state) +{ + if (server && server.get()) { + server->pub("NotifyTradeState", state); + } +} + BOOL CGA_CreatePortMutex(int port) { WCHAR szMutex[64]; @@ -121,7 +142,7 @@ DWORD WINAPI CGAServerThread(LPVOID) g_hQuitEvent = CreateEventW(NULL, TRUE, FALSE, NULL); - for (uint16_t port = CGA_PORT_BASE; port < CGA_PORT_BASE + 10; port++) + for (uint16_t port = CGA_PORT_BASE; port < CGA_PORT_BASE + 100; port++) { DWORD dwWait = WAIT_OBJECT_0; @@ -131,7 +152,7 @@ DWORD WINAPI CGAServerThread(LPVOID) try { - server = std::make_shared(port, pool_size, std::chrono::seconds{ 2 }); + server = std::make_shared(port, pool_size, std::chrono::seconds{ 10 }); server->register_handler("Initialize", timax::bind(&CGAService::InitializeGameData, &g_CGAService)); server->register_handler("Connect", timax::bind(&CGAService::Connect, &g_CGAService)); server->register_handler("IsInGame", timax::bind(&CGAService::IsInGame, &g_CGAService)); @@ -156,9 +177,12 @@ DWORD WINAPI CGAServerThread(LPVOID) server->register_handler("GetPetSkillsInfo", timax::bind(&CGAService::GetPetSkillsInfo, &g_CGAService)); server->register_handler("GetMapName", timax::bind(&CGAService::GetMapName, &g_CGAService)); + server->register_handler("GetMapIndex", timax::bind(&CGAService::GetMapIndex, &g_CGAService)); server->register_handler("GetMapXY", timax::bind(&CGAService::GetMapXY, &g_CGAService)); server->register_handler("GetMapXYFloat", timax::bind(&CGAService::GetMapXYFloat, &g_CGAService)); server->register_handler("GetMapUnits", timax::bind(&CGAService::GetMapUnits, &g_CGAService)); + server->register_handler("GetMapCollisionTable", timax::bind(&CGAService::GetMapCollisionTable, &g_CGAService)); + server->register_handler("GetMapObjectTable", timax::bind(&CGAService::GetMapObjectTable, &g_CGAService)); server->register_handler("GetMoveSpeed", timax::bind(&CGAService::GetMoveSpeed, &g_CGAService)); server->register_handler("WalkTo", timax::bind(&CGAService::WalkTo, &g_CGAService)); @@ -178,6 +202,7 @@ DWORD WINAPI CGAServerThread(LPVOID) server->register_handler("DropItem", timax::bind(&CGAService::DropItem, &g_CGAService)); server->register_handler("UseItem", timax::bind(&CGAService::UseItem, &g_CGAService)); server->register_handler("MoveItem", timax::bind(&CGAService::MoveItem, &g_CGAService)); + server->register_handler("DropPet", timax::bind(&CGAService::DropPet, &g_CGAService)); server->register_handler("ClickNPCDialog", timax::bind(&CGAService::ClickNPCDialog, &g_CGAService)); server->register_handler("SellNPCStore", timax::bind(&CGAService::SellNPCStore, &g_CGAService)); @@ -188,10 +213,7 @@ DWORD WINAPI CGAServerThread(LPVOID) server->register_handler("IsBattleUnitValid", timax::bind(&CGAService::IsBattleUnitValid, &g_CGAService)); server->register_handler("GetBattleUnit", timax::bind(&CGAService::GetBattleUnit, &g_CGAService)); server->register_handler("GetBattleUnits", timax::bind(&CGAService::GetBattleUnits, &g_CGAService)); - server->register_handler("GetBattleRoundCount", timax::bind(&CGAService::GetBattleRoundCount, &g_CGAService)); - server->register_handler("GetBattlePlayerPosition", timax::bind(&CGAService::GetBattlePlayerPosition, &g_CGAService)); - server->register_handler("GetBattlePlayerStatus", timax::bind(&CGAService::GetBattlePlayerStatus, &g_CGAService)); - server->register_handler("GetBattlePetId", timax::bind(&CGAService::GetBattlePetId, &g_CGAService)); + server->register_handler("GetBattleContext", timax::bind(&CGAService::GetBattleContext, &g_CGAService)); server->register_handler("BattleNormalAttack", timax::bind(&CGAService::BattleNormalAttack, &g_CGAService)); server->register_handler("BattleSkillAttack", timax::bind(&CGAService::BattleSkillAttack, &g_CGAService)); server->register_handler("BattleDefense", timax::bind(&CGAService::BattleDefense, &g_CGAService)); @@ -208,10 +230,21 @@ DWORD WINAPI CGAServerThread(LPVOID) server->register_handler("SetWorkDelay", timax::bind(&CGAService::SetWorkDelay, &g_CGAService)); server->register_handler("StartWork", timax::bind(&CGAService::StartWork, &g_CGAService)); server->register_handler("SetWorkAcceleration", timax::bind(&CGAService::SetWorkAcceleration, &g_CGAService)); + server->register_handler("SetImmediateDoneWork", timax::bind(&CGAService::SetImmediateDoneWork, &g_CGAService)); server->register_handler("CraftItem", timax::bind(&CGAService::CraftItem, &g_CGAService)); server->register_handler("AssessItem", timax::bind(&CGAService::AssessItem, &g_CGAService)); server->register_handler("GetCraftInfo", timax::bind(&CGAService::GetCraftInfo, &g_CGAService)); server->register_handler("GetCraftsInfo", timax::bind(&CGAService::GetCraftsInfo, &g_CGAService)); + server->register_handler("AssessItem", timax::bind(&CGAService::AssessItem, &g_CGAService)); + server->register_handler("DoRequest", timax::bind(&CGAService::DoRequest, &g_CGAService)); + server->register_handler("TradeAddStuffs", timax::bind(&CGAService::TradeAddStuffs, &g_CGAService)); + server->register_handler("GetTeamPlayerInfo", timax::bind(&CGAService::GetTeamPlayerInfo, &g_CGAService)); + server->register_handler("FixMapWarpStuck", timax::bind(&CGAService::FixMapWarpStuck, &g_CGAService)); + server->register_handler("SetNoSwitchAnim", timax::bind(&CGAService::SetNoSwitchAnim, &g_CGAService)); + server->register_handler("GetMoveHistory", timax::bind(&CGAService::GetMoveHistory, &g_CGAService)); + server->register_handler("EnableFlags", timax::bind(&CGAService::EnableFlags, &g_CGAService)); + server->register_handler("SetWindowResolution", timax::bind(&CGAService::SetWindowResolution, &g_CGAService)); + server->register_handler("RequestDownloadMap", timax::bind(&CGAService::RequestDownloadMap, &g_CGAService)); server->start(); dwWait = WaitForSingleObject(g_hQuitEvent, INFINITE);