| @@ -51,7 +51,10 @@ namespace THUAI6 | |||
| Key3 = 1, | |||
| Key5 = 2, | |||
| Key6 = 3, | |||
| PropType4 = 4, | |||
| AddSpeed = 4, | |||
| AddLifeOrAp = 5, | |||
| AddHpOrAp = 6, | |||
| ShieldOrSpear = 7, | |||
| }; | |||
| enum class BulletType : unsigned char | |||
| @@ -323,6 +326,10 @@ namespace THUAI6 | |||
| {PropType::Key3, "Key3"}, | |||
| {PropType::Key5, "Key5"}, | |||
| {PropType::Key6, "Key6"}, | |||
| {PropType::AddSpeed, "AddSpeed"}, | |||
| {PropType::AddLifeOrAp, "AddLifeOrAp"}, | |||
| {PropType::AddHpOrAp, "AddHpOrAp"}, | |||
| {PropType::ShieldOrSpear, "ShieldOrSpear"}, | |||
| }; | |||
| @@ -87,7 +87,10 @@ namespace Proto2THUAI6 | |||
| {protobuf::PropType::KEY3, THUAI6::PropType::Key3}, | |||
| {protobuf::PropType::KEY5, THUAI6::PropType::Key5}, | |||
| {protobuf::PropType::KEY6, THUAI6::PropType::Key6}, | |||
| {protobuf::PropType::PTYPE4, THUAI6::PropType::PropType4}, | |||
| {protobuf::PropType::ADD_SPEED, THUAI6::PropType::AddSpeed}, | |||
| {protobuf::PropType::ADD_HP_OR_AP, THUAI6::PropType::AddHpOrAp}, | |||
| {protobuf::PropType::ADD_LIFE_OR_AP, THUAI6::PropType::AddLifeOrAp}, | |||
| {protobuf::PropType::SHIELD_OR_SPEAR, THUAI6::PropType::ShieldOrSpear}, | |||
| }; | |||
| inline std::map<protobuf::PlayerType, THUAI6::PlayerType> playerTypeDict{ | |||
| @@ -338,7 +341,10 @@ namespace THUAI62Proto | |||
| {THUAI6::PropType::Key3, protobuf::PropType::KEY3}, | |||
| {THUAI6::PropType::Key5, protobuf::PropType::KEY5}, | |||
| {THUAI6::PropType::Key6, protobuf::PropType::KEY6}, | |||
| {THUAI6::PropType::PropType4, protobuf::PropType::PTYPE4}, | |||
| {THUAI6::PropType::AddHpOrAp, protobuf::PropType::ADD_HP_OR_AP}, | |||
| {THUAI6::PropType::AddLifeOrAp, protobuf::PropType::ADD_LIFE_OR_AP}, | |||
| {THUAI6::PropType::AddSpeed, protobuf::PropType::ADD_SPEED}, | |||
| {THUAI6::PropType::ShieldOrSpear, protobuf::PropType::SHIELD_OR_SPEAR}, | |||
| }; | |||
| inline std::map<THUAI6::PlayerType, protobuf::PlayerType> playerTypeDict{ | |||
| @@ -18,8 +18,10 @@ extern const THUAI6::StudentType studentType = THUAI6::StudentType::Athlete; | |||
| void AI::play(IStudentAPI& api) | |||
| { | |||
| api.Move(100, 1); | |||
| api.PrintSelfInfo(); | |||
| } | |||
| void AI::play(ITrickerAPI& api) | |||
| { | |||
| api.Move(100, 1); | |||
| } | |||
| @@ -26,6 +26,7 @@ StudentDebugAPI::StudentDebugAPI(ILogic& logic, bool file, bool print, bool warn | |||
| if (warnOnly) | |||
| printLogger->set_level(spdlog::level::warn); | |||
| logger = std::make_unique<spdlog::logger>("apiLogger", spdlog::sinks_init_list{fileLogger, printLogger}); | |||
| logger->flush_on(spdlog::level::warn); | |||
| } | |||
| TrickerDebugAPI::TrickerDebugAPI(ILogic& logic, bool file, bool print, bool warnOnly, int64_t playerID) : | |||
| @@ -324,7 +324,13 @@ void Logic::ProcessMessage() | |||
| } | |||
| bufferState->gameMap = std::move(map); | |||
| currentState->gameMap = bufferState->gameMap; | |||
| logger->info("Map loaded!"); | |||
| } | |||
| if (currentState->gameMap.empty()) | |||
| { | |||
| logger->error("Map not loaded!"); | |||
| throw std::runtime_error("Map not loaded!"); | |||
| } | |||
| LoadBuffer(clientMsg); | |||
| AILoop = true; | |||
| @@ -734,7 +740,6 @@ void Logic::Main(CreateAIFunc createAI, std::string IP, std::string port, bool f | |||
| if (file) | |||
| { | |||
| fileLogger->set_level(spdlog::level::trace); | |||
| spdlog::flush_every(std::chrono::seconds(1)); | |||
| } | |||
| else | |||
| fileLogger->set_level(spdlog::level::off); | |||
| @@ -745,6 +750,7 @@ void Logic::Main(CreateAIFunc createAI, std::string IP, std::string port, bool f | |||
| if (warnOnly) | |||
| printLogger->set_level(spdlog::level::warn); | |||
| logger = std::make_unique<spdlog::logger>("logicLogger", spdlog::sinks_init_list{fileLogger, printLogger}); | |||
| logger->flush_on(spdlog::level::warn); | |||
| // 打印当前的调试信息 | |||
| logger->info("*********Basic Info*********"); | |||
| @@ -39,36 +39,38 @@ const char descriptor_table_protodef_MessageType_2eproto[] PROTOBUF_SECTION_VARI | |||
| "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*H\n\010PropTyp" | |||
| "e\022\022\n\016NULL_PROP_TYPE\020\000\022\010\n\004KEY3\020\001\022\010\n\004KEY5\020" | |||
| "\002\022\010\n\004KEY6\020\003\022\n\n\006PTYPE4\020\004*f\n\017StudentBuffTy" | |||
| "pe\022\023\n\017NULL_SBUFF_TYPE\020\000\022\016\n\nSBUFFTYPE1\020\001\022" | |||
| "\016\n\nSBUFFTYPE2\020\002\022\016\n\nSBUFFTYPE3\020\003\022\016\n\nSBUFF" | |||
| "TYPE4\020\004*\251\002\n\013PlayerState\022\017\n\013NULL_STATUS\020\000" | |||
| "\022\010\n\004IDLE\020\001\022\014\n\010LEARNING\020\002\022\014\n\010ADDICTED\020\003\022\010" | |||
| "\n\004QUIT\020\004\022\r\n\tGRADUATED\020\005\022\013\n\007TREATED\020\006\022\013\n\007" | |||
| "RESCUED\020\007\022\013\n\007STUNNED\020\010\022\014\n\010TREATING\020\t\022\014\n\010" | |||
| "RESCUING\020\n\022\014\n\010SWINGING\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\016OPENING_A_GATE\020\022*f\n\017TrickerBu" | |||
| "ffType\022\023\n\017NULL_TBUFF_TYPE\020\000\022\016\n\nTBUFFTYPE" | |||
| "1\020\001\022\016\n\nTBUFFTYPE2\020\002\022\016\n\nTBUFFTYPE3\020\003\022\016\n\nT" | |||
| "BUFFTYPE4\020\004*J\n\nPlayerType\022\024\n\020NULL_PLAYER" | |||
| "_TYPE\020\000\022\022\n\016STUDENT_PLAYER\020\001\022\022\n\016TRICKER_P" | |||
| "LAYER\020\002*g\n\013StudentType\022\025\n\021NULL_STUDENT_T" | |||
| "YPE\020\000\022\013\n\007ATHLETE\020\001\022\020\n\014STUDENTTYPE2\020\002\022\020\n\014" | |||
| "STUDENTTYPE3\020\003\022\020\n\014STUDENTTYPE4\020\004*h\n\013Tric" | |||
| "kerType\022\025\n\021NULL_TRICKER_TYPE\020\000\022\014\n\010ASSASS" | |||
| "IN\020\001\022\020\n\014TRICKERTYPE2\020\002\022\020\n\014TRICKERTYPE3\020\003" | |||
| "\022\020\n\014TRICKERTYPE4\020\004*P\n\tGameState\022\023\n\017NULL_" | |||
| "GAME_STATE\020\000\022\016\n\nGAME_START\020\001\022\020\n\014GAME_RUN" | |||
| "NING\020\002\022\014\n\010GAME_END\020\003b\006proto3"; | |||
| "YPE\020\000\022\n\n\006CIRCLE\020\001\022\n\n\006SQUARE\020\002*\206\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*f\n\017StudentBuffType\022\023\n\017NULL_SBUFF_" | |||
| "TYPE\020\000\022\016\n\nSBUFFTYPE1\020\001\022\016\n\nSBUFFTYPE2\020\002\022\016" | |||
| "\n\nSBUFFTYPE3\020\003\022\016\n\nSBUFFTYPE4\020\004*\251\002\n\013Playe" | |||
| "rState\022\017\n\013NULL_STATUS\020\000\022\010\n\004IDLE\020\001\022\014\n\010LEA" | |||
| "RNING\020\002\022\014\n\010ADDICTED\020\003\022\010\n\004QUIT\020\004\022\r\n\tGRADU" | |||
| "ATED\020\005\022\013\n\007TREATED\020\006\022\013\n\007RESCUED\020\007\022\013\n\007STUN" | |||
| "NED\020\010\022\014\n\010TREATING\020\t\022\014\n\010RESCUING\020\n\022\014\n\010SWI" | |||
| "NGING\020\013\022\r\n\tATTACKING\020\014\022\013\n\007LOCKING\020\r\022\r\n\tR" | |||
| "UMMAGING\020\016\022\014\n\010CLIMBING\020\017\022\023\n\017OPENING_A_CH" | |||
| "EST\020\020\022\027\n\023USING_SPECIAL_SKILL\020\021\022\022\n\016OPENIN" | |||
| "G_A_GATE\020\022*f\n\017TrickerBuffType\022\023\n\017NULL_TB" | |||
| "UFF_TYPE\020\000\022\016\n\nTBUFFTYPE1\020\001\022\016\n\nTBUFFTYPE2" | |||
| "\020\002\022\016\n\nTBUFFTYPE3\020\003\022\016\n\nTBUFFTYPE4\020\004*J\n\nPl" | |||
| "ayerType\022\024\n\020NULL_PLAYER_TYPE\020\000\022\022\n\016STUDEN" | |||
| "T_PLAYER\020\001\022\022\n\016TRICKER_PLAYER\020\002*g\n\013Studen" | |||
| "tType\022\025\n\021NULL_STUDENT_TYPE\020\000\022\013\n\007ATHLETE\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\021NULL_T" | |||
| "RICKER_TYPE\020\000\022\014\n\010ASSASSIN\020\001\022\020\n\014TRICKERTY" | |||
| "PE2\020\002\022\020\n\014TRICKERTYPE3\020\003\022\020\n\014TRICKERTYPE4\020" | |||
| "\004*P\n\tGameState\022\023\n\017NULL_GAME_STATE\020\000\022\016\n\nG" | |||
| "AME_START\020\001\022\020\n\014GAME_RUNNING\020\002\022\014\n\010GAME_EN" | |||
| "D\020\003b\006proto3"; | |||
| static ::_pbi::once_flag descriptor_table_MessageType_2eproto_once; | |||
| const ::_pbi::DescriptorTable descriptor_table_MessageType_2eproto = { | |||
| false, | |||
| false, | |||
| 1348, | |||
| 1411, | |||
| descriptor_table_protodef_MessageType_2eproto, | |||
| "MessageType.proto", | |||
| &descriptor_table_MessageType_2eproto_once, | |||
| @@ -171,6 +173,9 @@ namespace protobuf | |||
| case 2: | |||
| case 3: | |||
| case 4: | |||
| case 5: | |||
| case 6: | |||
| case 7: | |||
| return true; | |||
| default: | |||
| return false; | |||
| @@ -155,16 +155,19 @@ namespace protobuf | |||
| enum PropType : int | |||
| { | |||
| NULL_PROP_TYPE = 0, | |||
| KEY3 = 1, | |||
| KEY5 = 2, | |||
| KEY6 = 3, | |||
| PTYPE4 = 4, | |||
| ADD_SPEED = 1, | |||
| ADD_LIFE_OR_AP = 2, | |||
| ADD_HP_OR_AP = 3, | |||
| SHIELD_OR_SPEAR = 4, | |||
| KEY3 = 5, | |||
| KEY5 = 6, | |||
| KEY6 = 7, | |||
| PropType_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::min(), | |||
| PropType_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::max() | |||
| }; | |||
| bool PropType_IsValid(int value); | |||
| constexpr PropType PropType_MIN = NULL_PROP_TYPE; | |||
| constexpr PropType PropType_MAX = PTYPE4; | |||
| constexpr PropType PropType_MAX = KEY6; | |||
| constexpr int PropType_ARRAYSIZE = PropType_MAX + 1; | |||
| const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* PropType_descriptor(); | |||
| @@ -46,6 +46,12 @@ message IDMsg | |||
| int64 player_id = 1; | |||
| } | |||
| message TreatAndRescueMsg | |||
| { | |||
| int64 player_id = 1; | |||
| int64 to_player_id = 2; | |||
| } | |||
| message SkillMsg | |||
| { | |||
| int64 player_id = 1; | |||
| @@ -3,5 +3,5 @@ python3 -m grpc_tools.protoc -I. --python_out=. --pyi_out=. Message2Clients.prot | |||
| python3 -m grpc_tools.protoc -I. --python_out=. --pyi_out=. Message2Server.proto | |||
| python3 -m grpc_tools.protoc -I. --python_out=. --pyi_out=. --grpc_python_out=. Services.proto | |||
| chmod -R 755 ./ | |||
| mv -f ./*.py ../../PyAPI/proto | |||
| mv -f ./*.pyi ../../PyAPI/proto | |||
| mv -f ./*.py ../../CAPI/python/proto | |||
| mv -f ./*.pyi ../../CAPI/python/proto | |||
| @@ -5,16 +5,17 @@ | |||
| xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |||
| xmlns:local="clr-namespace:Installer" | |||
| mc:Ignorable="d" | |||
| Title="Installer" Height="450" Width="800"> | |||
| Title="Installer" Height="200" Window.SizeToContent="Width"> | |||
| <Grid> | |||
| <Grid.ColumnDefinitions> | |||
| <ColumnDefinition Width="40" /> | |||
| <ColumnDefinition Width="75" /> | |||
| <ColumnDefinition Width="75" /> | |||
| <ColumnDefinition Width="250" /> | |||
| <ColumnDefinition Width="75" /> | |||
| <ColumnDefinition Width="75" /> | |||
| <ColumnDefinition Width="*" /> | |||
| <ColumnDefinition Width="50" /> | |||
| <ColumnDefinition Width="25" /> | |||
| <ColumnDefinition Width="50" /> | |||
| <ColumnDefinition Width="1*" /> | |||
| <ColumnDefinition Width="1*" /> | |||
| <ColumnDefinition Width="40" /> | |||
| </Grid.ColumnDefinitions> | |||
| <Grid.RowDefinitions> | |||
| @@ -26,22 +27,44 @@ | |||
| <RowDefinition Height="20" /> | |||
| <RowDefinition Height="20" /> | |||
| <RowDefinition Height="20" /> | |||
| <RowDefinition Height="*" /> | |||
| <RowDefinition Height="20" /> | |||
| </Grid.RowDefinitions> | |||
| <TextBlock Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="3" Text="欢迎使用选手包" Visibility="{Binding InstIntroVis}"/> | |||
| <TextBlock Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="3" Text="你已经安装了选手包,请选择你要进行的操作" Visibility="{Binding EditIntroVis}"/> | |||
| <TextBlock Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="5" Text="{Binding Intro}" /> | |||
| <TextBlock Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="5" Text="{Binding RouteBoxIntro}"/> | |||
| <TextBox Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="5" Name="RouteTxtBox" Text="{Binding Route}" Visibility="{Binding RouteBoxVis}"/> | |||
| <Button Grid.Row="3" Grid.Column="6" Name="GetRouteBtn" Content="Browse..." Command="{Binding ClickBrowseCommand}" Visibility="{Binding RouteBoxVis}" /> | |||
| <Button Grid.Row="3" Grid.Column="7" Name="SetBtm" Content="Confirm" Command="{Binding ClickConfirmCommand}" Visibility="{Binding RouteBoxVis}"/> | |||
| <Button Grid.Row="3" Grid.Column="2" Grid.ColumnSpan="2" Name="UpdateBtn" Content="{Binding UpdateBtnCont}" Command="{Binding ClickUpdateCommand}" Visibility="{Binding MenuVis}" /> | |||
| <Button Grid.Row="5" Grid.Column="2" Grid.ColumnSpan="2" Name="MoveBtn" Content="Move" Command="{Binding ClickMoveCommand}" Visibility="{Binding MenuVis}" /> | |||
| <Button Grid.Row="7" Grid.Column="2" Grid.ColumnSpan="2" Name="UninstBtn" Content="UnInstall" Command="{Binding ClickUninstCommand}" Visibility="{Binding MenuVis}" /> | |||
| <TextBlock Grid.Row="3" Grid.Column="4" Text="Processing" Grid.ColumnSpan="2" Visibility="{Binding ProgressVis}"/> | |||
| <ProgressBar Grid.Row="5" Grid.Column="2" Grid.ColumnSpan="6" Minimum="0" Maximum="100" Name="Progress" Visibility="{Binding ProgressVis}" IsIndeterminate="True"/> | |||
| <TextBlock Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="3" Text="将主体程序安装在:" Visibility="{Binding InstIntroVis}"/> | |||
| <TextBlock Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="3" Text="将主体程序移动到:" Visibility="{Binding MoveIntroVis}"/> | |||
| <TextBlock Grid.Row="4" Grid.Column="2" Grid.ColumnSpan="4" Text="操作完成!你可以继续操作或退出" Visibility="{Binding CompleteVis}"/> | |||
| <Button Grid.Row="6" Grid.Column="2" Name="BackBtn" Content="返回" Command="{Binding ClickBackCommand}" Visibility="{Binding CompleteVis}"/> | |||
| <Button Grid.Row="6" Grid.Column="4" Grid.ColumnSpan="2" Name="ExitBtn" Content="退出" Command="{Binding ClickExitCommand}" Visibility="{Binding CompleteVis}"/> | |||
| <TextBox Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="3" Name="RouteTxtBox" Text="{Binding Route}" Visibility="{Binding RouteBoxVis}"/> | |||
| <Button Grid.Row="3" Grid.Column="4" Name="GetRouteBtn" Content="Browse..." Command="{Binding ClickBrowseCommand}" Visibility="{Binding RouteBoxVis}" /> | |||
| <Button Grid.Row="3" Grid.Column="5" Name="SetBtm" Content="Confirm" Command="{Binding ClickConfirmCommand}" Visibility="{Binding RouteBoxVis}"/> | |||
| <Button Grid.Row="3" Grid.Column="2" Name="UpdateBtn" Content="Update" Command="{Binding ClickUpdateCommand}" Visibility="{Binding EditIntroVis}" /> | |||
| <TextBlock Grid.Row="3" Grid.Column="1" Text="账号:" Visibility="{Binding LoginVis}" /> | |||
| <TextBlock Grid.Row="5" Grid.Column="1" Text="密码:" Visibility="{Binding LoginVis}" /> | |||
| <TextBox Grid.Row="3" Grid.Column="2" Grid.ColumnSpan="4" Name="Username" Visibility="{Binding LoginVis}" Text="{Binding Username}" /> | |||
| <TextBox Grid.Row="5" Grid.Column="2" Grid.ColumnSpan="4" Name="Password" Visibility="{Binding LoginVis}" Text="{Binding Password}" /> | |||
| <Button Grid.Row="7" Grid.Column="1" Name="Login" Content="登录" Command="{Binding ClickLoginCommand}" Visibility="{Binding LoginVis}"/> | |||
| <Button Grid.Row="7" Grid.Column="2" Name="Launch" Content="{Binding LaunchBtnCont}" Command="{Binding ClickLaunchCommand}" Visibility="{Binding LoginVis}"/> | |||
| <Button Grid.Row="7" Grid.Column="4" Grid.ColumnSpan="2" Name="Edit" Content="修改文件" Command="{Binding ClickEditCommand}" Visibility="{Binding LoginVis}"/> | |||
| <TextBlock Grid.Row="6" Grid.Column="1" Text="用户名或密码错误!" Visibility="{Binding LoginFailVis}"/> | |||
| <Button Grid.Row="5" Grid.Column="2" Name="MoveBtn" Content="Move" Command="{Binding ClickMoveCommand}" Visibility="{Binding EditIntroVis}" /> | |||
| <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="6" Grid.Column="3" Grid.ColumnSpan="2" Content="退出登录" Command="{Binding ClickLogoutCommand}" Visibility="{Binding WebVis}" /> | |||
| <Button Grid.Row="7" Grid.Column="2" Name="UninstBtn" Content="UnInst" Command="{Binding ClickUninstCommand}" Visibility="{Binding EditIntroVis}" /> | |||
| </Grid> | |||
| </Window> | |||
| @@ -22,6 +22,9 @@ using System.Windows; | |||
| using System.Windows.Shapes; | |||
| //using System.Windows.Forms; | |||
| using MessageBox = System.Windows.MessageBox; | |||
| using Downloader; | |||
| namespace starter.viewmodel.settings | |||
| { | |||
| /// <summary> | |||
| @@ -32,27 +35,25 @@ namespace starter.viewmodel.settings | |||
| /// <summary> | |||
| /// downloader function | |||
| /// </summary> | |||
| private Downloader.Program.Data configData = new Downloader.Program.Data(""); | |||
| private Downloader.Program.Tencent_cos_download cloud = new Downloader.Program.Tencent_cos_download(); | |||
| private Data configData = new Data(""); | |||
| private Tencent_cos_download cloud = new Tencent_cos_download(); | |||
| private HttpClient client = new HttpClient(); | |||
| private WebConnect.Web web = new WebConnect.Web(); | |||
| /// <summary> | |||
| /// save settings | |||
| /// </summary> | |||
| public bool install() | |||
| { | |||
| if (Downloader.Program.Tencent_cos_download.CheckAlreadyDownload()) | |||
| if (Tencent_cos_download.CheckAlreadyDownload()) | |||
| { | |||
| MessageBoxResult repeatOption = MessageBox.Show($"文件已存在于{Downloader.Program.Data.FilePath},是否移动到新位置?", "重复安装", MessageBoxButton.YesNoCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel); | |||
| MessageBoxResult repeatOption = MessageBox.Show($"文件已存在于{Downloader.Program.Data.FilePath},是否移动到新位置?", "重复安装", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No); | |||
| // ask if abort install, with warning sign, defalut no; | |||
| if (repeatOption == MessageBoxResult.Cancel) | |||
| if (repeatOption == MessageBoxResult.No) | |||
| { | |||
| return false; // 回到选择地址界面 | |||
| } | |||
| else if (repeatOption == MessageBoxResult.No) | |||
| { | |||
| System.Environment.Exit(0); | |||
| return false; | |||
| } | |||
| else | |||
| { | |||
| Downloader.Program.Tencent_cos_download.MoveProgram(Route); | |||
| @@ -61,11 +62,76 @@ namespace starter.viewmodel.settings | |||
| } | |||
| else | |||
| { | |||
| Downloader.Program.Data.ResetFilepath(Route); | |||
| Downloader.Program.Tencent_cos_download.DownloadAll(); | |||
| Data.ResetFilepath(Route); | |||
| Tencent_cos_download.DownloadAll(); | |||
| return true; | |||
| } | |||
| } | |||
| public int move() | |||
| { | |||
| return Tencent_cos_download.MoveProgram(Route); | |||
| } | |||
| ///<summary> | |||
| ///check for update | |||
| /// </summary> | |||
| static bool ProfileAvailable | |||
| { | |||
| get; set; | |||
| } | |||
| /// <summary> | |||
| /// 检查更新 | |||
| /// </summary> | |||
| /// <returns></returns> | |||
| public Status checkUpdate() | |||
| { | |||
| UpdateInfo updateInfo = Tencent_cos_download.Check(); | |||
| if (updateInfo.newFileCount == -1) | |||
| { | |||
| if (updateInfo.changedFileCount == -1) | |||
| { | |||
| return Status.error; | |||
| } | |||
| else | |||
| { | |||
| return Status.disconnected; | |||
| } | |||
| } | |||
| else | |||
| { | |||
| if (updateInfo.changedFileCount != 0 || updateInfo.newFileCount != 0) | |||
| { | |||
| Updates = "发现新版本" + updateInfo.status; | |||
| } | |||
| return Status.menu; | |||
| } | |||
| } | |||
| public void Login() | |||
| { | |||
| _ = web.LoginToEEsast(client, Username, Password); | |||
| } | |||
| public bool Update() | |||
| { | |||
| return Tencent_cos_download.Update(); | |||
| } | |||
| public int Uninst() | |||
| { | |||
| return Tencent_cos_download.DeleteAll(); | |||
| } | |||
| public bool Launch() | |||
| { | |||
| if (Tencent_cos_download.CheckAlreadyDownload()) | |||
| { | |||
| Process.Start(System.IO.Path.Combine(Data.FilePath, startName)); | |||
| return true; | |||
| } | |||
| else | |||
| { | |||
| MessageBox.Show($"文件还不存在,请安装主体文件", "文件不存在", MessageBoxButton.OK, MessageBoxImage.Warning, MessageBoxResult.OK); | |||
| return false; | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Route of files | |||
| /// </summary> | |||
| @@ -73,24 +139,69 @@ namespace starter.viewmodel.settings | |||
| { | |||
| get | |||
| { | |||
| return Downloader.Program.Data.FilePath; | |||
| return Data.FilePath; | |||
| } | |||
| set | |||
| { | |||
| Downloader.Program.Data.FilePath = value; | |||
| Data.FilePath = value; | |||
| } | |||
| } | |||
| public string Username | |||
| { | |||
| get; set; | |||
| } | |||
| public string Password | |||
| { | |||
| get; set; | |||
| } | |||
| /// <summary> | |||
| /// if the route was set or is under editing | |||
| /// 关于更新的屏幕显示信息 | |||
| /// </summary> | |||
| public bool EditingRoute | |||
| private string updates; | |||
| public string Updates | |||
| { | |||
| get | |||
| { | |||
| return updates; | |||
| } | |||
| set | |||
| { | |||
| updates = value; | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// 关于介绍的屏幕显示信息 | |||
| /// </summary> | |||
| public enum Status { newUser, menu, move, working, disconnected, error, successful, login, web }; | |||
| public Status status | |||
| { | |||
| get; set; | |||
| } | |||
| public bool Working | |||
| { | |||
| get; set; | |||
| } | |||
| ///< summary> | |||
| /// if already installed | |||
| /// </summary> | |||
| public bool installed | |||
| /// <summary> | |||
| /// if an update is planned | |||
| /// </summary> | |||
| public bool UpdatePlanned | |||
| { | |||
| get | |||
| { | |||
| return Program.UpdatePlanned; | |||
| } | |||
| } | |||
| public bool CombatCompleted | |||
| { | |||
| get | |||
| { | |||
| return false; | |||
| } | |||
| } | |||
| public bool LoginFailed | |||
| { | |||
| get; set; | |||
| } | |||
| @@ -102,9 +213,21 @@ namespace Downloader | |||
| { | |||
| static List<string> newFileName = new List<string>(); // 新文件名 | |||
| static List<string> updateFileName = new List<string>(); // 更新文件名 | |||
| static string ProgramName = "THUAI6"; // 要运行或下载的程序名称 | |||
| static string playerFolder = "player"; // 选手代码保存文件夹路径 | |||
| static string startName = "maintest.exe"; // 启动的程序名 | |||
| public static string ProgramName = "THUAI6"; // 要运行或下载的程序名称 | |||
| public static string playerFolder = "player"; // 选手代码保存文件夹路径 | |||
| public static string startName = "maintest.exe"; // 启动的程序名 | |||
| public struct UpdateInfo // 更新信息,包括新版本版本号、更改文件数和新文件数 | |||
| { | |||
| public string status; | |||
| public int changedFileCount; | |||
| public int newFileCount; | |||
| } | |||
| public static bool UpdatePlanned | |||
| { | |||
| get; set; | |||
| } | |||
| static int filenum = 0; // 总文件个数 | |||
| public class Data | |||
| @@ -283,13 +406,14 @@ namespace Downloader | |||
| } | |||
| } | |||
| private static void Check() | |||
| public static UpdateInfo Check() | |||
| { | |||
| string json, MD5, jsonName; | |||
| int newFile = 0, updateFile = 0; | |||
| newFileName.Clear(); | |||
| updateFileName.Clear(); | |||
| jsonName = "hash.json"; | |||
| UpdateInfo updateInfo; | |||
| Tencent_cos_download Downloader = new Tencent_cos_download(); | |||
| try | |||
| @@ -308,14 +432,18 @@ namespace Downloader | |||
| catch (CosClientException clientEx) | |||
| { | |||
| // 请求失败 | |||
| Console.WriteLine("CosClientException: " + clientEx.ToString() + Environment.NewLine); | |||
| return; | |||
| updateInfo.status = "ClientEx: " + clientEx.ToString(); | |||
| updateInfo.newFileCount = -1; | |||
| updateInfo.changedFileCount = 0; | |||
| return updateInfo; | |||
| } | |||
| catch (CosServerException serverEx) | |||
| { | |||
| // 请求失败 | |||
| Console.WriteLine("CosClientException: " + serverEx.ToString() + Environment.NewLine); | |||
| return; | |||
| updateInfo.status = "ServerEx: " + serverEx.ToString(); | |||
| updateInfo.newFileCount = -1; | |||
| updateInfo.changedFileCount = 0; | |||
| return updateInfo; | |||
| } | |||
| using (StreamReader r = new StreamReader(System.IO.Path.Combine(Data.FilePath, jsonName))) | |||
| @@ -334,22 +462,29 @@ namespace Downloader | |||
| newFile = newFileName.Count; | |||
| updateFile = updateFileName.Count; | |||
| filenum = newFile + updateFile; | |||
| Console.WriteLine("----------------------" + Environment.NewLine); | |||
| //Console.WriteLine("----------------------" + Environment.NewLine); | |||
| if (newFile + updateFile == 0) | |||
| { | |||
| Console.WriteLine("当前平台已是最新版本!" + Environment.NewLine); | |||
| updateInfo.status = "latest"; | |||
| updateInfo.newFileCount = 0; | |||
| updateInfo.changedFileCount = 0; | |||
| newFileName.Clear(); | |||
| updateFileName.Clear(); | |||
| } | |||
| else | |||
| { | |||
| Console.WriteLine($"发现{newFile}个新文件" + Environment.NewLine); | |||
| updateInfo.status = "old"; | |||
| //TODO:获取版本号 | |||
| updateInfo.newFileCount = newFile; | |||
| /* | |||
| foreach (string filename in newFileName) | |||
| { | |||
| Console.WriteLine(filename); | |||
| } | |||
| Console.WriteLine(Environment.NewLine + $"发现{updateFile}个文件更新" + Environment.NewLine); | |||
| */ | |||
| updateInfo.changedFileCount = updateFile; | |||
| /* | |||
| foreach (string filename in updateFileName) | |||
| { | |||
| Console.WriteLine(filename); | |||
| @@ -359,8 +494,23 @@ namespace Downloader | |||
| Console.WriteLine("下载取消!"); | |||
| else | |||
| Download(); | |||
| */ | |||
| UpdatePlanned = true; | |||
| } | |||
| return updateInfo; | |||
| } | |||
| public static bool Update() | |||
| { | |||
| if (UpdatePlanned) | |||
| { | |||
| Download(); | |||
| UpdatePlanned = false; | |||
| return true; | |||
| } | |||
| return false; | |||
| } | |||
| private static void Download() | |||
| { | |||
| Tencent_cos_download Downloader = new Tencent_cos_download(); | |||
| @@ -592,7 +742,7 @@ namespace Downloader | |||
| } | |||
| } | |||
| public static void DeleteAll() | |||
| public static int DeleteAll() | |||
| { | |||
| DirectoryInfo di = new DirectoryInfo(Data.FilePath); | |||
| DirectoryInfo player = new DirectoryInfo(System.IO.Path.GetFullPath(System.IO.Path.Combine(Data.FilePath, playerFolder))); | |||
| @@ -619,17 +769,17 @@ namespace Downloader | |||
| catch (UnauthorizedAccessException) | |||
| { | |||
| Console.WriteLine("权限不足,无法删除!"); | |||
| return; | |||
| return -2; | |||
| } | |||
| catch (DirectoryNotFoundException) | |||
| { | |||
| Console.WriteLine("文件夹没有找到,请检查是否已经手动更改路径"); | |||
| return; | |||
| return -3; | |||
| } | |||
| catch (IOException) | |||
| { | |||
| Console.WriteLine("文件已经打开,请关闭后再删除"); | |||
| return; | |||
| return -1; | |||
| } | |||
| string json2; | |||
| @@ -665,19 +815,20 @@ namespace Downloader | |||
| catch (UnauthorizedAccessException) | |||
| { | |||
| Console.WriteLine("权限不足,无法删除!"); | |||
| return; | |||
| return -2; | |||
| } | |||
| catch (DirectoryNotFoundException) | |||
| { | |||
| Console.WriteLine("文件夹没有找到,请检查是否已经手动更改路径"); | |||
| return; | |||
| return -3; | |||
| } | |||
| catch (IOException) | |||
| { | |||
| Console.WriteLine("文件已经打开,请关闭后再删除"); | |||
| return; | |||
| return -1; | |||
| } | |||
| Console.WriteLine($"删除成功!player文件夹中的文件已经放在{ProgramName}的根目录下"); | |||
| return 0; | |||
| } | |||
| public static void OverwriteHash(Dictionary<string, string> jsonDict) | |||
| @@ -687,7 +838,7 @@ namespace Downloader | |||
| File.WriteAllText(@System.IO.Path.Combine(Data.FilePath, "hash.json"), Contentjson); | |||
| } | |||
| public static void MoveProgram(string newPath) | |||
| public static int MoveProgram(string newPath) | |||
| { | |||
| DirectoryInfo newdi = new DirectoryInfo(newPath); | |||
| DirectoryInfo olddi = new DirectoryInfo(Data.FilePath); | |||
| @@ -714,6 +865,7 @@ namespace Downloader | |||
| file.MoveTo(System.IO.Path.Combine(Data.FilePath, file.Name)); | |||
| } | |||
| Console.WriteLine("移动失败!"); | |||
| return -2; | |||
| } | |||
| catch (IOException) | |||
| { | |||
| @@ -727,9 +879,11 @@ namespace Downloader | |||
| file.MoveTo(System.IO.Path.Combine(Data.FilePath, file.Name)); | |||
| } | |||
| Console.WriteLine("移动失败!"); | |||
| return -1; | |||
| } | |||
| Data.ResetFilepath(newPath); | |||
| Console.WriteLine("更改路径成功!"); | |||
| return 0; | |||
| } | |||
| public static async Task main(string[] args) | |||
| { | |||
| @@ -3,6 +3,9 @@ using starter.viewmodel.common; | |||
| using System; | |||
| using System.Windows; | |||
| using System.Windows.Forms; | |||
| using Downloader; | |||
| using MessageBox = System.Windows.MessageBox; | |||
| using System.Configuration; | |||
| namespace starter.viewmodel.settings | |||
| { | |||
| @@ -19,12 +22,111 @@ namespace starter.viewmodel.settings | |||
| { | |||
| if (Downloader.Program.Tencent_cos_download.CheckAlreadyDownload()) | |||
| { | |||
| Installed = true; | |||
| obj.checkUpdate(); | |||
| Status = SettingsModel.Status.login; | |||
| this.RaisePropertyChanged("WindowWidth"); | |||
| //TODO:在启动时立刻检查更新,确保选手启动最新版选手包 | |||
| //TODO:若有更新,将启动键改为更新键; | |||
| //TODO:相应地,使用login界面启动; | |||
| //TODO:结构:上方为登录框架,下方有“修改选手包”按钮 | |||
| } | |||
| else | |||
| { | |||
| Route = Environment.GetEnvironmentVariable("USERPROFILE") + "\\THUAI6"; | |||
| EditingRoute = true; | |||
| Status = SettingsModel.Status.newUser; | |||
| this.RaisePropertyChanged("WindowWidth"); | |||
| } | |||
| } | |||
| //TODO:参赛界面:包括上传参赛代码、申请对战 | |||
| //TODO:界面中应包含上次对战完成提示及下载回放按钮 | |||
| public int ExtraColumn | |||
| { | |||
| get | |||
| { | |||
| if (Status == SettingsModel.Status.newUser || Status == SettingsModel.Status.move) | |||
| return 75; | |||
| else | |||
| return 0; | |||
| } | |||
| } | |||
| public int WindowWidth | |||
| { | |||
| get | |||
| { | |||
| switch (Status) | |||
| { | |||
| case SettingsModel.Status.newUser: | |||
| return 505; | |||
| case SettingsModel.Status.move: | |||
| return 505; | |||
| case SettingsModel.Status.working: | |||
| return 435; | |||
| case SettingsModel.Status.successful: | |||
| return 435; | |||
| default: | |||
| return 355; | |||
| } | |||
| } | |||
| } | |||
| public SettingsModel.Status Status | |||
| { | |||
| get | |||
| { | |||
| return obj.status; | |||
| } | |||
| set | |||
| { | |||
| obj.status = value; | |||
| this.RaisePropertyChanged("ExtraColumn"); | |||
| this.RaisePropertyChanged("Intro"); | |||
| this.RaisePropertyChanged("RouteBoxIntro"); | |||
| this.RaisePropertyChanged("LoginVis"); | |||
| this.RaisePropertyChanged("MenuVis"); | |||
| this.RaisePropertyChanged("RouteBoxVis"); | |||
| this.RaisePropertyChanged("ProgressVis"); | |||
| this.RaisePropertyChanged("CompleteVis"); | |||
| } | |||
| } | |||
| public string Intro | |||
| { | |||
| get | |||
| { | |||
| switch (Status) | |||
| { | |||
| case SettingsModel.Status.newUser: | |||
| return "欢迎使用选手包,请选择你想要安装选手包的位置:"; | |||
| case SettingsModel.Status.menu: | |||
| return "你已经安装了选手包,请选择想要进行的操作:"; | |||
| case SettingsModel.Status.login: | |||
| return "使用EESAST账号登录"; | |||
| case SettingsModel.Status.web: | |||
| return "THUAI6 赛场:"; | |||
| case SettingsModel.Status.disconnected: | |||
| return "你可能没有连接到网络,无法下载/更新选手包"; | |||
| case SettingsModel.Status.error: | |||
| return "我们遇到了一些问题,请向[]反馈"; | |||
| default: | |||
| return ""; | |||
| } | |||
| } | |||
| } | |||
| public string RouteBoxIntro | |||
| { | |||
| get | |||
| { | |||
| switch (Status) | |||
| { | |||
| case SettingsModel.Status.newUser: | |||
| return "将主体程序安装在:"; | |||
| case SettingsModel.Status.move: | |||
| return "将主体程序移动到:"; | |||
| default: | |||
| return ""; | |||
| } | |||
| } | |||
| } | |||
| @@ -40,67 +142,106 @@ namespace starter.viewmodel.settings | |||
| this.RaisePropertyChanged("Route"); | |||
| } | |||
| } | |||
| public bool Installed | |||
| public string Username | |||
| { | |||
| get | |||
| { | |||
| return obj.installed; | |||
| return obj.Username; | |||
| } | |||
| set | |||
| { | |||
| obj.installed = value; | |||
| this.RaisePropertyChanged("Installed"); | |||
| this.RaisePropertyChanged("InstIntroVis"); | |||
| this.RaisePropertyChanged("EditIntroVis"); | |||
| this.RaisePropertyChanged("MoveIntroVis"); | |||
| obj.Username = value; | |||
| this.RaisePropertyChanged("Username"); | |||
| } | |||
| } | |||
| public bool EditingRoute | |||
| public string Password | |||
| { | |||
| get { return obj.Password; } | |||
| set | |||
| { | |||
| obj.Password = value; | |||
| this.RaisePropertyChanged("Password"); | |||
| } | |||
| } | |||
| public Visibility MenuVis | |||
| { | |||
| get | |||
| { | |||
| return obj.EditingRoute; | |||
| return Status == SettingsModel.Status.menu ? Visibility.Visible : Visibility.Collapsed; | |||
| } | |||
| set | |||
| } | |||
| public Visibility RouteBoxVis | |||
| { | |||
| get | |||
| { | |||
| obj.EditingRoute = value; | |||
| this.RaisePropertyChanged("EditingRoute"); | |||
| this.RaisePropertyChanged("MoveIntroVis"); | |||
| this.RaisePropertyChanged("RouteBoxVis"); | |||
| return (Status == SettingsModel.Status.newUser || Status == SettingsModel.Status.move) ? Visibility.Visible : Visibility.Collapsed; | |||
| } | |||
| } | |||
| public Visibility RouteBoxVis // if the route editing textbox is visible | |||
| public Visibility LoginVis | |||
| { | |||
| get | |||
| { | |||
| return obj.EditingRoute ? Visibility.Visible : Visibility.Collapsed; | |||
| return Status == SettingsModel.Status.login ? Visibility.Visible : Visibility.Collapsed; | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// if the install/edit instruction can be seen | |||
| /// </summary> | |||
| public Visibility InstIntroVis | |||
| public Visibility ProgressVis | |||
| { | |||
| get | |||
| { | |||
| return Status == SettingsModel.Status.working ? Visibility.Visible : Visibility.Collapsed; | |||
| } | |||
| } | |||
| public Visibility CompleteVis | |||
| { | |||
| get | |||
| { | |||
| return obj.installed ? Visibility.Collapsed : Visibility.Visible; | |||
| return Status == SettingsModel.Status.successful ? Visibility.Visible : Visibility.Collapsed; | |||
| } | |||
| } | |||
| public Visibility EditIntroVis | |||
| public Visibility WebVis | |||
| { | |||
| get | |||
| { | |||
| return obj.installed ? Visibility.Visible : Visibility.Collapsed; | |||
| return Status == SettingsModel.Status.web ? Visibility.Visible : Visibility.Collapsed; | |||
| } | |||
| } | |||
| public Visibility MoveIntroVis | |||
| public Visibility LoginFailVis | |||
| { | |||
| get | |||
| { | |||
| if (obj.installed == true && obj.EditingRoute == true) | |||
| return Visibility.Visible; | |||
| return obj.LoginFailed ? Visibility.Visible : Visibility.Collapsed; | |||
| } | |||
| } | |||
| public Visibility MatchFinishedVis | |||
| { | |||
| get | |||
| { | |||
| return obj.CombatCompleted ? Visibility.Visible : Visibility.Collapsed; | |||
| } | |||
| } | |||
| public string UpdateBtnCont | |||
| { | |||
| get | |||
| { | |||
| return obj.UpdatePlanned ? "Update" : "Check Updates"; | |||
| } | |||
| } | |||
| public string UpdateInfo | |||
| { | |||
| get | |||
| { | |||
| if (obj.UpdatePlanned) | |||
| return obj.Updates; | |||
| else | |||
| return Visibility.Collapsed; | |||
| return ""; | |||
| } | |||
| } | |||
| public string LaunchBtnCont | |||
| { | |||
| get | |||
| { | |||
| return obj.UpdatePlanned ? "更新" : "启动"; | |||
| } | |||
| } | |||
| @@ -133,15 +274,175 @@ namespace starter.viewmodel.settings | |||
| { | |||
| clickConfirmCommand = new BaseCommand(new Action<object>(o => | |||
| { | |||
| if (obj.install()) | |||
| if (Status == SettingsModel.Status.newUser) | |||
| { | |||
| EditingRoute = false; | |||
| Installed = true; | |||
| Status = SettingsModel.Status.working; | |||
| if (obj.install()) | |||
| { | |||
| Status = SettingsModel.Status.menu; | |||
| } | |||
| } | |||
| else if (Status == SettingsModel.Status.move) | |||
| { | |||
| Status = SettingsModel.Status.working; | |||
| switch (obj.move()) | |||
| { | |||
| case -1: | |||
| MessageBox.Show("文件已打开或者目标路径下有同名文件!", "", MessageBoxButton.OK, MessageBoxImage.Warning, MessageBoxResult.OK); | |||
| break; | |||
| case -2: | |||
| Status = SettingsModel.Status.error; | |||
| break; | |||
| } | |||
| } | |||
| })); | |||
| } | |||
| return clickConfirmCommand; | |||
| } | |||
| } | |||
| private BaseCommand clickUpdateCommand; | |||
| public BaseCommand ClickUpdateCommand | |||
| { | |||
| get | |||
| { | |||
| if (clickUpdateCommand == null) | |||
| { | |||
| clickUpdateCommand = new BaseCommand(new Action<object>(o => | |||
| { | |||
| if (obj.UpdatePlanned) | |||
| { | |||
| Status = SettingsModel.Status.working; | |||
| if (obj.Update()) | |||
| { | |||
| Status = SettingsModel.Status.successful; | |||
| this.RaisePropertyChanged("UpdateButtonCont"); | |||
| } | |||
| else | |||
| Status = SettingsModel.Status.error; | |||
| } | |||
| else | |||
| { | |||
| Status = SettingsModel.Status.working; | |||
| Status = obj.checkUpdate(); | |||
| this.RaisePropertyChanged("UpdateButtonCont"); | |||
| } | |||
| })); | |||
| } | |||
| return clickUpdateCommand; | |||
| } | |||
| } | |||
| private BaseCommand clickMoveCommand; | |||
| public BaseCommand ClickMoveCommand | |||
| { | |||
| get | |||
| { | |||
| if (clickMoveCommand == null) | |||
| { | |||
| clickMoveCommand = new BaseCommand(new Action<object>(o => | |||
| { | |||
| Status = SettingsModel.Status.move; | |||
| })); | |||
| } | |||
| return clickMoveCommand; | |||
| } | |||
| } | |||
| private BaseCommand clickUninstCommand; | |||
| public BaseCommand ClickUninstCommand | |||
| { | |||
| get | |||
| { | |||
| if (clickUninstCommand == null) | |||
| { | |||
| clickUninstCommand = new BaseCommand(new Action<object>(o => | |||
| { | |||
| Status = SettingsModel.Status.working; | |||
| switch (obj.Uninst()) | |||
| { | |||
| case -1: | |||
| Status = SettingsModel.Status.menu; | |||
| MessageBox.Show("文件已经打开,请关闭后再删除", "", MessageBoxButton.OK, MessageBoxImage.Warning, MessageBoxResult.OK); | |||
| break; | |||
| case 0: | |||
| Status = SettingsModel.Status.successful; | |||
| break; | |||
| default: | |||
| Status = SettingsModel.Status.error; | |||
| break; | |||
| } | |||
| })); | |||
| } | |||
| return clickUninstCommand; | |||
| } | |||
| } | |||
| private BaseCommand clickLoginCommand; | |||
| public BaseCommand ClickLoginCommand | |||
| { | |||
| get | |||
| { | |||
| if (clickLoginCommand == null) | |||
| { | |||
| clickLoginCommand = new BaseCommand(new Action<object>(o => | |||
| { | |||
| obj.Login(); | |||
| this.RaisePropertyChanged("LoginFailVis"); | |||
| })); | |||
| } | |||
| return clickLoginCommand; | |||
| } | |||
| } | |||
| private BaseCommand clickLaunchCommand; | |||
| public BaseCommand ClickLaunchCommand | |||
| { | |||
| get | |||
| { | |||
| if (clickLaunchCommand == null) | |||
| { | |||
| clickLaunchCommand = new BaseCommand(new Action<object>(o => | |||
| { | |||
| if (!obj.Launch()) | |||
| { | |||
| Status = SettingsModel.Status.menu; | |||
| } | |||
| })); | |||
| } | |||
| return clickLaunchCommand; | |||
| } | |||
| } | |||
| private BaseCommand clickEditCommand; | |||
| public BaseCommand ClickEditCommand | |||
| { | |||
| get | |||
| { | |||
| if (clickEditCommand == null) | |||
| { | |||
| clickEditCommand = new BaseCommand(new Action<object>(o => | |||
| { | |||
| Status = SettingsModel.Status.menu; | |||
| })); | |||
| } | |||
| return clickEditCommand; | |||
| } | |||
| } | |||
| private BaseCommand clickLogoutCommand; | |||
| public BaseCommand ClickLogoutCommand | |||
| { | |||
| get | |||
| { | |||
| if (clickLogoutCommand == null) | |||
| { | |||
| clickLogoutCommand = new BaseCommand(new Action<object>(o => | |||
| { | |||
| Status = SettingsModel.Status.login; | |||
| })); | |||
| } | |||
| return clickLogoutCommand; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -460,6 +460,19 @@ namespace GameClass.GameObj | |||
| } | |||
| } | |||
| public Prop UseProp(PropType propType) | |||
| { | |||
| lock (gameObjLock) | |||
| { | |||
| foreach (Prop prop in propInventory) | |||
| { | |||
| if (prop.GetPropType() == propType) | |||
| return prop; | |||
| } | |||
| return new NullProp(); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// 如果indexing==GameData.maxNumOfPropInPropInventory表明道具栏为满 | |||
| /// </summary> | |||
| @@ -29,6 +29,15 @@ namespace GameClass.GameObj | |||
| public object ActiveSkillLock => commonSkillLock; | |||
| } | |||
| public class Punish : IActiveSkill | |||
| { | |||
| public int SkillCD => GameData.commonSkillCD; | |||
| public int DurationTime => GameData.commonSkillTime / 10 * 6; | |||
| private readonly object commonSkillLock = new object(); | |||
| public object ActiveSkillLock => commonSkillLock; | |||
| } | |||
| public class NuclearWeapon : IActiveSkill // 核武器 | |||
| { | |||
| public int SkillCD => GameData.commonSkillCD / 3 * 7; | |||
| @@ -86,6 +95,8 @@ namespace GameClass.GameObj | |||
| return ActiveSkillType.UseKnife; | |||
| case CanBeginToCharge: | |||
| return ActiveSkillType.CanBeginToCharge; | |||
| case Punish: | |||
| return ActiveSkillType.Publish; | |||
| default: | |||
| return ActiveSkillType.Null; | |||
| } | |||
| @@ -18,6 +18,7 @@ namespace Gaming | |||
| public bool MovePlayer(Character playerToMove, int moveTimeInMilliseconds, double moveDirection) | |||
| { | |||
| if (!playerToMove.Commandable()) return false; | |||
| playerToMove.PlayerState = PlayerStateType.Moving; | |||
| moveEngine.MoveObj(playerToMove, moveTimeInMilliseconds, moveDirection); | |||
| return true; | |||
| } | |||
| @@ -341,24 +341,24 @@ namespace Gaming | |||
| _ = attackManager.Attack(player, angle); | |||
| } | |||
| } | |||
| public void UseProp(long playerID, int indexing) | |||
| public void UseProp(long playerID, PropType propType) | |||
| { | |||
| if (!gameMap.Timer.IsGaming) | |||
| return; | |||
| Character? player = gameMap.FindPlayer(playerID); | |||
| if (player != null) | |||
| { | |||
| propManager.UseProp(player, indexing); | |||
| propManager.UseProp(player, propType); | |||
| } | |||
| } | |||
| public void ThrowProp(long playerID, int indexing) | |||
| public void ThrowProp(long playerID, PropType propType) | |||
| { | |||
| if (!gameMap.Timer.IsGaming) | |||
| return; | |||
| Character? player = gameMap.FindPlayer(playerID); | |||
| if (player != null) | |||
| { | |||
| propManager.ThrowProp(player, indexing); | |||
| propManager.ThrowProp(player, propType); | |||
| } | |||
| } | |||
| public bool PickProp(long playerID, PropType propType = PropType.Null) | |||
| @@ -373,14 +373,14 @@ namespace Gaming | |||
| return false; | |||
| } | |||
| public bool UseActiveSkill(long playerID, ActiveSkillType activeSkillType) | |||
| public bool UseActiveSkill(long playerID, int skillNum) | |||
| { | |||
| if (!gameMap.Timer.IsGaming) | |||
| return false; | |||
| Character? player = gameMap.FindPlayer(playerID); | |||
| if (player != null) | |||
| { | |||
| return skillManager.UseActiveSkill(player, activeSkillType); | |||
| return skillManager.UseActiveSkill(player, player.Occupation.ListOfIActiveSkill[skillNum]); | |||
| } | |||
| else | |||
| return false; | |||
| @@ -21,11 +21,11 @@ namespace Gaming | |||
| private readonly List<XY> availableCellForGenerateProp; | |||
| public void UseProp(Character player, int indexing) | |||
| public void UseProp(Character player, PropType propType) | |||
| { | |||
| if (player.IsResetting) | |||
| return; | |||
| Prop prop = player.UseProp(indexing); | |||
| Prop prop = player.UseProp(propType); | |||
| switch (prop.GetPropType()) | |||
| { | |||
| case PropType.ShieldOrSpear: | |||
| @@ -43,8 +43,12 @@ namespace Gaming | |||
| break; | |||
| case PropType.AddHpOrAp: | |||
| if (!player.IsGhost()) | |||
| player.HP += GameData.basicTreatmentDegree; | |||
| else player.AddAp(GameData.PropDuration); | |||
| if (player.HP < player.MaxHp) | |||
| { | |||
| player.HP += GameData.basicTreatmentDegree; | |||
| player.AddScore(GameData.ScorePropAddHp); | |||
| } | |||
| else player.AddAp(GameData.PropDuration); | |||
| break; | |||
| default: | |||
| break; | |||
| @@ -102,11 +106,11 @@ namespace Gaming | |||
| return false; | |||
| } | |||
| public void ThrowProp(Character player, int indexing) | |||
| public void ThrowProp(Character player, PropType propType) | |||
| { | |||
| if (!gameMap.Timer.IsGaming || player.IsResetting) | |||
| return; | |||
| Prop prop = player.UseProp(indexing); | |||
| Prop prop = player.UseProp(propType); | |||
| if (prop.GetPropType() == PropType.Null) | |||
| return; | |||
| @@ -76,7 +76,7 @@ namespace Preparation.Interface | |||
| public BulletType InitBullet => BulletType.Null; | |||
| public List<ActiveSkillType> ListOfIActiveSkill => new(new ActiveSkillType[] { ActiveSkillType.CanBeginToCharge }); | |||
| public List<ActiveSkillType> ListOfIActiveSkill => new(new ActiveSkillType[] { ActiveSkillType.Publish }); | |||
| public List<PassiveSkillType> ListOfIPassiveSkill => new(new PassiveSkillType[] { }); | |||
| public const int fixSpeed = 0; | |||
| @@ -116,7 +116,7 @@ namespace Preparation.Interface | |||
| public BulletType InitBullet => BulletType.Null; | |||
| public List<ActiveSkillType> ListOfIActiveSkill => new(new ActiveSkillType[] { }); | |||
| public List<ActiveSkillType> ListOfIActiveSkill => new(new ActiveSkillType[] { ActiveSkillType.CanBeginToCharge }); | |||
| public List<PassiveSkillType> ListOfIPassiveSkill => new(new PassiveSkillType[] { }); | |||
| public const int fixSpeed = GameData.basicFixSpeed * 6 / 10; | |||
| @@ -79,7 +79,7 @@ namespace Preparation.Utility | |||
| Athlete = 2, | |||
| RecoverAfterBattle = 3, | |||
| SpeedUpWhenLeavingGrass = 4, | |||
| PSkill4 = 5, | |||
| Teacher = 5, | |||
| PSkill5 = 6 | |||
| } | |||
| public enum ActiveSkillType // 主动技能 | |||
| @@ -90,7 +90,8 @@ namespace Preparation.Utility | |||
| NuclearWeapon = 3, | |||
| SuperFast = 4, | |||
| UseKnife = 5, | |||
| CanBeginToCharge = 6 | |||
| CanBeginToCharge = 6, | |||
| Publish = 7, | |||
| } | |||
| public enum PassiveSkillType | |||
| { | |||
| @@ -128,11 +128,8 @@ namespace Preparation.Utility | |||
| public const int ScorePropUseShield = 20; | |||
| public const int ScorePropUseSpear = 20; | |||
| public const int ScorePropAddAp = 10; | |||
| public const int ScorePropAddHp = 50; | |||
| public static int ScoreUseProp(PropType prop, bool IsGhost) | |||
| { | |||
| return 0; | |||
| } | |||
| public static int ScoreUseSkill(ActiveSkillType activeSkillType) | |||
| { | |||
| return 0; | |||
| @@ -305,11 +305,11 @@ namespace Server | |||
| foreach (var keyValue in player.TimeUntilActiveSkillAvailable) | |||
| msg.TrickerMessage.TimeUntilSkillAvailable.Add(keyValue.Value); | |||
| for (int i = 0; i < GameData.maxNumOfSkill - player.TimeUntilActiveSkillAvailable.Count(); ++i) | |||
| msg.StudentMessage.TimeUntilSkillAvailable.Add(-1); | |||
| msg.TrickerMessage.TimeUntilSkillAvailable.Add(-1); | |||
| msg.TrickerMessage.Place = ToPlaceType(player.Place); | |||
| foreach (var value in player.PropInventory) | |||
| msg.StudentMessage.Prop.Add(ToPropType(value.GetPropType())); | |||
| msg.TrickerMessage.Prop.Add(ToPropType(value.GetPropType())); | |||
| msg.TrickerMessage.TrickerType = ToTrickerType(player.CharacterType); | |||
| msg.TrickerMessage.Guid = player.ID; | |||
| @@ -262,23 +262,6 @@ | |||
| - [箱子不可被关闭] | |||
| - [箱子内道具最多两个] | |||
| ### 道具 | |||
| - 每次玩家试图捡起道具时,需要确保道具栏有空位 | |||
| - indexing指道具栏数组下标从0开始 | |||
| - 扔道具 | |||
| - Logic内实现 | |||
| ~~~csharp | |||
| public void ThrowProp(long playerID, int indexing) | |||
| ~~~ | |||
| - 对应下标出现空位,不会对数组进行重新排序 | |||
| - 使用道具 | |||
| - Logic内实现 | |||
| ~~~csharp | |||
| public void UseProp(long playerID,int indexing) | |||
| ~~~ | |||
| - 对应下标出现空位,不会对数组进行重新排序 | |||
| ### 治疗 | |||
| - 可行动的求生者可以对受伤的其他求生者进行治疗,治疗完成后会回复被治疗程度的血量。 | |||
| - 治疗时每毫秒增加相当于治疗者治疗速度的被治疗程度 | |||
| @@ -343,4 +326,30 @@ | |||
| #### ~~解除眩晕~~ | |||
| #### ~~自愈~~ | |||
| #### ~~自愈~~ | |||
| ## 道具 | |||
| - 每次玩家试图捡起道具时,需要确保道具栏有空位 | |||
| - indexing指道具栏数组下标从0开始 | |||
| - 扔道具 | |||
| - Logic内实现 | |||
| ~~~csharp | |||
| public void ThrowProp(long playerID, int indexing) | |||
| ~~~ | |||
| - 对应下标出现空位,不会对数组进行重新排序 | |||
| - 使用道具 | |||
| - Logic内实现 | |||
| ~~~csharp | |||
| public void UseProp(long playerID,int indexing) | |||
| ~~~ | |||
| - 对应下标出现空位,不会对数组进行重新排序 | |||
| | 道具 | 对学生增益 | [学生得分条件] | 对搞蛋鬼增益 | [搞蛋鬼得分条件] | | |||
| | :-------- | :-------------------------------------- | :-----------------| :-------------------------------------- |:-----------------| | |||
| | AddSpeed | 提高移动速度,持续10s |不得分| 提高移动速度,持续10s |不得分| | |||
| | AddLifeOrAp |若在10s内Hp归零,该增益消失以使Hp保留100|在10s内Hp归零,得分? |10秒内下一次攻击增伤1800000|10秒内有一次攻击,得分? | | |||
| | AddHpOrAp |回血1500000 | 回血成功 | 10秒内下一次攻击增伤1800000|10秒内有一次攻击,得分? | | |||
| | ShieldOrSpear | 10秒内能抵挡一次伤害 | 10秒内成功抵挡一次伤害 |10秒内下一次攻击能破盾,如果对方无盾,则增伤900000| 10秒内攻击中学生| | |||
| | Key3 | 能开启3教的门 |不得分| 能开启3教的门 |不得分| | |||
| | Key5 | 能开启5教的门 |不得分| 能开启3教的门 |不得分| | |||
| | Key6 | 能开启6教的门 |不得分| 能开启3教的门 |不得分| | |||