Beispiel #1
0
        /// <summary>
        /// Send the specified packet. Marks the buffer as used.
        /// </summary>

        public void SendTcpPacket(Buffer buffer)
        {
            buffer.MarkAsUsed();

            if (mSocket != null && mSocket.Connected)
            {
                buffer.BeginReading();

                lock (mOut)
                {
                    mOut.Enqueue(buffer);

                    if (mOut.Count == 1)
                    {
                        try
                        {
                            // If it's the first packet, let's begin the send process
                            mSocket.BeginSend(buffer.buffer, buffer.position, buffer.size, SocketFlags.None, OnSend, buffer);
                        }
                        catch (System.Exception ex)
                        {
                            Error(ex.Message);
                            Close(false);
                            Release();
                        }
                    }
                }
            }
            else
            {
                buffer.Recycle();
            }
        }
Beispiel #2
0
        /// <summary>
        /// Send the specified datagram.
        /// </summary>

        public void Send(Buffer buffer, IPEndPoint ip)
        {
            if (ip.Address.Equals(IPAddress.Broadcast))
            {
                Broadcast(buffer, ip.Port);
                return;
            }

            buffer.MarkAsUsed();

            if (mSocket != null)
            {
                buffer.BeginReading();

                lock (mOut)
                {
                    Datagram dg = new Datagram();
                    dg.buffer = buffer;
                    dg.ip     = ip;
                    mOut.Enqueue(dg);

                    if (mOut.Count == 1)
                    {
                        // If it's the first datagram, begin the sending process
                        mSocket.BeginSendTo(buffer.buffer, buffer.position, buffer.size,
                                            SocketFlags.None, ip, OnSend, null);
                    }
                }
            }
            else
            {
                buffer.Recycle();
                throw new InvalidOperationException("The socket is null. Did you forget to call UdpProtocol.Start()?");
            }
        }
        /// <summary>
        /// Create a new buffered remote function call.
        /// </summary>

        public void CreateRFC(uint inID, string funcName, Buffer buffer)
        {
            if (closed || buffer == null)
            {
                return;
            }
            buffer.MarkAsUsed();

            for (int i = 0; i < rfcs.size; ++i)
            {
                RFC r = rfcs[i];

                if (r.id == inID && r.funcName == funcName)
                {
                    if (r.buffer != null)
                    {
                        r.buffer.Recycle();
                    }
                    r.buffer = buffer;
                    return;
                }
            }

            RFC rfc = new RFC();

            rfc.id       = inID;
            rfc.buffer   = buffer;
            rfc.funcName = funcName;
            rfcs.Add(rfc);
        }
        /// <summary>
        /// Send the outgoing buffer to all players in the specified channel.
        /// </summary>

        void SendToChannel(bool reliable, Channel channel, Buffer buffer)
        {
            mBuffer.MarkAsUsed();
            if (mBuffer.size > 1024)
            {
                reliable = true;
            }

            for (int i = 0; i < channel.players.size; ++i)
            {
                TcpPlayer player = channel.players[i];

                if (player.stage == TcpProtocol.Stage.Connected)
                {
                    if (reliable || player.udpEndPoint == null || !mAllowUdp)
                    {
                        player.SendTcpPacket(mBuffer);
                    }
                    else
                    {
                        mUdp.Send(mBuffer, player.udpEndPoint);
                    }
                }
            }
            mBuffer.Recycle();
        }
