public async Task BeAbletToDealWithDataThatIsNotSendAsWholeAtOneMoment()
        {
            Packet packet = CreatePongMessage();

            using MemoryStream stream = new MemoryStream(2000);

            var receiver = new AdminPortTcpClientReceiver(packetService);
            await receiver.Start(stream);

            IAdminMessage receivedMessage = null;

            receiver.MessageReceived += (_, msg) => receivedMessage = msg;

            for (int i = 0; i < packet.Size; ++i)
            {
                stream.Write(packet.Buffer, i, 1);
                await Task.Delay(2);
            }


            stream.Position = 0;
            await WaitForMessage(receivedMessage);

            VerifyMessage(receivedMessage);
        }
        public async Task NotBeingAbleToReceiveCorrectPacket_AfterWrongPacket()
        {
            Packet packet = CreateWrongMessage();

            using MemoryStream stream = new MemoryStream(2000);

            var receiver = new AdminPortTcpClientReceiver(packetService);
            await receiver.Start(stream);

            IAdminMessage receivedMessage = null;

            receiver.MessageReceived += (_, msg) => receivedMessage = msg;

            stream.Write(packet.Buffer, 0, packet.Size);
            stream.Position = 0;
            long savedPos = stream.Position;
            await Task.Delay(1000);

            packet = CreatePongMessage();
            stream.Write(packet.Buffer, 0, packet.Size);
            stream.Position = savedPos;

            await WaitForMessage(receivedMessage);

            Assert.Null(receivedMessage);
        }
        public async Task StopEverything_AfterSecondStart()
        {
            Packet packet = CreatePongMessage();

            using MemoryStream stream = new MemoryStream(2000);

            var receiver = new AdminPortTcpClientReceiver(packetService);
            await receiver.Start(stream);

            try
            {
                await receiver.Start(stream);
            }
            catch (Exception) { }
            IAdminMessage receivedMessage = null;

            receiver.MessageReceived += (_, msg) => receivedMessage = msg;

            stream.Write(packet.Buffer, 0, packet.Size);
            stream.Position = 0;

            await WaitForMessage(receivedMessage);

            Assert.Null(receivedMessage);
        }
 private void OnMessageReceived(object who, IAdminMessage message)
 {
     if (message.MessageType == AdminMessageType.ADMIN_PACKET_SERVER_PONG)
     {
         var pongMsg = (AdminServerPongMessage)message;
         lastPingReceived = lastPingReceived || pongMsg.Argument == lastSendPingArg;
     }
 }
        private static void VerifyMessage(IAdminMessage receivedMessage)
        {
            Thread.Sleep(TimeSpan.FromSeconds(1));
            var pongMsg = receivedMessage as AdminServerPongMessage;

            Assert.NotNull(pongMsg);
            Assert.Equal(123u, pongMsg.Argument);
        }
Esempio n. 6
0
        public void PutMessagesIntoQueue_WhenUserWantsToSendMessage()
        {
            IAdminMessage msg = Mock.Of <IAdminMessage>();

            state.SendMessage(msg, context);

            Assert.Contains(msg, context.MessagesToSend);
        }
Esempio n. 7
0
        public void SendMessageToQueue_WhenSendingMessage()
        {
            IAdminMessage msg = Mock.Of <IAdminMessage>();

            state.SendMessage(msg, context);

            Assert.Single(context.MessagesToSend, msg);
            tcpClientMock.Verify(x => x.SendMessage(msg), Times.Never);
        }
        public void SendMessageToClient_WhenReceivingMessage()
        {
            IAdminMessage msg = Mock.Of <IAdminMessage>();

            state.SendMessage(msg, context);

            Assert.Empty(context.MessagesToSend);
            tcpClientMock.Verify(x => x.SendMessage(msg), Times.Once);
        }
 private static async Task WaitForMessage(IAdminMessage receivedMessage)
 {
     for (int i = 0; i < 100; ++i)
     {
         if (receivedMessage != null)
         {
             break;
         }
         await Task.Delay(1);
     }
 }
Esempio n. 10
0
        public async Task SendMessageEvent_WhenMessageIsReceived()
        {
            await client.Start(ip, port);

            IAdminMessage msg      = new AdminServerPongMessage(32u);
            IAdminMessage received = null;

            client.MessageReceived += (_, r) => received = r;
            receiverMock.Raise(x => x.MessageReceived += null, this, msg);
            Assert.Equal(msg, received);
        }
Esempio n. 11
0
        private void AdminPortTcpClient_MessageReceived(object sender, IAdminMessage e)
        {
            logger?.LogTrace($"{ServerInfo} Received message {e.MessageType} - {e}");
            StateRunners[Context.State].OnMessageReceived(e, Context);
            IAdminEvent?adminEvent = eventFactory.Create(e, Context);

            logger?.LogWarning($"{ServerInfo} adminEvent is null for {e.MessageType} {e}");
            if (adminEvent != null)
            {
                EventReceived?.Invoke(this, adminEvent);
            }
        }
Esempio n. 12
0
 public void SendMessage(IAdminMessage message)
 {
     try
     {
         StateRunners[Context.State].SendMessage(message, Context);
     }
     catch (Exception)
     {
         Context.State = AdminConnectionState.ErroredOut;
         throw;
     }
 }
        public void ReadPacket_WhenItCanCreateMessageBasedOnPacket()
        {
            var messageTransformer = new Mock <IPacketTransformer>();

            messageTransformer.SetupGet(x => x.SupportedMessageType).Returns(AdminMessageType.ADMIN_PACKET_SERVER_BANNED);
            IAdminMessage adminMessage = Mock.Of <IAdminMessage>();

            messageTransformer.Setup(x => x.Transform(It.IsAny <Packet>())).Returns(adminMessage);

            var    adminPacketService = new AdminPacketService(new IPacketTransformer[] { messageTransformer.Object }, new IMessageTransformer[0]);
            Packet packet             = new Packet();

            packet.SendByte((byte)AdminMessageType.ADMIN_PACKET_SERVER_BANNED);
            packet.PrepareToSend();

            Assert.Same(adminMessage, adminPacketService.ReadPacket(packet));
        }
        public async Task ErrorOut_AfterSendingWrongPacket()
        {
            Packet packet = CreateWrongMessage();

            using MemoryStream stream = new MemoryStream(2000);

            var receiver = new AdminPortTcpClientReceiver(packetService);
            await receiver.Start(stream);

            IAdminMessage receivedMessage = null;

            receiver.MessageReceived += (_, msg) => receivedMessage = msg;

            stream.Write(packet.Buffer, 0, packet.Size);
            stream.Position = 0;

            await Task.Delay(TimeSpan.FromSeconds(1));

            Assert.Equal(WorkState.Errored, receiver.State);
        }
        public async Task ReadPacketProperlyAndSendMessageAboutIt()
        {
            Packet packet = CreatePongMessage();

            using MemoryStream stream = new MemoryStream(2000);

            var receiver = new AdminPortTcpClientReceiver(packetService);
            await receiver.Start(stream);

            IAdminMessage receivedMessage = null;

            receiver.MessageReceived += (_, msg) => receivedMessage = msg;

            stream.Write(packet.Buffer, 0, packet.Size);
            stream.Position = 0;

            await WaitForMessage(receivedMessage);

            VerifyMessage(receivedMessage);
        }
