private void SetupClientEventHandlers(IClientEventReceiver clientEventReceiver) { clientEventReceiver.Event += (sender, args) => { var player = _game.GetPlayer(args.PlayerId); switch (args.Event) { case ClientEvent.Hello: var helloDto = new HelloDto { GameSettings = new GameSettingsDto { GameTickMs = _game.GetGameTickMs() }, World = _game.GetWorldDto() }; _eventSender.SendEvent(ServerEvent.Hello, helloDto, args.PlayerId); break; case ClientEvent.ChatMessage: var messageDto = (ClientChatMessageDto)args.Dto; var colour = player.GetBike().GetColour(); var sourceColour = $"rgba({colour.R:X2},{colour.G:X2},{colour.B:X2},%A%)"; var dto = new ChatMessageDto { IsSystemMessage = false, Message = messageDto.Message, SourceColour = sourceColour, Source = player.GetName(), Timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds() }; _eventSender.SendEvent(ServerEvent.ChatMessage, dto, null); break; case ClientEvent.KeepAlive: _eventSender.SendEvent(ServerEvent.KeepAliveAck, args.PlayerId); break; case ClientEvent.RequestJoinGame: RequestGameJoin(args.PlayerId, (ClientGameJoinDto)args.Dto); break; case ClientEvent.RequestRespawn: _game.RequestRespawn(player); break; case ClientEvent.Update: var updateDto = (ClientUpdateDto)args.Dto; _game.HandleClientUpdate(updateDto); break; case ClientEvent.UsePowerup: if (player.GetCurrentPowerUpType() == PowerUpType.Nothing) { return; // player doesn't have a powerup } _game.RequestUsePowerUp(player); break; default: throw new ArgumentOutOfRangeException(); } }; }