diff --git a/TShockAPI/Sockets/LinuxTcpSocket.cs b/TShockAPI/Sockets/LinuxTcpSocket.cs new file mode 100644 index 00000000..8ac7f944 --- /dev/null +++ b/TShockAPI/Sockets/LinuxTcpSocket.cs @@ -0,0 +1,173 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.Net.Sockets; +using System.Threading; +using Terraria; +using Terraria.Localization; +using Terraria.Net; +using Terraria.Net.Sockets; + +namespace TShockAPI.Sockets +{ + public class LinuxTcpSocket : ISocket + { + private byte[] _packetBuffer = new byte[1024]; + + private int _packetBufferLength; + + private List _callbackBuffer = new List(); + + private int _messagesInQueue; + + private TcpClient _connection; + + private TcpListener _listener; + + private SocketConnectionAccepted _listenerCallback; + + private RemoteAddress _remoteAddress; + + private bool _isListening; + + public int MessagesInQueue + { + get + { + return this._messagesInQueue; + } + } + + public LinuxTcpSocket() + { + this._connection = new TcpClient(); + this._connection.NoDelay = true; + } + + public LinuxTcpSocket(TcpClient tcpClient) + { + this._connection = tcpClient; + this._connection.NoDelay = true; + IPEndPoint iPEndPoint = (IPEndPoint)tcpClient.Client.RemoteEndPoint; + this._remoteAddress = new TcpAddress(iPEndPoint.Address, iPEndPoint.Port); + } + + void ISocket.Close() + { + this._remoteAddress = null; + this._connection.Close(); + } + + bool ISocket.IsConnected() + { + return this._connection != null && this._connection.Client != null && this._connection.Connected; + } + + void ISocket.Connect(RemoteAddress address) + { + TcpAddress tcpAddress = (TcpAddress)address; + this._connection.Connect(tcpAddress.Address, tcpAddress.Port); + this._remoteAddress = address; + } + + private void ReadCallback(IAsyncResult result) + { + Tuple tuple = (Tuple)result.AsyncState; + tuple.Item1(tuple.Item2, this._connection.GetStream().EndRead(result)); + } + + private void SendCallback(IAsyncResult result) + { + object[] expr_0B = (object[])result.AsyncState; + LegacyNetBufferPool.ReturnBuffer((byte[])expr_0B[1]); + Tuple tuple = (Tuple)expr_0B[0]; + try + { + this._connection.GetStream().EndWrite(result); + tuple.Item1(tuple.Item2); + } + catch (Exception) + { + ((ISocket)this).Close(); + } + } + + void ISocket.SendQueuedPackets() + { + } + + void ISocket.AsyncSend(byte[] data, int offset, int size, SocketSendCallback callback, object state) + { + byte[] array = LegacyNetBufferPool.RequestBuffer(data, offset, size); + this._connection.GetStream().BeginWrite(array, 0, size, new AsyncCallback(this.SendCallback), new object[] + { + new Tuple(callback, state), + array + }); + } + + void ISocket.AsyncReceive(byte[] data, int offset, int size, SocketReceiveCallback callback, object state) + { + this._connection.GetStream().BeginRead(data, offset, size, new AsyncCallback(this.ReadCallback), new Tuple(callback, state)); + } + + bool ISocket.IsDataAvailable() + { + return this._connection.GetStream().DataAvailable; + } + + RemoteAddress ISocket.GetRemoteAddress() + { + return this._remoteAddress; + } + + bool ISocket.StartListening(SocketConnectionAccepted callback) + { + IPAddress any = IPAddress.Any; + string ipString; + if (Program.LaunchParameters.TryGetValue("-ip", out ipString) && !IPAddress.TryParse(ipString, out any)) + { + any = IPAddress.Any; + } + this._isListening = true; + this._listenerCallback = callback; + if (this._listener == null) + { + this._listener = new TcpListener(any, Netplay.ListenPort); + } + try + { + this._listener.Start(); + } + catch (Exception) + { + return false; + } + ThreadPool.QueueUserWorkItem(new WaitCallback(this.ListenLoop)); + return true; + } + + void ISocket.StopListening() + { + this._isListening = false; + } + + private void ListenLoop(object unused) + { + while (this._isListening && !Netplay.disconnect) + { + try + { + Console.WriteLine("Creating linux socket"); + ISocket socket = new LinuxTcpSocket(this._listener.AcceptTcpClient()); + Console.WriteLine(Language.GetTextValue("Net.ClientConnecting", socket.GetRemoteAddress())); + this._listenerCallback(socket); + } + catch (Exception) + { + } + } + this._listener.Stop(); + } + } +} diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index 6e8d0bf0..c1172d0a 100644 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -40,6 +40,7 @@ using TShockAPI.Hooks; using TShockAPI.ServerSideCharacters; using Terraria.Utilities; using Microsoft.Xna.Framework; +using TShockAPI.Sockets; namespace TShockAPI { @@ -184,7 +185,20 @@ namespace TShockAPI string logFilename; string logPathSetupWarning; - TerrariaApi.Reporting.CrashReporter.HeapshotRequesting += CrashReporter_HeapshotRequesting; + OTAPI.Hooks.Net.Socket.Create = () => + { + //Console.WriteLine($"Creating socket {nameof(LinuxTcpSocket)}"); + return new LinuxTcpSocket(); + //return new OTAPI.Sockets.PoolSocket(); + //return new Terraria.Net.Sockets.TcpSocket(); + }; + OTAPI.Hooks.Player.Announce = (int playerId) => + { + //TShock handles this + return OTAPI.HookResult.Cancel; + }; + + TerrariaApi.Reporting.CrashReporter.HeapshotRequesting += CrashReporter_HeapshotRequesting; try { diff --git a/TShockAPI/TShockAPI.csproj b/TShockAPI/TShockAPI.csproj index 351ffc4f..aa744eff 100644 --- a/TShockAPI/TShockAPI.csproj +++ b/TShockAPI/TShockAPI.csproj @@ -68,8 +68,8 @@ ..\packages\MySql.Data.6.9.8\lib\net45\MySql.Data.dll True - - ..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll + + ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll True @@ -95,6 +95,7 @@ + diff --git a/TShockAPI/packages.config b/TShockAPI/packages.config index e8222e44..cc9c5276 100644 --- a/TShockAPI/packages.config +++ b/TShockAPI/packages.config @@ -2,5 +2,5 @@ - + \ No newline at end of file