Browse Source

Chore: Change Upload File Function

tags/0.1.0
sendssf 2 years ago
parent
commit
21957eb9fd
12 changed files with 281 additions and 234 deletions
  1. +32
    -0
      installer/Installer/Common.cs
  2. +45
    -22
      installer/Installer/MainWindow.xaml
  3. +9
    -5
      installer/Installer/Model.cs
  4. +103
    -33
      installer/Installer/ViewModel.cs
  5. +1
    -1
      logic/GameClass/GameObj/Bullet/Bullet.Ghost.cs
  6. +21
    -0
      logic/GameClass/GameObj/Map/Map.cs
  7. +4
    -3
      logic/Gaming/ActionManager.cs
  8. +7
    -1
      logic/Preparation/Utility/GameData.cs
  9. +26
    -26
      logic/Server/GameServer.cs
  10. +6
    -0
      logic/Server/Program.cs
  11. +2
    -4
      logic/Server/RpcServices.cs
  12. +25
    -139
      logic/规则Logic.md

+ 32
- 0
installer/Installer/Common.cs View File

@@ -1,6 +1,8 @@
using System.ComponentModel;
using System;
using System.Windows.Input;
using System.Globalization;
using System.Windows.Data;

namespace starter.viewmodel.common
{
@@ -66,4 +68,34 @@ namespace starter.viewmodel.common
}
}
}

public class RadioConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null || parameter == null)
{
return false;
}
string checkvalue = value.ToString();
string targetvalue = parameter.ToString();
bool r = checkvalue.Equals(targetvalue);
return r;
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null || parameter == null)
{
return null;
}

if ((bool)value)
{
return parameter.ToString();
}
return null;
}
}

}

+ 45
- 22
installer/Installer/MainWindow.xaml View File

@@ -3,9 +3,12 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Installer"
xmlns:local="clr-namespace:Installer" xmlns:c="clr-namespace:starter.viewmodel.common"
mc:Ignorable="d"
Title="Installer" Window.SizeToContent="WidthAndHeight">
<Window.Resources>
<c:RadioConverter x:Key="RadioConverter"/>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40" />
@@ -34,14 +37,14 @@
<TextBlock Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="5" Text="{Binding RouteBoxIntro}"/>

<TextBox Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="5" Name="RouteTxtBox" Text="{Binding Route}" Visibility="{Binding RouteBoxVis}"/>
<Button Grid.Row="3" Grid.Column="6" Name="GetRouteBtn" Content="Browse..." Command="{Binding ClickBrowseCommand}" Visibility="{Binding RouteBoxVis}" />
<Button Grid.Row="3" Grid.Column="7" Name="SetBtm" Content="Confirm" Command="{Binding ClickConfirmCommand}" Visibility="{Binding RouteBoxVis}"/>
<Button Grid.Row="3" Grid.Column="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="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}" />

<Button Grid.Row="5" Grid.Column="2" Grid.ColumnSpan="2" Name="MoveBtn" Content="Move" 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="UnInstall" 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}" />

<TextBlock Grid.Row="3" Grid.Column="4" Text="Processing" Grid.ColumnSpan="2" Visibility="{Binding ProgressVis}"/>
@@ -50,27 +53,40 @@
<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="4" Grid.ColumnSpan="2" Name="ExitBtn" Content="退出" Command="{Binding ClickExitCommand}" Visibility="{Binding CompleteVis}"/>