Beispiel #5
0
        /// <summary>
        /// Send the specified buffer to the entire LAN.
        /// </summary>

        public void Broadcast(Buffer buffer, int port)
        {
            if (buffer != null)
            {
                buffer.MarkAsUsed();
#if UNITY_WEBPLAYER || UNITY_FLASH
#if UNITY_EDITOR
                UnityEngine.Debug.LogError("[TNet] Sending broadcasts doesn't work in the Unity Web Player or Flash");
#endif
#else
                IPEndPoint endPoint = mMulticast ? mMulticastEndPoint : mBroadcastEndPoint;
                endPoint.Port = port;

                try
                {
                    mSocket.SendTo(buffer.buffer, buffer.position, buffer.size, SocketFlags.None, endPoint);
                }
                catch (System.Exception ex)
                {
                    Error(null, ex.Message);
                }
#endif
                buffer.Recycle();
            }
        }
        /// <summary>
        /// Send the specified datagram.
        /// </summary>

        public void Send(Buffer buffer, IPEndPoint ip)
        {
#if !MODDING
            if (ip.Address.Equals(IPAddress.Broadcast))
            {
                Broadcast(buffer, ip.Port);
            }
            else if (mSocket != null)
            {
                if (mSocket.AddressFamily != ip.AddressFamily)
                {
#if UNITY_EDITOR
                    UnityEngine.Debug.LogError("UDP socket " + name + " (" + mSocket.AddressFamily + ") and the desired address " + ip.Address +
                                               " (" + ip.AddressFamily + ") were started with different address families");
#else
                    Tools.LogError("UDP socket " + name + " (" + mSocket.AddressFamily + ") and the desired address " + ip.Address +
                                   " (" + ip.AddressFamily + ") were started with different address families");
#endif
                    return;
                }

                buffer.MarkAsUsed();
                buffer.BeginReading();

                lock (mOut)
                {
                    Datagram dg = new Datagram();
                    dg.buffer = buffer;
                    dg.ip     = ip;
                    mOut.Enqueue(dg);

                    if (mOut.Count == 1)
                    {
                        try
                        {
                            // If it's the first datagram, begin the sending process
                            mSocket.BeginSendTo(buffer.buffer, buffer.position, buffer.size, SocketFlags.None, ip, OnSend, null);
                        }
                        catch (Exception ex)
                        {
                            Tools.LogError(ex.Message + "\n" + ex.StackTrace);
                            buffer.Recycle();
                        }
                    }
                }
            }
            else
            {
                Tools.LogError("The socket is null. Did you forget to call UdpProtocol.Start()?");
            }
#endif
        }
Beispiel #7
0
        /// <summary>
        /// Send the specified datagram.
        /// </summary>

        public void Send(Buffer buffer, IPEndPoint ip)
        {
            if (ip.Address.Equals(IPAddress.Broadcast))
            {
                Broadcast(buffer, ip.Port);
            }
            else if (mSocket != null)
            {
                buffer.MarkAsUsed();
                buffer.BeginReading();

                lock (mOut)
                {
                    Datagram dg = new Datagram();
                    dg.buffer = buffer;
                    dg.ip     = ip;
                    mOut.Enqueue(dg);

                    if (mOut.Count == 1)
                    {
                        try
                        {
                            // If it's the first datagram, begin the sending process
                            mSocket.BeginSendTo(buffer.buffer, buffer.position, buffer.size,
                                                SocketFlags.None, ip, OnSend, null);
                        }
                        catch (Exception ex)
                        {
                            Tools.LogError(ex.Message + "\n" + ex.StackTrace);
                            buffer.Recycle();
                        }
                    }
                }
            }
            else
            {
                Tools.LogError("The socket is null. Did you forget to call UdpProtocol.Start()?");
            }
        }
Beispiel #8
0
        /// <summary>
        /// Create a new buffered remote function call.
        /// </summary>
        public void CreateRFC(uint inID, string funcName, Buffer buffer)
        {
            if (closed || buffer == null) return;
            buffer.MarkAsUsed();

            for (int i = 0; i < rfcs.size; ++i)
            {
            RFC r = rfcs[i];

            if (r.id == inID && r.funcName == funcName)
            {
                if (r.buffer != null) r.buffer.Recycle();
                r.buffer = buffer;
                return;
            }
            }

            RFC rfc = new RFC();
            rfc.id = inID;
            rfc.buffer = buffer;
            rfc.funcName = funcName;
            rfcs.Add(rfc);
        }
        /// <summary>
        /// Send the specified packet. Marks the buffer as used.
        /// </summary>

        public void SendTcpPacket(Buffer buffer)
        {
            buffer.MarkAsUsed();

            if (mSocket != null && mSocket.Connected)
            {
                buffer.BeginReading();

                lock (mOut)
                {
                    mOut.Enqueue(buffer);

                    if (mOut.Count == 1)
                    {
                        // If it's the first packet, let's begin the send process
                        mSocket.BeginSend(buffer.buffer, buffer.position, buffer.size, SocketFlags.None, OnSend, buffer);
                    }
                }
            }
            else
            {
                buffer.Recycle();
            }
        }
