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); }
public void PutMessagesIntoQueue_WhenUserWantsToSendMessage() { IAdminMessage msg = Mock.Of <IAdminMessage>(); state.SendMessage(msg, context); Assert.Contains(msg, context.MessagesToSend); }
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); } }
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); }
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); } }
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); }
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); }
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; }
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) { }
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); }
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) { }