private byte[] getBytes(RunnerLoginPacket str) { int size = Marshal.SizeOf(str); byte[] arr = new byte[size]; IntPtr ptr = Marshal.AllocHGlobal(size); Marshal.StructureToPtr(str, ptr, true); Marshal.Copy(ptr, arr, 0, size); Marshal.FreeHGlobal(ptr); return(arr); }
public RunnerConnErr Connect(string _host, int _port, BackgroundWorker worker = null) { Sender = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { worker?.ReportProgress(0, "Setting up socket..."); CommData = new byte[1048576]; Sender.ReceiveTimeout = -1; Sender.SendTimeout = 1000; Sender.Connect(_host, _port); worker?.ReportProgress(0, "Connecting..."); int len = Sender.Receive(CommData); string hello = Encoding.ASCII.GetString(CommData, 0, len - 1); worker?.ReportProgress(0, "Recieved hello!"); if (hello != "GM:Studio-Connect") { Sender.Disconnect(false); Sender.Shutdown(SocketShutdown.Both); Sender.Close(); State = RunnerSocketState.Error; return(RunnerConnErr.LoginError); } worker?.ReportProgress(0, "Logging in..."); var loginPacket = new RunnerLoginPacket(); loginPacket.SIG1 = RunnerLoginPacket.NETWORK_SIG1; loginPacket.SIG2 = RunnerLoginPacket.NETWORK_SIG2; loginPacket.Size = Marshal.SizeOf(loginPacket); loginPacket.GameID = RunnerLoginPacket.NETWORK_GAMEID; byte[] data = getBytes(loginPacket); Sender.Send(data, 0, loginPacket.Size, SocketFlags.None); worker?.ReportProgress(0, "Sent login packet"); len = Sender.Receive(CommData); State = RunnerSocketState.Connected; worker?.ReportProgress(0, "Sending GetGameData packet."); if (!SendCommand((int)RunnerCommand.GetGameData)) { throw new Exception("Could not send GetGameData command!"); } HeaderData = new byte[1048576]; HeaderStream = new MemoryStream(HeaderData); HeaderReader = new BinaryReader(HeaderStream); len = Recieve(); if (len > 0) { worker?.ReportProgress(0, "Loading game layout..."); byte[] glDat = new byte[len]; for (var i = 0; i < len; i++) { glDat[i] = HeaderData[i]; } GLData = new GameLayout(); GLData.GameYYDebug = YYDbg; if (!GLData.Load(glDat)) { worker?.ReportProgress(0, "Failed to parse game layout"); State = RunnerSocketState.Error; if (Sender.Connected) { Sender.Disconnect(false); } return(RunnerConnErr.InvalidGameStructure); } worker?.ReportProgress(0, "Game layout parsed ok."); } } catch (ArgumentNullException e) { worker?.ReportProgress(0, $"Argument is null! {e.Message}"); State = RunnerSocketState.Error; if (Sender.Connected) { Sender.Disconnect(false); } return(RunnerConnErr.NullArgument); } catch (SocketException e) { worker?.ReportProgress(0, $"Socket exception! {e.Message}"); State = RunnerSocketState.Error; if (Sender.Connected) { Sender.Disconnect(false); } return(RunnerConnErr.SocketError); } catch (Exception e) { worker?.ReportProgress(0, $"General exception! {e.Message}"); State = RunnerSocketState.Error; if (Sender.Connected) { Sender.Disconnect(false); } return(RunnerConnErr.GeneralException); } worker?.ReportProgress(0, "Done!"); for (int i = 0; i < HeaderData.Length; i++) { HeaderData[i] = 0; } HeaderStream.Seek(0, SeekOrigin.Begin); return(RunnerConnErr.None); }