Beispiel #10
0
        /// <summary>
        /// Send the specified buffer to the entire LAN.
        /// </summary>
        public void Broadcast(Buffer buffer, int port)
        {
            if (buffer != null)
            {
            buffer.MarkAsUsed();
            #if UNITY_WEBPLAYER || UNITY_FLASH
            #if UNITY_EDITOR
            UnityEngine.Debug.LogError("Sending broadcasts doesn't work in the Unity Web Player or Flash");
            #endif
            #else
            mBroadcastIP.Port = port;

            try
            {
                mSocket.SendTo(buffer.buffer, buffer.position, buffer.size, SocketFlags.None, mBroadcastIP);
            }
            catch (System.Exception ex)
            {
                Error(null, ex.Message);
            }
            #endif
            buffer.Recycle();
            }
        }
Beispiel #11
0
        /// <summary>
        /// Send the specified packet. Marks the buffer as used.
        /// </summary>

        public void SendTcpPacket(Buffer buffer)
        {
            buffer.MarkAsUsed();
            BinaryReader reader = buffer.BeginReading();

#if DEBUG_PACKETS && !STANDALONE
            Packet packet = (Packet)buffer.PeekByte(4);
            if (packet != Packet.RequestPing && packet != Packet.ResponsePing)
            {
                UnityEngine.Debug.Log("Sending: " + packet + " to " + name + " (" + (buffer.size - 5).ToString("N0") + " bytes)");
            }
#endif

            if (mSocket != null && mSocket.Connected)
            {
                lock (mOut)
                {
                    mOut.Enqueue(buffer);

                    // If it's the first packet, let's begin the send process
                    if (mOut.Count == 1)
                    {
                        try
                        {
#if !UNITY_WINRT
                            mSocket.BeginSend(buffer.buffer, buffer.position, buffer.size, SocketFlags.None, OnSend, buffer);
#endif
                        }
                        catch (System.Exception ex)
                        {
                            mOut.Clear();
                            buffer.Recycle();
                            RespondWithError(ex);
                            CloseNotThreadSafe(false);
                        }
                    }
                }
                return;
            }

            if (sendQueue != null)
            {
                if (buffer.position != 0)
                {
                    // Offline mode sends packets individually and they should not be reused
#if UNITY_EDITOR
                    Debug.LogWarning("Packet's position is " + buffer.position + " instead of 0. Potentially sending the same packet more than once. Ignoring...");
#endif
                    return;
                }

                // Skip the packet's size
                int size = reader.ReadInt32();

                if (size == buffer.size)
                {
                    // Note that after this the buffer can no longer be used again as its offset is +4
                    lock (sendQueue) sendQueue.Enqueue(buffer);
                    return;
                }

                // Multi-part packet -- split it up into separate ones
                lock (sendQueue)
                {
                    for (;;)
                    {
                        byte[] bytes = reader.ReadBytes(size);

                        Buffer       temp   = Buffer.Create();
                        BinaryWriter writer = temp.BeginWriting();
                        writer.Write(size);
                        writer.Write(bytes);
                        temp.BeginReading(4);
                        temp.EndWriting();
                        sendQueue.Enqueue(temp);

                        if (buffer.size > 0)
                        {
                            size = reader.ReadInt32();
                        }
                        else
                        {
                            break;
                        }
                    }
                }
            }

            buffer.Recycle();
        }
