コード例 #1
0
ファイル: NetLoop.cs プロジェクト: Scrama/Quarp
        public int SendUnreliableMessage(qsocket_t sock, MsgWriter data)
        {
            if (sock.driverdata == null)
            {
                return(-1);
            }

            qsocket_t sock2 = (qsocket_t)sock.driverdata;

            if ((sock2.receiveMessageLength + data.Length + sizeof(byte) + sizeof(short)) > Net.NET_MAXMESSAGE)
            {
                return(0);
            }

            int offset = sock2.receiveMessageLength;

            // message type
            sock2.receiveMessage[offset++] = 2;

            // length
            sock2.receiveMessage[offset++] = (byte)(data.Length & 0xff);
            sock2.receiveMessage[offset++] = (byte)(data.Length >> 8);

            // align
            offset++;

            // message
            Buffer.BlockCopy(data.Data, 0, sock2.receiveMessage, offset, data.Length);
            sock2.receiveMessageLength = IntAlign(sock2.receiveMessageLength + data.Length + 4);

            return(1);
        }
コード例 #2
0
ファイル: NetVcr.cs プロジェクト: Scrama/Quarp
        public qsocket_t CheckNewConnections()
        {
            if (Host.Time != _Next.time || _Next.op != VcrOp.VCR_OP_CONNECT)
            {
                Sys.Error("VCR missmatch");
            }

            if (_Next.session == 0)
            {
                ReadNext();
                return(null);
            }

            qsocket_t sock = Net.NewSocket();

            sock.driverdata = _Next.session;

            byte[] buf = new byte[Net.NET_NAMELEN];
            Host.VcrReader.Read(buf, 0, buf.Length);
            sock.address = Encoding.ASCII.GetString(buf);

            ReadNext();

            return(sock);
        }
コード例 #3
0
ファイル: Net.cs プロジェクト: Scrama/Quarp
        /// <summary>
        /// NET_SendUnreliableMessage
        /// returns 0 if the message connot be delivered reliably, but the connection
        ///		is still considered valid
        /// returns 1 if the message was sent properly
        /// returns -1 if the connection died
        /// </summary>
        public static int SendUnreliableMessage(qsocket_t sock, MsgWriter data)
        {
            if (sock == null)
            {
                return(-1);
            }

            if (sock.disconnected)
            {
                Con.Print("NET_SendMessage: disconnected socket\n");
                return(-1);
            }

            SetNetTime();

            int r = _Drivers[sock.driver].SendUnreliableMessage(sock, data);

            if (r == 1 && sock.driver != 0)
            {
                _UnreliableMessagesSent++;
            }

            if (_IsRecording)
            {
                _VcrSendMessage.time    = Host.Time;
                _VcrSendMessage.op      = VcrOp.VCR_OP_SENDMESSAGE;
                _VcrSendMessage.session = 1;// (long)sock; Uze todo: ???????
                _VcrSendMessage.ret     = r;
                byte[] buf = Sys.StructureToBytes(ref _VcrSendMessage);
                Host.VcrWriter.Write(buf);
            }

            return(r);
        }
コード例 #4
0
ファイル: Net.cs プロジェクト: Scrama/Quarp
        /// <summary>
        /// NET_CanSendMessage
        /// Returns true or false if the given qsocket can currently accept a
        /// message to be transmitted.
        /// </summary>
        public static bool CanSendMessage(qsocket_t sock)
        {
            if (sock == null)
            {
                return(false);
            }

            if (sock.disconnected)
            {
                return(false);
            }

            SetNetTime();

            bool r = _Drivers[sock.driver].CanSendMessage(sock);

            if (_IsRecording)
            {
                _VcrSendMessage.time    = Host.Time;
                _VcrSendMessage.op      = VcrOp.VCR_OP_CANSENDMESSAGE;
                _VcrSendMessage.session = 1; // (long)sock; Uze: todo: do something?
                _VcrSendMessage.ret     = r ? 1 : 0;
                byte[] buf = Sys.StructureToBytes(ref _VcrSendMessage);
                Host.VcrWriter.Write(buf, 0, buf.Length);
            }

            return(r);
        }
