Skip to content

Instantly share code, notes, and snippets.

@Vagonn
Created August 6, 2020 05:07
Show Gist options
  • Save Vagonn/423bbc89dadcf05a2e9211e97830bb77 to your computer and use it in GitHub Desktop.
Save Vagonn/423bbc89dadcf05a2e9211e97830bb77 to your computer and use it in GitHub Desktop.
using Barebones.MasterServer;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using Barebones.Logging;
using UnityEngine.Networking;
using UnityEngine.Networking.NetworkSystem;
[Serializable]
public class OnStartRoom : UnityEvent<bool, int, string>
{
}
public class MyGameServer : MonoBehaviour
{
public OnStartRoom OnStartRoom = new OnStartRoom();
// Fires when server room is successfully registered
public UnityEvent OnRoomServerRegisteredEvent;
private Barebones.Logging.Logger logger;
// Options of this room we must share with clients
private RoomOptions roomOptions;
// Controller of the room
private RoomController roomController;
private Dictionary<int, RoomPlayer> roomPlayersByMsfConnId = new Dictionary<int, RoomPlayer>();
private Dictionary<int, RoomPlayer> roomPlayersByUnetConnId = new Dictionary<int, RoomPlayer>();
void Awake()
{
logger = Msf.Create.Logger(GetType().Name);
logger.LogLevel = LogLevel.Info;
}
// This will be called only if we're connected to master server
public void OnConnectionEstablished()
{
NetworkServer.RegisterHandler((short)MsfMessageCodes.ValidateRoomAccessRequest, ValidateRoomAccessRequestHandler);
roomOptions = new RoomOptions
{
// Let's make this room as private until it is successfully registered.
// This is useful to prevent players connection to this room before registration process finished.
IsPublic = !Msf.Args.IsProvided(Msf.Args.Names.RoomIsPrivate),
// Just the name of the room
Name = Msf.Args.ExtractValue(Msf.Args.Names.RoomName, "Room_" + Msf.Helper.CreateRandomString(5)),
// If room uses the password
Password = Msf.Args.ExtractValue(Msf.Args.Names.RoomPassword, string.Empty),
// Room IP that will be used by players to connect to this room
RoomIp = Msf.Args.ExtractValue(Msf.Args.Names.RoomIp, "127.0.0.1"),
// Room port that will be used by players to connect to this room
RoomPort = Msf.Args.ExtractValueInt(Msf.Args.Names.RoomPort, 5000),
// Region that this room may use to filter it in games list
MaxConnections = Msf.Args.ExtractValueInt(Msf.Args.Names.RoomMaxConnections, 0)
};
print("My pass = " + roomOptions.Password);
print("RoomOptions.RoomName: " + roomOptions.Name);
print("SceneName: " + Msf.Args.ExtractValue(Msf.Args.Names.LoadScene, "NoScene"));
OnStartRoom.Invoke(false, roomOptions.RoomPort, Msf.Args.ExtractValue(Msf.Args.Names.LoadScene));
RegisterSpawnedProcess();
}
private void ValidateRoomAccessRequestHandler(NetworkMessage networkMessage)
{
var token = networkMessage.ReadMessage<StringMessage>().value;
roomController.ValidateAccess(token, (access, error) =>
{
if (access == null)
{
logger.Error("Failed to confirm access token: " + error);
//Confirmation failed, disconnect user
networkMessage.conn.Disconnect();
return;
}
logger.Debug("Access token confirmed for peer: " + access);
var player = new RoomPlayer(networkMessage.conn, access.PeerId);
roomPlayersByMsfConnId.Add(player.msfPeerId, player);
roomPlayersByUnetConnId.Add(player.conn.connectionId, player);
MyNetworkManager.singleton.ClientDisconnected.AddListener(OnPlayerLeft);
});
}
public void OnPlayerLeft(NetworkConnection connection)
{
print("OnPlayerLeft");
if (roomPlayersByUnetConnId.TryGetValue(connection.connectionId, out RoomPlayer player))
{
roomController.NotifyPlayerLeft(player.msfPeerId);
roomPlayersByUnetConnId.Remove(connection.connectionId);
roomPlayersByMsfConnId.Remove(player.msfPeerId);
}
}
// Before we register our room we need to register spawned process if required
private void RegisterSpawnedProcess()
{
if (!Msf.Server.Spawners.IsSpawnedProccess)
{
logger.Error("Room server process cannot be registered, because it is not a spawned process");
return;
}
// Let's register this process
Msf.Server.Spawners.RegisterSpawnedProcess(Msf.Args.SpawnTaskId, Msf.Args.SpawnTaskUniqueCode, (taskController, error) =>
{
if (taskController == null)
{
logger.Error($"Room server process cannot be registered. Reason: {error}");
return;
}
var properties = taskController.Options.ToDictionary();
foreach (KeyValuePair<string, string> kvp in properties)
{
print("pKey = " + kvp.Key + " pValue = " + kvp.Value);
}
if (properties.ContainsKey(MsfDictKeys.roomName))
roomOptions.Name = properties[MsfDictKeys.roomName];
//if (properties.ContainsKey(MsfDictKeys.roomPassword)) // setted in ConnectorToGame => dictionaryOptions
// roomOptions.Password = properties[MsfDictKeys.roomPassword];
// Then start registering our room server
RegisterRoomServer(() =>
{
logger.Info("Finalizing registration task");
print("options.Add(MsfDictKeys.roomId) = " + roomController.RoomId.ToString());
//print("options.Add(MsfDictKeys.roomPassword) = " + Msf.Args.ExtractValue(Msf.Args.Names.RoomPassword));
print("options.Add(MsfDictKeys.sceneName) = " + Msf.Args.ExtractValue(Msf.Args.Names.LoadScene));
// Create finalization options
var options = new DictionaryOptions();
options.Add(MsfDictKeys.roomId, roomController.RoomId.ToString());
options.Add(MsfDictKeys.sceneName, Msf.Args.ExtractValue(Msf.Args.Names.LoadScene));
//options.Add(MsfDictKeys.roomPassword, Msf.Args.ExtractValue(Msf.Args.Names.RoomPassword)); // setted in ConnectorToGame => customOptions
// Send finilization request
taskController.FinalizeTask(options, () =>
{
logger.Info("Ok!");
OnRoomServerRegisteredEvent?.Invoke();
});
});
});
}
// Start registering our room server
private void RegisterRoomServer(UnityAction successCallback = null)
{
logger.Info($"Registering room to list with options: {roomOptions}");
Msf.Server.Rooms.RegisterRoom(roomOptions, (roomController, error) =>
{
if (roomController == null)
{
logger.Error("Cannot register room. Reason: " + error);
return;
}
// Registered room controller
this.roomController = roomController;
logger.Info($"Room successfully created. RoomId: {roomController.RoomId}, RoomName: { roomOptions.Name}, RoomPassword: { roomOptions.Password}");
successCallback?.Invoke();
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment