Skip to content

Commit 4213908

Browse files
committed
Barrel respawn fix, remote server restart, player connect events
Fixed bug of respawning barrels due to RpcDespawnAll being too fast. Improved headless server argument support logic, enabled a new admin password to restart server, and moved it away from Mirror library. Prevented ShatterPart exception when the car respawns. Added player connect & disconnect events + displaying their count.
1 parent 313422f commit 4213908

12 files changed

Lines changed: 116 additions & 36 deletions

File tree

Assets/Game/Prefabs/Network/NetworkManager.prefab

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ MonoBehaviour:
103103
m_EditorClassIdentifier:
104104
dontDestroyOnLoad: 1
105105
runInBackground: 1
106-
startOnHeadless: 1
106+
startOnHeadless: 0
107107
showDebugMessages: 0
108108
serverTickRate: 30
109109
offlineScene: Assets/Game/Scenes/MainMenu.unity

Assets/Game/Prefabs/UI/MultiplayerUI.prefab

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -835,7 +835,7 @@ MonoBehaviour:
835835
m_HighlightedTrigger: Highlighted
836836
m_PressedTrigger: Pressed
837837
m_DisabledTrigger: Disabled
838-
m_Interactable: 1
838+
m_Interactable: 0
839839
m_TargetGraphic: {fileID: 3152670386605946882}
840840
m_OnClick:
841841
m_PersistentCalls:

Assets/Game/Prefabs/UI/Ping.prefab

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,6 @@ MonoBehaviour:
116116
syncMode: 0
117117
syncInterval: 0.1
118118
pingText: {fileID: 3519340171003635037}
119-
intervalByServer: 0.5
120-
ping: 0
121119
--- !u!114 &114523307598928054
122120
MonoBehaviour:
123121
m_ObjectHideFlags: 0
@@ -166,9 +164,9 @@ RectTransform:
166164
m_RootOrder: 0
167165
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
168166
m_AnchorMin: {x: 0.04, y: 0}
169-
m_AnchorMax: {x: 0, y: 0}
167+
m_AnchorMax: {x: 0.5, y: 0}
170168
m_AnchoredPosition: {x: 0, y: 0}
171-
m_SizeDelta: {x: 160, y: 30}
169+
m_SizeDelta: {x: 0, y: 30}
172170
m_Pivot: {x: 0, y: 0}
173171
--- !u!222 &3519340171003635036
174172
CanvasRenderer:
@@ -209,4 +207,4 @@ MonoBehaviour:
209207
m_HorizontalOverflow: 0
210208
m_VerticalOverflow: 0
211209
m_LineSpacing: 1
212-
m_Text: New Text
210+
m_Text: 'Ping: 9999ms (999 players)'

Assets/Game/Scripts/Network/Environment.cs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,20 +52,35 @@ private void SpawnAll()
5252

5353
public void RespawnAll()
5454
{
55-
RpcDespawnAll();
55+
RpcDespawnAllOnClient();
56+
DespawnAll();
5657
SpawnAll();
5758
}
5859