Esempio n. 16
0
        public override void OnMessageReceived(IAdminMessage message, IAdminPortClientContext context)
        {
            switch (message.MessageType)
            {
            case AdminMessageType.ADMIN_PACKET_SERVER_PROTOCOL:
            {
                var msg = (AdminServerProtocolMessage)message;

                foreach (var s in msg.AdminUpdateSettings)
                {
                    //this.logger.LogInformation($"Update settings {s.Key} - {s.Value}");
                    context.AdminUpdateSettings.TryUpdate(s.Key, new AdminUpdateSetting(true, s.Key, s.Value), context.AdminUpdateSettings[s.Key]);
                }

                break;
            }

            case AdminMessageType.ADMIN_PACKET_SERVER_WELCOME:
            {
                var msg = (AdminServerWelcomeMessage)message;
                // TODO: It will be not needed when we will have init accessors - then it will be easy to do non-null props that are accessed only through object initializer.
                // Hate this line of code ATM :<.
                Debug.Assert(msg.MapName != null && msg.NetworkRevision != null && msg.ServerName != null);


                context.AdminServerInfo = new AdminServerInfo()
                {
                    IsDedicated  = msg.IsDedicated,
                    MapName      = msg.MapName,
                    RevisionName = msg.NetworkRevision,
                    ServerName   = msg.ServerName
                };
                context.State = AdminConnectionState.Connected;

                //this.logger.LogInformation($"{ServerInfo.ServerIp}:{ServerInfo.ServerPort} - connected");
                break;
            }
            }
        }
        public override void OnMessageReceived(IAdminMessage message, IAdminPortClientContext context)
        {
            switch (message.MessageType)
            {
            case AdminMessageType.ADMIN_PACKET_SERVER_CLIENT_INFO:
            {
                var msg    = (AdminServerClientInfoMessage)message;
                var player = new Player(msg.ClientId, msg.ClientName);
                context.Players.AddOrUpdate(msg.ClientId, player, (_, __) => player);

                break;
            }

            case AdminMessageType.ADMIN_PACKET_SERVER_CLIENT_UPDATE:
            {
                var msg    = (AdminServerClientUpdateMessage)message;
                var player = context.Players[msg.ClientId];
                player.Name = msg.ClientName;
                break;
            }
            }
        }
        private async void MainLoop(Stream stream, CancellationToken token)
        {
            while (token.IsCancellationRequested == false)
            {
                try
                {
                    Packet packet = await WaitForPacket(stream, token);

                    IAdminMessage message = adminPacketService.ReadPacket(packet);
                    if (!token.IsCancellationRequested)
                    {
                        receivedMessages.Enqueue(message);
                    }
                }
                catch (Exception e)
                {
                    cancellationTokenSource.Cancel();
                    ErrorOcurred?.Invoke(this, e);
                    State = WorkState.Errored;
                }
            }
        }
        public async Task BeAbleToDealWithLongWaitingTimeForPacket()
        {
            Packet packet = CreatePongMessage();

            using MemoryStream stream = new MemoryStream(2000);

            var receiver = new AdminPortTcpClientReceiver(packetService);
            await receiver.Start(stream);

            IAdminMessage receivedMessage = null;

            receiver.MessageReceived += (_, msg) => receivedMessage = msg;

            await Task.Delay(TimeSpan.FromSeconds(10));

            stream.Write(packet.Buffer, 0, packet.Size);
            stream.Position = 0;

            await WaitForMessage(receivedMessage);

            VerifyMessage(receivedMessage);
        }
 public override void SendMessage(IAdminMessage message, IAdminPortClientContext context)
 {
     context.TcpClient.SendMessage(message);
 }
