| @@ -38,17 +38,19 @@ | |||||
| <TextBox Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="5" Name="RouteTxtBox" Text="{Binding Route}" Visibility="{Binding RouteBoxVis}"/> | <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="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}" /> | <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="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="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}" /> | <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}"/> | <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"/> | <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}" /> | <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}" /> | <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}"/> | <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}"/> | <TextBlock Grid.Row="5" Grid.Column="1" Foreground="Red" Text=" 用户名或密码错误!" Visibility="{Binding LoginFailVis}"/> | ||||
| </Grid> | </Grid> | ||||
| </StackPanel> | </StackPanel> | ||||
| <Button Grid.Row="7" Grid.Column="1" Name="Login" Content="登录" Command="{Binding ClickLoginCommand}" Visibility="{Binding LoginVis}"/> | <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}"/> | <Button Grid.Row="7" Grid.Column="4" Grid.ColumnSpan="2" Name="Edit" Content="修改文件" Command="{Binding ClickEditCommand}" Visibility="{Binding LoginVis}"/> | ||||
| @@ -21,10 +21,13 @@ using System.Net.Http; | |||||
| using System.Windows; | using System.Windows; | ||||
| using System.Windows.Shapes; | using System.Windows.Shapes; | ||||
| //using System.Windows.Forms; | //using System.Windows.Forms; | ||||
| using System.Threading.Tasks; | |||||
| using System.Threading; | |||||
| using MessageBox = System.Windows.MessageBox; | using MessageBox = System.Windows.MessageBox; | ||||
| using Downloader; | using Downloader; | ||||
| using COSXML.Transfer; | using COSXML.Transfer; | ||||
| using WebConnect; | |||||
| using System.IO.Compression; | using System.IO.Compression; | ||||
| using ICSharpCode.SharpZipLib.Tar; | using ICSharpCode.SharpZipLib.Tar; | ||||
| using ICSharpCode.SharpZipLib.GZip; | using ICSharpCode.SharpZipLib.GZip; | ||||
| @@ -55,6 +58,7 @@ namespace starter.viewmodel.settings | |||||
| PlayerNum = "nSelect"; | PlayerNum = "nSelect"; | ||||
| UploadReady = false; | UploadReady = false; | ||||
| LoginFailed = false; | LoginFailed = false; | ||||
| launchLanguage = LaunchLanguage.cpp; | |||||
| } | } | ||||
| /// <summary> | /// <summary> | ||||
| @@ -121,7 +125,7 @@ namespace starter.viewmodel.settings | |||||
| { | { | ||||
| if (updateInfo.changedFileCount != 0 || updateInfo.newFileCount != 0) | if (updateInfo.changedFileCount != 0 || updateInfo.newFileCount != 0) | ||||
| { | { | ||||
| Updates = "发现新版本"; | |||||
| Updates = $"{updateInfo.newFileCount}个新文件,{updateInfo.changedFileCount}个文件变化"; | |||||
| } | } | ||||
| return Status.menu; | return Status.menu; | ||||
| } | } | ||||
| @@ -131,6 +135,38 @@ namespace starter.viewmodel.settings | |||||
| { | { | ||||
| return await web.LoginToEEsast(client, Username, Password); | 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() | public bool Update() | ||||
| { | { | ||||
| return Tencent_cos_download.Update(); | return Tencent_cos_download.Update(); | ||||
| @@ -257,6 +293,15 @@ namespace starter.viewmodel.settings | |||||
| { | { | ||||
| get; set; | get; set; | ||||
| } | } | ||||
| public bool RememberMe | |||||
| { | |||||
| get; set; | |||||
| } | |||||
| public enum LaunchLanguage { cpp, python }; | |||||
| public LaunchLanguage launchLanguage | |||||
| { | |||||
| get; set; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| namespace Downloader | namespace Downloader | ||||
| @@ -422,7 +467,7 @@ namespace Downloader | |||||
| Dictionary<string, string> test = request.GetRequestHeaders(); | Dictionary<string, string> test = request.GetRequestHeaders(); | ||||
| request.SetCosProgressCallback(delegate (long completed, long total) | 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); | GetObjectResult result = cosXml.GetObject(request); | ||||
| @@ -466,6 +511,8 @@ namespace Downloader | |||||
| { | { | ||||
| if (fst != null) | if (fst != null) | ||||
| fst.Close(); | fst.Close(); | ||||
| if (File.Exists(strFileFullPath)) | |||||
| return "conflict"; | |||||
| return ""; | return ""; | ||||
| } | } | ||||
| finally | finally | ||||
| @@ -524,6 +571,8 @@ namespace Downloader | |||||
| MD5 = GetFileMd5Hash(System.IO.Path.Combine(Data.FilePath, pair.Key)); | MD5 = GetFileMd5Hash(System.IO.Path.Combine(Data.FilePath, pair.Key)); | ||||
| if (MD5.Length == 0) // 文档不存在 | if (MD5.Length == 0) // 文档不存在 | ||||
| newFileName.Add(pair.Key); | newFileName.Add(pair.Key); | ||||
| else if (MD5.Equals("conflict")) | |||||
| MessageBox.Show($"文件{pair.Key}已打开,无法检查是否为最新,若需要,请关闭文件稍后手动检查更新", "文件正在使用", MessageBoxButton.OK, MessageBoxImage.Warning); | |||||
| else if (MD5 != pair.Value) // MD5不匹配 | else if (MD5 != pair.Value) // MD5不匹配 | ||||
| updateFileName.Add(pair.Key); | updateFileName.Add(pair.Key); | ||||
| } | } | ||||
| @@ -584,7 +633,6 @@ namespace Downloader | |||||
| private static void Download() | private static void Download() | ||||
| { | { | ||||
| Tencent_cos_download Downloader = new Tencent_cos_download(); | Tencent_cos_download Downloader = new Tencent_cos_download(); | ||||
| int newFile = 0, updateFile = 0; | int newFile = 0, updateFile = 0; | ||||
| int totalnew = newFileName.Count, totalupdate = updateFileName.Count; | int totalnew = newFileName.Count, totalupdate = updateFileName.Count; | ||||
| filenum = totalnew + totalupdate; | filenum = totalnew + totalupdate; | ||||
| @@ -595,17 +643,17 @@ namespace Downloader | |||||
| { | { | ||||
| foreach (string filename in newFileName) | 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); | Downloader.download(System.IO.Path.Combine(@Data.FilePath, filename), filename); | ||||
| Console.WriteLine(filename + "下载完毕!" + Environment.NewLine); | |||||
| //Console.WriteLine(filename + "下载完毕!" + Environment.NewLine); | |||||
| newFile++; | newFile++; | ||||
| } | } | ||||
| foreach (string filename in updateFileName) | 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)); | File.Delete(System.IO.Path.Combine(@Data.FilePath, filename)); | ||||
| Downloader.download(System.IO.Path.Combine(@Data.FilePath, filename), filename); | Downloader.download(System.IO.Path.Combine(@Data.FilePath, filename), filename); | ||||
| Console.WriteLine(filename + "下载完毕!" + Environment.NewLine); | |||||
| //Console.WriteLine(filename + "下载完毕!" + Environment.NewLine); | |||||
| updateFile++; | updateFile++; | ||||
| } | } | ||||
| } | } | ||||
| @@ -771,7 +819,7 @@ namespace Downloader | |||||
| foreach (FileInfo NextFile in theFolder.GetFiles()) | foreach (FileInfo NextFile in theFolder.GetFiles()) | ||||
| { | { | ||||
| string filepath = topDir + @"/" + NextFile.Name; // 文件路径 | string filepath = topDir + @"/" + NextFile.Name; // 文件路径 | ||||
| Console.WriteLine(filepath); | |||||
| //Console.WriteLine(filepath); | |||||
| foreach (KeyValuePair<string, string> pair in jsonDict) | foreach (KeyValuePair<string, string> pair in jsonDict) | ||||
| { | { | ||||
| if (System.IO.Path.Equals(filepath, System.IO.Path.Combine(Data.FilePath, pair.Key).Replace('\\', '/'))) | if (System.IO.Path.Equals(filepath, System.IO.Path.Combine(Data.FilePath, pair.Key).Replace('\\', '/'))) | ||||
| @@ -921,7 +969,6 @@ namespace Downloader | |||||
| Console.WriteLine("文件已经打开,请关闭后再删除"); | Console.WriteLine("文件已经打开,请关闭后再删除"); | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| Console.WriteLine($"删除成功!player文件夹中的文件已经放在{ProgramName}的根目录下"); | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -1101,7 +1148,7 @@ namespace WebConnect | |||||
| switch (response.StatusCode) | switch (response.StatusCode) | ||||
| { | { | ||||
| case System.Net.HttpStatusCode.OK: | 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() | token = (System.Text.Json.JsonSerializer.Deserialize(await response.Content.ReadAsStreamAsync(), typeof(LoginResponse), new JsonSerializerOptions() | ||||
| { | { | ||||
| PropertyNamingPolicy = JsonNamingPolicy.CamelCase, | PropertyNamingPolicy = JsonNamingPolicy.CamelCase, | ||||
| @@ -1117,7 +1164,7 @@ namespace WebConnect | |||||
| default: | default: | ||||
| int code = ((int)response.StatusCode); | int code = ((int)response.StatusCode); | ||||
| Console.WriteLine(code); | |||||
| //Console.WriteLine(code); | |||||
| if (code == 401) | if (code == 401) | ||||
| { | { | ||||
| //Console.WriteLine("邮箱或密码错误!"); | //Console.WriteLine("邮箱或密码错误!"); | ||||
| @@ -1201,13 +1248,13 @@ namespace WebConnect | |||||
| uploadTask.progressCallback = delegate (long completed, long total) | 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 | try | ||||
| { | { | ||||
| COSXMLUploadTask.UploadTaskResult result = await transferManager.UploadAsync(uploadTask); | COSXMLUploadTask.UploadTaskResult result = await transferManager.UploadAsync(uploadTask); | ||||
| Console.WriteLine(result.GetResultInfo()); | |||||
| //Console.WriteLine(result.GetResultInfo()); | |||||
| string eTag = result.eTag; | string eTag = result.eTag; | ||||
| //到这里应该是成功了,但是因为我没有试过,也不知道具体情况,可能还要根据result的内容判断 | //到这里应该是成功了,但是因为我没有试过,也不知道具体情况,可能还要根据result的内容判断 | ||||
| } | } | ||||
| @@ -7,11 +7,19 @@ using Downloader; | |||||
| using MessageBox = System.Windows.MessageBox; | using MessageBox = System.Windows.MessageBox; | ||||
| using System.Configuration; | using System.Configuration; | ||||
| using System.Drawing.Design; | 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 | namespace starter.viewmodel.settings | ||||
| { | { | ||||
| public class SettingsViewModel : NotificationObject | public class SettingsViewModel : NotificationObject | ||||
| { | { | ||||
| //定义BackgroundWorker | |||||
| BackgroundWorker asyncDownloader; | |||||
| BackgroundWorker asyncUpdater; | |||||
| /// <summary> | /// <summary> | ||||
| /// Model object | /// Model object | ||||
| /// </summary> | /// </summary> | ||||
| @@ -22,17 +30,40 @@ namespace starter.viewmodel.settings | |||||
| public SettingsViewModel() | public SettingsViewModel() | ||||
| { | { | ||||
| //Program.Tencent_cos_download.UpdateHash(); | //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()) | if (Downloader.Program.Tencent_cos_download.CheckAlreadyDownload()) | ||||
| { | { | ||||
| obj.checkUpdate(); | obj.checkUpdate(); | ||||
| Status = SettingsModel.Status.login; | Status = SettingsModel.Status.login; | ||||
| this.RaisePropertyChanged("WindowWidth"); | this.RaisePropertyChanged("WindowWidth"); | ||||
| //TODO:在启动时立刻检查更新,确保选手启动最新版选手包 | |||||
| //TODO:若有更新,将启动键改为更新键; | |||||
| //TODO:相应地,使用login界面启动; | |||||
| //TODO:结构:上方为登录框架,下方有“修改选手包”按钮 | |||||
| this.RaisePropertyChanged("LaunchVis"); | |||||
| if (obj.RecallUser()) | |||||
| RememberMe = true; | |||||
| else | |||||
| RememberMe = false; | |||||
| this.RaisePropertyChanged("RememberMe"); | |||||
| //在启动时立刻检查更新,确保选手启动最新版选手包 | |||||
| //若有更新,将启动键改为更新键; | |||||
| //相应地,使用login界面启动; | |||||
| //结构:上方为登录框架,下方有“修改选手包”按钮 | |||||
| } | } | ||||
| else | 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:参赛界面:包括上传参赛代码、申请对战 | ||||
| //TODO:界面中应包含上次对战完成提示及下载回放按钮 | //TODO:界面中应包含上次对战完成提示及下载回放按钮 | ||||
| @@ -95,6 +205,10 @@ namespace starter.viewmodel.settings | |||||
| this.RaisePropertyChanged("CompleteVis"); | this.RaisePropertyChanged("CompleteVis"); | ||||
| this.RaisePropertyChanged("WindowWidth"); | this.RaisePropertyChanged("WindowWidth"); | ||||
| this.RaisePropertyChanged("WebVis"); | this.RaisePropertyChanged("WebVis"); | ||||
| this.RaisePropertyChanged("CoverVis"); | |||||
| this.RaisePropertyChanged("LaunchVis"); | |||||
| this.RaisePropertyChanged("NewUserVis"); | |||||
| this.RaisePropertyChanged("ConfirmBtnCont"); | |||||
| } | } | ||||
| } | } | ||||
| public string Intro | public string Intro | ||||
| @@ -128,9 +242,9 @@ namespace starter.viewmodel.settings | |||||
| { | { | ||||
| case SettingsModel.Status.newUser: | case SettingsModel.Status.newUser: | ||||
| return "将主体程序安装在:"; | |||||
| return "将选手包安装在(将创建THUAI6文件夹):"; | |||||
| case SettingsModel.Status.move: | case SettingsModel.Status.move: | ||||
| return "将主体程序移动到:"; | |||||
| return "将选手包移动到(THUAI6文件夹将会被整体移动):"; | |||||
| default: | default: | ||||
| return ""; | return ""; | ||||
| } | } | ||||
| @@ -179,7 +293,10 @@ namespace starter.viewmodel.settings | |||||
| public string Route | public string Route | ||||
| { | { | ||||
| get => obj.Route; | |||||
| get | |||||
| { | |||||
| return obj.Route; | |||||
| } | |||||
| set | set | ||||
| { | { | ||||
| obj.Route = value; | 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); | 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 | public Visibility MenuVis | ||||
| { | { | ||||
| get | get | ||||
| @@ -279,6 +417,19 @@ namespace starter.viewmodel.settings | |||||
| get { return obj.UploadReady ? Visibility.Visible : Visibility.Collapsed; } | 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 | public string UpdateBtnCont | ||||
| { | { | ||||
| get | get | ||||
| @@ -293,14 +444,21 @@ namespace starter.viewmodel.settings | |||||
| if (obj.UpdatePlanned) | if (obj.UpdatePlanned) | ||||
| return obj.Updates; | return obj.Updates; | ||||
| else | else | ||||
| return ""; | |||||
| return "已是最新版本"; | |||||
| } | } | ||||
| } | } | ||||
| public string LaunchBtnCont | public string LaunchBtnCont | ||||
| { | { | ||||
| get | 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 | public string UploadBtnCont | ||||
| @@ -310,6 +468,28 @@ namespace starter.viewmodel.settings | |||||
| return obj.UploadReady ? "上传代码" : "选择代码上传"; | 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) | public string RouteSelectWindow(string type) | ||||
| { | { | ||||
| @@ -365,16 +545,22 @@ namespace starter.viewmodel.settings | |||||
| { | { | ||||
| Status = SettingsModel.Status.working; | Status = SettingsModel.Status.working; | ||||
| this.RaisePropertyChanged("ProgressVis"); | this.RaisePropertyChanged("ProgressVis"); | ||||
| if (obj.install()) | |||||
| /*if (obj.install()) | |||||
| { | { | ||||
| Status = SettingsModel.Status.successful; | Status = SettingsModel.Status.successful; | ||||
| }*/ | |||||
| if (asyncDownloader.IsBusy) | |||||
| return; | |||||
| else | |||||
| { | |||||
| asyncDownloader.RunWorkerAsync(); | |||||
| } | } | ||||
| } | } | ||||
| else if (Status == SettingsModel.Status.move) | else if (Status == SettingsModel.Status.move) | ||||
| { | { | ||||
| Status = SettingsModel.Status.working; | |||||
| this.RaisePropertyChanged("ProgressVis"); | |||||
| //Status = SettingsModel.Status.working; | |||||
| //this.RaisePropertyChanged("ProgressVis"); | |||||
| switch (obj.move()) | switch (obj.move()) | ||||
| { | { | ||||
| case -1: | case -1: | ||||
| @@ -400,11 +586,14 @@ namespace starter.viewmodel.settings | |||||
| { | { | ||||
| clickUpdateCommand = new BaseCommand(new Action<object>(o => | clickUpdateCommand = new BaseCommand(new Action<object>(o => | ||||
| { | { | ||||
| this.RaisePropertyChanged("UpdateInfoVis"); | |||||
| if (obj.UpdatePlanned) | if (obj.UpdatePlanned) | ||||
| { | { | ||||
| UpdateInfoVis = Visibility.Collapsed; | |||||
| this.RaisePropertyChanged("UpdateInfoVis"); | |||||
| Status = SettingsModel.Status.working; | Status = SettingsModel.Status.working; | ||||
| this.RaisePropertyChanged("ProgressVis"); | this.RaisePropertyChanged("ProgressVis"); | ||||
| if (obj.Update()) | |||||
| /*if (obj.Update()) | |||||
| { | { | ||||
| Status = SettingsModel.Status.successful; | Status = SettingsModel.Status.successful; | ||||
| @@ -413,15 +602,22 @@ namespace starter.viewmodel.settings | |||||
| } | } | ||||
| else | else | ||||
| Status = SettingsModel.Status.error; | |||||
| Status = SettingsModel.Status.error;*/ | |||||
| if (asyncUpdater.IsBusy) | |||||
| return; | |||||
| else | |||||
| asyncUpdater.RunWorkerAsync("Manual"); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| UpdateInfoVis = Visibility.Visible; | |||||
| this.RaisePropertyChanged("UpdateInfoVis"); | |||||
| Status = SettingsModel.Status.working; | Status = SettingsModel.Status.working; | ||||
| this.RaisePropertyChanged("ProgressVis"); | this.RaisePropertyChanged("ProgressVis"); | ||||
| Status = obj.checkUpdate(); | Status = obj.checkUpdate(); | ||||
| this.RaisePropertyChanged("UpdateBtnCont"); | this.RaisePropertyChanged("UpdateBtnCont"); | ||||
| this.RaisePropertyChanged("UpdateInfo"); | this.RaisePropertyChanged("UpdateInfo"); | ||||
| this.RaisePropertyChanged("LaunchVis"); | |||||
| } | } | ||||
| })); | })); | ||||
| } | } | ||||
| @@ -452,8 +648,8 @@ namespace starter.viewmodel.settings | |||||
| { | { | ||||
| clickUninstCommand = new BaseCommand(new Action<object>(o => | clickUninstCommand = new BaseCommand(new Action<object>(o => | ||||
| { | { | ||||
| Status = SettingsModel.Status.working; | |||||
| this.RaisePropertyChanged("ProgressVis"); | |||||
| UpdateInfoVis = Visibility.Collapsed; | |||||
| this.RaisePropertyChanged("UpdateInfoVis"); | |||||
| switch (obj.Uninst()) | switch (obj.Uninst()) | ||||
| { | { | ||||
| case -1: | case -1: | ||||
| @@ -461,13 +657,15 @@ namespace starter.viewmodel.settings | |||||
| MessageBox.Show("文件已经打开,请关闭后再删除", "", MessageBoxButton.OK, MessageBoxImage.Warning, MessageBoxResult.OK); | MessageBox.Show("文件已经打开,请关闭后再删除", "", MessageBoxButton.OK, MessageBoxImage.Warning, MessageBoxResult.OK); | ||||
| break; | break; | ||||
| case 0: | case 0: | ||||
| Status = SettingsModel.Status.successful; | |||||
| Status = SettingsModel.Status.newUser; | |||||
| MessageBox.Show($"删除成功!player文件夹中的文件已经放在{Downloader.Program.ProgramName}的根目录下", "", MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.OK); | |||||
| break; | break; | ||||
| default: | default: | ||||
| Status = SettingsModel.Status.error; | Status = SettingsModel.Status.error; | ||||
| break; | break; | ||||
| } | } | ||||
| })); | })); | ||||
| } | } | ||||
| return clickUninstCommand; | return clickUninstCommand; | ||||
| @@ -491,6 +689,22 @@ namespace starter.viewmodel.settings | |||||
| case 0: | case 0: | ||||
| obj.LoginFailed = false; | obj.LoginFailed = false; | ||||
| Status = SettingsModel.Status.web; | 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"); | this.RaisePropertyChanged("CoverVis"); | ||||
| break; | break; | ||||
| case -2: | case -2: | ||||
| @@ -517,15 +731,10 @@ namespace starter.viewmodel.settings | |||||
| { | { | ||||
| Status = SettingsModel.Status.working; | Status = SettingsModel.Status.working; | ||||
| this.RaisePropertyChanged("ProgressVis"); | this.RaisePropertyChanged("ProgressVis"); | ||||
| if (obj.Update()) | |||||
| { | |||||
| this.RaisePropertyChanged("UpdateBtnCont"); | |||||
| this.RaisePropertyChanged("LaunchBtnCont"); | |||||
| Status = SettingsModel.Status.login; | |||||
| this.RaisePropertyChanged("UpdateInfo"); | |||||
| } | |||||
| if (asyncUpdater.IsBusy) | |||||
| return; | |||||
| else | else | ||||
| Status = SettingsModel.Status.error; | |||||
| asyncUpdater.RunWorkerAsync("Auto"); | |||||
| } | } | ||||
| else if (!obj.Launch()) | else if (!obj.Launch()) | ||||
| { | { | ||||
| @@ -546,6 +755,9 @@ namespace starter.viewmodel.settings | |||||
| clickEditCommand = new BaseCommand(new Action<object>(o => | clickEditCommand = new BaseCommand(new Action<object>(o => | ||||
| { | { | ||||
| Status = SettingsModel.Status.menu; | Status = SettingsModel.Status.menu; | ||||
| if (obj.UpdatePlanned) | |||||
| UpdateInfoVis = Visibility.Visible; | |||||
| this.RaisePropertyChanged("UpdateInfoVis"); | |||||
| })); | })); | ||||
| } | } | ||||
| return clickEditCommand; | return clickEditCommand; | ||||
| @@ -560,6 +772,8 @@ namespace starter.viewmodel.settings | |||||
| { | { | ||||
| clickBackCommand = new BaseCommand(new Action<object>(o => | clickBackCommand = new BaseCommand(new Action<object>(o => | ||||
| { | { | ||||
| UpdateInfoVis = Visibility.Collapsed; | |||||
| this.RaisePropertyChanged("UpdateInfoVis"); | |||||
| if (Downloader.Program.Tencent_cos_download.CheckAlreadyDownload()) | if (Downloader.Program.Tencent_cos_download.CheckAlreadyDownload()) | ||||
| Status = SettingsModel.Status.login; | Status = SettingsModel.Status.login; | ||||
| else | else | ||||
| @@ -671,12 +885,51 @@ namespace starter.viewmodel.settings | |||||
| { | { | ||||
| clickExitCommand = new BaseCommand(new Action<object>(o => | clickExitCommand = new BaseCommand(new Action<object>(o => | ||||
| { | { | ||||
| System.Windows.Application.Current.Shutdown(); | |||||
| Application.Current.Shutdown(); | |||||
| })); | })); | ||||
| } | } | ||||
| return clickExitCommand; | 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" | "commandLineArgs": "--port 8888 --characterID 3 --type 1 --occupation 5" | ||||
| } | } | ||||
| } | } | ||||
| } | |||||
| } | |||||
| @@ -52,7 +52,11 @@ V4.8 | |||||
| - **x坐标轴正方向竖直向下,y坐标轴正方向水平向右**; | - **x坐标轴正方向竖直向下,y坐标轴正方向水平向右**; | ||||
| - **极坐标以x坐标轴为极轴,角度逆时针为正方向**。 | - **极坐标以x坐标轴为极轴,角度逆时针为正方向**。 | ||||
| - 地图由50 * 50个格子构成,每个格子代表1000 * 1000的正方形。每个格子的编号(CellX,CellY)可以计算得到: | - 地图由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) | ## 游戏启动方式(For Debug) | ||||
| @@ -94,11 +100,7 @@ Server脚本中参数格式一般如下: | |||||
| ## Client | ## Client | ||||
| ### C++接口 | |||||
| 选手用Visual Studio打开CAPI.sln,编写AI.cpp,建议用Debug模式生成以方便自己调试,然后可以使用`RunCpp.cmd`启动。 | |||||
| `RunCpp.cmd`的脚本参数格式如下: | |||||
| `RunCpp.cmd`或`RunPython.cmd`的脚本参数格式如下: | |||||
| ```shell | ```shell | ||||
| -I 127.0.0.1 -P 8888 -p 0 -d -o -w | -I 127.0.0.1 -P 8888 -p 0 -d -o -w | ||||