コード例 #5
0
ファイル: ServerMain.cs プロジェクト: Scrama/Quarp
        /// <summary>
        /// SV_CheckForNewClients
        /// </summary>
        public static void CheckForNewClients()
        {
            //
            // check for new connections
            //
            while (true)
            {
                qsocket_t ret = Net.CheckNewConnections();
                if (ret == null)
                {
                    break;
                }

                //
                // init a new client structure
                //
                int i;
                for (i = 0; i < svs.maxclients; i++)
                {
                    if (!svs.clients[i].active)
                    {
                        break;
                    }
                }
                if (i == svs.maxclients)
                {
                    Sys.Error("Host_CheckForNewClients: no free clients");
                }

                svs.clients[i].netconnection = ret;
                ConnectClient(i);

                Net.ActiveConnections++;
            }
        }
コード例 #6
0
ファイル: NetLoop.cs プロジェクト: Scrama/Quarp
        public int GetMessage(qsocket_t sock)
        {
            if (sock.receiveMessageLength == 0)
            {
                return(0);
            }

            int ret    = sock.receiveMessage[0];
            int length = sock.receiveMessage[1] + (sock.receiveMessage[2] << 8);

            // alignment byte skipped here
            Net.Message.Clear();
            Net.Message.FillFrom(sock.receiveMessage, 4, length);

            length = IntAlign(length + 4);
            sock.receiveMessageLength -= length;

            if (sock.receiveMessageLength > 0)
            {
                Array.Copy(sock.receiveMessage, length, sock.receiveMessage, 0, sock.receiveMessageLength);
            }

            if (sock.driverdata != null && ret == 1)
            {
                ((qsocket_t)sock.driverdata).canSend = true;
            }

            return(ret);
        }
コード例 #7
0
ファイル: NetLoop.cs プロジェクト: Scrama/Quarp
        public int SendMessage(qsocket_t sock, MsgWriter data)
        {
            if (sock.driverdata == null)
            {
                return(-1);
            }

            qsocket_t sock2 = (qsocket_t)sock.driverdata;

            if ((sock2.receiveMessageLength + data.Length + 4) > Net.NET_MAXMESSAGE)
            {
                Sys.Error("Loop_SendMessage: overflow\n");
            }

            // message type
            int offset = sock2.receiveMessageLength;

            sock2.receiveMessage[offset++] = 1;

            // length
            sock2.receiveMessage[offset++] = (byte)(data.Length & 0xff);
            sock2.receiveMessage[offset++] = (byte)(data.Length >> 8);

            // align
            offset++;

            // message
            Buffer.BlockCopy(data.Data, 0, sock2.receiveMessage, offset, data.Length);
            sock2.receiveMessageLength = IntAlign(sock2.receiveMessageLength + data.Length + 4);

            sock.canSend = false;
            return(1);
        }
コード例 #8
0
ファイル: NetLoop.cs プロジェクト: Scrama/Quarp
 public bool CanSendMessage(qsocket_t sock)
 {
     if (sock.driverdata == null)
     {
         return(false);
     }
     return(sock.canSend);
 }
コード例 #9
0
ファイル: Net.cs プロジェクト: Scrama/Quarp
        /// <summary>
        /// NET_FreeQSocket
        /// </summary>
        public static void FreeSocket(qsocket_t sock)
        {
            // remove it from active list
            if (!_ActiveSockets.Remove(sock))
            {
                Sys.Error("NET_FreeQSocket: not active\n");
            }

            // add it to free list
            _FreeSockets.Add(sock);
            sock.disconnected = true;
        }
コード例 #10
0
ファイル: NetVcr.cs プロジェクト: Scrama/Quarp
        public int SendMessage(qsocket_t sock, MsgWriter data)
        {
            if (Host.Time != _Next.time || _Next.op != VcrOp.VCR_OP_SENDMESSAGE || _Next.session != SocketToSession(sock))
            {
                Sys.Error("VCR missmatch");
            }

            int ret = Host.VcrReader.ReadInt32();

            ReadNext();

            return(ret);
        }