Esempio n. 21
0
        private async void MainLoop(CancellationToken token)
        {
            Task <int> sizeTask = null;

            byte[] sizeBuffer = new byte[2];

            while (token.IsCancellationRequested == false)
            {
                try
                {
                    if (this.ConnectionState == AdminConnectionState.NotConnected)
                    {
                        tcpClient = new TcpClient();
                        tcpClient.ReceiveTimeout = 2000;
                        tcpClient.SendTimeout    = 2000;
                        lastMessageSentTime      = DateTime.Now;
                        lastMessageReceivedTime  = DateTime.Now;
                        tcpClient.Connect(ServerInfo.ServerIp, ServerInfo.ServerPort);
                        this.SendMessage(new AdminJoinMessage(ServerInfo.Password, "OttdBot", "1.0.0"));
                        logger.LogInformation($"{ServerInfo} Connecting");

                        this.ConnectionState = AdminConnectionState.Connecting;
                    }

                    if (this.tcpClient == null)
                    {
                        continue;
                    }

                    if ((DateTime.Now - lastMessageSentTime) > TimeSpan.FromSeconds(10))
                    {
                        this.SendMessage(new AdminPingMessage());
                    }

                    if (DateTime.Now - lastMessageReceivedTime > TimeSpan.FromMinutes(1))
                    {
                        throw new OttdException("No messages received for 60 seconds!");
                    }

                    for (int i = 0; i < 100; ++i)
                    {
                        if (this.sendMessageQueue.TryDequeue(out IAdminMessage msg))
                        {
                            logger.LogInformation($"{ServerInfo} sent {msg.MessageType}");
                            Packet packet = this.adminPacketService.CreatePacket(msg);
                            await tcpClient.GetStream().WriteAsync(packet.Buffer, 0, packet.Size).WaitMax(TimeSpan.FromSeconds(2));

                            lastMessageSentTime = DateTime.Now;
                        }
                        else
                        {
                            break;
                        }
                    }

                    while ((sizeTask ??= tcpClient.GetStream().ReadAsync(sizeBuffer, 0, 2)).IsCompleted)
                    {
                        var receivedBytes = sizeTask.Result;

                        if (receivedBytes != 2)
                        {
                            await Task.Delay(TimeSpan.FromMilliseconds(1));

                            int bytes = await tcpClient.GetStream().ReadAsync(sizeBuffer, 1, 1).WaitMax(TimeSpan.FromSeconds(2));

                            if (bytes == 0)
                            {
                                throw new OttdConnectionException("Something went wrong - restarting");
                            }
                        }

                        sizeTask = null;

                        ushort size = BitConverter.ToUInt16(sizeBuffer, 0);

                        byte[] content = new byte[size];
                        content[0] = sizeBuffer[0];
                        content[1] = sizeBuffer[1];
                        int contentSize = 2;

                        lastMessageReceivedTime = DateTime.Now;

                        do
                        {
                            await Task.Delay(TimeSpan.FromMilliseconds(1));

                            Task <int> task = tcpClient.GetStream().ReadAsync(content, contentSize, size - contentSize).WaitMax(TimeSpan.FromSeconds(2), $"{ServerInfo} no data received");
                            await      task;
                            contentSize += task.Result;
                            if (task.Result == 0)
                            {
                                throw new OttdConnectionException("No further data received in message!");
                            }
                        } while (contentSize < size);


                        var           packet  = new Packet(content);
                        IAdminMessage message = this.adminPacketService.ReadPacket(packet);
                        if (message == null)
                        {
                            break;
                        }

                        this.logger.LogInformation($"{ServerInfo} received {message.MessageType}");

                        switch (message.MessageType)
                        {
                        case AdminMessageType.ADMIN_PACKET_SERVER_PROTOCOL:
                        {
                            var msg = message as AdminServerProtocolMessage;

                            foreach (var s in msg.AdminUpdateSettings)
                            {
                                this.logger.LogInformation($"Update settings {s.Key} - {s.Value}");
                                this.AdminUpdateSettings.TryUpdate(s.Key, new AdminUpdateSetting(true, s.Key, s.Value), this.AdminUpdateSettings[s.Key]);
                            }

                            break;
                        }

                        case AdminMessageType.ADMIN_PACKET_SERVER_WELCOME:
                        {
                            var msg = message as AdminServerWelcomeMessage;

                            AdminServerInfo = new AdminServerInfo()
                            {
                                IsDedicated  = msg.IsDedicated,
                                MapName      = msg.MapName,
                                RevisionName = msg.NetworkRevision,
                                ServerName   = msg.ServerName
                            };


                            this.SendMessage(new AdminUpdateFrequencyMessage(AdminUpdateType.ADMIN_UPDATE_CHAT, UpdateFrequency.ADMIN_FREQUENCY_AUTOMATIC));
                            this.SendMessage(new AdminUpdateFrequencyMessage(AdminUpdateType.ADMIN_UPDATE_CONSOLE, UpdateFrequency.ADMIN_FREQUENCY_AUTOMATIC));
                            this.SendMessage(new AdminUpdateFrequencyMessage(AdminUpdateType.ADMIN_UPDATE_CLIENT_INFO, UpdateFrequency.ADMIN_FREQUENCY_AUTOMATIC));
                            this.SendMessage(new AdminPollMessage(AdminUpdateType.ADMIN_UPDATE_CLIENT_INFO, uint.MaxValue));

                            this.ConnectionState = AdminConnectionState.Connected;
                            this.logger.LogInformation($"{ServerInfo.ServerIp}:{ServerInfo.ServerPort} - connected");

                            break;
                        }

                        case AdminMessageType.ADMIN_PACKET_SERVER_CLIENT_INFO:
                        {
                            var msg    = message as AdminServerClientInfoMessage;
                            var player = new Player(msg.ClientId, msg.ClientName);
                            this.Players.AddOrUpdate(msg.ClientId, player, (_, __) => player);

                            break;
                        }

                        case AdminMessageType.ADMIN_PACKET_SERVER_CLIENT_UPDATE:
                        {
                            var msg    = message as AdminServerClientUpdateMessage;
                            var player = this.Players[msg.ClientId];
                            player.Name = msg.ClientName;

                            break;
                        }

                        default:
                        {
                            var msg = message as AdminServerChatMessage;
                            this.receivedMessagesQueue.Enqueue(message);
                            break;
                        }
                        }
                    }



                    await Task.Delay(TimeSpan.FromSeconds(0.5));
                }
                catch (Exception e)
                {
                    this.logger.LogError($"{ServerInfo.ServerIp}:{ServerInfo.ServerPort} encountered error {e.Message}", e);

                    this.tcpClient?.Dispose();
                    this.tcpClient = null;
                    this.sendMessageQueue.Clear();
                    this.receivedMessagesQueue.Clear();
                    sizeTask             = null;
                    this.ConnectionState = AdminConnectionState.NotConnected;

                    await Task.Delay(TimeSpan.FromSeconds(60));
                }
            }

            this.logger.LogInformation($"{ServerInfo} disconnected");
            this.ConnectionState = AdminConnectionState.Idle;
        }
