Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#66 Kick client if server leaves/crashes. #259

Merged
merged 1 commit into from
Oct 18, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ private static void PlayerConnectedAndDisconnected(bool gracefully) {
clientRuntime.Activate();

if (gracefully) {
clientRuntime.EventDispatcher().Dispatch(new GameQuitEvent(clientRuntime.Multiplayer()));
clientRuntime.EventDispatcher().Dispatch(new GameQuitEvent());
Assert.AreEqual(expected: 0, clientRuntime.Multiplayer().Players.Count());
} else {
clientRuntime.Dependencies.Get<IMultiplayerClient>().Disconnect();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ private void Bind() {
log.Debug("Binding host events");

eventDispatcher.Subscribe<GameStartedEvent>(OnGameStarted);
eventDispatcher.Subscribe<GameQuitEvent>(OnGameQuit);
eventDispatcher.Subscribe<StopMultiplayerEvent>(OnStopMultiplayer);

ChoreConsumerEvents.FindNextChore += p => server.Send(new FindNextChore(p), MultiplayerCommandOptions.SkipHost);
}
Expand All @@ -51,7 +51,7 @@ private void OnGameStarted(GameStartedEvent @event) {
};
}

private void OnGameQuit(GameQuitEvent @event) {
private void OnStopMultiplayer(StopMultiplayerEvent @event) {
if (@event.Multiplayer.Mode != MultiplayerMode.Host)
return;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
using MultiplayerMod.Core.Events;

namespace MultiplayerMod.Multiplayer.CoreOperations.Events;

public record ConnectionLostEvent : IDispatchableEvent;
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

namespace MultiplayerMod.Multiplayer.CoreOperations.Events;

public record GameQuitEvent(MultiplayerGame Multiplayer) : IDispatchableEvent;
public record GameQuitEvent : IDispatchableEvent;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
using MultiplayerMod.Core.Events;

namespace MultiplayerMod.Multiplayer.CoreOperations.Events;

public record StopMultiplayerEvent(MultiplayerGame Multiplayer) : IDispatchableEvent;
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ MultiplayerGame multiplayer
eventDispatcher.Subscribe<SinglePlayerModeSelectedEvent>(OnSinglePlayerModeSelected);
eventDispatcher.Subscribe<MultiplayerModeSelectedEvent>(OnMultiplayerModeSelected);
eventDispatcher.Subscribe<PlayerStateChangedEvent>(OnPlayerStateChangedEvent);
eventDispatcher.Subscribe<GameQuitEvent>(OnGameQuit);
eventDispatcher.Subscribe<StopMultiplayerEvent>(OnStopMultiplayer);
}

private void OnSinglePlayerModeSelected(SinglePlayerModeSelectedEvent @event) {
Expand All @@ -41,7 +41,7 @@ private void OnPlayerStateChangedEvent(PlayerStateChangedEvent @event) {
executionLevelManager.BaseLevel = ExecutionLevel.Game;
}

private void OnGameQuit(GameQuitEvent _) {
private void OnStopMultiplayer(StopMultiplayerEvent _) {
executionLevelManager.BaseLevel = ExecutionLevel.System;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public GameStateEventsRelay(EventDispatcher events, MultiplayerGame multiplayer,

private void OnWorldSave() => events.Dispatch(new WorldSavedEvent());

private void OnGameQuit() => events.Dispatch(new GameQuitEvent(multiplayer));
private void OnGameQuit() => events.Dispatch(new GameQuitEvent());

private void OnGameStarted() => scheduler.Run(() => events.Dispatch(new GameStartedEvent(multiplayer)));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public MultiplayerServerController(IMultiplayerServer server, IMultiplayerClient
this.events = events;

events.Subscribe<GameStartedEvent>(OnGameStarted);
events.Subscribe<GameQuitEvent>(OnGameQuit);
events.Subscribe<StopMultiplayerEvent>(OnStopMultiplayer);

server.StateChanged += OnServerStateChanged;
}
Expand All @@ -46,7 +46,7 @@ private void OnGameStarted(GameStartedEvent @event) {
server.Start();
}

private void OnGameQuit(GameQuitEvent @event) {
private void OnStopMultiplayer(StopMultiplayerEvent @event) {
if (@event.Multiplayer.Mode != MultiplayerMode.Host)
return;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ public class PlayersManagementController {
private readonly IMultiplayerServer server;
private readonly IMultiplayerClient client;

private readonly EventDispatcher events;

private readonly WorldManager worldManager;
private readonly MultiplayerGame multiplayer;
private readonly UnityTaskScheduler scheduler;
Expand All @@ -39,19 +41,21 @@ public PlayersManagementController(
MultiplayerGame multiplayer,
UnityTaskScheduler scheduler
) {
this.client = client;
this.profileProvider = profileProvider;
this.server = server;
this.client = client;
this.events = events;
this.worldManager = worldManager;
this.multiplayer = multiplayer;
this.scheduler = scheduler;
this.profileProvider = profileProvider;

server.ClientDisconnected += OnClientDisconnected;
events.Subscribe<ClientInitializationRequestEvent>(OnClientInitializationRequested);

client.StateChanged += OnClientStateChanged;
events.Subscribe<GameStartedEvent>(OnGameStarted);
events.Subscribe<GameQuitEvent>(OnGameQuit);
events.Subscribe<StopMultiplayerEvent>(OnStopMultiplayer);
events.Subscribe<CurrentPlayerInitializedEvent>(OnCurrentPlayerInitialized);
events.Subscribe<WorldSyncRequestedEvent>(OnWorldSaveRequested);
}
Expand All @@ -65,10 +69,12 @@ private void OnCurrentPlayerInitialized(CurrentPlayerInitializedEvent @event) {
}

private void OnClientStateChanged(MultiplayerClientState state) {
if (state != MultiplayerClientState.Connected)
return;

client.Send(new InitializeClientCommand(profileProvider.GetPlayerProfile()));
if (state == MultiplayerClientState.Connected)
client.Send(new InitializeClientCommand(profileProvider.GetPlayerProfile()));
if (state == MultiplayerClientState.Error) {
events.Dispatch(new StopMultiplayerEvent(multiplayer));
zuev93 marked this conversation as resolved.
Show resolved Hide resolved
events.Dispatch(new ConnectionLostEvent());
}
}

private void OnGameStarted(GameStartedEvent @event) {
Expand All @@ -81,6 +87,10 @@ private void OnGameStarted(GameStartedEvent @event) {

private void OnGameQuit(GameQuitEvent @event) {
client.Send(new RequestPlayerStateChangeCommand(multiplayer.Players.Current.Id, PlayerState.Leaving));
events.Dispatch(new StopMultiplayerEvent(multiplayer));
}

private void OnStopMultiplayer(StopMultiplayerEvent @event) {
client.Disconnect();
multiplayer.Players.Synchronize(Array.Empty<MultiplayerPlayer>());
}
Expand Down
27 changes: 27 additions & 0 deletions src/MultiplayerMod/Multiplayer/UI/Notifications.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using JetBrains.Annotations;
using MultiplayerMod.Core.Dependency;
using MultiplayerMod.Core.Events;
using MultiplayerMod.Multiplayer.CoreOperations.Events;

namespace MultiplayerMod.Multiplayer.UI;

[Dependency, UsedImplicitly]
public class Notifications {

public Notifications(EventDispatcher events) {
events.Subscribe<ConnectionLostEvent>(OnConnectionLost);
}

private void OnConnectionLost(ConnectionLostEvent @event) {
var screen = (InfoDialogScreen) GameScreenManager.Instance.StartScreen(
ScreenPrefabs.Instance.InfoDialogScreen.gameObject,
GameScreenManager.Instance.ssOverlayCanvas.gameObject
);
screen.SetHeader("Multiplayer");
screen.AddPlainText("Connection has been lost. Further play can not be synced");
screen.AddOption(
"OK",
polycone marked this conversation as resolved.
Show resolved Hide resolved
_ => PauseScreen.Instance.OnQuitConfirm()
);
}
}
6 changes: 4 additions & 2 deletions src/MultiplayerMod/Platform/Steam/Network/SteamClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public void Connect(IMultiplayerEndpoint endpoint) {
}

public void Disconnect() {
if (State <= MultiplayerClientState.Disconnected)
if (State == MultiplayerClientState.Disconnected)
throw new NetworkPlatformException("Client not connected");

UnityObject.Destroy(gameObject);
Expand Down Expand Up @@ -96,8 +96,10 @@ public void Send(IMultiplayerCommand command, MultiplayerCommandOptions options
k_nSteamNetworkingSend_Reliable,
out var messageOut
);
if (result != EResult.k_EResultOK && messageOut == 0)
if (result != EResult.k_EResultOK || messageOut == 0) {
log.Error($"Failed to send {command}: {result}");
SetState(MultiplayerClientState.Error);
}
}
);
}
Expand Down