<TextBlock Grid.Row="3" Grid.Column="1" Text="账号:" Visibility="{Binding LoginVis}" />
<TextBlock Grid.Row="5" Grid.Column="1" Text="密码:" Visibility="{Binding LoginVis}" />
<TextBox Grid.Row="3" Grid.Column="2" Grid.ColumnSpan="4" Name="Username" Visibility="{Binding LoginVis}" Text="{Binding Username}" />
<TextBox Grid.Row="5" Grid.Column="2" Grid.ColumnSpan="4" Name="Password" Visibility="{Binding LoginVis}" Text="{Binding Password}" />
<StackPanel Grid.Row="2" Grid.Column="1" Grid.RowSpan="5" Grid.ColumnSpan="5">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="10"/>
<RowDefinition Height="20"/>
<RowDefinition Height="10"/>
<RowDefinition Height="20"/>
<RowDefinition Height="10"/>
<RowDefinition Height="15"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="1" 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="3" Grid.Column="1" Name="Password" Visibility="{Binding LoginVis}" Text="{Binding Password}" />
<!--<CheckBox Grid.Row="5" Grid.Column="0" Visibility="{Binding LoginVis}">记住我</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="4" Grid.ColumnSpan="2" Name="Edit" Content="修改文件" Command="{Binding ClickEditCommand}" Visibility="{Binding LoginVis}"/>
<TextBlock Grid.Row="6" Grid.Column="1" Text="用户名或密码错误!" Visibility="{Binding LoginFailVis}"/>

<TextBlock Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2" Text="你有已完成的比赛!" Visibility="{Binding MatchFinishedVis}"/>
<Button Grid.Row="3" Grid.Column="1" Name ="Upload" Content="{Binding UploadBtnCont}" Command="{Binding ClickUploadCommand}" Visibility="{Binding WebVis}"/>
<TextBlock Grid.Row="4" Grid.Column="1" Grid.ColumnSpan="2" Text="{Binding CodeName}" Visibility="{Binding UploadReadyVis}" />
<Button Grid.Row="3" Grid.Column="2" Name="ReUpload" Content="重新选择代码" Command="{Binding ReselectCommand}" Visibility="{Binding UploadReadyVis}" />
<Button Grid.Row="3" Grid.Column="2" Name="ReUpload" Content="放弃上传" Command="{Binding ClickReselectCommand}" Visibility="{Binding UploadReadyVis}" />
<Button Grid.Row="6" Grid.Column="3" Grid.ColumnSpan="2" Content="退出登录" Command="{Binding ClickBackCommand}" Visibility="{Binding WebVis}" />
<!--objects below are not enabled-->
<Button Grid.Row="5" Grid.Column="1" Name="Download" Content="下载回放" IsEnabled="False" Command="{Binding ClickDownloadCommand}" Visibility="{Binding CoverVis}" />
<Button Grid.Row="7" Grid.Column="1" Name="Replay" Content="打开回放" IsEnabled="False" Command="{Binding ClickReplayCommand}" Visibility="{Binding CoverVis}" />
<Button Grid.Row="3" Grid.Column="3" Grid.ColumnSpan="2" Content="申请对战" IsEnabled="False" Command="{Binding ClickRequestCommand}" Visibility="{Binding WebVis}" />
<TextBox Grid.Row="4" Grid.Column="3" Grid.ColumnSpan="2" Text="暂不支持" IsEnabled="False" Visibility="{Binding WebVis}" />
<StackPanel Grid.Row="5" Grid.Column="1" Grid.RowSpan="3" Grid.ColumnSpan="2">
<Grid>
<Grid.RowDefinitions>
@@ -79,11 +95,18 @@
<RowDefinition Height="15"/>
<RowDefinition Height="15"/>
</Grid.RowDefinitions>
<RadioButton GroupName="playerNum" Grid.Row="0" Visibility="{Binding UploadReadyVis}">玩家1</RadioButton>
<RadioButton GroupName="playerNum" Grid.Row="1" Visibility="{Binding UploadReadyVis}">玩家2</RadioButton>
<RadioButton GroupName="playerNum" Grid.Row="2" Visibility="{Binding UploadReadyVis}">玩家3</RadioButton>
<RadioButton GroupName="playerNum" Grid.Row="3" Visibility="{Binding UploadReadyVis}">玩家4</RadioButton>
<RadioButton GroupName="playerNum" Grid.Row="0" Visibility="{Binding UploadReadyVis}" IsChecked="{Binding PlayerNum,Mode=TwoWay,Converter={StaticResource RadioConverter},ConverterParameter=1}">玩家1</RadioButton>
<RadioButton GroupName="playerNum" Grid.Row="1" Visibility="{Binding UploadReadyVis}" IsChecked="{Binding PlayerNum,Mode=TwoWay,Converter={StaticResource RadioConverter},ConverterParameter=2}">玩家2</RadioButton>
<RadioButton GroupName="playerNum" Grid.Row="2" Visibility="{Binding UploadReadyVis}" IsChecked="{Binding PlayerNum,Mode=TwoWay,Converter={StaticResource RadioConverter},ConverterParameter=3}">玩家3</RadioButton>
<RadioButton GroupName="playerNum" Grid.Row="3" Visibility="{Binding UploadReadyVis}" IsChecked="{Binding PlayerNum,Mode=TwoWay,Converter={StaticResource RadioConverter},ConverterParameter=4}">玩家4</RadioButton>
</Grid>
</StackPanel>
<!--objects below are not enabled-->
<Button Grid.Row="5" Grid.Column="1" Name="Download" Content="下载回放" IsEnabled="False" Command="{Binding ClickDownloadCommand}" Visibility="{Binding CoverVis}" />
<Button Grid.Row="7" Grid.Column="1" Name="Replay" Content="打开回放" IsEnabled="False" Command="{Binding ClickReplayCommand}" Visibility="{Binding CoverVis}" />
<Button Grid.Row="3" Grid.Column="3" Grid.ColumnSpan="2" Content="申请对战" IsEnabled="False" Command="{Binding ClickRequestCommand}" Visibility="{Binding WebVis}" />
<TextBox Grid.Row="4" Grid.Column="3" Grid.ColumnSpan="2" Text="暂不支持" IsEnabled="False" Visibility="{Binding WebVis}" />
</Grid>
</Window>

