| @@ -52,7 +52,7 @@ namespace THUAI6 | |||||
| Key5 = 2, | Key5 = 2, | ||||
| Key6 = 3, | Key6 = 3, | ||||
| AddSpeed = 4, | AddSpeed = 4, | ||||
| AddLifeOrAp = 5, | |||||
| AddLifeOrClairaudience = 5, | |||||
| AddHpOrAp = 6, | AddHpOrAp = 6, | ||||
| ShieldOrSpear = 7, | ShieldOrSpear = 7, | ||||
| RecoveryFromDizziness = 8, | RecoveryFromDizziness = 8, | ||||
| @@ -83,7 +83,8 @@ namespace THUAI6 | |||||
| Athlete = 1, | Athlete = 1, | ||||
| Teacher = 2, | Teacher = 2, | ||||
| StraightAStudent = 3, | StraightAStudent = 3, | ||||
| StudentType4 = 4, | |||||
| Robot = 4, | |||||
| TechOtaku = 5, | |||||
| }; | }; | ||||
| // 捣蛋鬼类型 | // 捣蛋鬼类型 | ||||
| @@ -282,12 +283,15 @@ namespace THUAI6 | |||||
| {StudentType::Athlete, "Athlete"}, | {StudentType::Athlete, "Athlete"}, | ||||
| {StudentType::Teacher, "Teacher"}, | {StudentType::Teacher, "Teacher"}, | ||||
| {StudentType::StraightAStudent, "StraightAStudent"}, | {StudentType::StraightAStudent, "StraightAStudent"}, | ||||
| {StudentType::Robot, "Robot"}, | |||||
| {StudentType::TechOtaku, "TechOtaku"}, | |||||
| }; | }; | ||||
| inline std::map<TrickerType, std::string> trickerTypeDict{ | inline std::map<TrickerType, std::string> trickerTypeDict{ | ||||
| {TrickerType::NullTrickerType, "NullTrickerType"}, | {TrickerType::NullTrickerType, "NullTrickerType"}, | ||||
| {TrickerType::Assassin, "Assassin"}, | {TrickerType::Assassin, "Assassin"}, | ||||
| {TrickerType::Klee, "Klee"}, | {TrickerType::Klee, "Klee"}, | ||||
| {TrickerType::ANoisyPerson, "ANoisyPerson"}, | |||||
| }; | }; | ||||
| inline std::map<PlayerState, std::string> playerStateDict{ | inline std::map<PlayerState, std::string> playerStateDict{ | ||||
| @@ -339,7 +343,7 @@ namespace THUAI6 | |||||
| {PropType::Key5, "Key5"}, | {PropType::Key5, "Key5"}, | ||||
| {PropType::Key6, "Key6"}, | {PropType::Key6, "Key6"}, | ||||
| {PropType::AddSpeed, "AddSpeed"}, | {PropType::AddSpeed, "AddSpeed"}, | ||||
| {PropType::AddLifeOrAp, "AddLifeOrAp"}, | |||||
| {PropType::AddLifeOrClairaudience, "AddLifeOrClairaudience"}, | |||||
| {PropType::AddHpOrAp, "AddHpOrAp"}, | {PropType::AddHpOrAp, "AddHpOrAp"}, | ||||
| {PropType::ShieldOrSpear, "ShieldOrSpear"}, | {PropType::ShieldOrSpear, "ShieldOrSpear"}, | ||||
| {PropType::RecoveryFromDizziness, "RecoveryFromDizziness"}, | {PropType::RecoveryFromDizziness, "RecoveryFromDizziness"}, | ||||
| @@ -4,6 +4,7 @@ | |||||
| #define UTILS_HPP | #define UTILS_HPP | ||||
| #include <cstdint> | #include <cstdint> | ||||
| #include <cmath> | |||||
| #include "Message2Clients.pb.h" | #include "Message2Clients.pb.h" | ||||
| #include "Message2Server.pb.h" | #include "Message2Server.pb.h" | ||||
| #include "MessageType.pb.h" | #include "MessageType.pb.h" | ||||
| @@ -93,7 +94,7 @@ namespace Proto2THUAI6 | |||||
| {protobuf::PropType::KEY6, THUAI6::PropType::Key6}, | {protobuf::PropType::KEY6, THUAI6::PropType::Key6}, | ||||
| {protobuf::PropType::ADD_SPEED, THUAI6::PropType::AddSpeed}, | {protobuf::PropType::ADD_SPEED, THUAI6::PropType::AddSpeed}, | ||||
| {protobuf::PropType::ADD_HP_OR_AP, THUAI6::PropType::AddHpOrAp}, | {protobuf::PropType::ADD_HP_OR_AP, THUAI6::PropType::AddHpOrAp}, | ||||
| {protobuf::PropType::ADD_LIFE_OR_AP, THUAI6::PropType::AddLifeOrAp}, | |||||
| {protobuf::PropType::ADD_LIFE_OR_CLAIRAUDIENCE, THUAI6::PropType::AddLifeOrClairaudience}, | |||||
| {protobuf::PropType::SHIELD_OR_SPEAR, THUAI6::PropType::ShieldOrSpear}, | {protobuf::PropType::SHIELD_OR_SPEAR, THUAI6::PropType::ShieldOrSpear}, | ||||
| {protobuf::PropType::RECOVERY_FROM_DIZZINESS, THUAI6::PropType::RecoveryFromDizziness}, | {protobuf::PropType::RECOVERY_FROM_DIZZINESS, THUAI6::PropType::RecoveryFromDizziness}, | ||||
| }; | }; | ||||
| @@ -107,34 +108,35 @@ namespace Proto2THUAI6 | |||||
| inline std::map<protobuf::StudentType, THUAI6::StudentType> studentTypeDict{ | inline std::map<protobuf::StudentType, THUAI6::StudentType> studentTypeDict{ | ||||
| {protobuf::StudentType::NULL_STUDENT_TYPE, THUAI6::StudentType::NullStudentType}, | {protobuf::StudentType::NULL_STUDENT_TYPE, THUAI6::StudentType::NullStudentType}, | ||||
| {protobuf::StudentType::ATHLETE, THUAI6::StudentType::Athlete}, | {protobuf::StudentType::ATHLETE, THUAI6::StudentType::Athlete}, | ||||
| {protobuf::StudentType::STUDENTTYPE2, THUAI6::StudentType::Teacher}, | |||||
| {protobuf::StudentType::STUDENTTYPE3, THUAI6::StudentType::StraightAStudent}, | |||||
| {protobuf::StudentType::STUDENTTYPE4, THUAI6::StudentType::StudentType4}, | |||||
| {protobuf::StudentType::TEACHER, THUAI6::StudentType::Teacher}, | |||||
| {protobuf::StudentType::STRAIGHT_A_STUDENT, THUAI6::StudentType::StraightAStudent}, | |||||
| {protobuf::StudentType::ROBOT, THUAI6::StudentType::Robot}, | |||||
| {protobuf::StudentType::TECH_OTAKU, THUAI6::StudentType::TechOtaku}, | |||||
| }; | }; | ||||
| inline std::map<protobuf::TrickerType, THUAI6::TrickerType> trickerTypeDict{ | inline std::map<protobuf::TrickerType, THUAI6::TrickerType> trickerTypeDict{ | ||||
| {protobuf::TrickerType::NULL_TRICKER_TYPE, THUAI6::TrickerType::NullTrickerType}, | {protobuf::TrickerType::NULL_TRICKER_TYPE, THUAI6::TrickerType::NullTrickerType}, | ||||
| {protobuf::TrickerType::ASSASSIN, THUAI6::TrickerType::Assassin}, | {protobuf::TrickerType::ASSASSIN, THUAI6::TrickerType::Assassin}, | ||||
| {protobuf::TrickerType::TRICKERTYPE2, THUAI6::TrickerType::Klee}, | |||||
| {protobuf::TrickerType::TRICKERTYPE3, THUAI6::TrickerType::ANoisyPerson}, | |||||
| {protobuf::TrickerType::KLEE, THUAI6::TrickerType::Klee}, | |||||
| {protobuf::TrickerType::A_NOISY_PERSON, THUAI6::TrickerType::ANoisyPerson}, | |||||
| {protobuf::TrickerType::TRICKERTYPE4, THUAI6::TrickerType::TrickerType4}, | {protobuf::TrickerType::TRICKERTYPE4, THUAI6::TrickerType::TrickerType4}, | ||||
| }; | }; | ||||
| inline std::map<protobuf::StudentBuffType, THUAI6::StudentBuffType> studentBuffTypeDict{ | inline std::map<protobuf::StudentBuffType, THUAI6::StudentBuffType> studentBuffTypeDict{ | ||||
| {protobuf::StudentBuffType::NULL_SBUFF_TYPE, THUAI6::StudentBuffType::NullStudentBuffType}, | {protobuf::StudentBuffType::NULL_SBUFF_TYPE, THUAI6::StudentBuffType::NullStudentBuffType}, | ||||
| {protobuf::StudentBuffType::SBUFFTYPE1, THUAI6::StudentBuffType::AddSpeed}, | |||||
| {protobuf::StudentBuffType::SBUFFTYPE2, THUAI6::StudentBuffType::AddLife}, | |||||
| {protobuf::StudentBuffType::SBUFFTYPE3, THUAI6::StudentBuffType::Shield}, | |||||
| {protobuf::StudentBuffType::SBUFFTYPE4, THUAI6::StudentBuffType::Invisible}, | |||||
| {protobuf::StudentBuffType::STUDENT_ADD_SPEED, THUAI6::StudentBuffType::AddSpeed}, | |||||
| {protobuf::StudentBuffType::ADD_LIFE, THUAI6::StudentBuffType::AddLife}, | |||||
| {protobuf::StudentBuffType::SHIELD, THUAI6::StudentBuffType::Shield}, | |||||
| {protobuf::StudentBuffType::STUDENT_INVISIBLE, THUAI6::StudentBuffType::Invisible}, | |||||
| }; | }; | ||||
| inline std::map<protobuf::TrickerBuffType, THUAI6::TrickerBuffType> trickerBuffTypeDict{ | inline std::map<protobuf::TrickerBuffType, THUAI6::TrickerBuffType> trickerBuffTypeDict{ | ||||
| {protobuf::TrickerBuffType::NULL_TBUFF_TYPE, THUAI6::TrickerBuffType::NullTrickerBuffType}, | {protobuf::TrickerBuffType::NULL_TBUFF_TYPE, THUAI6::TrickerBuffType::NullTrickerBuffType}, | ||||
| {protobuf::TrickerBuffType::TBUFFTYPE1, THUAI6::TrickerBuffType::AddSpeed}, | |||||
| {protobuf::TrickerBuffType::TBUFFTYPE2, THUAI6::TrickerBuffType::Spear}, | |||||
| {protobuf::TrickerBuffType::TBUFFTYPE3, THUAI6::TrickerBuffType::AddAp}, | |||||
| {protobuf::TrickerBuffType::TBUFFTYPE4, THUAI6::TrickerBuffType::Clairaudience}, | |||||
| {protobuf::TrickerBuffType::INVISIBLE, THUAI6::TrickerBuffType::Invisible}, | |||||
| {protobuf::TrickerBuffType::TRICKER_ADD_SPEED, THUAI6::TrickerBuffType::AddSpeed}, | |||||
| {protobuf::TrickerBuffType::SPEAR, THUAI6::TrickerBuffType::Spear}, | |||||
| {protobuf::TrickerBuffType::ADD_AP, THUAI6::TrickerBuffType::AddAp}, | |||||
| {protobuf::TrickerBuffType::CLAIRAUDIENCE, THUAI6::TrickerBuffType::Clairaudience}, | |||||
| {protobuf::TrickerBuffType::TRICKER_INVISIBLE, THUAI6::TrickerBuffType::Invisible}, | |||||
| }; | }; | ||||
| inline std::map<protobuf::PlayerState, THUAI6::PlayerState> playerStateDict{ | inline std::map<protobuf::PlayerState, THUAI6::PlayerState> playerStateDict{ | ||||
| @@ -170,8 +172,8 @@ namespace Proto2THUAI6 | |||||
| {protobuf::BulletType::NULL_BULLET_TYPE, THUAI6::BulletType::NullBulletType}, | {protobuf::BulletType::NULL_BULLET_TYPE, THUAI6::BulletType::NullBulletType}, | ||||
| {protobuf::BulletType::FLYING_KNIFE, THUAI6::BulletType::FlyingKnife}, | {protobuf::BulletType::FLYING_KNIFE, THUAI6::BulletType::FlyingKnife}, | ||||
| {protobuf::BulletType::COMMON_ATTACK_OF_TRICKER, THUAI6::BulletType::CommonAttackOfTricker}, | {protobuf::BulletType::COMMON_ATTACK_OF_TRICKER, THUAI6::BulletType::CommonAttackOfTricker}, | ||||
| {protobuf::BulletType::FAST_BULLET, THUAI6::BulletType::BombBomb}, | |||||
| {protobuf::BulletType::ORDINARY_BULLET, THUAI6::BulletType::JumpyDumpty}, | |||||
| {protobuf::BulletType::BOMB_BOMB, THUAI6::BulletType::BombBomb}, | |||||
| {protobuf::BulletType::JUMPY_DUMPTY, THUAI6::BulletType::JumpyDumpty}, | |||||
| {protobuf::BulletType::ATOM_BOMB, THUAI6::BulletType::AtomBomb}, | {protobuf::BulletType::ATOM_BOMB, THUAI6::BulletType::AtomBomb}, | ||||
| }; | }; | ||||
| @@ -350,7 +352,7 @@ namespace THUAI62Proto | |||||
| {THUAI6::PropType::Key5, protobuf::PropType::KEY5}, | {THUAI6::PropType::Key5, protobuf::PropType::KEY5}, | ||||
| {THUAI6::PropType::Key6, protobuf::PropType::KEY6}, | {THUAI6::PropType::Key6, protobuf::PropType::KEY6}, | ||||
| {THUAI6::PropType::AddHpOrAp, protobuf::PropType::ADD_HP_OR_AP}, | {THUAI6::PropType::AddHpOrAp, protobuf::PropType::ADD_HP_OR_AP}, | ||||
| {THUAI6::PropType::AddLifeOrAp, protobuf::PropType::ADD_LIFE_OR_AP}, | |||||
| {THUAI6::PropType::AddLifeOrClairaudience, protobuf::PropType::ADD_LIFE_OR_CLAIRAUDIENCE}, | |||||
| {THUAI6::PropType::AddSpeed, protobuf::PropType::ADD_SPEED}, | {THUAI6::PropType::AddSpeed, protobuf::PropType::ADD_SPEED}, | ||||
| {THUAI6::PropType::ShieldOrSpear, protobuf::PropType::SHIELD_OR_SPEAR}, | {THUAI6::PropType::ShieldOrSpear, protobuf::PropType::SHIELD_OR_SPEAR}, | ||||
| }; | }; | ||||
| @@ -364,14 +366,15 @@ namespace THUAI62Proto | |||||
| inline std::map<THUAI6::StudentType, protobuf::StudentType> studentTypeDict{ | inline std::map<THUAI6::StudentType, protobuf::StudentType> studentTypeDict{ | ||||
| {THUAI6::StudentType::NullStudentType, protobuf::StudentType::NULL_STUDENT_TYPE}, | {THUAI6::StudentType::NullStudentType, protobuf::StudentType::NULL_STUDENT_TYPE}, | ||||
| {THUAI6::StudentType::Athlete, protobuf::StudentType::ATHLETE}, | {THUAI6::StudentType::Athlete, protobuf::StudentType::ATHLETE}, | ||||
| {THUAI6::StudentType::Teacher, protobuf::StudentType::STUDENTTYPE2}, | |||||
| {THUAI6::StudentType::StraightAStudent, protobuf::StudentType::STUDENTTYPE3}, | |||||
| {THUAI6::StudentType::StudentType4, protobuf::StudentType::STUDENTTYPE4}, | |||||
| {THUAI6::StudentType::Teacher, protobuf::StudentType::TEACHER}, | |||||
| {THUAI6::StudentType::StraightAStudent, protobuf::StudentType::STRAIGHT_A_STUDENT}, | |||||
| {THUAI6::StudentType::Robot, protobuf::StudentType::ROBOT}, | |||||
| {THUAI6::StudentType::TechOtaku, protobuf::StudentType::TECH_OTAKU}, | |||||
| }; | }; | ||||
| // inline std::map<THUAI6::StudentBuffType, protobuf::StudentBuffType> studentBuffTypeDict{ | // inline std::map<THUAI6::StudentBuffType, protobuf::StudentBuffType> studentBuffTypeDict{ | ||||
| // {THUAI6::StudentBuffType::NullStudentBuffType, protobuf::StudentBuffType::NULL_SBUFF_TYPE}, | // {THUAI6::StudentBuffType::NullStudentBuffType, protobuf::StudentBuffType::NULL_SBUFF_TYPE}, | ||||
| // {THUAI6::StudentBuffType::StudentBuffType1, protobuf::StudentBuffType::SBUFFTYPE1}, | |||||
| // {THUAI6::StudentBuffType::StudentBuffType1, protobuf::StudentBuffType::ADD_SPEED}, | |||||
| // {THUAI6::StudentBuffType::StudentBuffType2, protobuf::StudentBuffType::SBUFFTYPE2}, | // {THUAI6::StudentBuffType::StudentBuffType2, protobuf::StudentBuffType::SBUFFTYPE2}, | ||||
| // {THUAI6::StudentBuffType::StudentBuffType3, protobuf::StudentBuffType::SBUFFTYPE3}, | // {THUAI6::StudentBuffType::StudentBuffType3, protobuf::StudentBuffType::SBUFFTYPE3}, | ||||
| // {THUAI6::StudentBuffType::StudentBuffType4, protobuf::StudentBuffType::SBUFFTYPE4}, | // {THUAI6::StudentBuffType::StudentBuffType4, protobuf::StudentBuffType::SBUFFTYPE4}, | ||||
| @@ -380,8 +383,8 @@ namespace THUAI62Proto | |||||
| inline std::map<THUAI6::TrickerType, protobuf::TrickerType> trickerTypeDict{ | inline std::map<THUAI6::TrickerType, protobuf::TrickerType> trickerTypeDict{ | ||||
| {THUAI6::TrickerType::NullTrickerType, protobuf::TrickerType::NULL_TRICKER_TYPE}, | {THUAI6::TrickerType::NullTrickerType, protobuf::TrickerType::NULL_TRICKER_TYPE}, | ||||
| {THUAI6::TrickerType::Assassin, protobuf::TrickerType::ASSASSIN}, | {THUAI6::TrickerType::Assassin, protobuf::TrickerType::ASSASSIN}, | ||||
| {THUAI6::TrickerType::Klee, protobuf::TrickerType::TRICKERTYPE2}, | |||||
| {THUAI6::TrickerType::ANoisyPerson, protobuf::TrickerType::TRICKERTYPE3}, | |||||
| {THUAI6::TrickerType::Klee, protobuf::TrickerType::KLEE}, | |||||
| {THUAI6::TrickerType::ANoisyPerson, protobuf::TrickerType::A_NOISY_PERSON}, | |||||
| {THUAI6::TrickerType::TrickerType4, protobuf::TrickerType::TRICKERTYPE4}, | {THUAI6::TrickerType::TrickerType4, protobuf::TrickerType::TRICKERTYPE4}, | ||||
| }; | }; | ||||
| @@ -6,7 +6,7 @@ | |||||
| extern const bool asynchronous = false; | extern const bool asynchronous = false; | ||||
| // 选手必须定义该变量来选择自己的阵营 | // 选手必须定义该变量来选择自己的阵营 | ||||
| extern const THUAI6::PlayerType playerType = THUAI6::PlayerType::StudentPlayer; | |||||
| extern const THUAI6::PlayerType playerType = THUAI6::PlayerType::TrickerPlayer; | |||||
| // 选手需要将两个都定义,本份代码中不选择的阵营任意定义即可 | // 选手需要将两个都定义,本份代码中不选择的阵营任意定义即可 | ||||
| extern const THUAI6::TrickerType trickerType = THUAI6::TrickerType::Assassin; | extern const THUAI6::TrickerType trickerType = THUAI6::TrickerType::Assassin; | ||||
| @@ -17,15 +17,14 @@ extern const THUAI6::StudentType studentType = THUAI6::StudentType::Athlete; | |||||
| void AI::play(IStudentAPI& api) | void AI::play(IStudentAPI& api) | ||||
| { | { | ||||
| api.SendMessage(1, "Hello, I'm player 0 using C++ interface!"); | |||||
| if (api.HaveMessage()) | |||||
| { | |||||
| auto msg = api.GetMessage(); | |||||
| api.Print("Player " + std::to_string(msg.first) + " says: " + msg.second); | |||||
| } | |||||
| api.PrintTricker(); | |||||
| } | } | ||||
| void AI::play(ITrickerAPI& api) | void AI::play(ITrickerAPI& api) | ||||
| { | { | ||||
| api.Move(100, 1); | |||||
| if (api.HaveMessage()) | |||||
| { | |||||
| auto msg = api.GetMessage(); | |||||
| api.Print("Message from " + std::to_string(msg.first) + ": " + msg.second); | |||||
| } | |||||
| } | } | ||||
| @@ -215,7 +215,6 @@ bool Communication::TryConnection(int64_t playerID) | |||||
| auto status = THUAI6Stub->TryConnection(&context, request, &reply); | auto status = THUAI6Stub->TryConnection(&context, request, &reply); | ||||
| if (status.ok()) | if (status.ok()) | ||||
| { | { | ||||
| std::cout << "Connection success!" << std::endl; | |||||
| return true; | return true; | ||||
| } | } | ||||
| else | else | ||||
| @@ -75,6 +75,11 @@ std::vector<std::vector<THUAI6::PlaceType>> Logic::GetFullMap() const | |||||
| THUAI6::PlaceType Logic::GetPlaceType(int32_t cellX, int32_t cellY) const | THUAI6::PlaceType Logic::GetPlaceType(int32_t cellX, int32_t cellY) const | ||||
| { | { | ||||
| std::unique_lock<std::mutex> lock(mtxState); | std::unique_lock<std::mutex> lock(mtxState); | ||||
| if (cellX < 0 || cellX >= currentState->gameMap.size() || cellY < 0 || cellY >= currentState->gameMap[0].size()) | |||||
| { | |||||
| logger->warn("Invalid position!"); | |||||
| return THUAI6::PlaceType::NullPlaceType; | |||||
| } | |||||
| logger->debug("Called GetPlaceType"); | logger->debug("Called GetPlaceType"); | ||||
| return currentState->gameMap[cellX][cellY]; | return currentState->gameMap[cellX][cellY]; | ||||
| } | } | ||||
| @@ -18,13 +18,13 @@ int THUAI6Main(int argc, char** argv, CreateAIFunc AIBuilder) | |||||
| extern const THUAI6::PlayerType playerType; | extern const THUAI6::PlayerType playerType; | ||||
| extern const THUAI6::TrickerType trickerType; | extern const THUAI6::TrickerType trickerType; | ||||
| extern const THUAI6::StudentType studentType; | extern const THUAI6::StudentType studentType; | ||||
| { | |||||
| file = true; | |||||
| print = true; | |||||
| Logic logic(playerType, pID, trickerType, studentType); | |||||
| logic.Main(AIBuilder, sIP, sPort, file, print, warnOnly); | |||||
| return 0; | |||||
| } | |||||
| // { | |||||
| // file = true; | |||||
| // print = true; | |||||
| // Logic logic(playerType, pID, trickerType, studentType); | |||||
| // logic.Main(AIBuilder, sIP, sPort, file, print, warnOnly); | |||||
| // return 0; | |||||
| // } | |||||
| // 使用cmdline的正式版本 | // 使用cmdline的正式版本 | ||||
| try | try | ||||
| @@ -30,48 +30,49 @@ static constexpr ::_pbi::MigrationSchema* schemas = nullptr; | |||||
| static constexpr ::_pb::Message* const* file_default_instances = nullptr; | static constexpr ::_pb::Message* const* file_default_instances = nullptr; | ||||
| const char descriptor_table_protodef_MessageType_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = | const char descriptor_table_protodef_MessageType_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = | ||||
| "\n\021MessageType.proto\022\010protobuf*\207\001\n\nBullet" | |||||
| "\n\021MessageType.proto\022\010protobuf*\202\001\n\nBullet" | |||||
| "Type\022\024\n\020NULL_BULLET_TYPE\020\000\022\020\n\014FLYING_KNI" | "Type\022\024\n\020NULL_BULLET_TYPE\020\000\022\020\n\014FLYING_KNI" | ||||
| "FE\020\001\022\034\n\030COMMON_ATTACK_OF_TRICKER\020\002\022\017\n\013FA" | |||||
| "ST_BULLET\020\003\022\023\n\017ORDINARY_BULLET\020\004\022\r\n\tATOM" | |||||
| "_BOMB\020\005*\241\001\n\tPlaceType\022\023\n\017NULL_PLACE_TYPE" | |||||
| "\020\000\022\010\n\004LAND\020\001\022\010\n\004WALL\020\002\022\t\n\005GRASS\020\003\022\r\n\tCLA" | |||||
| "SSROOM\020\004\022\010\n\004GATE\020\005\022\017\n\013HIDDEN_GATE\020\006\022\n\n\006W" | |||||
| "INDOW\020\007\022\t\n\005DOOR3\020\010\022\t\n\005DOOR5\020\t\022\t\n\005DOOR6\020\n" | |||||
| "\022\t\n\005CHEST\020\013*8\n\tShapeType\022\023\n\017NULL_SHAPE_T" | |||||
| "YPE\020\000\022\n\n\006CIRCLE\020\001\022\n\n\006SQUARE\020\002*\243\001\n\010PropTy" | |||||
| "pe\022\022\n\016NULL_PROP_TYPE\020\000\022\r\n\tADD_SPEED\020\001\022\022\n" | |||||
| "\016ADD_LIFE_OR_AP\020\002\022\020\n\014ADD_HP_OR_AP\020\003\022\023\n\017S" | |||||
| "HIELD_OR_SPEAR\020\004\022\010\n\004KEY3\020\005\022\010\n\004KEY5\020\006\022\010\n\004" | |||||
| "KEY6\020\007\022\033\n\027RECOVERY_FROM_DIZZINESS\020\010*f\n\017S" | |||||
| "tudentBuffType\022\023\n\017NULL_SBUFF_TYPE\020\000\022\016\n\nS" | |||||
| "BUFFTYPE1\020\001\022\016\n\nSBUFFTYPE2\020\002\022\016\n\nSBUFFTYPE" | |||||
| "3\020\003\022\016\n\nSBUFFTYPE4\020\004*\251\002\n\013PlayerState\022\017\n\013N" | |||||
| "ULL_STATUS\020\000\022\010\n\004IDLE\020\001\022\014\n\010LEARNING\020\002\022\014\n\010" | |||||
| "ADDICTED\020\003\022\010\n\004QUIT\020\004\022\r\n\tGRADUATED\020\005\022\013\n\007T" | |||||
| "REATED\020\006\022\013\n\007RESCUED\020\007\022\013\n\007STUNNED\020\010\022\014\n\010TR" | |||||
| "EATING\020\t\022\014\n\010RESCUING\020\n\022\014\n\010SWINGING\020\013\022\r\n\t" | |||||
| "ATTACKING\020\014\022\013\n\007LOCKING\020\r\022\r\n\tRUMMAGING\020\016\022" | |||||
| "\014\n\010CLIMBING\020\017\022\023\n\017OPENING_A_CHEST\020\020\022\027\n\023US" | |||||
| "ING_SPECIAL_SKILL\020\021\022\022\n\016OPENING_A_GATE\020\022*" | |||||
| "u\n\017TrickerBuffType\022\023\n\017NULL_TBUFF_TYPE\020\000\022" | |||||
| "\016\n\nTBUFFTYPE1\020\001\022\016\n\nTBUFFTYPE2\020\002\022\016\n\nTBUFF" | |||||
| "TYPE3\020\003\022\016\n\nTBUFFTYPE4\020\004\022\r\n\tINVISIBLE\020\005*J" | |||||
| "\n\nPlayerType\022\024\n\020NULL_PLAYER_TYPE\020\000\022\022\n\016ST" | |||||
| "UDENT_PLAYER\020\001\022\022\n\016TRICKER_PLAYER\020\002*g\n\013St" | |||||
| "udentType\022\025\n\021NULL_STUDENT_TYPE\020\000\022\013\n\007ATHL" | |||||
| "ETE\020\001\022\020\n\014STUDENTTYPE2\020\002\022\020\n\014STUDENTTYPE3\020" | |||||
| "\003\022\020\n\014STUDENTTYPE4\020\004*h\n\013TrickerType\022\025\n\021NU" | |||||
| "LL_TRICKER_TYPE\020\000\022\014\n\010ASSASSIN\020\001\022\020\n\014TRICK" | |||||
| "ERTYPE2\020\002\022\020\n\014TRICKERTYPE3\020\003\022\020\n\014TRICKERTY" | |||||
| "PE4\020\004*P\n\tGameState\022\023\n\017NULL_GAME_STATE\020\000\022" | |||||
| "\016\n\nGAME_START\020\001\022\020\n\014GAME_RUNNING\020\002\022\014\n\010GAM" | |||||
| "E_END\020\003b\006proto3"; | |||||
| "FE\020\001\022\034\n\030COMMON_ATTACK_OF_TRICKER\020\002\022\r\n\tBO" | |||||
| "MB_BOMB\020\003\022\020\n\014JUMPY_DUMPTY\020\004\022\r\n\tATOM_BOMB" | |||||
| "\020\005*\241\001\n\tPlaceType\022\023\n\017NULL_PLACE_TYPE\020\000\022\010\n" | |||||
| "\004LAND\020\001\022\010\n\004WALL\020\002\022\t\n\005GRASS\020\003\022\r\n\tCLASSROO" | |||||
| "M\020\004\022\010\n\004GATE\020\005\022\017\n\013HIDDEN_GATE\020\006\022\n\n\006WINDOW" | |||||
| "\020\007\022\t\n\005DOOR3\020\010\022\t\n\005DOOR5\020\t\022\t\n\005DOOR6\020\n\022\t\n\005C" | |||||
| "HEST\020\013*8\n\tShapeType\022\023\n\017NULL_SHAPE_TYPE\020\000" | |||||
| "\022\n\n\006CIRCLE\020\001\022\n\n\006SQUARE\020\002*\256\001\n\010PropType\022\022\n" | |||||
| "\016NULL_PROP_TYPE\020\000\022\r\n\tADD_SPEED\020\001\022\035\n\031ADD_" | |||||
| "LIFE_OR_CLAIRAUDIENCE\020\002\022\020\n\014ADD_HP_OR_AP\020" | |||||
| "\003\022\023\n\017SHIELD_OR_SPEAR\020\004\022\010\n\004KEY3\020\005\022\010\n\004KEY5" | |||||
| "\020\006\022\010\n\004KEY6\020\007\022\033\n\027RECOVERY_FROM_DIZZINESS\020" | |||||
| "\010*n\n\017StudentBuffType\022\023\n\017NULL_SBUFF_TYPE\020" | |||||
| "\000\022\025\n\021STUDENT_ADD_SPEED\020\001\022\014\n\010ADD_LIFE\020\002\022\n" | |||||
| "\n\006SHIELD\020\003\022\025\n\021STUDENT_INVISIBLE\020\004*\251\002\n\013Pl" | |||||
| "ayerState\022\017\n\013NULL_STATUS\020\000\022\010\n\004IDLE\020\001\022\014\n\010" | |||||
| "LEARNING\020\002\022\014\n\010ADDICTED\020\003\022\010\n\004QUIT\020\004\022\r\n\tGR" | |||||
| "ADUATED\020\005\022\013\n\007TREATED\020\006\022\013\n\007RESCUED\020\007\022\013\n\007S" | |||||
| "TUNNED\020\010\022\014\n\010TREATING\020\t\022\014\n\010RESCUING\020\n\022\014\n\010" | |||||
| "SWINGING\020\013\022\r\n\tATTACKING\020\014\022\013\n\007LOCKING\020\r\022\r" | |||||
| "\n\tRUMMAGING\020\016\022\014\n\010CLIMBING\020\017\022\023\n\017OPENING_A" | |||||
| "_CHEST\020\020\022\027\n\023USING_SPECIAL_SKILL\020\021\022\022\n\016OPE" | |||||
| "NING_A_GATE\020\022*~\n\017TrickerBuffType\022\023\n\017NULL" | |||||
| "_TBUFF_TYPE\020\000\022\025\n\021TRICKER_ADD_SPEED\020\001\022\t\n\005" | |||||
| "SPEAR\020\002\022\n\n\006ADD_AP\020\003\022\021\n\rCLAIRAUDIENCE\020\004\022\025" | |||||
| "\n\021TRICKER_INVISIBLE\020\005*J\n\nPlayerType\022\024\n\020N" | |||||
| "ULL_PLAYER_TYPE\020\000\022\022\n\016STUDENT_PLAYER\020\001\022\022\n" | |||||
| "\016TRICKER_PLAYER\020\002*q\n\013StudentType\022\025\n\021NULL" | |||||
| "_STUDENT_TYPE\020\000\022\013\n\007ATHLETE\020\001\022\013\n\007TEACHER\020" | |||||
| "\002\022\026\n\022STRAIGHT_A_STUDENT\020\003\022\t\n\005ROBOT\020\004\022\016\n\n" | |||||
| "TECH_OTAKU\020\005*b\n\013TrickerType\022\025\n\021NULL_TRIC" | |||||
| "KER_TYPE\020\000\022\014\n\010ASSASSIN\020\001\022\010\n\004KLEE\020\002\022\022\n\016A_" | |||||
| "NOISY_PERSON\020\003\022\020\n\014TRICKERTYPE4\020\004*P\n\tGame" | |||||
| "State\022\023\n\017NULL_GAME_STATE\020\000\022\016\n\nGAME_START" | |||||
| "\020\001\022\020\n\014GAME_RUNNING\020\002\022\014\n\010GAME_END\020\003b\006prot" | |||||
| "o3"; | |||||
| static ::_pbi::once_flag descriptor_table_MessageType_2eproto_once; | static ::_pbi::once_flag descriptor_table_MessageType_2eproto_once; | ||||
| const ::_pbi::DescriptorTable descriptor_table_MessageType_2eproto = { | const ::_pbi::DescriptorTable descriptor_table_MessageType_2eproto = { | ||||
| false, | false, | ||||
| false, | false, | ||||
| 1455, | |||||
| 1482, | |||||
| descriptor_table_protodef_MessageType_2eproto, | descriptor_table_protodef_MessageType_2eproto, | ||||
| "MessageType.proto", | "MessageType.proto", | ||||
| &descriptor_table_MessageType_2eproto_once, | &descriptor_table_MessageType_2eproto_once, | ||||
| @@ -291,6 +292,7 @@ namespace protobuf | |||||
| case 2: | case 2: | ||||
| case 3: | case 3: | ||||
| case 4: | case 4: | ||||
| case 5: | |||||
| return true; | return true; | ||||
| default: | default: | ||||
| return false; | return false; | ||||
| @@ -55,8 +55,8 @@ namespace protobuf | |||||
| NULL_BULLET_TYPE = 0, | NULL_BULLET_TYPE = 0, | ||||
| FLYING_KNIFE = 1, | FLYING_KNIFE = 1, | ||||
| COMMON_ATTACK_OF_TRICKER = 2, | COMMON_ATTACK_OF_TRICKER = 2, | ||||
| FAST_BULLET = 3, | |||||
| ORDINARY_BULLET = 4, | |||||
| BOMB_BOMB = 3, | |||||
| JUMPY_DUMPTY = 4, | |||||
| ATOM_BOMB = 5, | ATOM_BOMB = 5, | ||||
| BulletType_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::min(), | BulletType_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::min(), | ||||
| BulletType_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::max() | BulletType_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::max() | ||||
| @@ -156,7 +156,7 @@ namespace protobuf | |||||
| { | { | ||||
| NULL_PROP_TYPE = 0, | NULL_PROP_TYPE = 0, | ||||
| ADD_SPEED = 1, | ADD_SPEED = 1, | ||||
| ADD_LIFE_OR_AP = 2, | |||||
| ADD_LIFE_OR_CLAIRAUDIENCE = 2, | |||||
| ADD_HP_OR_AP = 3, | ADD_HP_OR_AP = 3, | ||||
| SHIELD_OR_SPEAR = 4, | SHIELD_OR_SPEAR = 4, | ||||
| KEY3 = 5, | KEY3 = 5, | ||||
| @@ -191,16 +191,16 @@ namespace protobuf | |||||
| enum StudentBuffType : int | enum StudentBuffType : int | ||||
| { | { | ||||
| NULL_SBUFF_TYPE = 0, | NULL_SBUFF_TYPE = 0, | ||||
| SBUFFTYPE1 = 1, | |||||
| SBUFFTYPE2 = 2, | |||||
| SBUFFTYPE3 = 3, | |||||
| SBUFFTYPE4 = 4, | |||||
| STUDENT_ADD_SPEED = 1, | |||||
| ADD_LIFE = 2, | |||||
| SHIELD = 3, | |||||
| STUDENT_INVISIBLE = 4, | |||||
| StudentBuffType_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::min(), | StudentBuffType_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::min(), | ||||
| StudentBuffType_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::max() | StudentBuffType_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::max() | ||||
| }; | }; | ||||
| bool StudentBuffType_IsValid(int value); | bool StudentBuffType_IsValid(int value); | ||||
| constexpr StudentBuffType StudentBuffType_MIN = NULL_SBUFF_TYPE; | constexpr StudentBuffType StudentBuffType_MIN = NULL_SBUFF_TYPE; | ||||
| constexpr StudentBuffType StudentBuffType_MAX = SBUFFTYPE4; | |||||
| constexpr StudentBuffType StudentBuffType_MAX = STUDENT_INVISIBLE; | |||||
| constexpr int StudentBuffType_ARRAYSIZE = StudentBuffType_MAX + 1; | constexpr int StudentBuffType_ARRAYSIZE = StudentBuffType_MAX + 1; | ||||
| const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* StudentBuffType_descriptor(); | const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* StudentBuffType_descriptor(); | ||||
| @@ -269,17 +269,17 @@ namespace protobuf | |||||
| enum TrickerBuffType : int | enum TrickerBuffType : int | ||||
| { | { | ||||
| NULL_TBUFF_TYPE = 0, | NULL_TBUFF_TYPE = 0, | ||||
| TBUFFTYPE1 = 1, | |||||
| TBUFFTYPE2 = 2, | |||||
| TBUFFTYPE3 = 3, | |||||
| TBUFFTYPE4 = 4, | |||||
| INVISIBLE = 5, | |||||
| TRICKER_ADD_SPEED = 1, | |||||
| SPEAR = 2, | |||||
| ADD_AP = 3, | |||||
| CLAIRAUDIENCE = 4, | |||||
| TRICKER_INVISIBLE = 5, | |||||
| TrickerBuffType_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::min(), | TrickerBuffType_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::min(), | ||||
| TrickerBuffType_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::max() | TrickerBuffType_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::max() | ||||
| }; | }; | ||||
| bool TrickerBuffType_IsValid(int value); | bool TrickerBuffType_IsValid(int value); | ||||
| constexpr TrickerBuffType TrickerBuffType_MIN = NULL_TBUFF_TYPE; | constexpr TrickerBuffType TrickerBuffType_MIN = NULL_TBUFF_TYPE; | ||||
| constexpr TrickerBuffType TrickerBuffType_MAX = INVISIBLE; | |||||
| constexpr TrickerBuffType TrickerBuffType_MAX = TRICKER_INVISIBLE; | |||||
| constexpr int TrickerBuffType_ARRAYSIZE = TrickerBuffType_MAX + 1; | constexpr int TrickerBuffType_ARRAYSIZE = TrickerBuffType_MAX + 1; | ||||
| const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* TrickerBuffType_descriptor(); | const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* TrickerBuffType_descriptor(); | ||||
| @@ -333,15 +333,16 @@ namespace protobuf | |||||
| { | { | ||||
| NULL_STUDENT_TYPE = 0, | NULL_STUDENT_TYPE = 0, | ||||
| ATHLETE = 1, | ATHLETE = 1, | ||||
| STUDENTTYPE2 = 2, | |||||
| STUDENTTYPE3 = 3, | |||||
| STUDENTTYPE4 = 4, | |||||
| TEACHER = 2, | |||||
| STRAIGHT_A_STUDENT = 3, | |||||
| ROBOT = 4, | |||||
| TECH_OTAKU = 5, | |||||
| StudentType_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::min(), | StudentType_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::min(), | ||||
| StudentType_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::max() | StudentType_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::max() | ||||
| }; | }; | ||||
| bool StudentType_IsValid(int value); | bool StudentType_IsValid(int value); | ||||
| constexpr StudentType StudentType_MIN = NULL_STUDENT_TYPE; | constexpr StudentType StudentType_MIN = NULL_STUDENT_TYPE; | ||||
| constexpr StudentType StudentType_MAX = STUDENTTYPE4; | |||||
| constexpr StudentType StudentType_MAX = TECH_OTAKU; | |||||
| constexpr int StudentType_ARRAYSIZE = StudentType_MAX + 1; | constexpr int StudentType_ARRAYSIZE = StudentType_MAX + 1; | ||||
| const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* StudentType_descriptor(); | const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* StudentType_descriptor(); | ||||
| @@ -365,8 +366,8 @@ namespace protobuf | |||||
| { | { | ||||
| NULL_TRICKER_TYPE = 0, | NULL_TRICKER_TYPE = 0, | ||||
| ASSASSIN = 1, | ASSASSIN = 1, | ||||
| TRICKERTYPE2 = 2, | |||||
| TRICKERTYPE3 = 3, | |||||
| KLEE = 2, | |||||
| A_NOISY_PERSON = 3, | |||||
| TRICKERTYPE4 = 4, | TRICKERTYPE4 = 4, | ||||
| TrickerType_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::min(), | TrickerType_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::min(), | ||||
| TrickerType_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::max() | TrickerType_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::max() | ||||
| @@ -2,6 +2,8 @@ import PyAPI.structures as THUAI6 | |||||
| from PyAPI.Interface import IStudentAPI, ITrickerAPI, IAI | from PyAPI.Interface import IStudentAPI, ITrickerAPI, IAI | ||||
| from typing import Union, Final, cast | from typing import Union, Final, cast | ||||
| import time | |||||
| class Setting: | class Setting: | ||||
| # 为假则play()期间确保游戏状态不更新,为真则只保证游戏状态在调用相关方法时不更新 | # 为假则play()期间确保游戏状态不更新,为真则只保证游戏状态在调用相关方法时不更新 | ||||
| @@ -39,20 +41,49 @@ class AssistFunction: | |||||
| return grid // numOfGridPerCell | return grid // numOfGridPerCell | ||||
| arrive: bool = False | |||||
| class AI(IAI): | class AI(IAI): | ||||
| # 选手在这里实现自己的逻辑,要求和上面选择的阵营保持一致 | # 选手在这里实现自己的逻辑,要求和上面选择的阵营保持一致 | ||||
| def StudentPlay(self, api: IStudentAPI) -> None: | def StudentPlay(self, api: IStudentAPI) -> None: | ||||
| studentSelfInfo = api.GetSelfInfo() | |||||
| if studentSelfInfo.playerID == 0: | |||||
| api.SendMessage(1, "Hello, I'm player 0 using python interface!") | |||||
| if studentSelfInfo.playerID == 1: | |||||
| api.SendMessage(0, "Hello, I'm player 1 using python interface!") | |||||
| api.Attack(float('nan')) | |||||
| time.sleep(0.5) | |||||
| api.PrintSelfInfo() | |||||
| # api.SendMessage(4, "Hello World!") | |||||
| # api.PrintSelfInfo() | |||||
| # global arrive | |||||
| # if not arrive: | |||||
| # if api.GetSelfInfo().x < 25500: | |||||
| # api.MoveDown(50) | |||||
| # return | |||||
| # if api.GetSelfInfo().y > 10500: | |||||
| # api.MoveLeft(50) | |||||
| # return | |||||
| # arrive = True | |||||
| # else: | |||||
| # api.SkipWindow() | |||||
| # # time.sleep(1) | |||||
| # api.PrintSelfInfo() | |||||
| # if api.GetSelfInfo().y < 18500: | |||||
| # api.MoveRight(50) | |||||
| # return | |||||
| # api.StartLearning() | |||||
| # if api.GetSelfInfo().y > 7000: | |||||
| # api.MoveLeft(50) | |||||
| # return | |||||
| # if api.GetSelfInfo().x > 20500: | |||||
| # api.MoveUp(50) | |||||
| # return | |||||
| # if api.GetSelfInfo().y > 4500: | |||||
| # api.MoveLeft(50) | |||||
| # return | |||||
| api.PrintTricker() | |||||
| if api.HaveMessage(): | |||||
| message = api.GetMessage() | |||||
| api.Print( | |||||
| f"Recieved Message from player {message[0]}: {message[1]}") | |||||
| return | return | ||||
| def TrickerPlay(self, api: ITrickerAPI) -> None: | def TrickerPlay(self, api: ITrickerAPI) -> None: | ||||
| @@ -2,7 +2,7 @@ import PyAPI.structures as THUAI6 | |||||
| from PyAPI.Interface import ILogic, IStudentAPI, ITrickerAPI, IGameTimer, IAI | from PyAPI.Interface import ILogic, IStudentAPI, ITrickerAPI, IGameTimer, IAI | ||||
| from math import pi | from math import pi | ||||
| from concurrent.futures import ThreadPoolExecutor, Future | from concurrent.futures import ThreadPoolExecutor, Future | ||||
| from typing import List, cast | |||||
| from typing import List, cast, Tuple | |||||
| class StudentAPI(IStudentAPI, IGameTimer): | class StudentAPI(IStudentAPI, IGameTimer): | ||||
| @@ -71,7 +71,7 @@ class StudentAPI(IStudentAPI, IGameTimer): | |||||
| def HaveMessage(self) -> bool: | def HaveMessage(self) -> bool: | ||||
| return self.__logic.HaveMessage() | return self.__logic.HaveMessage() | ||||
| def GetMessage(self) -> tuple[int, str]: | |||||
| def GetMessage(self) -> Tuple[int, str]: | |||||
| return self.__logic.GetMessage() | return self.__logic.GetMessage() | ||||
| # 等待下一帧 | # 等待下一帧 | ||||
| @@ -238,7 +238,7 @@ class TrickerAPI(ITrickerAPI, IGameTimer): | |||||
| def HaveMessage(self) -> bool: | def HaveMessage(self) -> bool: | ||||
| return self.__logic.HaveMessage() | return self.__logic.HaveMessage() | ||||
| def GetMessage(self) -> tuple[int, str]: | |||||
| def GetMessage(self) -> Tuple[int, str]: | |||||
| return self.__logic.GetMessage() | return self.__logic.GetMessage() | ||||
| # 等待下一帧 | # 等待下一帧 | ||||
| @@ -1,6 +1,6 @@ | |||||
| from math import pi | from math import pi | ||||
| from concurrent.futures import ThreadPoolExecutor, Future | from concurrent.futures import ThreadPoolExecutor, Future | ||||
| from typing import List, cast | |||||
| from typing import List, cast, Tuple | |||||
| import logging | import logging | ||||
| import os | import os | ||||
| import datetime | import datetime | ||||
| @@ -18,7 +18,7 @@ class StudentDebugAPI(IStudentAPI, IGameTimer): | |||||
| self.__logger = logging.getLogger("api " + str(playerID)) | self.__logger = logging.getLogger("api " + str(playerID)) | ||||
| self.__logger.setLevel(logging.DEBUG) | self.__logger.setLevel(logging.DEBUG) | ||||
| formatter = logging.Formatter( | formatter = logging.Formatter( | ||||
| "[%(name)s] [%(asctime)s] [%(levelname)s] %(message)s", "%H:%M:%S.%e") | |||||
| "[%(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"): | 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.makedirs(os.path.dirname(os.path.dirname( | ||||
| @@ -225,7 +225,7 @@ class StudentDebugAPI(IStudentAPI, IGameTimer): | |||||
| f"HaveMessage: failed at {self.__GetTime()}ms") | f"HaveMessage: failed at {self.__GetTime()}ms") | ||||
| return result | return result | ||||
| def GetMessage(self) -> tuple[int, str]: | |||||
| def GetMessage(self) -> Tuple[int, str]: | |||||
| self.__logger.info( | self.__logger.info( | ||||
| f"GetMessage: called at {self.__GetTime()}ms") | f"GetMessage: called at {self.__GetTime()}ms") | ||||
| result = self.__logic.GetMessage() | result = self.__logic.GetMessage() | ||||
| @@ -452,7 +452,7 @@ class TrickerDebugAPI(ITrickerAPI, IGameTimer): | |||||
| self.__logger = logging.getLogger("api " + str(playerID)) | self.__logger = logging.getLogger("api " + str(playerID)) | ||||
| self.__logger.setLevel(logging.DEBUG) | self.__logger.setLevel(logging.DEBUG) | ||||
| formatter = logging.Formatter( | formatter = logging.Formatter( | ||||
| "[%(name)s] [%(asctime)s] [%(levelname)s] %(message)s", "%H:%M:%S.%e") | |||||
| "[%(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"): | 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.makedirs(os.path.dirname(os.path.dirname( | ||||
| @@ -661,7 +661,7 @@ class TrickerDebugAPI(ITrickerAPI, IGameTimer): | |||||
| f"HaveMessage: failed at {self.__GetTime()}ms") | f"HaveMessage: failed at {self.__GetTime()}ms") | ||||
| return result | return result | ||||
| def GetMessage(self) -> tuple[int, str]: | |||||
| def GetMessage(self) -> Tuple[int, str]: | |||||
| self.__logger.info( | self.__logger.info( | ||||
| f"GetMessage: called at {self.__GetTime()}ms") | f"GetMessage: called at {self.__GetTime()}ms") | ||||
| result = self.__logic.GetMessage() | result = self.__logic.GetMessage() | ||||
| @@ -1,4 +1,4 @@ | |||||
| from typing import List, Union | |||||
| from typing import List, Union, Tuple | |||||
| from concurrent.futures import Future | from concurrent.futures import Future | ||||
| from abc import abstractmethod, ABCMeta | from abc import abstractmethod, ABCMeta | ||||
| import PyAPI.structures as THUAI6 | import PyAPI.structures as THUAI6 | ||||
| @@ -85,7 +85,7 @@ class ILogic(metaclass=ABCMeta): | |||||
| pass | pass | ||||
| @abstractmethod | @abstractmethod | ||||
| def GetMessage(self) -> tuple[int, str]: | |||||
| def GetMessage(self) -> Tuple[int, str]: | |||||
| pass | pass | ||||
| @abstractmethod | @abstractmethod | ||||
| @@ -227,7 +227,7 @@ class IAPI(metaclass=ABCMeta): | |||||
| pass | pass | ||||
| @abstractmethod | @abstractmethod | ||||
| def GetMessage(self) -> tuple[int, str]: | |||||
| def GetMessage(self) -> Tuple[int, str]: | |||||
| pass | pass | ||||
| # 等待下一帧 | # 等待下一帧 | ||||
| @@ -1,6 +1,5 @@ | |||||
| import os | import os | ||||
| from abc import abstractmethod | |||||
| from typing import List, Union, Callable | |||||
| from typing import List, Union, Callable, Tuple | |||||
| import threading | import threading | ||||
| import logging | import logging | ||||
| import proto.MessageType_pb2 as MessageType | import proto.MessageType_pb2 as MessageType | ||||
| @@ -96,6 +95,9 @@ class Logic(ILogic): | |||||
| def GetPlaceType(self, x: int, y: int) -> THUAI6.PlaceType: | def GetPlaceType(self, x: int, y: int) -> THUAI6.PlaceType: | ||||
| with self.__mtxState: | with self.__mtxState: | ||||
| if x < 0 or x >= len(self.__currentState.gameMap) or y < 0 or y >= len(self.__currentState.gameMap[0]): | |||||
| self.__logger.warning("Invalid position") | |||||
| return THUAI6.PlaceType.NullPlaceType | |||||
| self.__logger.debug("Called GetPlaceType") | self.__logger.debug("Called GetPlaceType") | ||||
| return self.__currentState.gameMap[x][y] | return self.__currentState.gameMap[x][y] | ||||
| @@ -182,7 +184,7 @@ class Logic(ILogic): | |||||
| self.__logger.debug("Called HaveMessage") | self.__logger.debug("Called HaveMessage") | ||||
| return not self.__messageQueue.empty() | return not self.__messageQueue.empty() | ||||
| def GetMessage(self) -> tuple[int, str]: | |||||
| def GetMessage(self) -> Tuple[int, str]: | |||||
| self.__logger.debug("Called GetMessage") | self.__logger.debug("Called GetMessage") | ||||
| if self.__messageQueue.empty(): | if self.__messageQueue.empty(): | ||||
| self.__logger.warning("Message queue is empty!") | self.__logger.warning("Message queue is empty!") | ||||
| @@ -544,7 +546,7 @@ class Logic(ILogic): | |||||
| # 建立日志组件 | # 建立日志组件 | ||||
| self.__logger.setLevel(logging.DEBUG) | self.__logger.setLevel(logging.DEBUG) | ||||
| formatter = logging.Formatter( | formatter = logging.Formatter( | ||||
| "[%(name)s] [%(asctime)s] [%(levelname)s] %(message)s", "%H:%M:%S.%e") | |||||
| "[%(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"): | 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.makedirs(os.path.dirname(os.path.dirname( | ||||
| @@ -26,12 +26,12 @@ def THUAI6Main(argv: List[str], AIBuilder: Callable) -> None: | |||||
| help="Server`s Port 8888 in default", dest="sPort", default="8888") | help="Server`s Port 8888 in default", dest="sPort", default="8888") | ||||
| parser.add_argument("-p", type=int, required=True, | parser.add_argument("-p", type=int, required=True, | ||||
| help="Player`s ID", dest="pID", choices=[0, 1, 2, 3, 4]) | help="Player`s ID", dest="pID", choices=[0, 1, 2, 3, 4]) | ||||
| parser.add_argument("-d", type=bool, required=False, | |||||
| help="Set this flag to save the debug log to ./logs folder", dest="file", default=False, const=True, nargs='?') | |||||
| parser.add_argument("-o", type=bool, required=False, | |||||
| help="Set this flag to print the debug log to the screen", dest="screen", default=False, const=True, nargs='?') | |||||
| parser.add_argument("-w", type=bool, required=False, | |||||
| help="Set this flag to only print warning on the screen", dest="warnOnly", default=False, const=True, nargs='?') | |||||
| parser.add_argument("-d", action='store_true', | |||||
| help="Set this flag to save the debug log to ./logs folder", dest="file") | |||||
| parser.add_argument("-o", action='store_true', | |||||
| help="Set this flag to print the debug log to the screen", dest="screen") | |||||
| parser.add_argument("-w", action='store_true', | |||||
| help="Set this flag to only print warning on the screen", dest="warnOnly") | |||||
| args = parser.parse_args() | args = parser.parse_args() | ||||
| pID = args.pID | pID = args.pID | ||||
| sIP = args.sIP | sIP = args.sIP | ||||
| @@ -39,6 +39,7 @@ def THUAI6Main(argv: List[str], AIBuilder: Callable) -> None: | |||||
| file = args.file | file = args.file | ||||
| screen = args.screen | screen = args.screen | ||||
| warnOnly = args.warnOnly | warnOnly = args.warnOnly | ||||
| print(warnOnly) | |||||
| logic = Logic(pID) | logic = Logic(pID) | ||||
| logic.Main(AIBuilder, sIP, sPort, file, screen, warnOnly) | logic.Main(AIBuilder, sIP, sPort, file, screen, warnOnly) | ||||
| @@ -1,6 +1,11 @@ | |||||
| from enum import Enum | from enum import Enum | ||||
| from typing import List, Dict, Tuple | |||||
| from typing import List, Dict | |||||
| import sys | |||||
| if sys.version_info < (3, 9): | |||||
| from typing import Tuple | |||||
| else: | |||||
| Tuple = tuple | |||||
| class GameState(Enum): | class GameState(Enum): | ||||
| NullGameState = 0 | NullGameState = 0 | ||||
| @@ -42,7 +47,7 @@ class PropType(Enum): | |||||
| Key5 = 2 | Key5 = 2 | ||||
| Key6 = 3 | Key6 = 3 | ||||
| AddSpeed = 4 | AddSpeed = 4 | ||||
| AddLifeOrAp = 5 | |||||
| AddLifeOrClairaudience = 5 | |||||
| AddHpOrAp = 6 | AddHpOrAp = 6 | ||||
| ShieldOrSpear = 7 | ShieldOrSpear = 7 | ||||
| RecoveryFromDizziness = 8 | RecoveryFromDizziness = 8 | ||||
| @@ -62,6 +67,8 @@ class StudentType(Enum): | |||||
| Athlete = 1 | Athlete = 1 | ||||
| Teacher = 2 | Teacher = 2 | ||||
| StraightAStudent = 3 | StraightAStudent = 3 | ||||
| Robot = 4 | |||||
| TechOtaku = 5 | |||||
| class TrickerType(Enum): | class TrickerType(Enum): | ||||
| @@ -200,12 +207,12 @@ class BombedBullet: | |||||
| class GameMap: | class GameMap: | ||||
| classroomState: Dict[tuple[int, int], int] = {} | |||||
| gateState: Dict[tuple[int, int], int] = {} | |||||
| chestState: Dict[tuple[int, int], int] = {} | |||||
| doorState: Dict[tuple[int, int], bool] = {} | |||||
| doorProgress: Dict[tuple[int, int], int] = {} | |||||
| hiddenGateState: Dict[tuple[int, int], HiddenGateState] = {} | |||||
| classroomState: Dict[Tuple[int, int], int] = {} | |||||
| gateState: Dict[Tuple[int, int], int] = {} | |||||
| chestState: Dict[Tuple[int, int], int] = {} | |||||
| doorState: Dict[Tuple[int, int], bool] = {} | |||||
| doorProgress: Dict[Tuple[int, int], int] = {} | |||||
| hiddenGateState: Dict[Tuple[int, int], HiddenGateState] = {} | |||||
| class GameInfo: | class GameInfo: | ||||
| @@ -90,7 +90,7 @@ class Proto2THUAI6(NoInstance): | |||||
| MessageType.KEY6: THUAI6.PropType.Key6, | MessageType.KEY6: THUAI6.PropType.Key6, | ||||
| MessageType.ADD_SPEED: THUAI6.PropType.AddSpeed, | MessageType.ADD_SPEED: THUAI6.PropType.AddSpeed, | ||||
| MessageType.ADD_HP_OR_AP: THUAI6.PropType.AddHpOrAp, | MessageType.ADD_HP_OR_AP: THUAI6.PropType.AddHpOrAp, | ||||
| MessageType.ADD_LIFE_OR_AP: THUAI6.PropType.AddLifeOrAp, | |||||
| MessageType.ADD_LIFE_OR_CLAIRAUDIENCE: THUAI6.PropType.AddLifeOrClairaudience, | |||||
| MessageType.SHIELD_OR_SPEAR: THUAI6.PropType.ShieldOrSpear, | MessageType.SHIELD_OR_SPEAR: THUAI6.PropType.ShieldOrSpear, | ||||
| MessageType.RECOVERY_FROM_DIZZINESS: THUAI6.PropType.RecoveryFromDizziness, } | MessageType.RECOVERY_FROM_DIZZINESS: THUAI6.PropType.RecoveryFromDizziness, } | ||||
| @@ -102,29 +102,31 @@ class Proto2THUAI6(NoInstance): | |||||
| studentTypeDict: Final[dict] = { | studentTypeDict: Final[dict] = { | ||||
| MessageType.NULL_STUDENT_TYPE: THUAI6.StudentType.NullStudentType, | MessageType.NULL_STUDENT_TYPE: THUAI6.StudentType.NullStudentType, | ||||
| MessageType.ATHLETE: THUAI6.StudentType.Athlete, | MessageType.ATHLETE: THUAI6.StudentType.Athlete, | ||||
| MessageType.STUDENTTYPE2: THUAI6.StudentType.Teacher, | |||||
| MessageType.STUDENTTYPE3: THUAI6.StudentType.StraightAStudent, } | |||||
| MessageType.TEACHER: THUAI6.StudentType.Teacher, | |||||
| MessageType.STRAIGHT_A_STUDENT: THUAI6.StudentType.StraightAStudent, | |||||
| MessageType.ROBOT: THUAI6.StudentType.Robot, | |||||
| MessageType.TECH_OTAKU: THUAI6.StudentType.TechOtaku, } | |||||
| trickerTypeDict: Final[dict] = { | trickerTypeDict: Final[dict] = { | ||||
| MessageType.NULL_TRICKER_TYPE: THUAI6.TrickerType.NullTrickerType, | MessageType.NULL_TRICKER_TYPE: THUAI6.TrickerType.NullTrickerType, | ||||
| MessageType.ASSASSIN: THUAI6.TrickerType.Assassin, | MessageType.ASSASSIN: THUAI6.TrickerType.Assassin, | ||||
| MessageType.TRICKERTYPE2: THUAI6.TrickerType.Klee, | |||||
| MessageType.TRICKERTYPE3: THUAI6.TrickerType.ANoisyPerson, } | |||||
| MessageType.KLEE: THUAI6.TrickerType.Klee, | |||||
| MessageType.A_NOISY_PERSON: THUAI6.TrickerType.ANoisyPerson, } | |||||
| studentBuffTypeDict: Final[dict] = { | studentBuffTypeDict: Final[dict] = { | ||||
| MessageType.NULL_SBUFF_TYPE: THUAI6.StudentBuffType.NullStudentBuffType, | MessageType.NULL_SBUFF_TYPE: THUAI6.StudentBuffType.NullStudentBuffType, | ||||
| MessageType.SBUFFTYPE1: THUAI6.StudentBuffType.AddSpeed, | |||||
| MessageType.SBUFFTYPE2: THUAI6.StudentBuffType.AddLife, | |||||
| MessageType.SBUFFTYPE3: THUAI6.StudentBuffType.Shield, | |||||
| MessageType.SBUFFTYPE4: THUAI6.StudentBuffType.Invisible, } | |||||
| MessageType.STUDENT_ADD_SPEED: THUAI6.StudentBuffType.AddSpeed, | |||||
| MessageType.ADD_LIFE: THUAI6.StudentBuffType.AddLife, | |||||
| MessageType.SHIELD: THUAI6.StudentBuffType.Shield, | |||||
| MessageType.STUDENT_INVISIBLE: THUAI6.StudentBuffType.Invisible, } | |||||
| trickerBuffTypeDict: Final[dict] = { | trickerBuffTypeDict: Final[dict] = { | ||||
| MessageType.NULL_TBUFF_TYPE: THUAI6.TrickerBuffType.NullTrickerBuffType, | MessageType.NULL_TBUFF_TYPE: THUAI6.TrickerBuffType.NullTrickerBuffType, | ||||
| MessageType.TBUFFTYPE1: THUAI6.TrickerBuffType.AddSpeed, | |||||
| MessageType.TBUFFTYPE2: THUAI6.TrickerBuffType.Spear, | |||||
| MessageType.TBUFFTYPE3: THUAI6.TrickerBuffType.AddAp, | |||||
| MessageType.TBUFFTYPE4: THUAI6.TrickerBuffType.Clairaudience, | |||||
| MessageType.INVISIBLE: THUAI6.TrickerBuffType.Invisible, } | |||||
| MessageType.TRICKER_ADD_SPEED: THUAI6.TrickerBuffType.AddSpeed, | |||||
| MessageType.SPEAR: THUAI6.TrickerBuffType.Spear, | |||||
| MessageType.ADD_AP: THUAI6.TrickerBuffType.AddAp, | |||||
| MessageType.CLAIRAUDIENCE: THUAI6.TrickerBuffType.Clairaudience, | |||||
| MessageType.TRICKER_INVISIBLE: THUAI6.TrickerBuffType.Invisible, } | |||||
| playerStateDict: Final[dict] = { | playerStateDict: Final[dict] = { | ||||
| MessageType.NULL_STATUS: THUAI6.PlayerState.NullState, | MessageType.NULL_STATUS: THUAI6.PlayerState.NullState, | ||||
| @@ -156,9 +158,9 @@ class Proto2THUAI6(NoInstance): | |||||
| bulletTypeDict: Final[dict] = { | bulletTypeDict: Final[dict] = { | ||||
| MessageType.NULL_BULLET_TYPE: THUAI6.BulletType.NullBulletType, | MessageType.NULL_BULLET_TYPE: THUAI6.BulletType.NullBulletType, | ||||
| MessageType.FLYING_KNIFE: THUAI6.BulletType.FlyingKnife, | MessageType.FLYING_KNIFE: THUAI6.BulletType.FlyingKnife, | ||||
| MessageType.FAST_BULLET: THUAI6.BulletType.BombBomb, | |||||
| MessageType.BOMB_BOMB: THUAI6.BulletType.BombBomb, | |||||
| MessageType.COMMON_ATTACK_OF_TRICKER: THUAI6.BulletType.CommonAttackOfTricker, | MessageType.COMMON_ATTACK_OF_TRICKER: THUAI6.BulletType.CommonAttackOfTricker, | ||||
| MessageType.ORDINARY_BULLET: THUAI6.BulletType.JumpyDumpty, | |||||
| MessageType.JUMPY_DUMPTY: THUAI6.BulletType.JumpyDumpty, | |||||
| MessageType.ATOM_BOMB: THUAI6.BulletType.AtomBomb, } | MessageType.ATOM_BOMB: THUAI6.BulletType.AtomBomb, } | ||||
| # 用于将Proto的对象转为THUAI6的对象 | # 用于将Proto的对象转为THUAI6的对象 | ||||
| @@ -303,14 +305,16 @@ class THUAI62Proto(NoInstance): | |||||
| studentTypeDict: Final[dict] = { | studentTypeDict: Final[dict] = { | ||||
| THUAI6.StudentType.NullStudentType: MessageType.NULL_STUDENT_TYPE, | THUAI6.StudentType.NullStudentType: MessageType.NULL_STUDENT_TYPE, | ||||
| THUAI6.StudentType.Athlete: MessageType.ATHLETE, | THUAI6.StudentType.Athlete: MessageType.ATHLETE, | ||||
| THUAI6.StudentType.Teacher: MessageType.STUDENTTYPE2, | |||||
| THUAI6.StudentType.StraightAStudent: MessageType.STUDENTTYPE3, } | |||||
| THUAI6.StudentType.Teacher: MessageType.TEACHER, | |||||
| THUAI6.StudentType.StraightAStudent: MessageType.STRAIGHT_A_STUDENT, | |||||
| THUAI6.StudentType.Robot: MessageType.ROBOT, | |||||
| THUAI6.StudentType.TechOtaku: MessageType.TECH_OTAKU, } | |||||
| trickerTypeDict: Final[dict] = { | trickerTypeDict: Final[dict] = { | ||||
| THUAI6.TrickerType.NullTrickerType: MessageType.NULL_TRICKER_TYPE, | THUAI6.TrickerType.NullTrickerType: MessageType.NULL_TRICKER_TYPE, | ||||
| THUAI6.TrickerType.Assassin: MessageType.ASSASSIN, | THUAI6.TrickerType.Assassin: MessageType.ASSASSIN, | ||||
| THUAI6.TrickerType.Klee: MessageType.TRICKERTYPE2, | |||||
| THUAI6.TrickerType.ANoisyPerson: MessageType.TRICKERTYPE3, } | |||||
| THUAI6.TrickerType.Klee: MessageType.KLEE, | |||||
| THUAI6.TrickerType.ANoisyPerson: MessageType.A_NOISY_PERSON, } | |||||
| propTypeDict: Final[dict] = { | propTypeDict: Final[dict] = { | ||||
| THUAI6.PropType.NullPropType: MessageType.NULL_PROP_TYPE, | THUAI6.PropType.NullPropType: MessageType.NULL_PROP_TYPE, | ||||
| @@ -318,7 +322,7 @@ class THUAI62Proto(NoInstance): | |||||
| THUAI6.PropType.Key5: MessageType.KEY5, | THUAI6.PropType.Key5: MessageType.KEY5, | ||||
| THUAI6.PropType.Key6: MessageType.KEY6, | THUAI6.PropType.Key6: MessageType.KEY6, | ||||
| THUAI6.PropType.AddHpOrAp: MessageType.ADD_HP_OR_AP, | THUAI6.PropType.AddHpOrAp: MessageType.ADD_HP_OR_AP, | ||||
| THUAI6.PropType.AddLifeOrAp: MessageType.ADD_LIFE_OR_AP, | |||||
| THUAI6.PropType.AddLifeOrClairaudience: MessageType.ADD_LIFE_OR_CLAIRAUDIENCE, | |||||
| THUAI6.PropType.AddSpeed: MessageType.ADD_SPEED, | THUAI6.PropType.AddSpeed: MessageType.ADD_SPEED, | ||||
| THUAI6.PropType.ShieldOrSpear: MessageType.SHIELD_OR_SPEAR, } | THUAI6.PropType.ShieldOrSpear: MessageType.SHIELD_OR_SPEAR, } | ||||
| @@ -0,0 +1,12 @@ | |||||
| #!/usr/bin/env bash | |||||
| python3 -m pip install -r requirements.txt | |||||
| mkdir -p proto | |||||
| python3 -m grpc_tools.protoc -I../../dependency/proto/ --python_out=./proto --pyi_out=./proto MessageType.proto | |||||
| python3 -m grpc_tools.protoc -I../../dependency/proto/ --python_out=./proto --pyi_out=./proto Message2Clients.proto | |||||
| python3 -m grpc_tools.protoc -I../../dependency/proto/ --python_out=./proto --pyi_out=./proto Message2Server.proto | |||||
| python3 -m grpc_tools.protoc -I../../dependency/proto/ --python_out=./proto --pyi_out=./proto --grpc_python_out=./proto Services.proto | |||||
| @@ -1,2 +1,2 @@ | |||||
| grpcio==1.53.0 | |||||
| grpcio-tools==1.53.0 | |||||
| grpcio==1.52.0 | |||||
| grpcio-tools==1.52.0 | |||||
| @@ -1,2 +1,4 @@ | |||||
| #!/usr/bin/env bash | |||||
| python PyAPI/main.py -I 172.22.32.1 -P 8888 -p 0 -d -o & | python PyAPI/main.py -I 172.22.32.1 -P 8888 -p 0 -d -o & | ||||
| python PyAPI/main.py -I 172.22.32.1 -P 8888 -p 1 -d -o & | |||||
| # python PyAPI/main.py -I 172.22.32.1 -P 8888 -p 1 -d -o & | |||||
| @@ -61,12 +61,29 @@ | |||||
| <TextBlock Grid.Row="6" Grid.Column="1" Text="用户名或密码错误!" Visibility="{Binding LoginFailVis}"/> | <TextBlock Grid.Row="6" Grid.Column="1" Text="用户名或密码错误!" Visibility="{Binding LoginFailVis}"/> | ||||
| <TextBlock Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2" Text="你有已完成的比赛!" Visibility="{Binding MatchFinishedVis}"/> | <TextBlock Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2" Text="你有已完成的比赛!" Visibility="{Binding MatchFinishedVis}"/> | ||||
| <Button Grid.Row="3" Grid.Column="1" Name ="Upload" Content="上传代码" Command="{Binding ClickUploadCommand}" Visibility="{Binding WebVis}"/> | |||||
| <Button Grid.Row="5" Grid.Column="1" Name="Download" Content="下载回放" Command="{Binding ClickDownloadCommand}" Visibility="{Binding WebVis}" /> | |||||
| <Button Grid.Row="7" Grid.Column="1" Name="Replay" Content="打开回放" Command="{Binding ClickReplayCommand}" Visibility="{Binding WebVis}" /> | |||||
| <Button Grid.Row="3" Grid.Column="3" Grid.ColumnSpan="2" Content="申请对战" Command="{Binding ClickRequestCommand}" Visibility="{Binding WebVis}" /> | |||||
| <TextBox Grid.Row="4" Grid.Column="3" Grid.ColumnSpan="2" Text="{Binding Enemy}" Visibility="{Binding WebVis}" /> | |||||
| <Button Grid.Row="3" Grid.Column="1" Name ="Upload" Content="{Binding UploadBtnCont}" Command="{Binding ClickUploadCommand}" Visibility="{Binding WebVis}"/> | |||||
| <TextBlock Grid.Row="4" Grid.Column="1" Grid.ColumnSpan="2" Text="{Binding CodeName}" Visibility="{Binding UploadReadyVis}" /> | |||||
| <Button Grid.Row="3" Grid.Column="2" Name="ReUpload" Content="重新选择代码" Command="{Binding ReselectCommand}" Visibility="{Binding UploadReadyVis}" /> | |||||
| <Button Grid.Row="6" Grid.Column="3" Grid.ColumnSpan="2" Content="退出登录" Command="{Binding ClickBackCommand}" Visibility="{Binding WebVis}" /> | <Button Grid.Row="6" Grid.Column="3" Grid.ColumnSpan="2" Content="退出登录" Command="{Binding ClickBackCommand}" Visibility="{Binding WebVis}" /> | ||||
| <!--objects below are not enabled--> | |||||
| <Button Grid.Row="5" Grid.Column="1" Name="Download" Content="下载回放" IsEnabled="False" Command="{Binding ClickDownloadCommand}" Visibility="{Binding CoverVis}" /> | |||||
| <Button Grid.Row="7" Grid.Column="1" Name="Replay" Content="打开回放" IsEnabled="False" Command="{Binding ClickReplayCommand}" Visibility="{Binding CoverVis}" /> | |||||
| <Button Grid.Row="3" Grid.Column="3" Grid.ColumnSpan="2" Content="申请对战" IsEnabled="False" Command="{Binding ClickRequestCommand}" Visibility="{Binding WebVis}" /> | |||||
| <TextBox Grid.Row="4" Grid.Column="3" Grid.ColumnSpan="2" Text="暂不支持" IsEnabled="False" Visibility="{Binding WebVis}" /> | |||||
| <StackPanel Grid.Row="5" Grid.Column="1" Grid.RowSpan="3" Grid.ColumnSpan="2"> | |||||
| <Grid> | |||||
| <Grid.RowDefinitions> | |||||
| <RowDefinition Height="15"/> | |||||
| <RowDefinition Height="15"/> | |||||
| <RowDefinition Height="15"/> | |||||
| <RowDefinition Height="15"/> | |||||
| </Grid.RowDefinitions> | |||||
| <RadioButton GroupName="playerNum" Grid.Row="0" Visibility="{Binding UploadReadyVis}">玩家1</RadioButton> | |||||
| <RadioButton GroupName="playerNum" Grid.Row="1" Visibility="{Binding UploadReadyVis}">玩家2</RadioButton> | |||||
| <RadioButton GroupName="playerNum" Grid.Row="2" Visibility="{Binding UploadReadyVis}">玩家3</RadioButton> | |||||
| <RadioButton GroupName="playerNum" Grid.Row="3" Visibility="{Binding UploadReadyVis}">玩家4</RadioButton> | |||||
| </Grid> | |||||
| </StackPanel> | |||||
| </Grid> | </Grid> | ||||
| </Window> | </Window> | ||||
| @@ -48,6 +48,9 @@ namespace starter.viewmodel.settings | |||||
| Username = ""; | Username = ""; | ||||
| Password = ""; | Password = ""; | ||||
| updates = ""; | updates = ""; | ||||
| CodeRoute = ""; | |||||
| UploadReady = false; | |||||
| LoginFailed = false; | |||||
| } | } | ||||
| /// <summary> | /// <summary> | ||||
| @@ -58,11 +61,11 @@ namespace starter.viewmodel.settings | |||||
| if (Tencent_cos_download.CheckAlreadyDownload()) | if (Tencent_cos_download.CheckAlreadyDownload()) | ||||
| { | { | ||||
| MessageBoxResult repeatOption = MessageBox.Show($"文件已存在于{Downloader.Program.Data.FilePath},是否移动到新位置?", "重复安装", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No); | MessageBoxResult repeatOption = MessageBox.Show($"文件已存在于{Downloader.Program.Data.FilePath},是否移动到新位置?", "重复安装", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No); | ||||
| // ask if abort install, with warning sign, defalut no; | |||||
| // ask if abort install, with warning sign, defalut move instead of abort; | |||||
| if (repeatOption == MessageBoxResult.No) | if (repeatOption == MessageBoxResult.No) | ||||
| { | { | ||||
| Route = Data.FilePath; | Route = Data.FilePath; | ||||
| return false; // 回到选择地址界面 | |||||
| return false; | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| @@ -120,9 +123,9 @@ namespace starter.viewmodel.settings | |||||
| } | } | ||||
| } | } | ||||
| public void Login() | |||||
| public async Task<bool> Login() | |||||
| { | { | ||||
| _ = web.LoginToEEsast(client, Username, Password); | |||||
| return await web.LoginToEEsast(client, Username, Password); | |||||
| } | } | ||||
| public bool Update() | public bool Update() | ||||
| { | { | ||||
| @@ -146,6 +149,25 @@ namespace starter.viewmodel.settings | |||||
| return false; | return false; | ||||
| } | } | ||||
| } | } | ||||
| public async Task<int> Upload() | |||||
| { | |||||
| switch (CodeRoute.Substring(CodeRoute.LastIndexOf('.') + 1)) | |||||
| { | |||||
| case "cpp": | |||||
| Language = "cpp"; | |||||
| break; | |||||
| case "h": | |||||
| Language = "cpp"; | |||||
| break; | |||||
| case "py": | |||||
| Language = "python"; | |||||
| break; | |||||
| default: | |||||
| return -8; | |||||
| } | |||||
| return await web.UploadFiles(client, CodeRoute, Language, "player_1"); | |||||
| } | |||||
| /// <summary> | /// <summary> | ||||
| /// Route of files | /// Route of files | ||||
| /// </summary> | /// </summary> | ||||
| @@ -162,6 +184,18 @@ namespace starter.viewmodel.settings | |||||
| { | { | ||||
| get; set; | get; set; | ||||
| } | } | ||||
| public string CodeRoute | |||||
| { | |||||
| get; set; | |||||
| } | |||||
| public string Language | |||||
| { | |||||
| get; set; | |||||
| } | |||||
| public string PlayerNum | |||||
| { | |||||
| get; set; | |||||
| } | |||||
| /// <summary> | /// <summary> | ||||
| /// 关于更新的屏幕显示信息 | /// 关于更新的屏幕显示信息 | ||||
| /// </summary> | /// </summary> | ||||
| @@ -212,6 +246,11 @@ namespace starter.viewmodel.settings | |||||
| { | { | ||||
| get; set; | get; set; | ||||
| } | } | ||||
| public bool UploadReady | |||||
| { | |||||
| get; set; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| namespace Downloader | namespace Downloader | ||||
| @@ -355,8 +394,8 @@ namespace Downloader | |||||
| .Build(); // 创建 CosXmlConfig 对象 | .Build(); // 创建 CosXmlConfig 对象 | ||||
| // 永久密钥访问凭证 | // 永久密钥访问凭证 | ||||
| string secretId = "***"; //"云 API 密钥 SecretId"; | |||||
| string secretKey = "***"; //"云 API 密钥 SecretKey"; | |||||
| string secretId = "***"; //"云 API 密钥 SecretId"; | |||||
| string secretKey = "***"; //"云 API 密钥 SecretKey"; | |||||
| long durationSecond = 1000; // 每次请求签名有效时长,单位为秒 | long durationSecond = 1000; // 每次请求签名有效时长,单位为秒 | ||||
| QCloudCredentialProvider cosCredentialProvider = new DefaultQCloudCredentialProvider( | QCloudCredentialProvider cosCredentialProvider = new DefaultQCloudCredentialProvider( | ||||
| @@ -997,7 +1036,7 @@ namespace Downloader | |||||
| } | } | ||||
| else if (choose == "9") | else if (choose == "9") | ||||
| { | { | ||||
| await web.UploadFiles(client); | |||||
| await web.UploadFiles(client, "", "", ""); | |||||
| } | } | ||||
| else if (choose == "exit") | else if (choose == "exit") | ||||
| { | { | ||||
| @@ -1013,8 +1052,9 @@ namespace WebConnect | |||||
| { | { | ||||
| class Web | class Web | ||||
| { | { | ||||
| public enum language { cpp, py }; | |||||
| public static string logintoken = ""; | public static string logintoken = ""; | ||||
| async public Task LoginToEEsast(HttpClient client, string useremail, string password) | |||||
| async public Task<bool> LoginToEEsast(HttpClient client, string useremail, string password) | |||||
| { | { | ||||
| string token = ""; | string token = ""; | ||||
| using (var response = await client.PostAsync("https://api.eesast.com/users/login", JsonContent.Create(new | using (var response = await client.PostAsync("https://api.eesast.com/users/login", JsonContent.Create(new | ||||
| @@ -1045,70 +1085,41 @@ namespace WebConnect | |||||
| Console.WriteLine(code); | Console.WriteLine(code); | ||||
| if (code == 401) | if (code == 401) | ||||
| { | { | ||||
| Console.WriteLine("邮箱或密码错误!"); | |||||
| //Console.WriteLine("邮箱或密码错误!"); | |||||
| return false; | |||||
| } | } | ||||
| return; | |||||
| break; | |||||
| } | } | ||||
| return true; | |||||
| } | } | ||||
| } | } | ||||
| async public Task UploadFiles(HttpClient client) //用来上传文件 | |||||
| /// <summary> | |||||
| /// | |||||
| /// </summary> | |||||
| /// <param name="client">http client</param> | |||||
| /// <param name="tarfile">代码源位置</param> | |||||
| /// <param name="type">编程语言,格式为"cpp"或"python"</param> | |||||
| /// <param name="plr">第x位玩家,格式为"player_x"</param> | |||||
| /// <returns>-1:tokenFail;-2:FileNotExist;-3:CosFail;-4:loginTimeout;-5:Fail;-6:ReadFileFail;-7:networkError</returns> | |||||
| async public Task<int> UploadFiles(HttpClient client, string tarfile, string type, string plr) //用来上传文件 | |||||
| { | { | ||||
| if (!ReadToken()) //读取token失败 | if (!ReadToken()) //读取token失败 | ||||
| { | { | ||||
| return; | |||||
| return -1; | |||||
| } | } | ||||
| try | try | ||||
| { | { | ||||
| string tarfile; //要上传的文件路径 | |||||
| string content; | string content; | ||||
| client.DefaultRequestHeaders.Authorization = new("Bearer", logintoken); | client.DefaultRequestHeaders.Authorization = new("Bearer", logintoken); | ||||
| Console.WriteLine("请输入要上传的文件完整路径:"); | |||||
| tarfile = Console.ReadLine(); | |||||
| if (!File.Exists(tarfile)) | if (!File.Exists(tarfile)) | ||||
| { | { | ||||
| Console.WriteLine("文件不存在!"); | |||||
| return; | |||||
| } | |||||
| Console.WriteLine("请选择语言类型:1.C++ 2.python"); | |||||
| string type = Console.ReadLine(); | |||||
| if (type == "1") | |||||
| { | |||||
| type = "cpp"; | |||||
| } | |||||
| else if (type == "2") | |||||
| { | |||||
| type = "python"; | |||||
| } | |||||
| else | |||||
| { | |||||
| return; | |||||
| } | |||||
| Console.WriteLine("请确认这是哪个玩家的代码:1.player_1 2.player_2 3.player_3 4.player_4"); | |||||
| string plr = Console.ReadLine(); | |||||
| if (plr == "1") | |||||
| { | |||||
| plr = "player_1"; | |||||
| } | |||||
| else if (plr == "2") | |||||
| { | |||||
| plr = "player_2"; | |||||
| } | |||||
| else if (plr == "3") | |||||
| { | |||||
| plr = "player_3"; | |||||
| } | |||||
| else if (plr == "4") | |||||
| { | |||||
| plr = "player_4"; | |||||
| } | |||||
| else | |||||
| { | |||||
| return; | |||||
| //Console.WriteLine("文件不存在!"); | |||||
| return -2; | |||||
| } | } | ||||
| using FileStream fs = new FileStream(tarfile, FileMode.Open, FileAccess.Read); | using FileStream fs = new FileStream(tarfile, FileMode.Open, FileAccess.Read); | ||||
| using StreamReader sr = new StreamReader(fs); | using StreamReader sr = new StreamReader(fs); | ||||
| content = sr.ReadToEnd(); | content = sr.ReadToEnd(); | ||||
| using (var response = await client.GetAsync($"https://api.eesast.com/static/player?team_id={GetTeamId()}")) | |||||
| using (var response = await client.GetAsync($"https://api.eesast.com/static/player?team_id={await GetTeamId()}")) | |||||
| { | { | ||||
| switch (response.StatusCode) | switch (response.StatusCode) | ||||
| { | { | ||||
| @@ -1161,27 +1172,30 @@ namespace WebConnect | |||||
| } | } | ||||
| catch (Exception e) | catch (Exception e) | ||||
| { | { | ||||
| Console.WriteLine("CosException: " + e); | |||||
| return -3; | |||||
| } | } | ||||
| break; | break; | ||||
| case System.Net.HttpStatusCode.Unauthorized: | case System.Net.HttpStatusCode.Unauthorized: | ||||
| Console.WriteLine("您未登录或登录过期,请先登录"); | |||||
| break; | |||||
| //Console.WriteLine("您未登录或登录过期,请先登录"); | |||||
| return -4; | |||||
| default: | default: | ||||
| Console.WriteLine("上传失败!"); | |||||
| break; | |||||
| //Console.WriteLine("上传失败!"); | |||||
| return -5; | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| catch (IOException) | catch (IOException) | ||||
| { | { | ||||
| Console.WriteLine("文件读取错误!请检查文件是否被其它应用占用!"); | |||||
| //Console.WriteLine("文件读取错误!请检查文件是否被其它应用占用!"); | |||||
| return -6; | |||||
| } | } | ||||
| catch | catch | ||||
| { | { | ||||
| Console.WriteLine("请求错误!请检查网络连接!"); | |||||
| //Console.WriteLine("请求错误!请检查网络连接!"); | |||||
| return -7; | |||||
| } | } | ||||
| return 0; | |||||
| } | } | ||||
| async public Task UserDetails(HttpClient client) // 用来测试访问网站 | async public Task UserDetails(HttpClient client) // 用来测试访问网站 | ||||
| @@ -1237,6 +1251,10 @@ namespace WebConnect | |||||
| json += @"{""THUAI6""" + ":" + @"""2023""}"; | json += @"{""THUAI6""" + ":" + @"""2023""}"; | ||||
| } | } | ||||
| dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(json); | dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(json); | ||||
| if (dict.ContainsKey("token")) | |||||
| { | |||||
| dict.Remove("token"); | |||||
| } | |||||
| dict?.Add("token", logintoken); | dict?.Add("token", logintoken); | ||||
| } | } | ||||
| using FileStream fs2 = new FileStream(savepath, FileMode.OpenOrCreate, FileAccess.ReadWrite); | using FileStream fs2 = new FileStream(savepath, FileMode.OpenOrCreate, FileAccess.ReadWrite); | ||||
| @@ -20,6 +20,7 @@ namespace starter.viewmodel.settings | |||||
| /// </summary> | /// </summary> | ||||
| public SettingsViewModel() | public SettingsViewModel() | ||||
| { | { | ||||
| //Program.Tencent_cos_download.UpdateHash(); | |||||
| if (Downloader.Program.Tencent_cos_download.CheckAlreadyDownload()) | if (Downloader.Program.Tencent_cos_download.CheckAlreadyDownload()) | ||||
| { | { | ||||
| obj.checkUpdate(); | obj.checkUpdate(); | ||||
| @@ -135,10 +136,7 @@ namespace starter.viewmodel.settings | |||||
| public string Route | public string Route | ||||
| { | { | ||||
| get | |||||
| { | |||||
| return obj.Route; | |||||
| } | |||||
| get => obj.Route; | |||||
| set | set | ||||
| { | { | ||||
| obj.Route = value; | obj.Route = value; | ||||
| @@ -147,10 +145,7 @@ namespace starter.viewmodel.settings | |||||
| } | } | ||||
| public string Username | public string Username | ||||
| { | { | ||||
| get | |||||
| { | |||||
| return obj.Username; | |||||
| } | |||||
| get => obj.Username; | |||||
| set | set | ||||
| { | { | ||||
| obj.Username = value; | obj.Username = value; | ||||
| @@ -159,13 +154,20 @@ namespace starter.viewmodel.settings | |||||
| } | } | ||||
| public string Password | public string Password | ||||
| { | { | ||||
| get { return obj.Password; } | |||||
| get => obj.Password; | |||||
| set | set | ||||
| { | { | ||||
| obj.Password = value; | obj.Password = value; | ||||
| this.RaisePropertyChanged("Password"); | this.RaisePropertyChanged("Password"); | ||||
| } | } | ||||
| } | } | ||||
| public string CodeName | |||||
| { | |||||
| get | |||||
| { | |||||
| return obj.CodeRoute.Substring(obj.CodeRoute.LastIndexOf('/') == -1 ? obj.CodeRoute.LastIndexOf('\\') + 1 : obj.CodeRoute.LastIndexOf('/') + 1); | |||||
| } | |||||
| } | |||||
| public Visibility MenuVis | public Visibility MenuVis | ||||
| { | { | ||||
| get | get | ||||
| @@ -208,6 +210,13 @@ namespace starter.viewmodel.settings | |||||
| return Status == SettingsModel.Status.web ? Visibility.Visible : Visibility.Collapsed; | return Status == SettingsModel.Status.web ? Visibility.Visible : Visibility.Collapsed; | ||||
| } | } | ||||
| } | } | ||||
| public Visibility CoverVis | |||||
| { | |||||
| get | |||||
| { | |||||
| return Status == SettingsModel.Status.web && !obj.UploadReady ? Visibility.Visible : Visibility.Collapsed; | |||||
| } | |||||
| } | |||||
| public Visibility LoginFailVis | public Visibility LoginFailVis | ||||
| { | { | ||||
| get | get | ||||
| @@ -222,6 +231,10 @@ namespace starter.viewmodel.settings | |||||
| return obj.CombatCompleted ? Visibility.Visible : Visibility.Collapsed; | return obj.CombatCompleted ? Visibility.Visible : Visibility.Collapsed; | ||||
| } | } | ||||
| } | } | ||||
| public Visibility UploadReadyVis | |||||
| { | |||||
| get { return obj.UploadReady ? Visibility.Visible : Visibility.Collapsed; } | |||||
| } | |||||
| public string UpdateBtnCont | public string UpdateBtnCont | ||||
| { | { | ||||
| @@ -247,6 +260,39 @@ namespace starter.viewmodel.settings | |||||
| return obj.UpdatePlanned ? "更新" : "启动"; | return obj.UpdatePlanned ? "更新" : "启动"; | ||||
| } | } | ||||
| } | } | ||||
| public string UploadBtnCont | |||||
| { | |||||
| get | |||||
| { | |||||
| return obj.UploadReady ? "上传代码" : "选择代码上传"; | |||||
| } | |||||
| } | |||||
| public string RouteSelectWindow(string type) | |||||
| { | |||||
| if (type == "Folder") | |||||
| { | |||||
| using (FolderBrowserDialog dialog = new FolderBrowserDialog()) | |||||
| { | |||||
| _ = dialog.ShowDialog(); | |||||
| if (dialog.SelectedPath != String.Empty) | |||||
| return dialog.SelectedPath; | |||||
| } | |||||
| } | |||||
| else if (type == "File") | |||||
| { | |||||
| var openFileDialog = new Microsoft.Win32.OpenFileDialog() | |||||
| { | |||||
| Filter = "c++ Source Files (.cpp)|*.cpp|c++ Header File (.h)|*.h|python Source File (.py)|*.py" | |||||
| }; | |||||
| var result = openFileDialog.ShowDialog(); | |||||
| if (result == true) | |||||
| { | |||||
| return openFileDialog.FileName; | |||||
| } | |||||
| } | |||||
| return ""; | |||||
| } | |||||
| private BaseCommand clickBrowseCommand; | private BaseCommand clickBrowseCommand; | ||||
| public BaseCommand ClickBrowseCommand | public BaseCommand ClickBrowseCommand | ||||
| @@ -257,12 +303,7 @@ namespace starter.viewmodel.settings | |||||
| { | { | ||||
| clickBrowseCommand = new BaseCommand(new Action<object>(o => | clickBrowseCommand = new BaseCommand(new Action<object>(o => | ||||
| { | { | ||||
| using (FolderBrowserDialog dialog = new FolderBrowserDialog()) | |||||
| { | |||||
| _ = dialog.ShowDialog(); | |||||
| if (dialog.SelectedPath != String.Empty) | |||||
| Route = dialog.SelectedPath; | |||||
| } | |||||
| Route = RouteSelectWindow("Folder"); | |||||
| })); | })); | ||||
| } | } | ||||
| return clickBrowseCommand; | return clickBrowseCommand; | ||||
| @@ -397,9 +438,16 @@ namespace starter.viewmodel.settings | |||||
| { | { | ||||
| if (clickLoginCommand == null) | if (clickLoginCommand == null) | ||||
| { | { | ||||
| clickLoginCommand = new BaseCommand(new Action<object>(o => | |||||
| clickLoginCommand = new BaseCommand(new Action<object>(async o => | |||||
| { | { | ||||
| obj.Login(); | |||||
| if (!(await obj.Login())) | |||||
| { | |||||
| obj.LoginFailed = true; | |||||
| } | |||||
| else | |||||
| { | |||||
| Status = SettingsModel.Status.web; | |||||
| } | |||||
| this.RaisePropertyChanged("LoginFailVis"); | this.RaisePropertyChanged("LoginFailVis"); | ||||
| })); | })); | ||||
| } | } | ||||
| @@ -469,5 +517,70 @@ namespace starter.viewmodel.settings | |||||
| return clickBackCommand; | return clickBackCommand; | ||||
| } | } | ||||
| } | } | ||||
| private BaseCommand clickUploadCommand; | |||||
| public BaseCommand ClickUploadCommand | |||||
| { | |||||
| get | |||||
| { | |||||
| if (clickUploadCommand == null) | |||||
| { | |||||
| clickUploadCommand = new BaseCommand(new Action<object>(async o => | |||||
| { | |||||
| if (obj.UploadReady) | |||||
| { | |||||
| switch (await obj.Upload()) | |||||
| { | |||||
| case -1: | |||||
| MessageBox.Show("Token失效!", "", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK); | |||||
| break; | |||||
| case -2: | |||||
| MessageBox.Show("目标路径不存在!", "", MessageBoxButton.OK, MessageBoxImage.Warning, MessageBoxResult.OK); | |||||
| break; | |||||
| case -3: | |||||
| MessageBox.Show("服务器错误", "", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK); | |||||
| break; | |||||
| case -4: | |||||
| MessageBox.Show("您未登录或登录失效", "", MessageBoxButton.OK, MessageBoxImage.Warning, MessageBoxResult.OK); | |||||
| Status = SettingsModel.Status.login; | |||||
| break; | |||||
| case -5: | |||||
| MessageBox.Show("您未报名THUAI!", "", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK); | |||||
| break; | |||||
| case -6: | |||||
| MessageBox.Show("读取文件失败,请确认文件是否被占用", "", MessageBoxButton.OK, MessageBoxImage.Warning, MessageBoxResult.OK); | |||||
| break; | |||||
| case -7: | |||||
| MessageBox.Show("网络错误,请检查你的网络", "", MessageBoxButton.OK, MessageBoxImage.Warning, MessageBoxResult.OK); | |||||
| break; | |||||
| case -8: | |||||
| MessageBox.Show("不是c++或python源文件", "", MessageBoxButton.OK, MessageBoxImage.Warning, MessageBoxResult.OK); | |||||
| break; | |||||
| } | |||||
| obj.CodeRoute = ""; | |||||
| obj.UploadReady = false; | |||||
| this.RaisePropertyChanged("UploadBtnCont"); | |||||
| this.RaisePropertyChanged("UploadReadyVis"); | |||||
| } | |||||
| else | |||||
| { | |||||
| obj.CodeRoute = RouteSelectWindow("File"); | |||||
| if (obj.CodeRoute != "") | |||||
| { | |||||
| obj.UploadReady = true; | |||||
| this.RaisePropertyChanged("UploadBtnCont"); | |||||
| this.RaisePropertyChanged("UploadReadyVis"); | |||||
| this.RaisePropertyChanged("CodeName"); | |||||
| } | |||||
| else | |||||
| { | |||||
| MessageBox.Show("未选择代码,请重新选择!", "", MessageBoxButton.OK, MessageBoxImage.Warning, MessageBoxResult.OK); | |||||
| } | |||||
| } | |||||
| })); | |||||
| } | |||||
| return clickUploadCommand; | |||||
| } | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -1030,6 +1030,7 @@ namespace Client | |||||
| TreatAndRescueMsg msgR = new() | TreatAndRescueMsg msgR = new() | ||||
| { | { | ||||
| PlayerId = playerID, | PlayerId = playerID, | ||||
| ToPlayerId = -1, | |||||
| }; | }; | ||||
| client.StartRescueMate(msgR); | client.StartRescueMate(msgR); | ||||
| break; | break; | ||||
| @@ -1037,6 +1038,7 @@ namespace Client | |||||
| TreatAndRescueMsg msgT = new() | TreatAndRescueMsg msgT = new() | ||||
| { | { | ||||
| PlayerId = playerID, | PlayerId = playerID, | ||||
| ToPlayerId = -1, | |||||
| }; | }; | ||||
| client.StartTreatMate(msgT); | client.StartTreatMate(msgT); | ||||
| break; | break; | ||||
| @@ -202,8 +202,6 @@ namespace Gaming | |||||
| playerTreated.HP == playerTreated.MaxHp || !GameData.ApproachToInteract(playerTreated.Position, player.Position)) | playerTreated.HP == playerTreated.MaxHp || !GameData.ApproachToInteract(playerTreated.Position, player.Position)) | ||||
| return false; | return false; | ||||
| Preparation.Utility.Debugger.Output(player, "treat " + playerTreated.ToString()); | |||||
| if (playerTreated.HP + playerTreated.DegreeOfTreatment >= playerTreated.MaxHp) | if (playerTreated.HP + playerTreated.DegreeOfTreatment >= playerTreated.MaxHp) | ||||
| { | { | ||||
| playerTreated.HP = playerTreated.MaxHp; | playerTreated.HP = playerTreated.MaxHp; | ||||
| @@ -201,8 +201,8 @@ namespace Server | |||||
| MessageOfAll msg = new MessageOfAll(); | MessageOfAll msg = new MessageOfAll(); | ||||
| //msg.GameTime | //msg.GameTime | ||||
| msg.SubjectFinished = (int)game.GameMap.NumOfRepairedGenerators; | msg.SubjectFinished = (int)game.GameMap.NumOfRepairedGenerators; | ||||
| //msg.StudentGraduated | |||||
| //msg.StudentQuited | |||||
| msg.StudentGraduated = (int)game.GameMap.NumOfEscapedStudent; | |||||
| msg.StudentQuited = (int)game.GameMap.NumOfDeceasedStudent; | |||||
| msg.StudentScore = 0; | msg.StudentScore = 0; | ||||
| msg.TrickerScore = 0; | msg.TrickerScore = 0; | ||||
| game.GameMap.GameObjLockDict[GameObjType.Character].EnterReadLock(); | game.GameMap.GameObjLockDict[GameObjType.Character].EnterReadLock(); | ||||
| @@ -54,6 +54,26 @@ namespace Server | |||||
| semaDict.Add(request.PlayerId, temp); | semaDict.Add(request.PlayerId, temp); | ||||
| } | } | ||||
| } | } | ||||
| do | |||||
| { | |||||
| semaDict[request.PlayerId].Item1.Wait(); | |||||
| try | |||||
| { | |||||
| if (currentGameInfo != null) | |||||
| { | |||||
| await responseStream.WriteAsync(currentGameInfo); | |||||
| //Console.WriteLine("Send!"); | |||||
| } | |||||
| } | |||||
| catch (Exception ex) | |||||
| { | |||||
| Console.WriteLine(ex); | |||||
| } | |||||
| finally | |||||
| { | |||||
| semaDict[request.PlayerId].Item2.Release(); | |||||
| } | |||||
| } while (game.GameMap.Timer.IsGaming); | |||||
| return; | return; | ||||
| } | } | ||||
| @@ -100,6 +120,10 @@ namespace Server | |||||
| //Console.WriteLine("Send!"); | //Console.WriteLine("Send!"); | ||||
| } | } | ||||
| } | } | ||||
| catch (Exception ex) | |||||
| { | |||||
| //Console.WriteLine(ex); | |||||
| } | |||||
| finally | finally | ||||
| { | { | ||||
| semaDict[request.PlayerId].Item2.Release(); | semaDict[request.PlayerId].Item2.Release(); | ||||
| @@ -112,9 +136,19 @@ namespace Server | |||||
| #if DEBUG | #if DEBUG | ||||
| Console.WriteLine($"Attack ID: {request.PlayerId}"); | Console.WriteLine($"Attack ID: {request.PlayerId}"); | ||||
| #endif | #endif | ||||
| BoolRes boolRes = new(); | |||||
| if (request.PlayerId >= spectatorMinPlayerID) | |||||
| { | |||||
| boolRes.ActSuccess = false; | |||||
| return Task.FromResult(boolRes); | |||||
| } | |||||
| if (request.Angle == double.NaN) | |||||
| { | |||||
| boolRes.ActSuccess = false; | |||||
| return Task.FromResult(boolRes); | |||||
| } | |||||
| var gameID = communicationToGameID[request.PlayerId]; | var gameID = communicationToGameID[request.PlayerId]; | ||||
| game.Attack(gameID, request.Angle); | game.Attack(gameID, request.Angle); | ||||
| BoolRes boolRes = new(); | |||||
| boolRes.ActSuccess = true; | boolRes.ActSuccess = true; | ||||
| return Task.FromResult(boolRes); | return Task.FromResult(boolRes); | ||||
| } | } | ||||
| @@ -125,8 +159,18 @@ namespace Server | |||||
| #if DEBUG | #if DEBUG | ||||
| Console.WriteLine($"Move ID: {request.PlayerId}, TimeInMilliseconds: {request.TimeInMilliseconds}"); | Console.WriteLine($"Move ID: {request.PlayerId}, TimeInMilliseconds: {request.TimeInMilliseconds}"); | ||||
| #endif | #endif | ||||
| var gameID = communicationToGameID[request.PlayerId]; | |||||
| MoveRes moveRes = new(); | MoveRes moveRes = new(); | ||||
| if (request.PlayerId >= spectatorMinPlayerID) | |||||
| { | |||||
| moveRes.ActSuccess = false; | |||||
| return Task.FromResult(moveRes); | |||||
| } | |||||
| if (request.Angle == double.NaN) | |||||
| { | |||||
| moveRes.ActSuccess = false; | |||||
| return Task.FromResult(moveRes); | |||||
| } | |||||
| var gameID = communicationToGameID[request.PlayerId]; | |||||
| game.MovePlayer(gameID, (int)request.TimeInMilliseconds, request.Angle); | game.MovePlayer(gameID, (int)request.TimeInMilliseconds, request.Angle); | ||||
| // 之后game.MovePlayer可能改为bool类 | // 之后game.MovePlayer可能改为bool类 | ||||
| moveRes.ActSuccess = true; | moveRes.ActSuccess = true; | ||||
| @@ -137,6 +181,11 @@ namespace Server | |||||
| public override Task<BoolRes> SendMessage(SendMsg request, ServerCallContext context) | public override Task<BoolRes> SendMessage(SendMsg request, ServerCallContext context) | ||||
| { | { | ||||
| var boolRes = new BoolRes(); | var boolRes = new BoolRes(); | ||||
| if (request.PlayerId >= spectatorMinPlayerID) | |||||
| { | |||||
| boolRes.ActSuccess = false; | |||||
| return Task.FromResult(boolRes); | |||||
| } | |||||
| if (!ValidPlayerID(request.PlayerId) || !ValidPlayerID(request.ToPlayerId) | if (!ValidPlayerID(request.PlayerId) || !ValidPlayerID(request.ToPlayerId) | ||||
| || PlayerIDToTeamID(request.PlayerId) != PlayerIDToTeamID(request.ToPlayerId) || request.PlayerId == request.ToPlayerId) | || PlayerIDToTeamID(request.PlayerId) != PlayerIDToTeamID(request.ToPlayerId) || request.PlayerId == request.ToPlayerId) | ||||
| { | { | ||||
| @@ -174,6 +223,11 @@ namespace Server | |||||
| Console.WriteLine($"PickProp ID: {request.PlayerId}"); | Console.WriteLine($"PickProp ID: {request.PlayerId}"); | ||||
| #endif | #endif | ||||
| BoolRes boolRes = new(); | BoolRes boolRes = new(); | ||||
| if (request.PlayerId >= spectatorMinPlayerID) | |||||
| { | |||||
| boolRes.ActSuccess = false; | |||||
| return Task.FromResult(boolRes); | |||||
| } | |||||
| var gameID = communicationToGameID[request.PlayerId]; | var gameID = communicationToGameID[request.PlayerId]; | ||||
| boolRes.ActSuccess = game.PickProp(gameID, CopyInfo.ToPropType(request.PropType)); | boolRes.ActSuccess = game.PickProp(gameID, CopyInfo.ToPropType(request.PropType)); | ||||
| return Task.FromResult(boolRes); | return Task.FromResult(boolRes); | ||||
| @@ -185,6 +239,11 @@ namespace Server | |||||
| Console.WriteLine($"UseProp ID: {request.PlayerId}"); | Console.WriteLine($"UseProp ID: {request.PlayerId}"); | ||||
| #endif | #endif | ||||
| BoolRes boolRes = new(); | BoolRes boolRes = new(); | ||||
| if (request.PlayerId >= spectatorMinPlayerID) | |||||
| { | |||||
| boolRes.ActSuccess = false; | |||||
| return Task.FromResult(boolRes); | |||||
| } | |||||
| var gameID = communicationToGameID[request.PlayerId]; | var gameID = communicationToGameID[request.PlayerId]; | ||||
| game.UseProp(gameID, CopyInfo.ToPropType(request.PropType)); | game.UseProp(gameID, CopyInfo.ToPropType(request.PropType)); | ||||
| boolRes.ActSuccess = true; | boolRes.ActSuccess = true; | ||||
| @@ -196,6 +255,11 @@ namespace Server | |||||
| Console.WriteLine($"ThrowProp ID: {request.PlayerId}"); | Console.WriteLine($"ThrowProp ID: {request.PlayerId}"); | ||||
| #endif | #endif | ||||
| BoolRes boolRes = new(); | BoolRes boolRes = new(); | ||||
| if (request.PlayerId >= spectatorMinPlayerID) | |||||
| { | |||||
| boolRes.ActSuccess = false; | |||||
| return Task.FromResult(boolRes); | |||||
| } | |||||
| var gameID = communicationToGameID[request.PlayerId]; | var gameID = communicationToGameID[request.PlayerId]; | ||||
| game.ThrowProp(gameID, CopyInfo.ToPropType(request.PropType)); | game.ThrowProp(gameID, CopyInfo.ToPropType(request.PropType)); | ||||
| boolRes.ActSuccess = true; | boolRes.ActSuccess = true; | ||||
| @@ -207,6 +271,11 @@ namespace Server | |||||
| Console.WriteLine($"UseSkill ID: {request.PlayerId}"); | Console.WriteLine($"UseSkill ID: {request.PlayerId}"); | ||||
| #endif | #endif | ||||
| BoolRes boolRes = new(); | BoolRes boolRes = new(); | ||||
| if (request.PlayerId >= spectatorMinPlayerID) | |||||
| { | |||||
| boolRes.ActSuccess = false; | |||||
| return Task.FromResult(boolRes); | |||||
| } | |||||
| var gameID = communicationToGameID[request.PlayerId]; | var gameID = communicationToGameID[request.PlayerId]; | ||||
| boolRes.ActSuccess = game.UseActiveSkill(gameID, request.SkillId); | boolRes.ActSuccess = game.UseActiveSkill(gameID, request.SkillId); | ||||
| return Task.FromResult(boolRes); | return Task.FromResult(boolRes); | ||||
| @@ -218,6 +287,11 @@ namespace Server | |||||
| Console.WriteLine($"Graduate ID: {request.PlayerId}"); | Console.WriteLine($"Graduate ID: {request.PlayerId}"); | ||||
| #endif | #endif | ||||
| BoolRes boolRes = new(); | BoolRes boolRes = new(); | ||||
| if (request.PlayerId >= spectatorMinPlayerID) | |||||
| { | |||||
| boolRes.ActSuccess = false; | |||||
| return Task.FromResult(boolRes); | |||||
| } | |||||
| var gameID = communicationToGameID[request.PlayerId]; | var gameID = communicationToGameID[request.PlayerId]; | ||||
| boolRes.ActSuccess = game.Escape(gameID); | boolRes.ActSuccess = game.Escape(gameID); | ||||
| return Task.FromResult(boolRes); | return Task.FromResult(boolRes); | ||||
| @@ -228,9 +302,22 @@ namespace Server | |||||
| Console.WriteLine($"StartRescueMate ID: {request.PlayerId}"); | Console.WriteLine($"StartRescueMate ID: {request.PlayerId}"); | ||||
| #endif | #endif | ||||
| BoolRes boolRes = new(); | BoolRes boolRes = new(); | ||||
| if (request.PlayerId >= spectatorMinPlayerID) | |||||
| { | |||||
| boolRes.ActSuccess = false; | |||||
| return Task.FromResult(boolRes); | |||||
| } | |||||
| var gameID = communicationToGameID[request.PlayerId]; | var gameID = communicationToGameID[request.PlayerId]; | ||||
| var toGameID = communicationToGameID[request.ToPlayerId]; | |||||
| boolRes.ActSuccess = game.Rescue(gameID, toGameID); | |||||
| if (request.ToPlayerId >= 0 && request.ToPlayerId < options.MaxStudentCount) | |||||
| { | |||||
| var toGameID = communicationToGameID[request.ToPlayerId]; | |||||
| boolRes.ActSuccess = game.Rescue(gameID, toGameID); | |||||
| } | |||||
| else | |||||
| { | |||||
| boolRes.ActSuccess = game.Rescue(gameID); | |||||
| } | |||||
| return Task.FromResult(boolRes); | return Task.FromResult(boolRes); | ||||
| } | } | ||||
| public override Task<BoolRes> StartTreatMate(TreatAndRescueMsg request, ServerCallContext context) | public override Task<BoolRes> StartTreatMate(TreatAndRescueMsg request, ServerCallContext context) | ||||
| @@ -239,9 +326,22 @@ namespace Server | |||||
| Console.WriteLine($"StartTreatMate ID: {request.PlayerId}"); | Console.WriteLine($"StartTreatMate ID: {request.PlayerId}"); | ||||
| #endif | #endif | ||||
| BoolRes boolRes = new(); | BoolRes boolRes = new(); | ||||
| if (request.PlayerId >= spectatorMinPlayerID) | |||||
| { | |||||
| boolRes.ActSuccess = false; | |||||
| return Task.FromResult(boolRes); | |||||
| } | |||||
| var gameID = communicationToGameID[request.PlayerId]; | var gameID = communicationToGameID[request.PlayerId]; | ||||
| var toGameID = communicationToGameID[request.ToPlayerId]; | |||||
| boolRes.ActSuccess = game.Treat(gameID, toGameID); | |||||
| if (request.ToPlayerId >= 0 && request.ToPlayerId < options.MaxStudentCount) | |||||
| { | |||||
| var toGameID = communicationToGameID[request.ToPlayerId]; | |||||
| boolRes.ActSuccess = game.Treat(gameID, toGameID); | |||||
| } | |||||
| else | |||||
| { | |||||
| boolRes.ActSuccess = game.Treat(gameID); | |||||
| } | |||||
| return Task.FromResult(boolRes); | return Task.FromResult(boolRes); | ||||
| } | } | ||||
| public override Task<BoolRes> StartLearning(IDMsg request, ServerCallContext context) | public override Task<BoolRes> StartLearning(IDMsg request, ServerCallContext context) | ||||
| @@ -250,6 +350,11 @@ namespace Server | |||||
| Console.WriteLine($"StartLearning ID: {request.PlayerId}"); | Console.WriteLine($"StartLearning ID: {request.PlayerId}"); | ||||
| #endif | #endif | ||||
| BoolRes boolRes = new(); | BoolRes boolRes = new(); | ||||
| if (request.PlayerId >= spectatorMinPlayerID) | |||||
| { | |||||
| boolRes.ActSuccess = false; | |||||
| return Task.FromResult(boolRes); | |||||
| } | |||||
| var gameID = communicationToGameID[request.PlayerId]; | var gameID = communicationToGameID[request.PlayerId]; | ||||
| boolRes.ActSuccess = game.Fix(gameID); | boolRes.ActSuccess = game.Fix(gameID); | ||||
| return Task.FromResult(boolRes); | return Task.FromResult(boolRes); | ||||
| @@ -260,6 +365,11 @@ namespace Server | |||||
| Console.WriteLine($"StartOpenChest ID: {request.PlayerId}"); | Console.WriteLine($"StartOpenChest ID: {request.PlayerId}"); | ||||
| #endif | #endif | ||||
| BoolRes boolRes = new(); | BoolRes boolRes = new(); | ||||
| if (request.PlayerId >= spectatorMinPlayerID) | |||||
| { | |||||
| boolRes.ActSuccess = false; | |||||
| return Task.FromResult(boolRes); | |||||
| } | |||||
| var gameID = communicationToGameID[request.PlayerId]; | var gameID = communicationToGameID[request.PlayerId]; | ||||
| boolRes.ActSuccess = game.OpenChest(gameID); | boolRes.ActSuccess = game.OpenChest(gameID); | ||||
| return Task.FromResult(boolRes); | return Task.FromResult(boolRes); | ||||
| @@ -271,6 +381,11 @@ namespace Server | |||||
| Console.WriteLine($"StartOpenGate ID: {request.PlayerId}"); | Console.WriteLine($"StartOpenGate ID: {request.PlayerId}"); | ||||
| #endif | #endif | ||||
| BoolRes boolRes = new(); | BoolRes boolRes = new(); | ||||
| if (request.PlayerId >= spectatorMinPlayerID) | |||||
| { | |||||
| boolRes.ActSuccess = false; | |||||
| return Task.FromResult(boolRes); | |||||
| } | |||||
| var gameID = communicationToGameID[request.PlayerId]; | var gameID = communicationToGameID[request.PlayerId]; | ||||
| boolRes.ActSuccess = game.OpenDoorway(gameID); | boolRes.ActSuccess = game.OpenDoorway(gameID); | ||||
| return Task.FromResult(boolRes); | return Task.FromResult(boolRes); | ||||
| @@ -281,6 +396,11 @@ namespace Server | |||||
| Console.WriteLine($"OpenDoor ID: {request.PlayerId}"); | Console.WriteLine($"OpenDoor ID: {request.PlayerId}"); | ||||
| #endif | #endif | ||||
| BoolRes boolRes = new(); | BoolRes boolRes = new(); | ||||
| if (request.PlayerId >= spectatorMinPlayerID) | |||||
| { | |||||
| boolRes.ActSuccess = false; | |||||
| return Task.FromResult(boolRes); | |||||
| } | |||||
| var gameID = communicationToGameID[request.PlayerId]; | var gameID = communicationToGameID[request.PlayerId]; | ||||
| boolRes.ActSuccess = game.LockOrOpenDoor(gameID); | boolRes.ActSuccess = game.LockOrOpenDoor(gameID); | ||||
| return Task.FromResult(boolRes); | return Task.FromResult(boolRes); | ||||
| @@ -292,6 +412,11 @@ namespace Server | |||||
| Console.WriteLine($"CloseDoor ID: {request.PlayerId}"); | Console.WriteLine($"CloseDoor ID: {request.PlayerId}"); | ||||
| #endif | #endif | ||||
| BoolRes boolRes = new(); | BoolRes boolRes = new(); | ||||
| if (request.PlayerId >= spectatorMinPlayerID) | |||||
| { | |||||
| boolRes.ActSuccess = false; | |||||
| return Task.FromResult(boolRes); | |||||
| } | |||||
| var gameID = communicationToGameID[request.PlayerId]; | var gameID = communicationToGameID[request.PlayerId]; | ||||
| boolRes.ActSuccess = game.LockOrOpenDoor(gameID); | boolRes.ActSuccess = game.LockOrOpenDoor(gameID); | ||||
| return Task.FromResult(boolRes); | return Task.FromResult(boolRes); | ||||
| @@ -303,6 +428,11 @@ namespace Server | |||||
| Console.WriteLine($"EndAllAction ID: {request.PlayerId}"); | Console.WriteLine($"EndAllAction ID: {request.PlayerId}"); | ||||
| #endif | #endif | ||||
| BoolRes boolRes = new(); | BoolRes boolRes = new(); | ||||
| if (request.PlayerId >= spectatorMinPlayerID) | |||||
| { | |||||
| boolRes.ActSuccess = false; | |||||
| return Task.FromResult(boolRes); | |||||
| } | |||||
| var gameID = communicationToGameID[request.PlayerId]; | var gameID = communicationToGameID[request.PlayerId]; | ||||
| boolRes.ActSuccess = game.Stop(gameID); | boolRes.ActSuccess = game.Stop(gameID); | ||||
| return Task.FromResult(boolRes); | return Task.FromResult(boolRes); | ||||
| @@ -315,6 +445,11 @@ namespace Server | |||||
| Console.WriteLine($"SkipWindow ID: {request.PlayerId}"); | Console.WriteLine($"SkipWindow ID: {request.PlayerId}"); | ||||
| #endif | #endif | ||||
| BoolRes boolRes = new(); | BoolRes boolRes = new(); | ||||
| if (request.PlayerId >= spectatorMinPlayerID) | |||||
| { | |||||
| boolRes.ActSuccess = false; | |||||
| return Task.FromResult(boolRes); | |||||
| } | |||||
| var gameID = communicationToGameID[request.PlayerId]; | var gameID = communicationToGameID[request.PlayerId]; | ||||
| boolRes.ActSuccess = game.ClimbingThroughWindow(gameID); | boolRes.ActSuccess = game.ClimbingThroughWindow(gameID); | ||||
| return Task.FromResult(boolRes); | return Task.FromResult(boolRes); | ||||
| @@ -532,6 +532,10 @@ | |||||
| } | } | ||||
| ~~~ | ~~~ | ||||
| #### 喧哗者 | |||||
| ### 学生(&老师) | ### 学生(&老师) | ||||
| #### 运动员 | #### 运动员 | ||||