diff --git a/CAPI/cpp/API/include/API.h b/CAPI/cpp/API/include/API.h index e46c66cd..bd1e79e0 100755 --- a/CAPI/cpp/API/include/API.h +++ b/CAPI/cpp/API/include/API.h @@ -67,12 +67,12 @@ class ILogic virtual bool Rebuild(THUAI7::ConstructionType constructionType) = 0; virtual bool Construct(THUAI7::ConstructionType constructionType) = 0; virtual bool Attack(double angle) = 0; - [[nodiscard]] virtual bool HaveView(int32_t gridX, int32_t gridY, int32_t selfX, int32_t selfY, int32_t viewRange) const = 0; + [[nodiscard]] virtual bool HaveView(int32_t selfX, int32_t selfY, int32_t targetX, int32_t targetY, int32_t viewRange) const = 0; // Team使用的部分 virtual bool Recycle(int64_t playerID) = 0; virtual bool InstallModule(int64_t playerID, THUAI7::ModuleType moduleType) = 0; - virtual bool BuildSweeper(THUAI7::SweeperType SweeperType, int32_t cellX, int32_t cellY) = 0; + virtual bool BuildSweeper(THUAI7::SweeperType SweeperType) = 0; }; class IAPI @@ -142,7 +142,7 @@ class ISweeperAPI : public IAPI virtual std::future Rebuild(THUAI7::ConstructionType constructionType) = 0; virtual std::future Construct(THUAI7::ConstructionType constructionType) = 0; virtual std::shared_ptr GetSelfInfo() const = 0; - virtual bool HaveView(int32_t gridX, int32_t gridY) const = 0; + virtual bool HaveView(int32_t targetX, int32_t targetY) const = 0; }; class ITeamAPI : public IAPI @@ -151,7 +151,7 @@ class ITeamAPI : public IAPI [[nodiscard]] virtual std::shared_ptr GetSelfInfo() const = 0; virtual std::future InstallModule(int64_t playerID, THUAI7::ModuleType moduletype) = 0; virtual std::future Recycle(int64_t playerID) = 0; - virtual std::future BuildSweeper(THUAI7::SweeperType SweeperType, int32_t cellX, int32_t cellY) = 0; + virtual std::future BuildSweeper(THUAI7::SweeperType SweeperType) = 0; }; class IGameTimer @@ -206,13 +206,13 @@ class SweeperAPI : public ISweeperAPI, public IGameTimer [[nodiscard]] int32_t GetConstructionHp(int32_t cellX, int32_t cellY) const override; [[nodiscard]] int32_t GetBridgeHp(int32_t x, int32_t y) const override; [[nodiscard]] int32_t GetGarbageState(int32_t cellX, int32_t cellY) const override; - [[nodiscard]] int32_t GetHomeHp() const override; [[nodiscard]] std::shared_ptr GetGameInfo() const override; - [[nodiscard]] std::vector GetPlayerGUIDs() const override; - [[nodiscard]] std::shared_ptr GetSelfInfo() const override; - [[nodiscard]] bool HaveView(int32_t gridX, int32_t gridY) const override; + [[nodiscard]] int32_t GetHomeHp() const override; [[nodiscard]] int32_t GetEnergy() const override; [[nodiscard]] int32_t GetScore() const override; + [[nodiscard]] std::vector GetPlayerGUIDs() const override; + [[nodiscard]] std::shared_ptr GetSelfInfo() const override; + [[nodiscard]] bool HaveView(int32_t targetX, int32_t targetY) const override; void Print(std::string str) const { } @@ -271,7 +271,7 @@ class TeamAPI : public ITeamAPI, public IGameTimer [[nodiscard]] int32_t GetEnergy() const override; std::future InstallModule(int64_t playerID, THUAI7::ModuleType moduleType) override; std::future Recycle(int64_t playerID) override; - std::future BuildSweeper(THUAI7::SweeperType SweeperType, int32_t cellX, int32_t cellY) override; + std::future BuildSweeper(THUAI7::SweeperType SweeperType) override; void Print(std::string str) const { } @@ -327,7 +327,7 @@ class SweeperDebugAPI : public ISweeperAPI, public IGameTimer [[nodiscard]] std::shared_ptr GetGameInfo() const override; [[nodiscard]] std::vector GetPlayerGUIDs() const override; [[nodiscard]] std::shared_ptr GetSelfInfo() const override; - [[nodiscard]] bool HaveView(int32_t gridX, int32_t gridY) const override; + [[nodiscard]] bool HaveView(int32_t targetX, int32_t targetY) const override; [[nodiscard]] int32_t GetEnergy() const override; [[nodiscard]] int32_t GetScore() const override; @@ -378,7 +378,7 @@ class TeamDebugAPI : public ITeamAPI, public IGameTimer [[nodiscard]] int32_t GetEnergy() const override; std::future InstallModule(int64_t playerID, THUAI7::ModuleType moduleType) override; std::future Recycle(int64_t playerID) override; - std::future BuildSweeper(THUAI7::SweeperType SweeperType, int32_t cellX, int32_t cellY) override; + std::future BuildSweeper(THUAI7::SweeperType SweeperType) override; void Print(std::string str) const override; void PrintSelfInfo() const override; // TODO diff --git a/CAPI/cpp/API/include/Communication.h b/CAPI/cpp/API/include/Communication.h index 649503c7..df3fc3e2 100755 --- a/CAPI/cpp/API/include/Communication.h +++ b/CAPI/cpp/API/include/Communication.h @@ -41,7 +41,7 @@ class Communication bool Send(int64_t playerID, int64_t toPlayerID, int64_t teamID, std::string message, bool binary); // Team bool InstallModule(int64_t playerID, int64_t teamID, THUAI7::ModuleType moduleType); - bool BuildSweeper(int64_t teamID, THUAI7::SweeperType SweeperType, int32_t x, int32_t y); + bool BuildSweeper(int64_t teamID, THUAI7::SweeperType SweeperType); bool Recycle(int64_t playerID, int64_t teamID); private: diff --git a/CAPI/cpp/API/include/logic.h b/CAPI/cpp/API/include/logic.h index a0fa47bc..3f16cfdc 100755 --- a/CAPI/cpp/API/include/logic.h +++ b/CAPI/cpp/API/include/logic.h @@ -120,12 +120,12 @@ class Logic : public ILogic bool Rebuild(THUAI7::ConstructionType constructionType); bool Construct(THUAI7::ConstructionType constructionType); bool Attack(double angle); - [[nodiscard]] bool HaveView(int32_t gridX, int32_t gridY, int32_t selfX, int32_t selfY, int32_t viewRange) const; + [[nodiscard]] bool HaveView(int32_t selfX, int32_t selfY, int32_t targetX, int32_t targetY, int32_t viewRange) const; // ITeamAPI bool Recycle(int64_t playerID); bool InstallModule(int64_t playerID, THUAI7::ModuleType moduleType); - bool BuildSweeper(THUAI7::SweeperType SweeperType, int32_t cellX, int32_t cellY); + bool BuildSweeper(THUAI7::SweeperType SweeperType); bool TryConnection(); void ProcessMessage(); diff --git a/CAPI/cpp/API/include/state.h b/CAPI/cpp/API/include/state.h index 20c8b70f..38f0905e 100755 --- a/CAPI/cpp/API/include/state.h +++ b/CAPI/cpp/API/include/state.h @@ -20,7 +20,6 @@ struct State std::shared_ptr teamSelf; std::vector> sweepers; std::vector> enemySweepers; - std::shared_ptr enemyTeam; std::vector> bullets; std::vector> gameMap; std::shared_ptr mapInfo; diff --git a/CAPI/cpp/API/include/structures.h b/CAPI/cpp/API/include/structures.h index ee1982b3..2b2a4787 100755 --- a/CAPI/cpp/API/include/structures.h +++ b/CAPI/cpp/API/include/structures.h @@ -259,7 +259,7 @@ namespace THUAI7 std::map, std::pair> recycleBankState; std::map, std::pair> chargeStationState; std::map, std::pair> signalTowerState; - std::map, std::pair> HomeState; + std::map, std::pair> homeState; std::map, int32_t> bridgeState; std::map, int32_t> garbageState; }; diff --git a/CAPI/cpp/API/include/utils.hpp b/CAPI/cpp/API/include/utils.hpp index 9fae134d..5279d05b 100755 --- a/CAPI/cpp/API/include/utils.hpp +++ b/CAPI/cpp/API/include/utils.hpp @@ -520,12 +520,10 @@ namespace THUAI72Proto return installMsg; } - inline protobuf::BuildSweeperMsg THUAI72ProtobufBuildSweeperMsg(int64_t teamID, THUAI7::SweeperType SweeperType, int32_t x, int32_t y) + inline protobuf::BuildSweeperMsg THUAI72ProtobufBuildSweeperMsg(int64_t teamID, THUAI7::SweeperType SweeperType) { protobuf::BuildSweeperMsg buildSweeperMsg; buildSweeperMsg.set_team_id(teamID); - buildSweeperMsg.set_x(x); - buildSweeperMsg.set_y(y); buildSweeperMsg.set_sweeper_type(THUAI72Proto::sweeperTypeDict[SweeperType]); return buildSweeperMsg; } diff --git a/CAPI/cpp/API/src/AI.cpp b/CAPI/cpp/API/src/AI.cpp index 95e6669c..996b690e 100755 --- a/CAPI/cpp/API/src/AI.cpp +++ b/CAPI/cpp/API/src/AI.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "AI.h" #include "constants.h" // 注意不要使用conio.h,Windows.h等非标准库 @@ -21,25 +22,29 @@ void AI::play(ISweeperAPI& api) { if (this->playerID == 1) { - // 玩家1执行操作 + api.Move(10, 2.1); + api.PrintSelfInfo(); + api.Attack(1.1); } else if (this->playerID == 2) { - // 玩家2执行操作 + api.Move(10, 2.1); + api.PrintSelfInfo(); } else if (this->playerID == 3) { - // 玩家3执行操作 + api.Move(10, 2.1); + api.PrintSelfInfo(); } else if (this->playerID == 4) { - // 玩家4执行操作 + api.Move(10, 2.1); + api.PrintSelfInfo(); } } void AI::play(ITeamAPI& api) // 默认team playerID 为0 { - auto self = api.GetSelfInfo(); api.PrintSelfInfo(); } diff --git a/CAPI/cpp/API/src/API.cpp b/CAPI/cpp/API/src/API.cpp index 1d0cc7ce..c0bac344 100755 --- a/CAPI/cpp/API/src/API.cpp +++ b/CAPI/cpp/API/src/API.cpp @@ -287,10 +287,10 @@ std::future SweeperAPI::Construct(THUAI7::ConstructionType constructionTyp { return logic.Construct(constructionType); }); } -bool SweeperAPI::HaveView(int32_t gridX, int32_t gridY) const +bool SweeperAPI::HaveView(int32_t targetX, int32_t targetY) const { auto selfInfo = GetSelfInfo(); - return logic.HaveView(gridX, gridY, selfInfo->x, selfInfo->y, selfInfo->viewRange); + return logic.HaveView(targetX, targetY, selfInfo->x, selfInfo->y, selfInfo->viewRange); } // Team独有 @@ -306,10 +306,10 @@ std::future TeamAPI::Recycle(int64_t playerID) { return logic.Recycle(playerID); }); } -std::future TeamAPI::BuildSweeper(THUAI7::SweeperType SweeperType, int32_t x, int32_t y) +std::future TeamAPI::BuildSweeper(THUAI7::SweeperType SweeperType) { return std::async(std::launch::async, [=]() - { return logic.BuildSweeper(SweeperType, x, y); }); + { return logic.BuildSweeper(SweeperType); }); } void SweeperAPI::Play(IAI& ai) diff --git a/CAPI/cpp/API/src/Communication.cpp b/CAPI/cpp/API/src/Communication.cpp index dcb2503d..db207f9d 100755 --- a/CAPI/cpp/API/src/Communication.cpp +++ b/CAPI/cpp/API/src/Communication.cpp @@ -187,11 +187,11 @@ bool Communication::Attack(int64_t playerID, int64_t teamID, double angle) return false; } -bool Communication::BuildSweeper(int64_t teamID, THUAI7::SweeperType SweeperType, int32_t x, int32_t y) +bool Communication::BuildSweeper(int64_t teamID, THUAI7::SweeperType SweeperType) { protobuf::BoolRes reply; ClientContext context; - auto request = THUAI72Proto::THUAI72ProtobufBuildSweeperMsg(teamID, SweeperType, x, y); + auto request = THUAI72Proto::THUAI72ProtobufBuildSweeperMsg(teamID, SweeperType); auto status = THUAI7Stub->BuildSweeper(&context, request, &reply); if (status.ok()) return true; diff --git a/CAPI/cpp/API/src/DebugAPI.cpp b/CAPI/cpp/API/src/DebugAPI.cpp index 64412d33..d6da5219 100755 --- a/CAPI/cpp/API/src/DebugAPI.cpp +++ b/CAPI/cpp/API/src/DebugAPI.cpp @@ -220,10 +220,10 @@ std::shared_ptr SweeperDebugAPI::GetSelfInfo() const return logic.SweeperGetSelfInfo(); } -bool SweeperDebugAPI::HaveView(int32_t gridX, int32_t gridY) const +bool SweeperDebugAPI::HaveView(int32_t targetX, int32_t targetY) const { auto selfInfo = GetSelfInfo(); - return logic.HaveView(gridX, gridY, selfInfo->x, selfInfo->y, selfInfo->viewRange); + return logic.HaveView(targetX, targetY, selfInfo->x, selfInfo->y, selfInfo->viewRange); } int32_t SweeperDebugAPI::GetEnergy() const @@ -436,10 +436,10 @@ std::future TeamDebugAPI::Recycle(int64_t playerID) { return logic.Recycle(playerID); }); } -std::future TeamDebugAPI::BuildSweeper(THUAI7::SweeperType SweeperType, int32_t x, int32_t y) +std::future TeamDebugAPI::BuildSweeper(THUAI7::SweeperType SweeperType) { return std::async(std::launch::async, [=]() - { return logic.BuildSweeper(SweeperType, x, y); }); + { return logic.BuildSweeper(SweeperType); }); } void TeamDebugAPI::PrintSelfInfo() const diff --git a/CAPI/cpp/API/src/logic.cpp b/CAPI/cpp/API/src/logic.cpp index 85e9f6af..f6d230e5 100755 --- a/CAPI/cpp/API/src/logic.cpp +++ b/CAPI/cpp/API/src/logic.cpp @@ -242,10 +242,10 @@ bool Logic::Construct(THUAI7::ConstructionType constructiontype) return pComm->Construct(playerID, teamID, constructiontype); } -bool Logic::BuildSweeper(THUAI7::SweeperType Sweepertype, int32_t x, int32_t y) +bool Logic::BuildSweeper(THUAI7::SweeperType Sweepertype) { logger->debug("Called BuildSweeper"); - return pComm->BuildSweeper(teamID, Sweepertype, x, y); + return pComm->BuildSweeper(teamID, Sweepertype); } // 等待完成 @@ -377,39 +377,31 @@ void Logic::LoadBufferSelf(const protobuf::MessageToClient& message) { for (const auto& item : message.obj_message()) { - if (Proto2THUAI7::messageOfObjDict[item.message_of_obj_case()] == THUAI7::MessageOfObj::SweeperMessage && item.sweeper_message().team_id() == teamID) + if (Proto2THUAI7::messageOfObjDict[item.message_of_obj_case()] == THUAI7::MessageOfObj::SweeperMessage) { - if (item.sweeper_message().player_id() == playerID) + if (item.sweeper_message().player_id() == playerID && item.sweeper_message().team_id() == teamID) { bufferState->sweeperSelf = Proto2THUAI7::Protobuf2THUAI7Sweeper(item.sweeper_message()); bufferState->sweepers.push_back(bufferState->sweeperSelf); - logger->debug("Add Self Sweeper!"); - } - else - { - std::shared_ptr Sweeper = Proto2THUAI7::Protobuf2THUAI7Sweeper(item.sweeper_message()); - bufferState->sweepers.push_back(Sweeper); - logger->debug("Add Sweeper!"); + logger->debug("Load Self Sweeper!"); } } } } - else // 本身是Team + else if (playerType == THUAI7::PlayerType::Team) { for (const auto& item : message.obj_message()) { - if (Proto2THUAI7::messageOfObjDict[item.message_of_obj_case()] == THUAI7::MessageOfObj::TeamMessage) + if (Proto2THUAI7::messageOfObjDict[item.message_of_obj_case()] == THUAI7::MessageOfObj::TeamMessage && item.team_message().team_id() == teamID) { - if (item.team_message().team_id() == teamID) - { - bufferState->teamSelf = Proto2THUAI7::Protobuf2THUAI7Team(item.team_message()); - logger->debug("Add Self Team!"); - } - else - { - bufferState->enemyTeam = Proto2THUAI7::Protobuf2THUAI7Team(item.team_message()); - logger->debug("Add Enemy Team!"); - } + bufferState->teamSelf = Proto2THUAI7::Protobuf2THUAI7Team(item.team_message()); + logger->debug("Load Self Team!"); + } + else if (Proto2THUAI7::messageOfObjDict[item.message_of_obj_case()] == THUAI7::MessageOfObj::SweeperMessage && item.team_message().team_id() == teamID) + { + std::shared_ptr Sweeper = Proto2THUAI7::Protobuf2THUAI7Sweeper(item.sweeper_message()); + bufferState->sweepers.push_back(Sweeper); + logger->debug("Load Sweeper!"); } } } @@ -430,15 +422,51 @@ void Logic::LoadBufferCase(const protobuf::MessageOfObj& item) { std::shared_ptr Sweeper = Proto2THUAI7::Protobuf2THUAI7Sweeper(item.sweeper_message()); bufferState->enemySweepers.push_back(Sweeper); - logger->debug("Add EnemySweeper!"); + logger->debug("Load EnemySweeper!"); } } + else if (teamID == item.sweeper_message().team_id() && playerID != item.sweeper_message().player_id()) + { + std::shared_ptr Sweeper = Proto2THUAI7::Protobuf2THUAI7Sweeper(item.sweeper_message()); + bufferState->sweepers.push_back(Sweeper); + logger->debug("Load Sweeper!"); + } break; case THUAI7::MessageOfObj::BulletMessage: - if (AssistFunction::HaveView(x, y, item.bullet_message().x(), item.bullet_message().y(), viewRange, bufferState->gameMap)) + if (item.bullet_message().team_id() != teamID && AssistFunction::HaveView(x, y, item.bullet_message().x(), item.bullet_message().y(), viewRange, bufferState->gameMap)) { bufferState->bullets.push_back(Proto2THUAI7::Protobuf2THUAI7Bullet(item.bullet_message())); - logger->debug("Add Bullet!"); + logger->debug("Load Bullet!"); + } + break; + case THUAI7::MessageOfObj::HomeMessage: + if (item.home_message().team_id() == teamID) + { + auto pos = std::make_pair(AssistFunction::GridToCell(item.home_message().x()), AssistFunction::GridToCell(item.home_message().y())); + if (bufferState->mapInfo->homeState.count(pos) == 0) + { + bufferState->mapInfo->homeState.emplace(pos, std::make_pair(item.home_message().team_id(), item.home_message().hp())); + logger->debug("Load Home!"); + } + else + { + bufferState->mapInfo->homeState[pos].second = item.home_message().hp(); + logger->debug("Update Home!"); + } + } + else if (AssistFunction::HaveView(x, y, item.home_message().x(), item.home_message().y(), viewRange, bufferState->gameMap)) + { + auto pos = std::make_pair(AssistFunction::GridToCell(item.home_message().x()), AssistFunction::GridToCell(item.home_message().y())); + if (bufferState->mapInfo->homeState.count(pos) == 0) + { + bufferState->mapInfo->homeState.emplace(pos, std::make_pair(item.home_message().team_id(), item.home_message().hp())); + logger->debug("Load Home!"); + } + else + { + bufferState->mapInfo->homeState[pos].second = item.home_message().hp(); + logger->debug("Update Home!"); + } } break; case THUAI7::MessageOfObj::RecycleBankMessage: @@ -448,7 +476,7 @@ void Logic::LoadBufferCase(const protobuf::MessageOfObj& item) if (bufferState->mapInfo->recycleBankState.count(pos) == 0) { bufferState->mapInfo->recycleBankState.emplace(pos, std::make_pair(item.recyclebank_message().team_id(), item.recyclebank_message().hp())); - logger->debug("Add RecycleBank!"); + logger->debug("Load RecycleBank!"); } else { @@ -462,7 +490,7 @@ void Logic::LoadBufferCase(const protobuf::MessageOfObj& item) if (bufferState->mapInfo->recycleBankState.count(pos) == 0) { bufferState->mapInfo->recycleBankState.emplace(pos, std::make_pair(item.recyclebank_message().team_id(), item.recyclebank_message().hp())); - logger->debug("Add RecycleBank!"); + logger->debug("Load RecycleBank!"); } else { @@ -478,7 +506,7 @@ void Logic::LoadBufferCase(const protobuf::MessageOfObj& item) if (bufferState->mapInfo->chargeStationState.count(pos) == 0) { bufferState->mapInfo->chargeStationState.emplace(pos, std::make_pair(item.chargestation_message().team_id(), item.chargestation_message().hp())); - logger->debug("Add ChargeStation!"); + logger->debug("Load ChargeStation!"); } else { @@ -492,7 +520,7 @@ void Logic::LoadBufferCase(const protobuf::MessageOfObj& item) if (bufferState->mapInfo->chargeStationState.count(pos) == 0) { bufferState->mapInfo->chargeStationState.emplace(pos, std::make_pair(item.chargestation_message().team_id(), item.chargestation_message().hp())); - logger->debug("Add ChargeStation!"); + logger->debug("Load ChargeStation!"); } else { @@ -508,7 +536,7 @@ void Logic::LoadBufferCase(const protobuf::MessageOfObj& item) if (bufferState->mapInfo->signalTowerState.count(pos) == 0) { bufferState->mapInfo->signalTowerState.emplace(pos, std::make_pair(item.signaltower_message().team_id(), item.signaltower_message().hp())); - logger->debug("Add SignalTower!"); + logger->debug("Load SignalTower!"); } else { @@ -522,7 +550,7 @@ void Logic::LoadBufferCase(const protobuf::MessageOfObj& item) if (bufferState->mapInfo->signalTowerState.count(pos) == 0) { bufferState->mapInfo->signalTowerState.emplace(pos, std::make_pair(item.signaltower_message().team_id(), item.signaltower_message().hp())); - logger->debug("Add SignalTower!"); + logger->debug("Load SignalTower!"); } else { @@ -538,7 +566,7 @@ void Logic::LoadBufferCase(const protobuf::MessageOfObj& item) if (bufferState->mapInfo->bridgeState.count(pos) == 0) { bufferState->mapInfo->bridgeState.emplace(pos, item.bridge_message().hp()); - logger->debug("Add Bridge!"); + logger->debug("Load Bridge!"); } else { @@ -554,7 +582,7 @@ void Logic::LoadBufferCase(const protobuf::MessageOfObj& item) if (bufferState->mapInfo->garbageState.count(pos) == 0) { bufferState->mapInfo->garbageState.emplace(pos, item.garbage_message().progress()); - logger->debug("Add Garbage!"); + logger->debug("Load Garbage!"); } else { @@ -566,17 +594,17 @@ void Logic::LoadBufferCase(const protobuf::MessageOfObj& item) case THUAI7::MessageOfObj::NewsMessage: { auto news = item.news_message(); - if (news.to_id() == playerID) + if (news.to_id() == playerID && news.team_id() == teamID) { if (Proto2THUAI7::newsTypeDict[news.news_case()] == THUAI7::NewsType::TextMessage) { messageQueue.emplace(std::make_pair(news.from_id(), news.text_message())); - logger->debug("Add News!"); + logger->debug("Load Text News!"); } else if (Proto2THUAI7::newsTypeDict[news.news_case()] == THUAI7::NewsType::BinaryMessage) { messageQueue.emplace(std::make_pair(news.from_id(), news.binary_message())); - logger->debug("Add Binary News!"); + logger->debug("Load Binary News!"); } else logger->error("Unknown NewsType!"); @@ -588,6 +616,202 @@ void Logic::LoadBufferCase(const protobuf::MessageOfObj& item) break; } } + else if (playerType == THUAI7::PlayerType::Team) + { + auto HaveOverView = [&](int32_t targetX, int32_t targetY) + { + for (const auto& sweeper : bufferState->sweepers) + { + if (AssistFunction::HaveView(sweeper->x, sweeper->y, targetX, targetY, sweeper->viewRange, bufferState->gameMap)) + return true; + } + return false; + }; + switch (Proto2THUAI7::messageOfObjDict[item.message_of_obj_case()]) + { + case THUAI7::MessageOfObj::SweeperMessage: + if (item.sweeper_message().team_id() != teamID && HaveOverView(item.sweeper_message().x(), item.sweeper_message().y())) + { + std::shared_ptr Sweeper = Proto2THUAI7::Protobuf2THUAI7Sweeper(item.sweeper_message()); + bufferState->enemySweepers.push_back(Sweeper); + logger->debug("Load Enemy Sweeper!"); + } + break; + case THUAI7::MessageOfObj::HomeMessage: + if (item.home_message().team_id() == teamID) + { + auto pos = std::make_pair(AssistFunction::GridToCell(item.home_message().x()), AssistFunction::GridToCell(item.home_message().y())); + if (bufferState->mapInfo->homeState.count(pos) == 0) + { + bufferState->mapInfo->homeState.emplace(pos, std::make_pair(item.home_message().team_id(), item.home_message().hp())); + logger->debug("Load Home!"); + } + else + { + bufferState->mapInfo->homeState[pos].second = item.home_message().hp(); + logger->debug("Update Home!"); + } + } + else if (HaveOverView(item.home_message().x(), item.home_message().y())) + { + auto pos = std::make_pair(AssistFunction::GridToCell(item.home_message().x()), AssistFunction::GridToCell(item.home_message().y())); + if (bufferState->mapInfo->homeState.count(pos) == 0) + { + bufferState->mapInfo->homeState.emplace(pos, std::make_pair(item.home_message().team_id(), item.home_message().hp())); + logger->debug("Load Home!"); + } + else + { + bufferState->mapInfo->homeState[pos].second = item.home_message().hp(); + logger->debug("Update Home!"); + } + } + break; + case THUAI7::MessageOfObj::RecycleBankMessage: + if (item.recyclebank_message().team_id() == teamID) + { + auto pos = std::make_pair(AssistFunction::GridToCell(item.recyclebank_message().x()), AssistFunction::GridToCell(item.recyclebank_message().y())); + if (bufferState->mapInfo->recycleBankState.count(pos) == 0) + { + bufferState->mapInfo->recycleBankState.emplace(pos, std::make_pair(item.recyclebank_message().team_id(), item.recyclebank_message().hp())); + logger->debug("Load RecycleBank!"); + } + else + { + bufferState->mapInfo->recycleBankState[pos].second = item.recyclebank_message().hp(); + logger->debug("Update RecycleBank!"); + } + } + else if (HaveOverView(item.recyclebank_message().x(), item.recyclebank_message().y())) + { + auto pos = std::make_pair(AssistFunction::GridToCell(item.recyclebank_message().x()), AssistFunction::GridToCell(item.recyclebank_message().y())); + if (bufferState->mapInfo->recycleBankState.count(pos) == 0) + { + bufferState->mapInfo->recycleBankState.emplace(pos, std::make_pair(item.recyclebank_message().team_id(), item.recyclebank_message().hp())); + logger->debug("Load RecycleBank!"); + } + else + { + bufferState->mapInfo->recycleBankState[pos].second = item.recyclebank_message().hp(); + logger->debug("Update RecycleBank!"); + } + } + break; + case THUAI7::MessageOfObj::ChargeStationMessage: + if (item.chargestation_message().team_id() == teamID) + { + auto pos = std::make_pair(AssistFunction::GridToCell(item.chargestation_message().x()), AssistFunction::GridToCell(item.chargestation_message().y())); + if (bufferState->mapInfo->chargeStationState.count(pos) == 0) + { + bufferState->mapInfo->chargeStationState.emplace(pos, std::make_pair(item.chargestation_message().team_id(), item.chargestation_message().hp())); + logger->debug("Load ChargeStation!"); + } + else + { + bufferState->mapInfo->chargeStationState[pos].second = item.chargestation_message().hp(); + logger->debug("Update ChargeStation!"); + } + } + else if (HaveOverView(item.chargestation_message().x(), item.chargestation_message().y())) + { + auto pos = std::make_pair(AssistFunction::GridToCell(item.chargestation_message().x()), AssistFunction::GridToCell(item.chargestation_message().y())); + if (bufferState->mapInfo->chargeStationState.count(pos) == 0) + { + bufferState->mapInfo->chargeStationState.emplace(pos, std::make_pair(item.chargestation_message().team_id(), item.chargestation_message().hp())); + logger->debug("Load ChargeStation!"); + } + else + { + bufferState->mapInfo->chargeStationState[pos].second = item.chargestation_message().hp(); + logger->debug("Update ChargeStation!"); + } + } + break; + case THUAI7::MessageOfObj::SignalTowerMessage: + if (item.signaltower_message().team_id() == teamID) + { + auto pos = std::make_pair(AssistFunction::GridToCell(item.signaltower_message().x()), AssistFunction::GridToCell(item.signaltower_message().y())); + if (bufferState->mapInfo->signalTowerState.count(pos) == 0) + { + bufferState->mapInfo->signalTowerState.emplace(pos, std::make_pair(item.signaltower_message().team_id(), item.signaltower_message().hp())); + logger->debug("Load SignalTower!"); + } + else + { + bufferState->mapInfo->signalTowerState[pos].second = item.signaltower_message().hp(); + logger->debug("Update SignalTower!"); + } + } + else if (HaveOverView(item.signaltower_message().x(), item.signaltower_message().y())) + { + auto pos = std::make_pair(AssistFunction::GridToCell(item.signaltower_message().x()), AssistFunction::GridToCell(item.signaltower_message().y())); + if (bufferState->mapInfo->signalTowerState.count(pos) == 0) + { + bufferState->mapInfo->signalTowerState.emplace(pos, std::make_pair(item.signaltower_message().team_id(), item.signaltower_message().hp())); + logger->debug("Load SignalTower!"); + } + else + { + bufferState->mapInfo->signalTowerState[pos].second = item.signaltower_message().hp(); + logger->debug("Update SignalTower!"); + } + } + break; + case THUAI7::MessageOfObj::BridgeMessage: + if (HaveOverView(item.bridge_message().x(), item.bridge_message().y())) + { + auto pos = std::make_pair(AssistFunction::GridToCell(item.bridge_message().x()), AssistFunction::GridToCell(item.bridge_message().y())); + if (bufferState->mapInfo->bridgeState.count(pos) == 0) + { + bufferState->mapInfo->bridgeState.emplace(pos, item.bridge_message().hp()); + logger->debug("Load Bridge!"); + } + else + { + bufferState->mapInfo->bridgeState[pos] = item.bridge_message().hp(); + logger->debug("Update Bridge!"); + } + } + break; + case THUAI7::MessageOfObj::GarbageMessage: + if (HaveOverView(item.garbage_message().x(), item.garbage_message().y())) + { + auto pos = std::make_pair(AssistFunction::GridToCell(item.garbage_message().x()), AssistFunction::GridToCell(item.garbage_message().y())); + if (bufferState->mapInfo->garbageState.count(pos) == 0) + { + bufferState->mapInfo->garbageState.emplace(pos, item.garbage_message().progress()); + logger->debug("Load Garbage!"); + } + else + { + bufferState->mapInfo->garbageState[pos] = item.garbage_message().progress(); + logger->debug("Update Garbage!"); + } + } + break; + case THUAI7::MessageOfObj::NewsMessage: + if (item.news_message().team_id() == teamID && item.news_message().to_id() == playerID) + { + auto news = item.news_message(); + if (Proto2THUAI7::newsTypeDict[news.news_case()] == THUAI7::NewsType::TextMessage) + { + messageQueue.emplace(std::make_pair(news.from_id(), news.text_message())); + logger->debug("Load Text News!"); + } + else if (Proto2THUAI7::newsTypeDict[news.news_case()] == THUAI7::NewsType::BinaryMessage) + { + messageQueue.emplace(std::make_pair(news.from_id(), news.binary_message())); + logger->debug("Load Binary News!"); + } + else + logger->error("Unknown NewsType!"); + } + break; + case THUAI7::MessageOfObj::NullMessageOfObj: + default: + break; + } + } } void Logic::LoadBuffer(const protobuf::MessageToClient& message) @@ -688,10 +912,10 @@ bool Logic::TryConnection() return pComm->TryConnection(playerID, teamID); } -bool Logic::HaveView(int32_t gridX, int32_t gridY, int32_t selfX, int32_t selfY, int32_t viewRange) const +bool Logic::HaveView(int32_t selfX, int32_t selfY, int32_t targetX, int32_t targetY, int32_t viewRange) const { std::unique_lock lock(mtxState); - return AssistFunction::HaveView(selfX, selfY, gridX, gridY, viewRange, currentState->gameMap); + return AssistFunction::HaveView(selfX, selfY, targetX, targetY, viewRange, currentState->gameMap); } void Logic::Main(CreateAIFunc createAI, std::string IP, std::string port, bool file, bool print, bool warnOnly) diff --git a/CAPI/cpp/proto/Message2Clients.pb.cc b/CAPI/cpp/proto/Message2Clients.pb.cc index 1d5d702c..ed96d73a 100644 --- a/CAPI/cpp/proto/Message2Clients.pb.cc +++ b/CAPI/cpp/proto/Message2Clients.pb.cc @@ -268,7 +268,7 @@ namespace protobuf ::_pbi::ConstantInitialized ) : _impl_{ - /*decltype(_impl_.team_id_)*/ int64_t{0}, /*decltype(_impl_.player_id_)*/ int64_t{0}, /*decltype(_impl_.score_)*/ 0, /*decltype(_impl_.energy_)*/ 0, /*decltype(_impl_.guid_)*/ int64_t{0}, /*decltype(_impl_._cached_size_)*/ {}} + /*decltype(_impl_.team_id_)*/ int64_t{0}, /*decltype(_impl_.player_id_)*/ int64_t{0}, /*decltype(_impl_.score_)*/ int64_t{0}, /*decltype(_impl_.energy_)*/ int64_t{0}, /*decltype(_impl_._cached_size_)*/ {}} { } struct MessageOfTeamDefaultTypeInternal @@ -444,7 +444,7 @@ namespace protobuf ::_pbi::ConstantInitialized ) : _impl_{ - /*decltype(_impl_.from_id_)*/ int64_t{0}, /*decltype(_impl_.to_id_)*/ int64_t{0}, /*decltype(_impl_.news_)*/ {}, /*decltype(_impl_._cached_size_)*/ {}, /*decltype(_impl_._oneof_case_)*/ {}} + /*decltype(_impl_.from_id_)*/ int64_t{0}, /*decltype(_impl_.to_id_)*/ int64_t{0}, /*decltype(_impl_.team_id_)*/ int64_t{0}, /*decltype(_impl_.news_)*/ {}, /*decltype(_impl_._cached_size_)*/ {}, /*decltype(_impl_._oneof_case_)*/ {}} { } struct MessageOfNewsDefaultTypeInternal @@ -603,7 +603,6 @@ const uint32_t TableStruct_Message2Clients_2eproto::offsets[] PROTOBUF_SECTION_V PROTOBUF_FIELD_OFFSET(::protobuf::MessageOfTeam, _impl_.player_id_), PROTOBUF_FIELD_OFFSET(::protobuf::MessageOfTeam, _impl_.score_), PROTOBUF_FIELD_OFFSET(::protobuf::MessageOfTeam, _impl_.energy_), - PROTOBUF_FIELD_OFFSET(::protobuf::MessageOfTeam, _impl_.guid_), ~0u, // no _has_bits_ PROTOBUF_FIELD_OFFSET(::protobuf::MessageOfObj, _internal_metadata_), ~0u, // no _extensions_ @@ -685,6 +684,7 @@ const uint32_t TableStruct_Message2Clients_2eproto::offsets[] PROTOBUF_SECTION_V ::_pbi::kInvalidFieldOffsetTag, PROTOBUF_FIELD_OFFSET(::protobuf::MessageOfNews, _impl_.from_id_), PROTOBUF_FIELD_OFFSET(::protobuf::MessageOfNews, _impl_.to_id_), + PROTOBUF_FIELD_OFFSET(::protobuf::MessageOfNews, _impl_.team_id_), PROTOBUF_FIELD_OFFSET(::protobuf::MessageOfNews, _impl_.news_), }; static const ::_pbi::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { @@ -700,14 +700,14 @@ static const ::_pbi::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protode {109, -1, -1, sizeof(::protobuf::MessageOfMap_Row)}, {116, -1, -1, sizeof(::protobuf::MessageOfMap)}, {125, -1, -1, sizeof(::protobuf::MessageOfTeam)}, - {136, -1, -1, sizeof(::protobuf::MessageOfObj)}, - {155, -1, -1, sizeof(::protobuf::MessageOfAll)}, - {168, -1, -1, sizeof(::protobuf::MessageToClient)}, - {177, -1, -1, sizeof(::protobuf::MoveRes)}, - {186, -1, -1, sizeof(::protobuf::BoolRes)}, - {193, -1, -1, sizeof(::protobuf::SweeperInfoRes)}, - {200, -1, -1, sizeof(::protobuf::EcoRes)}, - {207, -1, -1, sizeof(::protobuf::MessageOfNews)}, + {135, -1, -1, sizeof(::protobuf::MessageOfObj)}, + {154, -1, -1, sizeof(::protobuf::MessageOfAll)}, + {167, -1, -1, sizeof(::protobuf::MessageToClient)}, + {176, -1, -1, sizeof(::protobuf::MoveRes)}, + {185, -1, -1, sizeof(::protobuf::BoolRes)}, + {192, -1, -1, sizeof(::protobuf::SweeperInfoRes)}, + {199, -1, -1, sizeof(::protobuf::EcoRes)}, + {206, -1, -1, sizeof(::protobuf::MessageOfNews)}, }; static const ::_pb::Message* const file_default_instances[] = { @@ -770,43 +770,43 @@ const char descriptor_table_protodef_Message2Clients_2eproto[] PROTOBUF_SECTION_ "sageOfMap\022\016\n\006height\030\001 \001(\r\022\r\n\005width\030\002 \001(\r" "\022(\n\004rows\030\003 \003(\0132\032.protobuf.MessageOfMap.R" "ow\032(\n\003Row\022!\n\004cols\030\001 \003(\0162\023.protobuf.Place" - "Type\"`\n\rMessageOfTeam\022\017\n\007team_id\030\001 \001(\003\022\021" - "\n\tplayer_id\030\002 \001(\003\022\r\n\005score\030\003 \001(\005\022\016\n\006ener" - "gy\030\004 \001(\005\022\014\n\004guid\030\005 \001(\003\"\275\005\n\014MessageOfObj\022" - "5\n\017sweeper_message\030\001 \001(\0132\032.protobuf.Mess" - "ageOfSweeperH\000\0223\n\016bullet_message\030\002 \001(\0132\031" - ".protobuf.MessageOfBulletH\000\022=\n\023recycleba" - "nk_message\030\003 \001(\0132\036.protobuf.MessageOfRec" - "ycleBankH\000\022A\n\025chargestation_message\030\004 \001(" - "\0132 .protobuf.MessageOfChargeStationH\000\022=\n" - "\023signaltower_message\030\005 \001(\0132\036.protobuf.Me" - "ssageOfSignalTowerH\000\0223\n\016bridge_message\030\006" - " \001(\0132\031.protobuf.MessageOfBridgeH\000\022/\n\014hom" - "e_message\030\007 \001(\0132\027.protobuf.MessageOfHome" - "H\000\0225\n\017garbage_message\030\010 \001(\0132\032.protobuf.M" - "essageOfGarbageH\000\022-\n\013map_message\030\t \001(\0132\026" - ".protobuf.MessageOfMapH\000\022/\n\014news_message" - "\030\n \001(\0132\027.protobuf.MessageOfNewsH\000\022@\n\025bom" - "bed_bullet_message\030\013 \001(\0132\037.protobuf.Mess" - "ageOfBombedBulletH\000\022/\n\014team_message\030\014 \001(" - "\0132\027.protobuf.MessageOfTeamH\000B\020\n\016message_" - "of_obj\"\260\001\n\014MessageOfAll\022\021\n\tgame_time\030\001 \001" - "(\005\022\026\n\016red_team_score\030\002 \001(\005\022\027\n\017blue_team_" - "score\030\003 \001(\005\022\027\n\017red_team_energy\030\004 \001(\005\022\030\n\020" - "blue_team_energy\030\005 \001(\005\022\023\n\013red_home_hp\030\006 " - "\001(\005\022\024\n\014blue_home_hp\030\007 \001(\005\"\224\001\n\017MessageToC" - "lient\022+\n\013obj_message\030\001 \003(\0132\026.protobuf.Me" - "ssageOfObj\022\'\n\ngame_state\030\002 \001(\0162\023.protobu" - "f.GameState\022+\n\013all_message\030\003 \001(\0132\026.proto" - "buf.MessageOfAll\"J\n\007MoveRes\022\024\n\014actual_sp" - "eed\030\001 \001(\003\022\024\n\014actual_angle\030\002 \001(\001\022\023\n\013act_s" - "uccess\030\003 \001(\010\"\036\n\007BoolRes\022\023\n\013act_success\030\001" - " \001(\010\"B\n\016SweeperInfoRes\0220\n\014sweeper_info\030\001" - " \003(\0132\032.protobuf.MessageOfSweeper\"\031\n\006EcoR" - "es\022\017\n\007economy\030\001 \001(\003\"i\n\rMessageOfNews\022\026\n\014" - "text_message\030\001 \001(\tH\000\022\030\n\016binary_message\030\004" - " \001(\014H\000\022\017\n\007from_id\030\002 \001(\003\022\r\n\005to_id\030\003 \001(\003B\006" - "\n\004newsb\006proto3"; + "Type\"R\n\rMessageOfTeam\022\017\n\007team_id\030\001 \001(\003\022\021" + "\n\tplayer_id\030\002 \001(\003\022\r\n\005score\030\003 \001(\003\022\016\n\006ener" + "gy\030\004 \001(\003\"\275\005\n\014MessageOfObj\0225\n\017sweeper_mes" + "sage\030\001 \001(\0132\032.protobuf.MessageOfSweeperH\000" + "\0223\n\016bullet_message\030\002 \001(\0132\031.protobuf.Mess" + "ageOfBulletH\000\022=\n\023recyclebank_message\030\003 \001" + "(\0132\036.protobuf.MessageOfRecycleBankH\000\022A\n\025" + "chargestation_message\030\004 \001(\0132 .protobuf.M" + "essageOfChargeStationH\000\022=\n\023signaltower_m" + "essage\030\005 \001(\0132\036.protobuf.MessageOfSignalT" + "owerH\000\0223\n\016bridge_message\030\006 \001(\0132\031.protobu" + "f.MessageOfBridgeH\000\022/\n\014home_message\030\007 \001(" + "\0132\027.protobuf.MessageOfHomeH\000\0225\n\017garbage_" + "message\030\010 \001(\0132\032.protobuf.MessageOfGarbag" + "eH\000\022-\n\013map_message\030\t \001(\0132\026.protobuf.Mess" + "ageOfMapH\000\022/\n\014news_message\030\n \001(\0132\027.proto" + "buf.MessageOfNewsH\000\022@\n\025bombed_bullet_mes" + "sage\030\013 \001(\0132\037.protobuf.MessageOfBombedBul" + "letH\000\022/\n\014team_message\030\014 \001(\0132\027.protobuf.M" + "essageOfTeamH\000B\020\n\016message_of_obj\"\260\001\n\014Mes" + "sageOfAll\022\021\n\tgame_time\030\001 \001(\005\022\026\n\016red_team" + "_score\030\002 \001(\005\022\027\n\017blue_team_score\030\003 \001(\005\022\027\n" + "\017red_team_energy\030\004 \001(\005\022\030\n\020blue_team_ener" + "gy\030\005 \001(\005\022\023\n\013red_home_hp\030\006 \001(\005\022\024\n\014blue_ho" + "me_hp\030\007 \001(\005\"\224\001\n\017MessageToClient\022+\n\013obj_m" + "essage\030\001 \003(\0132\026.protobuf.MessageOfObj\022\'\n\n" + "game_state\030\002 \001(\0162\023.protobuf.GameState\022+\n" + "\013all_message\030\003 \001(\0132\026.protobuf.MessageOfA" + "ll\"J\n\007MoveRes\022\024\n\014actual_speed\030\001 \001(\003\022\024\n\014a" + "ctual_angle\030\002 \001(\001\022\023\n\013act_success\030\003 \001(\010\"\036" + "\n\007BoolRes\022\023\n\013act_success\030\001 \001(\010\"B\n\016Sweepe" + "rInfoRes\0220\n\014sweeper_info\030\001 \003(\0132\032.protobu" + "f.MessageOfSweeper\"\031\n\006EcoRes\022\017\n\007economy\030" + "\001 \001(\003\"z\n\rMessageOfNews\022\026\n\014text_message\030\001" + " \001(\tH\000\022\030\n\016binary_message\030\002 \001(\014H\000\022\017\n\007from" + "_id\030\003 \001(\003\022\r\n\005to_id\030\004 \001(\003\022\017\n\007team_id\030\005 \001(" + "\003B\006\n\004newsb\006proto3"; static const ::_pbi::DescriptorTable* const descriptor_table_Message2Clients_2eproto_deps[1] = { &::descriptor_table_MessageType_2eproto, }; @@ -814,7 +814,7 @@ static ::_pbi::once_flag descriptor_table_Message2Clients_2eproto_once; const ::_pbi::DescriptorTable descriptor_table_Message2Clients_2eproto = { false, false, - 2894, + 2897, descriptor_table_protodef_Message2Clients_2eproto, "Message2Clients.proto", &descriptor_table_Message2Clients_2eproto_once, @@ -4633,10 +4633,10 @@ namespace protobuf MessageOfTeam* const _this = this; (void)_this; new (&_impl_) Impl_{ - decltype(_impl_.team_id_){}, decltype(_impl_.player_id_){}, decltype(_impl_.score_){}, decltype(_impl_.energy_){}, decltype(_impl_.guid_){}, /*decltype(_impl_._cached_size_)*/ {}}; + decltype(_impl_.team_id_){}, decltype(_impl_.player_id_){}, decltype(_impl_.score_){}, decltype(_impl_.energy_){}, /*decltype(_impl_._cached_size_)*/ {}}; _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); - ::memcpy(&_impl_.team_id_, &from._impl_.team_id_, static_cast(reinterpret_cast(&_impl_.guid_) - reinterpret_cast(&_impl_.team_id_)) + sizeof(_impl_.guid_)); + ::memcpy(&_impl_.team_id_, &from._impl_.team_id_, static_cast(reinterpret_cast(&_impl_.energy_) - reinterpret_cast(&_impl_.team_id_)) + sizeof(_impl_.energy_)); // @@protoc_insertion_point(copy_constructor:protobuf.MessageOfTeam) } @@ -4647,7 +4647,7 @@ namespace protobuf (void)arena; (void)is_message_owned; new (&_impl_) Impl_{ - decltype(_impl_.team_id_){int64_t{0}}, decltype(_impl_.player_id_){int64_t{0}}, decltype(_impl_.score_){0}, decltype(_impl_.energy_){0}, decltype(_impl_.guid_){int64_t{0}}, /*decltype(_impl_._cached_size_)*/ {}}; + decltype(_impl_.team_id_){int64_t{0}}, decltype(_impl_.player_id_){int64_t{0}}, decltype(_impl_.score_){int64_t{0}}, decltype(_impl_.energy_){int64_t{0}}, /*decltype(_impl_._cached_size_)*/ {}}; } MessageOfTeam::~MessageOfTeam() @@ -4678,7 +4678,7 @@ namespace protobuf // Prevent compiler warnings about cached_has_bits being unused (void)cached_has_bits; - ::memset(&_impl_.team_id_, 0, static_cast(reinterpret_cast(&_impl_.guid_) - reinterpret_cast(&_impl_.team_id_)) + sizeof(_impl_.guid_)); + ::memset(&_impl_.team_id_, 0, static_cast(reinterpret_cast(&_impl_.energy_) - reinterpret_cast(&_impl_.team_id_)) + sizeof(_impl_.energy_)); _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } @@ -4713,31 +4713,21 @@ namespace protobuf else goto handle_unusual; continue; - // int32 score = 3; + // int64 score = 3; case 3: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 24)) { - _impl_.score_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr); + _impl_.score_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); } else goto handle_unusual; continue; - // int32 energy = 4; + // int64 energy = 4; case 4: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 32)) { - _impl_.energy_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr); - CHK_(ptr); - } - else - goto handle_unusual; - continue; - // int64 guid = 5; - case 5: - if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 40)) - { - _impl_.guid_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + _impl_.energy_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); } else @@ -4791,25 +4781,18 @@ namespace protobuf target = ::_pbi::WireFormatLite::WriteInt64ToArray(2, this->_internal_player_id(), target); } - // int32 score = 3; + // int64 score = 3; if (this->_internal_score() != 0) { target = stream->EnsureSpace(target); - target = ::_pbi::WireFormatLite::WriteInt32ToArray(3, this->_internal_score(), target); + target = ::_pbi::WireFormatLite::WriteInt64ToArray(3, this->_internal_score(), target); } - // int32 energy = 4; + // int64 energy = 4; if (this->_internal_energy() != 0) { target = stream->EnsureSpace(target); - target = ::_pbi::WireFormatLite::WriteInt32ToArray(4, this->_internal_energy(), target); - } - - // int64 guid = 5; - if (this->_internal_guid() != 0) - { - target = stream->EnsureSpace(target); - target = ::_pbi::WireFormatLite::WriteInt64ToArray(5, this->_internal_guid(), target); + target = ::_pbi::WireFormatLite::WriteInt64ToArray(4, this->_internal_energy(), target); } if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) @@ -4843,22 +4826,16 @@ namespace protobuf total_size += ::_pbi::WireFormatLite::Int64SizePlusOne(this->_internal_player_id()); } - // int32 score = 3; + // int64 score = 3; if (this->_internal_score() != 0) { - total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_score()); + total_size += ::_pbi::WireFormatLite::Int64SizePlusOne(this->_internal_score()); } - // int32 energy = 4; + // int64 energy = 4; if (this->_internal_energy() != 0) { - total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_energy()); - } - - // int64 guid = 5; - if (this->_internal_guid() != 0) - { - total_size += ::_pbi::WireFormatLite::Int64SizePlusOne(this->_internal_guid()); + total_size += ::_pbi::WireFormatLite::Int64SizePlusOne(this->_internal_energy()); } return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); @@ -4897,10 +4874,6 @@ namespace protobuf { _this->_internal_set_energy(from._internal_energy()); } - if (from._internal_guid() != 0) - { - _this->_internal_set_guid(from._internal_guid()); - } _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); } @@ -4923,7 +4896,7 @@ namespace protobuf using std::swap; _internal_metadata_.InternalSwap(&other->_internal_metadata_); ::PROTOBUF_NAMESPACE_ID::internal::memswap< - PROTOBUF_FIELD_OFFSET(MessageOfTeam, _impl_.guid_) + sizeof(MessageOfTeam::_impl_.guid_) - PROTOBUF_FIELD_OFFSET(MessageOfTeam, _impl_.team_id_)>( + PROTOBUF_FIELD_OFFSET(MessageOfTeam, _impl_.energy_) + sizeof(MessageOfTeam::_impl_.energy_) - PROTOBUF_FIELD_OFFSET(MessageOfTeam, _impl_.team_id_)>( reinterpret_cast(&_impl_.team_id_), reinterpret_cast(&other->_impl_.team_id_) ); @@ -7657,10 +7630,10 @@ namespace protobuf MessageOfNews* const _this = this; (void)_this; new (&_impl_) Impl_{ - decltype(_impl_.from_id_){}, decltype(_impl_.to_id_){}, decltype(_impl_.news_){}, /*decltype(_impl_._cached_size_)*/ {}, /*decltype(_impl_._oneof_case_)*/ {}}; + decltype(_impl_.from_id_){}, decltype(_impl_.to_id_){}, decltype(_impl_.team_id_){}, decltype(_impl_.news_){}, /*decltype(_impl_._cached_size_)*/ {}, /*decltype(_impl_._oneof_case_)*/ {}}; _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); - ::memcpy(&_impl_.from_id_, &from._impl_.from_id_, static_cast(reinterpret_cast(&_impl_.to_id_) - reinterpret_cast(&_impl_.from_id_)) + sizeof(_impl_.to_id_)); + ::memcpy(&_impl_.from_id_, &from._impl_.from_id_, static_cast(reinterpret_cast(&_impl_.team_id_) - reinterpret_cast(&_impl_.from_id_)) + sizeof(_impl_.team_id_)); clear_has_news(); switch (from.news_case()) { @@ -7689,7 +7662,7 @@ namespace protobuf (void)arena; (void)is_message_owned; new (&_impl_) Impl_{ - decltype(_impl_.from_id_){int64_t{0}}, decltype(_impl_.to_id_){int64_t{0}}, decltype(_impl_.news_){}, /*decltype(_impl_._cached_size_)*/ {}, /*decltype(_impl_._oneof_case_)*/ {}}; + decltype(_impl_.from_id_){int64_t{0}}, decltype(_impl_.to_id_){int64_t{0}}, decltype(_impl_.team_id_){int64_t{0}}, decltype(_impl_.news_){}, /*decltype(_impl_._cached_size_)*/ {}, /*decltype(_impl_._oneof_case_)*/ {}}; clear_has_news(); } @@ -7748,7 +7721,7 @@ namespace protobuf // Prevent compiler warnings about cached_has_bits being unused (void)cached_has_bits; - ::memset(&_impl_.from_id_, 0, static_cast(reinterpret_cast(&_impl_.to_id_) - reinterpret_cast(&_impl_.from_id_)) + sizeof(_impl_.to_id_)); + ::memset(&_impl_.from_id_, 0, static_cast(reinterpret_cast(&_impl_.team_id_) - reinterpret_cast(&_impl_.from_id_)) + sizeof(_impl_.team_id_)); clear_news(); _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } @@ -7776,32 +7749,42 @@ namespace protobuf else goto handle_unusual; continue; - // int64 from_id = 2; + // bytes binary_message = 2; case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 16)) + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 18)) { - _impl_.from_id_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + auto str = _internal_mutable_binary_message(); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); CHK_(ptr); } else goto handle_unusual; continue; - // int64 to_id = 3; + // int64 from_id = 3; case 3: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 24)) { - _impl_.to_id_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + _impl_.from_id_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); } else goto handle_unusual; continue; - // bytes binary_message = 4; + // int64 to_id = 4; case 4: - if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 34)) + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 32)) { - auto str = _internal_mutable_binary_message(); - ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); + _impl_.to_id_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } + else + goto handle_unusual; + continue; + // int64 team_id = 5; + case 5: + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 40)) + { + _impl_.team_id_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); } else @@ -7852,26 +7835,33 @@ namespace protobuf ); } - // int64 from_id = 2; + // bytes binary_message = 2; + if (_internal_has_binary_message()) + { + target = stream->WriteBytesMaybeAliased( + 2, this->_internal_binary_message(), target + ); + } + + // int64 from_id = 3; if (this->_internal_from_id() != 0) { target = stream->EnsureSpace(target); - target = ::_pbi::WireFormatLite::WriteInt64ToArray(2, this->_internal_from_id(), target); + target = ::_pbi::WireFormatLite::WriteInt64ToArray(3, this->_internal_from_id(), target); } - // int64 to_id = 3; + // int64 to_id = 4; if (this->_internal_to_id() != 0) { target = stream->EnsureSpace(target); - target = ::_pbi::WireFormatLite::WriteInt64ToArray(3, this->_internal_to_id(), target); + target = ::_pbi::WireFormatLite::WriteInt64ToArray(4, this->_internal_to_id(), target); } - // bytes binary_message = 4; - if (_internal_has_binary_message()) + // int64 team_id = 5; + if (this->_internal_team_id() != 0) { - target = stream->WriteBytesMaybeAliased( - 4, this->_internal_binary_message(), target - ); + target = stream->EnsureSpace(target); + target = ::_pbi::WireFormatLite::WriteInt64ToArray(5, this->_internal_team_id(), target); } if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) @@ -7893,18 +7883,24 @@ namespace protobuf // Prevent compiler warnings about cached_has_bits being unused (void)cached_has_bits; - // int64 from_id = 2; + // int64 from_id = 3; if (this->_internal_from_id() != 0) { total_size += ::_pbi::WireFormatLite::Int64SizePlusOne(this->_internal_from_id()); } - // int64 to_id = 3; + // int64 to_id = 4; if (this->_internal_to_id() != 0) { total_size += ::_pbi::WireFormatLite::Int64SizePlusOne(this->_internal_to_id()); } + // int64 team_id = 5; + if (this->_internal_team_id() != 0) + { + total_size += ::_pbi::WireFormatLite::Int64SizePlusOne(this->_internal_team_id()); + } + switch (news_case()) { // string text_message = 1; @@ -7916,7 +7912,7 @@ namespace protobuf ); break; } - // bytes binary_message = 4; + // bytes binary_message = 2; case kBinaryMessage: { total_size += 1 + @@ -7958,6 +7954,10 @@ namespace protobuf { _this->_internal_set_to_id(from._internal_to_id()); } + if (from._internal_team_id() != 0) + { + _this->_internal_set_team_id(from._internal_team_id()); + } switch (from.news_case()) { case kTextMessage: @@ -7997,7 +7997,7 @@ namespace protobuf using std::swap; _internal_metadata_.InternalSwap(&other->_internal_metadata_); ::PROTOBUF_NAMESPACE_ID::internal::memswap< - PROTOBUF_FIELD_OFFSET(MessageOfNews, _impl_.to_id_) + sizeof(MessageOfNews::_impl_.to_id_) - PROTOBUF_FIELD_OFFSET(MessageOfNews, _impl_.from_id_)>( + PROTOBUF_FIELD_OFFSET(MessageOfNews, _impl_.team_id_) + sizeof(MessageOfNews::_impl_.team_id_) - PROTOBUF_FIELD_OFFSET(MessageOfNews, _impl_.from_id_)>( reinterpret_cast(&_impl_.from_id_), reinterpret_cast(&other->_impl_.from_id_) ); diff --git a/CAPI/cpp/proto/Message2Clients.pb.h b/CAPI/cpp/proto/Message2Clients.pb.h index 200accd3..7dc9a11d 100644 --- a/CAPI/cpp/proto/Message2Clients.pb.h +++ b/CAPI/cpp/proto/Message2Clients.pb.h @@ -3033,7 +3033,6 @@ namespace protobuf kPlayerIdFieldNumber = 2, kScoreFieldNumber = 3, kEnergyFieldNumber = 4, - kGuidFieldNumber = 5, }; // int64 team_id = 1; void clear_team_id(); @@ -3055,34 +3054,24 @@ namespace protobuf void _internal_set_player_id(int64_t value); public: - // int32 score = 3; + // int64 score = 3; void clear_score(); - int32_t score() const; - void set_score(int32_t value); + int64_t score() const; + void set_score(int64_t value); private: - int32_t _internal_score() const; - void _internal_set_score(int32_t value); + int64_t _internal_score() const; + void _internal_set_score(int64_t value); public: - // int32 energy = 4; + // int64 energy = 4; void clear_energy(); - int32_t energy() const; - void set_energy(int32_t value); + int64_t energy() const; + void set_energy(int64_t value); private: - int32_t _internal_energy() const; - void _internal_set_energy(int32_t value); - - public: - // int64 guid = 5; - void clear_guid(); - int64_t guid() const; - void set_guid(int64_t value); - - private: - int64_t _internal_guid() const; - void _internal_set_guid(int64_t value); + int64_t _internal_energy() const; + void _internal_set_energy(int64_t value); public: // @@protoc_insertion_point(class_scope:protobuf.MessageOfTeam) @@ -3098,9 +3087,8 @@ namespace protobuf { int64_t team_id_; int64_t player_id_; - int32_t score_; - int32_t energy_; - int64_t guid_; + int64_t score_; + int64_t energy_; mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; }; union @@ -5005,7 +4993,7 @@ namespace protobuf enum NewsCase { kTextMessage = 1, - kBinaryMessage = 4, + kBinaryMessage = 2, NEWS_NOT_SET = 0, }; @@ -5108,12 +5096,13 @@ namespace protobuf enum : int { - kFromIdFieldNumber = 2, - kToIdFieldNumber = 3, + kFromIdFieldNumber = 3, + kToIdFieldNumber = 4, + kTeamIdFieldNumber = 5, kTextMessageFieldNumber = 1, - kBinaryMessageFieldNumber = 4, + kBinaryMessageFieldNumber = 2, }; - // int64 from_id = 2; + // int64 from_id = 3; void clear_from_id(); int64_t from_id() const; void set_from_id(int64_t value); @@ -5123,7 +5112,7 @@ namespace protobuf void _internal_set_from_id(int64_t value); public: - // int64 to_id = 3; + // int64 to_id = 4; void clear_to_id(); int64_t to_id() const; void set_to_id(int64_t value); @@ -5132,6 +5121,16 @@ namespace protobuf int64_t _internal_to_id() const; void _internal_set_to_id(int64_t value); + public: + // int64 team_id = 5; + void clear_team_id(); + int64_t team_id() const; + void set_team_id(int64_t value); + + private: + int64_t _internal_team_id() const; + void _internal_set_team_id(int64_t value); + public: // string text_message = 1; bool has_text_message() const; @@ -5154,7 +5153,7 @@ namespace protobuf std::string* _internal_mutable_text_message(); public: - // bytes binary_message = 4; + // bytes binary_message = 2; bool has_binary_message() const; private: @@ -5195,6 +5194,7 @@ namespace protobuf { int64_t from_id_; int64_t to_id_; + int64_t team_id_; union NewsUnion { constexpr NewsUnion() : @@ -6788,78 +6788,54 @@ namespace protobuf // @@protoc_insertion_point(field_set:protobuf.MessageOfTeam.player_id) } - // int32 score = 3; + // int64 score = 3; inline void MessageOfTeam::clear_score() { - _impl_.score_ = 0; + _impl_.score_ = int64_t{0}; } - inline int32_t MessageOfTeam::_internal_score() const + inline int64_t MessageOfTeam::_internal_score() const { return _impl_.score_; } - inline int32_t MessageOfTeam::score() const + inline int64_t MessageOfTeam::score() const { // @@protoc_insertion_point(field_get:protobuf.MessageOfTeam.score) return _internal_score(); } - inline void MessageOfTeam::_internal_set_score(int32_t value) + inline void MessageOfTeam::_internal_set_score(int64_t value) { _impl_.score_ = value; } - inline void MessageOfTeam::set_score(int32_t value) + inline void MessageOfTeam::set_score(int64_t value) { _internal_set_score(value); // @@protoc_insertion_point(field_set:protobuf.MessageOfTeam.score) } - // int32 energy = 4; + // int64 energy = 4; inline void MessageOfTeam::clear_energy() { - _impl_.energy_ = 0; + _impl_.energy_ = int64_t{0}; } - inline int32_t MessageOfTeam::_internal_energy() const + inline int64_t MessageOfTeam::_internal_energy() const { return _impl_.energy_; } - inline int32_t MessageOfTeam::energy() const + inline int64_t MessageOfTeam::energy() const { // @@protoc_insertion_point(field_get:protobuf.MessageOfTeam.energy) return _internal_energy(); } - inline void MessageOfTeam::_internal_set_energy(int32_t value) + inline void MessageOfTeam::_internal_set_energy(int64_t value) { _impl_.energy_ = value; } - inline void MessageOfTeam::set_energy(int32_t value) + inline void MessageOfTeam::set_energy(int64_t value) { _internal_set_energy(value); // @@protoc_insertion_point(field_set:protobuf.MessageOfTeam.energy) } - // int64 guid = 5; - inline void MessageOfTeam::clear_guid() - { - _impl_.guid_ = int64_t{0}; - } - inline int64_t MessageOfTeam::_internal_guid() const - { - return _impl_.guid_; - } - inline int64_t MessageOfTeam::guid() const - { - // @@protoc_insertion_point(field_get:protobuf.MessageOfTeam.guid) - return _internal_guid(); - } - inline void MessageOfTeam::_internal_set_guid(int64_t value) - { - _impl_.guid_ = value; - } - inline void MessageOfTeam::set_guid(int64_t value) - { - _internal_set_guid(value); - // @@protoc_insertion_point(field_set:protobuf.MessageOfTeam.guid) - } - // ------------------------------------------------------------------- // MessageOfObj @@ -8654,7 +8630,7 @@ namespace protobuf // @@protoc_insertion_point(field_set_allocated:protobuf.MessageOfNews.text_message) } - // bytes binary_message = 4; + // bytes binary_message = 2; inline bool MessageOfNews::_internal_has_binary_message() const { return news_case() == kBinaryMessage; @@ -8753,7 +8729,7 @@ namespace protobuf // @@protoc_insertion_point(field_set_allocated:protobuf.MessageOfNews.binary_message) } - // int64 from_id = 2; + // int64 from_id = 3; inline void MessageOfNews::clear_from_id() { _impl_.from_id_ = int64_t{0}; @@ -8777,7 +8753,7 @@ namespace protobuf // @@protoc_insertion_point(field_set:protobuf.MessageOfNews.from_id) } - // int64 to_id = 3; + // int64 to_id = 4; inline void MessageOfNews::clear_to_id() { _impl_.to_id_ = int64_t{0}; @@ -8801,6 +8777,30 @@ namespace protobuf // @@protoc_insertion_point(field_set:protobuf.MessageOfNews.to_id) } + // int64 team_id = 5; + inline void MessageOfNews::clear_team_id() + { + _impl_.team_id_ = int64_t{0}; + } + inline int64_t MessageOfNews::_internal_team_id() const + { + return _impl_.team_id_; + } + inline int64_t MessageOfNews::team_id() const + { + // @@protoc_insertion_point(field_get:protobuf.MessageOfNews.team_id) + return _internal_team_id(); + } + inline void MessageOfNews::_internal_set_team_id(int64_t value) + { + _impl_.team_id_ = value; + } + inline void MessageOfNews::set_team_id(int64_t value) + { + _internal_set_team_id(value); + // @@protoc_insertion_point(field_set:protobuf.MessageOfNews.team_id) + } + inline bool MessageOfNews::has_news() const { return news_case() != NEWS_NOT_SET; diff --git a/CAPI/cpp/proto/Message2Server.pb.cc b/CAPI/cpp/proto/Message2Server.pb.cc index 45954d56..2f28e47d 100644 --- a/CAPI/cpp/proto/Message2Server.pb.cc +++ b/CAPI/cpp/proto/Message2Server.pb.cc @@ -222,7 +222,7 @@ namespace protobuf ::_pbi::ConstantInitialized ) : _impl_{ - /*decltype(_impl_.x_)*/ 0, /*decltype(_impl_.y_)*/ 0, /*decltype(_impl_.team_id_)*/ int64_t{0}, /*decltype(_impl_.sweeper_type_)*/ 0, /*decltype(_impl_._cached_size_)*/ {}} + /*decltype(_impl_.team_id_)*/ int64_t{0}, /*decltype(_impl_.sweeper_type_)*/ 0, /*decltype(_impl_._cached_size_)*/ {}} { } struct BuildSweeperMsgDefaultTypeInternal @@ -333,8 +333,6 @@ const uint32_t TableStruct_Message2Server_2eproto::offsets[] PROTOBUF_SECTION_VA ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ ~0u, // no _inlined_string_donated_ - PROTOBUF_FIELD_OFFSET(::protobuf::BuildSweeperMsg, _impl_.x_), - PROTOBUF_FIELD_OFFSET(::protobuf::BuildSweeperMsg, _impl_.y_), PROTOBUF_FIELD_OFFSET(::protobuf::BuildSweeperMsg, _impl_.sweeper_type_), PROTOBUF_FIELD_OFFSET(::protobuf::BuildSweeperMsg, _impl_.team_id_), }; @@ -384,9 +382,9 @@ const char descriptor_table_protodef_Message2Server_2eproto[] PROTOBUF_SECTION_V "ver\030\002 \001(\003\022\017\n\007team_id\030\003 \001(\003\"[\n\nInstallMsg" "\022)\n\013module_type\030\001 \001(\0162\024.protobuf.ModuleT" "ype\022\021\n\tplayer_id\030\002 \001(\003\022\017\n\007team_id\030\003 \001(\003\"" - "e\n\017BuildSweeperMsg\022\t\n\001x\030\001 \001(\005\022\t\n\001y\030\002 \001(\005" - "\022+\n\014sweeper_type\030\003 \001(\0162\025.protobuf.Sweepe" - "rType\022\017\n\007team_id\030\004 \001(\003b\006proto3"; + "O\n\017BuildSweeperMsg\022+\n\014sweeper_type\030\001 \001(\016" + "2\025.protobuf.SweeperType\022\017\n\007team_id\030\002 \001(\003" + "b\006proto3"; static const ::_pbi::DescriptorTable* const descriptor_table_Message2Server_2eproto_deps[1] = { &::descriptor_table_MessageType_2eproto, }; @@ -394,7 +392,7 @@ static ::_pbi::once_flag descriptor_table_Message2Server_2eproto_once; const ::_pbi::DescriptorTable descriptor_table_Message2Server_2eproto = { false, false, - 870, + 848, descriptor_table_protodef_Message2Server_2eproto, "Message2Server.proto", &descriptor_table_Message2Server_2eproto_once, @@ -2787,10 +2785,10 @@ namespace protobuf BuildSweeperMsg* const _this = this; (void)_this; new (&_impl_) Impl_{ - decltype(_impl_.x_){}, decltype(_impl_.y_){}, decltype(_impl_.team_id_){}, decltype(_impl_.sweeper_type_){}, /*decltype(_impl_._cached_size_)*/ {}}; + decltype(_impl_.team_id_){}, decltype(_impl_.sweeper_type_){}, /*decltype(_impl_._cached_size_)*/ {}}; _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); - ::memcpy(&_impl_.x_, &from._impl_.x_, static_cast(reinterpret_cast(&_impl_.sweeper_type_) - reinterpret_cast(&_impl_.x_)) + sizeof(_impl_.sweeper_type_)); + ::memcpy(&_impl_.team_id_, &from._impl_.team_id_, static_cast(reinterpret_cast(&_impl_.sweeper_type_) - reinterpret_cast(&_impl_.team_id_)) + sizeof(_impl_.sweeper_type_)); // @@protoc_insertion_point(copy_constructor:protobuf.BuildSweeperMsg) } @@ -2801,7 +2799,7 @@ namespace protobuf (void)arena; (void)is_message_owned; new (&_impl_) Impl_{ - decltype(_impl_.x_){0}, decltype(_impl_.y_){0}, decltype(_impl_.team_id_){int64_t{0}}, decltype(_impl_.sweeper_type_){0}, /*decltype(_impl_._cached_size_)*/ {}}; + decltype(_impl_.team_id_){int64_t{0}}, decltype(_impl_.sweeper_type_){0}, /*decltype(_impl_._cached_size_)*/ {}}; } BuildSweeperMsg::~BuildSweeperMsg() @@ -2832,7 +2830,7 @@ namespace protobuf // Prevent compiler warnings about cached_has_bits being unused (void)cached_has_bits; - ::memset(&_impl_.x_, 0, static_cast(reinterpret_cast(&_impl_.sweeper_type_) - reinterpret_cast(&_impl_.x_)) + sizeof(_impl_.sweeper_type_)); + ::memset(&_impl_.team_id_, 0, static_cast(reinterpret_cast(&_impl_.sweeper_type_) - reinterpret_cast(&_impl_.team_id_)) + sizeof(_impl_.sweeper_type_)); _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } @@ -2847,29 +2845,9 @@ namespace protobuf ptr = ::_pbi::ReadTag(ptr, &tag); switch (tag >> 3) { - // int32 x = 1; + // .protobuf.SweeperType sweeper_type = 1; case 1: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 8)) - { - _impl_.x_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr); - CHK_(ptr); - } - else - goto handle_unusual; - continue; - // int32 y = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 16)) - { - _impl_.y_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr); - CHK_(ptr); - } - else - goto handle_unusual; - continue; - // .protobuf.SweeperType sweeper_type = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 24)) { uint64_t val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); @@ -2878,9 +2856,9 @@ namespace protobuf else goto handle_unusual; continue; - // int64 team_id = 4; - case 4: - if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 32)) + // int64 team_id = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 16)) { _impl_.team_id_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); @@ -2922,34 +2900,20 @@ namespace protobuf uint32_t cached_has_bits = 0; (void)cached_has_bits; - // int32 x = 1; - if (this->_internal_x() != 0) - { - target = stream->EnsureSpace(target); - target = ::_pbi::WireFormatLite::WriteInt32ToArray(1, this->_internal_x(), target); - } - - // int32 y = 2; - if (this->_internal_y() != 0) - { - target = stream->EnsureSpace(target); - target = ::_pbi::WireFormatLite::WriteInt32ToArray(2, this->_internal_y(), target); - } - - // .protobuf.SweeperType sweeper_type = 3; + // .protobuf.SweeperType sweeper_type = 1; if (this->_internal_sweeper_type() != 0) { target = stream->EnsureSpace(target); target = ::_pbi::WireFormatLite::WriteEnumToArray( - 3, this->_internal_sweeper_type(), target + 1, this->_internal_sweeper_type(), target ); } - // int64 team_id = 4; + // int64 team_id = 2; if (this->_internal_team_id() != 0) { target = stream->EnsureSpace(target); - target = ::_pbi::WireFormatLite::WriteInt64ToArray(4, this->_internal_team_id(), target); + target = ::_pbi::WireFormatLite::WriteInt64ToArray(2, this->_internal_team_id(), target); } if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) @@ -2971,25 +2935,13 @@ namespace protobuf // Prevent compiler warnings about cached_has_bits being unused (void)cached_has_bits; - // int32 x = 1; - if (this->_internal_x() != 0) - { - total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_x()); - } - - // int32 y = 2; - if (this->_internal_y() != 0) - { - total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_y()); - } - - // int64 team_id = 4; + // int64 team_id = 2; if (this->_internal_team_id() != 0) { total_size += ::_pbi::WireFormatLite::Int64SizePlusOne(this->_internal_team_id()); } - // .protobuf.SweeperType sweeper_type = 3; + // .protobuf.SweeperType sweeper_type = 1; if (this->_internal_sweeper_type() != 0) { total_size += 1 + @@ -3016,14 +2968,6 @@ namespace protobuf uint32_t cached_has_bits = 0; (void)cached_has_bits; - if (from._internal_x() != 0) - { - _this->_internal_set_x(from._internal_x()); - } - if (from._internal_y() != 0) - { - _this->_internal_set_y(from._internal_y()); - } if (from._internal_team_id() != 0) { _this->_internal_set_team_id(from._internal_team_id()); @@ -3054,9 +2998,9 @@ namespace protobuf using std::swap; _internal_metadata_.InternalSwap(&other->_internal_metadata_); ::PROTOBUF_NAMESPACE_ID::internal::memswap< - PROTOBUF_FIELD_OFFSET(BuildSweeperMsg, _impl_.sweeper_type_) + sizeof(BuildSweeperMsg::_impl_.sweeper_type_) - PROTOBUF_FIELD_OFFSET(BuildSweeperMsg, _impl_.x_)>( - reinterpret_cast(&_impl_.x_), - reinterpret_cast(&other->_impl_.x_) + PROTOBUF_FIELD_OFFSET(BuildSweeperMsg, _impl_.sweeper_type_) + sizeof(BuildSweeperMsg::_impl_.sweeper_type_) - PROTOBUF_FIELD_OFFSET(BuildSweeperMsg, _impl_.team_id_)>( + reinterpret_cast(&_impl_.team_id_), + reinterpret_cast(&other->_impl_.team_id_) ); } diff --git a/CAPI/cpp/proto/Message2Server.pb.h b/CAPI/cpp/proto/Message2Server.pb.h index 7165a7bc..4e903b72 100644 --- a/CAPI/cpp/proto/Message2Server.pb.h +++ b/CAPI/cpp/proto/Message2Server.pb.h @@ -2216,32 +2216,10 @@ namespace protobuf enum : int { - kXFieldNumber = 1, - kYFieldNumber = 2, - kTeamIdFieldNumber = 4, - kSweeperTypeFieldNumber = 3, + kTeamIdFieldNumber = 2, + kSweeperTypeFieldNumber = 1, }; - // int32 x = 1; - void clear_x(); - int32_t x() const; - void set_x(int32_t value); - - private: - int32_t _internal_x() const; - void _internal_set_x(int32_t value); - - public: - // int32 y = 2; - void clear_y(); - int32_t y() const; - void set_y(int32_t value); - - private: - int32_t _internal_y() const; - void _internal_set_y(int32_t value); - - public: - // int64 team_id = 4; + // int64 team_id = 2; void clear_team_id(); int64_t team_id() const; void set_team_id(int64_t value); @@ -2251,7 +2229,7 @@ namespace protobuf void _internal_set_team_id(int64_t value); public: - // .protobuf.SweeperType sweeper_type = 3; + // .protobuf.SweeperType sweeper_type = 1; void clear_sweeper_type(); ::protobuf::SweeperType sweeper_type() const; void set_sweeper_type(::protobuf::SweeperType value); @@ -2272,8 +2250,6 @@ namespace protobuf typedef void DestructorSkippable_; struct Impl_ { - int32_t x_; - int32_t y_; int64_t team_id_; int sweeper_type_; mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; @@ -3116,55 +3092,7 @@ namespace protobuf // BuildSweeperMsg - // int32 x = 1; - inline void BuildSweeperMsg::clear_x() - { - _impl_.x_ = 0; - } - inline int32_t BuildSweeperMsg::_internal_x() const - { - return _impl_.x_; - } - inline int32_t BuildSweeperMsg::x() const - { - // @@protoc_insertion_point(field_get:protobuf.BuildSweeperMsg.x) - return _internal_x(); - } - inline void BuildSweeperMsg::_internal_set_x(int32_t value) - { - _impl_.x_ = value; - } - inline void BuildSweeperMsg::set_x(int32_t value) - { - _internal_set_x(value); - // @@protoc_insertion_point(field_set:protobuf.BuildSweeperMsg.x) - } - - // int32 y = 2; - inline void BuildSweeperMsg::clear_y() - { - _impl_.y_ = 0; - } - inline int32_t BuildSweeperMsg::_internal_y() const - { - return _impl_.y_; - } - inline int32_t BuildSweeperMsg::y() const - { - // @@protoc_insertion_point(field_get:protobuf.BuildSweeperMsg.y) - return _internal_y(); - } - inline void BuildSweeperMsg::_internal_set_y(int32_t value) - { - _impl_.y_ = value; - } - inline void BuildSweeperMsg::set_y(int32_t value) - { - _internal_set_y(value); - // @@protoc_insertion_point(field_set:protobuf.BuildSweeperMsg.y) - } - - // .protobuf.SweeperType sweeper_type = 3; + // .protobuf.SweeperType sweeper_type = 1; inline void BuildSweeperMsg::clear_sweeper_type() { _impl_.sweeper_type_ = 0; @@ -3188,7 +3116,7 @@ namespace protobuf // @@protoc_insertion_point(field_set:protobuf.BuildSweeperMsg.sweeper_type) } - // int64 team_id = 4; + // int64 team_id = 2; inline void BuildSweeperMsg::clear_team_id() { _impl_.team_id_ = int64_t{0}; diff --git a/CAPI/python/PyAPI/AI.py b/CAPI/python/PyAPI/AI.py index ba94ee8c..82504ca0 100644 --- a/CAPI/python/PyAPI/AI.py +++ b/CAPI/python/PyAPI/AI.py @@ -1,9 +1,9 @@ import PyAPI.structures as THUAI7 -from PyAPI.Interface import IShipAPI, ITeamAPI, IAI +from PyAPI.Interface import ISweeperAPI, ITeamAPI, IAI +from PyAPI.utils import AssistFunction from typing import Union, Final, cast, List from PyAPI.constants import Constants import queue - import time @@ -12,33 +12,25 @@ class Setting: @staticmethod def Asynchronous() -> bool: return False - + @staticmethod - def SweeperTypes()->List[THUAI7.SweeperType]: - return [THUAI7.SweeperType.CivilianSweeper, - THUAI7.SweeperType.MilitarySweeper, - THUAI7.SweeperType.MilitarySweeper, - THUAI7.SweeperType.FlagSweeper] + def SweeperTypes() -> List[THUAI7.SweeperType]: + return [ + THUAI7.SweeperType.CivilianSweeper, + THUAI7.SweeperType.MilitarySweeper, + THUAI7.SweeperType.MilitarySweeper, + THUAI7.SweeperType.FlagSweeper, + ] numOfGridPerCell: Final[int] = 1000 -class AssistFunction: - @staticmethod - def CellToGrid(cell: int) -> int: - return cell * numOfGridPerCell + numOfGridPerCell // 2 - - @staticmethod - def GridToCell(grid: int) -> int: - return grid // numOfGridPerCell - - class AI(IAI): def __init__(self, pID: int): self.__playerID = pID - def ShipPlay(self, api: IShipAPI) -> None: + def SweeperPlay(self, api: ISweeperAPI) -> None: # 公共操作 if self.__playerID == 0: diff --git a/CAPI/python/PyAPI/API.py b/CAPI/python/PyAPI/API.py index d5a9528b..1b207eb5 100644 --- a/CAPI/python/PyAPI/API.py +++ b/CAPI/python/PyAPI/API.py @@ -1,17 +1,17 @@ import PyAPI.structures as THUAI7 -from PyAPI.Interface import ILogic, IShipAPI, ITeamAPI, IGameTimer, IAI +from PyAPI.Interface import ILogic, ISweeperAPI, ITeamAPI, IGameTimer, IAI from math import pi from concurrent.futures import ThreadPoolExecutor, Future from typing import List, cast, Tuple, Union -class ShipAPI(IShipAPI, IGameTimer): +class SweeperAPI(ISweeperAPI, IGameTimer): def __init__(self, logic: ILogic) -> None: self.__logic = logic self.__pool = ThreadPoolExecutor(20) def Move(self, timeInMilliseconds: int, angle: float) -> Future[bool]: - return self.__pool.submit(self.__logic.move, timeInMilliseconds, angle) + return self.__pool.submit(self.__logic.Move, timeInMilliseconds, angle) def MoveRight(self, timeInMilliseconds: int) -> Future[bool]: return self.Move(timeInMilliseconds, pi * 0.5) @@ -61,11 +61,11 @@ def HaveMessage(self) -> bool: def GetMessage(self) -> Tuple[int, Union[str, bytes]]: return self.__logic.GetMessage() - def GetShips(self) -> List[THUAI7.Sweeper]: - return self.__logic.GetShips() + def GetSweepers(self) -> List[THUAI7.Sweeper]: + return self.__logic.GetSweepers() - def GetEnemyShips(self) -> List[THUAI7.Sweeper]: - return self.__logic.GetEnemyShips() + def GetEnemySweepers(self) -> List[THUAI7.Sweeper]: + return self.__logic.GetEnemySweepers() def GetBullets(self) -> List[THUAI7.Bullet]: return self.__logic.GetBullets() @@ -79,11 +79,11 @@ def GetPlaceType(self, cellX: int, cellY: int) -> THUAI7.PlaceType: def GetConstructionHp(self, cellX: int, cellY: int) -> int: return self.__logic.GetConstructionHp(cellX, cellY) - def GetWormHp(self, cellX: int, cellY: int) -> int: - return self.__logic.GetWormHp(cellX, cellY) + def GetBridgeHp(self, cellX: int, cellY: int) -> int: + return self.__logic.GetBridgeHp(cellX, cellY) - def GetResourceState(self, cellX: int, cellY: int) -> int: - return self.__logic.GetResourceState(cellX, cellY) + def GetGarbageState(self, cellX: int, cellY: int) -> int: + return self.__logic.GetGarbageState(cellX, cellY) def GetHomeHp(self) -> int: return self.__logic.GetHomeHp() @@ -95,23 +95,27 @@ def GetPlayerGUIDs(self) -> List[int]: return self.__logic.GetPlayerGUIDs() def GetSelfInfo(self) -> THUAI7.Sweeper: - return cast(THUAI7.Ships, self.__logic.GetSelfInfo()) + return cast(THUAI7.Sweepers, self.__logic.GetSelfInfo()) - def GetMoney(self) -> int: - return self.__logic.GetMoney() + def GetEnergy(self) -> int: + return self.__logic.GetEnergy() def GetScore(self) -> int: return self.__logic.GetScore() def HaveView(self, gridX: int, gridY: int) -> bool: - return self.__logic.HaveView(gridX, gridY, - self.GetSelfInfo().x, self.GetSelfInfo().y, - self.GetSelfInfo().viewRange) + return self.__logic.HaveView( + gridX, + gridY, + self.GetSelfInfo().x, + self.GetSelfInfo().y, + self.GetSelfInfo().viewRange, + ) def Print(self, cont: str) -> None: pass - def PrintShip(self) -> None: + def PrintSweeper(self) -> None: pass def PrintTeam(self) -> None: @@ -127,7 +131,7 @@ def EndTimer(self) -> None: pass def Play(self, ai: IAI) -> None: - ai.ShipPlay(self) + ai.SweeperPlay(self) class TeamAPI(ITeamAPI, IGameTimer): @@ -168,11 +172,11 @@ def EndAllAction(self) -> Future[bool]: def GetBullets(self) -> List[THUAI7.Bullet]: return self.__logic.GetBullets() - def GetShips(self) -> List[THUAI7.Sweeper]: - return self.__logic.GetShips() + def GetSweepers(self) -> List[THUAI7.Sweeper]: + return self.__logic.GetSweepers() - def GetEnemyShips(self) -> List[THUAI7.Sweeper]: - return self.__logic.GetEnemyShips() + def GetEnemySweepers(self) -> List[THUAI7.Sweeper]: + return self.__logic.GetEnemySweepers() def GetFullMap(self) -> List[List[THUAI7.PlaceType]]: return self.__logic.GetFullMap() @@ -183,8 +187,8 @@ def GetPlaceType(self, cellX: int, cellY: int) -> THUAI7.PlaceType: def GetConstructionHp(self, cellX: int, cellY: int) -> int: return self.__logic.GetConstructionHp(cellX, cellY) - def GetWormHp(self, cellX: int, cellY: int) -> int: - return self.__logic.GetWormHp(cellX, cellY) + def GetBridgeHp(self, cellX: int, cellY: int) -> int: + return self.__logic.GetBridgeHp(cellX, cellY) def GetResouceState(self, cellX: int, cellY: int) -> int: return self.__logic.GetResouceState(cellX, cellY) @@ -204,8 +208,8 @@ def GetSelfInfo(self) -> THUAI7.Home: def GetScore(self) -> int: return self.__logic.GetScore() - def GetMoney(self) -> int: - return self.__logic.GetMoney() + def GetEnergy(self) -> int: + return self.__logic.GetEnergy() def InstallModule(self, ID: int, type: THUAI7.ModuleType) -> Future[bool]: return self.__pool.submit(self.__logic.InstallModule, ID, type) @@ -213,8 +217,8 @@ def InstallModule(self, ID: int, type: THUAI7.ModuleType) -> Future[bool]: def Recycle(self, ID: int) -> Future[bool]: return self.__pool.submit(self.__logic.Recycle, ID) - def BuildShip(self, shipType: THUAI7.SweeperType, cellX: int, cellY: int) -> Future[bool]: - return self.__pool.submit(self.__logic.BuildShip, shipType, cellX, cellY) + def BuildSweeper(self, sweeperType: THUAI7.SweeperType) -> Future[bool]: + return self.__pool.submit(self.__logic.BuildSweeper, sweeperType) def Print(self, string: str) -> None: pass diff --git a/CAPI/python/PyAPI/Communication.py b/CAPI/python/PyAPI/Communication.py index 5990742a..1bde4694 100644 --- a/CAPI/python/PyAPI/Communication.py +++ b/CAPI/python/PyAPI/Communication.py @@ -33,8 +33,10 @@ def __init__(self, sIP: str, sPort: str): def Move(self, time: int, angle: float, playerID: int) -> bool: try: with self.__mtxLimit: - if (self.__counter >= self.__limit - or self.__counterMove >= self.__moveLimit): + if ( + self.__counter >= self.__limit + or self.__counterMove >= self.__moveLimit + ): return False self.__counter += 1 self.__counterMove += 1 @@ -46,15 +48,22 @@ def Move(self, time: int, angle: float, playerID: int) -> bool: else: return moveResult.act_success - def SendMessage(self, toID: int, message: Union[str, bytes], playerID: int, teamID: int) -> bool: + def SendMessage( + self, toID: int, message: Union[str, bytes], playerID: int, teamID: int + ) -> bool: try: with self.__mtxLimit: if self.__counter >= self.__limit: return False self.__counter += 1 sendResult: Message2Clients.BoolRes = self.__THUAI7Stub.Send( - THUAI72Proto.THUAI72ProtobufSendMsg(playerID, toID, teamID, message, - True if isinstance(message, bytes) else False) + THUAI72Proto.THUAI72ProtobufSendMsg( + playerID, + toID, + teamID, + message, + True if isinstance(message, bytes) else False, + ) ) except grpc.RpcError: return False @@ -103,28 +112,36 @@ def Produce(self, playerID: int, teamID: int) -> bool: else: return produceResult.act_success - def Rebuild(self, constructionType: THUAI7.ConstructionType, playerID: int, teamID: int) -> bool: + def Rebuild( + self, constructionType: THUAI7.ConstructionType, playerID: int, teamID: int + ) -> bool: try: with self.__mtxLimit: if self.__counter >= self.__limit: return False self.__counter += 1 rebuildResult: Message2Clients.BoolRes = self.__THUAI7Stub.Rebuild( - THUAI72Proto.THUAI72ProtobufConstructMsg(playerID, teamID, constructionType) + THUAI72Proto.THUAI72ProtobufConstructMsg( + playerID, teamID, constructionType + ) ) except grpc.RpcError: return False else: return rebuildResult.act_success - def Construct(self, constructionType: THUAI7.ConstructionType, playerID: int, teamID: int) -> bool: + def Construct( + self, constructionType: THUAI7.ConstructionType, playerID: int, teamID: int + ) -> bool: try: with self.__mtxLimit: if self.__counter >= self.__limit: return False self.__counter += 1 constructResult: Message2Clients.BoolRes = self.__THUAI7Stub.Construct( - THUAI72Proto.THUAI72ProtobufConstructMsg(playerID, teamID, constructionType) + THUAI72Proto.THUAI72ProtobufConstructMsg( + playerID, teamID, constructionType + ) ) except grpc.RpcError: return False @@ -134,8 +151,10 @@ def Construct(self, constructionType: THUAI7.ConstructionType, playerID: int, te def EndAllAction(self, playerID: int, teamID: int) -> bool: try: with self.__mtxLimit: - if (self.__counter >= self.__limit - or self.__counterMove >= self.__moveLimit): + if ( + self.__counter >= self.__limit + or self.__counterMove >= self.__moveLimit + ): return False self.__counter += 1 self.__counterMove += 1 @@ -147,22 +166,31 @@ def EndAllAction(self, playerID: int, teamID: int) -> bool: else: return endResult.act_success - def SendMessage(self, toID: int, message: Union[str, bytes], playerID: int, teamID: int) -> bool: + def SendMessage( + self, toID: int, message: Union[str, bytes], playerID: int, teamID: int + ) -> bool: try: with self.__mtxLimit: if self.__counter >= self.__limit: return False self.__counter += 1 sendResult: Message2Clients.BoolRes = self.__THUAI7Stub.Send( - THUAI72Proto.THUAI72ProtobufSendMsg(playerID, toID, teamID, message, - True if isinstance(message, bytes) else False) + THUAI72Proto.THUAI72ProtobufSendMsg( + playerID, + toID, + teamID, + message, + True if isinstance(message, bytes) else False, + ) ) except grpc.RpcError: return False else: return sendResult.act_success - def InstallModule(self, moduleType: THUAI7.ModuleType, playerID: int, teamID: int) -> bool: + def InstallModule( + self, moduleType: THUAI7.ModuleType, playerID: int, teamID: int + ) -> bool: try: with self.__mtxLimit: if self.__counter >= self.__limit: @@ -190,14 +218,14 @@ def Recycle(self, playerID: int, teamID: int) -> bool: else: return recycleResult.act_success - def BuildShip(self, cellX: int, cellY: int, shipType: THUAI7.SweeperType, teamID: int) -> bool: + def BuildSweeper(self, sweeperType: THUAI7.SweeperType, teamID: int) -> bool: try: with self.__mtxLimit: if self.__counter >= self.__limit: return False self.__counter += 1 - buildResult: Message2Clients.BoolRes = self.__THUAI7Stub.BuildShip( - THUAI72Proto.THUAI72ProtobufBuildSweeperMsg(teamID, shipType, cellX, cellY) + buildResult: Message2Clients.BoolRes = self.__THUAI7Stub.BuildSweeper( + THUAI72Proto.THUAI72ProtobufBuildSweeperMsg(teamID, sweeperType) ) except grpc.RpcError: return False @@ -220,11 +248,15 @@ def GetMessage2Client(self) -> Message2Clients.MessageToClient: self.__haveNewMessage = False return self.__message2Client - def AddPlayer(self, playerID: int, teamID: int, shipType: THUAI7.SweeperType) -> None: + def AddPlayer( + self, playerID: int, teamID: int, sweeperType: THUAI7.SweeperType + ) -> None: def tMessage(): try: if playerID == 0: - playerMsg = THUAI72Proto.THUAI72ProtobufPlayerMsg(playerID, teamID, shipType) + playerMsg = THUAI72Proto.THUAI72ProtobufPlayerMsg( + playerID, teamID, sweeperType + ) for msg in self.__THUAI7Stub.AddPlayer(playerMsg): with self.__cvMessage: self.__haveNewMessage = True @@ -234,7 +266,9 @@ def tMessage(): self.__counter = 0 self.__counterMove = 0 elif playerID >= 1 and playerID <= 8: - playerMsg = THUAI72Proto.THUAI72ProtobufPlayerMsg(playerID, teamID, shipType) + playerMsg = THUAI72Proto.THUAI72ProtobufPlayerMsg( + playerID, teamID, sweeperType + ) for msg in self.__THUAI7Stub.AddPlayer(playerMsg): with self.__cvMessage: self.__haveNewMessage = True diff --git a/CAPI/python/PyAPI/DebugAPI.py b/CAPI/python/PyAPI/DebugAPI.py new file mode 100644 index 00000000..3e6191e0 --- /dev/null +++ b/CAPI/python/PyAPI/DebugAPI.py @@ -0,0 +1,497 @@ +import PyAPI.structures as THUAI7 +from PyAPI.Interface import ILogic, ISweeperAPI, ITeamAPI, IGameTimer, IAI +from math import pi +from concurrent.futures import ThreadPoolExecutor, Future +from typing import List, cast, Tuple, Union +import logging +import os +import datetime + + +class SweeperDebugAPI(ISweeperAPI, IGameTimer): + def __init__( + self, logic: ILogic, file: bool, screen: bool, warnOnly: bool, playerID: int + ) -> None: + self.__logic = logic + self.__pool = ThreadPoolExecutor(20) + self.__startPoint = datetime.datetime.now() + self.__logger = logging.getLogger("api " + str(playerID)) + self.__logger.setLevel(logging.DEBUG) + formatter = logging.Formatter( + "[%(name)s] [%(asctime)s.%(msecs)03d] [%(levelname)s] %(message)s", + "%H:%M:%S", + ) + # 确保文件存在 + if not os.path.exists( + os.path.dirname(os.path.dirname(os.path.realpath(__file__))) + "/logs" + ): + os.makedirs( + os.path.dirname(os.path.dirname(os.path.realpath(__file__))) + "/logs" + ) + + fileHandler = logging.FileHandler( + os.path.dirname(os.path.dirname(os.path.realpath(__file__))) + + "/logs/api-" + + str(playerID) + + "-log.txt", + mode="w+", + encoding="utf-8", + ) + screenHandler = logging.StreamHandler() + if file: + fileHandler.setLevel(logging.DEBUG) + fileHandler.setFormatter(formatter) + self.__logger.addHandler(fileHandler) + if screen: + if warnOnly: + screenHandler.setLevel(logging.WARNING) + else: + screenHandler.setLevel(logging.INFO) + screenHandler.setFormatter(formatter) + self.__logger.addHandler(screenHandler) + + def Move(self, timeInMilliseconds: int, angle: float) -> Future[bool]: + self.__logger.info( + f"Move: timeInMilliseconds = {timeInMilliseconds}, angle = {angle}, called at {self.__GetTime()}ms" + ) + + def logMove() -> bool: + result = self.__logic.Move(timeInMilliseconds, angle) + if not result: + self.__logger.warning(f"Move: failed at {self.__GetTime()}ms") + return result + + return self.__pool.submit(logMove) + + def MoveRight(self, timeInMilliseconds: int) -> Future[bool]: + return self.Move(timeInMilliseconds, pi * 0.5) + + def MoveLeft(self, timeInMilliseconds: int) -> Future[bool]: + return self.Move(timeInMilliseconds, pi * 1.5) + + def MoveUp(self, timeInMilliseconds: int) -> Future[bool]: + return self.Move(timeInMilliseconds, pi) + + def MoveDown(self, timeInMilliseconds: int) -> Future[bool]: + return self.Move(timeInMilliseconds, 0) + + def Attack(self, angle: float) -> Future[bool]: + self.__logger.info(f"Attack: angle = {angle}, called at {self.__GetTime()}ms") + + def logAttack() -> bool: + result = self.__logic.Attack(angle) + if not result: + self.__logger.warning(f"Attack: failed at {self.__GetTime()}ms") + return result + + return self.__pool.submit(logAttack) + + def Recover(self) -> Future[bool]: + self.__logger.info(f"Recover: called at {self.__GetTime()}ms") + + def logRecover() -> bool: + result = self.__logic.Recover() + if not result: + self.__logger.warning(f"Recover failed at {self.__GetTime()}ms") + return result + + return self.__pool.submit(logRecover) + + def Produce(self) -> Future[bool]: + self.__logger.info(f"Produce: called at {self.__GetTime()}ms") + + def logProduce() -> bool: + result = self.__logic.Produce() + if not result: + self.__logger.warning(f"Produce failed at {self.__GetTime()}ms") + return result + + return self.__pool.submit(logProduce) + + def Rebuild(self, constructionType: THUAI7.ConstructionType) -> Future[bool]: + self.__logger.info( + f"Rebuild: called at {self.__GetTime()}ms construction type {constructionType}" + ) + + def logRebuild() -> bool: + result = self.__logic.Rebuild(constructionType) + if not result: + self.__logger.warning( + f"Rebuild failed at {self.__GetTime()}ms with construction type {constructionType}" + ) + return result + + return self.__pool.submit(logRebuild) + + def Construct(self, constructionType: THUAI7.ConstructionType) -> Future[bool]: + self.__logger.info( + f"Construct: called at {self.__GetTime()}ms with construction type {constructionType}" + ) + + def logConstruct() -> bool: + result = self.__logic.Construct(constructionType) + if not result: + self.__logger.warning( + f"Construct failed at {self.__GetTime()}ms with construction type {constructionType}" + ) + return result + + return self.__pool.submit(logConstruct) + + def Wait(self) -> bool: + self.__logger.info(f"Wait: called at {self.__GetTime()}ms") + if self.__logic.GetCounter() == -1: + return False + else: + return self.__logic.WaitThread() + + def EndAllAction(self) -> Future[bool]: + self.__logger.info(f"EndAllAction: called at {self.__GetTime()}ms") + + def logEnd() -> bool: + result = self.__logic.EndAllAction() + if not result: + self.__logger.warning(f"EndAllAction: failed at {self.__GetTime()}ms") + return result + + return self.__pool.submit(logEnd) + + def SendMessage(self, toID: int, message: Union[str, bytes]) -> Future[bool]: + self.__logger.info( + f"SendMessage: toID = {toID}, message = {message}, called at {self.__GetTime()}ms" + ) + + def logSend() -> bool: + result = self.__logic.SendMessage(toID, message) + if not result: + self.__logger.warning(f"SendMessage: failed at {self.__GetTime()}ms") + return result + + return self.__pool.submit(logSend) + + def HaveMessage(self) -> bool: + self.__logger.info(f"HaveMessage: called at {self.__GetTime()}ms") + result = self.__logic.HaveMessage() + if not result: + self.__logger.warning(f"HaveMessage: failed at {self.__GetTime()}ms") + return result + + def GetMessage(self) -> Tuple[int, Union[str, bytes]]: + self.__logger.info(f"GetMessage: called at {self.__GetTime()}ms") + result = self.__logic.GetMessage() + if result[0] == -1: + self.__logger.warning(f"GetMessage: failed at {self.__GetTime()}ms") + return result + + def GetFrameCount(self) -> int: + return self.__logic.GetFrameCount() + + def GetSweepers(self) -> List[THUAI7.Sweeper]: + return self.__logic.GetSweepers() + + def GetEnemySweepers(self) -> List[THUAI7.Sweeper]: + return self.__logic.GetEnemySweepers() + + def GetBullets(self) -> List[THUAI7.Bullet]: + return self.__logic.GetBullets() + + def GetFullMap(self) -> List[List[THUAI7.PlaceType]]: + return self.__logic.GetFullMap() + + def GetPlaceType(self, cellX: int, cellY: int) -> THUAI7.PlaceType: + return self.__logic.GetPlaceType(cellX, cellY) + + def GetConstructionHp(self, cellX: int, cellY: int) -> int: + return self.__logic.GetConstructionHp(cellX, cellY) + + def GetBridgeHp(self, cellX: int, cellY: int) -> int: + return self.__logic.GetBridgeHp(cellX, cellY) + + def GetGarbageState(self, cellX: int, cellY: int) -> int: + return self.__logic.GetGarbageState(cellX, cellY) + + def GetHomeHp(self) -> int: + return self.__logic.GetHomeHp() + + def GetGameInfo(self) -> THUAI7.GameInfo: + return self.__logic.GetGameInfo() + + def GetPlayerGUIDs(self) -> List[int]: + return self.__logic.GetPlayerGUIDs() + + def GetSelfInfo(self) -> THUAI7.Sweeper: + return cast(THUAI7.Sweepers, self.__logic.GetSelfInfo()) + + def GetEnergy(self) -> int: + return self.__logic.GetEnergy() + + def GetScore(self) -> int: + return self.__logic.GetScore() + + def HaveView(self, gridX: int, gridY: int) -> bool: + return self.__logic.HaveView( + gridX, + gridY, + self.GetSelfInfo().x, + self.GetSelfInfo().y, + self.GetSelfInfo().viewRange, + ) + + def Print(self, cont: str) -> None: + self.__logger.info(cont) + + def PrintSweeper(self) -> None: + for sweeper in self.__logic.GetSweepers(): + self.__logger.info("******sweeper Info******") + self.__logger.info( + f"teamID={sweeper.teamID} playerID={sweeper.playerID}, GUID={sweeper.guid} sweeperType:{sweeper.sweeperType}" + ) + self.__logger.info( + f"x={sweeper.x}, y={sweeper.y} hp={sweeper.hp} armor={sweeper.armor} shield={sweeper.shield} state:{sweeper.sweeperState}" + ) + self.__logger.info( + f"speed={sweeper.speed}, view range={sweeper.viewRange}, facingDirection={sweeper.facingDirection}" + ) + self.__logger.info( + f"producerType:{sweeper.producerType} constructorType:{sweeper.constructorType}" + ) + self.__logger.info( + f"armorType:{sweeper.armorType} shieldType:{sweeper.shieldType} weaponType:{sweeper.weaponType}" + ) + self.__logger.info("************************\n") + + def PrintTeam(self) -> None: + pass + + def PrintSelfInfo(self) -> None: + sweeper = self.__logic.GetSelfInfo() + self.__logger.info("******sweeper Info******") + self.__logger.info( + f"teamID={sweeper.teamID} playerID={sweeper.playerID}, GUID={sweeper.guid} sweeperType:{sweeper.sweeperType}" + ) + self.__logger.info( + f"x={sweeper.x}, y={sweeper.y} hp={sweeper.hp} armor={sweeper.armor} shield={sweeper.shield} state:{sweeper.sweeperState}" + ) + self.__logger.info( + f"speed={sweeper.speed}, view range={sweeper.viewRange}, facingDirection={sweeper.facingDirection}" + ) + self.__logger.info( + f"producerType:{sweeper.producerType} constructorType:{sweeper.constructorType}" + ) + self.__logger.info( + f"armorType:{sweeper.armorType} shieldType:{sweeper.shieldType} weaponType:{sweeper.weaponType}" + ) + self.__logger.info("************************\n") + + def __GetTime(self) -> float: + return (datetime.datetime.now() - self.__startPoint) / datetime.timedelta( + milliseconds=1 + ) + + def StartTimer(self) -> None: + self.__startPoint = datetime.datetime.now() + self.__logger.info("=== AI.play() ===") + self.__logger.info(f"StartTimer: {self.__startPoint.time()}") + + def EndTimer(self) -> None: + self.__logger.info(f"Time elapsed: {self.__GetTime()}ms") + + def Play(self, ai: IAI) -> None: + ai.SweeperPlay(self) + + +class TeamDebugAPI(ITeamAPI, IGameTimer): + def __init__( + self, logic: ILogic, file: bool, screen: bool, warnOnly: bool, playerID: int + ) -> None: + self.__logic = logic + self.__pool = ThreadPoolExecutor(20) + self.__startPoint = datetime.datetime.now() + self.__logger = logging.getLogger("api " + str(playerID)) + self.__logger.setLevel(logging.DEBUG) + formatter = logging.Formatter( + "[%(name)s] [%(asctime)s.%(msecs)03d] [%(levelname)s] %(message)s", + "%H:%M:%S", + ) + # 确保文件存在 + if not os.path.exists( + os.path.dirname(os.path.dirname(os.path.realpath(__file__))) + "/logs" + ): + os.makedirs( + os.path.dirname(os.path.dirname(os.path.realpath(__file__))) + "/logs" + ) + + fileHandler = logging.FileHandler( + os.path.dirname(os.path.dirname(os.path.realpath(__file__))) + + "/logs/api-" + + str(playerID) + + "-log.txt", + mode="w+", + encoding="utf-8", + ) + screenHandler = logging.StreamHandler() + if file: + fileHandler.setLevel(logging.DEBUG) + fileHandler.setFormatter(formatter) + self.__logger.addHandler(fileHandler) + if screen: + if warnOnly: + screenHandler.setLevel(logging.WARNING) + else: + screenHandler.setLevel(logging.INFO) + screenHandler.setFormatter(formatter) + self.__logger.addHandler(screenHandler) + + def SendMessage(self, toID: int, message: Union[str, bytes]) -> Future[bool]: + self.__logger.info( + f"SendMessage: toID = {toID}, message = {message}, called at {self.__GetTime()}ms" + ) + + def logSend() -> bool: + result = self.__logic.SendMessage(toID, message) + if not result: + self.__logger.warning(f"SendMessage: failed at {self.__GetTime()}ms") + return result + + return self.__pool.submit(logSend) + + def HaveMessage(self) -> bool: + self.__logger.info(f"HaveMessage: called at {self.__GetTime()}ms") + result = self.__logic.HaveMessage() + if not result: + self.__logger.warning(f"HaveMessage: failed at {self.__GetTime()}ms") + return result + + def GetMessage(self) -> Tuple[int, Union[str, bytes]]: + self.__logger.info(f"GetMessage: called at {self.__GetTime()}ms") + result = self.__logic.GetMessage() + if result[0] == -1: + self.__logger.warning(f"GetMessage: failed at {self.__GetTime()}ms") + return result + + def Wait(self) -> bool: + self.__logger.info(f"Wait: called at {self.__GetTime()}ms") + if self.__logic.GetCounter() == -1: + return False + else: + return self.__logic.WaitThread() + + def EndAllAction(self) -> Future[bool]: + self.__logger.info(f"EndAllAction: called at {self.__GetTime()}ms") + + def logEnd() -> bool: + result = self.__logic.EndAllAction() + if not result: + self.__logger.warning(f"EndAllAction: failed at {self.__GetTime()}ms") + return result + + return self.__pool.submit(logEnd) + + def InstallModule( + self, playerID: int, moduleType: THUAI7.ModuleType + ) -> Future[bool]: + self.__logger.info( + f"InstallModule: playerID = {playerID}, type = {moduleType}, called at {self.__GetTime()}ms" + ) + + def logInstallModule() -> bool: + result = self.__logic.InstallModule(playerID, moduleType) + if not result: + self.__logger.warning(f"InstallModule: failed at {self.__GetTime()}ms") + return result + + return self.__pool.submit(logInstallModule) + + def Recycle(self, playerID: int) -> Future[bool]: + self.__logger.info(f"Recycle: ID = {playerID}, called at {self.__GetTime()}ms") + + def logRecycle() -> bool: + result = self.__logic.Recycle(playerID) + if not result: + self.__logger.warning(f"Recycle: failed at {self.__GetTime()}ms") + return result + + return self.__pool.submit(logRecycle) + + def BuildSweeper(self, sweeperType: THUAI7.SweeperType) -> Future[bool]: + self.__logger.info( + f"BuildSweeper: sweeperType = {sweeperType}, called at {self.__GetTime()}ms" + ) + + def logBuildSweeper() -> bool: + result = self.__logic.BuildSweeper(sweeperType) + if not result: + self.__logger.warning(f"BuildSweeper: failed at {self.__GetTime()}ms") + return result + + return self.__pool.submit(logBuildSweeper) + + def GetFrameCount(self) -> int: + return self.__logic.GetFrameCount() + + def GetBullets(self) -> List[THUAI7.Bullet]: + return self.__logic.GetBullets() + + def GetSweepers(self) -> List[THUAI7.Sweeper]: + return self.__logic.GetSweepers() + + def GetEnemySweepers(self) -> List[THUAI7.Sweeper]: + return self.__logic.GetEnemySweepers() + + def GetFullMap(self) -> List[List[THUAI7.PlaceType]]: + return self.__logic.GetFullMap() + + def GetPlaceType(self, cellX: int, cellY: int) -> THUAI7.PlaceType: + return self.__logic.GetPlaceType(cellX, cellY) + + def GetConstructionHp(self, cellX: int, cellY: int) -> int: + return self.__logic.GetConstructionHp(cellX, cellY) + + def GetBridgeHp(self, cellX: int, cellY: int) -> int: + return self.__logic.GetBridgeHp(cellX, cellY) + + def GetResouceState(self, cellX: int, cellY: int) -> int: + return self.__logic.GetResouceState(cellX, cellY) + + def GetHomeHp(self) -> int: + return self.__logic.GetHomeHp() + + def GetGameInfo(self) -> THUAI7.GameInfo: + return self.__logic.GetGameInfo() + + def GetPlayerGUIDs(self) -> List[int]: + return self.__logic.GetPlayerGUIDs() + + def GetSelfInfo(self) -> THUAI7.Home: + return cast(THUAI7.Home, self.__logic.GetSelfInfo()) + + def GetScore(self) -> int: + return self.__logic.GetScore() + + def GetEnergy(self) -> int: + return self.__logic.GetEnergy() + + def Print(self, string: str) -> None: + pass + + def PrintTeam(self) -> None: + pass + + def PrintSelfInfo(self) -> None: + pass + + def __GetTime(self) -> float: + return (datetime.datetime.now() - self.__startPoint) / datetime.timedelta( + milliseconds=1 + ) + + def StartTimer(self) -> None: + self.__startPoint = datetime.datetime.now() + self.__logger.info("=== AI.play() ===") + self.__logger.info(f"StartTimer: {self.__startPoint.time()}") + + def EndTimer(self) -> None: + self.__logger.info(f"Time elapsed: {self.__GetTime()}ms") + + def Play(self, ai: IAI) -> None: + ai.SweeperPlay(self) diff --git a/CAPI/python/PyAPI/Interface.py b/CAPI/python/PyAPI/Interface.py index b6b0fe23..2f7cde50 100644 --- a/CAPI/python/PyAPI/Interface.py +++ b/CAPI/python/PyAPI/Interface.py @@ -8,14 +8,14 @@ class ILogic(metaclass=ABCMeta): - '''`IAPI` 统一可用的接口''' + """`IAPI` 统一可用的接口""" @abstractmethod - def GetShips(self) -> List[THUAI7.Sweeper]: + def GetSweepers(self) -> List[THUAI7.Sweeper]: pass @abstractmethod - def GetEnemyShips(self) -> List[THUAI7.Sweeper]: + def GetEnemySweepers(self) -> List[THUAI7.Sweeper]: pass @abstractmethod @@ -47,11 +47,11 @@ def GetConstructionHp(self, cellX: int, cellY: int) -> int: pass @abstractmethod - def GetWormHp(self, cellX: int, cellY: int) -> int: + def GetBridgeHp(self, cellX: int, cellY: int) -> int: pass @abstractmethod - def GetResourceState(self, cellX: int, cellY: int) -> int: + def GetGarbageState(self, cellX: int, cellY: int) -> int: pass @abstractmethod @@ -59,7 +59,7 @@ def GetHomeHp(self) -> int: pass @abstractmethod - def GetMoney(self) -> int: + def GetEnergy(self) -> int: pass @abstractmethod @@ -115,7 +115,9 @@ def Attack(self, angle: float) -> bool: pass @abstractmethod - def HaveView(self, gridX: int, gridY: int, selfX: int, selfY: int, viewRange: int) -> bool: + def HaveView( + self, gridX: int, gridY: int, selfX: int, selfY: int, viewRange: int + ) -> bool: pass @abstractmethod @@ -127,18 +129,18 @@ def InstallModule(self, playerID: int, moduleType: THUAI7.ModuleType) -> bool: pass @abstractmethod - def BuildShip(self, shipType: THUAI7.SweeperType, cellX: int, cellY: int) -> bool: + def BuildSweeper(self, sweeperType: THUAI7.SweeperType) -> bool: pass class IAPI(metaclass=ABCMeta): - ''' + """ 选手可执行的操作,应当保证所有函数的返回值都应当为 `asyncio.Future`,例如下面的移动函数:\n 指挥本角色进行移动: - `timeInMilliseconds` 为移动时间,单位为毫秒 - `angleInRadian` 表示移动的方向,单位是弧度,使用极坐标——竖直向下方向为 x 轴,水平向右方向为 y 轴\n 发送信息、接受信息,注意收消息时无消息则返回 `nullopt` - ''' + """ @abstractmethod def SendMessage(self, toPlayerID: int, message: Union[str, bytes]) -> Future[bool]: @@ -159,12 +161,12 @@ def Move(self, timeInMilliseconds: int, angle: float) -> Future[bool]: # 获取游戏目前所进行的帧数 @abstractmethod def GetFrameCount(self) -> int: - '获取游戏目前所进行的帧数' + "获取游戏目前所进行的帧数" pass @abstractmethod def Wait(self) -> Future[bool]: - '等待下一帧' + "等待下一帧" pass @abstractmethod @@ -172,11 +174,11 @@ def EndAllAction(self) -> Future[bool]: pass @abstractmethod - def GetShips(self) -> List[THUAI7.Sweeper]: + def GetSweepers(self) -> List[THUAI7.Sweeper]: pass @abstractmethod - def GetEnemyShips(self) -> List[THUAI7.Sweeper]: + def GetEnemySweepers(self) -> List[THUAI7.Sweeper]: pass @abstractmethod @@ -200,11 +202,11 @@ def GetConstructionHp(self, cellX: int, cellY: int) -> int: pass @abstractmethod - def GetWormHp(self, cellX: int, cellY: int) -> int: + def GetBridgeHp(self, cellX: int, cellY: int) -> int: pass @abstractmethod - def GetResourceState(self, cellX: int, cellY: int) -> int: + def GetGarbageState(self, cellX: int, cellY: int) -> int: pass @abstractmethod @@ -212,7 +214,7 @@ def GetHomeHp(self) -> int: pass @abstractmethod - def GetMoney(self) -> int: + def GetEnergy(self) -> int: pass @abstractmethod @@ -228,7 +230,7 @@ def Print(self, string: str) -> None: pass @abstractmethod - def PrintShip(self) -> None: + def PrintSweeper(self) -> None: pass @abstractmethod @@ -244,7 +246,7 @@ def GetSelfInfo(self) -> Union[THUAI7.Sweeper, THUAI7.Team]: pass -class IShipAPI(IAPI, metaclass=ABCMeta): +class ISweeperAPI(IAPI, metaclass=ABCMeta): @abstractmethod def Move(self, timeInMilliseconds: int, angleInRadian: float) -> Future[bool]: pass @@ -300,7 +302,9 @@ def GetSelfInfo(self) -> THUAI7.Team: pass @abstractmethod - def InstallModule(self, playerID: int, moduleType: THUAI7.ModuleType) -> Future[bool]: + def InstallModule( + self, playerID: int, moduleType: THUAI7.ModuleType + ) -> Future[bool]: pass @abstractmethod @@ -308,13 +312,13 @@ def Recycle(self, playerID: int) -> Future[bool]: pass @abstractmethod - def BuildShip(self, shipType: THUAI7.SweeperType, cellX: int, cellY: int) -> Future[bool]: + def BuildSweeper(self, sweeperType: THUAI7.SweeperType) -> Future[bool]: pass class IAI(metaclass=ABCMeta): @abstractmethod - def ShipPlay(self, api: IShipAPI) -> None: + def SweeperPlay(self, api: ISweeperAPI) -> None: pass @abstractmethod diff --git a/CAPI/python/PyAPI/State.py b/CAPI/python/PyAPI/State.py index d032a174..e9451ef0 100644 --- a/CAPI/python/PyAPI/State.py +++ b/CAPI/python/PyAPI/State.py @@ -6,9 +6,8 @@ class State: def __init__(self) -> None: self.teamScore = 0 self.self = THUAI7.Sweeper() - self.ships = [] + self.sweepers = [] self.enemySweepers = [] - self.teams = [] self.gameMap = [] self.bullets = [] self.bombedBullets = [] @@ -19,15 +18,13 @@ def __init__(self) -> None: teamScore: int self: Union[THUAI7.Sweeper, THUAI7.Team] - ships: List[THUAI7.Sweeper] + sweepers: List[THUAI7.Sweeper] enemySweepers: List[THUAI7.Sweeper] - teams: List[THUAI7.Team] - gameMap: List[List[THUAI7.PlaceType]] bullets: List[THUAI7.Bullet] - #bombedBullets: List[THUAI7.BombedBullet] + # bombedBullets: List[THUAI7.BombedBullet] mapInfo: THUAI7.GameMap diff --git a/CAPI/python/PyAPI/logic.py b/CAPI/python/PyAPI/logic.py index b0a1aca9..f9c90fcb 100644 --- a/CAPI/python/PyAPI/logic.py +++ b/CAPI/python/PyAPI/logic.py @@ -10,19 +10,27 @@ from queue import Queue import PyAPI.structures as THUAI7 from PyAPI.utils import Proto2THUAI7, AssistFunction -from PyAPI.API import ShipAPI, TeamAPI +from PyAPI.API import SweeperAPI, TeamAPI +from PyAPI.DebugAPI import SweeperDebugAPI, TeamDebugAPI from PyAPI.AI import Setting from PyAPI.Communication import Communication from PyAPI.State import State from PyAPI.Interface import ILogic, IGameTimer +from PyAPI.DebugAPI import SweeperDebugAPI, TeamDebugAPI class Logic(ILogic): - def __init__(self, playerID: int, teamID: int, playerType: THUAI7.PlayerType, shipType: THUAI7.SweeperType) -> None: + def __init__( + self, + playerID: int, + teamID: int, + playerType: THUAI7.PlayerType, + sweeperType: THUAI7.SweeperType, + ) -> None: self.__playerID: int = playerID self.__teamID: int = teamID self.__playerType: THUAI7.PlayerType = playerType - self.__shipType: THUAI7.SweeperType = shipType + self.__sweeperType: THUAI7.SweeperType = sweeperType self.__comm: Communication @@ -55,14 +63,14 @@ def __init__(self, playerID: int, teamID: int, playerType: THUAI7.PlayerType, sh self.__messageQueue: Queue = Queue() - def GetShips(self) -> List[THUAI7.Sweeper]: + def GetSweepers(self) -> List[THUAI7.Sweeper]: with self.__mtxState: - self.__logger.debug("Called GetShips") - return copy.deepcopy(self.__currentState.ships) + self.__logger.debug("Called GetSweepers") + return copy.deepcopy(self.__currentState.sweepers) - def GetEnemyShips(self) -> List[THUAI7.Sweeper]: + def GetEnemySweepers(self) -> List[THUAI7.Sweeper]: with self.__mtxState: - self.__logger.debug("Called GetEnemyShips") + self.__logger.debug("Called GetEnemySweepers") return copy.deepcopy(self.__currentState.enemySweepers) def GetBullets(self) -> List[THUAI7.Bullet]: @@ -82,7 +90,12 @@ def GetFullMap(self) -> List[List[THUAI7.PlaceType]]: def GetPlaceType(self, x: int, y: int) -> THUAI7.PlaceType: with self.__mtxState: - if x < 0 or x >= len(self.__currentState.gameMap) or y < 0 or y >= len(self.__currentState.gameMap[0]): + if ( + x < 0 + or x >= len(self.__currentState.gameMap) + or y < 0 + or y >= len(self.__currentState.gameMap[0]) + ): self.__logger.warning("GetPlaceType: Out of range") return THUAI7.PlaceType(0) self.__logger.debug("Called GetPlaceType") @@ -128,54 +141,70 @@ def GetPlayerGUIDs(self) -> List[int]: def GetConstructionHp(self, cellX: int, cellY: int) -> int: with self.__mtxState: self.__logger.debug("Called GetConstructionHp") - if (cellX, cellY) in self.__currentState.mapInfo.factoryState: - return copy.deepcopy(self.__currentState.mapInfo.factoryState[(cellX, cellY)]) - elif (cellX, cellY) in self.__currentState.mapInfo.communityState: - return copy.deepcopy(self.__currentState.mapInfo.communityState[(cellX, cellY)]) - elif (cellX, cellY) in self.__currentState.mapInfo.fortState: - return copy.deepcopy(self.__currentState.mapInfo.fortState[(cellX, cellY)]) + if (cellX, cellY) in self.__currentState.mapInfo.recycleBankState: + return copy.deepcopy( + self.__currentState.mapInfo.recycleBankState[(cellX, cellY)] + ) + elif (cellX, cellY) in self.__currentState.mapInfo.chargeStationState: + return copy.deepcopy( + self.__currentState.mapInfo.chargeStationState[(cellX, cellY)] + ) + elif (cellX, cellY) in self.__currentState.mapInfo.signalTowerState: + return copy.deepcopy( + self.__currentState.mapInfo.signalTowerState[(cellX, cellY)] + ) else: self.__logger.warning("GetConstructionHp: Out of range") return -1 - def GetWormHp(self, cellX: int, cellY: int) -> int: + def GetBridgeHp(self, cellX: int, cellY: int) -> int: with self.__mtxState: - self.__logger.debug("Called GetWormHp") - if (cellX, cellY) not in self.__currentState.mapInfo.wormholeState: - self.__logger.warning("GetWormHp: Out of range") + self.__logger.debug("Called GetBridgeHp") + if (cellX, cellY) not in self.__currentState.mapInfo.bridgeState: + self.__logger.warning("GetBridgeHp: Out of range") return -1 else: - return copy.deepcopy(self.__currentState.mapInfo.wormholeState[(cellX, cellY)]) + return copy.deepcopy( + self.__currentState.mapInfo.bridgeState[(cellX, cellY)] + ) - def GetResourceState(self, cellX: int, cellY: int) -> int: + def GetGarbageState(self, cellX: int, cellY: int) -> int: with self.__mtxState: - self.__logger.debug("Called GetResourceState") - if (cellX, cellY) not in self.__currentState.mapInfo.resourceState: - self.__logger.warning("GetResourceState: Out of range") + self.__logger.debug("Called GetGarbageState") + if (cellX, cellY) not in self.__currentState.mapInfo.garbageState: + self.__logger.warning("GetGarbageState: Out of range") return -1 else: - return copy.deepcopy(self.__currentState.mapInfo.resourceState[(cellX, cellY)]) + return copy.deepcopy( + self.__currentState.mapInfo.garbageState[(cellX, cellY)] + ) def GetHomeHp(self) -> int: with self.__mtxState: self.__logger.debug("Called GetHomeHp") - return copy.deepcopy(self.__currentState.gameInfo.blueHomeHp - if self.__teamID == 1 - else self.__currentState.gameInfo.redHomeHp) + return copy.deepcopy( + self.__currentState.gameInfo.blueHomeHp + if self.__teamID == 1 + else self.__currentState.gameInfo.redHomeHp + ) - def GetMoney(self) -> int: + def GetEnergy(self) -> int: with self.__mtxState: - self.__logger.debug("Called GetMoney") - return copy.deepcopy(self.__currentState.gameInfo.blueMoney - if self.__teamID == 1 - else self.__currentState.gameInfo.redMoney) + self.__logger.debug("Called GetEnergy") + return copy.deepcopy( + self.__currentState.gameInfo.blueMoney + if self.__teamID == 1 + else self.__currentState.gameInfo.redMoney + ) def GetScore(self) -> int: with self.__mtxState: self.__logger.debug("Called GetScore") - return copy.deepcopy(self.__currentState.gameInfo.blueScore - if self.__teamID == 1 - else self.__currentState.gameInfo.redScore) + return copy.deepcopy( + self.__currentState.gameInfo.blueScore + if self.__teamID == 1 + else self.__currentState.gameInfo.redScore + ) def Attack(self, angle: float) -> int: self.__logger.debug("Called Attack") @@ -185,10 +214,14 @@ def EndAllAction(self) -> bool: self.__logger.debug("Called EndAllAction") return self.__comm.EndAllAction(self.__playerID, self.__teamID) - def HaveView(self, gridX: int, gridY: int, selfX: int, selfY: int, viewRange: int) -> bool: + def HaveView( + self, gridX: int, gridY: int, selfX: int, selfY: int, viewRange: int + ) -> bool: with self.__mtxState: self.__logger.debug("Called HaveView") - return AssistFunction.HaveView(viewRange, selfX, selfY, gridX, gridY, self.__currentState.gameMap) + return AssistFunction.HaveView( + viewRange, selfX, selfY, gridX, gridY, self.__currentState.gameMap + ) def TryConnection(self) -> bool: self.__logger.info("Called TryConnection") @@ -218,9 +251,9 @@ def Recycle(self) -> bool: self.__logger.debug("Called Recycle") return self.__comm.Recycle(self.__playerID, self.__playerID, self.__teamID) - def BuildShip(self, shipType: THUAI7.SweeperType, cellX: int, cellY: int) -> bool: - self.__logger.debug("Called BuildShip") - return self.__comm.BuildShip(cellX, cellY, shipType, self.__teamID) + def BuildSweeper(self, sweeperType: THUAI7.SweeperType) -> bool: + self.__logger.debug("Called BuildSweeper") + return self.__comm.BuildSweeper(sweeperType, self.__teamID) def __TryConnection(self) -> bool: self.__logger.info("Try to connect to the server.") @@ -229,7 +262,7 @@ def __TryConnection(self) -> bool: def __ProcessMessage(self) -> None: def messageThread(): self.__logger.info("Message thread started") - self.__comm.AddPlayer(self.__playerID, self.__teamID, self.__shipType) + self.__comm.AddPlayer(self.__playerID, self.__teamID, self.__sweeperType) self.__logger.info("Player added") while self.__gameState != THUAI7.GameState.GameEnd: @@ -275,11 +308,10 @@ def messageThread(): threading.Thread(target=messageThread).start() - def LoadBuffer(self, message: Message2Clients.MessageToClient) -> None: + def __LoadBuffer(self, message: Message2Clients.MessageToClient) -> None: with self.__cvBuffer: - self.__bufferState.ships.clear() + self.__bufferState.sweepers.clear() self.__bufferState.enemySweepers.clear() - self.__bufferState.teams.clear() self.__bufferState.bullets.clear() self.__bufferState.bombedBullets.clear() self.__bufferState.guids.clear() @@ -287,21 +319,26 @@ def LoadBuffer(self, message: Message2Clients.MessageToClient) -> None: if self.__playerID != 0: for obj in message.obj_message: - if obj.WhichOneof("message_of_obj") == "ship_message": - self.__bufferState.guids.append(obj.ship_message.guid) + if obj.WhichOneof("message_of_obj") == "sweeper_message": + self.__bufferState.guids.append(obj.sweeper_message.guid) else: for obj in message.obj_message: if obj.WhichOneof("message_of_obj") == "team_message": self.__bufferState.guids.append(obj.team_message.guid) - self.__bufferState.gameInfo = Proto2THUAI7.Protobuf2THUAI7GameInfo(message.all_message) + self.__bufferState.gameInfo = Proto2THUAI7.Protobuf2THUAI7GameInfo( + message.all_message + ) self.__LoadBufferSelf(message) for item in message.obj_message: self.__LoadBufferCase(item) if Setting.Asynchronous(): with self.__mtxState: - self.__currentState, self.__bufferState = self.__bufferState, self.__currentState + self.__currentState, self.__bufferState = ( + self.__bufferState, + self.__currentState, + ) self.__counterState = self.__counterBuffer self.__logger.info("Update state!") self.__freshed = True @@ -313,135 +350,463 @@ def LoadBuffer(self, message: Message2Clients.MessageToClient) -> None: def __LoadBufferSelf(self, message: Message2Clients.MessageToClient) -> None: if self.__playerID != 0: for item in message.obj_message: - if item.WhichOneof("message_of_obj") == "ship_message": - if item.ship_message.player_id == self.__playerID: - self.__bufferState.self = Proto2THUAI7.Protobuf2THUAI7Sweeper(item.ship_message) - self.__bufferState.ships.append(self.__bufferState.self) - else: - self.__bufferState.ships.append(Proto2THUAI7.Protobuf2THUAI7Sweeper(item.ship_message)) - self.__logger.debug("Load ship") + if item.WhichOneof("message_of_obj") == "sweeper_message": + if item.sweeper_message.player_id == self.__playerID: + self.__bufferState.self = Proto2THUAI7.Protobuf2THUAI7Sweeper( + item.sweeper_message + ) + self.__bufferState.sweepers.append(self.__bufferState.self) + self.__logger.debug("Load self sweeper") else: for item in message.obj_message: if item.WhichOneof("message_of_obj") == "team_message": - self.__bufferState.self = Proto2THUAI7.Protobuf2THUAI7Team(item.team_message) - self.__bufferState.teams.append(self.__bufferState.self) - self.__logger.debug("Load team") + self.__bufferState.self = Proto2THUAI7.Protobuf2THUAI7Team( + item.team_message + ) + self.__logger.debug("Load self team") + if item.WhichOneof("message_of_obj") == "sweeper_message": + if item.sweeper_message.team_id == self.__teamID: + self.__bufferState.sweepers.append( + Proto2THUAI7.Protobuf2THUAI7Sweeper(item.sweeper_message) + ) + self.__logger.debug("Load sweeper") def __LoadBufferCase(self, item: Message2Clients.MessageOfObj) -> None: - if item.WhichOneof("message_of_obj") == "ship_message": - if item.ship_message.team_id != self.__teamID: - if AssistFunction.HaveView(self.__bufferState.self.viewRange, - self.__bufferState.self.x, self.__bufferState.self.y, - item.ship_message.x, item.ship_message.y, - self.__bufferState.gameMap): - self.__bufferState.enemySweepers.append(Proto2THUAI7.Protobuf2THUAI7Sweeper(item.ship_message)) - self.__logger.debug("Load enemy ship") - - elif item.WhichOneof("message_of_obj") == "bullet_message": - if AssistFunction.HaveView(self.__bufferState.self.viewRange, - self.__bufferState.self.x, self.__bufferState.self.y, - item.bullet_message.x, item.bullet_message.y, - self.__bufferState.gameMap): - self.__bufferState.bullets.append(Proto2THUAI7.Protobuf2THUAI7Bullet(item.bullet_message)) - self.__logger.debug("Add Bullet!") - - elif item.WhichOneof("message_of_obj") == "factory_message": - if AssistFunction.HaveView(self.__bufferState.self.viewRange, self.__bufferState.self.x, - self.__bufferState.self.y, item.factory_message.x, item.factory_message.y, - self.__bufferState.gameMap): - pos = (AssistFunction.GridToCell(item.factory_message.x), - AssistFunction.GridToCell(item.factory_message.y)) - if pos not in self.__bufferState.mapInfo.factoryState: - self.__bufferState.mapInfo.factoryState[pos] = item.factory_message.hp - self.__logger.debug("New Factory") - else: - self.__bufferState.mapInfo.factoryState[pos] = item.factory_message.hp - self.__logger.debug("Update Factory") - - elif item.WhichOneof("message_of_obj") == "community_message": - if AssistFunction.HaveView(self.__bufferState.self.viewRange, - self.__bufferState.self.x, self.__bufferState.self.y, - item.community_message.x, item.community_message.y, - self.__bufferState.gameMap): - pos = (AssistFunction.GridToCell(item.community_message.x), - AssistFunction.GridToCell(item.community_message.y)) - if pos not in self.__bufferState.mapInfo.communityState: - self.__bufferState.mapInfo.communityState[pos] = item.community_message.hp - self.__logger.debug("New Community") + if self.__playerType == THUAI7.PlayerType.Sweeper: + if item.WhichOneof("message_of_obj") == "sweeper_message": + if item.sweeper_message.team_id != self.__teamID: + if AssistFunction.HaveView( + self.__bufferState.self.viewRange, + self.__bufferState.self.x, + self.__bufferState.self.y, + item.sweeper_message.x, + item.sweeper_message.y, + self.__bufferState.gameMap, + ): + self.__bufferState.enemySweepers.append( + Proto2THUAI7.Protobuf2THUAI7Sweeper(item.sweeper_message) + ) + self.__logger.debug("Load enemy sweeper") else: - self.__bufferState.mapInfo.communityState[pos] = item.community_message.hp - self.__logger.debug("Update Community") - - elif item.WhichOneof("message_of_obj") == "fort_message": - if AssistFunction.HaveView(self.__bufferState.self.viewRange, - self.__bufferState.self.x, self.__bufferState.self.y, - item.fort_message.x, item.fort_message.y, - self.__bufferState.gameMap): - pos = (AssistFunction.GridToCell(item.fort_message.x), - AssistFunction.GridToCell(item.fort_message.y)) - if pos not in self.__bufferState.mapInfo.fortState: - self.__bufferState.mapInfo.fortState[pos] = item.fort_message.hp - self.__logger.debug("New Fort") - else: - self.__bufferState.mapInfo.fortState[pos] = item.fort_message.hp - self.__logger.debug("Update Fort") - - elif item.WhichOneof("message_of_obj") == "wormhole_message": - pos = (AssistFunction.GridToCell(item.wormhole_message.x), - AssistFunction.GridToCell(item.wormhole_message.y)) - self.__bufferState.mapInfo.wormholeState[pos] = item.wormhole_message.hp - self.__logger.debug("Update Wormhole") - - elif item.WhichOneof("message_of_obj") == "home_message": - if AssistFunction.HaveView(self.__bufferState.self.viewRange, - self.__bufferState.self.x, self.__bufferState.self.y, - item.home_message.x, item.home_message.y, - self.__bufferState.gameMap): - pos = (AssistFunction.GridToCell(item.home_message.x), - AssistFunction.GridToCell(item.home_message.y)) - self.__bufferState.mapInfo.homeState[pos] = item.home_message.hp - self.__logger.debug("Update Home") - - elif item.WhichOneof("message_of_obj") == "resource_message": - if AssistFunction.HaveView(self.__bufferState.self.viewRange, - self.__bufferState.self.x, self.__bufferState.self.y, - item.resource_message.x, item.resource_message.y, - self.__bufferState.gameMap): - pos = (AssistFunction.GridToCell(item.resource_message.x), - AssistFunction.GridToCell(item.resource_message.y)) - self.__bufferState.mapInfo.resourceState[pos] = item.resource_message.progress - self.__logger.debug("Update Resource") - - elif item.WhichOneof("message_of_obj") == "news_message": - if item.news_message.to_id == self.__playerID: - if item.news_message.WhichOneof("news") == "text_message": - self.__messageQueue.put((item.news_message.from_id, item.news_message.text_message)) - self.__logger.debug("Add News!") - elif item.news_message.WhichOneof("news") == "binary_message": - self.__messageQueue.put((item.news_message.from_id, item.news_message.binary_message)) - self.__logger.debug("Add News!") - else: - self.__logger.error("Unknown News!") - - # elif item.WhichOneof("message_of_obj")=="bombed_bullet_message": - # if AssistFunction.HaveView( - # self.__bufferState.self.viewRange, - # self.__bufferState.self.x, - # self.__bufferState.self.y, - # item.bombed_bullet_message.x, - # item.bombed_bullet_message.y, - # self.__bufferState.gameMap, - # ): - # self.__bufferState.bombedBullets.append(Proto2THUAI7.Protobuf2THUAI7BombedBullet(item.bombed_bullet_message)) - # self.__logger.debug("Add Bombed Bullet!") - - elif item.WhichOneof("message_of_obj") == "team_message": - if item.team_message.team_id != self.__teamID: - self.__bufferState.teams.append(Proto2THUAI7.Protobuf2THUAI7Team(item.team_message)) - self.__logger.debug("Add Team!") + self.__bufferState.sweepers.append( + Proto2THUAI7.Protobuf2THUAI7Sweeper(item.sweeper_message) + ) + self.__logger.debug("Load sweeper") + + elif item.WhichOneof("message_of_obj") == "bullet_message": + if AssistFunction.HaveView( + self.__bufferState.self.viewRange, + self.__bufferState.self.x, + self.__bufferState.self.y, + item.bullet_message.x, + item.bullet_message.y, + self.__bufferState.gameMap, + ): + self.__bufferState.bullets.append( + Proto2THUAI7.Protobuf2THUAI7Bullet(item.bullet_message) + ) + self.__logger.debug("Load Bullet!") + + elif item.WhichOneof("message_of_obj") == "recyclebank_message": + if item.recyclebank_message.team_id == self.__teamID: + pos = ( + AssistFunction.GridToCell(item.recyclebank_message.x), + AssistFunction.GridToCell(item.recyclebank_message.y), + ) + if pos not in self.__bufferState.mapInfo.recycleBankState: + self.__bufferState.mapInfo.recycleBankState[pos] = ( + item.recyclebank_message.hp + ) + self.__logger.debug("New RecycleBank") + else: + self.__bufferState.mapInfo.recycleBankState[pos] = ( + item.recyclebank_message.hp + ) + self.__logger.debug("Update RecycleBank") + elif AssistFunction.HaveView( + self.__bufferState.self.viewRange, + self.__bufferState.self.x, + self.__bufferState.self.y, + item.recyclebank_message.x, + item.recyclebank_message.y, + self.__bufferState.gameMap, + ): + pos = ( + AssistFunction.GridToCell(item.recyclebank_message.x), + AssistFunction.GridToCell(item.recyclebank_message.y), + ) + if pos not in self.__bufferState.mapInfo.recycleBankState: + self.__bufferState.mapInfo.recycleBankState[pos] = ( + item.recyclebank_message.hp + ) + self.__logger.debug("New RecycleBank") + else: + self.__bufferState.mapInfo.recycleBankState[pos] = ( + item.recyclebank_message.hp + ) + self.__logger.debug("Update RecycleBank") + + elif item.WhichOneof("message_of_obj") == "chargestation_message": + if item.chargestation_message.team_id == self.__teamID: + pos = ( + AssistFunction.GridToCell(item.chargestation_message.x), + AssistFunction.GridToCell(item.chargestation_message.y), + ) + if pos not in self.__bufferState.mapInfo.chargeStationState: + self.__bufferState.mapInfo.chargeStationState[pos] = ( + item.chargestation_message.hp + ) + self.__logger.debug("New ChargeStation") + else: + self.__bufferState.mapInfo.chargeStationState[pos] = ( + item.chargestation_message.hp + ) + self.__logger.debug("Update ChargeStation") + elif AssistFunction.HaveView( + self.__bufferState.self.viewRange, + self.__bufferState.self.x, + self.__bufferState.self.y, + item.chargestation_message.x, + item.chargestation_message.y, + self.__bufferState.gameMap, + ): + pos = ( + AssistFunction.GridToCell(item.chargestation_message.x), + AssistFunction.GridToCell(item.chargestation_message.y), + ) + if pos not in self.__bufferState.mapInfo.chargeStationState: + self.__bufferState.mapInfo.chargeStationState[pos] = ( + item.chargestation_message.hp + ) + self.__logger.debug("New ChargeStation") + else: + self.__bufferState.mapInfo.chargeStationState[pos] = ( + item.chargestation_message.hp + ) + self.__logger.debug("Update ChargeStation") + + elif item.WhichOneof("message_of_obj") == "signaltower_message": + if item.signaltower_message.team_id == self.__teamID: + pos = ( + AssistFunction.GridToCell(item.signaltower_message.x), + AssistFunction.GridToCell(item.signaltower_message.y), + ) + if pos not in self.__bufferState.mapInfo.signalTowerState: + self.__bufferState.mapInfo.signalTowerState[pos] = ( + item.signaltower_message.hp + ) + self.__logger.debug("New SignalTower") + else: + self.__bufferState.mapInfo.signalTowerState[pos] = ( + item.signaltower_message.hp + ) + self.__logger.debug("Update SignalTower") + elif AssistFunction.HaveView( + self.__bufferState.self.viewRange, + self.__bufferState.self.x, + self.__bufferState.self.y, + item.signaltower_message.x, + item.signaltower_message.y, + self.__bufferState.gameMap, + ): + pos = ( + AssistFunction.GridToCell(item.signaltower_message.x), + AssistFunction.GridToCell(item.signaltower_message.y), + ) + if pos not in self.__bufferState.mapInfo.signalTowerState: + self.__bufferState.mapInfo.signalTowerState[pos] = ( + item.signaltower_message.hp + ) + self.__logger.debug("New SignalTower") + else: + self.__bufferState.mapInfo.signalTowerState[pos] = ( + item.signaltower_message.hp + ) + self.__logger.debug("Update SignalTower") + + elif item.WhichOneof("message_of_obj") == "bridge_message": + if AssistFunction.HaveView( + self.__bufferState.self.viewRange, + self.__bufferState.self.x, + self.__bufferState.self.y, + item.bridge_message.x, + item.bridge_message.y, + self.__bufferState.gameMap, + ): + pos = ( + AssistFunction.GridToCell(item.bridge_message.x), + AssistFunction.GridToCell(item.bridge_message.y), + ) + self.__bufferState.mapInfo.bridgeState[pos] = item.bridge_message.hp + self.__logger.debug("Update Bridge") + + elif item.WhichOneof("message_of_obj") == "home_message": + if item.home_message.team_id == self.__teamID: + pos = ( + AssistFunction.GridToCell(item.home_message.x), + AssistFunction.GridToCell(item.home_message.y), + ) + self.__bufferState.mapInfo.homeState[pos] = item.home_message.hp + self.__logger.debug("Update Home") + elif AssistFunction.HaveView( + self.__bufferState.self.viewRange, + self.__bufferState.self.x, + self.__bufferState.self.y, + item.home_message.x, + item.home_message.y, + self.__bufferState.gameMap, + ): + pos = ( + AssistFunction.GridToCell(item.home_message.x), + AssistFunction.GridToCell(item.home_message.y), + ) + self.__bufferState.mapInfo.homeState[pos] = item.home_message.hp + self.__logger.debug("Update Home") + + elif item.WhichOneof("message_of_obj") == "garbage_message": + if AssistFunction.HaveView( + self.__bufferState.self.viewRange, + self.__bufferState.self.x, + self.__bufferState.self.y, + item.garbage_message.x, + item.garbage_message.y, + self.__bufferState.gameMap, + ): + pos = ( + AssistFunction.GridToCell(item.garbage_message.x), + AssistFunction.GridToCell(item.garbage_message.y), + ) + self.__bufferState.mapInfo.garbageState[pos] = ( + item.garbage_message.progress + ) + self.__logger.debug("Update Garbage") + + elif item.WhichOneof("message_of_obj") == "news_message": + if ( + item.news_message.team_id == self.__teamID + and item.news_message.to_id == self.__playerID + ): + if item.news_message.WhichOneof("news") == "text_message": + self.__messageQueue.put( + (item.news_message.from_id, item.news_message.text_message) + ) + self.__logger.debug("Add News!") + elif item.news_message.WhichOneof("news") == "binary_message": + self.__messageQueue.put( + ( + item.news_message.from_id, + item.news_message.binary_message, + ) + ) + self.__logger.debug("Add News!") + else: + self.__logger.error("Unknown News!") + + # elif item.WhichOneof('message_of_obj')=='bombed_bullet_message': + # if AssistFunction.HaveView( + # self.__bufferState.self.viewRange, + # self.__bufferState.self.x, + # self.__bufferState.self.y, + # item.bombed_bullet_message.x, + # item.bombed_bullet_message.y, + # self.__bufferState.gameMap, + # ): + # self.__bufferState.bombedBullets.append(Proto2THUAI7.Protobuf2THUAI7BombedBullet(item.bombed_bullet_message)) + # self.__logger.debug('Add Bombed Bullet!') - else: - self.__logger.error("Unknown message!") + else: + self.__logger.error("Unknown message!") + elif self.__playerType == THUAI7.PlayerType.Team: + + def HaveOverView(targetX: int, targetY: int): + for sweeper in self.__bufferState.sweepers: + if AssistFunction.HaveView( + sweeper.viewRange, sweeper.x, sweeper.y, targetX, targetY + ): + return True + return False + + if item.WhichOneof("message_of_obj") == "sweeper_message": + if item.sweeper_message.team_id != self.__teamID: + if HaveOverView(item.sweeper_message.x, item.sweeper_message.y): + self.__bufferState.enemySweepers.append( + Proto2THUAI7.Protobuf2THUAI7Sweeper(item.sweeper_message) + ) + self.__logger.debug("Load enemy sweeper") + + elif item.WhichOneof("message_of_obj") == "recyclebank_message": + if item.recyclebank_message.team_id == self.__teamID: + pos = ( + AssistFunction.GridToCell(item.recyclebank_message.x), + AssistFunction.GridToCell(item.recyclebank_message.y), + ) + if pos not in self.__bufferState.mapInfo.recycleBankState: + self.__bufferState.mapInfo.recycleBankState[pos] = ( + item.recyclebank_message.hp + ) + self.__logger.debug("New RecycleBank") + else: + self.__bufferState.mapInfo.recycleBankState[pos] = ( + item.recyclebank_message.hp + ) + self.__logger.debug("Update RecycleBank") + elif HaveOverView( + item.recyclebank_message.x, item.recyclebank_message.y + ): + pos = ( + AssistFunction.GridToCell(item.recyclebank_message.x), + AssistFunction.GridToCell(item.recyclebank_message.y), + ) + if pos not in self.__bufferState.mapInfo.recycleBankState: + self.__bufferState.mapInfo.recycleBankState[pos] = ( + item.recyclebank_message.hp + ) + self.__logger.debug("New RecycleBank") + else: + self.__bufferState.mapInfo.recycleBankState[pos] = ( + item.recyclebank_message.hp + ) + self.__logger.debug("Update RecycleBank") + + elif item.WhichOneof("message_of_obj") == "chargestation_message": + if item.chargestation_message.team_id == self.__teamID: + pos = ( + AssistFunction.GridToCell(item.chargestation_message.x), + AssistFunction.GridToCell(item.chargestation_message.y), + ) + if pos not in self.__bufferState.mapInfo.chargeStationState: + self.__bufferState.mapInfo.chargeStationState[pos] = ( + item.chargestation_message.hp + ) + self.__logger.debug("New ChargeStation") + else: + self.__bufferState.mapInfo.chargeStationState[pos] = ( + item.chargestation_message.hp + ) + self.__logger.debug("Update ChargeStation") + elif HaveOverView( + item.chargestation_message.x, item.chargestation_message.y + ): + pos = ( + AssistFunction.GridToCell(item.chargestation_message.x), + AssistFunction.GridToCell(item.chargestation_message.y), + ) + if pos not in self.__bufferState.mapInfo.chargeStationState: + self.__bufferState.mapInfo.chargeStationState[pos] = ( + item.chargestation_message.hp + ) + self.__logger.debug("New ChargeStation") + else: + self.__bufferState.mapInfo.chargeStationState[pos] = ( + item.chargestation_message.hp + ) + self.__logger.debug("Update ChargeStation") + + elif item.WhichOneof("message_of_obj") == "signaltower_message": + if item.signaltower_message.team_id == self.__teamID: + pos = ( + AssistFunction.GridToCell(item.signaltower_message.x), + AssistFunction.GridToCell(item.signaltower_message.y), + ) + if pos not in self.__bufferState.mapInfo.signalTowerState: + self.__bufferState.mapInfo.signalTowerState[pos] = ( + item.signaltower_message.hp + ) + self.__logger.debug("New SignalTower") + else: + self.__bufferState.mapInfo.signalTowerState[pos] = ( + item.signaltower_message.hp + ) + self.__logger.debug("Update SignalTower") + elif HaveOverView( + item.signaltower_message.x, item.signaltower_message.y + ): + pos = ( + AssistFunction.GridToCell(item.signaltower_message.x), + AssistFunction.GridToCell(item.signaltower_message.y), + ) + if pos not in self.__bufferState.mapInfo.signalTowerState: + self.__bufferState.mapInfo.signalTowerState[pos] = ( + item.signaltower_message.hp + ) + self.__logger.debug("New SignalTower") + else: + self.__bufferState.mapInfo.signalTowerState[pos] = ( + item.signaltower_message.hp + ) + self.__logger.debug("Update SignalTower") + + elif item.WhichOneof("message_of_obj") == "bridge_message": + if HaveOverView(item.bridge_message.x, item.bridge_message.y): + pos = ( + AssistFunction.GridToCell(item.bridge_message.x), + AssistFunction.GridToCell(item.bridge_message.y), + ) + self.__bufferState.mapInfo.bridgeState[pos] = item.bridge_message.hp + self.__logger.debug("Update Bridge") + + elif item.WhichOneof("message_of_obj") == "home_message": + if item.home_message.team_id == self.__teamID: + pos = ( + AssistFunction.GridToCell(item.home_message.x), + AssistFunction.GridToCell(item.home_message.y), + ) + self.__bufferState.mapInfo.homeState[pos] = item.home_message.hp + self.__logger.debug("Update Home") + elif HaveOverView(item.home_message.x, item.home_message.y): + pos = ( + AssistFunction.GridToCell(item.home_message.x), + AssistFunction.GridToCell(item.home_message.y), + ) + self.__bufferState.mapInfo.homeState[pos] = item.home_message.hp + self.__logger.debug("Update Home") + + elif item.WhichOneof("message_of_obj") == "garbage_message": + if HaveOverView(item.garbage_message.x, item.garbage_message.y): + pos = ( + AssistFunction.GridToCell(item.garbage_message.x), + AssistFunction.GridToCell(item.garbage_message.y), + ) + self.__bufferState.mapInfo.garbageState[pos] = ( + item.garbage_message.progress + ) + self.__logger.debug("Update Garbage") + + elif item.WhichOneof("message_of_obj") == "news_message": + if ( + item.news_message.team_id == self.__teamID + and item.news_message.to_id == self.__playerID + ): + if item.news_message.WhichOneof("news") == "text_message": + self.__messageQueue.put( + (item.news_message.from_id, item.news_message.text_message) + ) + self.__logger.debug("Add News!") + elif item.news_message.WhichOneof("news") == "binary_message": + self.__messageQueue.put( + ( + item.news_message.from_id, + item.news_message.binary_message, + ) + ) + self.__logger.debug("Add News!") + else: + self.__logger.error("Unknown News!") + + # elif item.WhichOneof('message_of_obj')=='bombed_bullet_message': + # if AssistFunction.HaveView( + # self.__bufferState.self.viewRange, + # self.__bufferState.self.x, + # self.__bufferState.self.y, + # item.bombed_bullet_message.x, + # item.bombed_bullet_message.y, + # self.__bufferState.gameMap, + # ): + # self.__bufferState.bombedBullets.append(Proto2THUAI7.Protobuf2THUAI7BombedBullet(item.bombed_bullet_message)) + # self.__logger.debug('Add Bombed Bullet!') + + else: + self.__logger.error("Unknown message!") def __UnBlockAI(self) -> None: with self.__cvAI: @@ -453,7 +818,10 @@ def __Update(self) -> None: with self.__cvBuffer: self.__cvBuffer.wait_for(lambda: self.__bufferUpdated) with self.__mtxState: - self.__bufferState, self.__currentState = self.__currentState, self.__bufferState + self.__bufferState, self.__currentState = ( + self.__currentState, + self.__bufferState, + ) self.__counterState = self.__counterBuffer self.__bufferUpdated = False self.__logger.info("Update state!") @@ -479,14 +847,18 @@ def Main( "%H:%M:%S", ) # 确保文件存在 - # if not os.path.exists(os.path.dirname(os.path.dirname(os.path.realpath(__file__))) + "/logs"): + # if not os.path.exists(os.path.dirname(os.path.dirname(os.path.realpath(__file__))) + '/logs'): # os.makedirs(os.path.dirname(os.path.dirname( - # os.path.realpath(__file__))) + "/logs") + # os.path.realpath(__file__))) + '/logs') if platform.system().lower() == "windows": - os.system(f'mkdir "{os.path.dirname(os.path.dirname(os.path.realpath(__file__)))}\\logs"') + os.system( + f'mkdir "{os.path.dirname(os.path.dirname(os.path.realpath(__file__)))}\\logs"' + ) else: - os.system(f'mkdir -p "{os.path.dirname(os.path.dirname(os.path.realpath(__file__)))}/logs"') + os.system( + f'mkdir -p "{os.path.dirname(os.path.dirname(os.path.realpath(__file__)))}/logs"' + ) fileHandler = logging.FileHandler( os.path.dirname(os.path.dirname(os.path.realpath(__file__))) @@ -521,11 +893,11 @@ def Main( # 构造timer if not file and not screen: - self.__timer = ShipAPI(self) - # else: - # self.__timer = ShipDebugAPI( - # self, file, screen, warnOnly, self.__playerID - # ) + self.__timer = SweeperAPI(self) + else: + self.__timer = SweeperDebugAPI( + self, file, screen, warnOnly, self.__playerID + ) # 构建AI线程 def AIThread(): @@ -546,9 +918,12 @@ def AIThread(): self.__timer.EndTimer() if self.__TryConnection(): - self.__logger.info("Connect to the server successfully, AI thread will be started.") + self.__logger.info( + "Connect to the server successfully, AI thread will be started." + ) self.__threadAI = threading.Thread(target=AIThread) self.__threadAI.start() + self.__logger.info("Start to Process Message") self.__ProcessMessage() self.__logger.info("Join the AI thread.") self.__threadAI.join() diff --git a/CAPI/python/PyAPI/main.py b/CAPI/python/PyAPI/main.py index 4acb8392..fb3874a3 100644 --- a/CAPI/python/PyAPI/main.py +++ b/CAPI/python/PyAPI/main.py @@ -15,20 +15,20 @@ def PrintWelcomeString() -> None: # Generated by http://www.network-science.de/ascii/ with font "standard" - welcomeString = r''' - ______________ ___ ____ ___ _____ .____________ + welcomeString = r""" + ______________ ___ ____ ___ _____ .____________ \__ ___/ | \| | \/ _ \ | \______ \ | | / ~ \ | / /_\ \| | / / - | | \ Y / | / | \ | / / - |____| \___|_ /|______/\____|__ /___| /____/ - \/ \/ - _________ __ __ __ - / _____// |______ _______ / \ / \_____ _______ + | | \ Y / | / | \ | / / + |____| \___|_ /|______/\____|__ /___| /____/ + \/ \/ + _________ __ __ __ + / _____// |______ _______ / \ / \_____ _______ \_____ \\ __\__ \\_ __ \ \ \/\/ /\__ \\_ __ \ / \| | / __ \| | \/ \ / / __ \| | \/ - /_______ /|__| (____ /__| \__/\ / (____ /__| - \/ \/ \/ \/ - ''' + /_______ /|__| (____ /__| \__/\ / (____ /__| + \/ \/ \/ \/ + """ print(welcomeString) @@ -101,17 +101,17 @@ def THUAI7Main(argv: List[str], AIBuilder: Callable) -> None: screen = args.screen warnOnly = args.warnOnly playerType = THUAI7.PlayerType.NullPlayerType - shipType = THUAI7.SweeperType.NullSweeperType + sweeperType = THUAI7.SweeperType.NullSweeperType if pID == 0: playerType = THUAI7.PlayerType.Team else: playerType = THUAI7.PlayerType.Sweeper - shipType = Setting.SweeperTypes()[pID] + sweeperType = Setting.SweeperTypes()[pID] if platform.system().lower() == "windows": PrintWelcomeString() - logic = Logic(pID, tID, playerType, shipType) + logic = Logic(pID, tID, playerType, sweeperType) logic.Main(AIBuilder, sIP, sPort, file, screen, warnOnly) diff --git a/CAPI/python/PyAPI/structures.py b/CAPI/python/PyAPI/structures.py index 8ee68721..a4b66165 100644 --- a/CAPI/python/PyAPI/structures.py +++ b/CAPI/python/PyAPI/structures.py @@ -39,11 +39,7 @@ class PlayerTeam(Enum): Blue = 2 -playerTeamDict = { - PlayerTeam.NullTeam: 0, - PlayerTeam.Red: 1, - PlayerTeam.Blue: 2 -} +playerTeamDict = {PlayerTeam.NullTeam: 0, PlayerTeam.Red: 1, PlayerTeam.Blue: 2} class PlayerType(Enum): @@ -227,7 +223,7 @@ def __init__(self): self.recycleBankState: Dict[Tuple[int, int], Tuple[int, int]] = {} self.chargeStationState: Dict[Tuple[int, int], Tuple[int, int]] = {} self.signalTowerState: Dict[Tuple[int, int], Tuple[int, int]] = {} - self.HomeState: Dict[Tuple[int, int], Tuple[int, int]] = {} + self.homeState: Dict[Tuple[int, int], Tuple[int, int]] = {} self.bridgeState: Dict[Tuple[int, int], int] = {} self.garbageState: Dict[Tuple[int, int], int] = {} diff --git a/CAPI/python/PyAPI/utils.py b/CAPI/python/PyAPI/utils.py index d63d2d4b..6c7fe525 100644 --- a/CAPI/python/PyAPI/utils.py +++ b/CAPI/python/PyAPI/utils.py @@ -40,12 +40,16 @@ def HaveView( dy = deltaY / divide selfX = float(x) selfY = float(y) - if (newPlace == THUAI7.PlaceType.Grass and myPlace == THUAI7.PlaceType.Grass): + if newPlace == THUAI7.PlaceType.Grass and myPlace == THUAI7.PlaceType.Grass: for _ in range(divide): selfX += dx selfY += dy - if (map[AssistFunction.GridToCell(int(selfX))][AssistFunction.GridToCell(int(selfY))] - != THUAI7.PlaceType.Grass): + if ( + map[AssistFunction.GridToCell(int(selfX))][ + AssistFunction.GridToCell(int(selfY)) + ] + != THUAI7.PlaceType.Grass + ): return False else: return True @@ -53,8 +57,12 @@ def HaveView( for _ in range(divide): selfX += dx selfY += dy - if (map[AssistFunction.GridToCell(int(selfX))][AssistFunction.GridToCell(int(selfY))] - == THUAI7.PlaceType.Wall): + if ( + map[AssistFunction.GridToCell(int(selfX))][ + AssistFunction.GridToCell(int(selfY)) + ] + == THUAI7.PlaceType.Wall + ): return False else: return True @@ -201,7 +209,9 @@ class Proto2THUAI7: } @staticmethod - def Protobuf2THUAI7Sweeper(sweeperMsg: Message2Clients.MessageOfSweeper) -> THUAI7.Sweeper: + def Protobuf2THUAI7Sweeper( + sweeperMsg: Message2Clients.MessageOfSweeper, + ) -> THUAI7.Sweeper: sweeper = THUAI7.Sweeper() sweeper.x = sweeperMsg.x sweeper.y = sweeperMsg.y @@ -407,18 +417,12 @@ def THUAI72ProtobufMoveMsg( playerID: int, teamID: int, time: int, angle: float ) -> Message2Server.MoveMsg: return Message2Server.MoveMsg( - player_id=playerID, - team_id=teamID, - time_in_milliseconds=time, - angle=angle + player_id=playerID, team_id=teamID, time_in_milliseconds=time, angle=angle ) @staticmethod def THUAI72ProtobufIDMsg(playerID: int, teamID: int) -> Message2Server.IDMsg: - return Message2Server.IDMsg( - player_id=playerID, - team_id=teamID - ) + return Message2Server.IDMsg(player_id=playerID, team_id=teamID) @staticmethod def THUAI72ProtobufConstructMsg( @@ -427,27 +431,21 @@ def THUAI72ProtobufConstructMsg( return Message2Server.ConstructMsg( player_id=playerID, team_id=teamID, - construction_type=THUAI72Proto.constructionTypeDict[constructionType] + construction_type=THUAI72Proto.constructionTypeDict[constructionType], ) @staticmethod def THUAI72ProtobufAttackMsg( playerID: int, teamID: int, angle: float ) -> Message2Server.AttackMsg: - return Message2Server.AttackMsg( - player_id=playerID, - team_id=teamID, - angle=angle - ) + return Message2Server.AttackMsg(player_id=playerID, team_id=teamID, angle=angle) @staticmethod def THUAI72ProtobufRecoverMsg( playerID: int, teamID: int, recover: int ) -> Message2Server.RecoverMsg: return Message2Server.RecoverMsg( - player_id=playerID, - team_id=teamID, - recover=recover + player_id=playerID, team_id=teamID, recover=recover ) @staticmethod @@ -459,14 +457,14 @@ def THUAI72ProtobufSendMsg( player_id=playerID, team_id=teamID, binary_message=msg, - to_player_id=toPlayerID + to_player_id=toPlayerID, ) else: return Message2Server.SendMsg( player_id=playerID, team_id=teamID, text_message=msg, - to_player_id=toPlayerID + to_player_id=toPlayerID, ) @staticmethod @@ -476,32 +474,31 @@ def THUAI72ProtobufInstallMsg( return Message2Server.InstallMsg( module_type=THUAI72Proto.moduleTypeDict[moduleType], player_id=playerID, - team_id=teamID + team_id=teamID, ) @staticmethod def THUAI72ProtobufBuildSweeperMsg( - teamID: int, sweeperType: THUAI7.SweeperType, x: int, y: int + teamID: int, sweeperType: THUAI7.SweeperType ) -> Message2Server.BuildSweeperMsg: return Message2Server.BuildSweeperMsg( - team_id=teamID, - x=x, - y=y, - sweeper_type=THUAI72Proto.sweeperTypeDict[sweeperType] + team_id=teamID, sweeper_type=THUAI72Proto.sweeperTypeDict[sweeperType] ) @staticmethod def THUAI72ProtobufPlayerMsg( - playerID: int, teamID: int, shipType: THUAI7.SweeperType + playerID: int, teamID: int, sweeperType: THUAI7.SweeperType ) -> Message2Server.PlayerMsg: return Message2Server.PlayerMsg( player_id=playerID, team_id=teamID, - sweeper_type=THUAI72Proto.sweeperTypeDict[shipType] + sweeper_type=THUAI72Proto.sweeperTypeDict[sweeperType], ) @staticmethod def THUAI72ProtobufRecoverMsg( playerID: int, recover: int, teamID: int ) -> Message2Server.RecoverMsg: - return Message2Server.RecoverMsg(player_id=playerID, team_id=teamID, recover=recover) + return Message2Server.RecoverMsg( + player_id=playerID, team_id=teamID, recover=recover + ) diff --git a/dependency/proto/Message2Clients.proto b/dependency/proto/Message2Clients.proto index fbb6ff75..7e58c8bc 100755 --- a/dependency/proto/Message2Clients.proto +++ b/dependency/proto/Message2Clients.proto @@ -180,10 +180,11 @@ message MessageOfNews oneof news // 一条新闻 { string text_message = 1; - bytes binary_message = 4; + bytes binary_message = 2; } - int64 from_id = 2; - int64 to_id = 3; + int64 from_id = 3; + int64 to_id = 4; + int64 team_id = 5; } // message MsgRes // 用于获取队友发来的消息 // { diff --git a/dependency/proto/Message2Server.proto b/dependency/proto/Message2Server.proto index e79f3c81..0fd246e0 100755 --- a/dependency/proto/Message2Server.proto +++ b/dependency/proto/Message2Server.proto @@ -17,12 +17,6 @@ message PlayerMsg SweeperType sweeper_type = 3; } -message ActivateMsg -{ - int64 player_id = 1; - int64 team_id = 2; - SweeperType sweeper_type = 3; -} message MoveMsg { @@ -74,8 +68,8 @@ message InstallMsg } message BuildSweeperMsg { - int32 x = 1; - int32 y = 2; - SweeperType sweeper_type = 3; - int64 team_id = 4; + SweeperType sweeper_type = 1; + int64 team_id = 2; + int64 player_id = 3; + int32 birthpoint_index = 4; } \ No newline at end of file diff --git a/dependency/proto/Protos.csproj b/dependency/proto/Protos.csproj index 49013373..bef38da7 100755 --- a/dependency/proto/Protos.csproj +++ b/dependency/proto/Protos.csproj @@ -14,7 +14,7 @@ --> - + diff --git a/dependency/proto/Services.proto b/dependency/proto/Services.proto index 8b07b939..0680c364 100755 --- a/dependency/proto/Services.proto +++ b/dependency/proto/Services.proto @@ -12,7 +12,6 @@ service AvailableService rpc GetMap(NullRequest) returns (MessageOfMap); // 游戏过程中玩家执行操作的服务 // 船 - rpc Activate(ActivateMsg) returns (BoolRes); // 激活 rpc Move(MoveMsg) returns (MoveRes); // 移动 rpc Recover(RecoverMsg) returns (BoolRes); // 回复 rpc Produce(IDMsg) returns (BoolRes); // 开采 diff --git a/installer/Data/ConfigFileData.cs b/installer/Data/ConfigFileData.cs new file mode 100644 index 00000000..6059dbd7 --- /dev/null +++ b/installer/Data/ConfigFileData.cs @@ -0,0 +1,370 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json; +using System.Threading.Tasks; + +namespace installer.Data +{ + public enum LanguageOption + { + cpp = 0, python = 1 + } + public record CommandFile + { + public bool Enabled { get; set; } = true; + + public string IP { get; set; } = "127.0.0.1"; + + public string Port { get; set; } = "8888"; + + public string TeamID { get; set; } = "0"; + + public string PlayerID { get; set; } = "0"; + + public string SweeperType { get; set; } = "0"; + + public string PlaybackFile { get; set; } = "CLGG!@#$%^&*()_+"; + + public double PlaybackSpeed { get; set; } = 2.0; + + public LanguageOption Language { get; set; } = LanguageOption.cpp; + + public int LaunchID { get; set; } = 0; + + public bool Launched { get; set; } = false; + } + + public record ConfigDataFile + { + public string Description { get; set; } = "THUAI7-2024"; + public string MD5DataPath { get; set; } = ".\\hash.json"; + public string InstallPath { get; set; } = Path.Combine( + Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), + "THUAI7" + ); + public string Token { get; set; } = string.Empty; + public string UserName { get; set; } = string.Empty; + public string Password { get; set; } = string.Empty; + public bool Remembered { get; set; } = false; + public CommandFile Commands { get; set; } = new CommandFile(); + } + + public class Command + { + public Command(CommandFile? f = null) => file = f ?? new CommandFile(); + public event EventHandler? OnMemoryChanged; + public CommandFile file; + public bool Enabled + { + get => file.Enabled; + set + { + var temp = file.Enabled; + file.Enabled = value; + if (temp != value) + OnMemoryChanged?.Invoke(this, new EventArgs()); + } + } + + + public string IP + { + get => file.IP; + set + { + var temp = file.IP; + file.IP = value; + if (temp != value) + OnMemoryChanged?.Invoke(this, new EventArgs()); + } + } + + public string Port + { + get => file.Port; + set + { + var temp = file.Port; + file.Port = value; + if (temp != value) + OnMemoryChanged?.Invoke(this, new EventArgs()); + } + } + + + public string TeamID + { + get => file.TeamID; + set + { + var temp = file.TeamID; + file.TeamID = value; + if (temp != value) + OnMemoryChanged?.Invoke(this, new EventArgs()); + } + } + + + public string PlayerID + { + get => file.PlayerID; + set + { + var temp = file.PlayerID; + file.PlayerID = value; + if (temp != value) + OnMemoryChanged?.Invoke(this, new EventArgs()); + } + } + + + public string SweeperType + { + get => file.SweeperType; + set + { + var temp = file.SweeperType; + file.SweeperType = value; + if (temp != value) + OnMemoryChanged?.Invoke(this, new EventArgs()); + } + } + + + public string PlaybackFile + { + get => file.PlaybackFile; + set + { + var temp = file.PlaybackFile; + file.PlaybackFile = value; + if (temp != value) + OnMemoryChanged?.Invoke(this, new EventArgs()); + } + } + + + public double PlaybackSpeed + { + get => file.PlaybackSpeed; + set + { + var temp = file.PlaybackSpeed; + file.PlaybackSpeed = value; + if (temp != value) + OnMemoryChanged?.Invoke(this, new EventArgs()); + } + } + + + public LanguageOption Language + { + get => file.Language; + set + { + var temp = file.Language; + file.Language = value; + if (temp != value) + OnMemoryChanged?.Invoke(this, new EventArgs()); + } + } + + public int LaunchID + { + get => file.LaunchID; + set + { + var temp = file.LaunchID; + file.LaunchID = value; + if (temp != value) + OnMemoryChanged?.Invoke(this, new EventArgs()); + } + } + + + public bool Launched + { + get => file.Launched; + set + { + var temp = file.Launched; + file.Launched = value; + if (temp != value) + OnMemoryChanged?.Invoke(this, new EventArgs()); + } + } + + } + + public class ConfigData + { + public ConfigData(string? p = null, bool autoSave = true) + { + path = string.IsNullOrEmpty(p) ? Path.Combine( + Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), + "THUAI7.json") : p; + file = new ConfigDataFile(); + com = new Command(file.Commands); + ReadFile(); + + if (autoSave) + OnMemoryChanged += (_, _) => SaveFile(); + watcher = new FileSystemWatcher(Directory.GetParent(path)?.FullName ?? Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)); + watcher.Filter = "THUAI*.json"; + watcher.NotifyFilter = NotifyFilters.Attributes + | NotifyFilters.CreationTime + | NotifyFilters.DirectoryName + | NotifyFilters.FileName + | NotifyFilters.LastAccess + | NotifyFilters.LastWrite + | NotifyFilters.Security + | NotifyFilters.Size; + watcher.IncludeSubdirectories = false; + watcher.EnableRaisingEvents = true; + watcher.Changed += (_, _) => + { + ReadFile(); + OnFileChanged?.Invoke(this, new EventArgs()); + }; + } + + public void ReadFile() + { + try + { + using (FileStream s = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite)) + using (StreamReader r = new StreamReader(s)) + { + var f = JsonSerializer.Deserialize(r.ReadToEnd()); + if (f is null) + throw new JsonException(); + else file = f; + } + } + catch (Exception) + { + file = new ConfigDataFile(); + } + com = new Command(file.Commands); + com.OnMemoryChanged += (_, _) => OnMemoryChanged?.Invoke(this, new EventArgs()); + } + + public void SaveFile() + { + file.Commands = com.file; + using FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite); + using StreamWriter sw = new StreamWriter(fs); + fs.SetLength(0); + sw.Write(JsonSerializer.Serialize(file)); + sw.Flush(); + } + + public event EventHandler? OnMemoryChanged; + public event EventHandler? OnFileChanged; + + protected string path; + protected ConfigDataFile file; + protected FileSystemWatcher watcher; + protected Command com; + + public string Description + { + get => file.Description; + set + { + var temp = file.Description; + file.Description = value; + if (temp != value) + OnMemoryChanged?.Invoke(this, new EventArgs()); + } + } + + public string MD5DataPath + { + get => file.MD5DataPath; + set + { + var temp = file.MD5DataPath; + file.MD5DataPath = value; + if (temp != value) + OnMemoryChanged?.Invoke(this, new EventArgs()); + } + } + + public string InstallPath + { + get => file.InstallPath; + set + { + var temp = file.InstallPath; + file.InstallPath = value; + if (temp != value) + OnMemoryChanged?.Invoke(this, new EventArgs()); + } + } + + public string Token + { + get => file.Token; + set + { + var temp = file.Token; + file.Token = value; + if (temp != value) + OnMemoryChanged?.Invoke(this, new EventArgs()); + } + } + + public string UserName + { + get => file.UserName; + set + { + var temp = file.UserName; + file.UserName = value; + if (temp != value) + OnMemoryChanged?.Invoke(this, new EventArgs()); + } + } + + public string Password + { + get => file.Password; + set + { + var temp = file.Password; + file.Password = value; + if (temp != value) + OnMemoryChanged?.Invoke(this, new EventArgs()); + } + } + + public bool Remembered + { + get => file.Remembered; + set + { + var temp = file.Remembered; + file.Remembered = value; + if (temp != value) + OnMemoryChanged?.Invoke(this, new EventArgs()); + } + } + + public Command Commands + { + get => com; + set + { + var temp = com; + com = value; + if (temp != value) + OnMemoryChanged?.Invoke(this, new EventArgs()); + com.OnMemoryChanged += (_, _) => OnMemoryChanged?.Invoke(this, new EventArgs()); + } + } + } + +} diff --git a/installer/Data/MD5FileData.cs b/installer/Data/MD5FileData.cs new file mode 100644 index 00000000..c9322a0f --- /dev/null +++ b/installer/Data/MD5FileData.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace installer.Data +{ + public class MD5DataFile + { + public Dictionary Data { get; set; } = new Dictionary(); + public Version Version = new Version(1, 0, 0, 0); + public string Description { get; set; } + = "The Description of the current version."; + public string BugFixed { get; set; } + = "Bugs had been fixed."; + public string BugGenerated { get; set; } + = "New bugs found in the new version."; + } +} diff --git a/installer/Model/Downloader.cs b/installer/Model/Downloader.cs index db9f9f9e..145ade36 100755 --- a/installer/Model/Downloader.cs +++ b/installer/Model/Downloader.cs @@ -8,6 +8,8 @@ using System.Threading.Tasks; using System.IO.Compression; using System.Formats.Tar; +using installer.Data; +using installer.Services; namespace installer.Model { @@ -30,10 +32,11 @@ public class UserInfo public string StartName = "maintest.exe"; // 启动的程序名 public Local_Data Data; // 本地文件管理器 public Tencent_Cos Cloud; // THUAI7 Cos桶 + public Version CurrentVersion { get => Data.CurrentVersion; set => Data.CurrentVersion = value; } public HttpClient Client = new HttpClient(); public EEsast Web; // EEsast服务器 - public Logger Log; // 日志管理器 + public Logger Log; // 日志管理器 public Logger LogError; public enum UpdateStatus { @@ -47,10 +50,14 @@ public enum UpdateStatus public string Password { get => Web.Password; set { Web.Password = value; } } public string UserId { get => Web.ID; } public string UserEmail { get => Web.Email; } - public string CodeRoute { get; set; } = string.Empty; - public string PlayerNum { get; set; } = "nSelect"; - public enum LaunchLanguage { cpp, python }; - public LaunchLanguage Language { get; set; } = LaunchLanguage.cpp; + public Data.Command Commands + { + get => Data.Config.Commands; + set + { + Data.Config.Commands = value; + } + } public enum UsingOS { Win, Linux, OSX }; public UsingOS usingOS { get; set; } public ExceptionStack Exceptions; @@ -76,7 +83,7 @@ public Downloader() if ((Log.LastRecordTime != DateTime.MinValue && DateTime.Now.Month != Log.LastRecordTime.Month) || (LogError.LastRecordTime != DateTime.MinValue && DateTime.Now.Month != LogError.LastRecordTime.Month)) { - string tardir = Path.Combine(Data.InstallPath, "LogArchieved"); + string tardir = Path.Combine(Data.Config.InstallPath, "LogArchieved"); if (!Directory.Exists(tardir)) Directory.CreateDirectory(tardir); string tarPath = Path.Combine(tardir, $"Backup-{Log.LastRecordTime.Year}-{Log.LastRecordTime.Month}.tar"); @@ -108,7 +115,7 @@ public Downloader() LogError = LoggerProvider.FromFile(Path.Combine(Data.LogPath, "Main.error.log")); } Exceptions = new ExceptionStack(LogError, this); - Route = Data.InstallPath; + Route = Data.Config.InstallPath; Cloud = new Tencent_Cos("1319625962", "ap-beijing", "bucket1", LoggerProvider.FromFile(Path.Combine(Data.LogPath, "TencentCos.log")), LoggerProvider.FromFile(Path.Combine(Data.LogPath, "TencentCos.error.log"))); @@ -117,16 +124,10 @@ public Downloader() Web.Token_Changed += SaveToken; LoggerBinding(); - string? temp; - if (Data.Config.TryGetValue("Remembered", out temp)) + if (Data.Config.Remembered) { - if (Convert.ToBoolean(temp)) - { - if (Data.Config.TryGetValue("Username", out temp)) - Username = temp; - if (Data.Config.TryGetValue("Password", out temp)) - Password = temp; - } + Username = Data.Config.UserName; + Password = Data.Config.Password; } Cloud.UpdateSecret(MauiProgram.SecretID, MauiProgram.SecretKey); } @@ -197,7 +198,7 @@ public void UpdateMD5() public void Install(string? path = null) { Data.Installed = false; - Data.InstallPath = path ?? Data.InstallPath; + Data.Config.InstallPath = path ?? Data.Config.InstallPath; UpdateMD5(); if (Status == UpdateStatus.error) return; @@ -215,9 +216,9 @@ public void Install(string? path = null) } }; action = deleteTask; - deleteTask(new DirectoryInfo(Data.InstallPath)); + deleteTask(new DirectoryInfo(Data.Config.InstallPath)); - Data.ResetInstallPath(Data.InstallPath); + Data.ResetInstallPath(Data.Config.InstallPath); Cloud.Log = LoggerProvider.FromFile(Path.Combine(Data.LogPath, "TencentCos.log")); Cloud.LogError = LoggerProvider.FromFile(Path.Combine(Data.LogPath, "TencentCos.error.log")); Cloud.Exceptions = new ExceptionStack(Cloud.LogError, Cloud); @@ -229,11 +230,11 @@ public void Install(string? path = null) Exceptions = new ExceptionStack(LogError, this); LoggerBinding(); - string zp = Path.Combine(Data.InstallPath, "THUAI7.tar.gz"); + string zp = Path.Combine(Data.Config.InstallPath, "THUAI7.tar.gz"); Status = UpdateStatus.downloading; Cloud.DownloadFileAsync(zp, "THUAI7.tar.gz").Wait(); Status = UpdateStatus.unarchieving; - Cloud.ArchieveUnzip(zp, Data.InstallPath); + Cloud.ArchieveUnzip(zp, Data.Config.InstallPath); File.Delete(zp); Status = UpdateStatus.hash_computing; @@ -257,7 +258,7 @@ public void Install(string? path = null) public void ResetInstallPath(string newPath) { newPath = newPath.EndsWith(Path.DirectorySeparatorChar) ? newPath[0..-1] : newPath; - var installPath = Data.InstallPath.EndsWith(Path.DirectorySeparatorChar) ? Data.InstallPath[0..-1] : Data.InstallPath; + var installPath = Data.Config.InstallPath.EndsWith(Path.DirectorySeparatorChar) ? Data.Config.InstallPath[0..-1] : Data.Config.InstallPath; if (newPath != installPath) { Log.Dispose(); LogError.Dispose(); Exceptions.logger.Dispose(); @@ -291,25 +292,76 @@ public bool CheckUpdate() Status = UpdateStatus.hash_computing; Data.ScanDir(); Status = UpdateStatus.success; - return Data.MD5Update.Count != 0; + return Data.MD5Update.Count != 0 || CurrentVersion < Data.FileHashData.Version; } /// /// 更新文件 /// - public void Update() + public int Update() { + int result = 0; if (CheckUpdate()) { + // 处理AI.cpp/AI.py合并问题 + if (CurrentVersion < Data.FileHashData.Version) + { + var c = CurrentVersion; + var v = Data.FileHashData.Version; + Status = UpdateStatus.downloading; + var p = Path.Combine(Data.Config.InstallPath, "Templates"); + var tocpp = Cloud.DownloadFileAsync(Path.Combine(p, $"v{c}.cpp.t"), + $"./Template/v{c}.cpp.t"); + var topy = Cloud.DownloadFileAsync(Path.Combine(p, $"v{c}.py.t"), + $"./Template/v{c}.py.t"); + var tncpp = Cloud.DownloadFileAsync(Path.Combine(p, $"v{v}.cpp.t"), + $"./Template/v{v}.cpp.t"); + var tnpy = Cloud.DownloadFileAsync(Path.Combine(p, $"v{v}.py.t"), + $"./Template/v{v}.py.t"); + Task.WaitAll(tocpp, topy, tncpp, tnpy); + if (Directory.GetFiles(p).Count() == 4) + { + if (Data.LangEnabled[LanguageOption.cpp].Item1) + { + var so = FileService.ReadToEnd(Path.Combine(p, $"v{c}.cpp.t")); + var sn = FileService.ReadToEnd(Path.Combine(p, $"v{v}.cpp.t")); + var sa = FileService.ReadToEnd(Data.LangEnabled[LanguageOption.cpp].Item2); + var s = FileService.MergeUserCode(sa, so, sn); + using (var f = new FileStream(Data.LangEnabled[LanguageOption.cpp].Item2 + ".temp", FileMode.Create)) + using (var w = new StreamWriter(f)) + { + w.Write(s); + w.Flush(); + } + result |= 1; + } + if (Data.LangEnabled[LanguageOption.python].Item1) + { + var so = FileService.ReadToEnd(Path.Combine(p, $"v{c}.py.t")); + var sn = FileService.ReadToEnd(Path.Combine(p, $"v{v}.py.t")); + var sa = FileService.ReadToEnd(Data.LangEnabled[LanguageOption.python].Item2); + var s = FileService.MergeUserCode(sa, so, sn); + using (var f = new FileStream(Data.LangEnabled[LanguageOption.python].Item2 + ".temp", FileMode.Create)) + using (var w = new StreamWriter(f)) + { + w.Write(s); + w.Flush(); + } + result |= 2; + } + } + } + downloadFailed.Clear(); + Status = UpdateStatus.downloading; - Cloud.DownloadQueueAsync(Data.InstallPath, + Cloud.DownloadQueueAsync(Data.Config.InstallPath, from item in Data.MD5Update where item.state != System.Data.DataRowState.Added select item.name, downloadFailed).Wait(); foreach (var item in Data.MD5Update.Where((s) => s.state == System.Data.DataRowState.Added)) { var _file = item.name; var file = _file.StartsWith('.') ? - Path.Combine(Data.InstallPath, _file) : _file; + Path.Combine(Data.Config.InstallPath, _file) : _file; File.Delete(file); } if (downloadFailed.Count == 0) @@ -320,16 +372,17 @@ public void Update() if (Data.MD5Update.Count == 0) { Status = UpdateStatus.success; - return; + return result; } } } else { Status = UpdateStatus.success; - return; + return result; } Status = UpdateStatus.error; + return result; } /// @@ -352,45 +405,21 @@ public async Task Login(string username = "", string password = "") /// public void SaveToken(object? sender, EventArgs args) { - if (Data.Config.ContainsKey("Token")) - Data.Config["Token"] = Web.Token; - else - Data.Config.Add("Token", Web.Token); - Data.SaveConfig(); + Data.Config.Token = Web.Token; } public void RememberUser() { - if (Data.Config.ContainsKey("Username")) - Data.Config["Username"] = Username; - else - Data.Config.Add("Username", Username); - - if (Data.Config.ContainsKey("Password")) - Data.Config["Password"] = Password; - else - Data.Config.Add("Password", Password); - - if (Data.Config.ContainsKey("Remembered")) - Data.Config["Remembered"] = "true"; - else - Data.Config.Add("Remembered", "true"); - - Data.SaveConfig(); + Data.Config.UserName = Username; + Data.Config.Password = Password; + Data.Config.Remembered = true; } public void ForgetUser() { - if (Data.Config.ContainsKey("Remembered")) - Data.Config["Remembered"] = "false"; - - if (Data.Config.ContainsKey("Username")) - Data.Config["Username"] = string.Empty; - - if (Data.Config.ContainsKey("Password")) - Data.Config["Password"] = string.Empty; - - Data.SaveConfig(); + Data.Config.UserName = string.Empty; + Data.Config.Password = string.Empty; + Data.Config.Remembered = false; } /// @@ -399,9 +428,20 @@ public void ForgetUser() /// 对应玩家id public void UploadFiles(int player_id) { - Web.UploadFiles(Client, Path.Combine(Data.InstallPath, Data.UserCodePath), - Language == LaunchLanguage.cpp ? "cpp" : "python", - $"player_{player_id}").Wait(); + string lang; + switch (Commands.Language) + { + case LanguageOption.cpp: + lang = "cpp"; + break; + case LanguageOption.python: + lang = "python"; + break; + default: + lang = "unknown"; + break; + } + Web.UploadFiles(Client, Data.LangEnabled[Commands.Language].Item2, lang, $"player_{player_id}").Wait(); } #endregion } diff --git a/installer/Model/Helper.cs b/installer/Model/Helper.cs deleted file mode 100755 index 84447485..00000000 --- a/installer/Model/Helper.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Security.Cryptography; -using System.Text; -using System.Threading.Tasks; - -namespace installer.Model -{ - internal static class Helper - { - public static string GetFileMd5Hash(string strFileFullPath) - { - FileStream? fst = null; - try - { - fst = new FileStream(strFileFullPath, FileMode.Open, FileAccess.Read); - byte[] data = MD5.Create().ComputeHash(fst); - - StringBuilder sBuilder = new StringBuilder(); - - for (int i = 0; i < data.Length; i++) - { - sBuilder.Append(data[i].ToString("x2")); - } - - fst.Close(); - return sBuilder.ToString().ToLower(); - } - catch (Exception) - { - if (fst != null) - fst.Close(); - if (File.Exists(strFileFullPath)) - return "conflict"; - return ""; - } - finally - { - } - } - - public static string ConvertAbsToRel(string basePath, string fullPath) - { - if (fullPath.StartsWith(basePath)) - { - fullPath = fullPath.Replace(basePath, "."); - } - return fullPath; - } - } -} diff --git a/installer/Model/Local_Data.cs b/installer/Model/Local_Data.cs index 76063de8..a6466050 100755 --- a/installer/Model/Local_Data.cs +++ b/installer/Model/Local_Data.cs @@ -7,59 +7,22 @@ using System.Text.Json; using System.Threading.Tasks; using System.Diagnostics; +using installer.Services; +using installer.Data; + +using Command = installer.Data.Command; namespace installer.Model { - public record VersionID - { - public VersionID(int major, int minor, int build, int revision) - { - (Major, Minor, Build, Revision) = (major, minor, build, revision); - } - public int Major, Minor, Build, Revision; - public static bool operator >(VersionID left, VersionID right) - { - return (left.Major > right.Major) | - (left.Major == right.Major && left.Minor > right.Minor) | - (left.Major == right.Major && left.Minor == right.Minor && left.Build > right.Build) | - (left.Major == right.Major && left.Minor == right.Minor && left.Build == right.Build && left.Revision > right.Revision); - } - public static bool operator <(VersionID left, VersionID right) - { - return (left.Major < right.Major) | - (left.Major == right.Major && left.Minor < right.Minor) | - (left.Major == right.Major && left.Minor == right.Minor && left.Build < right.Build) | - (left.Major == right.Major && left.Minor == right.Minor && left.Build == right.Build && left.Revision < right.Revision); - } - } - public class MD5DataFile - { - public Dictionary Data { get; set; } = new Dictionary(); - public (int, int, int, int) Version = (1, 0, 0, 0); - public string Description { get; set; } - = "The Description of the current version."; - public string BugFixed { get; set; } - = "Bugs had been fixed."; - public string BugGenerated { get; set; } - = "New bugs found in the new version."; - } - public class Local_Data { public string ConfigPath; // 标记路径记录文件THUAI7.json的路径 public string MD5DataPath; // 标记MD5本地缓存文件的路径 - public string UserCodePostfix = "cpp"; // 用户文件后缀(.cpp/.py) - public MD5DataFile FileData = new MD5DataFile(); - public string UserCodePath - { - get => Path.Combine(InstallPath, - $"???{Path.DirectorySeparatorChar}AI{UserCodePostfix}"); - } - public string LogPath { get => Path.Combine(InstallPath, "Logs"); } - public Dictionary Config - { - get; protected set; - } = new Dictionary(); + public MD5DataFile FileHashData = new MD5DataFile(); + public ConfigData Config; + public Version CurrentVersion; + public Dictionary LangEnabled; + public string LogPath { get => Path.Combine(Config.InstallPath, "Logs"); } public ConcurrentDictionary MD5Data { get; protected set; @@ -68,7 +31,6 @@ public ConcurrentDictionary MD5Data { get; set; } // 路径为绝对路径 - public string InstallPath = ""; // 最后一级为THUAI7文件夹所在目录 public bool Installed = false; // 项目是否安装 public bool RememberMe = false; // 是否记录账号密码 public Logger Log; @@ -84,54 +46,50 @@ public Local_Data() "THUAI7.json"); if (File.Exists(ConfigPath)) { - ReadConfig(); - if (Config.ContainsKey("InstallPath") && Directory.Exists(Config["InstallPath"])) + Config = new ConfigData(ConfigPath); + if (Directory.Exists(Config.InstallPath)) { - InstallPath = Config["InstallPath"]; - if (Config.ContainsKey("MD5DataPath")) + if (File.Exists(Config.MD5DataPath)) { - MD5DataPath = Config["MD5DataPath"].StartsWith('.') ? - Path.Combine(InstallPath, Config["MD5DataPath"]) : - Config["MD5DataPath"]; + MD5DataPath = Config.MD5DataPath.StartsWith('.') ? + Path.Combine(Config.InstallPath, Config.MD5DataPath) : + Config.MD5DataPath; if (!File.Exists(MD5DataPath)) SaveMD5Data(); ReadMD5Data(); + CurrentVersion = FileHashData.Version; MD5Update.Clear(); } else { - MD5DataPath = Path.Combine(InstallPath, $".{Path.DirectorySeparatorChar}hash.json"); - Config["MD5DataPath"] = $".{Path.DirectorySeparatorChar}hash.json"; + MD5DataPath = Path.Combine(Config.InstallPath, $".{Path.DirectorySeparatorChar}hash.json"); + Config.MD5DataPath = $".{Path.DirectorySeparatorChar}hash.json"; + CurrentVersion = FileHashData.Version; SaveMD5Data(); - SaveConfig(); } - RememberMe = (Config.ContainsKey("Remembered") && Convert.ToBoolean(Config["Remembered"])); + RememberMe = (Config.Remembered && Convert.ToBoolean(Config.Remembered)); Installed = true; } else { var dir = Directory.CreateDirectory(Path.Combine(AppContext.BaseDirectory, "THUAI7")); - InstallPath = dir.FullName; - Config["InstallPath"] = InstallPath; - MD5DataPath = Path.Combine(InstallPath, $".{Path.DirectorySeparatorChar}hash.json"); - Config["MD5DataPath"] = $".{Path.DirectorySeparatorChar}hash.json"; + Config.InstallPath = dir.FullName; + Config.MD5DataPath = Config.InstallPath; + MD5DataPath = Path.Combine(Config.InstallPath, $".{Path.DirectorySeparatorChar}hash.json"); + Config.MD5DataPath = $".{Path.DirectorySeparatorChar}hash.json"; + CurrentVersion = FileHashData.Version; SaveMD5Data(); - SaveConfig(); } } else { - Config = new Dictionary - { - { "THUAI7", "2024" }, - { "MD5DataPath", $".{Path.DirectorySeparatorChar}hash.json" } - }; + Config = new ConfigData(); var dir = Directory.CreateDirectory(Path.Combine(AppContext.BaseDirectory, "THUAI7")); - InstallPath = dir.FullName; - Config["InstallPath"] = InstallPath; - MD5DataPath = Path.Combine(InstallPath, $".{Path.DirectorySeparatorChar}hash.json"); + Config.InstallPath = dir.FullName; + MD5DataPath = Path.Combine(Config.InstallPath, $".{Path.DirectorySeparatorChar}hash.json"); + CurrentVersion = FileHashData.Version; + Config.MD5DataPath = $".{Path.DirectorySeparatorChar}hash.json"; SaveMD5Data(); - SaveConfig(); } if (!Directory.Exists(LogPath)) Directory.CreateDirectory(LogPath); @@ -146,12 +104,17 @@ public Local_Data() Log = LoggerProvider.FromFile(Path.Combine(LogPath, "LocalData.log")); LogError = LoggerProvider.FromFile(Path.Combine(LogPath, "LocalData.error.log")); Exceptions = new ExceptionStack(LogError, this); + LangEnabled = new Dictionary(); + foreach (var a in typeof(LanguageOption).GetEnumValues()) + { + LangEnabled.Add((LanguageOption)a, (false, string.Empty)); + } } ~Local_Data() { SaveMD5Data(); - SaveConfig(); + Config.SaveFile(); } public void ResetInstallPath(string newPath) @@ -159,25 +122,25 @@ public void ResetInstallPath(string newPath) // 移动已有文件夹至新位置 try { - if (InstallPath != newPath) + if (Config.InstallPath != newPath) { if (!Directory.Exists(newPath)) { Directory.CreateDirectory(newPath); } - Log.LogInfo($"Move work started: {InstallPath} -> {newPath}"); + Log.LogInfo($"Move work started: {Config.InstallPath} -> {newPath}"); Log.Dispose(); LogError.Dispose(); Exceptions.logger.Dispose(); Action action = (dir) => { }; var moveTask = (DirectoryInfo dir) => { foreach (var file in dir.EnumerateFiles()) { - var newName = Path.Combine(newPath, Helper.ConvertAbsToRel(InstallPath, file.FullName)); + var newName = Path.Combine(newPath, FileService.ConvertAbsToRel(Config.InstallPath, file.FullName)); file.MoveTo(newName); } foreach (var sub in dir.EnumerateDirectories()) { - var newName = Path.Combine(newPath, Helper.ConvertAbsToRel(InstallPath, sub.FullName)); + var newName = Path.Combine(newPath, FileService.ConvertAbsToRel(Config.InstallPath, sub.FullName)); if (!Directory.Exists(newName)) { Directory.CreateDirectory(newName); @@ -186,18 +149,13 @@ public void ResetInstallPath(string newPath) } }; action = moveTask; - moveTask(new DirectoryInfo(InstallPath)); - Directory.Delete(InstallPath, true); - InstallPath = newPath; + moveTask(new DirectoryInfo(Config.InstallPath)); + Directory.Delete(Config.InstallPath, true); + Config.InstallPath = newPath; } - if (Config.ContainsKey("InstallPath")) - Config["InstallPath"] = InstallPath; - else - Config.Add("InstallPath", InstallPath); - MD5DataPath = Config["MD5DataPath"].StartsWith('.') ? - Path.Combine(InstallPath, Config["MD5DataPath"]) : - Config["MD5DataPath"]; - SaveConfig(); + MD5DataPath = Config.MD5DataPath.StartsWith('.') ? + Path.Combine(Config.InstallPath, Config.MD5DataPath) : + Config.MD5DataPath; SaveMD5Data(); Installed = true; } @@ -214,60 +172,24 @@ public void ResetInstallPath(string newPath) Log = LoggerProvider.FromFile(Path.Combine(LogPath, "LocalData.log")); LogError = LoggerProvider.FromFile(Path.Combine(LogPath, "LocalData.error.log")); Exceptions = new ExceptionStack(LogError, this); - Log.LogInfo($"Move work finished: {InstallPath} -> {newPath}"); - } - } - - public void ReadConfig() - { - try - { - using (StreamReader r = new StreamReader(ConfigPath)) - { - string json = r.ReadToEnd(); - if (json is null || json == "") - { - json += @"{""THUAI7""" + ":" + @"""2024""}"; - } - Config = JsonSerializer.Deserialize>(json) ?? new Dictionary(); - } - } - catch (Exception e) - { - Exceptions.Push(e); - } - } - - public void SaveConfig() - { - try - { - using FileStream fs = new FileStream(ConfigPath, FileMode.OpenOrCreate, FileAccess.ReadWrite); - using StreamWriter sw = new StreamWriter(fs); - fs.SetLength(0); - sw.Write(JsonSerializer.Serialize(Config)); - sw.Flush(); - } - catch (Exception e) - { - Exceptions.Push(e); + Log.LogInfo($"Move work finished: {Config.InstallPath} -> {newPath}"); } } public void ReadMD5Data() { - FileData = new MD5DataFile(); + FileHashData = new MD5DataFile(); StreamReader r = new StreamReader(MD5DataPath); try { string json = r.ReadToEnd(); if (!string.IsNullOrEmpty(json)) { - FileData = JsonSerializer.Deserialize(json) ?? new MD5DataFile(); + FileHashData = JsonSerializer.Deserialize(json) ?? new MD5DataFile(); } r.Close(); r.Dispose(); } - catch (JsonException e) + catch (JsonException) { // Json反序列化失败,考虑重新创建MD5数据库 r.Close(); r.Dispose(); @@ -279,7 +201,7 @@ public void ReadMD5Data() Exceptions.Push(e); r.Close(); r.Dispose(); } - foreach (var item in FileData.Data) + foreach (var item in FileHashData.Data) { var key = item.Key.Replace('/', Path.DirectorySeparatorChar); MD5Data.AddOrUpdate(key, (k) => @@ -299,14 +221,15 @@ public void SaveMD5Data() { try { + FileHashData.Version = CurrentVersion; using (FileStream fs = new FileStream(MD5DataPath, FileMode.OpenOrCreate, FileAccess.ReadWrite)) using (StreamWriter sw = new StreamWriter(fs)) { fs.SetLength(0); var exp1 = from i in MD5Data select new KeyValuePair(i.Key.Replace(Path.DirectorySeparatorChar, '/'), i.Value); - FileData.Data = exp1.ToDictionary(); - sw.Write(JsonSerializer.Serialize(FileData)); + FileHashData.Data = exp1.ToDictionary(); + sw.Write(JsonSerializer.Serialize(FileHashData)); sw.Flush(); } } @@ -323,7 +246,7 @@ public void ScanDir() if (_file is null) continue; var file = _file.StartsWith('.') ? - Path.Combine(InstallPath, _file) : _file; + Path.Combine(Config.InstallPath, _file) : _file; if (!File.Exists(file) && MD5Data.TryRemove(_file, out _)) { MD5Update.Add((DataRowState.Deleted, _file)); @@ -332,12 +255,12 @@ public void ScanDir() // 层序遍历文件树 Stack stack = new Stack(); List files = new List(); - stack.Push(InstallPath); + stack.Push(Config.InstallPath); while (stack.Count > 0) { string cur = stack.Pop(); files.AddRange(from f in Directory.GetFiles(cur) - where !IsUserFile(f) + where !IsUserFile(f, LangEnabled) select f); foreach (var d in Directory.GetDirectories(cur)) stack.Push(d); @@ -357,8 +280,8 @@ public void ScanDir() if (loopState.IsStopped) break; var file = files[i]; - var relFile = Helper.ConvertAbsToRel(InstallPath, file); - var hash = Helper.GetFileMd5Hash(file); + var relFile = FileService.ConvertAbsToRel(Config.InstallPath, file); + var hash = FileService.GetFileMd5Hash(file); MD5Data.AddOrUpdate(relFile, (k) => { MD5Update.Add((DataRowState.Added, relFile)); @@ -374,7 +297,6 @@ public void ScanDir() SaveMD5Data(); } - public static bool IsUserFile(string filename) { if (filename.Contains("git") || filename.Contains("bin") || filename.Contains("obj")) @@ -392,10 +314,18 @@ public static bool IsUserFile(string filename) return false; } + public static bool IsUserFile(string filename, Dictionary dict) + { + if (filename.Contains("AI.cpp")) + dict[LanguageOption.cpp] = (true, filename); + if (filename.Contains("AI.py")) + dict[LanguageOption.python] = (true, filename); + return IsUserFile(filename); + } public static int CountFile(string folder, string? root = null) { int result = (from f in Directory.EnumerateFiles(folder) - let t = Helper.ConvertAbsToRel(root ?? folder, f) + let t = FileService.ConvertAbsToRel(root ?? folder, f) where !IsUserFile(t) select f).Count(); foreach (var d in Directory.EnumerateDirectories(folder)) diff --git a/installer/Model/Logger.cs b/installer/Model/Logger.cs index 2c87f2e0..23f1bd0e 100644 --- a/installer/Model/Logger.cs +++ b/installer/Model/Logger.cs @@ -283,7 +283,7 @@ public override void Dispose() public class ExceptionStack { public Logger logger; - public ConcurrentStack Exceptions; + protected ConcurrentStack Exceptions; protected object? Source; public event EventHandler? OnFailed; public event EventHandler? OnFailProcessed; diff --git a/installer/Page/LaunchPage.xaml b/installer/Page/LaunchPage.xaml index 21dcf000..8318831a 100644 --- a/installer/Page/LaunchPage.xaml +++ b/installer/Page/LaunchPage.xaml @@ -5,12 +5,106 @@ x:Class="installer.Page.LaunchPage" Title="Launcher"> - + + + + + + + + + + + + + + + + +