Esempio n. 22
0
 public override void SendMessage(IAdminMessage message, IAdminPortClientContext context)
 {
     // we are ignoring messages. They will probably do not make sense anyway if server will be started again.
 }
 public void SendMessage(IAdminMessage message)
 {
     messagesToSend.Enqueue(message);
 }
 public void SendMessage(IAdminMessage message, IAdminPortClientContext context)
 {
     throw new AdminPortException("AdminPortClient had fatal error - unable to continue");
 }
 public void OnMessageReceived(IAdminMessage message, IAdminPortClientContext context)
 {
 }
Esempio n. 26
0
        public Packet CreatePacket(IAdminMessage message)
        {
            Packet packet = new Packet();

            packet.SendByte((byte)message.MessageType);

            switch (message.MessageType)
            {
            case AdminMessageType.ADMIN_PACKET_ADMIN_JOIN:
            {
                var msg = message as AdminJoinMessage;
                packet.SendString(msg.Password, 33);
                packet.SendString(msg.AdminName, 25);
                packet.SendString(msg.AdminVersion, 33);
                break;
            }

            case AdminMessageType.ADMIN_PACKET_ADMIN_POLL:
            {
                var msg = message as AdminPollMessage;
                packet.SendByte((byte)msg.UpdateType);
                packet.SendU32(msg.Argument);

                break;
            }

            case AdminMessageType.ADMIN_PACKET_ADMIN_UPDATE_FREQUENCY:
            {
                var msg = message as AdminUpdateFrequencyMessage;
                packet.SendU16((ushort)msg.UpdateType);
                packet.SendU16((ushort)msg.UpdateFrequency);
                break;
            }

            case AdminMessageType.ADMIN_PACKET_ADMIN_CHAT:
            {
                var msg = message as AdminChatMessage;
                packet.SendByte((byte)msg.NetworkAction);
                packet.SendByte((byte)msg.ChatDestination);
                packet.SendU32(msg.Destination);
                packet.SendString(msg.Message, 900);

                break;
            }

            case AdminMessageType.ADMIN_PACKET_ADMIN_RCON:
            {
                var msg = message as AdminRconMessage;
                packet.SendString(msg.Command, 500);
                break;
            }

            case AdminMessageType.ADMIN_PACKET_ADMIN_PING:
            {
                var msg = message as AdminPingMessage;
                packet.SendU32(msg.Argument);
                break;
            }

            case AdminMessageType.ADMIN_PACKET_ADMIN_QUIT:
            case AdminMessageType.ADMIN_PACKET_ADMIN_GAMESCRIPT:     //this will be implemented later or never.
            {
                break;
            }
            }

            packet.PrepareToSend();
            return(packet);
        }
Esempio n. 27
0
 public IAdminEvent ProcessMessage(IAdminMessage adminMessage, in IAdminPortClient client)
 public void SendMessage(IAdminMessage message)
 {
     sender.SendMessage(message);
 }
 public virtual void SimulateMessageReceived(IAdminMessage msg) => MessageReceived?.Invoke(this, msg);
 public virtual void SendMessage(IAdminMessage message)
 {
 }