+ 9
- 5
installer/Installer/Model.cs View File

@@ -49,6 +49,7 @@ namespace starter.viewmodel.settings
Password = "";
updates = "";
CodeRoute = "";
PlayerNum = "nSelect";
UploadReady = false;
LoginFailed = false;
}
@@ -166,7 +167,9 @@ namespace starter.viewmodel.settings
default:
return -8;
}
return await web.UploadFiles(client, CodeRoute, Language, "player_1");
if (PlayerNum.Equals("nSelect"))
return -9;
return await web.UploadFiles(client, CodeRoute, Language, PlayerNum);
}
/// <summary>
/// Route of files
@@ -394,8 +397,8 @@ namespace Downloader
.Build(); // 创建 CosXmlConfig 对象

// 永久密钥访问凭证
string secretId = "***"; //"云 API 密钥 SecretId";
string secretKey = "***"; //"云 API 密钥 SecretKey";
string secretId = "***"; //"云 API 密钥 SecretId";
string secretKey = "***"; //"云 API 密钥 SecretKey";

long durationSecond = 1000; // 每次请求签名有效时长,单位为秒
QCloudCredentialProvider cosCredentialProvider = new DefaultQCloudCredentialProvider(
@@ -1119,7 +1122,8 @@ namespace WebConnect
using FileStream fs = new FileStream(tarfile, FileMode.Open, FileAccess.Read);
using StreamReader sr = new StreamReader(fs);
content = sr.ReadToEnd();
using (var response = await client.GetAsync($"https://api.eesast.com/static/player?team_id={await GetTeamId()}"))
string targetUrl = $"https://api.eesast.com/static/player?team_id={await GetTeamId()}";
using (var response = await client.GetAsync(targetUrl))
{
switch (response.StatusCode)
{
@@ -1343,7 +1347,7 @@ namespace WebConnect
// ""query"": ""query MyQuery {{contest_team_member(where: {{user_id: {{_eq: \""{Downloader.UserInfo._id}\""}}}}) {{ team_id }}}}"",
// ""variables"": {{}},
// }}", null, "application/json");
var content = new StringContent("{\"query\":\"query MyQuery {\\r\\n contest_team_member(where: {user_id: {_eq: \\\""+Downloader.UserInfo._id+"\\\"}}) {\\r\\n team_id\\r\\n }\\r\\n}\",\"variables\":{}}", null, "application/json");
var content = new StringContent("{\"query\":\"query MyQuery {\\r\\n contest_team_member(where: {user_id: {_eq: \\\"" + Downloader.UserInfo._id + "\\\"}}) {\\r\\n team_id\\r\\n }\\r\\n}\",\"variables\":{}}", null, "application/json");
request.Content = content;
var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();


+ 103
- 33
installer/Installer/ViewModel.cs View File

@@ -6,8 +6,7 @@ using System.Windows.Forms;
using Downloader;
using MessageBox = System.Windows.MessageBox;
using System.Configuration;
using WebConnect;
using System.Net.Http;
using System.Drawing.Design;

namespace starter.viewmodel.settings
{
@@ -135,6 +134,46 @@ namespace starter.viewmodel.settings
}
}
}
public int PlayerNum
{
get
{
int ans;
if (obj.PlayerNum.Equals("player_1"))
ans = 1;
else if (obj.PlayerNum.Equals("player_2"))
ans = 2;
else if (obj.PlayerNum.Equals("player_3"))
ans = 3;
else if (obj.PlayerNum.Equals("player_4"))
ans = 4;
else
ans = 0;
return ans;
}
set
{
switch (value)
{
case 1:
obj.PlayerNum = "player_1";
break;
case 2:
obj.PlayerNum = "player_2";
break;
case 3:
obj.PlayerNum = "player_3";
break;
case 4:
obj.PlayerNum = "player_4";
break;
default:
obj.PlayerNum = "nSelect";
break;
}
this.RaisePropertyChanged("PlayerNum");
}
}

public string Route
{
@@ -242,7 +281,7 @@ namespace starter.viewmodel.settings
{
get
{
return obj.UpdatePlanned ? "Update" : "Check Updates";
return obj.UpdatePlanned ? "更新" : "检查更新";
}
}
public string UpdateInfo
@@ -448,7 +487,9 @@ namespace starter.viewmodel.settings
}
else
{
obj.LoginFailed = false;
Status = SettingsModel.Status.web;
this.RaisePropertyChanged("CoverVis");
}
this.RaisePropertyChanged("LoginFailVis");
}));
@@ -530,38 +571,46 @@ namespace starter.viewmodel.settings
{
if (obj.UploadReady)
{
switch (await obj.Upload())
if (obj.PlayerNum.Equals("nSelect"))
{
case -1:
MessageBox.Show("Token失效!", "", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK);
break;
case -2:
MessageBox.Show("目标路径不存在!", "", MessageBoxButton.OK, MessageBoxImage.Warning, MessageBoxResult.OK);
break;
case -3:
MessageBox.Show("服务器错误", "", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK);
break;
case -4:
MessageBox.Show("您未登录或登录失效", "", MessageBoxButton.OK, MessageBoxImage.Warning, MessageBoxResult.OK);
Status = SettingsModel.Status.login;
break;
case -5:
MessageBox.Show("您未报名THUAI!", "", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK);
break;
case -6:
MessageBox.Show("读取文件失败,请确认文件是否被占用", "", MessageBoxButton.OK, MessageBoxImage.Warning, MessageBoxResult.OK);
break;
case -7:
MessageBox.Show("网络错误,请检查你的网络", "", MessageBoxButton.OK, MessageBoxImage.Warning, MessageBoxResult.OK);
break;
case -8:
MessageBox.Show("不是c++或python源文件", "", MessageBoxButton.OK, MessageBoxImage.Warning, MessageBoxResult.OK);
break;
MessageBox.Show("您还没有选择要上传的玩家身份", "", MessageBoxButton.OK, MessageBoxImage.Warning, MessageBoxResult.OK);
}
else
{
switch (await obj.Upload())
{
case -1:
MessageBox.Show("Token失效!", "", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK);
break;
case -2:
MessageBox.Show("目标路径不存在!", "", MessageBoxButton.OK, MessageBoxImage.Warning, MessageBoxResult.OK);
break;
case -3:
MessageBox.Show("服务器错误", "", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK);
break;
case -4:
MessageBox.Show("您未登录或登录失效", "", MessageBoxButton.OK, MessageBoxImage.Warning, MessageBoxResult.OK);
Status = SettingsModel.Status.login;
break;
case -5:
MessageBox.Show("您未报名THUAI!", "", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK);
break;
case -6:
MessageBox.Show("读取文件失败,请确认文件是否被占用", "", MessageBoxButton.OK, MessageBoxImage.Warning, MessageBoxResult.OK);
break;
case -7:
MessageBox.Show("网络错误,请检查你的网络", "", MessageBoxButton.OK, MessageBoxImage.Warning, MessageBoxResult.OK);
break;
case -8:
MessageBox.Show("不是c++或python源文件", "", MessageBoxButton.OK, MessageBoxImage.Warning, MessageBoxResult.OK);
break;
}
obj.CodeRoute = "";
obj.UploadReady = false;
this.RaisePropertyChanged("UploadBtnCont");
this.RaisePropertyChanged("UploadReadyVis");
this.RaisePropertyChanged("CoverVis");
}
obj.CodeRoute = "";
obj.UploadReady = false;
this.RaisePropertyChanged("UploadBtnCont");
this.RaisePropertyChanged("UploadReadyVis");
}
else
{
@@ -572,6 +621,7 @@ namespace starter.viewmodel.settings
this.RaisePropertyChanged("UploadBtnCont");
this.RaisePropertyChanged("UploadReadyVis");
this.RaisePropertyChanged("CodeName");
this.RaisePropertyChanged("CoverVis");
}
else
{
@@ -583,6 +633,26 @@ namespace starter.viewmodel.settings
return clickUploadCommand;
}
}
private BaseCommand clickReselectCommand;
public BaseCommand ClickReselectCommand
{
get
{
if (clickReselectCommand == null)
{
clickReselectCommand = new BaseCommand(new Action<object>(o =>
{
obj.CodeRoute = "";
obj.UploadReady = false;
this.RaisePropertyChanged("UploadBtnCont");
this.RaisePropertyChanged("UploadReadyVis");
this.RaisePropertyChanged("CodeName");
this.RaisePropertyChanged("CoverVis");
}));
}
return clickReselectCommand;
}
}
}

}

