Browse Source

Merge pull request #471 from Timothy-Liuxf/refactor/server

refactor(server): ♻️ make server base class to unify gameserver and playback server
tags/0.1.0
Timothy Liu GitHub 2 years ago
parent
commit
2333f02614
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 64 additions and 92 deletions
  1. +8
    -13
      logic/Server/GameServer.cs
  2. +11
    -11
      logic/Server/PlaybackServer.cs
  3. +27
    -57
      logic/Server/Program.cs
  4. +4
    -11
      logic/Server/RpcServices.cs
  5. +14
    -0
      logic/Server/ServerBase.cs

+ 8
- 13
logic/Server/GameServer.cs View File

@@ -1,22 +1,17 @@
using Grpc.Core;
using Protobuf;
using System.Threading;
using Timothy.FrameRateTask;
using System;
using System.Net.Http.Headers;
using GameClass.GameObj;
using Gaming; using Gaming;
using GameClass.GameObj;
using Preparation.Utility;
using Playback;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Preparation.Interface;
using Playback;
using Preparation.Utility;
using Protobuf;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using Timothy.FrameRateTask;




namespace Server namespace Server
{ {
public partial class GameServer : AvailableService.AvailableServiceBase
partial class GameServer : ServerBase
{ {
private ConcurrentDictionary<long, (SemaphoreSlim, SemaphoreSlim)> semaDict = new(); private ConcurrentDictionary<long, (SemaphoreSlim, SemaphoreSlim)> semaDict = new();
// private object semaDictLock = new(); // private object semaDictLock = new();
@@ -86,7 +81,7 @@ namespace Server
} }
} }


public void WaitForEnd()
public override void WaitForEnd()
{ {
this.endGameSem.Wait(); this.endGameSem.Wait();
mwr?.Dispose(); mwr?.Dispose();
@@ -202,7 +197,7 @@ namespace Server
return false; return false;
} }


public int[] GetScore()
public override int[] GetScore()
{ {
int[] score = new int[2]; // 0代表Student,1代表Tricker int[] score = new int[2]; // 0代表Student,1代表Tricker
game.GameMap.GameObjLockDict[GameObjType.Character].EnterReadLock(); game.GameMap.GameObjLockDict[GameObjType.Character].EnterReadLock();


+ 11
- 11
logic/Server/PlaybackServer.cs View File

@@ -1,26 +1,23 @@
using Protobuf;
using Playback;
using System;
using System.Threading;
using Timothy.FrameRateTask;
using Gaming;
using Gaming;
using Grpc.Core; using Grpc.Core;
using Playback;
using Protobuf;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using Timothy.FrameRateTask;


namespace Server namespace Server
{ {
class PlaybackServer : AvailableService.AvailableServiceBase
class PlaybackServer : ServerBase
{ {
protected readonly ArgumentOptions options; protected readonly ArgumentOptions options;
private int[,] teamScore; private int[,] teamScore;
private ConcurrentDictionary<long, (SemaphoreSlim, SemaphoreSlim)> semaDict = new(); private ConcurrentDictionary<long, (SemaphoreSlim, SemaphoreSlim)> semaDict = new();
private object semaDictLock = new();
// private object semaDictLock = new();
private MessageToClient? currentGameInfo = new(); private MessageToClient? currentGameInfo = new();
private MessageOfObj currentMapMsg = new(); private MessageOfObj currentMapMsg = new();
private uint spectatorMinPlayerID = 2023; private uint spectatorMinPlayerID = 2023;
private List<uint> spectatorList = new List<uint>();
// private List<uint> spectatorList = new List<uint>();
public int TeamCount => options.TeamCount; public int TeamCount => options.TeamCount;
private MessageWriter? mwr = null;
private object spetatorJoinLock = new(); private object spetatorJoinLock = new();
protected object spectatorLock = new object(); protected object spectatorLock = new object();
protected bool isSpectatorJoin = false; protected bool isSpectatorJoin = false;
@@ -47,6 +44,7 @@ namespace Server
return finalScore; return finalScore;
} }
} }
public override int[] GetScore() => FinalScore;
public PlaybackServer(ArgumentOptions options) public PlaybackServer(ArgumentOptions options)
{ {
this.options = options; this.options = options;
@@ -57,6 +55,7 @@ namespace Server


public override async Task AddPlayer(PlayerMsg request, IServerStreamWriter<MessageToClient> responseStream, ServerCallContext context) public override async Task AddPlayer(PlayerMsg request, IServerStreamWriter<MessageToClient> responseStream, ServerCallContext context)
{ {
Console.WriteLine($"AddPlayer: {request.PlayerId}");
if (request.PlayerId >= spectatorMinPlayerID && options.NotAllowSpectator == false) if (request.PlayerId >= spectatorMinPlayerID && options.NotAllowSpectator == false)
{ {
// 观战模式 // 观战模式
@@ -95,6 +94,7 @@ namespace Server
} }
catch { } catch { }
Console.WriteLine($"The spectator {request.PlayerId} exited"); Console.WriteLine($"The spectator {request.PlayerId} exited");
return;
} }
} }
catch (Exception) catch (Exception)
@@ -139,7 +139,7 @@ namespace Server
} }
} }


