| @@ -13,7 +13,6 @@ | |||
| #include <condition_variable> | |||
| #include <queue> | |||
| #include <atomic> | |||
| #include "ConcurrentQueue.hpp" | |||
| class Logic; | |||
| @@ -28,8 +27,6 @@ public: | |||
| bool PickProp(THUAI6::PropType prop, int64_t playerID); | |||
| bool UseProp(THUAI6::PropType prop, int64_t playerID); | |||
| bool UseSkill(int32_t skillID, int64_t playerID); | |||
| std::optional<std::pair<int64_t, std::string>> GetMessage(); | |||
| bool HaveMessage(); | |||
| bool SendMessage(int64_t toID, std::string message, int64_t playerID); | |||
| bool OpenDoor(int64_t playerID); | |||
| bool CloseDoor(int64_t playerID); | |||
| @@ -50,15 +47,10 @@ public: | |||
| protobuf::MessageToClient GetMessage2Client(); | |||
| void AddPlayer(int64_t playerID, THUAI6::PlayerType playerType, THUAI6::StudentType studentType, THUAI6::TrickerType trickerType); | |||
| [[nodiscard]] std::vector<std::vector<THUAI6::PlaceType>> GetMap(int64_t playerID); | |||
| void ReadMessage(int64_t playerID); | |||
| private: | |||
| std::unique_ptr<protobuf::AvailableService::Stub> THUAI6Stub; | |||
| bool haveNewMessage = false; | |||
| protobuf::MessageToClient message2Client; | |||
| ConcurrentQueue<std::pair<int64_t, std::string>> messageQueue; | |||
| std::mutex mtxMessage; | |||
| std::condition_variable cvMessage; | |||
| }; | |||
| @@ -29,6 +29,7 @@ | |||
| #include "structures.h" | |||
| #include "state.h" | |||
| #include "Communication.h" | |||
| #include "ConcurrentQueue.hpp" | |||
| // 封装了通信组件和对AI对象进行操作 | |||
| class Logic : public ILogic | |||
| @@ -63,7 +64,7 @@ private: | |||
| std::condition_variable cvAI; | |||
| // 信息队列 | |||
| std::queue<std::pair<int64_t, std::string>> messageQueue; | |||
| ConcurrentQueue<std::pair<int64_t, std::string>> messageQueue; | |||
| // 存储状态,分别是现在的状态和缓冲区的状态。 | |||
| State state[2]; | |||
| @@ -142,6 +142,9 @@ namespace THUAI6 | |||
| DoorMessage = 7, | |||
| GateMessage = 8, | |||
| ChestMessage = 9, | |||
| MapMessage = 10, | |||
| NewsMessage = 11, | |||
| HiddenGateMessage = 12, | |||
| }; | |||
| // 玩家类 | |||
| @@ -154,13 +157,16 @@ namespace THUAI6 | |||
| int64_t playerID; // 玩家ID | |||
| int64_t guid; // 全局唯一ID | |||
| int16_t radius; // 圆形物体的半径或正方形物体的内切圆半径 | |||
| int32_t score; // 分数 | |||
| double facingDirection; // 朝向 | |||
| int32_t damage; // 攻击伤害 | |||
| std::vector<double> timeUntilSkillAvailable; // 技能冷却时间 | |||
| PlayerType playerType; // 玩家类型 | |||
| std::vector<PropType> props; | |||
| PlaceType place; // 所处格子的类型 | |||
| BulletType bulletType; | |||
| PlayerState playerState; | |||
| }; | |||
| @@ -168,14 +174,21 @@ namespace THUAI6 | |||
| struct Student : public Player | |||
| { | |||
| StudentType studentType; | |||
| int32_t determination; // 剩余毅力(本次Emo之前还能承受的伤害) | |||
| int32_t addiction; | |||
| int32_t determination; // 剩余毅力 | |||
| int32_t addiction; // 沉迷程度 | |||
| int32_t learningSpeed; | |||
| int32_t treatSpeed; | |||
| int32_t treatProgress; | |||
| int32_t rescueProgress; | |||
| double dangerAlert; | |||
| std::vector<StudentBuffType> buff; // buff | |||
| }; | |||
| struct Tricker : public Player | |||
| { | |||
| int32_t damage; | |||
| double trickDesire; | |||
| double classVolume; | |||
| TrickerType trickerType; // 捣蛋鬼类型 | |||
| std::vector<TrickerBuffType> buff; // buff | |||
| }; | |||
| @@ -190,6 +203,7 @@ namespace THUAI6 | |||
| PlayerType team; // 子弹所属队伍 | |||
| PlaceType place; // 所处格子的类型 | |||
| double bombRange; // 炸弹爆炸范围 | |||
| int32_t speed; // 子弹速度 | |||
| }; | |||
| struct BombedBullet | |||
| @@ -221,8 +235,11 @@ namespace THUAI6 | |||
| std::map<std::pair<int32_t, int32_t>, int32_t> gateState; | |||
| std::map<std::pair<int32_t, int32_t>, bool> doorState; | |||
| std::map<std::pair<int32_t, int32_t>, int32_t> doorNumber; | |||
| std::map<std::pair<int32_t, int32_t>, int32_t> chestState; | |||
| std::map<std::pair<int32_t, int32_t>, bool> hiddenGateState; | |||
| }; | |||
| struct GameInfo | |||
| @@ -313,6 +330,9 @@ namespace THUAI6 | |||
| {MessageOfObj::DoorMessage, "DoorMessage"}, | |||
| {MessageOfObj::GateMessage, "GateMessage"}, | |||
| {MessageOfObj::ChestMessage, "ChestMessage"}, | |||
| {MessageOfObj::MapMessage, "MapMessage"}, | |||
| {MessageOfObj::NewsMessage, "NewsMessage"}, | |||
| {MessageOfObj::HiddenGateMessage, "HiddenGateMessage"}, | |||
| }; | |||
| } // namespace THUAI6 | |||
| @@ -167,6 +167,9 @@ namespace Proto2THUAI6 | |||
| {protobuf::MessageOfObj::MessageOfObjCase::kGateMessage, THUAI6::MessageOfObj::GateMessage}, | |||
| {protobuf::MessageOfObj::MessageOfObjCase::kChestMessage, THUAI6::MessageOfObj::ChestMessage}, | |||
| {protobuf::MessageOfObj::MessageOfObjCase::MESSAGE_OF_OBJ_NOT_SET, THUAI6::MessageOfObj::NullMessageOfObj}, | |||
| {protobuf::MessageOfObj::MessageOfObjCase::kMapMessage, THUAI6::MessageOfObj::MapMessage}, | |||
| {protobuf::MessageOfObj::MessageOfObjCase::kNewsMessage, THUAI6::MessageOfObj::NewsMessage}, | |||
| {protobuf::MessageOfObj::MessageOfObjCase::kHiddenGateMessage, THUAI6::MessageOfObj::HiddenGateMessage}, | |||
| }; | |||
| @@ -177,6 +180,11 @@ namespace Proto2THUAI6 | |||
| tricker->x = trickerMsg.x(); | |||
| tricker->y = trickerMsg.y(); | |||
| tricker->speed = trickerMsg.speed(); | |||
| tricker->score = trickerMsg.score(); | |||
| tricker->facingDirection = trickerMsg.facing_direction(); | |||
| tricker->bulletType = bulletTypeDict[trickerMsg.bullet_type()]; | |||
| tricker->trickDesire = trickerMsg.trick_desire(); | |||
| tricker->classVolume = trickerMsg.class_volume(); | |||
| tricker->damage = trickerMsg.damage(); | |||
| for (int i = 0; i < trickerMsg.time_until_skill_available().size(); i++) | |||
| tricker->timeUntilSkillAvailable.push_back(trickerMsg.time_until_skill_available(i)); | |||
| @@ -205,9 +213,16 @@ namespace Proto2THUAI6 | |||
| student->playerID = studentMsg.player_id(); | |||
| student->guid = studentMsg.guid(); | |||
| student->radius = studentMsg.radius(); | |||
| student->score = studentMsg.score(); | |||
| student->facingDirection = studentMsg.facing_direction(); | |||
| student->bulletType = bulletTypeDict[studentMsg.bullet_type()]; | |||
| student->learningSpeed = studentMsg.learning_speed(); | |||
| student->treatSpeed = studentMsg.treat_speed(); | |||
| student->treatProgress = studentMsg.treat_progress(); | |||
| student->rescueProgress = studentMsg.rescue_progress(); | |||
| student->dangerAlert = studentMsg.danger_alert(); | |||
| for (int i = 0; i < studentMsg.time_until_skill_available().size(); i++) | |||
| student->timeUntilSkillAvailable.push_back(studentMsg.time_until_skill_available(i)); | |||
| student->damage = studentMsg.damage(); | |||
| student->playerType = THUAI6::PlayerType::StudentPlayer; | |||
| for (int i = 0; i < studentMsg.prop().size(); i++) | |||
| student->props.push_back(propTypeDict[studentMsg.prop(i)]); | |||
| @@ -262,6 +277,7 @@ namespace Proto2THUAI6 | |||
| bullet->team = playerTypeDict[bulletMsg.team()]; | |||
| bullet->place = placeTypeDict[bulletMsg.place()]; | |||
| bullet->bombRange = bulletMsg.bomb_range(); | |||
| bullet->speed = bulletMsg.speed(); | |||
| return bullet; | |||
| } | |||
| @@ -17,7 +17,7 @@ extern const THUAI6::StudentType studentType = THUAI6::StudentType::StudentType1 | |||
| void AI::play(IStudentAPI& api) | |||
| { | |||
| api.Move(1, 1); | |||
| api.Move(100, 1); | |||
| } | |||
| void AI::play(ITrickerAPI& api) | |||
| @@ -231,32 +231,6 @@ protobuf::MessageToClient Communication::GetMessage2Client() | |||
| return message2Client; | |||
| } | |||
| std::optional<std::pair<int64_t, std::string>> Communication::GetMessage() | |||
| { | |||
| return messageQueue.tryPop(); | |||
| } | |||
| bool Communication::HaveMessage() | |||
| { | |||
| return !messageQueue.empty(); | |||
| } | |||
| void Communication::ReadMessage(int64_t playerID) | |||
| { | |||
| auto tRead = [=]() | |||
| { | |||
| auto request = THUAI62Proto::THUAI62ProtobufID(playerID); | |||
| ClientContext context; | |||
| protobuf::MsgRes messageReceived; | |||
| auto reader = THUAI6Stub->GetMessage(&context, request); | |||
| while (reader->Read(&messageReceived)) | |||
| { | |||
| messageQueue.emplace(messageReceived.from_player_id(), messageReceived.message_received()); | |||
| } | |||
| }; | |||
| std::thread(tRead).detach(); | |||
| } | |||
| void Communication::AddPlayer(int64_t playerID, THUAI6::PlayerType playerType, THUAI6::StudentType studentType, THUAI6::TrickerType trickerType) | |||
| { | |||
| auto tMessage = [=]() | |||
| @@ -276,27 +250,3 @@ void Communication::AddPlayer(int64_t playerID, THUAI6::PlayerType playerType, T | |||
| }; | |||
| std::thread(tMessage).detach(); | |||
| } | |||
| std::vector<std::vector<THUAI6::PlaceType>> Communication::GetMap(int64_t playerID) | |||
| { | |||
| protobuf::MessageOfMap mapResult; | |||
| ClientContext context; | |||
| auto request = THUAI62Proto::THUAI62ProtobufID(playerID); | |||
| auto status = THUAI6Stub->GetMap(&context, request, &mapResult); | |||
| if (status.ok()) | |||
| { | |||
| std::vector<std::vector<THUAI6::PlaceType>> map; | |||
| for (int i = 0; i < mapResult.row_size(); i++) | |||
| { | |||
| std::vector<THUAI6::PlaceType> row; | |||
| for (int j = 0; j < mapResult.row(i).col_size(); j++) | |||
| { | |||
| row.push_back(Proto2THUAI6::placeTypeDict[mapResult.row(i).col(j)]); | |||
| } | |||
| map.push_back(std::move(row)); | |||
| } | |||
| return map; | |||
| } | |||
| else | |||
| return {}; | |||
| } | |||
| @@ -546,7 +546,7 @@ void StudentDebugAPI::PrintStudent() const | |||
| { | |||
| logger->info("******Student Info******"); | |||
| logger->info("playerID={}, GUID={}, x={}, y={}", student->playerID, student->guid, student->x, student->y); | |||
| logger->info("speed={}, view range={}, damage={}, place={}", student->speed, student->viewRange, student->damage, THUAI6::placeTypeDict[student->place]); | |||
| logger->info("speed={}, view range={}, place={}", student->speed, student->viewRange, THUAI6::placeTypeDict[student->place]); | |||
| logger->info("state={}, determination={}, addiction={}", THUAI6::playerStateDict[student->playerState], student->determination, student->addiction); | |||
| std::string skillTime = "skill time="; | |||
| for (const auto& time : student->timeUntilSkillAvailable) | |||
| @@ -570,7 +570,7 @@ void TrickerDebugAPI::PrintStudent() const | |||
| { | |||
| logger->info("******Student Info******"); | |||
| logger->info("playerID={}, GUID={}, x={}, y={}", student->playerID, student->guid, student->x, student->y); | |||
| logger->info("speed={}, view range={}, damage={}, place={}", student->speed, student->viewRange, student->damage, THUAI6::placeTypeDict[student->place]); | |||
| logger->info("speed={}, view range={}, place={}", student->speed, student->viewRange, THUAI6::placeTypeDict[student->place]); | |||
| logger->info("state={}, determination={}, addiction={}", THUAI6::playerStateDict[student->playerState], student->determination, student->addiction); | |||
| std::string skillTime = "skill time="; | |||
| for (const auto& time : student->timeUntilSkillAvailable) | |||
| @@ -661,7 +661,7 @@ void StudentDebugAPI::PrintSelfInfo() const | |||
| auto self = logic.StudentGetSelfInfo(); | |||
| logger->info("******Self Info******"); | |||
| logger->info("playerID={}, GUID={}, x={}, y={}", self->playerID, self->guid, self->x, self->y); | |||
| logger->info("speed={}, view range={}, damage={}, place={}", self->speed, self->viewRange, self->damage, THUAI6::placeTypeDict[self->place]); | |||
| logger->info("speed={}, view range={}, place={}", self->speed, self->viewRange, THUAI6::placeTypeDict[self->place]); | |||
| logger->info("state={}, determination={}, addiction", THUAI6::playerStateDict[self->playerState], self->determination, self->addiction); | |||
| std::string skillTime = "skill time="; | |||
| for (const auto& time : self->timeUntilSkillAvailable) | |||
| @@ -159,13 +159,13 @@ bool Logic::SendMessage(int64_t toID, std::string message) | |||
| bool Logic::HaveMessage() | |||
| { | |||
| logger->debug("Called HaveMessage"); | |||
| return pComm->HaveMessage(); | |||
| return !messageQueue.empty(); | |||
| } | |||
| std::optional<std::pair<int64_t, std::string>> Logic::GetMessage() | |||
| { | |||
| logger->debug("Called GetMessage"); | |||
| return pComm->GetMessage(); | |||
| return messageQueue.tryPop(); | |||
| } | |||
| bool Logic::Graduate() | |||
| @@ -246,9 +246,6 @@ void Logic::ProcessMessage() | |||
| { | |||
| logger->info("Message thread start!"); | |||
| pComm->AddPlayer(playerID, playerType, studentType, trickerType); | |||
| currentState->gameMap = pComm->GetMap(playerID); | |||
| bufferState->gameMap = currentState->gameMap; | |||
| pComm->ReadMessage(playerID); | |||
| while (gameState != THUAI6::GameState::GameEnd) | |||
| { | |||
| auto clientMsg = pComm->GetMessage2Client(); // 在获得新消息之前阻塞 | |||
| @@ -270,6 +267,24 @@ void Logic::ProcessMessage() | |||
| currentState->guids = playerGUIDs; | |||
| bufferState->guids = playerGUIDs; | |||
| // 读取地图 | |||
| for (const auto& item : clientMsg.obj_message()) | |||
| if (Proto2THUAI6::messageOfObjDict[item.message_of_obj_case()] == THUAI6::MessageOfObj::MapMessage) | |||
| { | |||
| auto map = std::vector<std::vector<THUAI6::PlaceType>>(); | |||
| auto mapResult = item.map_message(); | |||
| for (int i = 0; i < item.map_message().row_size(); i++) | |||
| { | |||
| std::vector<THUAI6::PlaceType> row; | |||
| for (int j = 0; j < mapResult.row(i).col_size(); j++) | |||
| { | |||
| row.push_back(Proto2THUAI6::placeTypeDict[mapResult.row(i).col(j)]); | |||
| } | |||
| map.push_back(std::move(row)); | |||
| } | |||
| bufferState->gameMap = std::move(map); | |||
| currentState->gameMap = bufferState->gameMap; | |||
| } | |||
| LoadBuffer(clientMsg); | |||
| AILoop = true; | |||
| @@ -282,6 +297,12 @@ void Logic::ProcessMessage() | |||
| for (const auto& obj : clientMsg.obj_message()) | |||
| if (Proto2THUAI6::messageOfObjDict[obj.message_of_obj_case()] == THUAI6::MessageOfObj::StudentMessage) | |||
| playerGUIDs.push_back(obj.student_message().guid()); | |||
| else if (Proto2THUAI6::messageOfObjDict[obj.message_of_obj_case()] == THUAI6::MessageOfObj::NewsMessage) | |||
| { | |||
| auto news = obj.news_message(); | |||
| if (news.to_id() == playerID) | |||
| messageQueue.emplace(std::make_pair(news.from_id(), news.news())); | |||
| } | |||
| for (const auto& obj : clientMsg.obj_message()) | |||
| if (Proto2THUAI6::messageOfObjDict[obj.message_of_obj_case()] == THUAI6::MessageOfObj::TrickerMessage) | |||
| playerGUIDs.push_back(obj.tricker_message().guid()); | |||
| @@ -334,12 +355,126 @@ void Logic::LoadBuffer(protobuf::MessageToClient& message) | |||
| logger->debug("Add Student!"); | |||
| } | |||
| for (const auto& item : message.obj_message()) | |||
| if (Proto2THUAI6::messageOfObjDict[item.message_of_obj_case()] == THUAI6::MessageOfObj::TrickerMessage) | |||
| if (AssistFunction::HaveView(bufferState->studentSelf->viewRange, bufferState->studentSelf->x, bufferState->studentSelf->y, item.tricker_message().x(), item.tricker_message().y(), bufferState->studentSelf->place, Proto2THUAI6::placeTypeDict[item.tricker_message().place()], bufferState->gameMap)) | |||
| { | |||
| bufferState->trickers.push_back(Proto2THUAI6::Protobuf2THUAI6Tricker(item.tricker_message())); | |||
| logger->debug("Add Tricker!"); | |||
| } | |||
| switch (Proto2THUAI6::messageOfObjDict[item.message_of_obj_case()]) | |||
| { | |||
| case THUAI6::MessageOfObj::PropMessage: | |||
| if (AssistFunction::HaveView(bufferState->studentSelf->viewRange, bufferState->studentSelf->x, bufferState->studentSelf->y, item.prop_message().x(), item.prop_message().y(), bufferState->studentSelf->place, Proto2THUAI6::placeTypeDict[item.prop_message().place()], currentState->gameMap)) | |||
| { | |||
| bufferState->props.push_back(Proto2THUAI6::Protobuf2THUAI6Prop(item.prop_message())); | |||
| logger->debug("Add Prop!"); | |||
| } | |||
| break; | |||
| case THUAI6::MessageOfObj::BulletMessage: | |||
| if (AssistFunction::HaveView(bufferState->studentSelf->viewRange, bufferState->studentSelf->x, bufferState->studentSelf->y, item.prop_message().x(), item.prop_message().y(), bufferState->studentSelf->place, Proto2THUAI6::placeTypeDict[item.prop_message().place()], currentState->gameMap)) | |||
| { | |||
| bufferState->bullets.push_back(Proto2THUAI6::Protobuf2THUAI6Bullet(item.bullet_message())); | |||
| logger->debug("Add Bullet!"); | |||
| } | |||
| break; | |||
| case THUAI6::MessageOfObj::ClassroomMessage: | |||
| { | |||
| if (AssistFunction::HaveView(bufferState->studentSelf->viewRange, bufferState->studentSelf->x, bufferState->studentSelf->y, item.classroom_message().x(), item.classroom_message().y(), bufferState->studentSelf->place, THUAI6::PlaceType::Land, currentState->gameMap)) | |||
| { | |||
| auto pos = std::make_pair(item.classroom_message().x(), item.classroom_message().y()); | |||
| if (bufferState->mapInfo->classRoomState.count(pos) == 0) | |||
| { | |||
| bufferState->mapInfo->classRoomState.emplace(pos, item.classroom_message().progress()); | |||
| logger->debug("Add Classroom!"); | |||
| } | |||
| else | |||
| { | |||
| bufferState->mapInfo->classRoomState[pos] = item.classroom_message().progress(); | |||
| logger->debug("Update Classroom!"); | |||
| } | |||
| } | |||
| break; | |||
| } | |||
| case THUAI6::MessageOfObj::ChestMessage: | |||
| { | |||
| if (AssistFunction::HaveView(bufferState->studentSelf->viewRange, bufferState->studentSelf->x, bufferState->studentSelf->y, item.chest_message().x(), item.chest_message().y(), bufferState->studentSelf->place, THUAI6::PlaceType::Land, currentState->gameMap)) | |||
| { | |||
| auto pos = std::make_pair(item.chest_message().x(), item.chest_message().y()); | |||
| if (bufferState->mapInfo->chestState.count(pos) == 0) | |||
| { | |||
| bufferState->mapInfo->chestState.emplace(pos, item.chest_message().progress()); | |||
| logger->debug("Add Chest!"); | |||
| } | |||
| else | |||
| { | |||
| bufferState->mapInfo->chestState[pos] = item.chest_message().progress(); | |||
| logger->debug("Update Chest!"); | |||
| } | |||
| } | |||
| break; | |||
| } | |||
| case THUAI6::MessageOfObj::DoorMessage: | |||
| { | |||
| if (AssistFunction::HaveView(bufferState->studentSelf->viewRange, bufferState->studentSelf->x, bufferState->studentSelf->y, item.door_message().x(), item.door_message().y(), bufferState->studentSelf->place, THUAI6::PlaceType::Land, currentState->gameMap)) | |||
| { | |||
| auto pos = std::make_pair(item.door_message().x(), item.door_message().y()); | |||
| if (bufferState->mapInfo->doorState.count(pos) == 0) | |||
| { | |||
| bufferState->mapInfo->doorState.emplace(pos, item.door_message().is_open()); | |||
| bufferState->mapInfo->doorNumber.emplace(pos, item.door_message().number()); | |||
| logger->debug("Add Door!"); | |||
| } | |||
| else | |||
| { | |||
| bufferState->mapInfo->doorState[pos] = item.door_message().is_open(); | |||
| bufferState->mapInfo->doorNumber[pos] = item.door_message().number(); | |||
| logger->debug("Update Door!"); | |||
| } | |||
| } | |||
| break; | |||
| } | |||
| case THUAI6::MessageOfObj::HiddenGateMessage: | |||
| { | |||
| if (AssistFunction::HaveView(bufferState->studentSelf->viewRange, bufferState->studentSelf->x, bufferState->studentSelf->y, item.hidden_gate_message().x(), item.hidden_gate_message().y(), bufferState->studentSelf->place, THUAI6::PlaceType::Land, currentState->gameMap)) | |||
| { | |||
| auto pos = std::make_pair(item.hidden_gate_message().x(), item.hidden_gate_message().y()); | |||
| if (bufferState->mapInfo->hiddenGateState.count(pos) == 0) | |||
| { | |||
| bufferState->mapInfo->hiddenGateState.emplace(pos, item.hidden_gate_message().opened()); | |||
| logger->debug("Add HiddenGate!"); | |||
| } | |||
| else | |||
| { | |||
| bufferState->mapInfo->hiddenGateState[pos] = item.hidden_gate_message().opened(); | |||
| logger->debug("Update HiddenGate!"); | |||
| } | |||
| } | |||
| break; | |||
| } | |||
| case THUAI6::MessageOfObj::GateMessage: | |||
| { | |||
| if (!AssistFunction::HaveView(bufferState->studentSelf->viewRange, bufferState->studentSelf->x, bufferState->studentSelf->y, item.gate_message().x(), item.gate_message().y(), bufferState->studentSelf->place, THUAI6::PlaceType::Land, currentState->gameMap)) | |||
| { | |||
| auto pos = std::make_pair(item.gate_message().x(), item.gate_message().y()); | |||
| if (bufferState->mapInfo->gateState.count(pos) == 0) | |||
| { | |||
| bufferState->mapInfo->gateState.emplace(pos, item.gate_message().progress()); | |||
| logger->debug("Add Gate!"); | |||
| } | |||
| else | |||
| { | |||
| bufferState->mapInfo->gateState[pos] = item.gate_message().progress(); | |||
| logger->debug("Update Gate!"); | |||
| } | |||
| } | |||
| break; | |||
| } | |||
| case THUAI6::MessageOfObj::TrickerMessage: | |||
| { | |||
| if (AssistFunction::HaveView(bufferState->studentSelf->viewRange, bufferState->studentSelf->x, bufferState->studentSelf->y, item.tricker_message().x(), item.tricker_message().y(), bufferState->studentSelf->place, Proto2THUAI6::placeTypeDict[item.tricker_message().place()], bufferState->gameMap)) | |||
| { | |||
| bufferState->trickers.push_back(Proto2THUAI6::Protobuf2THUAI6Tricker(item.tricker_message())); | |||
| logger->debug("Add Tricker!"); | |||
| } | |||
| } | |||
| case THUAI6::MessageOfObj::NullMessageOfObj: | |||
| default: | |||
| break; | |||
| } | |||
| } | |||
| else | |||
| { | |||
| @@ -356,92 +491,127 @@ void Logic::LoadBuffer(protobuf::MessageToClient& message) | |||
| } | |||
| } | |||
| for (const auto& item : message.obj_message()) | |||
| if (Proto2THUAI6::messageOfObjDict[item.message_of_obj_case()] == THUAI6::MessageOfObj::StudentMessage) | |||
| if (AssistFunction::HaveView(bufferState->trickerSelf->viewRange, bufferState->trickerSelf->x, bufferState->trickerSelf->y, item.student_message().x(), item.student_message().y(), bufferState->trickerSelf->place, Proto2THUAI6::placeTypeDict[item.student_message().place()], bufferState->gameMap)) | |||
| { | |||
| bufferState->students.push_back(Proto2THUAI6::Protobuf2THUAI6Student(item.student_message())); | |||
| logger->debug("Add Student!"); | |||
| } | |||
| } | |||
| for (const auto& item : message.obj_message()) | |||
| switch (Proto2THUAI6::messageOfObjDict[item.message_of_obj_case()]) | |||
| { | |||
| case THUAI6::MessageOfObj::PropMessage: | |||
| bufferState->props.push_back(Proto2THUAI6::Protobuf2THUAI6Prop(item.prop_message())); | |||
| logger->debug("Add Prop!"); | |||
| break; | |||
| case THUAI6::MessageOfObj::BulletMessage: | |||
| bufferState->bullets.push_back(Proto2THUAI6::Protobuf2THUAI6Bullet(item.bullet_message())); | |||
| logger->debug("Add Bullet!"); | |||
| break; | |||
| case THUAI6::MessageOfObj::BombedBulletMessage: | |||
| bufferState->bombedBullets.push_back(Proto2THUAI6::Protobuf2THUAI6BombedBullet(item.bombed_bullet_message())); | |||
| logger->debug("Add BombedBullet!"); | |||
| break; | |||
| case THUAI6::MessageOfObj::ClassroomMessage: | |||
| { | |||
| auto pos = std::make_pair(item.classroom_message().x(), item.classroom_message().y()); | |||
| if (bufferState->mapInfo->classRoomState.count(pos) == 0) | |||
| switch (Proto2THUAI6::messageOfObjDict[item.message_of_obj_case()]) | |||
| { | |||
| case THUAI6::MessageOfObj::PropMessage: | |||
| if (AssistFunction::HaveView(bufferState->trickerSelf->viewRange, bufferState->trickerSelf->x, bufferState->trickerSelf->y, item.prop_message().x(), item.prop_message().y(), bufferState->trickerSelf->place, Proto2THUAI6::placeTypeDict[item.prop_message().place()], currentState->gameMap)) | |||
| { | |||
| bufferState->mapInfo->classRoomState.emplace(pos, item.classroom_message().progress()); | |||
| logger->debug("Add Classroom!"); | |||
| bufferState->props.push_back(Proto2THUAI6::Protobuf2THUAI6Prop(item.prop_message())); | |||
| logger->debug("Add Prop!"); | |||
| } | |||
| else | |||
| break; | |||
| case THUAI6::MessageOfObj::BulletMessage: | |||
| if (AssistFunction::HaveView(bufferState->trickerSelf->viewRange, bufferState->trickerSelf->x, bufferState->trickerSelf->y, item.prop_message().x(), item.prop_message().y(), bufferState->trickerSelf->place, Proto2THUAI6::placeTypeDict[item.prop_message().place()], currentState->gameMap)) | |||
| { | |||
| bufferState->mapInfo->classRoomState[pos] = item.classroom_message().progress(); | |||
| logger->debug("Update Classroom!"); | |||
| bufferState->bullets.push_back(Proto2THUAI6::Protobuf2THUAI6Bullet(item.bullet_message())); | |||
| logger->debug("Add Bullet!"); | |||
| } | |||
| break; | |||
| } | |||
| case THUAI6::MessageOfObj::ChestMessage: | |||
| { | |||
| auto pos = std::make_pair(item.chest_message().x(), item.chest_message().y()); | |||
| if (bufferState->mapInfo->chestState.count(pos) == 0) | |||
| case THUAI6::MessageOfObj::ClassroomMessage: | |||
| { | |||
| bufferState->mapInfo->chestState.emplace(pos, item.chest_message().progress()); | |||
| logger->debug("Add Chest!"); | |||
| if (AssistFunction::HaveView(bufferState->trickerSelf->viewRange, bufferState->trickerSelf->x, bufferState->trickerSelf->y, item.classroom_message().x(), item.classroom_message().y(), bufferState->trickerSelf->place, THUAI6::PlaceType::Land, currentState->gameMap)) | |||
| { | |||
| auto pos = std::make_pair(item.classroom_message().x(), item.classroom_message().y()); | |||
| if (bufferState->mapInfo->classRoomState.count(pos) == 0) | |||
| { | |||
| bufferState->mapInfo->classRoomState.emplace(pos, item.classroom_message().progress()); | |||
| logger->debug("Add Classroom!"); | |||
| } | |||
| else | |||
| { | |||
| bufferState->mapInfo->classRoomState[pos] = item.classroom_message().progress(); | |||
| logger->debug("Update Classroom!"); | |||
| } | |||
| } | |||
| break; | |||
| } | |||
| else | |||
| case THUAI6::MessageOfObj::ChestMessage: | |||
| { | |||
| bufferState->mapInfo->chestState[pos] = item.chest_message().progress(); | |||
| logger->debug("Update Chest!"); | |||
| if (AssistFunction::HaveView(bufferState->trickerSelf->viewRange, bufferState->trickerSelf->x, bufferState->trickerSelf->y, item.chest_message().x(), item.chest_message().y(), bufferState->trickerSelf->place, THUAI6::PlaceType::Land, currentState->gameMap)) | |||
| { | |||
| auto pos = std::make_pair(item.chest_message().x(), item.chest_message().y()); | |||
| if (bufferState->mapInfo->chestState.count(pos) == 0) | |||
| { | |||
| bufferState->mapInfo->chestState.emplace(pos, item.chest_message().progress()); | |||
| logger->debug("Add Chest!"); | |||
| } | |||
| else | |||
| { | |||
| bufferState->mapInfo->chestState[pos] = item.chest_message().progress(); | |||
| logger->debug("Update Chest!"); | |||
| } | |||
| } | |||
| break; | |||
| } | |||
| break; | |||
| } | |||
| case THUAI6::MessageOfObj::DoorMessage: | |||
| { | |||
| auto pos = std::make_pair(item.door_message().x(), item.door_message().y()); | |||
| if (bufferState->mapInfo->doorState.count(pos) == 0) | |||
| case THUAI6::MessageOfObj::DoorMessage: | |||
| { | |||
| bufferState->mapInfo->doorState.emplace(pos, item.door_message().is_open()); | |||
| logger->debug("Add Door!"); | |||
| if (AssistFunction::HaveView(bufferState->trickerSelf->viewRange, bufferState->trickerSelf->x, bufferState->trickerSelf->y, item.door_message().x(), item.door_message().y(), bufferState->trickerSelf->place, THUAI6::PlaceType::Land, currentState->gameMap)) | |||
| { | |||
| auto pos = std::make_pair(item.door_message().x(), item.door_message().y()); | |||
| if (bufferState->mapInfo->doorState.count(pos) == 0) | |||
| { | |||
| bufferState->mapInfo->doorState.emplace(pos, item.door_message().is_open()); | |||
| bufferState->mapInfo->doorNumber.emplace(pos, item.door_message().number()); | |||
| logger->debug("Add Door!"); | |||
| } | |||
| else | |||
| { | |||
| bufferState->mapInfo->doorState[pos] = item.door_message().is_open(); | |||
| bufferState->mapInfo->doorNumber[pos] = item.door_message().number(); | |||
| logger->debug("Update Door!"); | |||
| } | |||
| } | |||
| break; | |||
| } | |||
| else | |||
| case THUAI6::MessageOfObj::HiddenGateMessage: | |||
| { | |||
| bufferState->mapInfo->doorState[pos] = item.door_message().is_open(); | |||
| logger->debug("Update Door!"); | |||
| if (AssistFunction::HaveView(bufferState->trickerSelf->viewRange, bufferState->trickerSelf->x, bufferState->trickerSelf->y, item.hidden_gate_message().x(), item.hidden_gate_message().y(), bufferState->trickerSelf->place, THUAI6::PlaceType::Land, currentState->gameMap)) | |||
| { | |||
| auto pos = std::make_pair(item.hidden_gate_message().x(), item.hidden_gate_message().y()); | |||
| if (bufferState->mapInfo->hiddenGateState.count(pos) == 0) | |||
| { | |||
| bufferState->mapInfo->hiddenGateState.emplace(pos, item.hidden_gate_message().opened()); | |||
| logger->debug("Add HiddenGate!"); | |||
| } | |||
| else | |||
| { | |||
| bufferState->mapInfo->hiddenGateState[pos] = item.hidden_gate_message().opened(); | |||
| logger->debug("Update HiddenGate!"); | |||
| } | |||
| } | |||
| break; | |||
| } | |||
| break; | |||
| } | |||
| case THUAI6::MessageOfObj::GateMessage: | |||
| { | |||
| auto pos = std::make_pair(item.gate_message().x(), item.gate_message().y()); | |||
| if (bufferState->mapInfo->gateState.count(pos) == 0) | |||
| case THUAI6::MessageOfObj::GateMessage: | |||
| { | |||
| bufferState->mapInfo->gateState.emplace(pos, item.gate_message().progress()); | |||
| logger->debug("Add Gate!"); | |||
| if (!AssistFunction::HaveView(bufferState->trickerSelf->viewRange, bufferState->trickerSelf->x, bufferState->trickerSelf->y, item.gate_message().x(), item.gate_message().y(), bufferState->trickerSelf->place, THUAI6::PlaceType::Land, currentState->gameMap)) | |||
| { | |||
| auto pos = std::make_pair(item.gate_message().x(), item.gate_message().y()); | |||
| if (bufferState->mapInfo->gateState.count(pos) == 0) | |||
| { | |||
| bufferState->mapInfo->gateState.emplace(pos, item.gate_message().progress()); | |||
| logger->debug("Add Gate!"); | |||
| } | |||
| else | |||
| { | |||
| bufferState->mapInfo->gateState[pos] = item.gate_message().progress(); | |||
| logger->debug("Update Gate!"); | |||
| } | |||
| } | |||
| break; | |||
| } | |||
| else | |||
| case THUAI6::MessageOfObj::StudentMessage: | |||
| { | |||
| bufferState->mapInfo->gateState[pos] = item.gate_message().progress(); | |||
| logger->debug("Update Gate!"); | |||
| if (AssistFunction::HaveView(bufferState->trickerSelf->viewRange, bufferState->trickerSelf->x, bufferState->trickerSelf->y, item.student_message().x(), item.student_message().y(), bufferState->trickerSelf->place, Proto2THUAI6::placeTypeDict[item.student_message().place()], bufferState->gameMap)) | |||
| { | |||
| bufferState->students.push_back(Proto2THUAI6::Protobuf2THUAI6Student(item.student_message())); | |||
| logger->debug("Add Student!"); | |||
| } | |||
| } | |||
| case THUAI6::MessageOfObj::NullMessageOfObj: | |||
| default: | |||
| break; | |||
| } | |||
| case THUAI6::MessageOfObj::NullMessageOfObj: | |||
| default: | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| if (asynchronous) | |||
| { | |||
| { | |||
| @@ -522,7 +692,10 @@ void Logic::Main(CreateAIFunc createAI, std::string IP, std::string port, bool f | |||
| fileLogger->set_pattern(pattern); | |||
| printLogger->set_pattern(pattern); | |||
| if (file) | |||
| { | |||
| fileLogger->set_level(spdlog::level::trace); | |||
| spdlog::flush_every(std::chrono::seconds(1)); | |||
| } | |||
| else | |||
| fileLogger->set_level(spdlog::level::off); | |||
| if (print) | |||
| @@ -9,9 +9,9 @@ | |||
| int THUAI6Main(int argc, char** argv, CreateAIFunc AIBuilder) | |||
| { | |||
| int pID = 114514; | |||
| std::string sIP = "114.51.41.91"; | |||
| std::string sPort = "9810"; | |||
| int pID = 0; | |||
| std::string sIP = "183.172.213.88"; | |||
| std::string sPort = "8888"; | |||
| bool file = false; | |||
| bool print = false; | |||
| bool warnOnly = false; | |||
| @@ -19,13 +19,13 @@ int THUAI6Main(int argc, char** argv, CreateAIFunc AIBuilder) | |||
| extern const THUAI6::TrickerType trickerType; | |||
| extern const THUAI6::StudentType studentType; | |||
| // 仅供早期调试使用 | |||
| { | |||
| file = false; | |||
| print = true; | |||
| Logic logic(playerType, pID, trickerType, studentType); | |||
| logic.Main(AIBuilder, sIP, sPort, file, print, warnOnly); | |||
| return 0; | |||
| } | |||
| // { | |||
| // file = false; | |||
| // print = true; | |||
| // Logic logic(playerType, pID, trickerType, studentType); | |||
| // logic.Main(AIBuilder, sIP, sPort, file, print, warnOnly); | |||
| // return 0; | |||
| // } | |||
| // 使用cmdline的正式版本 | |||
| try | |||
| @@ -35,7 +35,7 @@ int THUAI6Main(int argc, char** argv, CreateAIFunc AIBuilder) | |||
| TCLAP::ValueArg<std::string> serverIP("I", "serverIP", "Server`s IP 127.0.0.1 in default", false, "127.0.0.1", "string"); | |||
| cmd.add(serverIP); | |||
| TCLAP::ValueArg<uint16_t> serverPort("P", "serverPort", "Port the server listens to 7777 in default", false, 7777, "USORT"); | |||
| TCLAP::ValueArg<std::string> serverPort("P", "serverPort", "Port the server listens to 7777 in default", false, "7777", "USORT"); | |||
| cmd.add(serverPort); | |||
| std::vector<int> validPlayerIDs{0, 1, 2, 3}; | |||
| @@ -70,6 +70,7 @@ int THUAI6Main(int argc, char** argv, CreateAIFunc AIBuilder) | |||
| std::cerr << "Parsing error: " << e.error() << " for arg " << e.argId() << std::endl; | |||
| return 1; | |||
| } | |||
| std::cout << file << std::endl; | |||
| Logic logic(playerType, pID, trickerType, studentType); | |||
| logic.Main(AIBuilder, sIP, sPort, file, print, warnOnly); | |||
| return 0; | |||
| @@ -13,7 +13,7 @@ | |||
| #error incompatible with your Protocol Buffer headers. Please update | |||
| #error your headers. | |||
| #endif | |||
| #if 3021009 < PROTOBUF_MIN_PROTOC_VERSION | |||
| #if 3021005 < PROTOBUF_MIN_PROTOC_VERSION | |||
| #error This file was generated by an older version of protoc which is | |||
| #error incompatible with your Protocol Buffer headers. Please | |||
| #error regenerate this file with a newer version of protoc. | |||
| @@ -13,7 +13,7 @@ | |||
| #error incompatible with your Protocol Buffer headers. Please update | |||
| #error your headers. | |||
| #endif | |||
| #if 3021009 < PROTOBUF_MIN_PROTOC_VERSION | |||
| #if 3021005 < PROTOBUF_MIN_PROTOC_VERSION | |||
| #error This file was generated by an older version of protoc which is | |||
| #error incompatible with your Protocol Buffer headers. Please | |||
| #error regenerate this file with a newer version of protoc. | |||
| @@ -28,9 +28,9 @@ namespace protobuf | |||
| "/protobuf.AvailableService/Move", | |||
| "/protobuf.AvailableService/PickProp", | |||
| "/protobuf.AvailableService/UseProp", | |||
| "/protobuf.AvailableService/ThrowProp", | |||
| "/protobuf.AvailableService/UseSkill", | |||
| "/protobuf.AvailableService/SendMessage", | |||
| "/protobuf.AvailableService/GetMessage", | |||
| "/protobuf.AvailableService/StartLearning", | |||
| "/protobuf.AvailableService/StartRescueMate", | |||
| "/protobuf.AvailableService/StartTreatMate", | |||
| @@ -42,7 +42,6 @@ namespace protobuf | |||
| "/protobuf.AvailableService/StartOpenGate", | |||
| "/protobuf.AvailableService/StartOpenChest", | |||
| "/protobuf.AvailableService/EndAllAction", | |||
| "/protobuf.AvailableService/GetMap", | |||
| }; | |||
| std::unique_ptr<AvailableService::Stub> AvailableService::NewStub(const std::shared_ptr<::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options) | |||
| @@ -59,9 +58,9 @@ namespace protobuf | |||
| rpcmethod_Move_(AvailableService_method_names[2], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel), | |||
| rpcmethod_PickProp_(AvailableService_method_names[3], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel), | |||
| rpcmethod_UseProp_(AvailableService_method_names[4], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel), | |||
| rpcmethod_UseSkill_(AvailableService_method_names[5], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel), | |||
| rpcmethod_SendMessage_(AvailableService_method_names[6], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel), | |||
| rpcmethod_GetMessage_(AvailableService_method_names[7], options.suffix_for_stats(), ::grpc::internal::RpcMethod::SERVER_STREAMING, channel), | |||
| rpcmethod_ThrowProp_(AvailableService_method_names[5], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel), | |||
| rpcmethod_UseSkill_(AvailableService_method_names[6], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel), | |||
| rpcmethod_SendMessage_(AvailableService_method_names[7], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel), | |||
| rpcmethod_StartLearning_(AvailableService_method_names[8], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel), | |||
| rpcmethod_StartRescueMate_(AvailableService_method_names[9], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel), | |||
| rpcmethod_StartTreatMate_(AvailableService_method_names[10], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel), | |||
| @@ -72,8 +71,7 @@ namespace protobuf | |||
| rpcmethod_SkipWindow_(AvailableService_method_names[15], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel), | |||
| rpcmethod_StartOpenGate_(AvailableService_method_names[16], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel), | |||
| rpcmethod_StartOpenChest_(AvailableService_method_names[17], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel), | |||
| rpcmethod_EndAllAction_(AvailableService_method_names[18], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel), | |||
| rpcmethod_GetMap_(AvailableService_method_names[19], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel) | |||
| rpcmethod_EndAllAction_(AvailableService_method_names[18], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel) | |||
| { | |||
| } | |||
| @@ -209,6 +207,34 @@ namespace protobuf | |||
| return result; | |||
| } | |||
| ::grpc::Status AvailableService::Stub::ThrowProp(::grpc::ClientContext* context, const ::protobuf::PropMsg& request, ::protobuf::BoolRes* response) | |||
| { | |||
| return ::grpc::internal::BlockingUnaryCall<::protobuf::PropMsg, ::protobuf::BoolRes, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), rpcmethod_ThrowProp_, context, request, response); | |||
| } | |||
| void AvailableService::Stub::async::ThrowProp(::grpc::ClientContext* context, const ::protobuf::PropMsg* request, ::protobuf::BoolRes* response, std::function<void(::grpc::Status)> f) | |||
| { | |||
| ::grpc::internal::CallbackUnaryCall<::protobuf::PropMsg, ::protobuf::BoolRes, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_ThrowProp_, context, request, response, std::move(f)); | |||
| } | |||
| void AvailableService::Stub::async::ThrowProp(::grpc::ClientContext* context, const ::protobuf::PropMsg* request, ::protobuf::BoolRes* response, ::grpc::ClientUnaryReactor* reactor) | |||
| { | |||
| ::grpc::internal::ClientCallbackUnaryFactory::Create<::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_ThrowProp_, context, request, response, reactor); | |||
| } | |||
| ::grpc::ClientAsyncResponseReader<::protobuf::BoolRes>* AvailableService::Stub::PrepareAsyncThrowPropRaw(::grpc::ClientContext* context, const ::protobuf::PropMsg& request, ::grpc::CompletionQueue* cq) | |||
| { | |||
| return ::grpc::internal::ClientAsyncResponseReaderHelper::Create<::protobuf::BoolRes, ::protobuf::PropMsg, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), cq, rpcmethod_ThrowProp_, context, request); | |||
| } | |||
| ::grpc::ClientAsyncResponseReader<::protobuf::BoolRes>* AvailableService::Stub::AsyncThrowPropRaw(::grpc::ClientContext* context, const ::protobuf::PropMsg& request, ::grpc::CompletionQueue* cq) | |||
| { | |||
| auto* result = | |||
| this->PrepareAsyncThrowPropRaw(context, request, cq); | |||
| result->StartCall(); | |||
| return result; | |||
| } | |||
| ::grpc::Status AvailableService::Stub::UseSkill(::grpc::ClientContext* context, const ::protobuf::SkillMsg& request, ::protobuf::BoolRes* response) | |||
| { | |||
| return ::grpc::internal::BlockingUnaryCall<::protobuf::SkillMsg, ::protobuf::BoolRes, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), rpcmethod_UseSkill_, context, request, response); | |||
| @@ -265,26 +291,6 @@ namespace protobuf | |||
| return result; | |||
| } | |||
| ::grpc::ClientReader<::protobuf::MsgRes>* AvailableService::Stub::GetMessageRaw(::grpc::ClientContext* context, const ::protobuf::IDMsg& request) | |||
| { | |||
| return ::grpc::internal::ClientReaderFactory<::protobuf::MsgRes>::Create(channel_.get(), rpcmethod_GetMessage_, context, request); | |||
| } | |||
| void AvailableService::Stub::async::GetMessage(::grpc::ClientContext* context, const ::protobuf::IDMsg* request, ::grpc::ClientReadReactor<::protobuf::MsgRes>* reactor) | |||
| { | |||
| ::grpc::internal::ClientCallbackReaderFactory<::protobuf::MsgRes>::Create(stub_->channel_.get(), stub_->rpcmethod_GetMessage_, context, request, reactor); | |||
| } | |||
| ::grpc::ClientAsyncReader<::protobuf::MsgRes>* AvailableService::Stub::AsyncGetMessageRaw(::grpc::ClientContext* context, const ::protobuf::IDMsg& request, ::grpc::CompletionQueue* cq, void* tag) | |||
| { | |||
| return ::grpc::internal::ClientAsyncReaderFactory<::protobuf::MsgRes>::Create(channel_.get(), cq, rpcmethod_GetMessage_, context, request, true, tag); | |||
| } | |||
| ::grpc::ClientAsyncReader<::protobuf::MsgRes>* AvailableService::Stub::PrepareAsyncGetMessageRaw(::grpc::ClientContext* context, const ::protobuf::IDMsg& request, ::grpc::CompletionQueue* cq) | |||
| { | |||
| return ::grpc::internal::ClientAsyncReaderFactory<::protobuf::MsgRes>::Create(channel_.get(), cq, rpcmethod_GetMessage_, context, request, false, nullptr); | |||
| } | |||
| ::grpc::Status AvailableService::Stub::StartLearning(::grpc::ClientContext* context, const ::protobuf::IDMsg& request, ::protobuf::BoolRes* response) | |||
| { | |||
| return ::grpc::internal::BlockingUnaryCall<::protobuf::IDMsg, ::protobuf::BoolRes, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), rpcmethod_StartLearning_, context, request, response); | |||
| @@ -593,34 +599,6 @@ namespace protobuf | |||
| return result; | |||
| } | |||
| ::grpc::Status AvailableService::Stub::GetMap(::grpc::ClientContext* context, const ::protobuf::IDMsg& request, ::protobuf::MessageOfMap* response) | |||
| { | |||
| return ::grpc::internal::BlockingUnaryCall<::protobuf::IDMsg, ::protobuf::MessageOfMap, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), rpcmethod_GetMap_, context, request, response); | |||
| } | |||
| void AvailableService::Stub::async::GetMap(::grpc::ClientContext* context, const ::protobuf::IDMsg* request, ::protobuf::MessageOfMap* response, std::function<void(::grpc::Status)> f) | |||
| { | |||
| ::grpc::internal::CallbackUnaryCall<::protobuf::IDMsg, ::protobuf::MessageOfMap, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_GetMap_, context, request, response, std::move(f)); | |||
| } | |||
| void AvailableService::Stub::async::GetMap(::grpc::ClientContext* context, const ::protobuf::IDMsg* request, ::protobuf::MessageOfMap* response, ::grpc::ClientUnaryReactor* reactor) | |||
| { | |||
| ::grpc::internal::ClientCallbackUnaryFactory::Create<::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_GetMap_, context, request, response, reactor); | |||
| } | |||
| ::grpc::ClientAsyncResponseReader<::protobuf::MessageOfMap>* AvailableService::Stub::PrepareAsyncGetMapRaw(::grpc::ClientContext* context, const ::protobuf::IDMsg& request, ::grpc::CompletionQueue* cq) | |||
| { | |||
| return ::grpc::internal::ClientAsyncResponseReaderHelper::Create<::protobuf::MessageOfMap, ::protobuf::IDMsg, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), cq, rpcmethod_GetMap_, context, request); | |||
| } | |||
| ::grpc::ClientAsyncResponseReader<::protobuf::MessageOfMap>* AvailableService::Stub::AsyncGetMapRaw(::grpc::ClientContext* context, const ::protobuf::IDMsg& request, ::grpc::CompletionQueue* cq) | |||
| { | |||
| auto* result = | |||
| this->PrepareAsyncGetMapRaw(context, request, cq); | |||
| result->StartCall(); | |||
| return result; | |||
| } | |||
| AvailableService::Service::Service() | |||
| { | |||
| AddMethod(new ::grpc::internal::RpcServiceMethod( | |||
| @@ -696,13 +674,13 @@ namespace protobuf | |||
| AddMethod(new ::grpc::internal::RpcServiceMethod( | |||
| AvailableService_method_names[5], | |||
| ::grpc::internal::RpcMethod::NORMAL_RPC, | |||
| new ::grpc::internal::RpcMethodHandler<AvailableService::Service, ::protobuf::SkillMsg, ::protobuf::BoolRes, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( | |||
| new ::grpc::internal::RpcMethodHandler<AvailableService::Service, ::protobuf::PropMsg, ::protobuf::BoolRes, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( | |||
| [](AvailableService::Service* service, | |||
| ::grpc::ServerContext* ctx, | |||
| const ::protobuf::SkillMsg* req, | |||
| const ::protobuf::PropMsg* req, | |||
| ::protobuf::BoolRes* resp) | |||
| { | |||
| return service->UseSkill(ctx, req, resp); | |||
| return service->ThrowProp(ctx, req, resp); | |||
| }, | |||
| this | |||
| ) | |||
| @@ -710,27 +688,27 @@ namespace protobuf | |||
| AddMethod(new ::grpc::internal::RpcServiceMethod( | |||
| AvailableService_method_names[6], | |||
| ::grpc::internal::RpcMethod::NORMAL_RPC, | |||
| new ::grpc::internal::RpcMethodHandler<AvailableService::Service, ::protobuf::SendMsg, ::protobuf::BoolRes, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( | |||
| new ::grpc::internal::RpcMethodHandler<AvailableService::Service, ::protobuf::SkillMsg, ::protobuf::BoolRes, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( | |||
| [](AvailableService::Service* service, | |||
| ::grpc::ServerContext* ctx, | |||
| const ::protobuf::SendMsg* req, | |||
| const ::protobuf::SkillMsg* req, | |||
| ::protobuf::BoolRes* resp) | |||
| { | |||
| return service->SendMessage(ctx, req, resp); | |||
| return service->UseSkill(ctx, req, resp); | |||
| }, | |||
| this | |||
| ) | |||
| )); | |||
| AddMethod(new ::grpc::internal::RpcServiceMethod( | |||
| AvailableService_method_names[7], | |||
| ::grpc::internal::RpcMethod::SERVER_STREAMING, | |||
| new ::grpc::internal::ServerStreamingHandler<AvailableService::Service, ::protobuf::IDMsg, ::protobuf::MsgRes>( | |||
| ::grpc::internal::RpcMethod::NORMAL_RPC, | |||
| new ::grpc::internal::RpcMethodHandler<AvailableService::Service, ::protobuf::SendMsg, ::protobuf::BoolRes, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( | |||
| [](AvailableService::Service* service, | |||
| ::grpc::ServerContext* ctx, | |||
| const ::protobuf::IDMsg* req, | |||
| ::grpc::ServerWriter<::protobuf::MsgRes>* writer) | |||
| const ::protobuf::SendMsg* req, | |||
| ::protobuf::BoolRes* resp) | |||
| { | |||
| return service->GetMessage(ctx, req, writer); | |||
| return service->SendMessage(ctx, req, resp); | |||
| }, | |||
| this | |||
| ) | |||
| @@ -889,20 +867,6 @@ namespace protobuf | |||
| this | |||
| ) | |||
| )); | |||
| AddMethod(new ::grpc::internal::RpcServiceMethod( | |||
| AvailableService_method_names[19], | |||
| ::grpc::internal::RpcMethod::NORMAL_RPC, | |||
| new ::grpc::internal::RpcMethodHandler<AvailableService::Service, ::protobuf::IDMsg, ::protobuf::MessageOfMap, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( | |||
| [](AvailableService::Service* service, | |||
| ::grpc::ServerContext* ctx, | |||
| const ::protobuf::IDMsg* req, | |||
| ::protobuf::MessageOfMap* resp) | |||
| { | |||
| return service->GetMap(ctx, req, resp); | |||
| }, | |||
| this | |||
| ) | |||
| )); | |||
| } | |||
| AvailableService::Service::~Service() | |||
| @@ -949,7 +913,7 @@ namespace protobuf | |||
| return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); | |||
| } | |||
| ::grpc::Status AvailableService::Service::UseSkill(::grpc::ServerContext* context, const ::protobuf::SkillMsg* request, ::protobuf::BoolRes* response) | |||
| ::grpc::Status AvailableService::Service::ThrowProp(::grpc::ServerContext* context, const ::protobuf::PropMsg* request, ::protobuf::BoolRes* response) | |||
| { | |||
| (void)context; | |||
| (void)request; | |||
| @@ -957,7 +921,7 @@ namespace protobuf | |||
| return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); | |||
| } | |||
| ::grpc::Status AvailableService::Service::SendMessage(::grpc::ServerContext* context, const ::protobuf::SendMsg* request, ::protobuf::BoolRes* response) | |||
| ::grpc::Status AvailableService::Service::UseSkill(::grpc::ServerContext* context, const ::protobuf::SkillMsg* request, ::protobuf::BoolRes* response) | |||
| { | |||
| (void)context; | |||
| (void)request; | |||
| @@ -965,11 +929,11 @@ namespace protobuf | |||
| return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); | |||
| } | |||
| ::grpc::Status AvailableService::Service::GetMessage(::grpc::ServerContext* context, const ::protobuf::IDMsg* request, ::grpc::ServerWriter<::protobuf::MsgRes>* writer) | |||
| ::grpc::Status AvailableService::Service::SendMessage(::grpc::ServerContext* context, const ::protobuf::SendMsg* request, ::protobuf::BoolRes* response) | |||
| { | |||
| (void)context; | |||
| (void)request; | |||
| (void)writer; | |||
| (void)response; | |||
| return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); | |||
| } | |||
| @@ -1061,12 +1025,4 @@ namespace protobuf | |||
| return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); | |||
| } | |||
| ::grpc::Status AvailableService::Service::GetMap(::grpc::ServerContext* context, const ::protobuf::IDMsg* request, ::protobuf::MessageOfMap* response) | |||
| { | |||
| (void)context; | |||
| (void)request; | |||
| (void)response; | |||
| return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); | |||
| } | |||
| } // namespace protobuf | |||
| @@ -31,18 +31,18 @@ static constexpr ::_pb::Message* const* file_default_instances = nullptr; | |||
| const char descriptor_table_protodef_Services_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = | |||
| "\n\016Services.proto\022\010protobuf\032\025Message2Clie" | |||
| "nts.proto\032\024Message2Server.proto2\233\010\n\020Avai" | |||
| "nts.proto\032\024Message2Server.proto2\350\007\n\020Avai" | |||
| "lableService\0223\n\rTryConnection\022\017.protobuf" | |||
| ".IDMsg\032\021.protobuf.BoolRes\022=\n\tAddPlayer\022\023" | |||
| ".protobuf.PlayerMsg\032\031.protobuf.MessageTo" | |||
| "Client0\001\022,\n\004Move\022\021.protobuf.MoveMsg\032\021.pr" | |||
| "otobuf.MoveRes\0220\n\010PickProp\022\021.protobuf.Pr" | |||
| "opMsg\032\021.protobuf.BoolRes\022/\n\007UseProp\022\021.pr" | |||
| "otobuf.PropMsg\032\021.protobuf.BoolRes\0221\n\010Use" | |||
| "Skill\022\022.protobuf.SkillMsg\032\021.protobuf.Boo" | |||
| "lRes\0223\n\013SendMessage\022\021.protobuf.SendMsg\032\021" | |||
| ".protobuf.BoolRes\0221\n\nGetMessage\022\017.protob" | |||
| "uf.IDMsg\032\020.protobuf.MsgRes0\001\0223\n\rStartLea" | |||
| "otobuf.PropMsg\032\021.protobuf.BoolRes\0221\n\tThr" | |||
| "owProp\022\021.protobuf.PropMsg\032\021.protobuf.Boo" | |||
| "lRes\0221\n\010UseSkill\022\022.protobuf.SkillMsg\032\021.p" | |||
| "rotobuf.BoolRes\0223\n\013SendMessage\022\021.protobu" | |||
| "f.SendMsg\032\021.protobuf.BoolRes\0223\n\rStartLea" | |||
| "rning\022\017.protobuf.IDMsg\032\021.protobuf.BoolRe" | |||
| "s\0225\n\017StartRescueMate\022\017.protobuf.IDMsg\032\021." | |||
| "protobuf.BoolRes\0224\n\016StartTreatMate\022\017.pro" | |||
| @@ -56,9 +56,8 @@ const char descriptor_table_protodef_Services_2eproto[] PROTOBUF_SECTION_VARIABL | |||
| "tartOpenGate\022\017.protobuf.IDMsg\032\021.protobuf" | |||
| ".BoolRes\0224\n\016StartOpenChest\022\017.protobuf.ID" | |||
| "Msg\032\021.protobuf.BoolRes\0222\n\014EndAllAction\022\017" | |||
| ".protobuf.IDMsg\032\021.protobuf.BoolRes\0221\n\006Ge" | |||
| "tMap\022\017.protobuf.IDMsg\032\026.protobuf.Message" | |||
| "OfMapb\006proto3"; | |||
| ".protobuf.IDMsg\032\021.protobuf.BoolResb\006prot" | |||
| "o3"; | |||
| static const ::_pbi::DescriptorTable* const descriptor_table_Services_2eproto_deps[2] = { | |||
| &::descriptor_table_Message2Clients_2eproto, | |||
| &::descriptor_table_Message2Server_2eproto, | |||
| @@ -67,7 +66,7 @@ static ::_pbi::once_flag descriptor_table_Services_2eproto_once; | |||
| const ::_pbi::DescriptorTable descriptor_table_Services_2eproto = { | |||
| false, | |||
| false, | |||
| 1133, | |||
| 1082, | |||
| descriptor_table_protodef_Services_2eproto, | |||
| "Services.proto", | |||
| &descriptor_table_Services_2eproto_once, | |||
| @@ -13,7 +13,7 @@ | |||
| #error incompatible with your Protocol Buffer headers. Please update | |||
| #error your headers. | |||
| #endif | |||
| #if 3021009 < PROTOBUF_MIN_PROTOC_VERSION | |||
| #if 3021005 < PROTOBUF_MIN_PROTOC_VERSION | |||
| #error This file was generated by an older version of protoc which is | |||
| #error incompatible with your Protocol Buffer headers. Please | |||
| #error regenerate this file with a newer version of protoc. | |||
| @@ -16,14 +16,12 @@ message MessageOfStudent | |||
| repeated PropType prop = 8; | |||
| PlayerState player_state = 9; | |||
| int64 guid = 10; | |||
| PlayerState state = 11; | |||
| BulletType bullet_type = 12; | |||
| int32 learning_speed = 13; // 修理电机的速度 | |||
| int32 treat_speed = 14; // 治疗的速度 | |||
| int64 player_id = 15; | |||
| int32 view_range = 16; // 视野距离 | |||
| int32 radius = 17; // 半径 | |||
| // int32 damage = 18; | |||
| double danger_alert = 19; // 危险警报,在捣蛋鬼靠近时会有预警 | |||
| int32 score = 20; | |||
| int32 treat_progress = 21; // 治疗进度 | |||
| @@ -38,13 +36,11 @@ message MessageOfTricker | |||
| int32 x = 1; | |||
| int32 y = 2; | |||
| int32 speed = 3; | |||
| int32 damage = 4; // 对学生造成的伤害 | |||
| repeated double time_until_skill_available = 5; | |||
| PlaceType place = 6; | |||
| repeated PropType prop = 7; | |||
| TrickerType tricker_type = 8; | |||
| int64 guid = 9; | |||
| // bool movable = 10; // 是否进入了攻击后摇 | |||
| int32 score = 10; | |||
| int64 player_id = 11; | |||
| int32 view_range = 12; // 视野距离 | |||
| @@ -169,6 +165,7 @@ message MessageOfObj | |||
| MessageOfChest chest_message = 9; | |||
| MessageOfHiddenGate hidden_gate_message = 10; | |||
| MessageOfNews news_message = 11; | |||
| MessageOfMap map_message = 12; | |||
| } | |||
| } | |||
| @@ -6,7 +6,7 @@ enum BulletType | |||
| { | |||
| NULL_BULLET_TYPE = 0; | |||
| FLYING_KNIFE = 1; | |||
| COMMON_ATTACK_OF_GHOST = 2; | |||
| COMMON_ATTACK_OF_TRICKER = 2; | |||
| FAST_BULLET = 3; | |||
| ORDINARY_BULLET = 4; | |||
| ATOM_BOMB = 5; | |||
| @@ -108,7 +108,7 @@ enum StudentType | |||
| enum TrickerType | |||
| { | |||
| NULL_TRICKER_TYPE = 0; | |||
| TRICKERTYPE1 = 1; | |||
| ASSASSIN = 1; | |||
| TRICKERTYPE2 = 2; | |||
| TRICKERTYPE3 = 3; | |||
| TRICKERTYPE4 = 4; | |||
| @@ -1,35 +0,0 @@ | |||
| <Project Sdk="Microsoft.NET.Sdk"> | |||
| <PropertyGroup> | |||
| <TargetFramework>net6.0</TargetFramework> | |||
| <ImplicitUsings>enable</ImplicitUsings> | |||
| <Nullable>enable</Nullable> | |||
| </PropertyGroup> | |||
| <ItemGroup> | |||
| <None Remove="Message2Clients.proto" /> | |||
| <None Remove="Message2Server.proto" /> | |||
| <None Remove="MessageType.proto" /> | |||
| <None Remove="Services.proto" /> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <Protobuf Include="Message2Clients.proto" /> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <PackageReference Include="Google.Protobuf" Version="3.22.1" /> | |||
| <PackageReference Include="Grpc.Core" Version="2.46.6" /> | |||
| <PackageReference Include="Grpc.Tools" Version="2.52.0"> | |||
| <PrivateAssets>all</PrivateAssets> | |||
| <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | |||
| </PackageReference> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <Protobuf Include="Message2Server.proto" /> | |||
| <Protobuf Include="MessageType.proto" /> | |||
| <Protobuf Include="Services.proto" /> | |||
| </ItemGroup> | |||
| </Project> | |||
| @@ -30,5 +30,4 @@ service AvailableService | |||
| rpc StartOpenGate (IDMsg) returns (BoolRes); // 开闸门 | |||
| rpc StartOpenChest (IDMsg) returns (BoolRes); | |||
| rpc EndAllAction (IDMsg) returns (BoolRes); // 结束所有动作 | |||
| rpc GetMap (IDMsg) returns (MessageOfMap); // 游戏开始时候获取地图 | |||
| } | |||
| @@ -12,13 +12,15 @@ | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <PackageReference Include="FrameRateTask" Version="1.2.0" /> | |||
| <PackageReference Include="Google.Protobuf" Version="3.22.1" /> | |||
| <PackageReference Include="Grpc" Version="2.46.6" /> | |||
| <PackageReference Include="Grpc.Core" Version="2.46.6" /> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <ProjectReference Include="..\..\dependency\proto\Proto.csproj" /> | |||
| <ProjectReference Include="..\..\dependency\proto\Protos.csproj" /> | |||
| <ProjectReference Include="..\..\playback\Playback\Playback.csproj" /> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| @@ -5,7 +5,9 @@ VisualStudioVersion = 17.1.32328.378 | |||
| MinimumVisualStudioVersion = 10.0.40219.1 | |||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Client", "Client.csproj", "{5AD8481D-90EF-410C-BD48-355DB97EEAB3}" | |||
| EndProject | |||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Proto", "..\..\dependency\proto\Proto.csproj", "{E445B0DD-D0DF-4413-AE47-1748392843F7}" | |||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Playback", "..\..\playback\Playback\Playback.csproj", "{662FDB27-FBF3-4D2D-BDA4-B4BF4D35B866}" | |||
| EndProject | |||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Protos", "..\..\dependency\proto\Protos.csproj", "{A0F72D3B-9A82-48EB-90AF-B3770151AD83}" | |||
| EndProject | |||
| Global | |||
| GlobalSection(SolutionConfigurationPlatforms) = preSolution | |||
| @@ -17,10 +19,14 @@ Global | |||
| {5AD8481D-90EF-410C-BD48-355DB97EEAB3}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
| {5AD8481D-90EF-410C-BD48-355DB97EEAB3}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
| {5AD8481D-90EF-410C-BD48-355DB97EEAB3}.Release|Any CPU.Build.0 = Release|Any CPU | |||
| {E445B0DD-D0DF-4413-AE47-1748392843F7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||
| {E445B0DD-D0DF-4413-AE47-1748392843F7}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
| {E445B0DD-D0DF-4413-AE47-1748392843F7}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
| {E445B0DD-D0DF-4413-AE47-1748392843F7}.Release|Any CPU.Build.0 = Release|Any CPU | |||
| {662FDB27-FBF3-4D2D-BDA4-B4BF4D35B866}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||
| {662FDB27-FBF3-4D2D-BDA4-B4BF4D35B866}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
| {662FDB27-FBF3-4D2D-BDA4-B4BF4D35B866}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
| {662FDB27-FBF3-4D2D-BDA4-B4BF4D35B866}.Release|Any CPU.Build.0 = Release|Any CPU | |||
| {A0F72D3B-9A82-48EB-90AF-B3770151AD83}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||
| {A0F72D3B-9A82-48EB-90AF-B3770151AD83}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
| {A0F72D3B-9A82-48EB-90AF-B3770151AD83}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
| {A0F72D3B-9A82-48EB-90AF-B3770151AD83}.Release|Any CPU.Build.0 = Release|Any CPU | |||
| EndGlobalSection | |||
| GlobalSection(SolutionProperties) = preSolution | |||
| HideSolutionNode = FALSE | |||
| @@ -16,14 +16,13 @@ using System.Diagnostics; | |||
| using System.Windows.Threading; | |||
| using Grpc.Core; | |||
| using Protobuf; | |||
| using Playback; | |||
| // 目前MainWindow还未复现的功能: | |||
| // 部分errordisplayer | |||
| // private void ReactToCommandline(), | |||
| // private void Playback(string fileName, double pbSpeed = 2.0) | |||
| // 交互:private void ClickToSetMode(object sender, RoutedEventArgs e) | |||
| // private void Bonus() | |||
| namespace Client | |||
| @@ -59,11 +58,11 @@ namespace Client | |||
| listOfDoor = new List<MessageOfDoor>(); | |||
| listOfGate = new List<MessageOfGate>(); | |||
| WindowStartupLocation = WindowStartupLocation.CenterScreen; | |||
| comInfo[0] = "127.0.0.1"; | |||
| comInfo[0] = "183.172.213.88"; | |||
| comInfo[1] = "8888"; | |||
| comInfo[2] = "0"; | |||
| comInfo[3] = "1"; | |||
| comInfo[2] = "4"; | |||
| comInfo[3] = "2"; | |||
| comInfo[4] = "1"; | |||
| ConnectToServer(comInfo); | |||
| OnReceive(); | |||
| //DrawMap(); | |||
| @@ -91,7 +90,50 @@ namespace Client | |||
| } | |||
| } | |||
| // 连接Server,comInfo[]的格式:0-ip 1- port 2-playerID 3-human/TrickerType | |||
| // 获得地图信息,未更新数值 | |||
| private void GetMap(MessageOfMap obj) | |||
| { | |||
| int[,] map = new int[50, 50]; | |||
| try | |||
| { | |||
| for (int i = 0; i < 50; i++) | |||
| { | |||
| for (int j = 0; j < 50; j++) | |||
| { | |||
| map[i, j] = Convert.ToInt32(obj.Row[i].Col[j]) + 4;//与proto一致 | |||
| } | |||
| } | |||
| } | |||
| catch | |||
| { | |||
| mapFlag = false; | |||
| } | |||
| finally | |||
| { | |||
| defaultMap = map; | |||
| mapFlag = true; | |||
| } | |||
| } | |||
| //private void Playback(string fileName, double pbSpeed = 2.0) | |||
| //{ | |||
| // var pbClient = new PlaybackClient(fileName, pbSpeed); | |||
| // int[,]? map; | |||
| // if ((map = pbClient.ReadDataFromFile(dataDict, drawPicLock)) != null) | |||
| // { | |||
| // isClientStocked = false; | |||
| // isPlaybackMode = true; | |||
| // defaultMap = map; | |||
| // mapFlag = true; | |||
| // } | |||
| // else | |||
| // { | |||
| // MessageBox.Show("Failed to read the playback file!"); | |||
| // isClientStocked = true; | |||
| // } | |||
| //} | |||
| // 连接Server,comInfo[]的格式:0-ip 1- port 2-playerID 3-human/TrickerType 4-occupation | |||
| private void ConnectToServer(string[] comInfo) | |||
| { | |||
| if (!isPlaybackMode) | |||
| @@ -115,6 +157,7 @@ namespace Client | |||
| 1 => PlayerType.StudentPlayer, | |||
| 2 => PlayerType.TrickerPlayer, | |||
| }; | |||
| playerMsg.PlayerType=playerType; | |||
| if (Convert.ToInt64(comInfo[3]) == 1) | |||
| { | |||
| humanOrButcher = true; | |||
| @@ -196,30 +239,6 @@ namespace Client | |||
| UpperLayerOfMap.Children.Add(icon); | |||
| } | |||
| // 获得地图信息,未更新数值 | |||
| private void GetMap(MessageOfMap obj) | |||
| { | |||
| int[,] map = new int[50, 50]; | |||
| try | |||
| { | |||
| for (int i = 0; i < 50; i++) | |||
| { | |||
| for (int j = 0; j < 50; j++) | |||
| { | |||
| map[i, j] = Convert.ToInt32(obj.Row[i].Col[j])+4;//与proto一致 | |||
| } | |||
| } | |||
| } | |||
| catch | |||
| { | |||
| mapFlag = false; | |||
| } | |||
| finally | |||
| { | |||
| defaultMap = map; | |||
| mapFlag = true; | |||
| } | |||
| } | |||
| private void ZoomMap() | |||
| { | |||
| for (int i = 0; i < 50; i++) | |||
| @@ -381,11 +400,11 @@ namespace Client | |||
| case MessageOfObj.MessageOfObjOneofCase.GateMessage: | |||
| listOfGate.Add(obj.GateMessage); | |||
| break; | |||
| case MessageOfObj.MessageOfObjOneofCase.MapMessage: | |||
| GetMap(obj.MapMessage); | |||
| break; | |||
| } | |||
| } | |||
| IDMsg idMsg = new IDMsg(); | |||
| idMsg.PlayerId = playerID; | |||
| GetMap(client.GetMap(idMsg)); | |||
| listOfAll.Add(content.AllMessage); | |||
| break; | |||
| case GameState.GameRunning: | |||
| @@ -660,7 +679,7 @@ namespace Client | |||
| HorizontalAlignment = HorizontalAlignment.Left, | |||
| VerticalAlignment = VerticalAlignment.Top, | |||
| Margin = new Thickness(data.Y * unitWidth / 1000.0 - unitWidth / 2, data.X * unitHeight / 1000.0 - unitHeight / 2, 0, 0), | |||
| Fill = Brushes.Black, | |||
| Fill = Brushes.Chocolate, | |||
| }; | |||
| UpperLayerOfMap.Children.Add(icon); | |||
| } | |||
| @@ -0,0 +1,254 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using System.Text; | |||
| using System.Threading.Tasks; | |||
| using Protobuf; | |||
| using Playback; | |||
| using System.Threading; | |||
| using Timothy.FrameRateTask; | |||
| namespace Client | |||
| { | |||
| public class PlaybackClient | |||
| { | |||
| private readonly string fileName; | |||
| private readonly double playbackSpeed; | |||
| private readonly int frameTimeInMilliseconds; | |||
| public MessageReader? Reader; | |||
| public PlaybackClient(string fileName, double playbackSpeed = 1.0, int frameTimeInMilliseconds = 50) | |||
| { | |||
| this.fileName = fileName; | |||
| this.playbackSpeed = playbackSpeed; | |||
| this.frameTimeInMilliseconds = frameTimeInMilliseconds; | |||
| //this.sema = new SemaphoreSlim(1, 1); | |||
| try | |||
| { | |||
| Reader = new MessageReader(this.fileName); | |||
| } | |||
| catch (Exception ex) | |||
| { | |||
| Reader = null; | |||
| Console.WriteLine(ex.Message); | |||
| return; | |||
| } | |||
| } | |||
| public int[,]? ReadDataFromFile(List<MessageOfProp> listOfProp,List<MessageOfStudent> listOfHuman,List<MessageOfTricker> listOfButcher,List<MessageOfBullet> listOfBullet, | |||
| List<MessageOfBombedBullet> listOfBombedBullet,List<MessageOfAll> listOfAll,List<MessageOfChest> listOfChest,List<MessageOfClassroom> listOfClassroom, | |||
| List<MessageOfDoor> listOfDoor, List<MessageOfGate> listOfGate, object dataLock) | |||
| { | |||
| if (Reader == null) | |||
| return null; | |||
| //Sema.Wait(); | |||
| bool endFile = false; | |||
| bool mapFlag = false; // 是否获取了地图 | |||
| int[,] map = new int[50, 50]; | |||
| long frame = (long)(this.frameTimeInMilliseconds / this.playbackSpeed); | |||
| var mapCollecter = new MessageReader(this.fileName); | |||
| while (!mapFlag) | |||
| { | |||
| var msg = mapCollecter.ReadOne(); | |||
| if (msg == null) | |||
| throw new Exception("Map messgae is not in the playback file!"); | |||
| foreach (var obj in msg.ObjMessage) | |||
| { | |||
| if (obj.MessageOfObjCase == MessageOfObj.MessageOfObjOneofCase.MapMessage) | |||
| { | |||
| try | |||
| { | |||
| for (int i = 0; i < 50; i++) | |||
| { | |||
| for (int j = 0; j < 50; j++) | |||
| { | |||
| map[i, j] = Convert.ToInt32(obj.MapMessage.Row[i].Col[j]) + 4; | |||
| } | |||
| } | |||
| } | |||
| catch | |||
| { | |||
| mapFlag = false; | |||
| } | |||
| finally | |||
| { | |||
| mapFlag = true; | |||
| } | |||
| break; | |||
| } | |||
| } | |||
| }; | |||
| new Thread(() => | |||
| { | |||
| new FrameRateTaskExecutor<int> | |||
| ( | |||
| () => !endFile, | |||
| () => | |||
| { | |||
| var content = Reader.ReadOne(); | |||
| if (content == null) | |||
| endFile = true; | |||
| else | |||
| { | |||
| lock (dataLock) | |||
| { | |||
| listOfHuman.Clear(); | |||
| listOfButcher.Clear(); | |||
| listOfProp.Clear(); | |||
| listOfBombedBullet.Clear(); | |||
| listOfBullet.Clear(); | |||
| listOfAll.Clear(); | |||
| listOfChest.Clear(); | |||
| listOfClassroom.Clear(); | |||
| listOfDoor.Clear(); | |||
| listOfGate.Clear(); | |||
| switch (content.GameState) | |||
| { | |||
| case GameState.GameStart: | |||
| foreach (var obj in content.ObjMessage) | |||
| { | |||
| switch (obj.MessageOfObjCase) | |||
| { | |||
| case MessageOfObj.MessageOfObjOneofCase.StudentMessage: | |||
| //if (humanOrButcher && obj.StudentMessage.PlayerId == playerID) | |||
| //{ | |||
| // human = obj.StudentMessage; | |||
| //} | |||
| listOfHuman.Add(obj.StudentMessage); | |||
| break; | |||
| case MessageOfObj.MessageOfObjOneofCase.TrickerMessage: | |||
| //if (!humanOrButcher && obj.TrickerMessage.PlayerId == playerID) | |||
| //{ | |||
| // butcher = obj.TrickerMessage; | |||
| //} | |||
| listOfButcher.Add(obj.TrickerMessage); | |||
| break; | |||
| case MessageOfObj.MessageOfObjOneofCase.PropMessage: | |||
| listOfProp.Add(obj.PropMessage); | |||
| break; | |||
| case MessageOfObj.MessageOfObjOneofCase.BombedBulletMessage: | |||
| listOfBombedBullet.Add(obj.BombedBulletMessage); | |||
| break; | |||
| case MessageOfObj.MessageOfObjOneofCase.BulletMessage: | |||
| listOfBullet.Add(obj.BulletMessage); | |||
| break; | |||
| case MessageOfObj.MessageOfObjOneofCase.ChestMessage: | |||
| listOfChest.Add(obj.ChestMessage); | |||
| break; | |||
| case MessageOfObj.MessageOfObjOneofCase.ClassroomMessage: | |||
| listOfClassroom.Add(obj.ClassroomMessage); | |||
| break; | |||
| case MessageOfObj.MessageOfObjOneofCase.DoorMessage: | |||
| listOfDoor.Add(obj.DoorMessage); | |||
| break; | |||
| case MessageOfObj.MessageOfObjOneofCase.GateMessage: | |||
| listOfGate.Add(obj.GateMessage); | |||
| break; | |||
| case MessageOfObj.MessageOfObjOneofCase.MapMessage: | |||
| break; | |||
| } | |||
| } | |||
| listOfAll.Add(content.AllMessage); | |||
| break; | |||
| case GameState.GameRunning: | |||
| foreach (var obj in content.ObjMessage) | |||
| { | |||
| switch (obj.MessageOfObjCase) | |||
| { | |||
| case MessageOfObj.MessageOfObjOneofCase.StudentMessage: | |||
| //if (humanOrButcher && obj.StudentMessage.PlayerId == playerID) | |||
| //{ | |||
| // human = obj.StudentMessage; | |||
| //} | |||
| listOfHuman.Add(obj.StudentMessage); | |||
| break; | |||
| case MessageOfObj.MessageOfObjOneofCase.TrickerMessage: | |||
| //if (!humanOrButcher && obj.TrickerMessage.PlayerId == playerID) | |||
| //{ | |||
| // butcher = obj.TrickerMessage; | |||
| //} | |||
| listOfButcher.Add(obj.TrickerMessage); | |||
| break; | |||
| case MessageOfObj.MessageOfObjOneofCase.PropMessage: | |||
| listOfProp.Add(obj.PropMessage); | |||
| break; | |||
| case MessageOfObj.MessageOfObjOneofCase.BombedBulletMessage: | |||
| listOfBombedBullet.Add(obj.BombedBulletMessage); | |||
| break; | |||
| case MessageOfObj.MessageOfObjOneofCase.BulletMessage: | |||
| listOfBullet.Add(obj.BulletMessage); | |||
| break; | |||
| case MessageOfObj.MessageOfObjOneofCase.ChestMessage: | |||
| listOfChest.Add(obj.ChestMessage); | |||
| break; | |||
| case MessageOfObj.MessageOfObjOneofCase.ClassroomMessage: | |||
| listOfClassroom.Add(obj.ClassroomMessage); | |||
| break; | |||
| case MessageOfObj.MessageOfObjOneofCase.DoorMessage: | |||
| listOfDoor.Add(obj.DoorMessage); | |||
| break; | |||
| case MessageOfObj.MessageOfObjOneofCase.GateMessage: | |||
| listOfGate.Add(obj.GateMessage); | |||
| break; | |||
| } | |||
| } | |||
| listOfAll.Add(content.AllMessage); | |||
| break; | |||
| case GameState.GameEnd: | |||
| foreach (var obj in content.ObjMessage) | |||
| { | |||
| switch (obj.MessageOfObjCase) | |||
| { | |||
| case MessageOfObj.MessageOfObjOneofCase.StudentMessage: | |||
| listOfHuman.Add(obj.StudentMessage); | |||
| break; | |||
| case MessageOfObj.MessageOfObjOneofCase.TrickerMessage: | |||
| listOfButcher.Add(obj.TrickerMessage); | |||
| break; | |||
| case MessageOfObj.MessageOfObjOneofCase.PropMessage: | |||
| listOfProp.Add(obj.PropMessage); | |||
| break; | |||
| case MessageOfObj.MessageOfObjOneofCase.BombedBulletMessage: | |||
| listOfBombedBullet.Add(obj.BombedBulletMessage); | |||
| break; | |||
| case MessageOfObj.MessageOfObjOneofCase.BulletMessage: | |||
| listOfBullet.Add(obj.BulletMessage); | |||
| break; | |||
| case MessageOfObj.MessageOfObjOneofCase.ChestMessage: | |||
| listOfChest.Add(obj.ChestMessage); | |||
| break; | |||
| case MessageOfObj.MessageOfObjOneofCase.ClassroomMessage: | |||
| listOfClassroom.Add(obj.ClassroomMessage); | |||
| break; | |||
| case MessageOfObj.MessageOfObjOneofCase.DoorMessage: | |||
| listOfDoor.Add(obj.DoorMessage); | |||
| break; | |||
| case MessageOfObj.MessageOfObjOneofCase.GateMessage: | |||
| listOfGate.Add(obj.GateMessage); | |||
| break; | |||
| } | |||
| } | |||
| listOfAll.Add(content.AllMessage); | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| }, | |||
| frame, | |||
| () => | |||
| { | |||
| //Sema.Release(); | |||
| //MessageBox.Show("Game Over!"); | |||
| return 1; | |||
| } | |||
| ) | |||
| { AllowTimeExceed = true }.Start(); | |||
| }) | |||
| { IsBackground = true }.Start(); | |||
| return map; | |||
| } | |||
| } | |||
| } | |||
| @@ -68,7 +68,7 @@ namespace Client | |||
| } | |||
| private void SetDynamicValue(MessageOfTricker obj) | |||
| { | |||
| if (!obj.Movable) // 认为movable为真时可动 | |||
| if (obj.PlayerState==PlayerState.Stunned) | |||
| { | |||
| skillprogress.Value = 0; | |||
| skillprogress.Background = Brushes.Gray; | |||
| @@ -12,29 +12,40 @@ namespace ClientTest | |||
| var client = new AvailableService.AvailableServiceClient(channel); | |||
| PlayerMsg playerInfo = new(); | |||
| playerInfo.PlayerId = 0; | |||
| playerInfo.StudentType = StudentType.NullStudentType; | |||
| playerInfo.PlayerType = PlayerType.StudentPlayer; | |||
| playerInfo.StudentType = StudentType._1; | |||
| var call = client.AddPlayer(playerInfo); | |||
| MoveMsg moveMsg = new(); | |||
| moveMsg.PlayerId = 0; | |||
| moveMsg.TimeInMilliseconds = 100; | |||
| moveMsg.Angle = 0; | |||
| int tot = 0; | |||
| /*while (await call.ResponseStream.MoveNext()) | |||
| { | |||
| var currentGameInfo = call.ResponseStream.Current; | |||
| if (currentGameInfo.GameState == GameState.GameStart) break; | |||
| }*/ | |||
| while (true) | |||
| { | |||
| Console.ReadLine(); | |||
| client.Move(moveMsg); | |||
| Thread.Sleep(50); | |||
| MoveRes boolRes = client.Move(moveMsg); | |||
| if (boolRes.ActSuccess == false) break; | |||
| tot++; | |||
| if (tot % 10 == 0) moveMsg.Angle += 1; | |||
| Console.WriteLine("Move!"); | |||
| } | |||
| while (await call.ResponseStream.MoveNext()) | |||
| /*while (await call.ResponseStream.MoveNext()) | |||
| { | |||
| Console.WriteLine("hi"); | |||
| //Console.WriteLine("hi"); | |||
| var currentGameInfo = call.ResponseStream.Current; | |||
| for (int i = 0; i < currentGameInfo.ObjMessage.Count; i++) | |||
| { | |||
| if (currentGameInfo.ObjMessage[i].MessageOfObjCase == MessageOfObj.MessageOfObjOneofCase.StudentMessage) | |||
| Console.WriteLine($"Human is at ({currentGameInfo.ObjMessage[i].StudentMessage.X}, {currentGameInfo.ObjMessage[i].StudentMessage.Y})"); | |||
| } | |||
| } | |||
| }*/ | |||
| } | |||
| } | |||
| @@ -115,7 +115,7 @@ namespace Server | |||
| case Preparation.Utility.BulletType.FlyingKnife: | |||
| return Protobuf.BulletType.FlyingKnife; | |||
| case Preparation.Utility.BulletType.CommonAttackOfGhost: | |||
| return Protobuf.BulletType.CommonAttackOfGhost; | |||
| return Protobuf.BulletType.CommonAttackOfTricker; | |||
| default: | |||
| return Protobuf.BulletType.NullBulletType; | |||
| } | |||
| @@ -131,6 +131,16 @@ namespace Server | |||
| return Protobuf.StudentType.NullStudentType; | |||
| } | |||
| } | |||
| private static Protobuf.TrickerType ToTrickerType(Preparation.Utility.CharacterType characterType) | |||
| { | |||
| switch (characterType) | |||
| { | |||
| case Preparation.Utility.CharacterType.Assassin: | |||
| return Protobuf.TrickerType.Assassin; | |||
| default: | |||
| return Protobuf.TrickerType.NullTrickerType; | |||
| } | |||
| } | |||
| public static MessageOfObj? Auto(GameObj gameObj) | |||
| { | |||
| @@ -151,6 +161,12 @@ namespace Server | |||
| return PickedProp((PickedProp)gameObj); | |||
| else return null; //先写着防报错 | |||
| } | |||
| public static MessageOfObj? Auto(MessageOfNews news) | |||
| { | |||
| MessageOfObj objMsg = new(); | |||
| objMsg.NewsMessage = news; | |||
| return objMsg; | |||
| } | |||
| private static MessageOfObj? Student(Student player) | |||
| { | |||
| @@ -171,9 +187,9 @@ namespace Server | |||
| msg.StudentMessage.Prop.Add(ToPropType(Value.GetPropType())); | |||
| msg.StudentMessage.Place = ToPlaceType(player.Place); | |||
| //msg.StudentMessage.StudentType; // 下面写 | |||
| msg.StudentMessage.Guid = player.ID; | |||
| msg.StudentMessage.State = ToPlayerState(player.PlayerState); | |||
| msg.StudentMessage.PlayerState = ToPlayerState(player.PlayerState); | |||
| msg.StudentMessage.PlayerId = player.PlayerID; | |||
| msg.StudentMessage.ViewRange = player.ViewRange; | |||
| msg.StudentMessage.Radius = player.Radius; | |||
| @@ -205,17 +221,18 @@ namespace Server | |||
| msg.TrickerMessage.X = player.Position.x; | |||
| msg.TrickerMessage.Y = player.Position.y; | |||
| msg.TrickerMessage.Speed = player.MoveSpeed; | |||
| msg.TrickerMessage.Damage = 0; | |||
| foreach (var keyValue in player.TimeUntilActiveSkillAvailable) | |||
| msg.StudentMessage.TimeUntilSkillAvailable.Add(keyValue.Value); | |||
| //msg.TrickerMessage.Place = 0; 下面写了 | |||
| //msg.TrickerMessage.Prop = PropType.NullPropType; // 下面写 | |||
| msg.TrickerMessage.TrickerType = TrickerType.NullTrickerType; // 下面写 | |||
| msg.TrickerMessage.Guid = 0; | |||
| msg.TrickerMessage.Movable = false; | |||
| msg.TrickerMessage.PlayerId = 0; | |||
| msg.TrickerMessage.ViewRange = 0; | |||
| msg.TrickerMessage.Radius = 0; | |||
| msg.TrickerMessage.TimeUntilSkillAvailable.Add(keyValue.Value); | |||
| msg.TrickerMessage.Place = ToPlaceType(player.Place); | |||
| foreach (var Value in player.PropInventory) | |||
| msg.StudentMessage.Prop.Add(ToPropType(Value.GetPropType())); | |||
| msg.TrickerMessage.TrickerType = ToTrickerType(player.CharacterType); // 下面写 | |||
| msg.TrickerMessage.Guid = player.ID; | |||
| msg.TrickerMessage.Score = player.Score; | |||
| msg.TrickerMessage.PlayerId = player.PlayerID; | |||
| msg.TrickerMessage.ViewRange = player.ViewRange; | |||
| msg.TrickerMessage.Radius = player.Radius; | |||
| //msg.TrickerMessage.Buff[0] = ButcherBuffType.NullSbuffType; 下面写了 | |||
| @@ -20,11 +20,11 @@ namespace Server | |||
| protected readonly ArgumentOptions options; | |||
| private HttpSender? httpSender; | |||
| private object gameLock = new(); | |||
| private object[] teamCommunicationLock; | |||
| private const int playerNum = 1; // 注意修改 | |||
| private MessageToClient currentGameInfo = new(); | |||
| private MessageOfMap currentMapMsg = new(); | |||
| private Queue<MsgRes>[] teamCommunicatonMsg; | |||
| private MessageOfObj currentMapMsg = new(); | |||
| private object newsLock = new(); | |||
| private List<MessageOfNews> currentNews = new(); | |||
| private SemaphoreSlim endGameSem = new(0); | |||
| protected readonly Game game; | |||
| private uint spectatorMinPlayerID = 2022; | |||
| @@ -33,7 +33,6 @@ namespace Server | |||
| protected long[] communicationToGameID; // 通信用的ID映射到游戏内的ID,通信中0-3为Student,4为Tricker | |||
| private readonly object messageToAllClientsLock = new(); | |||
| public static readonly long SendMessageToClientIntervalInMilliseconds = 50; | |||
| private readonly Semaphore endGameInfoSema = new(0, 1); | |||
| private MessageWriter? mwr = null; | |||
| public void StartGame() | |||
| @@ -117,7 +116,7 @@ namespace Server | |||
| if (options.ResultFileName != DefaultArgumentOptions.FileName) | |||
| SaveGameResult(options.ResultFileName + ".json"); | |||
| //SendGameResult(); | |||
| endGameInfoSema.Release(); | |||
| this.endGameSem.Release(); | |||
| } | |||
| public void ReportGame(GameState gameState, bool requiredGaming = true) | |||
| @@ -126,16 +125,40 @@ namespace Server | |||
| currentGameInfo = new(); | |||
| lock (messageToAllClientsLock) | |||
| { | |||
| //currentGameInfo.MapMessage = (Message(game.GameMap)); | |||
| switch (gameState) | |||
| { | |||
| case GameState.GameRunning: | |||
| case GameState.GameStart: | |||
| case GameState.GameEnd: | |||
| foreach (GameObj gameObj in gameObjList) | |||
| { | |||
| currentGameInfo.ObjMessage.Add(CopyInfo.Auto(gameObj)); | |||
| } | |||
| lock (newsLock) | |||
| { | |||
| foreach (var news in currentNews) | |||
| { | |||
| currentGameInfo.ObjMessage.Add(CopyInfo.Auto(news)); | |||
| } | |||
| currentNews.Clear(); | |||
| } | |||
| currentGameInfo.GameState = gameState; | |||
| currentGameInfo.AllMessage = new(); // 还没写 | |||
| mwr?.WriteOne(currentGameInfo); | |||
| break; | |||
| case GameState.GameStart: | |||
| currentGameInfo.ObjMessage.Add(currentMapMsg); | |||
| foreach (GameObj gameObj in gameObjList) | |||
| { | |||
| currentGameInfo.ObjMessage.Add(CopyInfo.Auto(gameObj)); | |||
| } | |||
| lock (newsLock) | |||
| { | |||
| foreach (var news in currentNews) | |||
| { | |||
| currentGameInfo.ObjMessage.Add(CopyInfo.Auto(news)); | |||
| } | |||
| currentNews.Clear(); | |||
| } | |||
| currentGameInfo.GameState = gameState; | |||
| currentGameInfo.AllMessage = new(); // 还没写 | |||
| mwr?.WriteOne(currentGameInfo); | |||
| @@ -168,7 +191,7 @@ namespace Server | |||
| } | |||
| private uint GetBirthPointIdx(long playerID) // 获取出生点位置 | |||
| { | |||
| return (uint)(playerID + 1); // ID从0-4,出生点从1-5 | |||
| return (uint)playerID + 1; // ID从0-4,出生点从1-5 | |||
| } | |||
| private bool ValidPlayerID(long playerID) | |||
| { | |||
| @@ -193,15 +216,16 @@ namespace Server | |||
| default: return Protobuf.PlaceType.NullPlaceType; | |||
| } | |||
| } | |||
| private MessageOfMap MapMsg(uint[,] map) | |||
| private MessageOfObj MapMsg(uint[,] map) | |||
| { | |||
| MessageOfMap msgOfMap = new MessageOfMap(); | |||
| MessageOfObj msgOfMap = new(); | |||
| msgOfMap.MapMessage = new(); | |||
| for (int i = 0; i < GameData.rows; i++) | |||
| { | |||
| msgOfMap.Row.Add(new MessageOfMap.Types.Row()); | |||
| msgOfMap.MapMessage.Row.Add(new MessageOfMap.Types.Row()); | |||
| for (int j = 0; j < GameData.cols; j++) | |||
| { | |||
| msgOfMap.Row[i].Col.Add(IntToPlaceType(map[i, j])); | |||
| msgOfMap.MapMessage.Row[i].Col.Add(IntToPlaceType(map[i, j])); | |||
| } | |||
| } | |||
| return msgOfMap; | |||
| @@ -226,6 +250,7 @@ namespace Server | |||
| protected readonly object addPlayerLock = new(); | |||
| public override async Task AddPlayer(PlayerMsg request, IServerStreamWriter<MessageToClient> responseStream, ServerCallContext context) | |||
| { | |||
| Console.WriteLine($"AddPlayer: {request.PlayerId}"); | |||
| if (request.PlayerId >= spectatorMinPlayerID) | |||
| { | |||
| @@ -246,7 +271,25 @@ namespace Server | |||
| if (communicationToGameID[request.PlayerId] != GameObj.invalidID) //是否已经添加了该玩家 | |||
| return; | |||
| Preparation.Utility.CharacterType characterType = Preparation.Utility.CharacterType.Athlete; // 待修改 | |||
| Preparation.Utility.CharacterType characterType = Preparation.Utility.CharacterType.Null; // 待修改 | |||
| if (request.PlayerType == PlayerType.StudentPlayer) | |||
| { | |||
| switch (request.StudentType) | |||
| { | |||
| default: | |||
| characterType = Preparation.Utility.CharacterType.Athlete; | |||
| break; | |||
| } | |||
| } | |||
| else if (request.PlayerType == PlayerType.TrickerPlayer) | |||
| { | |||
| switch (request.TrickerType) | |||
| { | |||
| default: | |||
| characterType = Preparation.Utility.CharacterType.Assassin; | |||
| break; | |||
| } | |||
| } | |||
| lock (addPlayerLock) | |||
| { | |||
| @@ -295,18 +338,20 @@ namespace Server | |||
| Console.WriteLine($"Move ID: {request.PlayerId}, TimeInMilliseconds: {request.TimeInMilliseconds}"); | |||
| #endif | |||
| var gameID = communicationToGameID[request.PlayerId]; | |||
| game.MovePlayer(gameID, (int)request.TimeInMilliseconds, request.Angle); | |||
| // 之后game.MovePlayer可能改为bool类型 | |||
| MoveRes moveRes = new(); | |||
| game.MovePlayer(gameID, (int)request.TimeInMilliseconds, request.Angle); | |||
| // 之后game.MovePlayer可能改为bool类 | |||
| moveRes.ActSuccess = true; | |||
| if (!game.GameMap.Timer.IsGaming) moveRes.ActSuccess = false; | |||
| return Task.FromResult(moveRes); | |||
| } | |||
| public override Task<BoolRes> PickProp(PropMsg request, ServerCallContext context) | |||
| { | |||
| BoolRes boolRes = new(); | |||
| var gameID = communicationToGameID[request.PlayerId]; | |||
| if (request.PropType == Protobuf.PropType.NullPropType) | |||
| boolRes.ActSuccess = game.PickProp(request.PlayerId, Preparation.Utility.PropType.Null); | |||
| boolRes.ActSuccess = game.PickProp(gameID, Preparation.Utility.PropType.Null); | |||
| // 待修改 | |||
| return Task.FromResult(boolRes); | |||
| } | |||
| @@ -320,8 +365,6 @@ namespace Server | |||
| boolRes.ActSuccess = false; | |||
| return Task.FromResult(boolRes); | |||
| } | |||
| MsgRes msg = new(); | |||
| msg.HaveMessage = false; | |||
| if (request.Message.Length > 256) | |||
| { | |||
| #if DEBUG | |||
| @@ -332,30 +375,22 @@ namespace Server | |||
| } | |||
| else | |||
| { | |||
| msg.HaveMessage = true; | |||
| msg.FromPlayerId = request.PlayerId; | |||
| msg.MessageReceived = request.Message; | |||
| MessageOfNews news = new(); | |||
| news.News = request.Message; | |||
| news.FromId = request.PlayerId; | |||
| news.ToId = request.ToPlayerId; | |||
| lock (newsLock) | |||
| { | |||
| currentNews.Add(news); | |||
| } | |||
| #if DEBUG | |||
| Console.WriteLine(msg); | |||
| Console.WriteLine(news.News); | |||
| #endif | |||
| teamCommunicatonMsg[request.ToPlayerId].Enqueue(msg); | |||
| //teamCommunicatonMsg[request.ToPlayerId].Enqueue(msg); | |||
| } | |||
| boolRes.ActSuccess = true; | |||
| return Task.FromResult(boolRes); | |||
| } | |||
| public override Task GetMessage(IDMsg request, IServerStreamWriter<MsgRes> responseStream, ServerCallContext context) | |||
| { | |||
| if (!game.GameMap.Timer.IsGaming) return Task.CompletedTask; | |||
| lock (teamCommunicationLock[request.PlayerId]) | |||
| { | |||
| while (teamCommunicatonMsg[request.PlayerId].Count > 0) | |||
| { | |||
| responseStream.WriteAsync(teamCommunicatonMsg[request.PlayerId].Dequeue()); | |||
| } | |||
| } | |||
| return Task.CompletedTask; | |||
| } | |||
| public override Task<BoolRes> UseProp(PropMsg request, ServerCallContext context) | |||
| { | |||
| return base.UseProp(request, context); | |||
| @@ -436,9 +471,8 @@ namespace Server | |||
| } | |||
| finally { this.game = new Game(map, options.TeamCount); } | |||
| } | |||
| currentMapMsg = MapMsg(game.GameMap.ProtoGameMap); | |||
| communicationToGameID = new long[options.PlayerCountPerTeam + 1]; | |||
| teamCommunicatonMsg = new Queue<MsgRes>[options.PlayerCountPerTeam + 1]; | |||
| teamCommunicationLock = new object[options.PlayerCountPerTeam + 1]; | |||
| //创建server时先设定待加入人物都是invalid | |||
| for (int i = 0; i < communicationToGameID.GetLength(0); i++) | |||
| { | |||
| @@ -2,7 +2,7 @@ | |||
| "profiles": { | |||
| "Server": { | |||
| "commandName": "Project", | |||
| "commandLineArgs": "-p 8888" | |||
| "commandLineArgs": "-p 8888\r\n-f playback\r\n-g 600\r\n-b true\r\n-c 4\r\n-t 2" | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -125,6 +125,7 @@ | |||
| - 翻窗时间 | |||
| - 开锁门时间 | |||
| - 开箱时间 | |||
| - *视野范围* | |||
| ### 学生:人物 | |||
| - 修理电机速度 | |||
| @@ -134,7 +135,7 @@ | |||
| - 沉迷游戏程度 | |||
| - 最大沉迷游戏程度 | |||
| - 被治疗程度 | |||
| - (去)救援(别人)程度 | |||
| - *(去)救援(别人)程度* | |||
| ### 搞蛋鬼:人物 | |||
| 无 | |||