public void RequiredBytesTest() { var value = 0; Assert.True(ByteCompression.RequiredBytes(value) == 1, $"Required bytes in {typeof(ByteCompression).Name} returns invalid bytes count for value {value}."); value = 1; Assert.True(ByteCompression.RequiredBytes(value) == 1, $"Required bytes in {typeof(ByteCompression).Name} returns invalid bytes count for value {value}."); value = 0xFF; Assert.True(ByteCompression.RequiredBytes(value) == 1, $"Required bytes in {typeof(ByteCompression).Name} returns invalid bytes count for value {value}."); value = 0x100; Assert.True(ByteCompression.RequiredBytes(value) == 2, $"Required bytes in {typeof(ByteCompression).Name} returns invalid bytes count for value {value}."); value = 0x1FF; Assert.True(ByteCompression.RequiredBytes(value) == 2, $"Required bytes in {typeof(ByteCompression).Name} returns invalid bytes count for value {value}."); value = 0x10000; Assert.True(ByteCompression.RequiredBytes(value) == 3, $"Required bytes in {typeof(ByteCompression).Name} returns invalid bytes count for value {value}."); value = 0x1FFFF; Assert.True(ByteCompression.RequiredBytes(value) == 3, $"Required bytes in {typeof(ByteCompression).Name} returns invalid bytes count for value {value}."); value = 0x1FFFFFF; Assert.True(ByteCompression.RequiredBytes(value) == 4, $"Required bytes in {typeof(ByteCompression).Name} returns invalid bytes count for value {value}."); value = int.MaxValue; Assert.True(ByteCompression.RequiredBytes(value) == 4, $"Required bytes in {typeof(ByteCompression).Name} returns invalid bytes count for value {value}."); value = -1; Assert.True(ByteCompression.RequiredBytes(value) == 4, $"Required bytes in {typeof(ByteCompression).Name} returns invalid bytes count for value {value}."); }
/// <inheritdoc/> public void ReceiveMessage(IPeerManager sender, Message message) { var command = (IdsRegisterCommandType)message.Content.PopInt(ByteCompression .RequiredBytes <IdsRegisterCommandType>()); var key = message.Content.PopString(); var id = message.Content.PopInt(BytesPerId); switch (command) { case IdsRegisterCommandType.BindIdAndKey: if (AssignIds) { return; } BindReceiver(key, id); break; case IdsRegisterCommandType.UnbindIdAndKey: if (AssignIds) { return; } UnbindKeyId(key, id); break; } }
public void PushPeekPopLongTests(long value) { var bytesCount = ByteCompression.RequiredBytes(value); var bytesStack = new BytesStack(bytesCount); bytesStack.PushLong(value, bytesCount); var result = bytesStack.PeekLong(bytesCount); Assert.True(value == result, "PeekLong returns different value than was pushed."); result = bytesStack.PopLong(bytesCount); Assert.True(value == result, "PopLong returns different value than was pushed."); Assert.True(bytesStack.Count == 0, "BytesStack is not empty after PopLong alone long."); }
public void PushPeekPopIntTests(uint value) { var bytesCount = ByteCompression.RequiredBytes(value); var bytesStack = new BytesStack(bytesCount); bytesStack.PushUint(value, bytesCount); var result = bytesStack.PeekUint(bytesCount); Assert.True(value == result, "PeekUint returns different value than was pushed."); result = bytesStack.PopUint(bytesCount); Assert.True(value == result, "PopUint returns different value than was pushed."); Assert.True(bytesStack.Count == 0, "BytesStack is not empty after PopUint alone integer."); }
/// <inheritdoc/> public void ReceiveMessage(IPeerManager sender, Message message) { var commandType = (DistributedRootCommandType)message.Content.PopInt( ByteCompression.RequiredBytes <DistributedRootCommandType>()); switch (commandType) { case DistributedRootCommandType.InstantiateDistributedObject: InstantiatePrefab(message.Content.PopInt(), message.Content.PopString(), message.Content.PopString()); break; default: throw new ArgumentOutOfRangeException(); } }
private void LockingCommandOnExecuted(ILockingCommand executedCommand) { executedCommand.Executed -= LockingCommandOnExecuted; lockingCommands.Remove(executedCommand); ActionsSemaphore.Unlock(); var isClient = Loader.Instance.Network.IsClient; if (!isClient) { return; } var message = MessagesPool.Instance.GetMessage( ByteCompression.RequiredBytes <MessageType>()); message.AddressKey = Key; message.Content.PushEnum <MessageType>((int)MessageType.LockingCommandExecuted); message.Type = DistributedMessageType.ReliableOrdered; BroadcastMessage(message); }
private DistributedMessage GetSpawnMessage(NPCSpawnData data) { var message = MessagesPool.Instance.GetMessage( ByteCompression.RotationMaxRequiredBytes + ByteCompression.PositionRequiredBytes + 12 + BytesStack.GetMaxByteCount(data.GenId) + 1 + ByteCompression.RequiredBytes <NPCManagerCommandType>()); message.AddressKey = Key; var indexOfPrefab = NPCVehicles.FindIndex(npc => npc.Equals(data.Template)); message.Content.PushCompressedRotation(data.Rotation); message.Content.PushCompressedPosition(data.Position); message.Content.PushCompressedColor(data.Color, 1); message.Content.PushInt(data.Seed); message.Content.PushInt(indexOfPrefab, 2); message.Content.PushString(data.GenId); message.Content.PushBool(data.Active); message.Content.PushEnum <NPCManagerCommandType>((int)NPCManagerCommandType.SpawnNPC); message.Type = DistributedMessageType.ReliableOrdered; return(message); }
/// <inheritdoc/> public void ReceiveMessage(IPeerManager sender, DistributedMessage distributedMessage) { var command = (IdsRegisterCommandType)distributedMessage.Content.PopInt( ByteCompression .RequiredBytes <IdsRegisterCommandType>()); var key = distributedMessage.Content.PopString(); var id = distributedMessage.Content.PopInt(BytesPerId); IIdentifiedObject registeredObject; int awaitingId; switch (command) { case IdsRegisterCommandType.BindIdAndKey: if (AssignIds) { return; } //Check if object is already registered if ((idToObjectDictionary.TryGetValue(id, out registeredObject) && registeredObject.Key == key) || (awaitingKeyIdBinds.TryGetValue(key, out awaitingId) && awaitingId == id)) { return; } //New bind to the id received before receiving unbind command if (registeredObject != null) { UnbindKeyId(key, id); idRegistrationTimestamp.Remove(id); } idRegistrationTimestamp.Add(id, distributedMessage.ServerTimestamp); TryBindReceiver(key, id); break; case IdsRegisterCommandType.UnbindIdAndKey: if (AssignIds) { return; } //Remove awaiting binding if it is available if (awaitingKeyIdBinds.TryGetValue(key, out awaitingId) && awaitingId == id) { awaitingKeyIdBinds.Remove(key); idRegistrationTimestamp.Remove(id); return; } //Check if object have not been unbounded already if (!idToObjectDictionary.TryGetValue(id, out registeredObject)) { return; } //Check if bound object has the same key if (registeredObject.Key != key) { return; } UnbindKeyId(key, id); idRegistrationTimestamp.Remove(id); break; } }
void Update() { while (ApiLock.IsUnlocked && Actions.TryDequeue(out var action)) { try { var isMasterSimulation = Loader.Instance.Network.IsMaster; if (action.Command is ILockingCommand lockingCommand) { ApiLock.RegisterNewCommand(lockingCommand); } if (action.Command is IDelegatedCommand delegatedCommand && isMasterSimulation) { var endpoint = delegatedCommand.TargetNodeEndPoint(action.Arguments); //If there is a connection to this endpoint forward the command, otherwise execute it locally if (Loader.Instance.Network.Master.IsConnectedToClient(endpoint)) { var message = MessagesPool.Instance.GetMessage( BytesStack.GetMaxByteCount(action.Arguments) + BytesStack.GetMaxByteCount(action.Command.Name) + ByteCompression.RequiredBytes <MessageType>()); message.AddressKey = Key; message.Content.PushString(action.Arguments.ToString()); message.Content.PushString(action.Command.Name); message.Content.PushEnum <MessageType>((int)MessageType.Command); UnicastMessage(endpoint, message); } else { action.Command.Execute(action.Arguments); } } else { action.Command.Execute(action.Arguments); if (action.Command is IDistributedCommand && isMasterSimulation) { var message = MessagesPool.Instance.GetMessage( BytesStack.GetMaxByteCount(action.Arguments) + BytesStack.GetMaxByteCount(action.Command.Name) + ByteCompression.RequiredBytes <MessageType>()); message.AddressKey = Key; message.Content.PushString(action.Arguments.ToString()); message.Content.PushString(action.Command.Name); message.Content.PushEnum <MessageType>((int)MessageType.Command); message.Type = DistributedMessageType.ReliableOrdered; BroadcastMessage(message); } } } catch (Exception ex) { UnityEngine.Debug.LogException(ex); var st = new StackTrace(ex, true); StackFrame frame = null; int i = 0; while (i < st.FrameCount) { frame = st.GetFrame(i++); if (frame.GetFileLineNumber() != 0) { break; } frame = null; } if (frame == null) { SendError(ex.Message); } else { var fname = frame.GetFileName(); var line = frame.GetFileLineNumber(); SendError($"{ex.Message} at {fname}@{line}"); } ApiLock.ForceUnlock(); } }