60+
[ClientRpc]
61+
public void RpcDespawnAllOnClient()
62+
{
63+
// Clients need to clean up their locally spawned objects
64+
if (isServer)
65+
{
66+
return;
67+
}
68+
69+
DespawnAll();
70+
}
71+
5972
/// <summary>
6073
/// When called on server, de-spawns all barrels.
6174
/// When called on a client, de-spawns all dynamically registered local detachable objects.
6275
/// </summary>
63-
[ClientRpc]
64-
public void RpcDespawnAll()
76+
private void DespawnAll()
6577
{
6678
foreach (var spawnedObject in _spawnedObjects)
6779
{
68-
Destroy(spawnedObject);
80+
if (spawnedObject)
81+
{
82+
Destroy(spawnedObject);
83+
}
6984
}
7085

7186
_spawnedObjects.Clear();

Assets/Game/Scripts/Network/GameNetworkPlayer.cs

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ namespace Game.Scripts.Network
1010
public class GameNetworkPlayer : NetworkBehaviour
1111
{
1212
public static GameNetworkPlayer LocalPlayer;
13+
public static int PlayerCount;
1314

1415
public const float StartHealth = 100;
1516

@@ -27,25 +28,25 @@ public class GameNetworkPlayer : NetworkBehaviour
2728
[SyncVar(hook = nameof(OnSyncHealth))] public float health;
2829

2930
private NetworkIdentity _identity;
30-
private ArenaUi _arenaUi;
3131
private Camera _spectatorCamera;
3232
private HoveringDetails _hoveringDetails;
3333
private bool _inCarSelection;
3434

3535
[SyncVar] private GameObject _car;
3636
private int _carIndex;
3737
private VehiclePhysics _vehiclePhysics;
38+
private bool _quitting;
3839

3940
public GameObject Car => _car;
4041

4142
public void Start()
4243
{
43-
CmdInitialize(MainMenu.PlayerName);
44+
PlayerCount++;
4445
_identity = GetComponent<NetworkIdentity>();
45-
_arenaUi = GameObject.Find("ArenaUI").GetComponent<ArenaUi>();
4646
// If this is the local player, then the Start means he has just has just connected, so he will pick a car
4747
if (isLocalPlayer)
4848
{
49+
CmdInitialize(MainMenu.PlayerName);
4950
LocalPlayer = this;
5051
_spectatorCamera = GameObject.Find("SpectatorCamera").GetComponent<Camera>()
5152
?? throw new NullReferenceException($"Missing SpectatorCamera");
@@ -60,10 +61,27 @@ public void Start()
6061
// If the car wasn't spawned yet, then wait for the RPC callback
6162
}
6263

64+
private void OnDestroy()
65+
{
66+
if (!_quitting && !isLocalPlayer)
67+
{
68+
DisplayPositiveEvent($"{playerName}: Disconnected", true);
69+
}
70+
71+
PlayerCount--;
72+
}
73+
74+
private void OnApplicationQuit()
75+
{
76+
_quitting = true;
77+
}
78+
6379
[Command]
6480
public void CmdInitialize(string playerName)
6581
{
6682
this.playerName = playerName;
83+
// RPC doesn't have access to the playerName yet
84+
RpcDisplayPositiveEvent($"{playerName}: Connected", true);
6785
}
6886

6987
/// <summary>
@@ -79,7 +97,7 @@ public void ChangeCarByLocalPlayer()
7997

8098
_spectatorCamera.gameObject.SetActive(false);
8199
vehicleCamera.gameObject.SetActive(false);
82-
_arenaUi.DisableUi();
100+
ArenaUi.Instance.DisableUi();
83101
// Ensure that the car selection scene is never loaded twice
84102
if (!_inCarSelection)
85103
{
@@ -164,7 +182,7 @@ public void RpcOnSpawnedCar(GameObject car, bool byNewRound)
164182
health = StartHealth;
165183
if (isLocalPlayer)
166184
{
167-
_arenaUi.EnableUi(this);
185+
ArenaUi.Instance.EnableUi(this);
168186
_spectatorCamera.gameObject.SetActive(false);
169187
vehicleCamera.gameObject.SetActive(true);
170188
vehicleCamera.playerCar = car.transform;
@@ -259,13 +277,13 @@ public void RpcDisplayHealth(float displayHealth)
259277
[ClientRpc]
260278
public void RpcDisplayPlayerHitEvent(string player2, float health, int score)
261279
{
262-
_arenaUi.DisplayPlayerHitEvent(playerName, player2, health, score);
280+
ArenaUi.Instance.DisplayPlayerHitEvent(playerName, player2, health, score);
263281
}
264282

265283
[ClientRpc]
266284
public void RpcDisplayObjectHitEvent(string by, float hp)
267285
{
268-
_arenaUi.DisplayObjectHitEvent(playerName, by, hp);
286+
ArenaUi.Instance.DisplayObjectHitEvent(playerName, by, hp);
269287
}
270288

271289
[ClientRpc]
@@ -276,7 +294,17 @@ public void RpcDisplayPositiveEvent(string positiveMessage, bool announcement)
276294

277295
public void DisplayPositiveEvent(string positiveMessage, bool announcement)
278296
{
279-
_arenaUi.DisplayPositiveEvent(!announcement ? $"{playerName}: {positiveMessage}" : positiveMessage);
297+
ArenaUi.Instance.DisplayPositiveEvent(!announcement ? $"{playerName}: {positiveMessage}" : positiveMessage);
298+
}
299+
300+
[Command]
301+
public void CmdRestartServer(string remoteAdminPassword)
302+
{
303+
Debug.Log($"Attempt of {playerName} to restart server using password {remoteAdminPassword}");
304+
if (MainMenu.RemoteAdminPassword != null && MainMenu.RemoteAdminPassword.Equals(remoteAdminPassword))
305+
{
306+
GameObject.Find("NetworkManager").GetComponent<NetworkManager>().StopHost();
307+
}
280308
}
281309
}
282310
}

Assets/Game/Scripts/Network/VehicleSync.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ public class SyncListVehicleInput : SyncList<VehicleInput>{}
7373

7474
VehicleInput currentVehicleInputs = new VehicleInput ();
7575
VehicleTransform currentVehicleTransform = new VehicleTransform ();
76-
VehicleLights currentVehicleLights = new VehicleLights ();
76+
// TODO: there was = new VehicleLights();
77+
VehicleLights currentVehicleLights;
7778

7879
bool CB_running = false;
7980

Assets/Game/Scripts/UI/ArenaUi.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ namespace Game.Scripts.UI
88
{
99
public class ArenaUi : MonoBehaviour
1010
{
11+
public static ArenaUi Instance;
12+
1113
private enum EventType
1214
{
1315
PlayerHit,
@@ -34,6 +36,11 @@ private enum EventType
3436
private Tuple<string, string, float> _lastObjectHitEvent =
3537
new Tuple<string, string, float>(null, null, 0);
3638

39+
private void Awake()
40+
{
41+
Instance = this;
42+
}
43+
3744
void Start()
3845
{
3946
for (var childIndex = 0; childIndex < events.transform.childCount; childIndex++)

Assets/Game/Scripts/UI/MainMenu.cs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Linq;
33
using Game.Scripts.Network;
44
using Mirror;
5+
using Mirror.Websocket;
56
using UnityEngine;
67
using UnityEngine.UI;
78
using Random = System.Random;
@@ -12,10 +13,12 @@ public class MainMenu : MonoBehaviour
1213
{
1314
public static string PlayerName;
1415
public static bool ShouldReconnect;
16+
public static string RemoteAdminPassword;
1517

1618
[Header("Settings pages")] public GameObject menuPage;
1719
public GameObject settingsPage;
1820
[Header("Text callbacks")] public InputField playerInput;
21+
private bool _headlessServerStarted;
1922

2023
private NetworkManager _networkManager;
2124

@@ -42,6 +45,32 @@ private void OnEnable()
4245
}
4346
}
4447

48+
private void HeadlessServerStart()
49+
{
50+
Debug.Log("Running server in a headless mode. Following command line argument formats are supported:\n* Change the listening port:\n port 7778\n* Enable remote administration using password:\n admin MySecretPassword");
51+
var args = System.Environment.GetCommandLineArgs();
52+
for (int argsIndex = 2; argsIndex < args.Length - 1; argsIndex += 2)
53+
{
54+
switch (args[argsIndex])
55+
{
56+
case "port":
57+
case "-port":
58+
case "--port":
59+
Debug.Log(
60+
$"Switching {(int.TryParse(args[argsIndex + 1], out var port) ? $"to port {(_networkManager.GetComponent<WebsocketTransport>().port = port).ToString()}" : $"port failed, cannot recognize {args[argsIndex + 1]}")}");
61+
break;
62+
case "admin":
63+
case "-admin":
64+
case "--admin":
65+
Debug.Log(
66+
$"Setting remote administration password to: ${RemoteAdminPassword = args[argsIndex + 1]}");
67+
break;
68+
}
69+
}
70+
71+
_networkManager.StartHost();
72+
}
73+
4574
private void InitializePlayerName()
4675
{
4776
// Player's name initialization
@@ -141,6 +170,16 @@ private void InitializePlayerName()
141170

142171
private void Update()
143172
{
173+
// Called when running using server build, or after invoking command GameNetworkPlayer.CmdRestartServer
174+
// This has to be called from Update instead of Start or OnEnable in order to properly initialize
175+
if (NetworkManager.isHeadless && !_headlessServerStarted)
176+
{
177+
_headlessServerStarted = true;
178+
PlayerName = "Server";
179+
HeadlessServerStart();
180+
return;
181+
}
182+
144183
if (Input.GetKeyDown(KeyCode.Return) || Input.GetKeyDown(KeyCode.KeypadEnter))
145184
{
146185
if (menuPage.activeInHierarchy)

Assets/Game/Scripts/UI/Ping.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using Game.Scripts.Network;
12
using UnityEngine;
23
using Mirror;
34
using UnityEngine.UI;
@@ -8,11 +9,12 @@ public class Ping : NetworkBehaviour
89

910
private void Start()
1011
{
11-
transform.parent = GameObject.Find("Managers").transform;
12+
transform.SetParent(GameObject.Find("Managers").transform);
1213
}
1314

1415
void Update()
1516
{
16-
pingText.text = $"Ping : {(int) (NetworkTime.rtt * 1000 / 2)}ms";
17+
var playerCount = GameNetworkPlayer.PlayerCount - 1;
18+
pingText.text = $"Ping: {(int) (NetworkTime.rtt * 1000 / 2)}ms ({playerCount} player{(playerCount == 1 ? "" : "s")})";
1719
}
1820
}

Assets/Mirror/Runtime/NetworkManager.cs

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -236,18 +236,7 @@ public virtual void Start()
236236
// (tick rate is applied in StartServer!)
237237
if (isHeadless && startOnHeadless)
238238
{
239-
var args = Environment.GetCommandLineArgs();
240-
if (args.Length == 3 && new[] {"port", "-port", "--port"}.Contains(args[1]))
241-
{
242-
Debug.Log(
243-
$"Switching {(int.TryParse(args[2], out var port) ? $"to port {(GetComponent<WebsocketTransport>().port = port).ToString()}" : $"port failed, cannot recognize {args[2]}")}");
244-
}
245-
else
246-
{
247-
Debug.Log("If you need to change the listening port, consider using a \"port\" parameter");
248-
}
249-
250-
StartHost();
239+
StartServer();
251240
}
252241
}
253242

0 commit comments

Comments
 (0)