Skip to content

Commit

Permalink
Backport Changes from Mirror
Browse files Browse the repository at this point in the history
  • Loading branch information
MrGadget1024 committed Jul 20, 2024
1 parent a1ad956 commit 2c9d26b
Showing 1 changed file with 35 additions and 20 deletions.
55 changes: 35 additions & 20 deletions Telepathy/Server.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class Server : Common
{
// events to hook into
// => OnData uses ArraySegment for allocation free receives later
public Action<int> OnConnected;
public Action<int, string> OnConnected;
public Action<int, ArraySegment<byte>> OnData;
public Action<int> OnDisconnected;

Expand Down Expand Up @@ -86,16 +86,16 @@ void Listen(int port)
listener = TcpListener.Create(port);
listener.Server.NoDelay = NoDelay;
// IMPORTANT: do not set send/receive timeouts on listener.
// On linux setting the recv timeout will cause the blocking
// Accept call to timeout with EACCEPT (which mono interprets
// as EWOULDBLOCK).
// On linux setting the recv timeout will cause the blocking
// Accept call to timeout with EACCEPT (which mono interprets
// as EWOULDBLOCK).
// https://stackoverflow.com/questions/1917814/eagain-error-for-accept-on-blocking-socket/1918118#1918118
// => fixes https://github.com/vis2k/Mirror/issues/2695
//
//listener.Server.SendTimeout = SendTimeout;
//listener.Server.ReceiveTimeout = ReceiveTimeout;
listener.Start();
Log.Info("[Telepathy] Server: listening port=" + port);
Log.Info("Server: listening port=" + port);

// keep accepting new clients
while (true)
Expand Down Expand Up @@ -138,7 +138,7 @@ void Listen(int port)
}
catch (Exception exception)
{
Log.Error("[Telepathy] Server send thread exception: " + exception);
Log.Error("Server send thread exception: " + exception);
}
});
sendThread.IsBackground = true;
Expand Down Expand Up @@ -172,7 +172,7 @@ void Listen(int port)
}
catch (Exception exception)
{
Log.Error("[Telepathy] Server client thread exception: " + exception);
Log.Error("Server client thread exception: " + exception);
}
});
receiveThread.IsBackground = true;
Expand All @@ -183,18 +183,18 @@ void Listen(int port)
{
// UnityEditor causes AbortException if thread is still
// running when we press Play again next time. that's okay.
Log.Info("[Telepathy] Server thread aborted. That's okay. " + exception);
Log.Info("Server thread aborted. That's okay. " + exception);
}
catch (SocketException exception)
{
// calling StopServer will interrupt this thread with a
// 'SocketException: interrupted'. that's okay.
Log.Info("[Telepathy] Server Thread stopped. That's okay. " + exception);
Log.Info("Server Thread stopped. That's okay. " + exception);
}
catch (Exception exception)
{
// something went wrong. probably important.
Log.Error("[Telepathy] Server Exception: " + exception);
Log.Error("Server Exception: " + exception);
}
}

Expand All @@ -215,7 +215,7 @@ public bool Start(int port)
// start the listener thread
// (on low priority. if main thread is too busy then there is not
// much value in accepting even more clients)
Log.Info("[Telepathy] Server: Start port=" + port);
Log.Info("Server: Start port=" + port);
listenerThread = new Thread(() => { Listen(port); });
listenerThread.IsBackground = true;
listenerThread.Priority = ThreadPriority.BelowNormal;
Expand All @@ -228,7 +228,7 @@ public void Stop()
// only if started
if (!Active) return;

Log.Info("[Telepathy] Server: stopping...");
Log.Info("Server: stopping...");

// stop listening to connections so that no one can connect while we
// close the client connections
Expand Down Expand Up @@ -295,7 +295,7 @@ public bool Send(int connectionId, ArraySegment<byte> message)
else
{
// log the reason
Log.Warning($"[Telepathy] Server.Send: sendPipe for connection {connectionId} reached limit of {SendQueueLimit}. This can happen if we call send faster than the network can process messages. Disconnecting this connection for load balancing.");
Log.Warning($"Server.Send: sendPipe for connection {connectionId} reached limit of {SendQueueLimit}. This can happen if we call send faster than the network can process messages. Disconnecting this connection for load balancing.");

// just close it. send thread will take care of the rest.
connection.client.Close();
Expand All @@ -311,19 +311,34 @@ public bool Send(int connectionId, ArraySegment<byte> message)
//Logger.Log("Server.Send: invalid connectionId: " + connectionId);
return false;
}
Log.Error("[Telepathy] Server.Send: message too big: " + message.Count + ". Limit: " + MaxMessageSize);
Log.Error("Server.Send: message too big: " + message.Count + ". Limit: " + MaxMessageSize);
return false;
}

// client's ip is sometimes needed by the server, e.g. for bans
public string GetClientAddress(int connectionId)
{
// find the connection
if (clients.TryGetValue(connectionId, out ConnectionState connection))
try
{
// find the connection
if (clients.TryGetValue(connectionId, out ConnectionState connection))
{
return ((IPEndPoint)connection.client.Client.RemoteEndPoint).Address.ToString();
}
return "";
}
catch (SocketException)
{
return ((IPEndPoint)connection.client.Client.RemoteEndPoint).Address.ToString();
// using server.listener.LocalEndpoint causes an Exception
// in UWP + Unity 2019:
// Exception thrown at 0x00007FF9755DA388 in UWF.exe:
// Microsoft C++ exception: Il2CppExceptionWrapper at memory
// location 0x000000E15A0FCDD0. SocketException: An address
// incompatible with the requested protocol was used at
// System.Net.Sockets.Socket.get_LocalEndPoint ()
// so let's at least catch it and recover
return "unknown";
}
return "";
}

// disconnect (kick) a client
Expand All @@ -334,7 +349,7 @@ public bool Disconnect(int connectionId)
{
// just close it. send thread will take care of the rest.
connection.client.Close();
Log.Info("[Telepathy] Server.Disconnect connectionId:" + connectionId);
Log.Info("Server.Disconnect connectionId:" + connectionId);
return true;
}
return false;
Expand Down Expand Up @@ -373,7 +388,7 @@ public int Tick(int processLimit, Func<bool> checkEnabled = null)
switch (eventType)
{
case EventType.Connected:
OnConnected?.Invoke(connectionId);
OnConnected?.Invoke(connectionId, GetClientAddress(connectionId));
break;
case EventType.Data:
OnData?.Invoke(connectionId, message);
Expand Down

0 comments on commit 2c9d26b

Please sign in to comment.