コード例 #11
0
ファイル: NetVcr.cs プロジェクト: Scrama/Quarp
        public bool CanSendMessage(qsocket_t sock)
        {
            if (Host.Time != _Next.time || _Next.op != VcrOp.VCR_OP_CANSENDMESSAGE || _Next.session != SocketToSession(sock))
            {
                Sys.Error("VCR missmatch");
            }

            int ret = Host.VcrReader.ReadInt32();

            ReadNext();

            return(ret != 0);
        }
コード例 #12
0
ファイル: Net.cs プロジェクト: Scrama/Quarp
        /// <summary>
        /// NET_CheckNewConnections
        /// </summary>
        /// <returns></returns>
        public static qsocket_t CheckNewConnections()
        {
            SetNetTime();

            for (_DriverLevel = 0; _DriverLevel < _Drivers.Length; _DriverLevel++)
            {
                if (!_Drivers[_DriverLevel].IsInitialized)
                {
                    continue;
                }

                if (_DriverLevel > 0 && !_IsListening)
                {
                    continue;
                }

                qsocket_t ret = Net.Driver.CheckNewConnections();
                if (ret != null)
                {
                    if (_IsRecording)
                    {
                        _VcrConnect.time    = Host.Time;
                        _VcrConnect.op      = VcrOp.VCR_OP_CONNECT;
                        _VcrConnect.session = 1; // (long)ret; // Uze: todo: make it work on 64bit systems
                        byte[] buf = Sys.StructureToBytes(ref _VcrConnect);
                        Host.VcrWriter.Write(buf, 0, buf.Length);
                        buf = Encoding.ASCII.GetBytes(ret.address);
                        int count = Math.Min(buf.Length, NET_NAMELEN);
                        int extra = NET_NAMELEN - count;
                        Host.VcrWriter.Write(buf, 0, count);
                        for (int i = 0; i < extra; i++)
                        {
                            Host.VcrWriter.Write((byte)0);
                        }
                    }
                    return(ret);
                }
            }

            if (_IsRecording)
            {
                _VcrConnect.time    = Host.Time;
                _VcrConnect.op      = VcrOp.VCR_OP_CONNECT;
                _VcrConnect.session = 0;
                byte[] buf = Sys.StructureToBytes(ref _VcrConnect);
                Host.VcrWriter.Write(buf, 0, buf.Length);
            }

            return(null);
        }
コード例 #13
0
ファイル: NetDatagram.cs プロジェクト: Scrama/Quarp
        /// <summary>
        /// Datagram_CheckNewConnections
        /// </summary>
        public qsocket_t CheckNewConnections()
        {
            qsocket_t ret = null;

            for (Net.LanDriverLevel = 0; Net.LanDriverLevel < Net.LanDrivers.Length; Net.LanDriverLevel++)
            {
                if (Net.LanDriver.IsInitialized)
                {
                    ret = InternalCheckNewConnections();
                    if (ret != null)
                    {
                        break;
                    }
                }
            }
            return(ret);
        }
コード例 #14
0
ファイル: NetDatagram.cs プロジェクト: Scrama/Quarp
        /// <summary>
        /// Datagram_Connect
        /// </summary>
        public qsocket_t Connect(string host)
        {
            qsocket_t ret = null;

            for (Net.LanDriverLevel = 0; Net.LanDriverLevel < Net.LanDrivers.Length; Net.LanDriverLevel++)
            {
                if (Net.LanDrivers[Net.LanDriverLevel].IsInitialized)
                {
                    ret = InternalConnect(host);
                    if (ret != null)
                    {
                        break;
                    }
                }
            }
            return(ret);
        }
コード例 #15
0
ファイル: NetLoop.cs プロジェクト: Scrama/Quarp
        public void Close(qsocket_t sock)
        {
            if (sock.driverdata != null)
            {
                ((qsocket_t)sock.driverdata).driverdata = null;
            }

            sock.ClearBuffers();
            sock.canSend = true;
            if (sock == _Client)
            {
                _Client = null;
            }
            else
            {
                _Server = null;
            }
        }
