Beispiel #1
0
        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}.");
        }
Beispiel #2
0
        /// <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;
            }
        }
Beispiel #3
0
        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.");
        }
Beispiel #4
0
        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.");
        }
Beispiel #5
0
        /// <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);
        }
Beispiel #7
0
    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);
    }
Beispiel #8
0
        /// <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;
            }
        }
Beispiel #9
0
        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();
                }
            }