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); } } }
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); } } }
/// <summary> /// 把输入写入发送buffer中 /// </summary> /// <param name="buffer"></param> /// <param name="data"></param> /// <exception cref="InvalidOperationException"></exception> public unsafe void Schedule(DynamicBuffer <OutgoingRpcDataStreamBufferComponent> buffer, TActionRequest data) { TActionSerializer serializer = default; // 1字节:Rpc协议头 2字节:rpcIndex DataStreamWriter writer = new DataStreamWriter(UnsafeUtility.SizeOf <TActionRequest>() + 1 + 2, Allocator.Temp); if (buffer.Length == 0) { writer.WriteByte((byte)NetworkStreamProtocol.Rpc); } if (!rpcTypeHashToIndex.TryGetValue(rpcType, out var rpcIndex)) { throw new InvalidOperationException("Could not find RPC index for type"); } writer.WriteUShort((ushort)rpcIndex); serializer.Serialize(ref writer, data); // 把DataStreamWriter内存数据Copy到Buffer中 var prevLen = buffer.Length; buffer.ResizeUninitialized(buffer.Length + writer.Length); byte *ptr = (byte *)buffer.GetUnsafePtr(); ptr += prevLen; UnsafeUtility.MemCpy(ptr, writer.AsNativeArray().GetUnsafeReadOnlyPtr(), writer.Length); }
public void ReadWritePackedUIntWithDeferred() { using (var compressionModel = new NetworkCompressionModel(Allocator.Persistent)) { var dataStream = new DataStreamWriter(300 * 4, Allocator.Temp); uint base_val = 2000; uint count = 277; var def = dataStream; dataStream.WriteInt((int)0); for (uint i = 0; i < count; ++i) { dataStream.WritePackedUInt(base_val + i, compressionModel); } dataStream.Flush(); def.WriteInt(1979); def = dataStream; dataStream.WriteInt((int)0); def.WriteInt(1979); dataStream.Flush(); var reader = new DataStreamReader(dataStream.AsNativeArray()); Assert.AreEqual(1979, reader.ReadInt()); for (uint i = 0; i < count; ++i) { var val = reader.ReadPackedUInt(compressionModel); Assert.AreEqual(base_val + i, val); } Assert.AreEqual(1979, reader.ReadInt()); } }
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); } } }
private byte[] SerializeParams() { var writer = new DataStreamWriter(1000, Allocator.Temp); for (var i = 0; i < _animator.parameterCount; i++) { switch (_animatorControllerParameters[i].type) { case AnimatorControllerParameterType.Float: writer.WriteFloat(_animator.GetFloat(_animatorControllerParameters[i].nameHash)); break; case AnimatorControllerParameterType.Int: writer.WriteInt(_animator.GetInteger(_animatorControllerParameters[i].nameHash)); break; case AnimatorControllerParameterType.Bool: case AnimatorControllerParameterType.Trigger: writer.WriteBool(_animator.GetBool(_animatorControllerParameters[i].nameHash)); break; default: throw new ArgumentOutOfRangeException(); } } return(writer.AsNativeArray().ToArray()); }
public void ReadIntoExistingByteArray() { var byteArray = new NativeArray <byte>(100, Allocator.Temp); DataStreamWriter dataStream; dataStream = new DataStreamWriter(3, Allocator.Temp); { dataStream.WriteByte((byte)'a'); dataStream.WriteByte((byte)'b'); dataStream.WriteByte((byte)'c'); var reader = new DataStreamReader(dataStream.AsNativeArray()); reader.ReadBytes(byteArray.GetSubArray(0, dataStream.Length)); reader = new DataStreamReader(dataStream.AsNativeArray()); for (int i = 0; i < reader.Length; ++i) { Assert.AreEqual(byteArray[i], reader.ReadByte()); } } }
public unsafe void Schedule(DynamicBuffer <OutgoingRpcDataStreamBufferComponent> buffer, ComponentDataFromEntity <GhostComponent> ghostFromEntity, TActionRequest data) { var serializer = default(TActionSerializer); var serializerState = new RpcSerializerState { GhostFromEntity = ghostFromEntity }; var msgHeaderLen = dynamicAssemblyList ? 10 : 4; int maxSize = UnsafeUtility.SizeOf <TActionRequest>() + msgHeaderLen + 1; int rpcIndex = 0; if (!dynamicAssemblyList && !rpcTypeHashToIndex.TryGetValue(rpcType, out rpcIndex)) { throw new InvalidOperationException("Could not find RPC index for type"); } while (true) { DataStreamWriter writer = new DataStreamWriter(maxSize, Allocator.Temp); int packetHeaderLen = 0; if (buffer.Length == 0) { packetHeaderLen = 1; writer.WriteByte((byte)NetworkStreamProtocol.Rpc); } if (dynamicAssemblyList) { writer.WriteULong(rpcType); } else { writer.WriteUShort((ushort)rpcIndex); } var lenWriter = writer; writer.WriteUShort((ushort)0); serializer.Serialize(ref writer, serializerState, data); if (!writer.HasFailedWrites) { if (writer.Length - packetHeaderLen > ushort.MaxValue) { throw new InvalidOperationException("RPC is too large to serialize"); } lenWriter.WriteUShort((ushort)(writer.Length - msgHeaderLen - packetHeaderLen)); var prevLen = buffer.Length; buffer.ResizeUninitialized(buffer.Length + writer.Length); byte *ptr = (byte *)buffer.GetUnsafePtr(); ptr += prevLen; UnsafeUtility.MemCpy(ptr, writer.AsNativeArray().GetUnsafeReadOnlyPtr(), writer.Length); break; } maxSize *= 2; } }
public void ReadWriteString() { var dataStream = new DataStreamWriter(300 * 4, Allocator.Temp); NativeString64 src = new NativeString64("This is a string"); dataStream.WriteString(src); //Assert.AreEqual(src.LengthInBytes+2, dataStream.Length); var reader = new DataStreamReader(dataStream.AsNativeArray()); var dst = reader.ReadString(); Assert.AreEqual(src, dst); }
public void ReadingDataFromStreamWithSliceOffset() { var dataStream = new DataStreamWriter(100, Allocator.Temp); dataStream.WriteByte((byte)'a'); dataStream.WriteByte((byte)'b'); dataStream.WriteByte((byte)'c'); dataStream.WriteByte((byte)'d'); dataStream.WriteByte((byte)'e'); dataStream.WriteByte((byte)'f'); var reader = new DataStreamReader(dataStream.AsNativeArray().GetSubArray(3, 3)); Assert.AreEqual('d', reader.ReadByte()); Assert.AreEqual('e', reader.ReadByte()); Assert.AreEqual('f', reader.ReadByte()); }
public void ReadWritePackedStringDelta() { var dataStream = new DataStreamWriter(300 * 4, Allocator.Temp); var compressionModel = new NetworkCompressionModel(Allocator.Temp); NativeString64 src = new NativeString64("This is a string"); NativeString64 baseline = new NativeString64("This is another string"); dataStream.WritePackedStringDelta(src, baseline, compressionModel); dataStream.Flush(); //Assert.LessOrEqual(dataStream.Length, src.LengthInBytes+2); var reader = new DataStreamReader(dataStream.AsNativeArray()); var dst = reader.ReadPackedStringDelta(baseline, compressionModel); Assert.AreEqual(src, dst); }
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()); } }
public static unsafe void SendProtocolVersion(DynamicBuffer <OutgoingRpcDataStreamBufferComponent> buffer, NetworkProtocolVersion version) { bool dynamicAssemblyList = (version.RpcCollectionVersion == 0); int msgHeaderLen = dynamicAssemblyList ? 10 : 4; DataStreamWriter writer = new DataStreamWriter(UnsafeUtility.SizeOf <NetworkProtocolVersion>() + msgHeaderLen + 1, Allocator.Temp); #if ENABLE_UNITY_COLLECTIONS_CHECKS if (buffer.Length != 0) { throw new InvalidOperationException("Protocol version must be the very first RPC sent"); } #endif writer.WriteByte((byte)NetworkStreamProtocol.Rpc); if (dynamicAssemblyList) { writer.WriteULong(0); } else { writer.WriteUShort(ushort.MaxValue); } var lenWriter = writer; writer.WriteUShort((ushort)0); writer.WriteInt(version.NetCodeVersion); writer.WriteInt(version.GameVersion); if (dynamicAssemblyList) { writer.WriteULong(0); writer.WriteULong(0); } else { writer.WriteULong(version.RpcCollectionVersion); writer.WriteULong(version.ComponentCollectionVersion); } lenWriter.WriteUShort((ushort)(writer.Length - msgHeaderLen - 1)); var prevLen = buffer.Length; buffer.ResizeUninitialized(buffer.Length + writer.Length); byte *ptr = (byte *)buffer.GetUnsafePtr(); ptr += prevLen; UnsafeUtility.MemCpy(ptr, writer.AsNativeArray().GetUnsafeReadOnlyPtr(), writer.Length); }
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(); }); }
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()); }
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(); }
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(); }
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); } } }
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); } } }