Browse Source

Merge branch 'dev' of github.com:DragonAura/THUAI6 into dev

tags/0.1.0
DragonAura 2 years ago
parent
commit
8aba210afb
14 changed files with 167 additions and 95 deletions
  1. +29
    -5
      README.md
  2. +14
    -7
      dependency/proto/Message2Server.proto
  3. +14
    -9
      logic/ClientTest/Program.cs
  4. +1
    -1
      logic/GameClass/GameObj/Character/Character.SkillManager.cs
  5. +2
    -1
      logic/GameClass/GameObj/Character/Character.cs
  6. +4
    -0
      logic/GameClass/Skill/ActiveSkill.cs
  7. +4
    -2
      logic/GameClass/Skill/Occupation.cs
  8. +14
    -0
      logic/Gaming/ActionManager.cs
  9. +15
    -2
      logic/Gaming/Game.cs
  10. +4
    -1
      logic/Preparation/Utility/EnumType.cs
  11. +1
    -1
      logic/Preparation/Utility/GameData.cs
  12. +53
    -55
      logic/Server/CopyInfo.cs
  13. +12
    -11
      logic/Server/GameServer.cs
  14. BIN
      resource/eesast_logo_32x32.png

+ 29
- 5
README.md View File

@@ -21,7 +21,7 @@ GitLink 镜像地址:[THUAI6: GitLink Mirror](https://www.gitlink.org.cn/EESAS

### 配置说明

本仓库使用 git 进行版本控制,为所有开发工作共用仓库,请勿上传不必要的文件。主目录文件结构非必要请勿修改,且主目录中已配置的`.gitignore`、`.gitattributes`文件非必要请勿修改;各子目录已预先包含使用`Visual Studio`开发的`.gitignore`模板,可以根据自身需要增加忽略规则;如有必要,可在子目录下自定义`.gitattributes`文件
本仓库使用 Git 进行版本控制,为所有开发工作共用仓库,请勿上传不必要的文件。主目录文件结构非必要请勿修改,且主目录中已配置的 `.gitignore`、`.gitattributes` 文件非必要请勿修改;各子目录已预先包含使用 `Visual Studio` 开发的 `.gitignore` 模板,可以根据自身需要增加忽略规则;如有必要,可在子目录下自定义 `.gitattributes` 文件

### 目录分配

@@ -46,7 +46,7 @@ GitLink 镜像地址:[THUAI6: GitLink Mirror](https://www.gitlink.org.cn/EESAS

### 关于社区开发者

- 社区开发者开发工作请遵循 [THUAI6社区开发者贡献指南](./CONTRIBUTING.md)
- 社区开发者开发工作请遵循 [THUAI6 社区开发者贡献指南](./CONTRIBUTING.md)
- 社区开发者贡献的代码请遵循 [Contributor Covenant Code of Conduct](./CODE_OF_CONDUCT.md)

### 开发流程
@@ -63,7 +63,7 @@ THUAI6 开发组成员与其他贡献者应当遵循以下流程:

- 非必要请勿上传大文件到 Github

- commit 提交信息请遵循 Semantic Commit 规范,即:`type: content `格式
- commit 提交信息请遵循 [Semantic Commits](https://www.conventionalcommits.org/zh-hans) 规范,即:`type: content` 格式

常用的 commit message type 包括:

@@ -90,7 +90,7 @@ THUAI6 开发组成员与其他贡献者应当遵循以下流程:

## 代码风格

本仓库严格规定了`C++`与`CSharp`代码风格,具体配置请参见 [.clang-format](.clang-format)
本仓库严格规定了 `C++` `CSharp` 代码风格,具体配置请参见 [.clang-format](.clang-format)

### 风格说明

@@ -158,17 +158,41 @@ THUAI6 开发组成员与其他贡献者应当遵循以下流程:
>

- 命名允许较长,但不应过于啰嗦冗余,能完整表明意图即可。

- 代码应保证良好的可读性;**禁止**中学 OI 竞赛的各种“卡常”奇技淫巧!!!效率并非总是最重要的,良好的可读性与可维护性往往更加重要

- 熟练运用面向对象编程的思想,设计架构时尽可能降低模块与模块的耦合性,保证代码的可维护性

- 慎用全局变量、全局函数等

- 尽可能将各功能模块化,便于日后复用;尽可能降低类与类的耦合,善用继承与多态

- 适当设计单元测试,保证代码的正确运行

- 注意跨平台问题,代码需保证同时支持 Windows 与 Linux,避免直接的系统调用带来的跨平台问题

- 善于使用 [Google](https://www.google.com/) 并使用[**英文**](https://en.wikipedia.org/wiki/American_English)搜索,善于查阅 [Microsoft Learn](https://learn.microsoft.com/)、[cppreference](https://en.cppreference.com/)、[StackOverflow](https://stackoverflow.com/) 以及第三方库官方文档等;不应轻信 [CSDN](https://www.csdn.net/) 等劣质博客社区以及[博客园](https://www.cnblogs.com/)、[简书](https://www.jianshu.com/)等质量参差不齐的博客社区,对其内容需全方位多角度仔细求证方可相信

- Pull requests 模板中的复选框采用 Markdown 格式:

```markdown
- [ ] 不勾选
- [x] 勾选
```
效果:
- [ ] 不勾选
- [x] 勾选

- 注意维护开发文档,便于后来者快速了解本仓库代码结构

- 小组内合理分工,避免个人任务量过重或过轻
- 做好部会记录,及时完成工作任务,避免拖延到ddl

- 做好部会记录,及时完成工作任务,避免拖延到 ddl

- 各组间多交流,相互了解各自的开发进度,加强协作,遇到困难互相帮助

- 加油,奥里给 ,冲冲冲

## 开发组成员


+ 14
- 7
dependency/proto/Message2Server.proto View File

@@ -18,38 +18,45 @@ message PlayerMsg
message MoveMsg
{
int64 player_id = 1;
double angle = 2;
int64 time_in_milliseconds = 3;
PlayerType player_type = 2;
double angle = 3;
int64 time_in_milliseconds = 4;
}

message PropMsg
{
int64 player_id = 1;
PropType prop_type = 2;
PlayerType player_type = 2;
PropType prop_type = 3;
}

message SendMsg
{
int64 player_id = 1;
int64 to_player_id = 2;
string message = 3;
PlayerType player_type = 2;
int64 to_player_id = 3;
PlayerType to_player_type = 4;
string message = 5;
}

message AttackMsg // 相当于攻击
{
int64 player_id = 1;
double angle = 2;
PlayerType player_type = 2;
double angle = 3;
}

message IDMsg
{
int64 player_id = 1;
PlayerType player_type = 2;
}

message SkillMsg
{
int64 player_id = 1;
int32 skill_id = 2;
PlayerType player_type = 2;
int32 skill_id = 3;
}

// 基本继承于THUAI5,为了使发送的信息尽可能不被浪费,暂定不发这类大包。


+ 14
- 9
logic/ClientTest/Program.cs View File

@@ -15,21 +15,26 @@ namespace ClientTest
playerInfo.PlayerType = PlayerType.StudentPlayer;
playerInfo.StudentType = StudentType.NullStudentType;
var call = client.AddPlayer(playerInfo);
MoveMsg moveMsg = new();
moveMsg.PlayerId = 0;
moveMsg.PlayerType = PlayerType.StudentPlayer;
moveMsg.TimeInMilliseconds = 100;
moveMsg.Angle = 0;
while (true)
{
Console.ReadLine();
client.Move(moveMsg);
Console.WriteLine("Move!");
}

while (await call.ResponseStream.MoveNext())
{
var currentGameInfo = call.ResponseStream.Current;
if (playerInfo.PlayerType == PlayerType.StudentPlayer)
{
for (int i = 0; i < currentGameInfo.StudentMessage.Count; i++)
{
Console.WriteLine($"Human is at ({currentGameInfo.StudentMessage[i].X}, {currentGameInfo.StudentMessage[i].Y})");
}
}
if (playerInfo.PlayerType == PlayerType.TrickerPlayer)
{
for (int i = 0; i < currentGameInfo.TrickerMessage.Count; i++)
for (int i = 0; i < currentGameInfo.ObjMessage.Count; i++)
{
Console.WriteLine($"Butcher is at ({currentGameInfo.TrickerMessage[i].X}, {currentGameInfo.TrickerMessage[i].Y})");
//Console.WriteLine($"Human is at ({currentGameInfo.StudentMessage[i].X}, {currentGameInfo.StudentMessage[i].Y})");
}
}
}


+ 1
- 1
logic/GameClass/GameObj/Character/Character.SkillManager.cs View File

@@ -12,7 +12,7 @@ namespace GameClass.GameObj
private readonly IOccupation occupation;
public IOccupation Occupation => occupation;

private Dictionary<ActiveSkillType, int> timeUntilActiveSkillAvailable;
private Dictionary<ActiveSkillType, int> timeUntilActiveSkillAvailable = new();
public Dictionary<ActiveSkillType, int> TimeUntilActiveSkillAvailable => timeUntilActiveSkillAvailable;

public bool SetTimeUntilActiveSkillAvailable(ActiveSkillType activeSkillType, int timeUntilActiveSkillAvailable)


+ 2
- 1
logic/GameClass/GameObj/Character/Character.cs View File

@@ -65,7 +65,7 @@ namespace GameClass.GameObj
}
set
{
if (!(value == PlayerStateType.IsMoving || value == PlayerStateType.Null))
if (!(value == PlayerStateType.IsMoving))
lock (gameObjLock)
IsMoving = false;

@@ -477,6 +477,7 @@ namespace GameClass.GameObj
playerState = playerStateType;
CanMove = false;
IsResetting = true;
Position = GameData.PosWhoDie;
}
}



+ 4
- 0
logic/GameClass/Skill/ActiveSkill.cs View File

@@ -214,6 +214,10 @@ namespace GameClass.Skill
{
case BecomeInvisible:
return ActiveSkillType.BecomeInvisible;
case UseKnife:
return ActiveSkillType.UseKnife;
case BeginToCharge:
return ActiveSkillType.BeginToCharge;
default:
return ActiveSkillType.Null;
}


+ 4
- 2
logic/GameClass/Skill/Occupation.cs View File

@@ -43,7 +43,7 @@ namespace GameClass.Skill
public List<IActiveSkill> ListOfIActiveSkill => new(new IActiveSkill[] { new BecomeInvisible(), new UseKnife() });
public List<IPassiveSkill> ListOfIPassiveSkill => new(new IPassiveSkill[] { });
}
public class Athlete : IOccupation
public class Athlete : IStudent
{
private const int moveSpeed = GameData.basicMoveSpeed;
public int MoveSpeed => moveSpeed;
@@ -59,7 +59,9 @@ namespace GameClass.Skill

public BulletType InitBullet => BulletType.CommonAttackOfGhost;

public List<IActiveSkill> ListOfIActiveSkill => new(new IActiveSkill[] { new BecomeInvisible(), new UseKnife() });
public List<IActiveSkill> ListOfIActiveSkill => new(new IActiveSkill[] { new BeginToCharge() });
public List<IPassiveSkill> ListOfIPassiveSkill => new(new IPassiveSkill[] { });

public int FixSpeed => GameData.basicFixSpeed;
}
}