Beispiel #12
0
        /// <summary>
        /// Send the specified datagram.
        /// </summary>
        public void Send(Buffer buffer, IPEndPoint ip)
        {
            if (ip.Address.Equals(IPAddress.Broadcast))
            {
            Broadcast(buffer, ip.Port);
            return;
            }

            buffer.MarkAsUsed();

            if (mSocket != null)
            {
            buffer.BeginReading();

            lock (mOut)
            {
                Datagram dg = new Datagram();
                dg.buffer = buffer;
                dg.ip = ip;
                mOut.Enqueue(dg);

                if (mOut.Count == 1)
                {
                    // If it's the first datagram, begin the sending process
                    mSocket.BeginSendTo(buffer.buffer, buffer.position, buffer.size,
                        SocketFlags.None, ip, OnSend, null);
                }
            }
            }
            else
            {
            buffer.Recycle();
            throw new InvalidOperationException("The socket is null. Did you forget to call UdpProtocol.Start()?");
            }
        }
Beispiel #13
0
        /// <summary>
        /// Send the specified packet. Marks the buffer as used.
        /// </summary>

        public void SendTcpPacket(Buffer buffer, bool instant = false)
        {
#if !MODDING
            buffer.MarkAsUsed();

            var reader = buffer.BeginReading();

            if (buffer.size == 0)
            {
#if UNITY_EDITOR
                Debug.LogError("Trying to send a zero packet! " + buffer.position + " " + buffer.isWriting + " " + id);
#endif
                buffer.Recycle();
                return;
            }

#if DEBUG_PACKETS && !STANDALONE
            var packet = (Packet)buffer.PeekByte(4);
            if (packet != Packet.RequestPing && packet != Packet.ResponsePing)
            {
                UnityEngine.Debug.Log("Sending: " + packet + " to " + name + " (" + (buffer.size - 5).ToString("N0") + " bytes)");
            }
#endif
            if (custom != null)
            {
                if (!custom.SendPacket(buffer))
                {
                    buffer.Recycle();
                    Disconnect();
                }
                else
                {
                    buffer.Recycle();
                }
                return;
            }

            if (mSocket != null && mSocket.Connected)
            {
                lock (mOut)
                {
#if UNITY_WINRT
                    mSocket.Send(buffer.buffer, buffer.size, SocketFlags.None);
#else
                    if (instant)
                    {
                        try
                        {
                            var before = mSocket.NoDelay;
                            if (!before)
                            {
                                mSocket.NoDelay = true;
                            }
                            mSocket.Send(buffer.buffer, buffer.position, buffer.size, SocketFlags.None);
                            if (!before)
                            {
                                mSocket.NoDelay = false;
                            }
                            buffer.Recycle();
                            return;
                        }
                        catch { }
                    }

                    if (mSending)
                    {
                        // Simply add this packet to the outgoing queue
                        mOut.Enqueue(buffer);
                    }
                    else
                    {
                        // If it's the first packet, let's begin the send process
                        mSending = true;

                        try
                        {
                            mSocket.BeginSend(buffer.buffer, buffer.position, buffer.size, SocketFlags.None, OnSend, buffer);
                        }
                        catch (System.Exception ex)
                        {
                            mOut.Clear();
                            buffer.Recycle();
                            AddError(ex);
                            CloseNotThreadSafe(false);
                            mSending = false;
                        }
                    }
#endif
                }
                return;
            }

            if (sendQueue != null)
            {
                if (buffer.position != 0)
                {
                    // Offline mode sends packets individually and they should not be reused
#if UNITY_EDITOR
                    Debug.LogWarning("Packet's position is " + buffer.position + " instead of 0. Potentially sending the same packet more than once. Ignoring...");
#endif
                    return;
                }

                // Skip the packet's size
                int size = reader.ReadInt32();

                if (size == buffer.size)
                {
                    lock (sendQueue) sendQueue.Enqueue(buffer);
                    return;
                }

                // Multi-part packet -- split it up into separate ones
                lock (sendQueue)
                {
                    for (;;)
                    {
                        var bytes  = reader.ReadBytes(size);
                        var temp   = Buffer.Create();
                        var writer = temp.BeginWriting();
                        writer.Write(size);
                        writer.Write(bytes);
                        temp.BeginReading(4);
                        sendQueue.Enqueue(temp);

                        if (buffer.size > 0)
                        {
                            size = reader.ReadInt32();
                        }
                        else
                        {
                            break;
                        }
                    }
                }
            }
#endif
            buffer.Recycle();
        }
