Esempio n. 1
0
        public void UnspawnNetObjects(NetObject[] netObjects)
        {
            if (State != ServerState.Started && State != ServerState.Debug)
            {
                throw new InvalidOperationException("Cannot unspawn NetObjects: Server not running");
            }
            foreach (NetObject netObject in netObjects)
            {
                NetObjectManager.Instance.Unspawn(netObject.ID);
            }

            if (State == ServerState.Debug)
            {
                return;
            }
            int size = 8                        // header
                       + netObjects.Length * 4; // payload
            var streamWriter = new DataStreamWriter(size, Allocator.Temp);
            {
                streamWriter.WriteInt(Commands.UnspawnNetObjects);
                streamWriter.WriteInt(netObjects.Length);
                foreach (NetObject netObject in netObjects)
                {
                    streamWriter.WriteInt(netObject.ID);
                }

                for (var i = 0; i < _connections.Length; i++)
                {
                    DataStreamWriter writer = _serverDriver.BeginSend(_reliablePipeline, _connections[i]);
                    writer.WriteBytes(streamWriter.AsNativeArray());
                    _serverDriver.EndSend(writer);
                }
            }
        }
Esempio n. 2
0
        public void Send(ushort playerId, string name, byte[] data)
        {
            if (data.Length <= NetworkLinkerPool.MTU - HeaderSize)
            {
                Debug.LogError("MTU以下のサイズのデータは送れません");
                return;
            }

            int hash        = ByteToHash(data);
            var transporter = new LargeBytesTransporter(hash, data);

            int nameByteCount = DataStreamWriter.GetByteSizeStr(name);
            int dataSize      = NetworkLinkerPool.MTU - HeaderSize - 13 - nameByteCount;

            unsafe
            {
                fixed(byte *dataPtr = &data[transporter.pos])
                {
                    using (var writer = new DataStreamWriter(dataSize + 13 + nameByteCount, Allocator.Temp)) {
                        writer.Write((byte)BuiltInPacket.Type.DataTransporter);
                        writer.Write((byte)TransporterType.LargeBytes);
                        writer.Write(hash);
                        writer.Write((byte)FlagDef.Start);
                        writer.Write(name);
                        writer.Write(data.Length);
                        writer.WriteBytes(dataPtr, dataSize);
                        NetworkManager.Brodcast(writer, QosType.Reliable, true);
                    }
                }
            }
            transporter.pos           += dataSize;
            sendTransporterTable[hash] = transporter;
        }
Esempio n. 3
0
        public void DenyGameAction(GameAction gameAction, GameAction.IParameters parameters, int actorNumber,
                                   float triggerTime)
        {
            if (State == ServerState.Debug)
            {
                return;
            }
            if (State != ServerState.Started)
            {
                throw new InvalidOperationException($"Cannot deny {gameAction}: Server not running");
            }

            var streamWriter = new DataStreamWriter(MaxBytesPerMessage, Allocator.Temp);

            streamWriter.WriteInt(Commands.GameAction);
            streamWriter.WriteInt(GameActionManager.Instance.GetID(gameAction));
            streamWriter.WriteInt(actorNumber);
            streamWriter.WriteFloat(triggerTime);
            streamWriter.WriteBool(false); // invalid
            gameAction.SerializeParameters(ref streamWriter, parameters);

            for (var i = 0; i < _connections.Length; i++)
            {
                if (_connections[i].InternalId == actorNumber)
                {
                    DataStreamWriter writer = _serverDriver.BeginSend(_reliablePipeline, _connections[i]);
                    writer.WriteBytes(streamWriter.AsNativeArray());
                    _serverDriver.EndSend(writer);
                }
            }
        }
Esempio n. 4
0
        public void SendRPC(NetBehaviour netBehaviour, string methodName, object[] args)
        {
            if (State == ServerState.Debug)
            {
                return;
            }
            if (State != ServerState.Started)
            {
                throw new InvalidOperationException($"Cannot send rpc {methodName}: Server not running");
            }

            var streamWriter = new DataStreamWriter(MaxBytesPerMessage, Allocator.Temp);
            {
                streamWriter.WriteInt(Commands.NetObjectRPC);
                streamWriter.WriteFloat(Time);
                streamWriter.WriteInt(netBehaviour.NetObject.ID);
                streamWriter.WriteUShort(netBehaviour.NetBehaviourID);
                NetObjectManager.Instance.SerializeRPC(ref streamWriter, netBehaviour, methodName, args);

                for (var i = 0; i < _connections.Length; i++)
                {
                    DataStreamWriter writer = _serverDriver.BeginSend(_reliablePipeline, _connections[i]);
                    writer.WriteBytes(streamWriter.AsNativeArray());
                    _serverDriver.EndSend(writer);
                }
            }
        }
