public void Run() { m_logger.Info("Running server plugin:"); m_logger.Info("Server Data Port: {0}", m_config.Server.DataPort); m_logger.Info("Server Command Port: {0}", m_config.Server.CommandPoint); if (m_config.Forward.HasValue) { m_logger.Info("Forward Data Port: {0}", m_config.Forward.Value.DataPort); m_logger.Info("Forward Command Port: {0}", m_config.Forward.Value.CommandPoint); } m_logger.Info("Opening UDP client at {0}", m_config.Server.DataPort); var server = new UdpClient(m_config.Server.DataPort); UdpClient forwardClient = null; if (m_config.SuppressSocketError) { m_logger.Debug("Suppressing socket error"); SuppressSocketError(server); } if (m_config.Forward.HasValue) { m_logger.Debug("Opening forwarding client from {0} to {1}", m_config.Forward.Value.CommandPoint, m_config.Server.CommandPoint); forwardClient = new UdpClient(m_config.Forward.Value.CommandPoint); if (m_config.SuppressSocketError) { m_logger.Debug("Suppressing socket error for forwarding client"); SuppressSocketError(forwardClient); } m_logger.Info("Enabling forwarding thread"); var commandThread = new Thread(() => CommandForwardTask(server, forwardClient)); commandThread.Start(); } var recievePoint = m_config.Server.DataPort; m_logger.Debug("Creating Commander"); var commander = new Commander(server, m_config.Server); m_logger.Info("Waiting for messages from server"); while (true) { var bytes = server.Receive(ref recievePoint); m_logger.Debug("Recieved data packet."); if (m_config.Forward.HasValue && forwardClient != null) { m_logger.Debug("Forwarding data packet"); forwardClient.Send(bytes, bytes.Length, m_config.Forward.Value.DataPort); } var br = new BinaryReader(new MemoryStream(bytes)); var rawPacketID = br.ReadByte(); var packetType = (ACSMessage)rawPacketID; m_logger.Debug("Packet type: {0}", packetType); if (!m_isKnownSession && packetType != ACSMessage.Version && packetType != ACSMessage.SessionInfo && packetType != ACSMessage.NewSession) { m_logger.Info("Unknown session, requesting info."); commander.GetSessionInfoCurrent(); } switch (packetType) { case ACSMessage.NewSession: var nsInfo = SessionInfo.Parse(br); m_logger.Trace("Packet contents: {0}", nsInfo); m_isKnownSession = true; foreach (var handler in m_handlers) { handler.OnNewSession(commander, nsInfo); } break; case ACSMessage.NewConnection: var ncInfo = ConnectionInfo.Parse(br); m_logger.Trace("Packet contents: {0}", ncInfo); foreach (var handler in m_handlers) { handler.OnNewConnection(commander, ncInfo); } break; case ACSMessage.ConnectionClosed: var ccInfo = ConnectionInfo.Parse(br); m_logger.Trace("Packet contents: {0}", ccInfo); foreach (var handler in m_handlers) { handler.OnConnectionClosed(commander, ccInfo); } break; case ACSMessage.CarUpdate: var cuInfo = CarUpdateInfo.Parse(br); m_logger.Trace("Packet contents: {0}", cuInfo); foreach (var handler in m_handlers) { handler.OnCarUpdate(commander, cuInfo); } break; case ACSMessage.CarInfo: var ciInfo = CarInfo.Parse(br); m_logger.Trace("Packet contents: {0}", ciInfo); foreach (var handler in m_handlers) { handler.OnCarInfo(commander, ciInfo); } break; case ACSMessage.EndSession: var esInfo = Parsing.ReadUnicodeString(br); m_logger.Trace("Packet contents: {0}", esInfo); foreach (var handler in m_handlers) { handler.OnEndSession(commander, esInfo); } break; case ACSMessage.LapCompleted: var lcInfo = LapCompletedInfo.Parse(br); m_logger.Trace("Packet contents: {0}", lcInfo); foreach (var handler in m_handlers) { handler.OnLapCompleted(commander, lcInfo); } break; case ACSMessage.Version: var version = br.ReadByte(); m_logger.Trace("Packet contents: {0}", version); foreach (var handler in m_handlers) { handler.OnProtocolVersion(commander, version); } break; case ACSMessage.Chat: var chat = ChatMessage.Parse(br); m_logger.Trace("Packet contents: {0}", chat); foreach (var handler in m_handlers) { handler.OnChatMessage(commander, chat); } break; case ACSMessage.ClientLoaded: var clId = br.ReadByte(); m_logger.Trace("Packet contents: {0}", clId); foreach (var handler in m_handlers) { handler.OnClientLoaded(commander, clId); } break; case ACSMessage.SessionInfo: var siInfo = SessionInfo.Parse(br); m_logger.Trace("Packet contents: {0}", siInfo); m_isKnownSession = true; foreach (var handler in m_handlers) { handler.OnSessionInfo(commander, siInfo); } break; case ACSMessage.Error: var err = Parsing.ReadUnicodeString(br); m_logger.Info("Error recieved from server: {0}", err); foreach (var handler in m_handlers) { handler.OnError(commander, err); } break; case ACSMessage.ClientEvent: var ceInfo = ClientEventInfo.Parse(br); m_logger.Trace("Packet contents: {0}", ceInfo); foreach (var handler in m_handlers) { handler.OnClientEvent(commander, ceInfo); } break; default: m_logger.Error("Received invalid packet ID: {0}", rawPacketID); break; } } }