Browse Source

fix: 🐛 spectator now can get mapMsg when isgaming

tags/0.1.0
gsy1519 2 years ago
parent
commit
645373ae4d
1 changed files with 60 additions and 12 deletions
  1. +60
    -12
      logic/Server/PlaybackServer.cs

+ 60
- 12
logic/Server/PlaybackServer.cs View File

@@ -5,6 +5,7 @@ using System.Threading;
using Timothy.FrameRateTask;
using Gaming;
using Grpc.Core;
using System.Collections.Concurrent;

namespace Server
{
@@ -12,13 +13,31 @@ namespace Server
{
protected readonly ArgumentOptions options;
private int[,] teamScore;
private Dictionary<long, (SemaphoreSlim, SemaphoreSlim)> semaDict = new();
private ConcurrentDictionary<long, (SemaphoreSlim, SemaphoreSlim)> semaDict = new();
private object semaDictLock = new();
private MessageToClient? currentGameInfo = new();
private MessageOfObj currentMapMsg = new();
private uint spectatorMinPlayerID = 2023;
private List<uint> spectatorList = new List<uint>();
public int TeamCount => options.TeamCount;
private MessageWriter? mwr = null;
private object spetatorJoinLock = new();
protected object spectatorLock = new object();
protected bool isSpectatorJoin = false;
protected bool IsSpectatorJoin
{
get
{
lock (spectatorLock)
return isSpectatorJoin;
}

set
{
lock (spectatorLock)
isSpectatorJoin = value;
}
}
private bool IsGaming { get; set; }
private int[] finalScore;
public int[] FinalScore
@@ -38,18 +57,20 @@ namespace Server

public override async Task AddPlayer(PlayerMsg request, IServerStreamWriter<MessageToClient> responseStream, ServerCallContext context)
{
if (request.PlayerId >= spectatorMinPlayerID)
if (request.PlayerId >= spectatorMinPlayerID && options.NotAllowSpectator == false)
{
// 观战模式
uint tp = (uint)request.PlayerId;
if (!spectatorList.Contains(tp))
lock (spetatorJoinLock) // 具体原因见另一个上锁的地方
{
spectatorList.Add(tp);
Console.WriteLine("A new spectator comes to watch this game.");
var temp = (new SemaphoreSlim(0, 1), new SemaphoreSlim(0, 1));
lock (semaDictLock)
if (semaDict.TryAdd(request.PlayerId, (new SemaphoreSlim(0, 1), new SemaphoreSlim(0, 1))))
{
Console.WriteLine("A new spectator comes to watch this game.");
IsSpectatorJoin = true;
}
else
{
semaDict.Add(request.PlayerId, temp);
Console.WriteLine($"Duplicated Spectator ID {request.PlayerId}");
return;
}
}
do
@@ -63,15 +84,32 @@ namespace Server
//Console.WriteLine("Send!");
}
}
catch (InvalidOperationException)
{
if (semaDict.TryRemove(request.PlayerId, out var semas))
{
try
{
semas.Item1.Release();
semas.Item2.Release();
}
catch { }
Console.WriteLine($"The spectator {request.PlayerId} exited");
}
}
catch (Exception)
{
//Console.WriteLine(ex);
// Console.WriteLine(ex);
}
finally
{
semaDict[request.PlayerId].Item2.Release();
try
{
semaDict[request.PlayerId].Item2.Release();
}
catch { }
}
} while (IsGaming == true);
} while (IsGaming);
return;
}
}
@@ -79,6 +117,16 @@ namespace Server
public void ReportGame(MessageToClient? msg)
{
currentGameInfo = msg;
if (currentGameInfo != null && currentGameInfo.GameState == GameState.GameStart)
{
currentMapMsg = currentGameInfo.ObjMessage[0];
}

if (currentGameInfo != null && IsSpectatorJoin)
{
currentGameInfo.ObjMessage.Add(currentMapMsg);
IsSpectatorJoin = false;
}

foreach (var kvp in semaDict)
{


Loading…
Cancel
Save