+ 14
- 0
logic/Gaming/ActionManager.cs View File

@@ -22,6 +22,20 @@ namespace Gaming
return true;
}

public bool Stop(Character player)
{
if (player.PlayerState == PlayerStateType.IsRescuing || player.PlayerState == PlayerStateType.IsRescued
|| player.PlayerState == PlayerStateType.IsFixing || player.PlayerState == PlayerStateType.IsMoving
|| player.PlayerState == PlayerStateType.IsTreated || player.PlayerState == PlayerStateType.IsTreating
|| player.PlayerState == PlayerStateType.IsClosingDoor || player.PlayerState == PlayerStateType.IsOpeningDoor
|| player.PlayerState == PlayerStateType.IsClimbingThtoughWindows)
{
player.PlayerState = PlayerStateType.Null;
return true;
}
return false;
}

public bool Fix(Student player)// 自动检查有无发电机可修
{
if (player.PlayerState != PlayerStateType.Null || player.IsGhost())


+ 15
- 2
logic/Gaming/Game.cs View File

@@ -180,17 +180,18 @@ namespace Gaming
Character? player = gameMap.FindPlayer(playerID);
if (player != null)
{
return actionManager.MovePlayer(player, moveTimeInMilliseconds, angle);
var res = actionManager.MovePlayer(player, moveTimeInMilliseconds, angle);
#if DEBUG
Console.WriteLine($"PlayerID:{playerID} move to ({player.Position.x},{player.Position.y})!");
#endif
return res;
}
else
{
return false;
#if DEBUG
Console.WriteLine($"PlayerID:{playerID} player does not exists!");
#endif
return false;
}
}
public bool Treat(long playerID, long playerTreatedID)
@@ -243,6 +244,18 @@ namespace Gaming
}
return false;
}
public bool Stop(long playerID)
{
if (!gameMap.Timer.IsGaming)
return false;
Character player = gameMap.FindPlayer(playerID);
if (player != null)
{
return actionManager.Stop(player);
}
return false;
}

