示例#1
0
        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);
        }
示例#2
0
        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);
        }