Beispiel #14
0
        /// <summary>
        /// Send the specified packet. Marks the buffer as used.
        /// </summary>
        public void SendTcpPacket(Buffer buffer)
        {
            buffer.MarkAsUsed();

            if (mSocket != null && mSocket.Connected)
            {
            buffer.BeginReading();

            lock (mOut)
            {
                mOut.Enqueue(buffer);

                if (mOut.Count == 1)
                {
                    try
                    {
                        // If it's the first packet, let's begin the send process
                        mSocket.BeginSend(buffer.buffer, buffer.position, buffer.size, SocketFlags.None, OnSend, buffer);
                    }
                    catch (System.Exception ex)
                    {
                        Error(ex.Message);
                        Close(false);
                        Release();
                    }
                }
            }
            }
            else buffer.Recycle();
        }
        /// <summary>
        /// Process a packet from the player.
        /// </summary>

        void ProcessChannelPacket(TcpPlayer player, Buffer buffer, BinaryReader reader, Packet request)
        {
            switch (request)
            {
            case Packet.RequestCreate:
            {
                // Create a new object
                ushort objectIndex = reader.ReadUInt16();
                byte   type        = reader.ReadByte();
                uint   uniqueID    = 0;

                if (type != 0)
                {
                    uniqueID = --player.channel.objectCounter;

                    // 1-32767 is reserved for existing scene objects.
                    // 32768 - 16777215 is for dynamically created objects.
                    if (uniqueID < 32768)
                    {
                        player.channel.objectCounter = 0xFFFFFF;
                        uniqueID = 0xFFFFFF;
                    }

                    Channel.CreatedObject obj = new Channel.CreatedObject();
                    obj.playerID = player.id;
                    obj.objectID = objectIndex;
                    obj.uniqueID = uniqueID;
                    obj.type     = type;

                    if (buffer.size > 0)
                    {
                        obj.buffer = buffer;
                        buffer.MarkAsUsed();
                    }
                    player.channel.created.Add(obj);
                }

                // Inform the channel
                BinaryWriter writer = BeginSend(Packet.ResponseCreate);
                writer.Write(player.id);
                writer.Write(objectIndex);
                writer.Write(uniqueID);
                if (buffer.size > 0)
                {
                    writer.Write(buffer.buffer, buffer.position, buffer.size);
                }
                EndSend(true, player.channel, null);
                break;
            }

            case Packet.RequestDestroy:
            {
                // Destroy the specified network object
                uint uniqueID = reader.ReadUInt32();

                // Remove this object
                if (player.channel.DestroyObject(uniqueID))
                {
                    // Inform all players in the channel that the object should be destroyed
                    BinaryWriter writer = BeginSend(Packet.ResponseDestroy);
                    writer.Write((ushort)1);
                    writer.Write(uniqueID);
                    EndSend(true, player.channel, null);
                }
                break;
            }

            case Packet.RequestLoadLevel:
            {
                // Change the currently loaded level
                if (player.channel.host == player)
                {
                    player.channel.Reset();
                    player.channel.level = reader.ReadString();

                    BinaryWriter writer = BeginSend(Packet.ResponseLoadLevel);
                    writer.Write(string.IsNullOrEmpty(player.channel.level) ? "" : player.channel.level);
                    EndSend(true, player.channel, null);
                }
                break;
            }

            case Packet.RequestSetHost:
            {
                // Transfer the host state from one player to another
                if (player.channel.host == player)
                {
                    TcpPlayer newHost = GetPlayer(reader.ReadInt32());
                    if (newHost != null && newHost.channel == player.channel)
                    {
                        SendSetHost(newHost);
                    }
                }
                break;
            }

            case Packet.RequestLeaveChannel:
            {
                SendLeaveChannel(player, true);
                break;
            }

            case Packet.RequestCloseChannel:
            {
                player.channel.persistent = false;
                player.channel.closed     = true;
                break;
            }

            case Packet.RequestSetPlayerLimit:
            {
                player.channel.playerLimit = reader.ReadUInt16();
                break;
            }

            case Packet.RequestRemoveRFC:
            {
                uint   id       = reader.ReadUInt32();
                string funcName = ((id & 0xFF) == 0) ? reader.ReadString() : null;
                player.channel.DeleteRFC(id, funcName);
                break;
            }

            case Packet.RequestSetChannelData:
            {
                player.channel.data = reader.ReadString();
                BinaryWriter writer = BeginSend(Packet.ResponseSetChannelData);
                writer.Write(player.channel.data);
                EndSend(true, player.channel, null);
                break;
            }
            }
        }