コード例 #16
0
ファイル: Net.cs プロジェクト: Scrama/Quarp
        /// <summary>
        /// NET_Close
        /// </summary>
        public static void Close(qsocket_t sock)
        {
            if (sock == null)
            {
                return;
            }

            if (sock.disconnected)
            {
                return;
            }

            SetNetTime();

            // call the driver_Close function
            _Drivers[sock.driver].Close(sock);

            FreeSocket(sock);
        }
コード例 #17
0
 public void Clear()
 {
     this.active        = false;
     this.spawned       = false;
     this.dropasap      = false;
     this.privileged    = false;
     this.sendsignon    = false;
     this.last_message  = 0;
     this.netconnection = null;
     this.cmd.Clear();
     this.wishdir = Vector3.Zero;
     this.message.Clear();
     this.edict  = null;
     this.name   = null;
     this.colors = 0;
     Array.Clear(this.ping_times, 0, this.ping_times.Length);
     this.num_pings = 0;
     Array.Clear(this.spawn_parms, 0, this.spawn_parms.Length);
     this.old_frags = 0;
 }
コード例 #18
0
ファイル: ServerMain.cs プロジェクト: Scrama/Quarp
        /// <summary>
        /// SV_ConnectClient
        /// Initializes a client_t for a new net connection.  This will only be called
        /// once for a player each game, not once for each level change.
        /// </summary>
        static void ConnectClient(int clientnum)
        {
            client_t client = svs.clients[clientnum];

            Con.DPrint("Client {0} connected\n", client.netconnection.address);

            int     edictnum = clientnum + 1;
            edict_t ent      = EdictNum(edictnum);

            // set up the client_t
            qsocket_t netconnection = client.netconnection;

            float[] spawn_parms = new float[NUM_SPAWN_PARMS];
            if (sv.loadgame)
            {
                Array.Copy(client.spawn_parms, spawn_parms, spawn_parms.Length);
            }

            client.Clear();
            client.netconnection         = netconnection;
            client.name                  = "unconnected";
            client.active                = true;
            client.spawned               = false;
            client.edict                 = ent;
            client.message.AllowOverflow = true; // we can catch it
            client.privileged            = false;

            if (sv.loadgame)
            {
                Array.Copy(spawn_parms, client.spawn_parms, spawn_parms.Length);
            }
            else
            {
                // call the progs to get default spawn parms for the new client
                Progs.Execute(Progs.GlobalStruct.SetNewParms);

                AssignGlobalSpawnparams(client);
            }

            SendServerInfo(client);
        }
コード例 #19
0
ファイル: Net.cs プロジェクト: Scrama/Quarp
        /// <summary>
        /// NET_NewQSocket
        /// Called by drivers when a new communications endpoint is required
        /// The sequence and buffer fields will be filled in properly
        /// </summary>
        public static qsocket_t NewSocket()
        {
            if (_FreeSockets.Count == 0)
            {
                return(null);
            }

            if (Net.ActiveConnections >= Server.svs.maxclients)
            {
                return(null);
            }

            // get one from free list
            int       i    = _FreeSockets.Count - 1;
            qsocket_t sock = _FreeSockets[i];

            _FreeSockets.RemoveAt(i);

            // add it to active list
            _ActiveSockets.Add(sock);

            sock.disconnected              = false;
            sock.connecttime               = _Time;
            sock.address                   = "UNSET ADDRESS";
            sock.driver                    = _DriverLevel;
            sock.socket                    = null;
            sock.driverdata                = null;
            sock.canSend                   = true;
            sock.sendNext                  = false;
            sock.lastMessageTime           = _Time;
            sock.ackSequence               = 0;
            sock.sendSequence              = 0;
            sock.unreliableSendSequence    = 0;
            sock.sendMessageLength         = 0;
            sock.receiveSequence           = 0;
            sock.unreliableReceiveSequence = 0;
            sock.receiveMessageLength      = 0;

            return(sock);
        }
