Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Source/Client/Networking/HostUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ private static void PrepareLocalServer(ServerSettings settings, bool fromReplay)
localServer.startingTimer = TickPatch.Timer;
}

localServer.initData =
ServerInitData.Deserialize(new ByteReader(ClientJoiningState.PackInitData(settings.syncConfigs)));
localServer.StartInitData().SetResult(
ServerInitData.Deserialize(new ByteReader(ClientJoiningState.PackInitData(settings.syncConfigs))));
}

private static void PrepareGame()
Expand Down
4 changes: 2 additions & 2 deletions Source/Common/CommandHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@
{
bool debugCmd =
cmd == CommandType.DebugTools ||
cmd == CommandType.Sync && server.initData!.DebugOnlySyncCmds.Contains(BitConverter.ToInt32(data, 0));
cmd == CommandType.Sync && server.InitData!.DebugOnlySyncCmds.Contains(BitConverter.ToInt32(data, 0));
if (debugCmd && !CanUseDevMode(sourcePlayer))
return;

bool hostOnly = cmd == CommandType.Sync && server.initData!.HostOnlySyncCmds.Contains(BitConverter.ToInt32(data, 0));
bool hostOnly = cmd == CommandType.Sync && server.InitData!.HostOnlySyncCmds.Contains(BitConverter.ToInt32(data, 0));
if (hostOnly && !sourcePlayer.IsHost)
return;

Expand Down Expand Up @@ -79,7 +79,7 @@
}

public bool CanUseDevMode(ServerPlayer player) =>
server.settings.debugMode && server.settings.devModeScope switch

Check warning on line 82 in Source/Common/CommandHandler.cs

View workflow job for this annotation

GitHub Actions / Builds

The switch expression does not handle some values of its input type (it is not exhaustive) involving an unnamed enum value. For example, the pattern '(Multiplayer.Common.DevModeScope)2' is not covered.

Check warning on line 82 in Source/Common/CommandHandler.cs

View workflow job for this annotation

GitHub Actions / Builds

The switch expression does not handle some values of its input type (it is not exhaustive) involving an unnamed enum value. For example, the pattern '(Multiplayer.Common.DevModeScope)2' is not covered.
{
DevModeScope.Everyone => true,
DevModeScope.HostOnly => player.IsHost
Expand Down
15 changes: 4 additions & 11 deletions Source/Common/MultiplayerServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ static MultiplayerServer()
public ActionQueue queue = new();
public ServerSettings settings;

public ServerInitData? initData;
public ServerInitData? InitData => initDataSource.Task.ResultNowOrNull();
private TaskCompletionSource<ServerInitData?> initDataSource = new();
public InitDataState InitDataState =>
initData != null ? InitDataState.Complete :
InitData != null ? InitDataState.Complete :
// started init data must've completed with null, meaning the client disconnected while waiting for the data,
// so we are waiting again
initDataSource.Task.IsCompleted ? InitDataState.Waiting :
Expand Down Expand Up @@ -250,22 +250,15 @@ public void RegisterChatCmd(string cmdName, ChatCmdHandler handler) =>

public void HandleChatCmd(IChatSource source, string cmd) => chatCmdManager.Handle(source, cmd);

public Task<ServerInitData?> InitData() => initDataSource.Task;
public Task<ServerInitData?> InitDataTask() => initDataSource.Task;

/// Can only start one init data at a time. A StartInitData is considered complete once
/// TaskCompletionResult.SetResult is called. Until that time no new calls to StartInitData will succeed.
public TaskCompletionSource<ServerInitData?> StartInitData()
{
if (InitDataState != InitDataState.Waiting)
throw new InvalidOperationException($"Can't start init data in state {InitDataState}");
var currInitDataSource = initDataSource = new TaskCompletionSource<ServerInitData?>();
currInitDataSource.Task.ContinueWith(task =>
{
if (currInitDataSource != initDataSource)
ServerLog.Error("InitDataSource changed during StartInitData");
initData = task.Result;
}, TaskContinuationOptions.ExecuteSynchronously);
return currInitDataSource;
return initDataSource = new TaskCompletionSource<ServerInitData?>();
}
}

Expand Down
17 changes: 10 additions & 7 deletions Source/Common/Networking/State/ServerJoiningState.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Threading.Tasks;
using System;
using System.Threading.Tasks;

namespace Multiplayer.Common;

Expand All @@ -13,7 +14,7 @@ protected override async Task RunState()
HandleProtocol(await Packet(Packets.Client_Protocol));
HandleUsername(await Packet(Packets.Client_Username));

while (await Server.InitData() is null && await EndIfDead())
while (await Server.InitDataTask() is null && await EndIfDead())
if (Server.InitDataState == InitDataState.Waiting)
await RequestInitData();

Expand Down Expand Up @@ -105,9 +106,11 @@ private bool HandleClientJoinData(ByteReader data)
var modCtorRoundMode = data.ReadEnum<RoundModeEnum>();
var staticCtorRoundMode = data.ReadEnum<RoundModeEnum>();

if ((modCtorRoundMode, staticCtorRoundMode) != Server.initData!.RoundModes)
var serverInitData = Server.InitData ??
throw new Exception("Server init data is null during handling of client join data");
if ((modCtorRoundMode, staticCtorRoundMode) != serverInitData.RoundModes)
{
Player.Disconnect($"FP round modes don't match: {(modCtorRoundMode, staticCtorRoundMode)} != {Server.initData!.RoundModes}");
Player.Disconnect($"FP round modes don't match: {(modCtorRoundMode, staticCtorRoundMode)} != {serverInitData.RoundModes}");
return false;
}

Expand All @@ -129,7 +132,7 @@ private bool HandleClientJoinData(ByteReader data)

var status = DefCheckStatus.Ok;

if (!Server.initData!.DefInfos.TryGetValue(defType, out DefInfo info))
if (!serverInitData.DefInfos.TryGetValue(defType, out DefInfo info))
status = DefCheckStatus.Not_Found;
else if (info.count != defCount)
status = DefCheckStatus.Count_Diff;
Expand All @@ -146,10 +149,10 @@ private bool HandleClientJoinData(ByteReader data)
Packets.Server_JoinData,
Server.settings.gameName,
Player.id,
Server.initData!.RwVersion,
serverInitData.RwVersion,
MpVersion.Version,
defsResponse.ToArray(),
Server.initData.RawData
serverInitData.RawData
);

return defsMatch;
Expand Down
4 changes: 4 additions & 0 deletions Source/Common/Util/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace Multiplayer.Common
{
Expand Down Expand Up @@ -128,6 +129,9 @@ public static float MaxOrZero<T>(this IEnumerable<T> items, Func<T, float> map)
{
return items.Max(i => (float?)map(i)) ?? 0f;
}

public static T? ResultNowOrNull<T>(this Task<T> task) where T : class? =>
task.Status == TaskStatus.RanToCompletion ? task.Result : null;
}

public static class Utils
Expand Down
Loading