diff --git a/logic/Protos/Protos.csproj b/dependency/proto/Protos.csproj
similarity index 86%
rename from logic/Protos/Protos.csproj
rename to dependency/proto/Protos.csproj
index e6fac69..8c98b0a 100644
--- a/logic/Protos/Protos.csproj
+++ b/dependency/proto/Protos.csproj
@@ -10,11 +10,12 @@
+
-
+
@@ -27,6 +28,7 @@
+
diff --git a/logic/ClientTest/ClientTest.csproj b/logic/ClientTest/ClientTest.csproj
index e9bbb1e..075a2ce 100644
--- a/logic/ClientTest/ClientTest.csproj
+++ b/logic/ClientTest/ClientTest.csproj
@@ -14,7 +14,7 @@
-
+
diff --git a/logic/ClientTest/Program.cs b/logic/ClientTest/Program.cs
index 529dce3..ef30dc9 100644
--- a/logic/ClientTest/Program.cs
+++ b/logic/ClientTest/Program.cs
@@ -7,7 +7,7 @@ namespace ClientTest
{
public static async Task Main(string[] args)
{
- Channel channel = new Channel("127.0.0.1:8888", ChannelCredentials.Insecure);
+ Channel channel = new Channel("0.0.0.0:8888", ChannelCredentials.Insecure);
var client = new AvailableService.AvailableServiceClient(channel);
PlayerMsg playerInfo = new();
playerInfo.PlayerId = Convert.ToInt32(args[0]);
diff --git a/logic/Protos/Message2Clients.proto b/logic/Protos/Message2Clients.proto
deleted file mode 100644
index edae464..0000000
--- a/logic/Protos/Message2Clients.proto
+++ /dev/null
@@ -1,125 +0,0 @@
-// Message2Client
-syntax = "proto3";
-package protobuf;
-
-import "MessageType.proto";
-import "Message2Server.proto";
-
-message MessageOfHuman
-{
- int32 x = 1;
- int32 y = 2;
- int32 speed = 3;
- int32 life = 4; // 本次未倒地前的血量,也即还可以受的伤害
- int32 hanged_time = 5; // 被挂上的次数
- double time_until_skill_available = 6;
- PlaceType place = 7;
- PropType prop = 8;
- HumanType human_type = 9;
- int64 guid = 10;
- bool on_chair = 11; // 是否被挂
- double chair_time = 12; // 被挂的时间
- bool on_ground = 13; // 是否倒地
- double ground_time = 14; // 倒地时间
- int64 player_id = 15;
- int32 view_range = 16; // 视野距离
- repeated HumanBuffType buff = 17;
-}
-
-message MessageOfButcher
-{
- int32 x = 1;
- int32 y = 2;
- int32 speed = 3;
- int32 damage = 4;
- double time_until_skill_available = 5;
- PlaceType place = 6;
- PropType prop = 7;
- ButcherType butcher_type = 8;
- int64 guid = 9;
- bool movable = 10; // 是否进入了攻击后摇
- int64 playerID = 11;
- int32 view_range = 12; // 视野距离
- repeated ButcherBuffType buff = 13;
-}
-
-message MessageOfProp // 可拾取道具的信息
-{
- PropType type = 1;
- int32 x = 2;
- int32 y = 3;
- double facing_direction = 4;
- int64 guid = 5;
- PlaceType place = 6;
- int32 size = 7;
- bool is_moving = 8;
-}
-
-message MessageOfPickedProp //for Unity,直接继承自THUAI5
-{
- PropType type = 1;
- int32 x = 2;
- int32 y = 3;
- double facing_direction = 4;
- int64 mapping_id = 5;
-}
-
-message MessageOfMap
-{
- message Row
- {
- repeated PlaceType col = 1;
- }
- repeated Row row = 2;
-}
-
-message MessageToClient
-{
- repeated MessageOfHuman human_message = 1;
- repeated MessageOfButcher butcher_message = 2; // 是否真正repeated待定
- repeated MessageOfProp prop_message = 3;
- MessageOfMap map_massage = 4;
-}
-
-message MoveRes // 如果打算设计撞墙保留平行速度分量,且需要返回值则可用这个(大概没啥用)
-{
- int64 actual_speed = 1;
- double actual_angle = 2;
-}
-
-message BoolRes // 用于只需要判断执行操作是否成功的行为,如捡起道具、使用道具
-{
- bool act_success = 1;
-}
-
-message MsgRes // 用于获取队友发来的消息
-{
- bool have_message = 1; // 是否有待接收的消息
- int64 from_player_id = 2;
- string message_received = 3;
-}
-
-service AvailableService
-{
- rpc TryConnection(IDMsg) returns(BoolRes);
-
- // 游戏开局调用一次的服务
- rpc AddPlayer(PlayerMsg) returns(stream MessageToClient); // 连接上后等待游戏开始,server会定时通过该服务向所有client发送消息。
-
- // 游戏过程中玩家执行操作的服务
- rpc Move(MoveMsg) returns (MoveRes);
- rpc PickProp(PickMsg) returns (BoolRes);
- rpc UseProp(IDMsg) returns (BoolRes);
- rpc UseSkill(IDMsg) returns (BoolRes);
- rpc SendMessage(SendMsg) returns (BoolRes);
- rpc HaveMessage(IDMsg) returns (BoolRes);
- rpc GetMessage(IDMsg) returns (MsgRes);
- rpc FixMachine(stream IDMsg) returns (stream BoolRes); // 若正常修复且未被打断则返回修复成功,位置错误/被打断则返回修复失败,下同
- rpc SaveHuman(stream IDMsg) returns (stream BoolRes);
- rpc Attack (AttackMsg) returns (BoolRes);
- rpc CarryHuman (IDMsg) returns (BoolRes);
- rpc ReleaseHuman (IDMsg) returns (BoolRes);
- rpc HangHuman (IDMsg) returns (BoolRes);
- rpc Escape (IDMsg) returns (BoolRes);
-
-}
\ No newline at end of file
diff --git a/logic/Protos/Message2Server.proto b/logic/Protos/Message2Server.proto
deleted file mode 100644
index b3891b6..0000000
--- a/logic/Protos/Message2Server.proto
+++ /dev/null
@@ -1,62 +0,0 @@
-// Message2Server
-syntax = "proto3";
-package protobuf;
-
-import "MessageType.proto";
-
-message PlayerMsg
-{
- int64 player_id = 1;
- PlayerType player_type = 2;
- oneof job_type
- {
- HumanType human_type = 3;
- ButcherType butcher_type = 4;
- }
-}
-
-message MoveMsg
-{
- int64 player_id = 1;
- double angle = 2;
- int64 time_in_milliseconds = 3;
-}
-
-message PickMsg
-{
- int64 player_id = 1;
- PropType prop_type = 2;
-}
-
-message SendMsg
-{
- int64 player_id = 1;
- int64 to_player_id = 2;
- string message = 3;
-}
-
-message AttackMsg
-{
- int64 player_id = 1;
- double angle = 2;
-}
-
-message IDMsg
-{
- int64 player_id = 1;
-}
-
-// 基本继承于THUAI5,为了使发送的信息尽可能不被浪费,暂定不发这类大包。
-// message MessageToServer
-// {
-// MessageType messageType = 1;
-// int64 playerID = 2; // 消息发送者的playerID
-// PlayerType playerType = 3;
-// HumanType humanType= 4;
-// ButcherType butcherType = 5;
-// double angle = 6; // messageType为Move, Attack时的角度
-// PropType propType = 7; // messageType为PickProp时要捡起的道具类型,防止多个道具堆叠时出现问题
-// int64 timeInMilliseconds = 8;//时间参数
-// int64 ToPlayerID = 9; // messageType为Send时要发送的对象的ID
-// string message = 10; // messageType为Send时发送的消息内容
-// }
\ No newline at end of file
diff --git a/logic/Protos/MessageType.proto b/logic/Protos/MessageType.proto
deleted file mode 100644
index 2041fe0..0000000
--- a/logic/Protos/MessageType.proto
+++ /dev/null
@@ -1,110 +0,0 @@
-// MessageType
-syntax = "proto3";
-package protobuf;
-
-enum PlaceType // 地图中的所有物件类型
-{
- NULL_PLACE_TYPE = 0;
-
- // 地图情况,其中Gate是总体的大门,HiddenGate是地窖
- LAND = 1;
- WALL = 2;
- GRASS = 3;
- MACHINE = 4;
- GATE = 5;
- HIDDEN_GATE = 6;
- // 待补充有特殊效果的地形
-
-}
-
-enum ShapeType // 形状类型
-{
- NULL_SHAPE_TYPE = 0;
- CIRCLE = 1; // 人类、屠夫、可拾取道具等为圆形
- SQUARE = 2; // 地形均为方形
-}
-
-enum PropType // 地图中的可拾取道具类型
-{
- NULL_PROP_TYPE = 0;
- PTYPE1 = 1;
- PTYPE2 = 2;
- PTYPE3 = 3;
- PTYPE4 = 4;
-
-}
-
-enum HumanBuffType // 人类可用的增益效果类型
-{
- NULL_HBUFF_TYPE = 0;
- HBUFFTYPE1 = 1;
- HBUFFTYPE2 = 2;
- HBUFFTYPE3 = 3;
- HBUFFTYPE4 = 4;
-}
-
-enum ButcherBuffType // 屠夫可用的增益效果类型
-{
- NULL_BBUFF_TYPE = 0;
- BBUFFTYPE1 = 1;
- BBUFFTYPE2 = 2;
- BBUFFTYPE3 = 3;
- BBUFFTYPE4 = 4;
-}
-
-// 特别说明:由于Human阵营和Butcher阵营有显著的隔离,且暂定职业、主动技能和被动效果相互绑定,故不按照THUAI5的方式区分ActiveSkillType和PassiveSkillType,而是选择了按照阵营来给不同阵营赋予不同的职业(及技能)。
-
-enum PlayerType
-{
- NULL_PLAYER_TYPE = 0;
- HUMAN_PLAYER = 1;
- BUTCHER_PLAYER = 2;
-}
-
-enum HumanType
-{
- NULL_HUMAN_TYPE = 0;
- HUMANTYPE1 = 1;
- HUMANTYPE2 = 2;
- HUMANTYPE3 = 3;
- HUMANTYPE4 = 4;
-}
-
-enum ButcherType
-{
- NULL_BUTCHER_TYPE = 0;
- BUTCHERTYPE1 = 1;
- BUTCHERTYPE2 = 2;
- BUTCHERTYPE3 = 3;
- BUTCHERTYPE4 = 4;
-}
-
-// 取消了大包之后,MessageType的枚举是否有必要保留还有待商榷
-// enum MessageType
-// {
-// // 公共信息类型
-// Move = 0;
-// PickProp = 1;
-// UseProp = 2;
-// UseSkill = 3;
-// Map = 4;
-// Send = 5;
-
-// // 人类限定信息类型
-// FixMachine = 6;
-// SaveHuman = 7;
-
-// // 屠夫限定信息类型
-// Attack = 8;
-// CarryHuman = 9;
-// ReleaseHuman = 10;
-// HangHuman = 11;
-
-// // 游戏相关信息类型
-// AddPlayer = 12;
-// InvalidPlayer = 13;
-// ValidPlayer = 14;
-// StartGame = 15;
-// Gaming = 16;
-// EndGame = 17;
-// }
diff --git a/logic/Server/Game.cs b/logic/Server/Game.cs
index 96e7680..9eef516 100644
--- a/logic/Server/Game.cs
+++ b/logic/Server/Game.cs
@@ -18,7 +18,7 @@ namespace Server
public bool IsGaming
{
get => Interlocked.CompareExchange(ref isGaming, 0, 0) != 0;
- set => Interlocked.Exchange(ref isGaming, value ? 1 : 0);
+ set => Interlocked.Exchange(ref isGaming, value? 1: 0);
}
public MessageToClient GetCopiedGameInfo()
@@ -32,19 +32,18 @@ namespace Server
{
lock (gameInfoLock)
{
- if (player.PlayerType == PlayerType.NullPlayerType) return;
+ if (player.PlayerType == PlayerType.NullPlayerType)
+ return;
if (player.PlayerType == PlayerType.HumanPlayer)
{
- gameInfo.HumanMessage.Add(new MessageOfHuman()
- {
+ gameInfo.HumanMessage.Add(new MessageOfHuman() {
PlayerId = player.PlayerId
});
return;
}
if (player.PlayerType == PlayerType.ButcherPlayer)
{
- gameInfo.ButcherMessage.Add(new MessageOfButcher()
- {
+ gameInfo.ButcherMessage.Add(new MessageOfButcher() {
PlayerID = player.PlayerId
});
return;
@@ -66,39 +65,39 @@ namespace Server
() => IsGaming,
() =>
{
- lock (gameInfo)
- {
- for (int i = 0; i < gameInfo.HumanMessage.Count; i++)
- {
- if (gameInfo.HumanMessage[i] != null)
- {
- gameInfo.HumanMessage[i].X++;
- gameInfo.HumanMessage[i].Y--;
- }
- }
- for (int i = 0; i < gameInfo.ButcherMessage.Count; i++)
- {
- if (gameInfo.ButcherMessage[i] != null)
- {
- gameInfo.ButcherMessage[i].X--;
- gameInfo.ButcherMessage[i].Y++;
- }
- }
- }
+ lock (gameInfo)
+ {
+ for (int i = 0; i < gameInfo.HumanMessage.Count; i++)
+ {
+ if (gameInfo.HumanMessage[i] != null)
+ {
+ gameInfo.HumanMessage[i].X++;
+ gameInfo.HumanMessage[i].Y--;
+ }
+ }
+ for (int i = 0; i < gameInfo.ButcherMessage.Count; i++)
+ {
+ if (gameInfo.ButcherMessage[i] != null)
+ {
+ gameInfo.ButcherMessage[i].X--;
+ gameInfo.ButcherMessage[i].Y++;
+ }
+ }
+ }
},
100,
() =>
{
- IsGaming = false;
- waitHandle.Release();
- return 0;
+ IsGaming = false;
+ waitHandle.Release();
+ return 0;
},
gameTime
).Start();
- }
+ }
)
{ IsBackground = true }.Start();
return waitHandle;
- }
}
}
+}
diff --git a/logic/Server/GameServer.cs b/logic/Server/GameServer.cs
index c31d611..f97a06f 100644
--- a/logic/Server/GameServer.cs
+++ b/logic/Server/GameServer.cs
@@ -11,7 +11,7 @@ namespace Server
{
private Dictionary semaDict = new();
private object gameLock = new();
- private const int playerNum = 2;
+ private const int playerNum = 1;
private MessageToClient currentGameInfo = new();
private Game game = new();
public int GameTime => game.GameTime;
@@ -22,11 +22,11 @@ namespace Server
var onConnection = new BoolRes();
lock (gameLock)
{
- if (0 <= request.PlayerId && request.PlayerId < playerNum)
+ // if (0 <= request.PlayerId && request.PlayerId < playerNum)
{
onConnection.ActSuccess = true;
return Task.FromResult(onConnection);
- }
+ }
}
onConnection.ActSuccess = false;
return Task.FromResult(onConnection);
@@ -53,13 +53,12 @@ namespace Server
{
Console.WriteLine("Game starts!");
StartGame();
- }
+ }
}
do
{
semaDict[request.PlayerId].Item1.Wait();
-
if (currentGameInfo != null)
{
await responseStream.WriteAsync(currentGameInfo);
@@ -80,44 +79,42 @@ namespace Server
1000,
() =>
{
- ReportGame(); // 最后发一次消息,唤醒发消息的线程,防止发消息的线程由于有概率处在 Wait 状态而卡住
- return 0;
+ ReportGame(); // 最后发一次消息,唤醒发消息的线程,防止发消息的线程由于有概率处在 Wait 状态而卡住
+ return 0;
}
).Start();
- })
+ })
{ IsBackground = true }.Start();
new Thread(() =>
{
waitHandle.Wait();
- this.endGameSem.Release();
- })
+ this.endGameSem.Release();
+ })
{ IsBackground = true }.Start();
+}
+public void WaitForEnd()
+{
+ this.endGameSem.Wait();
+}
- }
- public void WaitForEnd()
- {
- this.endGameSem.Wait();
- }
-
- public void ReportGame()
- {
- currentGameInfo = game.GetCopiedGameInfo();
-
- foreach (var kvp in semaDict)
- {
- kvp.Value.Item1.Release();
- }
+public void ReportGame()
+{
+ currentGameInfo = game.GetCopiedGameInfo();
- foreach (var kvp in semaDict)
- {
- kvp.Value.Item2.Wait();
- }
- }
+ foreach (var kvp in semaDict)
+ {
+ kvp.Value.Item1.Release();
+ }
- public GameServer()
- {
+ foreach (var kvp in semaDict)
+ {
+ kvp.Value.Item2.Wait();
+ }
+}
- }
- }
+public GameServer()
+{
+}
+}
}
\ No newline at end of file
diff --git a/logic/Server/Program.cs b/logic/Server/Program.cs
index 155a97b..080ac4d 100644
--- a/logic/Server/Program.cs
+++ b/logic/Server/Program.cs
@@ -14,8 +14,7 @@ namespace Server
try
{
GameServer gameServer = new();
- Grpc.Core.Server server = new Grpc.Core.Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) })
- {
+ Grpc.Core.Server server = new Grpc.Core.Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) }) {
Services = { AvailableService.BindService(gameServer) },
Ports = { new ServerPort("0.0.0.0", 8888, ServerCredentials.Insecure) }
};
diff --git a/logic/Server/Server.csproj b/logic/Server/Server.csproj
index b87aa89..62045cf 100644
--- a/logic/Server/Server.csproj
+++ b/logic/Server/Server.csproj
@@ -19,7 +19,7 @@
-
+
diff --git a/logic/logic.sln b/logic/logic.sln
index 2fc1991..d95a3b7 100644
--- a/logic/logic.sln
+++ b/logic/logic.sln
@@ -5,9 +5,9 @@ VisualStudioVersion = 17.0.32014.148
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Server", "Server\Server.csproj", "{D033B809-2FB7-4340-B8B4-DDA30D6CA6FF}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Protos", "Protos\Protos.csproj", "{EA81EE05-A0E3-4D3E-8D7A-C5CD0C9255CD}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClientTest", "ClientTest\ClientTest.csproj", "{F3C98717-DD4F-45B8-B0F0-C217E7E2B5D4}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClientTest", "ClientTest\ClientTest.csproj", "{F3C98717-DD4F-45B8-B0F0-C217E7E2B5D4}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Protos", "..\dependency\proto\Protos.csproj", "{9ADA1EF8-DF2F-4C2E-9DE2-BC94DF89B44D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -19,14 +19,14 @@ Global
{D033B809-2FB7-4340-B8B4-DDA30D6CA6FF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D033B809-2FB7-4340-B8B4-DDA30D6CA6FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D033B809-2FB7-4340-B8B4-DDA30D6CA6FF}.Release|Any CPU.Build.0 = Release|Any CPU
- {EA81EE05-A0E3-4D3E-8D7A-C5CD0C9255CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {EA81EE05-A0E3-4D3E-8D7A-C5CD0C9255CD}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {EA81EE05-A0E3-4D3E-8D7A-C5CD0C9255CD}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {EA81EE05-A0E3-4D3E-8D7A-C5CD0C9255CD}.Release|Any CPU.Build.0 = Release|Any CPU
{F3C98717-DD4F-45B8-B0F0-C217E7E2B5D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F3C98717-DD4F-45B8-B0F0-C217E7E2B5D4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F3C98717-DD4F-45B8-B0F0-C217E7E2B5D4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F3C98717-DD4F-45B8-B0F0-C217E7E2B5D4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9ADA1EF8-DF2F-4C2E-9DE2-BC94DF89B44D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9ADA1EF8-DF2F-4C2E-9DE2-BC94DF89B44D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9ADA1EF8-DF2F-4C2E-9DE2-BC94DF89B44D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9ADA1EF8-DF2F-4C2E-9DE2-BC94DF89B44D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE