Changed room update methods

This commit is contained in:
Derek S 2021-04-10 00:36:27 -05:00
parent 68b840bfb8
commit 5a66b93132
2 changed files with 84 additions and 34 deletions

View file

@ -45,9 +45,16 @@ namespace LightReflectiveMirror
public static void WriteString(this byte[] data, ref int position, string value) public static void WriteString(this byte[] data, ref int position, string value)
{ {
data.WriteInt(ref position, value.Length); if (string.IsNullOrWhiteSpace(value))
for (int i = 0; i < value.Length; i++) {
data.WriteChar(ref position, value[i]); data.WriteInt(ref position, 0);
}
else
{
data.WriteInt(ref position, value.Length);
for (int i = 0; i < value.Length; i++)
data.WriteChar(ref position, value[i]);
}
} }
public static string ReadString(this byte[] data, ref int position) public static string ReadString(this byte[] data, ref int position)

View file

@ -122,13 +122,16 @@ namespace LightReflectiveMirror
{ {
if (_connectedToRelay) if (_connectedToRelay)
{ {
// Send a blank message with just the opcode 200, which is heartbeat
int pos = 0; int pos = 0;
_clientSendBuffer.WriteByte(ref pos, 200); _clientSendBuffer.WriteByte(ref pos, 200);
clientToServerTransport.ClientSend(0, new ArraySegment<byte>(_clientSendBuffer, 0, pos)); clientToServerTransport.ClientSend(0, new ArraySegment<byte>(_clientSendBuffer, 0, pos));
// If NAT Puncher is initialized, send heartbeat on that as well.
if (_NATPuncher != null) if (_NATPuncher != null)
_NATPuncher.Send(new byte[] { 0 }, 1, _relayPuncherIP); _NATPuncher.Send(new byte[] { 0 }, 1, _relayPuncherIP);
// Check if any server-side proxies havent been used in 10 seconds, and timeout if so.
var keys = new List<IPEndPoint>(_serverProxies.GetAllKeys()); var keys = new List<IPEndPoint>(_serverProxies.GetAllKeys());
for (int i = 0; i < keys.Count; i++) for (int i = 0; i < keys.Count; i++)
@ -148,33 +151,39 @@ namespace LightReflectiveMirror
{ {
var data = segmentData.Array; var data = segmentData.Array;
int pos = segmentData.Offset; int pos = segmentData.Offset;
// Read the opcode of the incoming data, this allows us to know what its used for.
OpCodes opcode = (OpCodes)data.ReadByte(ref pos); OpCodes opcode = (OpCodes)data.ReadByte(ref pos);
switch (opcode) switch (opcode)
{ {
case OpCodes.Authenticated: case OpCodes.Authenticated:
// Server authenticated us! That means we are fully ready to host and join servers.
serverStatus = "Authenticated! Good to go!"; serverStatus = "Authenticated! Good to go!";
_isAuthenticated = true; _isAuthenticated = true;
RequestServerList(); RequestServerList();
break; break;
case OpCodes.AuthenticationRequest: case OpCodes.AuthenticationRequest:
// Server requested that we send an authentication request, lets send our auth key.
serverStatus = "Sent authentication to relay..."; serverStatus = "Sent authentication to relay...";
SendAuthKey(); SendAuthKey();
break; break;
case OpCodes.GetData: case OpCodes.GetData:
// Someone sent us a packet from their mirror over the relay
var recvData = data.ReadBytes(ref pos); var recvData = data.ReadBytes(ref pos);
// If we are the server and the client is registered, invoke the callback
if (_isServer) if (_isServer)
{ {
if (_connectedRelayClients.TryGetByFirst(data.ReadInt(ref pos), out int clientID)) if (_connectedRelayClients.TryGetByFirst(data.ReadInt(ref pos), out int clientID))
OnServerDataReceived?.Invoke(clientID, new ArraySegment<byte>(recvData), channel); OnServerDataReceived?.Invoke(clientID, new ArraySegment<byte>(recvData), channel);
} }
// If we are the client, invoke the callback
if (_isClient) if (_isClient)
OnClientDataReceived?.Invoke(new ArraySegment<byte>(recvData), channel); OnClientDataReceived?.Invoke(new ArraySegment<byte>(recvData), channel);
break; break;
case OpCodes.ServerLeft: case OpCodes.ServerLeft:
// Called when we were kicked, or server was closed.
if (_isClient) if (_isClient)
{ {
_isClient = false; _isClient = false;
@ -182,8 +191,10 @@ namespace LightReflectiveMirror
} }
break; break;
case OpCodes.PlayerDisconnected: case OpCodes.PlayerDisconnected:
// Called when another player left the room.
if (_isServer) if (_isServer)
{ {
// Get their client ID and invoke the mirror callback
int user = data.ReadInt(ref pos); int user = data.ReadInt(ref pos);
if (_connectedRelayClients.TryGetByFirst(user, out int clientID)) if (_connectedRelayClients.TryGetByFirst(user, out int clientID))
{ {
@ -193,28 +204,34 @@ namespace LightReflectiveMirror
} }
break; break;
case OpCodes.RoomCreated: case OpCodes.RoomCreated:
// We successfully created the room, the server also gave us the serverId of the room!
serverId = data.ReadString(ref pos); serverId = data.ReadString(ref pos);
break; break;
case OpCodes.ServerJoined: case OpCodes.ServerJoined:
// Called when a player joins the room or when we joined a room.
int clientId = data.ReadInt(ref pos); int clientId = data.ReadInt(ref pos);
if (_isClient) if (_isClient)
{ {
// We successfully joined a room, let mirror know.
OnClientConnected?.Invoke(); OnClientConnected?.Invoke();
} }
if (_isServer) if (_isServer)
{ {
// A client joined our room, let mirror know and setup their ID in the dictionary.
_connectedRelayClients.Add(clientId, _currentMemberId); _connectedRelayClients.Add(clientId, _currentMemberId);
OnServerConnected?.Invoke(_currentMemberId); OnServerConnected?.Invoke(_currentMemberId);
_currentMemberId++; _currentMemberId++;
} }
break; break;
case OpCodes.DirectConnectIP: case OpCodes.DirectConnectIP:
// Either a client is trying to join us via NAT Punch, or we are trying to join a host over NAT punch/Direct connect.
var ip = data.ReadString(ref pos); var ip = data.ReadString(ref pos);
int port = data.ReadInt(ref pos); int port = data.ReadInt(ref pos);
bool attemptNatPunch = data.ReadBool(ref pos); bool attemptNatPunch = data.ReadBool(ref pos);
_directConnectEndpoint = new IPEndPoint(IPAddress.Parse(ip), port); _directConnectEndpoint = new IPEndPoint(IPAddress.Parse(ip), port);
// Both client and server will send data to each other to open the hole.
if (useNATPunch && attemptNatPunch) if (useNATPunch && attemptNatPunch)
{ {
StartCoroutine(NATPunch(_directConnectEndpoint)); StartCoroutine(NATPunch(_directConnectEndpoint));
@ -222,6 +239,7 @@ namespace LightReflectiveMirror
if (!_isServer) if (!_isServer)
{ {
// We arent the server, so lets tell the direct connect module to attempt a connection and initializing our middle man socket.
if (_clientProxy == null && useNATPunch && attemptNatPunch) if (_clientProxy == null && useNATPunch && attemptNatPunch)
{ {
_clientProxy = new SocketProxy(_NATIP.Port - 1); _clientProxy = new SocketProxy(_NATIP.Port - 1);
@ -241,6 +259,7 @@ namespace LightReflectiveMirror
break; break;
case OpCodes.RequestNATConnection: case OpCodes.RequestNATConnection:
// Called when the LRM node would like us to establish a NAT puncher connection. Its safe to ignore if NAT punch is disabled.
if (GetLocalIp() != null && _directConnectModule != null) if (GetLocalIp() != null && _directConnectModule != null)
{ {
byte[] initalData = new byte[150]; byte[] initalData = new byte[150];
@ -297,45 +316,69 @@ namespace LightReflectiveMirror
swt.port = port; swt.port = port;
} }
public void UpdateRoomInfo(string newServerName = null, string newServerData = null, bool? newServerIsPublic = null, int? newPlayerCap = null) public void UpdateRoomName(string newServerName = "My Awesome Server!")
{ {
if (_isServer) if (_isServer)
{ {
int pos = 0; int pos = 0;
_clientSendBuffer.WriteByte(ref pos, (byte)OpCodes.UpdateRoomData); _clientSendBuffer.WriteByte(ref pos, (byte)OpCodes.UpdateRoomData);
if (!string.IsNullOrEmpty(newServerName)) _clientSendBuffer.WriteBool(ref pos, true);
{ _clientSendBuffer.WriteString(ref pos, newServerName);
_clientSendBuffer.WriteBool(ref pos, true); _clientSendBuffer.WriteBool(ref pos, false);
_clientSendBuffer.WriteString(ref pos, newServerName); _clientSendBuffer.WriteBool(ref pos, false);
} _clientSendBuffer.WriteBool(ref pos, false);
else
_clientSendBuffer.WriteBool(ref pos, false);
if (!string.IsNullOrEmpty(newServerData)) clientToServerTransport.ClientSend(0, new ArraySegment<byte>(_clientSendBuffer, 0, pos));
{ }
_clientSendBuffer.WriteBool(ref pos, true); }
_clientSendBuffer.WriteString(ref pos, newServerData);
}
else
_clientSendBuffer.WriteBool(ref pos, false);
if (newServerIsPublic != null) public void UpdateRoomData(string newServerData = "Extra Data!")
{ {
_clientSendBuffer.WriteBool(ref pos, true); if (_isServer)
_clientSendBuffer.WriteBool(ref pos, newServerIsPublic.Value); {
} int pos = 0;
else _clientSendBuffer.WriteByte(ref pos, (byte)OpCodes.UpdateRoomData);
_clientSendBuffer.WriteBool(ref pos, false);
if (newPlayerCap != null) _clientSendBuffer.WriteBool(ref pos, false);
{ _clientSendBuffer.WriteBool(ref pos, true);
_clientSendBuffer.WriteBool(ref pos, true); _clientSendBuffer.WriteString(ref pos, newServerData);
_clientSendBuffer.WriteInt(ref pos, newPlayerCap.Value); _clientSendBuffer.WriteBool(ref pos, false);
} _clientSendBuffer.WriteBool(ref pos, false);
else
_clientSendBuffer.WriteBool(ref pos, false); clientToServerTransport.ClientSend(0, new ArraySegment<byte>(_clientSendBuffer, 0, pos));
}
}
public void UpdateRoomVisibility(bool isPublic = true)
{
if (_isServer)
{
int pos = 0;
_clientSendBuffer.WriteByte(ref pos, (byte)OpCodes.UpdateRoomData);
_clientSendBuffer.WriteBool(ref pos, false);
_clientSendBuffer.WriteBool(ref pos, false);
_clientSendBuffer.WriteBool(ref pos, true);
_clientSendBuffer.WriteBool(ref pos, isPublic);
_clientSendBuffer.WriteBool(ref pos, false);
clientToServerTransport.ClientSend(0, new ArraySegment<byte>(_clientSendBuffer, 0, pos));
}
}
public void UpdateRoomPlayerCount(int maxPlayers = 16)
{
if (_isServer)
{
int pos = 0;
_clientSendBuffer.WriteByte(ref pos, (byte)OpCodes.UpdateRoomData);
_clientSendBuffer.WriteBool(ref pos, false);
_clientSendBuffer.WriteBool(ref pos, false);
_clientSendBuffer.WriteBool(ref pos, false);
_clientSendBuffer.WriteBool(ref pos, true);
_clientSendBuffer.WriteInt(ref pos, maxPlayers);
clientToServerTransport.ClientSend(0, new ArraySegment<byte>(_clientSendBuffer, 0, pos)); clientToServerTransport.ClientSend(0, new ArraySegment<byte>(_clientSendBuffer, 0, pos));
} }