/// <summary>
        /// Start the lobby server link.
        /// </summary>

        public override void Start()
        {
            base.Start();

            if (mTcp == null)
            {
                mTcp      = new TcpProtocol();
                mTcp.name = "Link";
            }
            mNextConnect = 0;
        }
예제 #2
0
        /// <summary>
        /// Start the lobby server link.
        /// </summary>
        public override void Start()
        {
            base.Start();

            if (mTcp == null)
            {
            mTcp = new TcpProtocol();
            mTcp.name = "Link";
            }
            mNextConnect = 0;
        }
예제 #3
0
        /// <summary>
        /// Start the lobby server link.
        /// </summary>

        public override void Start()
        {
            base.Start();

#if FORCE_EN_US
            Tools.SetCurrentCultureToEnUS();
#endif
            if (mTcp == null)
            {
                mTcp      = new TcpProtocol();
                mTcp.name = "Link";
            }
            mNextConnect = 0;
        }
예제 #4
0
        /// <summary>
        /// Thread that will be processing incoming data.
        /// </summary>
        void ThreadFunction()
        {
            for (; ; )
            {
            mTime = DateTime.Now.Ticks / 10000;

            // Accept incoming connections
            while (mListener != null && mListener.Pending())
            {
                TcpProtocol tc = new TcpProtocol();
                tc.data = (long)(-1);
                tc.StartReceiving(mListener.AcceptSocket());
                mTcp.Add(tc);
            }

            Buffer buffer = null;

            // Process incoming TCP packets
            for (int i = 0; i < mTcp.size; ++i)
            {
                TcpProtocol tc = mTcp[i];

                while (tc.ReceivePacket(out buffer))
                {
                    try
                    {
                        if (!ProcessPacket(buffer, tc))
                        {
                            RemoveServer(tc);
                            tc.Disconnect();
                        }
                    }
            #if STANDALONE
                    catch (System.Exception ex)
                    {
                        Console.WriteLine("ERROR: " + ex.Message);
                        RemoveServer(tc);
                        tc.Disconnect();
                    }
            #else
                    catch (System.Exception)
                    {
                        RemoveServer(tc);
                        tc.Disconnect();
                    }
            #endif
                    if (buffer != null)
                    {
                        buffer.Recycle();
                        buffer = null;
                    }
                }
            }

            // We only want to send instant updates if the number of players is under a specific threshold
            if (mTcp.size > instantUpdatesClientLimit) mInstantUpdates = false;

            // Send the server list to all connected clients
            for (int i = 0; i < mTcp.size; ++i)
            {
                TcpProtocol tc = mTcp[i];
                long customTimestamp = (long)tc.data;

                // Timestamp of -1 means we don't want updates to be sent
                if (tc.stage != TcpProtocol.Stage.Connected || customTimestamp == -1) continue;

                // If timestamp was set then the list was already sent previously
                if (customTimestamp != 0)
                {
                    // List hasn't changed -- do nothing
                    if (customTimestamp >= mLastChange) continue;

                    // Too many clients: we want the updates to be infrequent
                    if (!mInstantUpdates && customTimestamp + 4000 > mTime) continue;
                }

                // Create the server list packet
                if (buffer == null)
                {
                    buffer = Buffer.Create();
                    BinaryWriter writer = buffer.BeginPacket(Packet.ResponseServerList);
                    mList.WriteTo(writer);
                    buffer.EndPacket();
                }
                tc.SendTcpPacket(buffer);
                tc.data = mTime;
            }

            if (buffer != null)
            {
                buffer.Recycle();
                buffer = null;
            }
            Thread.Sleep(1);
            }
        }
예제 #5
0
        /// <summary>
        /// Process an incoming packet.
        /// </summary>
        bool ProcessPacket(Buffer buffer, TcpProtocol tc)
        {
            BinaryReader reader = buffer.BeginReading();
            Packet request = (Packet)reader.ReadByte();

            // TCP connections must be verified first to ensure that they are using the correct protocol
            if (tc.stage == TcpProtocol.Stage.Verifying)
            {
            if (tc.VerifyRequestID(request, reader, false)) return true;
            #if STANDALONE
            Console.WriteLine(tc.address + " has failed the verification step");
            #endif
            return false;
            }

            switch (request)
            {
            case Packet.RequestServerList:
            {
                if (reader.ReadUInt16() != GameServer.gameID) return false;
                tc.data = (long)0;
                return true;
            }
            case Packet.RequestAddServer:
            {
                if (reader.ReadUInt16() != GameServer.gameID) return false;
                ServerList.Entry ent = new ServerList.Entry();
                ent.ReadFrom(reader);

                if (ent.externalAddress.Address.Equals(IPAddress.None))
                    ent.externalAddress = tc.tcpEndPoint;

                mList.Add(ent, mTime).data = tc;
                mLastChange = mTime;
            #if STANDALONE
                Console.WriteLine(tc.address + " added a server (" + ent.internalAddress + ", " + ent.externalAddress + ")");
            #endif
                return true;
            }
            case Packet.RequestRemoveServer:
            {
                if (reader.ReadUInt16() != GameServer.gameID) return false;
                IPEndPoint internalAddress, externalAddress;
                Tools.Serialize(reader, out internalAddress);
                Tools.Serialize(reader, out externalAddress);

                if (externalAddress.Address.Equals(IPAddress.None))
                    externalAddress = tc.tcpEndPoint;

                RemoveServer(internalAddress, externalAddress);
            #if STANDALONE
                Console.WriteLine(tc.address + " removed a server (" + internalAddress + ", " + externalAddress + ")");
            #endif
                return true;
            }
            case Packet.Disconnect:
            {
            #if STANDALONE
                if (RemoveServer(tc)) Console.WriteLine(tc.address + " has disconnected");
            #else
                RemoveServer(tc);
            #endif
                mTcp.Remove(tc);
                return true;
            }
            case Packet.RequestSaveFile:
            {
                string fileName = reader.ReadString();
                byte[] data = reader.ReadBytes(reader.ReadInt32());
                SaveFile(fileName, data);
                break;
            }
            case Packet.RequestLoadFile:
            {
                string fn = reader.ReadString();
                byte[] data = LoadFile(fn);

                BinaryWriter writer = BeginSend(Packet.ResponseLoadFile);
                writer.Write(fn);

                if (data != null)
                {
                    writer.Write(data.Length);
                    writer.Write(data);
                }
                else writer.Write(0);
                EndSend(tc);
                break;
            }
            case Packet.RequestDeleteFile:
            {
                DeleteFile(reader.ReadString());
                break;
            }
            case Packet.Error:
            {
            #if STANDALONE
                Console.WriteLine(tc.address + " error: " + reader.ReadString());
            #endif
                return false;
            }
            }
            #if STANDALONE
            Console.WriteLine(tc.address + " sent a packet not handled by the lobby server: " + request);
            #endif
            return false;
        }
예제 #6
0
 /// <summary>
 /// Send the outgoing buffer to the specified player.
 /// </summary>
 void EndSend(TcpProtocol tc)
 {
     mBuffer.EndPacket();
     tc.SendTcpPacket(mBuffer);
     mBuffer.Recycle();
     mBuffer = null;
 }