-
Notifications
You must be signed in to change notification settings - Fork 30
Expand file tree
/
Copy pathTestMultiplayerServer.cs
More file actions
120 lines (100 loc) · 4.08 KB
/
TestMultiplayerServer.cs
File metadata and controls
120 lines (100 loc) · 4.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
using System;
using System.Collections.Generic;
using System.Linq;
using MultiplayerMod.Core.Extensions;
using MultiplayerMod.ModRuntime;
using MultiplayerMod.Multiplayer.Commands;
using MultiplayerMod.Multiplayer.Commands.Registry;
using MultiplayerMod.Network;
namespace MultiplayerMod.Test.Environment.Network;
public class TestMultiplayerServer : IMultiplayerServer {
public event Action<MultiplayerServerState>? StateChanged;
public event Action<IMultiplayerClientId>? ClientConnected;
public event Action<IMultiplayerClientId>? ClientDisconnected;
public event Action<IMultiplayerClientId, IMultiplayerCommand>? CommandReceived;
public MultiplayerServerState State { get; private set; } = MultiplayerServerState.Stopped;
public IMultiplayerEndpoint Endpoint { get; }
public List<IMultiplayerClientId> Clients { get; } = new();
private readonly TestRuntime runtime;
private readonly MultiplayerCommandRegistry registry;
private readonly TestMultiplayerClientId currentPlayer;
private readonly Queue<System.Action> pendingActions = new();
public bool EnablePendingActions { get; set; }
public TestMultiplayerServer(
TestMultiplayerClientId identity,
TestRuntime runtime,
MultiplayerCommandRegistry registry
) {
Endpoint = new TestMultiplayerEndpoint(this);
currentPlayer = identity;
this.runtime = runtime;
this.registry = registry;
}
public void Start() {
EnqueuePendingAction(() => SetState(MultiplayerServerState.Preparing));
EnqueuePendingAction(() => SetState(MultiplayerServerState.Starting));
EnqueuePendingAction(() => SetState(MultiplayerServerState.Started));
}
public void Stop() {
EnqueuePendingAction(() => SetState(MultiplayerServerState.Stopped));
}
public bool RunPendingAction() {
if (pendingActions.Count <= 0)
return false;
pendingActions.Dequeue().Invoke();
return true;
}
private void EnqueuePendingAction(System.Action action) {
if (EnablePendingActions) {
pendingActions.Enqueue(action);
return;
}
action();
}
public void Send(IMultiplayerClientId player, IMultiplayerCommand command) {
(player as TestMultiplayerClientId)!.Client.Receive(CommandTools.Copy(command));
}
public void Send(IMultiplayerCommand command, MultiplayerCommandOptions options) {
var oldRuntime = (TestRuntime) Runtime.Instance;
try {
runtime.Activate();
var players = new List<IMultiplayerClientId>(Clients).Cast<TestMultiplayerClientId>();
if (options.HasFlag(MultiplayerCommandOptions.SkipHost))
players = players.Where(it => !it.Equals(currentPlayer));
players.ForEach(it => it.Client.Receive(CommandTools.Copy(command)));
} finally {
oldRuntime.Activate();
}
}
private void SetState(MultiplayerServerState state) {
State = state;
StateChanged?.Invoke(state);
}
public void Accept(IMultiplayerClientId client) {
Clients.Add(client);
ClientConnected?.Invoke(client);
}
public void Drop(IMultiplayerClientId client) {
Clients.Remove(client);
ClientDisconnected?.Invoke(client);
}
public void Receive(TestMultiplayerClient source, IMultiplayerCommand command, MultiplayerCommandOptions options) {
var oldRuntime = (TestRuntime) Runtime.Instance;
try {
runtime.Activate();
var configuration = registry.GetCommandConfiguration(command.GetType());
if (configuration.ExecuteOnServer) {
CommandReceived?.Invoke(source.Id, CommandTools.Copy(command));
return;
}
new List<IMultiplayerClientId>(Clients).Cast<TestMultiplayerClientId>()
.Where(it => !ReferenceEquals(it.Client, source))
.ForEach(it => it.Client.Receive(CommandTools.Copy(command)));
} finally {
oldRuntime.Activate();
}
}
public void Tick()
{
}
}