Browse Source

Merge branch 'eesast:dev' into new

tags/0.1.0
shangfengh GitHub 2 years ago
parent
commit
1389808ad8
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 406 additions and 70 deletions
  1. +1
    -0
      installer/Installer/Installer.csproj
  2. +9
    -6
      installer/Installer/MainWindow.xaml
  3. +101
    -28
      installer/Installer/Model.cs
  4. +280
    -27
      installer/Installer/ViewModel.cs
  5. +1
    -1
      logic/Client/Properties/launchSettings.json
  6. +5
    -1
      logic/GameRules.md
  7. +9
    -7
      使用文档.md

+ 1
- 0
installer/Installer/Installer.csproj View File

@@ -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" />


+ 9
- 6
installer/Installer/MainWindow.xaml View File

@@ -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}"/>




+ 101
- 28
installer/Installer/Model.cs View File

@@ -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的内容判断
}


+ 280
- 27
installer/Installer/ViewModel.cs View File

@@ -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;
}
}
}

}

+ 1
- 1
logic/Client/Properties/launchSettings.json View File

@@ -5,4 +5,4 @@
"commandLineArgs": "--port 8888 --characterID 3 --type 1 --occupation 5"
}
}
}
}

+ 5
- 1
logic/GameRules.md View File

@@ -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}
$$

- 格子有对应区域类型:陆地、墙、草地、教室、校门、隐藏校门、门、窗、箱子

### 人物


+ 9
- 7
使用文档.md View File

@@ -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


Loading…
Cancel
Save