2019-09-19 10:28:02 +00:00
|
|
|
using System;
|
2019-09-19 17:02:34 +00:00
|
|
|
using System.Linq;
|
2019-09-19 10:28:02 +00:00
|
|
|
using System.Collections.Generic;
|
|
|
|
using UnityEngine;
|
|
|
|
using Mirror;
|
|
|
|
|
2019-09-19 17:02:34 +00:00
|
|
|
namespace BetterTee.Server
|
|
|
|
{
|
2019-09-19 10:28:02 +00:00
|
|
|
|
|
|
|
public class ServerMainController : MonoBehaviour
|
|
|
|
{
|
|
|
|
[Header("Status")]
|
2019-09-19 17:02:34 +00:00
|
|
|
public Dictionary<NetworkConnection, ConnectedPlayer> players;
|
|
|
|
public Dictionary<NetworkConnection, ConnectedViewer> viewers;
|
2019-09-22 17:58:06 +00:00
|
|
|
public GamePhase gamePhase = GamePhase.UNINTIALIZED;
|
2019-09-19 17:02:34 +00:00
|
|
|
public GameSettings gameSettings = null;
|
|
|
|
public int? currentActNumber = null;
|
2019-09-22 17:58:06 +00:00
|
|
|
public string lobbyPassword = null;
|
|
|
|
|
|
|
|
public bool CanStartGame {
|
|
|
|
get {
|
|
|
|
return (
|
|
|
|
gamePhase == GamePhase.LOBBY &&
|
|
|
|
gameSettings != null &&
|
|
|
|
players.Count >= gameSettings.minimumPlayers
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2019-09-19 17:02:34 +00:00
|
|
|
|
|
|
|
public ActSettings CurrentActSettings {
|
|
|
|
get {
|
|
|
|
if(gameSettings == null) return null;
|
|
|
|
if(currentActNumber == null) return null;
|
|
|
|
return gameSettings.acts[currentActNumber.Value - 1];
|
|
|
|
}
|
|
|
|
}
|
2019-09-19 10:28:02 +00:00
|
|
|
|
|
|
|
[Header("Constants")]
|
|
|
|
public const int MAX_CONNECTIONS = 32;
|
2019-09-22 17:58:06 +00:00
|
|
|
public const int PASSWORD_LENGTH = 4;
|
2019-09-19 17:02:34 +00:00
|
|
|
|
|
|
|
#region Unity Methods
|
2019-09-19 10:28:02 +00:00
|
|
|
|
|
|
|
protected void Start() {
|
2019-09-19 17:02:34 +00:00
|
|
|
ServerStart();
|
2019-09-19 10:28:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
protected void OnDestroy() {
|
|
|
|
if(NetworkServer.active) NetworkServer.Shutdown();
|
|
|
|
}
|
|
|
|
|
2019-09-19 17:02:34 +00:00
|
|
|
#endregion
|
|
|
|
|
|
|
|
public void ServerStart() {
|
2019-09-22 17:58:06 +00:00
|
|
|
gamePhase = GamePhase.LOBBY;
|
2019-09-19 17:02:34 +00:00
|
|
|
players = new Dictionary<NetworkConnection, ConnectedPlayer>();
|
|
|
|
viewers = new Dictionary<NetworkConnection, ConnectedViewer>();
|
2019-09-19 10:28:02 +00:00
|
|
|
Transport.activeTransport = GetComponent<TelepathyTransport>();
|
|
|
|
|
2019-09-22 17:58:06 +00:00
|
|
|
#region Password Creation
|
|
|
|
char[] charList = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();
|
|
|
|
lobbyPassword = "";
|
|
|
|
for(int i = 0; i < PASSWORD_LENGTH; i++) {
|
|
|
|
lobbyPassword += charList[UnityEngine.Random.Range(0, charList.Length)];
|
|
|
|
}
|
|
|
|
Debug.Log("The server password is: {}");
|
|
|
|
#endregion
|
|
|
|
|
2019-09-19 10:28:02 +00:00
|
|
|
#region Client Messages
|
|
|
|
NetworkServer.RegisterHandler<NetMsg.Client.PlayerJoin>(OnPlayerJoin);
|
2019-09-19 17:02:34 +00:00
|
|
|
NetworkServer.RegisterHandler<NetMsg.Client.ActResultsMsg>(OnActResults);
|
2019-09-19 10:28:02 +00:00
|
|
|
#endregion
|
|
|
|
#region Viewer Messages
|
2019-09-19 17:02:34 +00:00
|
|
|
NetworkServer.RegisterHandler<NetMsg.Viewer.Settings>(OnGameSettings);
|
2019-09-19 10:28:02 +00:00
|
|
|
NetworkServer.RegisterHandler<NetMsg.Viewer.ViewerLink>(OnViewerLink);
|
2019-09-19 17:02:34 +00:00
|
|
|
NetworkServer.RegisterHandler<NetMsg.Viewer.GameStart>(OnGameStart);
|
2019-09-19 10:28:02 +00:00
|
|
|
#endregion
|
|
|
|
#region Other Messages
|
|
|
|
NetworkServer.RegisterHandler<ConnectMessage>(OnConnect);
|
2019-09-19 17:02:34 +00:00
|
|
|
NetworkServer.RegisterHandler<DisconnectMessage>(OnDisconnect);
|
2019-09-19 10:28:02 +00:00
|
|
|
#endregion
|
|
|
|
|
|
|
|
NetworkServer.Listen(MAX_CONNECTIONS);
|
|
|
|
}
|
|
|
|
|
2019-09-19 17:02:34 +00:00
|
|
|
public void SendLobbyUpdate() {
|
|
|
|
SendToAllRegistered<NetMsg.Server.LobbyStatusChange>(new NetMsg.Server.LobbyStatusChange {
|
|
|
|
players = players.Values.ToList().ConvertAll<ConnectedPlayerData>(player => player.Data).ToArray(),
|
2019-09-22 17:58:06 +00:00
|
|
|
viewers = viewers.Values.ToList().ConvertAll<ConnectedViewerData>(viewer => viewer.Data).ToArray(),
|
|
|
|
canStart = (gameSettings != null && players.Count >= gameSettings.minimumPlayers)
|
2019-09-19 17:02:34 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
public void GameStart() {
|
2019-09-22 17:58:06 +00:00
|
|
|
gamePhase = GamePhase.ACTS;
|
|
|
|
currentActNumber = 1;
|
|
|
|
//TODO?
|
2019-09-19 17:02:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void ActInit() {
|
|
|
|
SendToAllRegistered<NetMsg.Server.ActInit>(new NetMsg.Server.ActInit {
|
|
|
|
settings = CurrentActSettings
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
#region SendToAll Methods
|
|
|
|
|
|
|
|
public void SendToAllPlayers<T>(T message, int channelId = 0)
|
|
|
|
where T: IMessageBase {
|
|
|
|
foreach(NetworkConnection connection in players.Keys) {
|
|
|
|
connection.Send<T>(message, channelId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void SendToAllViewers<T>(T message, int channelId = 0)
|
|
|
|
where T: IMessageBase {
|
|
|
|
foreach(NetworkConnection connection in viewers.Keys) {
|
|
|
|
connection.Send<T>(message, channelId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void SendToAllRegistered<T>(T message, int channelId = 0)
|
|
|
|
where T: IMessageBase {
|
|
|
|
SendToAllPlayers<T>(message, channelId);
|
|
|
|
SendToAllViewers<T>(message, channelId);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
2019-09-19 10:28:02 +00:00
|
|
|
#region Network Events
|
|
|
|
|
2019-09-22 17:58:06 +00:00
|
|
|
protected void OnConnect(NetworkConnection connection, ConnectMessage message) {}
|
2019-09-19 17:02:34 +00:00
|
|
|
|
|
|
|
protected void OnDisconnect(NetworkConnection connection, DisconnectMessage message) {
|
|
|
|
//How to handle disconnections?
|
2019-09-22 17:58:06 +00:00
|
|
|
if(gamePhase == GamePhase.LOBBY) {
|
|
|
|
try {
|
|
|
|
players.Remove(connection);
|
|
|
|
}
|
|
|
|
catch(KeyNotFoundException) {}
|
|
|
|
|
|
|
|
try {
|
|
|
|
viewers.Remove(connection);
|
|
|
|
}
|
|
|
|
catch(KeyNotFoundException) {}
|
|
|
|
|
|
|
|
SendLobbyUpdate();
|
2019-09-19 17:02:34 +00:00
|
|
|
}
|
2019-09-22 17:58:06 +00:00
|
|
|
else {
|
|
|
|
Debug.LogWarning("Disconnections after the lobby phase aren't handled");
|
2019-09-19 17:02:34 +00:00
|
|
|
}
|
|
|
|
}
|
2019-09-19 10:28:02 +00:00
|
|
|
|
2019-09-22 17:58:06 +00:00
|
|
|
protected void OnPlayerJoin(NetworkConnection connection, NetMsg.Client.PlayerJoin message) {
|
|
|
|
if(gameSettings == null) {
|
|
|
|
connection.Send<NetMsg.Server.Error.MissingGameSettings>(new NetMsg.Server.Error.MissingGameSettings());
|
|
|
|
connection.Disconnect();
|
|
|
|
return;
|
|
|
|
}
|
2019-09-19 17:02:34 +00:00
|
|
|
if(message.gamePassword != lobbyPassword) {
|
2019-09-19 10:28:02 +00:00
|
|
|
connection.Send<NetMsg.Server.Error.InvalidPassword>(new NetMsg.Server.Error.InvalidPassword());
|
|
|
|
connection.Disconnect();
|
|
|
|
return;
|
|
|
|
}
|
2019-09-22 17:58:06 +00:00
|
|
|
if(gamePhase != GamePhase.LOBBY) {
|
2019-09-19 10:28:02 +00:00
|
|
|
connection.Send<NetMsg.Server.Error.GameAlreadyStarted>(new NetMsg.Server.Error.GameAlreadyStarted());
|
|
|
|
connection.Disconnect();
|
|
|
|
return;
|
|
|
|
}
|
2019-09-19 17:02:34 +00:00
|
|
|
if(players.Count >= gameSettings.maximumPlayers) {
|
|
|
|
connection.Send<NetMsg.Server.Error.MaxPlayersCapReached>(new NetMsg.Server.Error.MaxPlayersCapReached());
|
|
|
|
connection.Disconnect();
|
|
|
|
return;
|
|
|
|
}
|
2019-09-19 10:28:02 +00:00
|
|
|
|
2019-09-19 17:02:34 +00:00
|
|
|
ConnectedPlayer newPlayer = new ConnectedPlayer {
|
2019-09-19 10:28:02 +00:00
|
|
|
name = message.playerName,
|
|
|
|
id = players.Count
|
|
|
|
};
|
2019-09-19 17:02:34 +00:00
|
|
|
players.Add(connection, newPlayer);
|
2019-09-19 10:28:02 +00:00
|
|
|
|
2019-09-19 17:02:34 +00:00
|
|
|
SendLobbyUpdate();
|
2019-09-19 10:28:02 +00:00
|
|
|
}
|
|
|
|
|
2019-09-22 17:58:06 +00:00
|
|
|
protected void OnViewerLink(NetworkConnection connection, NetMsg.Viewer.ViewerLink message) {
|
2019-09-19 17:02:34 +00:00
|
|
|
if(message.gamePassword != lobbyPassword) {
|
2019-09-19 10:28:02 +00:00
|
|
|
connection.Send<NetMsg.Server.Error.InvalidPassword>(new NetMsg.Server.Error.InvalidPassword());
|
|
|
|
connection.Disconnect();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-09-19 17:02:34 +00:00
|
|
|
ConnectedViewer newViewer = new ConnectedViewer {
|
|
|
|
name = message.viewerName,
|
2019-09-19 10:28:02 +00:00
|
|
|
id = viewers.Count
|
|
|
|
};
|
2019-09-19 17:02:34 +00:00
|
|
|
viewers.Add(connection, newViewer);
|
2019-09-19 10:28:02 +00:00
|
|
|
|
2019-09-19 17:02:34 +00:00
|
|
|
SendLobbyUpdate();
|
2019-09-22 17:58:06 +00:00
|
|
|
}
|
2019-09-19 17:02:34 +00:00
|
|
|
|
2019-09-22 17:58:06 +00:00
|
|
|
protected void OnGameSettings(NetworkConnection connection, NetMsg.Viewer.Settings message) {
|
|
|
|
if(gameSettings != null) {
|
|
|
|
Debug.LogWarning("gameSettings were overwritten.");
|
|
|
|
}
|
|
|
|
|
|
|
|
gameSettings = message.settings;
|
|
|
|
|
|
|
|
SendLobbyUpdate();
|
2019-09-19 17:02:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
protected void OnGameStart(NetworkConnection connection, NetMsg.Viewer.GameStart message) {
|
|
|
|
if(gameSettings == null) {
|
|
|
|
connection.Send<NetMsg.Server.Error.NoSettings>(new NetMsg.Server.Error.NoSettings());
|
|
|
|
connection.Disconnect();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if(players.Count < gameSettings.minimumPlayers) {
|
|
|
|
connection.Send<NetMsg.Server.Error.NotEnoughPlayers>(new NetMsg.Server.Error.NotEnoughPlayers());
|
|
|
|
connection.Disconnect();
|
|
|
|
return;
|
|
|
|
}
|
2019-09-19 10:28:02 +00:00
|
|
|
|
2019-09-19 17:02:34 +00:00
|
|
|
GameStart();
|
2019-09-19 10:28:02 +00:00
|
|
|
}
|
2019-09-22 17:58:06 +00:00
|
|
|
|
|
|
|
protected void OnActResults(NetworkConnection connection, NetMsg.Client.ActResultsMsg message) {}
|
2019-09-19 10:28:02 +00:00
|
|
|
|
|
|
|
#endregion
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|