コード例 #20
0
ファイル: NetLoop.cs プロジェクト: Scrama/Quarp
        public qsocket_t Connect(string host)
        {
            if (host != "local")
            {
                return(null);
            }

            _LocalConnectPending = true;

            if (_Client == null)
            {
                _Client = Net.NewSocket();
                if (_Client == null)
                {
                    Con.Print("Loop_Connect: no qsocket available\n");
                    return(null);
                }
                _Client.address = "localhost";
            }
            _Client.ClearBuffers();
            _Client.canSend = true;

            if (_Server == null)
            {
                _Server = Net.NewSocket();
                if (_Server == null)
                {
                    Con.Print("Loop_Connect: no qsocket available\n");
                    return(null);
                }
                _Server.address = "LOCAL";
            }
            _Server.ClearBuffers();
            _Server.canSend = true;

            _Client.driverdata = _Server;
            _Server.driverdata = _Client;

            return(_Client);
        }
コード例 #21
0
ファイル: NetVcr.cs プロジェクト: Scrama/Quarp
        public int GetMessage(qsocket_t sock)
        {
            if (Host.Time != _Next.time || _Next.op != VcrOp.VCR_OP_GETMESSAGE || _Next.session != SocketToSession(sock))
            {
                Sys.Error("VCR missmatch");
            }

            int ret = Host.VcrReader.ReadInt32();

            if (ret != 1)
            {
                ReadNext();
                return(ret);
            }

            int length = Host.VcrReader.ReadInt32();

            Net.Message.FillFrom(Host.VcrReader.BaseStream, length);

            ReadNext();

            return(1);
        }
コード例 #22
0
ファイル: NetVcr.cs プロジェクト: Scrama/Quarp
 public long SocketToSession(qsocket_t sock)
 {
     return((long)sock.driverdata);
 }
コード例 #23
0
ファイル: NetVcr.cs プロジェクト: Scrama/Quarp
 public void Close(qsocket_t sock)
 {
     // nothing to do
 }
コード例 #24
0
ファイル: NetVcr.cs プロジェクト: Scrama/Quarp
 public bool CanSendUnreliableMessage(qsocket_t sock)
 {
     return(true);
 }
コード例 #25
0
ファイル: NetVcr.cs プロジェクト: Scrama/Quarp
 public int SendUnreliableMessage(qsocket_t sock, MsgWriter data)
 {
     throw new NotImplementedException();
 }
コード例 #26
0
ファイル: Net.cs プロジェクト: Scrama/Quarp
        /// <summary>
        /// NET_Connect
        /// called by client to connect to a host.  Returns -1 if not able to connect
        /// </summary>
        public static qsocket_t Connect(string host)
        {
            int numdrivers = _Drivers.Length;// net_numdrivers;

            SetNetTime();

            if (String.IsNullOrEmpty(host))
            {
                host = null;
            }

            if (host != null)
            {
                if (Common.SameText(host, "local"))
                {
                    numdrivers = 1;
                    goto JustDoIt;
                }

                if (HostCacheCount > 0)
                {
                    foreach (hostcache_t hc in _HostCache)
                    {
                        if (Common.SameText(hc.name, host))
                        {
                            host = hc.cname;
                            goto JustDoIt;
                        }
                    }
                }
            }

            SlistSilent = (host != null);
            Slist_f();

            while (_SlistInProgress)
            {
                Poll();
            }

            if (host == null)
            {
                if (HostCacheCount != 1)
                {
                    return(null);
                }
                host = _HostCache[0].cname;
                Con.Print("Connecting to...\n{0} @ {1}\n\n", _HostCache[0].name, host);
            }

            _DriverLevel = 0;
            foreach (hostcache_t hc in _HostCache)
            {
                if (Common.SameText(host, hc.name))
                {
                    host = hc.cname;
                    break;
                }
                _DriverLevel++;
            }

JustDoIt:
            _DriverLevel = 0;
            foreach (INetDriver drv in _Drivers)
            {
                if (!drv.IsInitialized)
                {
                    continue;
                }
                qsocket_t ret = drv.Connect(host);
                if (ret != null)
                {
                    return(ret);
                }
                _DriverLevel++;
            }

            if (host != null)
            {
                Con.Print("\n");
                PrintSlistHeader();
                PrintSlist();
                PrintSlistTrailer();
            }

            return(null);
        }