Beispiel #16
0
        /// <summary>
        /// Process a packet from the player.
        /// </summary>
        void ProcessChannelPacket(TcpPlayer player, Buffer buffer, BinaryReader reader, Packet request)
        {
            switch (request)
            {
            case Packet.RequestCreate:
            {
                // Create a new object
                ushort objectIndex = reader.ReadUInt16();
                byte type = reader.ReadByte();
                uint uniqueID = 0;

                if (type != 0)
                {
                    uniqueID = --player.channel.objectCounter;

                    // 1-32767 is reserved for existing scene objects.
                    // 32768 - 16777215 is for dynamically created objects.
                    if (uniqueID < 32768)
                    {
                        player.channel.objectCounter = 0xFFFFFF;
                        uniqueID = 0xFFFFFF;
                    }

                    Channel.CreatedObject obj = new Channel.CreatedObject();
                    obj.playerID = player.id;
                    obj.objectID = objectIndex;
                    obj.uniqueID = uniqueID;
                    obj.type = type;

                    if (buffer.size > 0)
                    {
                        obj.buffer = buffer;
                        buffer.MarkAsUsed();
                    }
                    player.channel.created.Add(obj);
                }

                // Inform the channel
                BinaryWriter writer = BeginSend(Packet.ResponseCreate);
                writer.Write(player.id);
                writer.Write(objectIndex);
                writer.Write(uniqueID);
                if (buffer.size > 0) writer.Write(buffer.buffer, buffer.position, buffer.size);
                EndSend(true, player.channel, null);
                break;
            }
            case Packet.RequestDestroy:
            {
                // Destroy the specified network object
                uint uniqueID = reader.ReadUInt32();

                // Remove this object
                if (player.channel.DestroyObject(uniqueID))
                {
                    // Inform all players in the channel that the object should be destroyed
                    BinaryWriter writer = BeginSend(Packet.ResponseDestroy);
                    writer.Write((ushort)1);
                    writer.Write(uniqueID);
                    EndSend(true, player.channel, null);
                }
                break;
            }
            case Packet.RequestLoadLevel:
            {
                // Change the currently loaded level
                if (player.channel.host == player)
                {
                    player.channel.Reset();
                    player.channel.level = reader.ReadString();

                    BinaryWriter writer = BeginSend(Packet.ResponseLoadLevel);
                    writer.Write(string.IsNullOrEmpty(player.channel.level) ? "" : player.channel.level);
                    EndSend(true, player.channel, null);
                }
                break;
            }
            case Packet.RequestSetHost:
            {
                // Transfer the host state from one player to another
                if (player.channel.host == player)
                {
                    TcpPlayer newHost = GetPlayer(reader.ReadInt32());
                    if (newHost != null && newHost.channel == player.channel) SendSetHost(newHost);
                }
                break;
            }
            case Packet.RequestLeaveChannel:
            {
                SendLeaveChannel(player, true);
                break;
            }
            case Packet.RequestCloseChannel:
            {
                player.channel.persistent = false;
                player.channel.closed = true;
                break;
            }
            case Packet.RequestSetPlayerLimit:
            {
                player.channel.playerLimit = reader.ReadUInt16();
                break;
            }
            case Packet.RequestRemoveRFC:
            {
                uint id = reader.ReadUInt32();
                string funcName = ((id & 0xFF) == 0) ? reader.ReadString() : null;
                player.channel.DeleteRFC(id, funcName);
                break;
            }
            case Packet.RequestSetChannelData:
            {
                player.channel.data = reader.ReadString();
                BinaryWriter writer = BeginSend(Packet.ResponseSetChannelData);
                writer.Write(player.channel.data);
                EndSend(true, player.channel, null);
                break;
            }
            }
        }