| @@ -9,6 +9,7 @@ | |||
| </PropertyGroup> | |||
| <ItemGroup> | |||
| <PackageReference Include="ICSharpCode.SharpZipLib.dll" Version="0.85.4.369" /> | |||
| <PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" /> | |||
| <PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> | |||
| <PackageReference Include="Tencent.QCloud.Cos.Sdk" Version="5.4.34" /> | |||
| @@ -38,17 +38,19 @@ | |||
| <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="选择文件夹" Command="{Binding ClickBrowseCommand}" Visibility="{Binding RouteBoxVis}" /> | |||
| <Button Grid.Row="3" Grid.Column="7" Name="SetBtm" Content="确认并安装" Command="{Binding ClickConfirmCommand}" Visibility="{Binding RouteBoxVis}"/> | |||
| <Button Grid.Row="3" Grid.Column="7" Name="SetBtm" Content="{Binding ConfirmBtnCont}" Command="{Binding ClickConfirmCommand}" Visibility="{Binding RouteBoxVis}"/> | |||
| <Button Grid.Row="4" Grid.Column="6" Grid.ColumnSpan="2" Name="ReadExsisted" Content="从所选文件夹直接读取" Command="{Binding ClickReadCommand}" Visibility="{Binding NewUserVis}"/> | |||
| <Button Grid.Row="3" Grid.Column="2" Grid.ColumnSpan="2" Name="UpdateBtn" Content="{Binding UpdateBtnCont}" Command="{Binding ClickUpdateCommand}" Visibility="{Binding MenuVis}" /> | |||
| <TextBlock Grid.Row="4" Grid.Column="2" Text="{Binding UpdateInfo}" Visibility="{Binding MenuVis}" /> | |||
| <TextBlock Grid.Row="4" Grid.Column="2" Grid.ColumnSpan="2" FontSize="10" Text="{Binding UpdateInfo}" Visibility="{Binding UpdateInfoVis}" /> | |||
| <Button Grid.Row="5" Grid.Column="2" Grid.ColumnSpan="2" Name="MoveBtn" Content="移动文件" Command="{Binding ClickMoveCommand}" Visibility="{Binding MenuVis}" /> | |||
| <Button Grid.Row="6" Grid.Column="2" Grid.ColumnSpan="2" Name="UninstBtn" Content="卸载选手包" Command="{Binding ClickUninstCommand}" Visibility="{Binding MenuVis}" /> | |||
| <Button Grid.Row="7" Grid.Column="2" Grid.ColumnSpan="2" Name="MenuBackBtn" Content="回到登陆界面" Command="{Binding ClickBackCommand}" 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="3" Grid.Column="3" Text="正在下载……" Grid.ColumnSpan="2" Visibility="{Binding ProgressVis}"/> | |||
| <ProgressBar Grid.Row="5" Grid.Column="1" Grid.ColumnSpan="7" Minimum="0" Maximum="100" Name="Progress" Visibility="{Binding ProgressVis}" IsIndeterminate="True"/> | |||
| <TextBlock Grid.Row="4" Grid.Column="1" Grid.ColumnSpan="4" Text="操作完成!你可以继续操作或退出" Visibility="{Binding CompleteVis}"/> | |||
| <Button Grid.Row="6" Grid.Column="1" Name="BackBtn" Content="返回" Command="{Binding ClickBackCommand}" Visibility="{Binding CompleteVis}" Click="BackBtn_Click"/> | |||
| @@ -72,13 +74,14 @@ | |||
| <TextBlock Grid.Row="3" Grid.Column="0" Text="密码:" Visibility="{Binding LoginVis}" /> | |||
| <TextBox Grid.Row="1" Grid.Column="1" Name="Username" Visibility="{Binding LoginVis}" Text="{Binding Username}" /> | |||
| <PasswordBox Grid.Row="3" Grid.Column="1" Name="Password" Visibility="{Binding LoginVis}" c:PasswordHelper.Attach="True" c:PasswordHelper.Password="{Binding Password, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> | |||
| <!--<CheckBox Grid.Row="5" Grid.Column="0" Visibility="{Binding LoginVis}">记住我</CheckBox>--> | |||
| <CheckBox Grid.Row="5" Grid.Column="0" Visibility="{Binding LoginVis}" IsChecked="{Binding RememberMe}">记住我</CheckBox> | |||
| <TextBlock Grid.Row="5" Grid.Column="1" Foreground="Red" Text=" 用户名或密码错误!" Visibility="{Binding LoginFailVis}"/> | |||
| </Grid> | |||
| </StackPanel> | |||
| <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="2" Name="Launch" FontSize="11" Content="{Binding LaunchBtnCont}" Command="{Binding ClickLaunchCommand}" Visibility="{Binding LoginVis}"/> | |||
| <Button Grid.Row="7" Grid.Column="3" Name="ShiftLanguage" FontSize="11" Content="更改语言" Command="{Binding ClickShiftLanguageCommand}" Visibility="{Binding LaunchVis}"/> | |||
| <Button Grid.Row="7" Grid.Column="4" Grid.ColumnSpan="2" Name="Edit" Content="修改文件" Command="{Binding ClickEditCommand}" Visibility="{Binding LoginVis}"/> | |||
| @@ -21,10 +21,16 @@ using System.Net.Http; | |||
| using System.Windows; | |||
| using System.Windows.Shapes; | |||
| //using System.Windows.Forms; | |||
| using System.Threading.Tasks; | |||
| using System.Threading; | |||
| using MessageBox = System.Windows.MessageBox; | |||
| using Downloader; | |||
| using COSXML.Transfer; | |||
| using WebConnect; | |||
| using System.IO.Compression; | |||
| using ICSharpCode.SharpZipLib.Tar; | |||
| using ICSharpCode.SharpZipLib.GZip; | |||
| namespace starter.viewmodel.settings | |||
| { | |||
| @@ -52,6 +58,7 @@ namespace starter.viewmodel.settings | |||
| PlayerNum = "nSelect"; | |||
| UploadReady = false; | |||
| LoginFailed = false; | |||
| launchLanguage = LaunchLanguage.cpp; | |||
| } | |||
| /// <summary> | |||
| @@ -118,7 +125,7 @@ namespace starter.viewmodel.settings | |||
| { | |||
| if (updateInfo.changedFileCount != 0 || updateInfo.newFileCount != 0) | |||
| { | |||
| Updates = "发现新版本"; | |||
| Updates = $"{updateInfo.newFileCount}个新文件,{updateInfo.changedFileCount}个文件变化"; | |||
| } | |||
| return Status.menu; | |||
| } | |||
| @@ -128,6 +135,38 @@ namespace starter.viewmodel.settings | |||
| { | |||
| return await web.LoginToEEsast(client, Username, Password); | |||
| } | |||
| public bool RememberUser() | |||
| { | |||
| int result = 0; | |||
| result |= Web.WriteUserEmail(Username); | |||
| result |= Web.WriteUserPassword(Password); | |||
| return result == 0; | |||
| } | |||
| public bool RecallUser() | |||
| { | |||
| Username = Web.ReadUserEmail(); | |||
| if (Username == null || Username.Equals("")) | |||
| { | |||
| Username = ""; | |||
| return false; | |||
| } | |||
| Password = Web.ReadUserPassword(); | |||
| if (Password == null || Username.Equals("")) | |||
| { | |||
| Password = ""; | |||
| return false; | |||
| } | |||
| return true; | |||
| } | |||
| public bool ForgetUser() | |||
| { | |||
| int result = 0; | |||
| result |= Web.WriteUserEmail(""); | |||
| result |= Web.WriteUserPassword(""); | |||
| return result == 0; | |||
| } | |||
| public bool Update() | |||
| { | |||
| return Tencent_cos_download.Update(); | |||
| @@ -254,6 +293,15 @@ namespace starter.viewmodel.settings | |||
| { | |||
| get; set; | |||
| } | |||
| public bool RememberMe | |||
| { | |||
| get; set; | |||
| } | |||
| public enum LaunchLanguage { cpp, python }; | |||
| public LaunchLanguage launchLanguage | |||
| { | |||
| get; set; | |||
| } | |||
| } | |||
| } | |||
| namespace Downloader | |||
| @@ -419,7 +467,7 @@ namespace Downloader | |||
| Dictionary<string, string> test = request.GetRequestHeaders(); | |||
| request.SetCosProgressCallback(delegate (long completed, long total) | |||
| { | |||
| Console.WriteLine(String.Format("progress = {0:##.##}%", completed * 100.0 / total)); | |||
| //Console.WriteLine(String.Format("progress = {0:##.##}%", completed * 100.0 / total)); | |||
| }); | |||
| // 执行请求 | |||
| GetObjectResult result = cosXml.GetObject(request); | |||
| @@ -463,6 +511,8 @@ namespace Downloader | |||
| { | |||
| if (fst != null) | |||
| fst.Close(); | |||
| if (File.Exists(strFileFullPath)) | |||
| return "conflict"; | |||
| return ""; | |||
| } | |||
| finally | |||
| @@ -521,6 +571,8 @@ namespace Downloader | |||
| MD5 = GetFileMd5Hash(System.IO.Path.Combine(Data.FilePath, pair.Key)); | |||
| if (MD5.Length == 0) // 文档不存在 | |||
| newFileName.Add(pair.Key); | |||
| else if (MD5.Equals("conflict")) | |||
| MessageBox.Show($"文件{pair.Key}已打开,无法检查是否为最新,若需要,请关闭文件稍后手动检查更新", "文件正在使用", MessageBoxButton.OK, MessageBoxImage.Warning); | |||
| else if (MD5 != pair.Value) // MD5不匹配 | |||
| updateFileName.Add(pair.Key); | |||
| } | |||
| @@ -581,7 +633,6 @@ namespace Downloader | |||
| private static void Download() | |||
| { | |||
| Tencent_cos_download Downloader = new Tencent_cos_download(); | |||
| int newFile = 0, updateFile = 0; | |||
| int totalnew = newFileName.Count, totalupdate = updateFileName.Count; | |||
| filenum = totalnew + totalupdate; | |||
| @@ -592,17 +643,17 @@ namespace Downloader | |||
| { | |||
| foreach (string filename in newFileName) | |||
| { | |||
| Console.WriteLine(newFile + 1 + "/" + totalnew + ":开始下载" + filename); | |||
| //Console.WriteLine(newFile + 1 + "/" + totalnew + ":开始下载" + filename); | |||
| Downloader.download(System.IO.Path.Combine(@Data.FilePath, filename), filename); | |||
| Console.WriteLine(filename + "下载完毕!" + Environment.NewLine); | |||
| //Console.WriteLine(filename + "下载完毕!" + Environment.NewLine); | |||
| newFile++; | |||
| } | |||
| foreach (string filename in updateFileName) | |||
| { | |||
| Console.WriteLine(updateFile + 1 + "/" + totalupdate + ":开始下载" + filename); | |||
| //Console.WriteLine(updateFile + 1 + "/" + totalupdate + ":开始下载" + filename); | |||
| File.Delete(System.IO.Path.Combine(@Data.FilePath, filename)); | |||
| Downloader.download(System.IO.Path.Combine(@Data.FilePath, filename), filename); | |||
| Console.WriteLine(filename + "下载完毕!" + Environment.NewLine); | |||
| //Console.WriteLine(filename + "下载完毕!" + Environment.NewLine); | |||
| updateFile++; | |||
| } | |||
| } | |||
| @@ -700,12 +751,35 @@ namespace Downloader | |||
| newFileName.Clear(); | |||
| updateFileName.Clear(); | |||
| foreach (KeyValuePair<string, string> pair in jsonDict) | |||
| newFileName.Add("THUAI6.tar.gz"); | |||
| Download(); | |||
| Stream inStream = null; | |||
| Stream gzipStream = null; | |||
| TarArchive tarArchive = null; | |||
| try | |||
| { | |||
| newFileName.Add(pair.Key); | |||
| using (inStream = File.OpenRead(System.IO.Path.Combine(Data.FilePath, "THUAI6.tar.gz"))) | |||
| { | |||
| using (gzipStream = new GZipInputStream(inStream)) | |||
| { | |||
| tarArchive = TarArchive.CreateInputTarArchive(gzipStream); | |||
| tarArchive.ExtractContents(Data.FilePath); | |||
| tarArchive.Close(); | |||
| } | |||
| } | |||
| } | |||
| Download(); | |||
| catch (Exception ex) | |||
| { | |||
| //出错 | |||
| } | |||
| finally | |||
| { | |||
| if (null != tarArchive) tarArchive.Close(); | |||
| if (null != gzipStream) gzipStream.Close(); | |||
| if (null != inStream) inStream.Close(); | |||
| } | |||
| FileInfo fileInfo = new FileInfo(System.IO.Path.Combine(Data.FilePath, "THUAI6.tar.gz")); | |||
| fileInfo.Delete(); | |||
| string json2; | |||
| Dictionary<string, string> dict = new Dictionary<string, string>(); | |||
| string existpath = System.IO.Path.Combine(Data.dataPath, "THUAI6.json"); | |||
| @@ -732,6 +806,8 @@ namespace Downloader | |||
| using StreamWriter sw = new StreamWriter(fs2); | |||
| fs2.SetLength(0); | |||
| sw.Write(JsonConvert.SerializeObject(dict)); | |||
| Check(); | |||
| Download(); | |||
| } | |||
| public static void Change_all_hash(string topDir, Dictionary<string, string> jsonDict) // 更改HASH | |||
| @@ -743,7 +819,7 @@ namespace Downloader | |||
| foreach (FileInfo NextFile in theFolder.GetFiles()) | |||
| { | |||
| string filepath = topDir + @"/" + NextFile.Name; // 文件路径 | |||
| Console.WriteLine(filepath); | |||
| //Console.WriteLine(filepath); | |||
| foreach (KeyValuePair<string, string> pair in jsonDict) | |||
| { | |||
| if (System.IO.Path.Equals(filepath, System.IO.Path.Combine(Data.FilePath, pair.Key).Replace('\\', '/'))) | |||
| @@ -812,22 +888,20 @@ namespace Downloader | |||
| 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))); | |||
| //DirectoryInfo player = new DirectoryInfo(System.IO.Path.GetFullPath(System.IO.Path.Combine(Data.FilePath, playerFolder))); | |||
| FileInfo[] allfile = di.GetFiles(); | |||
| try | |||
| { | |||
| foreach (FileInfo file in di.GetFiles()) | |||
| foreach (FileInfo file in allfile) | |||
| { | |||
| //if(file.Name == "AI.cpp" || file.Name == "AI.py") | |||
| //{ | |||
| // string filename = System.IO.Path.GetFileName(file.FullName); | |||
| // file.MoveTo(System.IO.Path.Combine(Data.FilePath, filename)); | |||
| // continue; | |||
| //} | |||
| file.Delete(); | |||
| } | |||
| foreach (FileInfo file in player.GetFiles()) | |||
| { | |||
| if (file.Name == "AI.cpp" || file.Name == "AI.py") | |||
| { | |||
| continue; | |||
| } | |||
| string filename = System.IO.Path.GetFileName(file.FullName); | |||
| file.MoveTo(System.IO.Path.Combine(Data.FilePath, filename)); | |||
| } | |||
| foreach (DirectoryInfo subdi in di.GetDirectories()) | |||
| { | |||
| subdi.Delete(true); | |||
| @@ -895,7 +969,6 @@ namespace Downloader | |||
| Console.WriteLine("文件已经打开,请关闭后再删除"); | |||
| return -1; | |||
| } | |||
| Console.WriteLine($"删除成功!player文件夹中的文件已经放在{ProgramName}的根目录下"); | |||
| return 0; | |||
| } | |||
| @@ -1075,7 +1148,7 @@ namespace WebConnect | |||
| switch (response.StatusCode) | |||
| { | |||
| case System.Net.HttpStatusCode.OK: | |||
| Console.WriteLine("Success login"); | |||
| //Console.WriteLine("Success login"); | |||
| token = (System.Text.Json.JsonSerializer.Deserialize(await response.Content.ReadAsStreamAsync(), typeof(LoginResponse), new JsonSerializerOptions() | |||
| { | |||
| PropertyNamingPolicy = JsonNamingPolicy.CamelCase, | |||
| @@ -1091,7 +1164,7 @@ namespace WebConnect | |||
| default: | |||
| int code = ((int)response.StatusCode); | |||
| Console.WriteLine(code); | |||
| //Console.WriteLine(code); | |||
| if (code == 401) | |||
| { | |||
| //Console.WriteLine("邮箱或密码错误!"); | |||
| @@ -1175,13 +1248,13 @@ namespace WebConnect | |||
| uploadTask.progressCallback = delegate (long completed, long total) | |||
| { | |||
| Console.WriteLine(string.Format("progress = {0:##.##}%", completed * 100.0 / total)); | |||
| //Console.WriteLine(string.Format("progress = {0:##.##}%", completed * 100.0 / total)); | |||
| }; | |||
| try | |||
| { | |||
| COSXMLUploadTask.UploadTaskResult result = await transferManager.UploadAsync(uploadTask); | |||
| Console.WriteLine(result.GetResultInfo()); | |||
| //Console.WriteLine(result.GetResultInfo()); | |||
| string eTag = result.eTag; | |||
| //到这里应该是成功了,但是因为我没有试过,也不知道具体情况,可能还要根据result的内容判断 | |||
| } | |||
| @@ -7,11 +7,19 @@ using Downloader; | |||
| using MessageBox = System.Windows.MessageBox; | |||
| using System.Configuration; | |||
| using System.Drawing.Design; | |||
| using Application = System.Windows.Application; | |||
| using System.ComponentModel; | |||
| using Installer; | |||
| using static System.Windows.Forms.VisualStyles.VisualStyleElement; | |||
| using System.IO; | |||
| namespace starter.viewmodel.settings | |||
| { | |||
| public class SettingsViewModel : NotificationObject | |||
| { | |||
| //定义BackgroundWorker | |||
| BackgroundWorker asyncDownloader; | |||
| BackgroundWorker asyncUpdater; | |||
| /// <summary> | |||
| /// Model object | |||
| /// </summary> | |||
| @@ -22,17 +30,40 @@ namespace starter.viewmodel.settings | |||
| public SettingsViewModel() | |||
| { | |||
| //Program.Tencent_cos_download.UpdateHash(); | |||
| //WebConnect.Web.WriteUserEmail("wangsk21@mails.tsinghua.edu.cn"); | |||
| //实例化BackgroundWorker | |||
| asyncDownloader = new BackgroundWorker(); | |||
| asyncUpdater = new BackgroundWorker(); | |||
| //指示BackgroundWorker是否可以报告进度更新 | |||
| //当该属性值为True是,将可以成功调用ReportProgress方法,否则将引发InvalidOperationException异常。 | |||
| asyncDownloader.WorkerReportsProgress = true; | |||
| asyncUpdater.WorkerReportsProgress = true; | |||
| //挂载方法: | |||
| asyncDownloader.DoWork += AsyncDownloader_DoWork; | |||
| asyncUpdater.DoWork += AsyncUpdater_DoWork; | |||
| //完成通知器: | |||
| asyncDownloader.RunWorkerCompleted += AsyncDownloader_RunWorkerCompleted; | |||
| asyncUpdater.RunWorkerCompleted += AsyncUpdater_RunWorkerCompleted; | |||
| UpdateInfoVis = Visibility.Collapsed; | |||
| if (Downloader.Program.Tencent_cos_download.CheckAlreadyDownload()) | |||
| { | |||
| obj.checkUpdate(); | |||
| Status = SettingsModel.Status.login; | |||
| this.RaisePropertyChanged("WindowWidth"); | |||
| //TODO:在启动时立刻检查更新,确保选手启动最新版选手包 | |||
| //TODO:若有更新,将启动键改为更新键; | |||
| //TODO:相应地,使用login界面启动; | |||
| //TODO:结构:上方为登录框架,下方有“修改选手包”按钮 | |||
| this.RaisePropertyChanged("LaunchVis"); | |||
| if (obj.RecallUser()) | |||
| RememberMe = true; | |||
| else | |||
| RememberMe = false; | |||
| this.RaisePropertyChanged("RememberMe"); | |||
| //在启动时立刻检查更新,确保选手启动最新版选手包 | |||
| //若有更新,将启动键改为更新键; | |||
| //相应地,使用login界面启动; | |||
| //结构:上方为登录框架,下方有“修改选手包”按钮 | |||
| } | |||
| else | |||
| { | |||
| @@ -42,6 +73,85 @@ namespace starter.viewmodel.settings | |||
| } | |||
| } | |||
| private void AsyncDownloader_RunWorkerCompleted(object? sender, RunWorkerCompletedEventArgs e) | |||
| { | |||
| if (e.Result == null) | |||
| { | |||
| Status = SettingsModel.Status.error; | |||
| } | |||
| else if ((bool)e.Result) | |||
| { | |||
| Status = SettingsModel.Status.successful; | |||
| } | |||
| else | |||
| { | |||
| Status = SettingsModel.Status.newUser; | |||
| } | |||
| } | |||
| private void AsyncUpdater_RunWorkerCompleted(object? sender, RunWorkerCompletedEventArgs e) | |||
| { | |||
| if (e.Result == null) | |||
| { | |||
| Status = SettingsModel.Status.error; | |||
| } | |||
| else | |||
| { | |||
| this.RaisePropertyChanged("LaunchVis"); | |||
| if ((int)e.Result == 1) | |||
| { | |||
| Status = SettingsModel.Status.successful; | |||
| this.RaisePropertyChanged("UpdateBtnCont"); | |||
| this.RaisePropertyChanged("UpdateInfo"); | |||
| this.RaisePropertyChanged("LaunchBtnCont"); | |||
| } | |||
| else if ((int)e.Result == 2) | |||
| { | |||
| Status = SettingsModel.Status.login; | |||
| this.RaisePropertyChanged("UpdateBtnCont"); | |||
| this.RaisePropertyChanged("LaunchBtnCont"); | |||
| this.RaisePropertyChanged("UpdateInfo"); | |||
| } | |||
| } | |||
| } | |||
| private void AsyncUpdater_DoWork(object? sender, DoWorkEventArgs e) | |||
| { | |||
| if (asyncUpdater.CancellationPending) | |||
| { | |||
| e.Cancel = true; | |||
| return; | |||
| } | |||
| else | |||
| { | |||
| if (obj.Update()) | |||
| if (e.Argument.ToString().Equals("Manual")) | |||
| { | |||
| e.Result = 1; | |||
| } | |||
| else | |||
| e.Result = 2; | |||
| else | |||
| e.Result = -1; | |||
| } | |||
| } | |||
| private void AsyncDownloader_DoWork(object? sender, DoWorkEventArgs e) | |||
| { | |||
| if (asyncDownloader.CancellationPending) | |||
| { | |||
| e.Cancel = true; | |||
| return; | |||
| } | |||
| else | |||
| { | |||
| if (obj.install()) | |||
| e.Result = true; | |||
| else | |||
| e.Result = false; | |||
| } | |||
| } | |||
| //TODO:参赛界面:包括上传参赛代码、申请对战 | |||
| //TODO:界面中应包含上次对战完成提示及下载回放按钮 | |||
| @@ -95,6 +205,10 @@ namespace starter.viewmodel.settings | |||
| this.RaisePropertyChanged("CompleteVis"); | |||
| this.RaisePropertyChanged("WindowWidth"); | |||
| this.RaisePropertyChanged("WebVis"); | |||
| this.RaisePropertyChanged("CoverVis"); | |||
| this.RaisePropertyChanged("LaunchVis"); | |||
| this.RaisePropertyChanged("NewUserVis"); | |||
| this.RaisePropertyChanged("ConfirmBtnCont"); | |||
| } | |||
| } | |||
| public string Intro | |||
| @@ -128,9 +242,9 @@ namespace starter.viewmodel.settings | |||
| { | |||
| case SettingsModel.Status.newUser: | |||
| return "将主体程序安装在:"; | |||
| return "将选手包安装在(将创建THUAI6文件夹):"; | |||
| case SettingsModel.Status.move: | |||
| return "将主体程序移动到:"; | |||
| return "将选手包移动到(THUAI6文件夹将会被整体移动):"; | |||
| default: | |||
| return ""; | |||
| } | |||
| @@ -179,7 +293,10 @@ namespace starter.viewmodel.settings | |||
| public string Route | |||
| { | |||
| get => obj.Route; | |||
| get | |||
| { | |||
| return obj.Route; | |||
| } | |||
| set | |||
| { | |||
| obj.Route = value; | |||
| @@ -211,6 +328,27 @@ namespace starter.viewmodel.settings | |||
| return obj.CodeRoute.Substring(obj.CodeRoute.LastIndexOf('/') == -1 ? obj.CodeRoute.LastIndexOf('\\') + 1 : obj.CodeRoute.LastIndexOf('/') + 1); | |||
| } | |||
| } | |||
| public bool RememberMe | |||
| { | |||
| get | |||
| { | |||
| return obj.RememberMe; | |||
| } | |||
| set | |||
| { | |||
| obj.RememberMe = value; | |||
| this.RaisePropertyChanged("RememberMe"); | |||
| } | |||
| } | |||
| public Visibility NewUserVis | |||
| { | |||
| get | |||
| { | |||
| return Status == SettingsModel.Status.newUser ? Visibility.Visible : Visibility.Collapsed; | |||
| } | |||
| } | |||
| public Visibility MenuVis | |||
| { | |||
| get | |||
| @@ -279,6 +417,19 @@ namespace starter.viewmodel.settings | |||
| get { return obj.UploadReady ? Visibility.Visible : Visibility.Collapsed; } | |||
| } | |||
| public Visibility UpdateInfoVis | |||
| { | |||
| get; set; | |||
| } | |||
| public Visibility LaunchVis | |||
| { | |||
| get | |||
| { | |||
| return obj.status == SettingsModel.Status.login && (!obj.UpdatePlanned) ? Visibility.Visible : Visibility.Collapsed; | |||
| } | |||
| } | |||
| public string UpdateBtnCont | |||
| { | |||
| get | |||
| @@ -293,14 +444,21 @@ namespace starter.viewmodel.settings | |||
| if (obj.UpdatePlanned) | |||
| return obj.Updates; | |||
| else | |||
| return ""; | |||
| return "已是最新版本"; | |||
| } | |||
| } | |||
| public string LaunchBtnCont | |||
| { | |||
| get | |||
| { | |||
| return obj.UpdatePlanned ? "更新" : "启动"; | |||
| string ans; | |||
| if (obj.UpdatePlanned) | |||
| ans = "更新"; | |||
| else if (obj.launchLanguage == SettingsModel.LaunchLanguage.cpp) | |||
| ans = "启动c++包"; | |||
| else | |||
| ans = "启动python包"; | |||
| return ans; | |||
| } | |||
| } | |||
| public string UploadBtnCont | |||
| @@ -310,6 +468,28 @@ namespace starter.viewmodel.settings | |||
| return obj.UploadReady ? "上传代码" : "选择代码上传"; | |||
| } | |||
| } | |||
| public string ShiftLanguageBtnCont | |||
| { | |||
| get | |||
| { | |||
| return obj.launchLanguage == SettingsModel.LaunchLanguage.cpp ? "改为python" : "改为c++"; | |||
| } | |||
| } | |||
| public string ConfirmBtnCont | |||
| { | |||
| get | |||
| { | |||
| switch (Status) | |||
| { | |||
| case SettingsModel.Status.newUser: | |||
| return "确认并安装"; | |||
| case SettingsModel.Status.move: | |||
| return "确认并移动"; | |||
| default: | |||
| return ""; | |||
| } | |||
| } | |||
| } | |||
| public string RouteSelectWindow(string type) | |||
| { | |||
| @@ -365,16 +545,22 @@ namespace starter.viewmodel.settings | |||
| { | |||
| Status = SettingsModel.Status.working; | |||
| this.RaisePropertyChanged("ProgressVis"); | |||
| if (obj.install()) | |||
| /*if (obj.install()) | |||
| { | |||
| Status = SettingsModel.Status.successful; | |||
| }*/ | |||
| if (asyncDownloader.IsBusy) | |||
| return; | |||
| else | |||
| { | |||
| asyncDownloader.RunWorkerAsync(); | |||
| } | |||
| } | |||
| else if (Status == SettingsModel.Status.move) | |||
| { | |||
| Status = SettingsModel.Status.working; | |||
| this.RaisePropertyChanged("ProgressVis"); | |||
| //Status = SettingsModel.Status.working; | |||
| //this.RaisePropertyChanged("ProgressVis"); | |||
| switch (obj.move()) | |||
| { | |||
| case -1: | |||
| @@ -400,11 +586,14 @@ namespace starter.viewmodel.settings | |||
| { | |||
| clickUpdateCommand = new BaseCommand(new Action<object>(o => | |||
| { | |||
| this.RaisePropertyChanged("UpdateInfoVis"); | |||
| if (obj.UpdatePlanned) | |||
| { | |||
| UpdateInfoVis = Visibility.Collapsed; | |||
| this.RaisePropertyChanged("UpdateInfoVis"); | |||
| Status = SettingsModel.Status.working; | |||
| this.RaisePropertyChanged("ProgressVis"); | |||
| if (obj.Update()) | |||
| /*if (obj.Update()) | |||
| { | |||
| Status = SettingsModel.Status.successful; | |||
| @@ -413,15 +602,22 @@ namespace starter.viewmodel.settings | |||
| } | |||
| else | |||
| Status = SettingsModel.Status.error; | |||
| Status = SettingsModel.Status.error;*/ | |||
| if (asyncUpdater.IsBusy) | |||
| return; | |||
| else | |||
| asyncUpdater.RunWorkerAsync("Manual"); | |||
| } | |||
| else | |||
| { | |||
| UpdateInfoVis = Visibility.Visible; | |||
| this.RaisePropertyChanged("UpdateInfoVis"); | |||
| Status = SettingsModel.Status.working; | |||
| this.RaisePropertyChanged("ProgressVis"); | |||
| Status = obj.checkUpdate(); | |||
| this.RaisePropertyChanged("UpdateBtnCont"); | |||
| this.RaisePropertyChanged("UpdateInfo"); | |||
| this.RaisePropertyChanged("LaunchVis"); | |||
| } | |||
| })); | |||
| } | |||
| @@ -452,8 +648,8 @@ namespace starter.viewmodel.settings | |||
| { | |||
| clickUninstCommand = new BaseCommand(new Action<object>(o => | |||
| { | |||
| Status = SettingsModel.Status.working; | |||
| this.RaisePropertyChanged("ProgressVis"); | |||
| UpdateInfoVis = Visibility.Collapsed; | |||
| this.RaisePropertyChanged("UpdateInfoVis"); | |||
| switch (obj.Uninst()) | |||
| { | |||
| case -1: | |||
| @@ -461,13 +657,15 @@ namespace starter.viewmodel.settings | |||
| MessageBox.Show("文件已经打开,请关闭后再删除", "", MessageBoxButton.OK, MessageBoxImage.Warning, MessageBoxResult.OK); | |||
| break; | |||
| case 0: | |||
| Status = SettingsModel.Status.successful; | |||
| Status = SettingsModel.Status.newUser; | |||
| MessageBox.Show($"删除成功!player文件夹中的文件已经放在{Downloader.Program.ProgramName}的根目录下", "", MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.OK); | |||
| break; | |||
| default: | |||
| Status = SettingsModel.Status.error; | |||
| break; | |||
| } | |||
| })); | |||
| } | |||
| return clickUninstCommand; | |||
| @@ -491,6 +689,22 @@ namespace starter.viewmodel.settings | |||
| case 0: | |||
| obj.LoginFailed = false; | |||
| Status = SettingsModel.Status.web; | |||
| if (obj.RememberMe) | |||
| { | |||
| obj.RememberUser(); | |||
| RememberMe = true; | |||
| this.RaisePropertyChanged("RememberMe"); | |||
| } | |||
| else | |||
| { | |||
| obj.ForgetUser(); | |||
| RememberMe = false; | |||
| this.RaisePropertyChanged("RememberMe"); | |||
| Username = ""; | |||
| Password = ""; | |||
| this.RaisePropertyChanged("Username"); | |||
| this.RaisePropertyChanged("Password"); | |||
| } | |||
| this.RaisePropertyChanged("CoverVis"); | |||
| break; | |||
| case -2: | |||
| @@ -517,15 +731,10 @@ namespace starter.viewmodel.settings | |||
| { | |||
| Status = SettingsModel.Status.working; | |||
| this.RaisePropertyChanged("ProgressVis"); | |||
| if (obj.Update()) | |||
| { | |||
| this.RaisePropertyChanged("UpdateBtnCont"); | |||
| this.RaisePropertyChanged("LaunchBtnCont"); | |||
| Status = SettingsModel.Status.login; | |||
| this.RaisePropertyChanged("UpdateInfo"); | |||
| } | |||
| if (asyncUpdater.IsBusy) | |||
| return; | |||
| else | |||
| Status = SettingsModel.Status.error; | |||
| asyncUpdater.RunWorkerAsync("Auto"); | |||
| } | |||
| else if (!obj.Launch()) | |||
| { | |||
| @@ -546,6 +755,9 @@ namespace starter.viewmodel.settings | |||
| clickEditCommand = new BaseCommand(new Action<object>(o => | |||
| { | |||
| Status = SettingsModel.Status.menu; | |||
| if (obj.UpdatePlanned) | |||
| UpdateInfoVis = Visibility.Visible; | |||
| this.RaisePropertyChanged("UpdateInfoVis"); | |||
| })); | |||
| } | |||
| return clickEditCommand; | |||
| @@ -560,6 +772,8 @@ namespace starter.viewmodel.settings | |||
| { | |||
| clickBackCommand = new BaseCommand(new Action<object>(o => | |||
| { | |||
| UpdateInfoVis = Visibility.Collapsed; | |||
| this.RaisePropertyChanged("UpdateInfoVis"); | |||
| if (Downloader.Program.Tencent_cos_download.CheckAlreadyDownload()) | |||
| Status = SettingsModel.Status.login; | |||
| else | |||
| @@ -671,12 +885,51 @@ namespace starter.viewmodel.settings | |||
| { | |||
| clickExitCommand = new BaseCommand(new Action<object>(o => | |||
| { | |||
| System.Windows.Application.Current.Shutdown(); | |||
| Application.Current.Shutdown(); | |||
| })); | |||
| } | |||
| return clickExitCommand; | |||
| } | |||
| } | |||
| private BaseCommand clickShiftLanguageCommand; | |||
| public BaseCommand ClickShiftLanguageCommand | |||
| { | |||
| get | |||
| { | |||
| if (clickShiftLanguageCommand == null) | |||
| { | |||
| clickShiftLanguageCommand = new BaseCommand(new Action<object>(o => | |||
| { | |||
| if (obj.launchLanguage == SettingsModel.LaunchLanguage.cpp) | |||
| obj.launchLanguage = SettingsModel.LaunchLanguage.python; | |||
| else | |||
| obj.launchLanguage = SettingsModel.LaunchLanguage.cpp; | |||
| this.RaisePropertyChanged("ShiftLanguageBtnCont"); | |||
| this.RaisePropertyChanged("LaunchBtnCont"); | |||
| })); | |||
| } | |||
| return clickShiftLanguageCommand; | |||
| } | |||
| } | |||
| private BaseCommand clickReadCommand; | |||
| public BaseCommand ClickReadCommand | |||
| { | |||
| get | |||
| { | |||
| if (clickReadCommand == null) | |||
| { | |||
| clickReadCommand = new BaseCommand(new Action<object>(o => | |||
| { | |||
| if (!Directory.Exists(Route + "/THUAI6")) | |||
| Route = Route.Substring(0, Route.Length - 7); | |||
| Program.Data.ResetFilepath(Route); | |||
| if (Program.Tencent_cos_download.CheckAlreadyDownload()) | |||
| Status = SettingsModel.Status.login; | |||
| })); | |||
| } | |||
| return clickReadCommand; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -5,4 +5,4 @@ | |||
| "commandLineArgs": "--port 8888 --characterID 3 --type 1 --occupation 5" | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -52,7 +52,11 @@ V4.8 | |||
| - **x坐标轴正方向竖直向下,y坐标轴正方向水平向右**; | |||
| - **极坐标以x坐标轴为极轴,角度逆时针为正方向**。 | |||
| - 地图由50 * 50个格子构成,每个格子代表1000 * 1000的正方形。每个格子的编号(CellX,CellY)可以计算得到: | |||
| - $$CellX=\frac{x}{1000},CellY=\frac{y}{1000}$$ | |||
| $$ | |||
| CellX=\frac{x}{1000},CellY=\frac{y}{1000} | |||
| $$ | |||
| - 格子有对应区域类型:陆地、墙、草地、教室、校门、隐藏校门、门、窗、箱子 | |||
| ### 人物 | |||
| @@ -1,10 +1,16 @@ | |||
| # 使用文档 | |||
| 本文档仅供Windows选手参考,Linux选手仿照本文档即可 | |||
| 本文档仅供Windows选手参考,Linux选手仿照本文档即可。 | |||
| 使用python语言的选手要先运行`win/GeneratePythonProto.cmd`,更详细说明请参考`Tool_tutorial.pdf`。 | |||
| ## 路径 | |||
| Windows选手使用脚本位于Win文件夹下,Linux选手使用脚本位于Linux文件夹下 | |||
| Windows选手使用脚本位于Win文件夹下,Linux选手使用脚本位于Linux文件夹下。 | |||
| 对于c++选手,在 AI.cpp 里写代码,AI::play 函数是代码的编写入口,启动游戏前要进行编译 | |||
| 对于python选手,在AI.py里写代码,启动游戏前要进行编译 | |||
| ## 游戏启动方式(For Debug) | |||
| @@ -94,11 +100,7 @@ Server脚本中参数格式一般如下: | |||
| ## Client | |||
| ### C++接口 | |||
| 选手用Visual Studio打开CAPI.sln,编写AI.cpp,建议用Debug模式生成以方便自己调试,然后可以使用`RunCpp.cmd`启动。 | |||
| `RunCpp.cmd`的脚本参数格式如下: | |||
| `RunCpp.cmd`或`RunPython.cmd`的脚本参数格式如下: | |||
| ```shell | |||
| -I 127.0.0.1 -P 8888 -p 0 -d -o -w | |||