コード例 #27
0
ファイル: Net.cs プロジェクト: Scrama/Quarp
        /// <summary>
        /// NET_GetMessage
        /// returns data in net_message sizebuf
        /// returns 0 if no data is waiting
        /// returns 1 if a message was received
        /// returns 2 if an unreliable message was received
        /// returns -1 if the connection died
        /// </summary>
        public static int GetMessage(qsocket_t sock)
        {
            //int ret;

            if (sock == null)
            {
                return(-1);
            }

            if (sock.disconnected)
            {
                Con.Print("NET_GetMessage: disconnected socket\n");
                return(-1);
            }

            SetNetTime();

            int ret = _Drivers[sock.driver].GetMessage(sock);

            // see if this connection has timed out
            if (ret == 0 && sock.driver != 0)
            {
                if (_Time - sock.lastMessageTime > _MessageTimeout.Value)
                {
                    Close(sock);
                    return(-1);
                }
            }

            if (ret > 0)
            {
                if (sock.driver != 0)
                {
                    sock.lastMessageTime = _Time;
                    if (ret == 1)
                    {
                        _MessagesReceived++;
                    }
                    else if (ret == 2)
                    {
                        _UnreliableMessagesReceived++;
                    }
                }

                if (_IsRecording)
                {
                    _VcrGetMessage.time    = Host.Time;
                    _VcrGetMessage.op      = VcrOp.VCR_OP_GETMESSAGE;
                    _VcrGetMessage.session = 1;// (long)sock; Uze todo: write somethisng meaningful
                    _VcrGetMessage.ret     = ret;
                    byte[] buf = Sys.StructureToBytes(ref _VcrGetMessage);
                    Host.VcrWriter.Write(buf, 0, buf.Length);
                    Host.VcrWriter.Write(Net.Message.Length);
                    Host.VcrWriter.Write(Net.Message.Data, 0, Net.Message.Length);
                }
            }
            else
            {
                if (_IsRecording)
                {
                    _VcrGetMessage.time    = Host.Time;
                    _VcrGetMessage.op      = VcrOp.VCR_OP_GETMESSAGE;
                    _VcrGetMessage.session = 1; // (long)sock; Uze todo: fix this
                    _VcrGetMessage.ret     = ret;
                    byte[] buf = Sys.StructureToBytes(ref _VcrGetMessage);
                    Host.VcrWriter.Write(buf, 0, buf.Length);
                }
            }

            return(ret);
        }