public void Attack(long playerID, double angle)
{
if (!gameMap.Timer.IsGaming)


+ 4
- 1
logic/Preparation/Utility/EnumType.cs View File

@@ -19,6 +19,9 @@ namespace Preparation.Utility
IsRescued = 10,
IsStunned = 11,
IsTryingToAttack = 12,//指前摇
IsOpeningDoor = 13,
IsClosingDoor = 14,
IsClimbingThtoughWindows = 15,
}
public enum GameObjType
{
@@ -79,7 +82,7 @@ namespace Preparation.Utility
NuclearWeapon = 3,
SuperFast = 4,
UseKnife = 5,
ASkill5 = 6
BeginToCharge = 6
}
public enum PassiveSkillType
{


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

@@ -7,7 +7,7 @@ namespace Preparation.Utility
{
#region 基本常数与常方法
public const int numOfPosGridPerCell = 1000; // 每格的【坐标单位】数
public const int numOfStepPerSecond = 100; // 每秒行走的步数
public const int numOfStepPerSecond = 20; // 每秒行走的步数
public const int frameDuration = 50; // 每帧时长

public const int lengthOfMap = 50000; // 地图长度


+ 53
- 55
logic/Server/CopyInfo.cs View File

@@ -8,7 +8,26 @@ namespace Server
public static class CopyInfo
{
// 下面赋值为0的大概率是还没写完 2023-03-03
private static MessageOfStudent Human(Character player)
/*public static MessageOfObj? Auto(GameObj gameObj)
{
if (gameObj.Type == Preparation.Utility.GameObjType.Character)
{
Character character = (Character)gameObj;
if (character.IsGhost())
return Tri
}
else if (gameObj.Type == Preparation.Utility.GameObjType.Bullet)
return Bullet((Bullet)gameObj);
else if (gameObj.Type == Preparation.Utility.GameObjType.Prop)
return Prop((Prop)gameObj);
else if (gameObj.Type == Preparation.Utility.GameObjType.BombedBullet)
return BombedBullet((BombedBullet)gameObj);
else if (gameObj.Type == Preparation.Utility.GameObjType.PickedProp)
return PickedProp((PickedProp)gameObj);
else return null; //先写着防报错
}*/

private static MessageOfStudent? Student(Character player)
{
MessageOfStudent msg = new MessageOfStudent();
if (player.IsGhost()) return null;
@@ -19,7 +38,6 @@ namespace Server
msg.Determination = player.HP;
msg.FailNum = 0;
msg.TimeUntilSkillAvailable = 0;
//msg.Place = 0; 下面写了
msg.StudentType = StudentType.NullStudentType; // 下面写
msg.Guid = 0;
msg.State = StudentState.NullStatus;
@@ -28,32 +46,7 @@ namespace Server
msg.PlayerId = 0;
msg.ViewRange = 0;
msg.Radius = 0;
//msg.Buff[0] = StudentBuffType.NullSbuffType; 下面写了

/* THUAI5中的内容
msg.BulletNum = player.BulletNum;
msg.CanMove = player.CanMove;
msg.CD = player.CD;
msg.GemNum = player.GemNum;
msg.Guid = player.ID;
msg.IsResetting = player.IsResetting;
msg.LifeNum = player.DeathCount + 1;
msg.Radius = player.Radius;
msg.TimeUntilCommonSkillAvailable = player.TimeUntilCommonSkillAvailable;
msg.TeamID = player.TeamID;
msg.PlayerID = player.PlayerID;
msg.IsInvisible = player.IsInvisible;
msg.FacingDirection = player.FacingDirection;

//应该要发队伍分数,这里先发个人分数
msg.MessageOfHuman.Score = player.Score;

//这条暂时没啥用
msg.MessageOfHuman.TimeUntilUltimateSkillAvailable = 0;

msg.MessageOfHuman.Vampire = player.Vampire;*/

foreach (KeyValuePair<Preparation.Utility.BuffType, bool> kvp in player.Buff)
{
@@ -78,19 +71,24 @@ namespace Server
}
}
}
/*switch (player.Place)
switch (player.Place)
{
case Preparation.Utility.PlaceType.Land:
msg.Place = PlaceType.Land;
case Preparation.Utility.PlaceType.EmergencyExit:
msg.Place = PlaceType.HiddenGate;
break;
case Preparation.Utility.PlaceType.Grass1:
msg.Place = PlaceType.Grass;
case Preparation.Utility.PlaceType.Doorway:
msg.Place = PlaceType.Gate;
break;
case Preparation.Utility.PlaceType.Grass2:
case Preparation.Utility.PlaceType.Grass:
msg.Place = PlaceType.Grass;
break;
case Preparation.Utility.PlaceType.Grass3:
msg.Place = PlaceType.Grass;
case Preparation.Utility.PlaceType.BirthPoint1:
case Preparation.Utility.PlaceType.BirthPoint2:
case Preparation.Utility.PlaceType.BirthPoint3:
case Preparation.Utility.PlaceType.BirthPoint4:
case Preparation.Utility.PlaceType.BirthPoint5:
case Preparation.Utility.PlaceType.Null:
msg.Place = PlaceType.Land;
break;
// case Preparation.Utility.PlaceType.Invisible:
// msg.MessageOfHuman.Place = Communication.Proto.PlaceType.Invisible;
@@ -98,36 +96,36 @@ namespace Server
default:
msg.Place = PlaceType.NullPlaceType;
break;
}*/
}

//Character的储存方式可能得改,用enum type存道具和子弹,不应该用对象
//现在懒得改了,有时间再重整一波
/*if (player.PropInventory == null)
msg.Prop = PropType.NullPropType;
if (player.PropInventory == null)
msg.Prop.Add(PropType.NullPropType);
else
{
switch (player.PropInventory.GetPropType())
{
case Preparation.Utility.PropType.Gem:
msg.Prop = PropType.NullPropType;
break;
case Preparation.Utility.PropType.addLIFE:
msg.MessageOfHuman.Prop = Communication.Proto.PropType.AddLife;
break;
case Preparation.Utility.PropType.addSpeed:
msg.MessageOfHuman.Prop = Communication.Proto.PropType.AddSpeed;
break;
case Preparation.Utility.PropType.Shield:
msg.MessageOfHuman.Prop = Communication.Proto.PropType.Shield;
break;
case Preparation.Utility.PropType.Spear:
msg.MessageOfHuman.Prop = Communication.Proto.PropType.Spear;
break;
default:
msg.Prop = PropType.NullPropType;
msg.Prop.Add(PropType.NullPropType);
break;
/*case Preparation.Utility.PropType.addLIFE:
msg.MessageOfHuman.Prop = Communication.Proto.PropType.AddLife;
break;
case Preparation.Utility.PropType.addSpeed:
msg.MessageOfHuman.Prop = Communication.Proto.PropType.AddSpeed;
break;
case Preparation.Utility.PropType.Shield:
msg.MessageOfHuman.Prop = Communication.Proto.PropType.Shield;
break;
case Preparation.Utility.PropType.Spear:
msg.MessageOfHuman.Prop = Communication.Proto.PropType.Spear;
break;
default:
msg.Prop = PropType.NullPropType;
break;*/
}
}*/
}
/*switch (player.PassiveSkillType) 需要对接一下,proto里似乎没有这个
{
case Preparation.Utility.PassiveSkillType.RecoverAfterBattle:


+ 12
- 11
logic/Server/GameServer.cs View File

@@ -114,6 +114,7 @@ namespace Server
public void ReportGame()
{
//currentGameInfo = null;
var gameObjList = game.GetGameObj();

foreach (var kvp in semaDict)
{
@@ -191,8 +192,9 @@ namespace Server
{
Game.PlayerInitInfo playerInitInfo = new(GetBirthPointIdx(request.PlayerType, request.PlayerId), PlayerTypeToTeamID(request.PlayerType), request.PlayerId, characterType);
long newPlayerID = game.AddPlayer(playerInitInfo);
//if (newPlayerID == GameObj.invalidID)
//return;
if (newPlayerID == GameObj.invalidID)
return;
communicationToGameID[PlayerTypeToTeamID(request.PlayerType), request.PlayerId] = newPlayerID;
// 内容待修改
var temp = (new SemaphoreSlim(0, 1), new SemaphoreSlim(0, 1));
bool start = false;
@@ -238,7 +240,8 @@ namespace Server
public override Task<MoveRes> Move(MoveMsg request, ServerCallContext context)
{
Console.WriteLine($"Move ID: {request.PlayerId}, TimeInMilliseconds: {request.TimeInMilliseconds}");
game.MovePlayer(request.PlayerId, (int)request.TimeInMilliseconds, request.Angle);
var gameID = communicationToGameID[PlayerTypeToTeamID(request.PlayerType), request.PlayerId];
game.MovePlayer(gameID, (int)request.TimeInMilliseconds, request.Angle);
// 之后game.MovePlayer可能改为bool类型
MoveRes moveRes = new();
moveRes.ActSuccess = true;
@@ -257,13 +260,11 @@ namespace Server
{
return base.SendMessage(request, context);
}

public override Task<BoolRes> UseProp(IDMsg request, ServerCallContext context)
public override Task<BoolRes> UseProp(PropMsg request, ServerCallContext context)
{
return base.UseProp(request, context);
}

public override Task<BoolRes> UseSkill(IDMsg request, ServerCallContext context)
public override Task<BoolRes> UseSkill(SkillMsg request, ServerCallContext context)
{
return base.UseSkill(request, context);
}
@@ -272,13 +273,13 @@ namespace Server
{
return base.Graduate(request, context);
}
public override Task<BoolRes> StartHealMate(IDMsg request, ServerCallContext context)
public override Task<BoolRes> StartRescueMate(IDMsg request, ServerCallContext context)
{
return base.StartHealMate(request, context);
return base.StartRescueMate(request, context);
}
public override Task<BoolRes> StartHelpMate(IDMsg request, ServerCallContext context)
public override Task<BoolRes> StartTreatMate(IDMsg request, ServerCallContext context)
{
return base.StartHelpMate(request, context);
return base.StartTreatMate(request, context);
}
public override Task<BoolRes> StartLearning(IDMsg request, ServerCallContext context)
{


BIN
resource/eesast_logo_32x32.png View File

Before After
Width: 32  |  Height: 32  |  Size: 3.0 kB

Loading…
Cancel
Save