public void WaitForGame()
public override void WaitForEnd()
{ {
try try
{ {


+ 27
- 57
logic/Server/Program.cs View File

@@ -1,15 +1,16 @@
using Grpc.Core;
using CommandLine;
using Grpc.Core;
using Protobuf; using Protobuf;
using System.Threading;
using Timothy.FrameRateTask;
using System;
using System.Net.Http.Headers;
using CommandLine;


namespace Server namespace Server
{ {
public class Program public class Program
{ {
static ServerBase CreateServer(ArgumentOptions options)
{
return options.Playback ? new PlaybackServer(options) : new GameServer(options);
}

static int Main(string[] args) static int Main(string[] args)
{ {
foreach (var arg in args) foreach (var arg in args)
@@ -28,61 +29,30 @@ namespace Server


Console.WriteLine("Server begins to run: " + options.ServerPort.ToString()); Console.WriteLine("Server begins to run: " + options.ServerPort.ToString());


if (options.Playback)
try
{ {
try
{
PlaybackServer? playbackServer = new(options);
Grpc.Core.Server server = new Grpc.Core.Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) })
{
Services = { AvailableService.BindService(playbackServer) },
Ports = { new ServerPort(options.ServerIP, options.ServerPort, ServerCredentials.Insecure) }
};
server.Start();

Console.WriteLine("Server begins to listen!");
playbackServer.WaitForGame();
Console.WriteLine("Server end!");
server.ShutdownAsync().Wait();

Thread.Sleep(50);
Console.WriteLine("");
Console.WriteLine("=================== Final Score ====================");
Console.WriteLine($"Studnet: {playbackServer.FinalScore[0]}");
Console.WriteLine($"Tricker: {playbackServer.FinalScore[1]}");
}
catch (Exception ex)
var server = CreateServer(options);
Grpc.Core.Server rpcServer = new Grpc.Core.Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) })
{ {
Console.WriteLine(ex.ToString());
}
Services = { AvailableService.BindService(server) },
Ports = { new ServerPort(options.ServerIP, options.ServerPort, ServerCredentials.Insecure) }
};
rpcServer.Start();

Console.WriteLine("Server begins to listen!");
server.WaitForEnd();
Console.WriteLine("Server end!");
rpcServer.ShutdownAsync().Wait();

Thread.Sleep(50);
Console.WriteLine("");
Console.WriteLine("=================== Final Score ====================");
Console.WriteLine($"Studnet: {server.GetScore()[0]}");
Console.WriteLine($"Tricker: {server.GetScore()[1]}");
} }
else
catch (Exception ex)
{ {
try
{
GameServer? gameServer = new(options);
Grpc.Core.Server server = new Grpc.Core.Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) })
{
Services = { AvailableService.BindService(gameServer) },
Ports = { new ServerPort(options.ServerIP, options.ServerPort, ServerCredentials.Insecure) }
};
server.Start();

Console.WriteLine("Server begins to listen!");
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)
{
Console.WriteLine(ex.ToString());
}
Console.WriteLine(ex.ToString());
} }
return 0; return 0;
} }


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

@@ -1,19 +1,12 @@
using Grpc.Core;
using Protobuf;
using System.Threading;
using System;
using System.Net.Http.Headers;
using GameClass.GameObj;
using Gaming; using Gaming;
using GameClass.GameObj;
using Grpc.Core;
using Preparation.Utility; using Preparation.Utility;
using Playback;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Preparation.Interface;
using Protobuf;


namespace Server namespace Server
{ {
public partial class GameServer : AvailableService.AvailableServiceBase
partial class GameServer : ServerBase
{ {
private int playerCountNow = 0; private int playerCountNow = 0;
protected object spectatorLock = new object(); protected object spectatorLock = new object();


+ 14
- 0
logic/Server/ServerBase.cs View File

@@ -0,0 +1,14 @@
using Grpc.Core;
using Playback;
using Protobuf;
using System.Collections.Concurrent;
using Timothy.FrameRateTask;

namespace Server
{
abstract class ServerBase : AvailableService.AvailableServiceBase
{
public abstract void WaitForEnd();
public abstract int[] GetScore();
}
}

Loading…
Cancel
Save