コード例 #28
0
ファイル: NetDatagram.cs プロジェクト: Scrama/Quarp
        /// <summary>
        /// _Datagram_Connect
        /// </summary>
        qsocket_t InternalConnect(string host)
        {
            // see if we can resolve the host name
            EndPoint sendaddr = Net.LanDriver.GetAddrFromName(host);

            if (sendaddr == null)
            {
                return(null);
            }

            Socket newsock = Net.LanDriver.OpenSocket(0);

            if (newsock == null)
            {
                return(null);
            }

            qsocket_t sock = Net.NewSocket();

            if (sock == null)
            {
                goto ErrorReturn2;
            }
            sock.socket    = newsock;
            sock.landriver = Net.LanDriverLevel;

            // connect to the host
            if (Net.LanDriver.Connect(newsock, sendaddr) == -1)
            {
                goto ErrorReturn;
            }

            // send the connection request
            Con.Print("trying...\n");
            Scr.UpdateScreen();
            double start_time = Net.Time;
            int    ret        = 0;

            for (int reps = 0; reps < 3; reps++)
            {
                Net.Message.Clear();
                // save space for the header, filled in later
                Net.Message.WriteLong(0);
                Net.Message.WriteByte(CCReq.CCREQ_CONNECT);
                Net.Message.WriteString("QUAKE");
                Net.Message.WriteByte(Net.NET_PROTOCOL_VERSION);
                Common.WriteInt(Net.Message.Data, 0, Common.BigLong(NetFlags.NETFLAG_CTL |
                                                                    (Net.Message.Length & NetFlags.NETFLAG_LENGTH_MASK)));
                //*((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
                Net.LanDriver.Write(newsock, Net.Message.Data, Net.Message.Length, sendaddr);
                Net.Message.Clear();
                EndPoint readaddr = new IPEndPoint(IPAddress.Any, 0);
                do
                {
                    ret = Net.Message.FillFrom(newsock, ref readaddr);
                    // if we got something, validate it
                    if (ret > 0)
                    {
                        // is it from the right place?
                        if (sock.LanDriver.AddrCompare(readaddr, sendaddr) != 0)
                        {
#if DEBUG
                            Con.Print("wrong reply address\n");
                            Con.Print("Expected: {0}\n", StrAddr(sendaddr));
                            Con.Print("Received: {0}\n", StrAddr(readaddr));
                            Scr.UpdateScreen();
#endif
                            ret = 0;
                            continue;
                        }

                        if (ret < sizeof(int))
                        {
                            ret = 0;
                            continue;
                        }

                        Net.Reader.Reset();

                        int control = Common.BigLong(Net.Reader.ReadLong());// BigLong(*((int *)net_message.data));
                        //MSG_ReadLong();
                        if (control == -1)
                        {
                            ret = 0;
                            continue;
                        }
                        if ((control & (~NetFlags.NETFLAG_LENGTH_MASK)) != NetFlags.NETFLAG_CTL)
                        {
                            ret = 0;
                            continue;
                        }
                        if ((control & NetFlags.NETFLAG_LENGTH_MASK) != ret)
                        {
                            ret = 0;
                            continue;
                        }
                    }
                }while ((ret == 0) && (Net.SetNetTime() - start_time) < 2.5);
                if (ret > 0)
                {
                    break;
                }
                Con.Print("still trying...\n");
                Scr.UpdateScreen();
                start_time = Net.SetNetTime();
            }

            string reason = String.Empty;
            if (ret == 0)
            {
                reason = "No Response";
                Con.Print("{0}\n", reason);
                Menu.ReturnReason = reason;
                goto ErrorReturn;
            }

            if (ret == -1)
            {
                reason = "Network Error";
                Con.Print("{0}\n", reason);
                Menu.ReturnReason = reason;
                goto ErrorReturn;
            }

            ret = Net.Reader.ReadByte();
            if (ret == CCRep.CCREP_REJECT)
            {
                reason = Net.Reader.ReadString();
                Con.Print(reason);
                Menu.ReturnReason = reason;
                goto ErrorReturn;
            }

            if (ret == CCRep.CCREP_ACCEPT)
            {
                IPEndPoint ep = (IPEndPoint)sendaddr;
                sock.addr = new IPEndPoint(ep.Address, ep.Port);
                Net.LanDriver.SetSocketPort(sock.addr, Net.Reader.ReadLong());
            }
            else
            {
                reason = "Bad Response";
                Con.Print("{0}\n", reason);
                Menu.ReturnReason = reason;
                goto ErrorReturn;
            }

            sock.address = Net.LanDriver.GetNameFromAddr(sendaddr);

            Con.Print("Connection accepted\n");
            sock.lastMessageTime = Net.SetNetTime();

            // switch the connection to the specified address
            if (Net.LanDriver.Connect(newsock, sock.addr) == -1)
            {
                reason = "Connect to Game failed";
                Con.Print("{0}\n", reason);
                Menu.ReturnReason = reason;
                goto ErrorReturn;
            }

            Menu.ReturnOnError = false;
            return(sock);

ErrorReturn:
            Net.FreeSocket(sock);
ErrorReturn2:
            Net.LanDriver.CloseSocket(newsock);
            if (Menu.ReturnOnError && Menu.ReturnMenu != null)
            {
                Menu.ReturnMenu.Show();
                Menu.ReturnOnError = false;
            }
            return(null);
        }