Esempio n. 5
0
            public unsafe void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex)
            {
                var entities    = chunk.GetNativeArray(entityType);
                var connections = chunk.GetNativeArray(connectionType);
                var inBuffers   = chunk.GetBufferAccessor(InBufferType);
                var outBuffers  = chunk.GetBufferAccessor(OutBufferType);

                for (int i = 0; i < inBuffers.Length; i++)
                {
                    if (driver.GetConnectionState(connections[i].Value) != NetworkConnection.State.Connected)
                    {
                        continue;
                    }

                    var parameters = new RpcExecutor.Parameters
                    {
                        Reader        = inBuffers[i].AsDataStreamReader(),
                        CommandBuffer = commandBuffer,
                        Connection    = entities[i],
                        JobIndex      = chunkIndex
                    };

#if UNITY_EDITOR || DEVELOPMENT_BUILD
                    RpcMS2(parameters.Reader.Length);
#endif
                    while (parameters.Reader.GetBytesRead() < parameters.Reader.Length)
                    {
                        var rpcIndex = parameters.Reader.ReadUShort();
                        if (rpcIndex >= execute.Length)
                        {
                        }
                        else
                        {
                            //TODO 安卓调用闪退
                            execute[rpcIndex].Execute.Ptr.Invoke(ref parameters);
                        }
                    }

                    inBuffers[i].Clear();

                    var sendBuf = outBuffers[i];
                    if (sendBuf.Length > 0)
                    {
                        DataStreamWriter tmp = driver.BeginSend(reliablePipeline, connections[i].Value);
                        if (!tmp.IsCreated)
                        {
                            return;
                        }
                        tmp.WriteBytes((byte *)sendBuf.GetUnsafePtr(), sendBuf.Length);

#if UNITY_EDITOR || DEVELOPMENT_BUILD
                        RpcMS1(tmp.Length);
#endif
                        driver.EndSend(tmp);
                        sendBuf.Clear();
                    }
                }
            }
Esempio n. 6
0
        protected override void SendFragmentData()
        {
            if (sendTransporterTable == null)
            {
                return;
            }

            removeTransporterList.Clear();

            foreach (var pair in sendTransporterTable)
            {
                var transporter = pair.Value;

                int sendAmount = 0;
                while (sendAmount < SendBytePerFrame)
                {
                    FlagDef flag     = FlagDef.None;
                    int     dataSize = NetworkLinkerPool.MTU - HeaderSize - 7;

                    if (transporter.pos + dataSize > transporter.data.Length)
                    {
                        flag     = FlagDef.Complete;
                        dataSize = transporter.data.Length - transporter.pos;
                        //Debug.Log ("Complete");
                    }
                    unsafe
                    {
                        fixed(byte *dataPtr = &transporter.data[transporter.pos])
                        {
                            using (var writer = new DataStreamWriter(dataSize + 7, Allocator.Temp)) {
                                writer.Write((byte)BuiltInPacket.Type.DataTransporter);
                                writer.Write((byte)TransporterType.LargeBytes);
                                writer.Write(transporter.hash);
                                writer.Write((byte)flag);
                                writer.WriteBytes(dataPtr, dataSize);
                                NetworkManager.Brodcast(writer, QosType.Reliable, true);
                            }
                        }
                    }
                    transporter.pos += dataSize;
                    sendAmount      += dataSize;
                    if (flag == FlagDef.Complete)
                    {
                        removeTransporterList.Add(transporter.hash);
                        ExeceOnSendComplete(transporter, true);
                        break;
                    }
                }
                //Debug.Log ("SendFragmentData Hash=" + transporter.hash + ", Pos" + transporter.pos);
            }


            foreach (int hash in removeTransporterList)
            {
                sendTransporterTable.Remove(hash);
            }
        }
Esempio n. 7
0
 public void Serialize(DataStreamWriter writer)
 {
     writer.Write(Command.LengthInBytes);
     unsafe
     {
         fixed(byte *b = &Command.buffer.byte0000)
         {
             writer.WriteBytes(b, Command.LengthInBytes);
         }
     }
 }