+ 1
- 1
logic/GameClass/GameObj/Bullet/Bullet.Ghost.cs View File

@@ -164,7 +164,7 @@ namespace GameClass.GameObj
ap = value;
}
}
public override int Speed => 4300;
public override int Speed => (int)(GameData.basicBulletMoveSpeed * 43 / 37);
public override bool IsRemoteAttack => false;

public override int CastTime => 0;


+ 21
- 0
logic/GameClass/GameObj/Map/Map.cs View File

@@ -296,6 +296,27 @@ namespace GameClass.GameObj
}
return GameObjForInteract;
}
public GameObj? PartInTheSameCell(XY Pos, GameObjType gameObjType)
{
GameObj? GameObjForInteract = null;
GameObjLockDict[gameObjType].EnterReadLock();
try
{
foreach (GameObj gameObj in GameObjDict[gameObjType])
{
if (GameData.PartInTheSameCell(gameObj.Position, Pos))
{
GameObjForInteract = gameObj;
break;
}
}
}
finally
{
GameObjLockDict[gameObjType].ExitReadLock();
}
return GameObjForInteract;
}
public GameObj? OneForInteractInACross(XY Pos, GameObjType gameObjType)
{
GameObj? GameObjForInteract = null;


+ 4
- 3
logic/Gaming/ActionManager.cs View File

@@ -55,7 +55,7 @@ namespace Gaming

public bool Fix(Student player)// 自动检查有无发电机可修
{
if ((!player.Commandable()) || player.PlayerState == PlayerStateType.Fixing)
if (player.CharacterType == CharacterType.Teacher || (!player.Commandable()) || player.PlayerState == PlayerStateType.Fixing)
return false;
Generator? generatorForFix = (Generator?)gameMap.OneForInteract(player.Position, GameObjType.Generator);

@@ -368,7 +368,7 @@ namespace Gaming
if (!(player.Commandable()) || player.PlayerState == PlayerStateType.LockingOrOpeningTheDoor)
return false;
Door? doorToLock = (Door?)gameMap.OneForInteract(player.Position, GameObjType.Door);
if (doorToLock == null || doorToLock.OpenOrLockDegree > 0)
if (doorToLock == null || doorToLock.OpenOrLockDegree > 0 || gameMap.PartInTheSameCell(doorToLock.Position, GameObjType.Character) != null)
return false;
bool flag = false;
foreach (Prop prop in player.PropInventory)
@@ -403,7 +403,8 @@ namespace Gaming
loopCondition: () => flag && player.PlayerState == PlayerStateType.LockingOrOpeningTheDoor && gameMap.Timer.IsGaming && doorToLock.OpenOrLockDegree < GameData.degreeOfLockingOrOpeningTheDoor,
loopToDo: () =>
{
flag = ((gameMap.OneInTheSameCell(doorToLock.Position, GameObjType.Character)) == null);
flag = ((gameMap.PartInTheSameCell(doorToLock.Position, GameObjType.Character)) == null);
Preparation.Utility.Debugger.Output(doorToLock, flag.ToString());
doorToLock.OpenOrLockDegree += GameData.frameDuration * player.SpeedOfOpeningOrLocking;
},
timeInterval: GameData.frameDuration,


+ 7
- 1
logic/Preparation/Utility/GameData.cs View File

@@ -1,4 +1,5 @@
using System;
using Preparation.Interface;
using System;
using System.Net.NetworkInformation;

namespace Preparation.Utility
@@ -68,6 +69,11 @@ namespace Preparation.Utility
{
return PosGridToCellX(pos1) == PosGridToCellX(pos2) && PosGridToCellY(pos1) == PosGridToCellY(pos2);
}
public static bool PartInTheSameCell(XY pos1, XY pos2)
{
return Math.Abs((pos1 - pos2).x) < characterRadius + (numOfPosGridPerCell / 2)
&& Math.Abs((pos1 - pos2).y) < characterRadius + (numOfPosGridPerCell / 2);
}
public static bool ApproachToInteract(XY pos1, XY pos2)
{
if (pos1 == pos2) return false;


+ 26
- 26
logic/Server/GameServer.cs View File

@@ -83,10 +83,9 @@ namespace Server
private void SaveGameResult(string path)
{
Dictionary<string, int> result = new Dictionary<string, int>();
for (int i = 0; i < TeamCount; i++)
{
result.Add("Team" + i.ToString(), GetTeamScore(i)); //Team待修改
}
int[] score = GetScore();
result.Add("Student", score[0]);
result.Add("Tricker", score[1]);
JsonSerializer serializer = new JsonSerializer();
using (StreamWriter sw = new StreamWriter(path))
{
@@ -99,10 +98,9 @@ namespace Server
protected virtual void SendGameResult() // 天梯的 Server 给网站发消息记录比赛结果
{
var scores = new JObject[options.TeamCount];
for (ushort i = 0; i < options.TeamCount; ++i)
{
scores[i] = new JObject { ["team_id"] = i.ToString(), ["score"] = GetTeamScore(i) };
} // Team待修改
int[] score = GetScore();
scores[0] = new JObject { ["team_name"] = "Student", ["score"] = score[0] };
scores[1] = new JObject { ["team_name"] = "Tricker", ["score"] = score[1] };
httpSender?.SendHttpRequest
(
new JObject
@@ -166,9 +164,24 @@ namespace Server
kvp.Value.Item2.Wait();
}
}
public int GetTeamScore(long teamID)
public int[] GetScore()
{
return game.GetTeamScore(teamID);
int[] score = new int[2]; // 0代表Student,1代表Tricker
game.GameMap.GameObjLockDict[GameObjType.Character].EnterReadLock();
try
{
foreach (Character character in game.GameMap.GameObjDict[GameObjType.Character])
{
if (!character.IsGhost()) score[0] += character.Score;
else score[1] += character.Score;
}

}
finally
{
game.GameMap.GameObjLockDict[GameObjType.Character].ExitReadLock();
}
return score;
}

private int PlayerIDToTeamID(long playerID)
@@ -202,22 +215,9 @@ namespace Server
msg.SubjectFinished = (int)game.GameMap.NumOfRepairedGenerators;
msg.StudentGraduated = (int)game.GameMap.NumOfEscapedStudent;
msg.StudentQuited = (int)game.GameMap.NumOfDeceasedStudent;
msg.StudentScore = 0;
msg.TrickerScore = 0;
game.GameMap.GameObjLockDict[GameObjType.Character].EnterReadLock();
try
{
foreach (Character character in game.GameMap.GameObjDict[GameObjType.Character])
{
if (!character.IsGhost()) msg.StudentScore += character.Score;
else msg.TrickerScore += character.Score;
}

}
finally
{
game.GameMap.GameObjLockDict[GameObjType.Character].ExitReadLock();
}
int[] score = GetScore();
msg.StudentScore = score[0];
msg.TrickerScore = score[1];
//msg.GateOpened
//msg.HiddenGateRefreshed
//msg.HiddenGateOpened


+ 6
- 0
logic/Server/Program.cs View File

@@ -42,6 +42,12 @@ namespace Server
gameServer.WaitForEnd();
Console.WriteLine("Server end!");
server.ShutdownAsync().Wait();

Thread.Sleep(50);
Console.WriteLine("");
Console.WriteLine("=================== Final Score ====================");
Console.WriteLine($"Studnet: {gameServer.GetScore()[0]}");
Console.WriteLine($"Tricker: {gameServer.GetScore()[1]}");
}
catch (Exception ex)
{


+ 2
- 4
logic/Server/RpcServices.cs View File

@@ -65,9 +65,9 @@ namespace Server
//Console.WriteLine("Send!");
}
}
catch (Exception ex)
catch (Exception)
{
Console.WriteLine(ex);
//Console.WriteLine(ex);
}
finally
{
@@ -97,7 +97,6 @@ namespace Server
if (newPlayerID == GameObj.invalidID)
return;
communicationToGameID[request.PlayerId] = newPlayerID;
// 内容待修改
var temp = (new SemaphoreSlim(0, 1), new SemaphoreSlim(0, 1));
bool start = false;
Console.WriteLine($"Id: {request.PlayerId} joins.");
@@ -172,7 +171,6 @@ namespace Server
}
var gameID = communicationToGameID[request.PlayerId];
game.MovePlayer(gameID, (int)request.TimeInMilliseconds, request.Angle);
// 之后game.MovePlayer可能改为bool类
moveRes.ActSuccess = true;
if (!game.GameMap.Timer.IsGaming) moveRes.ActSuccess = false;
return Task.FromResult(moveRes);


+ 25
- 139
logic/规则Logic.md View File

@@ -4,13 +4,6 @@
- *斜体表示Logic底层尚未(完全)实现*
- []表示待决定

## 游戏简介
- 1位捣蛋鬼对抗4位学生的非对称竞技模式
- [本届THUAI电子系赛道为以4名同学和1名捣蛋鬼的求学与阻挠展开的非对称竞技模式,同学需要完成足够的家庭作业和考试,相互督促以避免沉迷娱乐生活,利用道具地形躲避捣蛋鬼的各种干扰诱惑,完成学业;捣蛋鬼则要极力阻止。]
- [我们的设计是一个非对称游戏,类似第五人格,分为学生、捣蛋鬼两个阵营。在游戏中,学生修完若干课程之后通过考试即可顺利毕业,捣蛋鬼试图干扰学生使其沉迷游戏,以致于无法修完规定课程,直至挂科、退学。]
[对于选手来说,需要提前制定好学生的学习方案以抵御对方捣蛋鬼的干扰,类似地,也需要制定好捣蛋鬼的行动策略以影响对方学生的学习,也即每队至少要写好两份代码以执行不同阵营的不同策略。]
[当一局比赛结束(场上的学生有且仅有两种状态:退学或毕业)时,分别记录双方总得分;之后双方换边进行下半场比赛。最终将每队的学生方、捣蛋鬼方的得分相加,比较总得分判断胜负。]

## 简要规则

### 地图
@@ -21,29 +14,30 @@
- 略
- 地图上的每个格子有自己的区域类型:陆地、墙、草地、电机、出口、紧急出口、门、窗、箱子

### 人物状态
游戏人物共有17种不可叠加的状态:(加^为学生独有)
1.普通状态
2^.学习
3^.被治疗
4^.在治疗
5.开或锁门
6.翻箱
7.使用技能
8^.正在毕业
9^.唤醒他人中

10^.被唤醒中(从沉迷状态中)
11^.沉迷
12^.退学
13^.毕业
14.被眩晕
15.前摇
16.后摇
17.翻窗

其中后8项为不可行动状态
-不加声明,不可行动状态中的玩家各项指令是无效的
### 人物
- 人物半径为800
- 游戏人物共有17种不可叠加的状态:(加^为学生独有)
1. 普通状态
2. 学习^
3. 被治疗^
4. 在治疗^
5. 开或锁门
6. 翻箱
7. 使用技能
8. 正在毕业^
9. 唤醒他人中^

10. 被唤醒中(从沉迷状态中^
11. 沉迷^
12. 退学^
13. 毕业^
14. 被眩晕
15. 前摇
16. 后摇
17. 翻窗

- 其中后8项为不可行动状态
- 不加声明,不可行动状态中的玩家各项指令是无效的

### 交互
- 除了翻窗,交互目标与交互者在一个九宫格内则为可交互
@@ -265,7 +259,6 @@
## 细则

### 特殊说明

- 不加说明,这里“学生”往往包括职业“教师”

### 初始状态
@@ -299,118 +292,11 @@
- 爬窗:从窗一侧边缘中点到另一侧格子中心,位置渐移,时间=距离/爬窗速度。中断时,停留在另一侧格子中心

### 箱子
- 地图上有8个箱子
- 同一时刻只允许一人进行开启
- 未开启完成的箱子在下一次需要重新开始开启。
- 箱子开启后其中道具才可以被观测和拿取

## 游戏内Logic底层的枚举类型、类与属性
- 底层实现中的属性,不代表界面全部都需要展示,也可能需要额外展示信息
- 只展示外部需要的属性,部分属性被省略

### 物体
- 位置
- 位置地形
- ID
- 类型
- 面向角度
- 形状
- 半径
- 是否可移动
- 是否在移动
- 移动速度

### 人物:物体

- 装弹CD
- 持有子弹数量
- 血量
- 最大血量
- 玩家状态(不可叠加)
- Bgm(字典)
- 得分
- 当前子弹类型
- 原始子弹类型
- 持有道具 (最多三个)(数组)
- 是否隐身
- 队伍ID
- 玩家ID
- 当前Buff
- 职业类型
- 拥有的被动技能(列表)
- 拥有的主动技能(列表)
- 各个主动技能CD(字典)
- 警戒半径
- double 隐蔽度
- 翻窗时间
- 开锁门速度
- 开箱速度
- 视野范围

### 学生:人物
- 修理电机速度
- 治疗速度
- 沉迷游戏程度
- 最大沉迷游戏程度
- 被治疗程度
- 被救援程度

### 搞蛋鬼:人物

### 队伍:
- 队伍ID
- 队伍得分
- 队伍成员

### 所有物:
- 主人

### 子弹:所有物
- 子弹攻击范围
- 子弹爆炸范围
- 子弹攻击力
- 是否可以穿墙
- 是否为远程攻击
- 移动速度
- 子弹类型

### 爆炸中的子弹:物体
- 原来的子弹ID
- 爆炸范围
- 子弹类型

### 道具:所有物
- 道具类型

### 被捡起的道具:物体
- 原来的道具ID
- 道具类型

### 出口:物体
- 电力供应(是否可以被打开)
- 开启进度

### 紧急出口:物体
- 是否显现
- 是否打开

### 墙:物体

### 窗:物体
- 正在翻窗的人

### 箱子:物体
- 开箱进度

### 门:物体
- 属于那个教学区
- 是否锁上
- 开锁门进度
- 不提供是否可以锁上的属性

### 电机(建议称为homework):物体
- 修理程度

## 键鼠控制

| 键位 | 效果 |


Loading…
Cancel
Save