Esempio n. 8
0
 public void Serialize(DataStreamWriter writer)
 {
     writer.Write(MapName.LengthInBytes);
     unsafe
     {
         fixed(byte *b = &MapName.buffer.byte0000)
         {
             writer.WriteBytes(b, MapName.LengthInBytes);
         }
     }
 }
        public IEnumerator ServerAndClient_PingPong_Successfully()
        {
            SetupServerAndClientAndConnectThem(0);

            //send data from client
            DataStreamWriter m_OutStream = client_driver.BeginSend(clientToServerConnection);

            m_OutStream.Clear();
            m_OutStream.WriteBytes(new NativeArray <byte>(SharedConstants.ping, Allocator.Temp));
            client_driver.EndSend(m_OutStream);
            client_driver.ScheduleFlushSend(default).Complete();
Esempio n. 10
0
 public void Serialize(DataStreamWriter writer)
 {
     GameDebug.Assert(writer.Capacity - writer.Length > Message.LengthInBytes * 2, "Chat message too large (writer=" + (writer.Capacity - writer.Length) + " msg=" + Message.LengthInBytes * 2);
     writer.Write(Message.LengthInBytes);
     unsafe
     {
         fixed(byte *b = &Message.buffer.byte0000)
         {
             writer.WriteBytes(b, Message.LengthInBytes);
         }
     }
 }
Esempio n. 11
0
 protected DataStreamWriter CreateSendPacket(DataStreamWriter data, QosType qos, ushort targetId, ushort senderId)
 {
     unsafe {
         byte * dataPtr    = DataStreamUnsafeUtility.GetUnsafeReadOnlyPtr(data);
         ushort dataLength = (ushort)data.Length;
         var    writer     = new DataStreamWriter(data.Length + 4, Allocator.Temp);
         writer.Write(targetId);
         writer.Write(senderId);
         writer.WriteBytes(dataPtr, data.Length);
         return(writer);
     }
 }
Esempio n. 12
0
 //TODO できればScene単位でパケットをまとめて、type(1byte) sceneHash(4byte)の5byteのデータを削減したい
 private void CreateRpcPacket(ref DataStreamWriter writer, ref DataStreamWriter rpcPacket, byte componentIndex, byte methodId)
 {
     unsafe {
         byte *dataPtr = DataStreamUnsafeUtility.GetUnsafeReadOnlyPtr(rpcPacket);
         writer.Write((byte)BuiltInPacket.Type.BehaviourRpc);
         writer.Write(sceneHash);
         writer.Write(netId);
         writer.Write(componentIndex);
         writer.Write(methodId);
         writer.WriteBytes(dataPtr, rpcPacket.Length);
     }
 }
Esempio n. 13
0
    public unsafe void SendPacket(ref SoakStatisticsPoint stats, ref SoakJobContext ctx)
    {
        var message = new SoakMessage
        {
            id   = ctx.FrameId,
            time = fixedTime,

            sequence = ctx.NextSequenceNumber++,
            length   = packetData.Length
        };

        streamWriter.Clear();

        streamWriter.WriteBytes(message.data, SoakMessage.HeaderLength);
        streamWriter.WriteBytes((byte *)packetData.GetUnsafeReadOnlyPtr(), packetData.Length);

        stats.SentBytes += connection[0].Send(driver, streamWriter);
        stats.SentPackets++;

        pendingSoaks[message.id % pendingSoaks.Length] = message;
    }
Esempio n. 14
0
 public void Serialize(DataStreamWriter writer)
 {
     writer.Write(TeamId);
     writer.Write(CharacterType);
     writer.Write(PlayerName.LengthInBytes);
     unsafe
     {
         fixed(byte *b = &PlayerName.buffer.byte0000)
         {
             writer.WriteBytes(b, PlayerName.LengthInBytes);
         }
     }
 }
Esempio n. 15
0
 protected override void Serialize(ref DataStreamWriter writer, byte dirtyMask)
 {
     if (IsDirtyAt(dirtyMask, 0))
     {
         writer.WriteInt(_paramBytes.Length);
         writer.WriteBytes(new NativeArray <byte>(_paramBytes, Allocator.Temp));
     }
     if (IsDirtyAt(dirtyMask, 1))
     {
         writer.WriteInt(_currentStateHash);
         writer.WriteFloat(_currentEnterTime);
     }
 }
Esempio n. 16
0
    public void Execute(int i)
    {
        SoakMessage inbound  = default(SoakMessage);
        SoakMessage outbound = default(SoakMessage);

        if (connections[i].Connection.IsCreated)
        {
            var ctx = connections[i];
            DataStreamReader  strm;
            NetworkEvent.Type cmd;
            bool close = false;
            while ((cmd = driver.PopEventForConnection(ctx.Connection, out strm)) != NetworkEvent.Type.Empty)
            {
                if (cmd == NetworkEvent.Type.Data)
                {
                    var readerCtx = default(DataStreamReader.Context);
                    unsafe
                    {
                        if (!strm.IsCreated)
                        {
                            Debug.Log("wtf not created.");
                        }
                        strm.ReadBytes(ref readerCtx, inbound.data, strm.Length);
                        Assert.AreEqual(strm.Length, inbound.length + SoakMessage.HeaderLength);

                        outbound.id       = inbound.id;
                        outbound.sequence = ctx.NextSequenceId++;

                        var soakData = new DataStreamWriter(SoakMessage.HeaderLength, Allocator.Temp);
                        soakData.WriteBytes(outbound.data, SoakMessage.HeaderLength);

                        driver.Send(connections[i].Connection, soakData);
                        soakData.Dispose();
                    }
                }
                else if (cmd == NetworkEvent.Type.Disconnect)
                {
                    close = true;
                }
            }

            if (close)
            {
                ctx.Connection     = default(NetworkConnection);
                ctx.NextSequenceId = -1;
            }
            connections[i] = ctx;
        }
    }
Esempio n. 17
0
        public unsafe void Execute(Entity entity, int index, ref NetworkStreamConnection connection)
        {
            if (!connection.Value.IsCreated)
            {
                return;
            }
            var buffer = rpcBufferFromEntity[entity];

            if (buffer.Length > 0)
            {
                DataStreamWriter tmp = new DataStreamWriter(buffer.Length, Allocator.Temp);
                tmp.WriteBytes((byte *)buffer.GetUnsafePtr(), buffer.Length);
                driver.Send(reliablePipeline, connection.Value, tmp);
                buffer.Clear();
            }
        }
Esempio n. 18
0
            static unsafe void WriteString(DataStreamWriter writer, string value)
            {
                s_Encoder = s_Encoder ?? s_Encoding.GetEncoder();
                var buffer = new byte[byte.MaxValue];
                var chars  = value.ToCharArray();

                s_Encoder.Convert(chars, 0, chars.Length, buffer, 0, byte.MaxValue, true, out var charsUsed, out var bytesUsed, out var completed);
                Debug.Assert(bytesUsed <= byte.MaxValue);

                writer.Write((byte)bytesUsed);

                fixed(byte *bufferPtr = &buffer[0])
                {
                    writer.WriteBytes(bufferPtr, bytesUsed);
                }
            }
Esempio n. 19
0
 protected DataStreamWriter CreateSendPacket(DataStreamWriter data, QosType qos, NativeList <ushort> targetIdList, ushort senderId)
 {
     unsafe {
         byte * dataPtr    = DataStreamUnsafeUtility.GetUnsafeReadOnlyPtr(data);
         ushort dataLength = (ushort)data.Length;
         var    writer     = new DataStreamWriter(data.Length + 6 + targetIdList.Length * 2, Allocator.Temp);
         writer.Write(ushort.MaxValue - 1);
         writer.Write(senderId);
         writer.Write((ushort)targetIdList.Length);
         for (int i = 0; i < targetIdList.Length; i++)
         {
             writer.Write(targetIdList[i]);
         }
         writer.WriteBytes(dataPtr, data.Length);
         return(writer);
     }
 }
Esempio n. 20
0
        unsafe public static void WriteString(this DataStreamWriter writer, string value, Encoding encoding)
        {
            var encoder = encoding.GetEncoder();

            var  chars = value.ToCharArray();
            int  charsUsed, bytesUsed;
            bool completed;

            encoder.Convert(chars, 0, chars.Length, buffer, 0, byte.MaxValue, true, out charsUsed, out bytesUsed, out completed);
            Debug.Assert(bytesUsed <= byte.MaxValue);

            writer.Write((byte)bytesUsed);
            fixed(byte *buf = buffer)
            {
                writer.WriteBytes(buf, bytesUsed);
            }
        }
Esempio n. 21
0
        public void CreateStreamWithSourceByteArray()
        {
            byte[] byteArray = new byte[100];
            byteArray[0] = (byte)'a';
            byteArray[1] = (byte)'b';
            byteArray[2] = (byte)'c';

            DataStreamWriter dataStream;

            dataStream = new DataStreamWriter(byteArray.Length, Allocator.Temp);
            dataStream.WriteBytes(new NativeArray <byte>(byteArray, Allocator.Temp));
            var reader = new DataStreamReader(dataStream.AsNativeArray());

            for (int i = 0; i < byteArray.Length; ++i)
            {
                Assert.AreEqual(byteArray[i], reader.ReadByte());
            }
        }
Esempio n. 22
0
        public void CreateStreamWithPartOfSourceByteArray()
        {
            byte[] byteArray =
            {
                (byte)'s', (byte)'o', (byte)'m', (byte)'e',
                (byte)' ', (byte)'d', (byte)'a', (byte)'t', (byte)'a'
            };

            DataStreamWriter dataStream;

            dataStream = new DataStreamWriter(4, Allocator.Temp);
            dataStream.WriteBytes(new NativeArray <byte>(byteArray, Allocator.Temp).GetSubArray(0, 4));
            Assert.AreEqual(dataStream.Length, 4);
            var reader = new DataStreamReader(dataStream.AsNativeArray());

            for (int i = 0; i < dataStream.Length; ++i)
            {
                Assert.AreEqual(byteArray[i], reader.ReadByte());
            }

            Assert.Throws <ArgumentOutOfRangeException>(() => { reader.ReadByte(); });
        }
Esempio n. 23
0
        //private byte[] buffer = null;

        public async void Send(ushort playerId, string fileName, System.IO.FileStream fileStream)
        {
            if (fileStream.Length <= NetworkLinkerPool.MTU - HeaderSize)
            {
                Debug.LogError("MTU以下のサイズのデータは送れません");
                return;
            }

            int hash        = FileToHash(fileStream);
            var transporter = new FileTransporter(hash, fileName, fileStream, SendBytePerFrame, 0);

            int nameByteCount = DataStreamWriter.GetByteSizeStr(fileName);
            int dataSize      = NetworkLinkerPool.MTU - HeaderSize - 15 - nameByteCount;

            fileStream.Seek(0, SeekOrigin.Begin);
            int readSize = await fileStream.ReadAsync(transporter.buffer, 0, dataSize);

            //Debug.Log ("Start : " + string.Join ("", transporter.buffer));

            unsafe
            {
                fixed(byte *dataPtr = transporter.buffer)
                {
                    using (var writer = new DataStreamWriter(dataSize + 15 + nameByteCount, Allocator.Temp)) {
                        writer.Write((byte)BuiltInPacket.Type.DataTransporter);
                        writer.Write((byte)TransporterType.File);
                        writer.Write(hash);
                        writer.Write((byte)FlagDef.Start);
                        writer.Write(fileName);
                        writer.Write((int)fileStream.Length);
                        writer.Write((ushort)dataSize);
                        writer.WriteBytes(dataPtr, dataSize);
                        NetworkManager.Brodcast(writer, QosType.Reliable, true);
                    }
                }
            }
            transporter.pos           += dataSize;
            sendTransporterTable[hash] = transporter;
        }
Esempio n. 24
0
        public void CreateStreamWithPartOfSourceByteArray()
        {
            byte[] byteArray =
            {
                (byte)'s', (byte)'o', (byte)'m', (byte)'e',
                (byte)' ', (byte)'d', (byte)'a', (byte)'t', (byte)'a'
            };

            DataStreamWriter dataStream;

            dataStream = new DataStreamWriter(4, Allocator.Temp);
            dataStream.WriteBytes(new NativeArray <byte>(byteArray, Allocator.Temp).GetSubArray(0, 4));
            Assert.AreEqual(dataStream.Length, 4);
            var reader = new DataStreamReader(dataStream.AsNativeArray());

            for (int i = 0; i < dataStream.Length; ++i)
            {
                Assert.AreEqual(byteArray[i], reader.ReadByte());
            }

            LogAssert.Expect(LogType.Error, "Trying to read 1 bytes from a stream where only 0 are available");
            Assert.AreEqual(0, reader.ReadByte());
        }
Esempio n. 25
0
            public void Execute()
            {
                var reader = new DataStreamReader(packetChunks, 0, packetChunks.Length);
                var ctx    = default(DataStreamReader.Context);

                for (int i = 0; i < packetLengths.Length; i++)
                {
                    ushort packetDataLen = packetLengths[i];
                    if (packetDataLen == 0)
                    {
                        continue;
                    }
                    var packet = reader.ReadChunk(ref ctx, packetDataLen);

                    using (var temp = new DataStreamWriter(packetDataLen, Allocator.Temp)) {
                        unsafe {
                            byte *packetPtr = packet.GetUnsafeReadOnlyPtr();
                            temp.WriteBytes(packetPtr, packetDataLen);
                        }
                        //Debug.Log ("SendUnreliableChunksJob ChunkIndex = " + i + ", packetDataLen=" + packetDataLen);
                        connection.Send(driver, temp);
                    }
                }
            }
Esempio n. 26
0
        public void SendNetObjectsUpdate()
        {
            if (State == ServerState.Debug)
            {
                return;
            }
            if (State != ServerState.Started)
            {
                throw new InvalidOperationException("Cannot set NetObject update: Server not running");
            }

            Profiler.BeginSample("NetObject Update");
            NetObject[] netObjects = NetObjectManager.Instance.NetObjects;

            const int headerSizeInBytes = 8;
            var       streamWriter      = new DataStreamWriter(MaxBytesPerMessage, Allocator.Temp);
            var       objectWriter      = new DataStreamWriter(MaxBytesPerMessage - headerSizeInBytes, Allocator.Temp);
            var       objectIndex       = 0;

            // compose new message if objects left to send or serialize
            while (objectIndex < netObjects.Length || objectWriter.Length > 0)
            {
                // header
                streamWriter.Clear();
                streamWriter.WriteInt(Commands.UpdateNetObjects);
                DataStreamWriter objectCountWriter = streamWriter;
                streamWriter.WriteInt(0);

                // add items as long as they fit
                var objectsInMessage = 0;
                while (streamWriter.Length + objectWriter.Length <= MaxBytesPerMessage)
                {
                    if (objectWriter.Length > 0)
                    {
                        streamWriter.WriteBytes(objectWriter.AsNativeArray());
                        objectWriter.Clear();
                        objectsInMessage++;
                    }

                    // next object. Write if dirty
                    if (objectIndex < netObjects.Length)
                    {
                        NetObject netObject = netObjects[objectIndex++];
                        if (netObject.IsDirty)
                        {
                            WriteNetObject(netObject, ref objectWriter);
                        }
                    }
                    else
                    {
                        break;
                    }
                }

                objectCountWriter.WriteInt(objectsInMessage);

                // message complete. Send if payload exists
                if (objectsInMessage == 0)
                {
                    break;
                }
                for (var connectionIndex = 0; connectionIndex < _connections.Length; connectionIndex++)
                {
                    DataStreamWriter writer = _serverDriver.BeginSend(_reliablePipeline, _connections[connectionIndex]);
                    writer.WriteBytes(streamWriter.AsNativeArray());
                    _serverDriver.EndSend(writer);
                }
            }

            Profiler.EndSample();
        }
Esempio n. 27
0
        private void SendNetAssetUpdate(bool fullLoad, NativeList <NetworkConnection> connections)
        {
            if (State == ServerState.Debug)
            {
                return;
            }
            if (State != ServerState.Started)
            {
                throw new InvalidOperationException("Cannot send NetAsset update: Server not running");
            }
            Profiler.BeginSample("NetAsset Update");

            NetAsset[] netAssets         = NetAssetManager.Instance.GetAll();
            const int  headerSizeInBytes = 8;
            var        streamWriter      = new DataStreamWriter(MaxBytesPerMessage, Allocator.Temp);
            var        assetWriter       = new DataStreamWriter(MaxBytesPerMessage - headerSizeInBytes, Allocator.Temp);
            var        assetIndex        = 0;

            // compose new message if assets left to send or serialize
            while (assetIndex < netAssets.Length || assetWriter.Length > 0)
            {
                streamWriter.Clear();

                // write header
                streamWriter.WriteInt(Commands.UpdateNetAssets);
                DataStreamWriter netAssetCountWriter = streamWriter;
                streamWriter.WriteInt(0);

                // add assets as long as they fit
                var assetsInMessage = 0;
                while (streamWriter.Length + assetWriter.Length <= MaxBytesPerMessage)
                {
                    if (assetWriter.Length > 0)
                    {
                        streamWriter.WriteBytes(assetWriter.AsNativeArray());
                        assetWriter.Clear();
                        assetsInMessage++;
                    }

                    // next asset. Serialize if dirty
                    if (assetIndex < netAssets.Length)
                    {
                        NetAsset netAsset = netAssets[assetIndex++];
                        if (fullLoad || netAsset.IsDirty())
                        {
                            SerializeNetAsset(netAsset, ref assetWriter, fullLoad);
                        }
                    }
                    else
                    {
                        break;
                    }
                }

                netAssetCountWriter.WriteInt(assetsInMessage);

                // message complete. Send if payload exists
                if (assetsInMessage == 0)
                {
                    break;
                }
                for (var connectionIndex = 0; connectionIndex < connections.Length; connectionIndex++)
                {
                    DataStreamWriter writer = _serverDriver.BeginSend(_reliablePipeline, connections[connectionIndex]);
                    writer.WriteBytes(streamWriter.AsNativeArray());
                    _serverDriver.EndSend(writer);
                }
            }

            Profiler.EndSample();
        }
Esempio n. 28
0
        private void SendSpawnMessage(NetObject[] netObjects, NativeList <NetworkConnection> connections)
        {
            if (connections.Length == 0)
            {
                return;
            }
            AssertActive();
            const int headerSizeInBytes = 8;
            var       streamWriter      = new DataStreamWriter(MaxBytesPerMessage, Allocator.Temp);
            var       objectWriter      = new DataStreamWriter(MaxBytesPerMessage - headerSizeInBytes, Allocator.Temp);
            var       objectIndex       = 0;

            // compose new message if objects left to send or copy to message stream
            while (objectIndex < netObjects.Length || objectWriter.Length > 0)
            {
                streamWriter.Clear();

                // write header
                streamWriter.WriteInt(Commands.SpawnNetObjects);
                DataStreamWriter objectCountWriter = streamWriter;
                streamWriter.WriteInt(0);

                // copy data over to message stream and write to object stream
                var objectsInMessage = 0;
                while (streamWriter.Length + objectWriter.Length <= MaxBytesPerMessage)
                {
                    if (objectWriter.Length > 0)
                    {
                        streamWriter.WriteBytes(objectWriter.AsNativeArray());
                        objectWriter.Clear();
                        objectsInMessage++;
                    }

                    if (objectIndex < netObjects.Length)
                    {
                        NetObject netObject = netObjects[objectIndex++];
                        objectWriter.WriteInt(netObject.ID);
                        objectWriter.WriteUShort(netObject.PrefabIndex);
                        objectWriter.WriteInt(netObject.OwnerActorNumber);
                        objectWriter.WriteVector3(netObject.transform.position);
                        objectWriter.WriteQuaternion(netObject.transform.rotation);
                        objectWriter.WriteInt(netObject.gameObject.scene.buildIndex);
                        DataStreamWriter objectSizeWriter = objectWriter;
                        objectWriter.WriteInt(0);
                        int length = objectWriter.Length;
                        netObject.Serialize(ref objectWriter, true);
                        objectSizeWriter.WriteInt(objectWriter.Length - length);
                    }
                    else
                    {
                        break;
                    }
                }

                objectCountWriter.WriteInt(objectsInMessage);

                // message complete. Send if payload present
                if (objectsInMessage == 0)
                {
                    return;
                }
                for (var connectionIndex = 0; connectionIndex < connections.Length; connectionIndex++)
                {
                    DataStreamWriter writer = _serverDriver.BeginSend(_reliablePipeline, connections[connectionIndex]);
                    writer.WriteBytes(streamWriter.AsNativeArray());
                    _serverDriver.EndSend(writer);
                }
            }
        }
Esempio n. 29
0
        public void SendBatchedNetObjectsUpdate()
        {
            if (State == ClientState.Debug)
            {
                return;
            }
            if (State != ClientState.Connected)
            {
                Debug.LogWarning($"Cannot send messages in client state {State}");
                return;
            }

            if (IsHost)
            {
                return;
            }

            NetObject[] netObjects = NetObjectManager.Instance.NetObjects;

            const int headerSizeInBytes = 8;
            var       streamWriter      = new DataStreamWriter(MaxBytesPerMessage, Allocator.Temp);
            var       objectWriter      = new DataStreamWriter(MaxBytesPerMessage - headerSizeInBytes, Allocator.Temp);
            var       objectIndex       = 0;

            // compose new message if objects left to send or serialize
            while (objectIndex < netObjects.Length || objectWriter.Length > 0)
            {
                // header
                streamWriter.Clear();
                streamWriter.WriteInt(Commands.UpdateNetObjects);
                DataStreamWriter objectCountWriter = streamWriter;
                streamWriter.WriteInt(0);

                // add items as long as they fit
                var objectsInMessage = 0;
                while (streamWriter.Length + objectWriter.Length <= MaxBytesPerMessage)
                {
                    if (objectWriter.Length > 0)
                    {
                        streamWriter.WriteBytes(objectWriter.AsNativeArray());
                        objectWriter.Clear();
                        objectsInMessage++;
                    }

                    // next object. Write if dirty and controlled by this client
                    if (objectIndex < netObjects.Length)
                    {
                        NetObject netObject = netObjects[objectIndex++];
                        if (netObject.IsDirty && netObject.IsMine)
                        {
                            WriteNetObject(netObject, ref objectWriter);
                        }
                    }
                    else
                    {
                        break;
                    }
                }

                objectCountWriter.WriteInt(objectsInMessage);

                // message complete. Send if payload exists
                if (objectsInMessage > 0)
                {
                    DataStreamWriter writer = _clientDriver.BeginSend(_reliablePipeline, _clientToServerConnection);
                    writer.WriteBytes(streamWriter.AsNativeArray());
                    _clientDriver.EndSend(writer);
                    DataSent?.Invoke(writer.Length);
                }
            }
        }
Esempio n. 30
0
        protected override void OnUpdate()
        {
            if (!m_ConnectionWithoutSnapshotBufferGroup.IsEmptyIgnoreFilter)
            {
                using (var entities = m_ConnectionWithoutSnapshotBufferGroup.ToEntityArray(Allocator.TempJob))
                {
                    foreach (var entity in entities)
                    {
                        var buffer = EntityManager.AddBuffer <ClientSnapshotBuffer>(entity);
                        buffer.ResizeUninitialized(1200);
                        buffer.Clear();
                    }
                }
            }

            using (var deleteKeys = new NativeList <Entity>(8, Allocator.Temp))
            {
                foreach (var kvp in m_SerializeLookup)
                {
                    if (!EntityManager.Exists(kvp.Key))
                    {
                        deleteKeys.Add(kvp.Key);
                    }
                }

                foreach (var key in deleteKeys)
                {
                    m_SerializeLookup[key].Data.Dispose();
                    m_SerializeLookup.Remove(key);
                }
            }

            var connectionEntities           = m_ConnectionGroup.ToEntityArray(Allocator.TempJob);
            var networkStreamConnectionArray = m_ConnectionGroup.ToComponentDataArray <NetworkStreamConnection>(Allocator.TempJob);
            var ackComponentArray            = m_ConnectionGroup.ToComponentDataArray <NetworkSnapshotAckComponent>(Allocator.TempJob);

            foreach (var entity in connectionEntities)
            {
                if (m_SerializeLookup.ContainsKey(entity))
                {
                    continue;
                }

                m_SerializeLookup[entity] = new ReferencableSerializeClientData
                {
                    Data = new SerializeClientData(Allocator.Persistent)
                };
            }

            m_CreateSnapshotSystem.CreateSnapshot(m_ServerSimulationSystemGroup.ServerTick, m_SerializeLookup);

            var localTime = NetworkTimeSystem.TimestampMS;

            for (var ent = 0; ent < connectionEntities.Length; ent++)
            {
                var entity     = connectionEntities[ent];
                var connection = networkStreamConnectionArray[ent];
                var ack        = ackComponentArray[ent];

                var buffer = EntityManager.GetBuffer <ClientSnapshotBuffer>(entity);

                m_DataStream.Clear();
                m_DataStream.Write((byte)NetworkStreamProtocol.Snapshot);
                m_DataStream.Write(localTime);
                var returnTime = ack.LastReceivedRemoteTime;
                if (returnTime != 0)
                {
                    returnTime -= (localTime - ack.LastReceiveTimestamp);
                }
                m_DataStream.Write(returnTime);
                m_DataStream.Write(ack.ServerCommandAge);
                m_DataStream.Write(byte.MaxValue);
                m_DataStream.Write(m_ServerSimulationSystemGroup.ServerTick);

                Profiler.BeginSample("Compressing");
                var compressed       = UnsafeUtility.Malloc(LZ4Codec.MaximumOutputSize(buffer.Length), UnsafeUtility.AlignOf <byte>(), Allocator.Temp);
                var compressedLength = LZ4Codec.MaximumOutputSize(buffer.Length);
                {
                    var encoder = LZ4Level.L04_HC;                     // default encoder
                    //encoder = LZ4Level.L12_MAX;

                    var size = LZ4Codec.Encode((byte *)buffer.GetUnsafePtr(), buffer.Length, (byte *)compressed, compressedLength, encoder);
                    Profiler.EndSample();
                    m_DataStream.Write(size);
                    m_DataStream.Write(buffer.Length);

                    if (size > 1000)
                    {
                        Debug.Log($"s={size} b={buffer.Length}");
                    }

                    m_DataStream.WriteBytes((byte *)compressed, size);
                }
                UnsafeUtility.Free(compressed, Allocator.Temp);

                m_ReceiveSystem.Driver.Send(m_ReceiveSystem.ReliablePipeline, connection.Value, m_DataStream);
            }

            connectionEntities.Dispose();
            networkStreamConnectionArray.Dispose();
            ackComponentArray.Dispose();
        }