/// <summary> /// This function reads and processes every incoming message arriving from the server. /// </summary> /// <returns>False, if the connection manager thread has to stop, true otherwise.</returns> private bool ProcessIncomingMessages() { List <RCPackage> incomingPackages = new List <RCPackage>(); if (this.connection.ReceiveIncomingPackages(ref incomingPackages)) { foreach (RCPackage package in incomingPackages) { if (package.PackageType == RCPackageType.NETWORK_CUSTOM_PACKAGE && package.Sender >= 0 && package.Sender < this.memberCount && package.Sender != this.clientID) { /// Custom message from a member --> notify the listener. this.listener.PackageArrived(package, package.Sender); } else if (package.PackageType == RCPackageType.NETWORK_CONTROL_PACKAGE && package.PackageFormat.ID == Network.FORMAT_LOBBY_LINE_STATE_REPORT) { /// Line state report from the server. short clientID = package.ReadShort(0); byte[] lineStateBytes = package.ReadByteArray(1); LobbyLineState[] lineStates = new LobbyLineState[lineStateBytes.Length]; bool lineStatesOK = true; for (int i = 0; i < lineStateBytes.Length; i++) { if (lineStateBytes[i] == (byte)LobbyLineState.Closed || lineStateBytes[i] == (byte)LobbyLineState.Engaged || lineStateBytes[i] == (byte)LobbyLineState.Opened) { lineStates[i] = (LobbyLineState)lineStateBytes[i]; } else { lineStatesOK = false; } } lineStatesOK = lineStatesOK && (clientID == this.clientID) && (lineStateBytes.Length == this.memberCount); if (!lineStatesOK) { /// Line state report error --> shutdown. this.connection.Shutdown(); if (this.Disposed != null) { this.Disposed(this); } this.listener.LobbyLost(); return(false); } else { /// Line state report arrived --> notify the listener this.listener.LineStateReport(clientID, lineStates); ///return true; } } else if (package.PackageType == RCPackageType.NETWORK_CONTROL_PACKAGE && package.PackageFormat.ID == Network.FORMAT_DISCONNECT_INDICATOR) { /// Disconnection indicator from the server. RCPackage disconnectAck = RCPackage.CreateNetworkControlPackage(Network.FORMAT_DISCONNECT_ACK); disconnectAck.WriteString(0, string.Empty); disconnectAck.WriteByteArray(1, new byte[0] { }); this.connection.SendPackage(disconnectAck); this.connection.Shutdown(); if (this.Disposed != null) { this.Disposed(this); } this.listener.LobbyLost(); return(false); } else if (package.PackageType == RCPackageType.NETWORK_CONTROL_PACKAGE && package.PackageFormat.ID != Network.FORMAT_DEDICATED_MESSAGE && package.PackageFormat.ID != Network.FORMAT_DISCONNECT_ACK && package.PackageFormat.ID != Network.FORMAT_DISCONNECT_INDICATOR && package.PackageFormat.ID != Network.FORMAT_LOBBY_INFO && package.PackageFormat.ID != Network.FORMAT_LOBBY_INFO_VANISHED && package.PackageFormat.ID != Network.FORMAT_LOBBY_LINE_STATE_REPORT) { /// Custom internal message from the server --> notify the listener TraceManager.WriteAllTrace(string.Format("Incoming package: {0}", package.ToString()), NetworkingSystemTraceFilters.INFO); this.listener.ControlPackageArrived(package); } else { /// Unexpected package format and type --> immediate shutdown this.connection.Shutdown(); if (this.Disposed != null) { this.Disposed(this); } this.listener.LobbyLost(); return(false); } } /// end-foreach (RCPackage package in incomingPackages) /// Incoming packages has been processed. return(true); } else { /// Receive error --> immediate shutdown this.connection.Shutdown(); if (this.Disposed != null) { this.Disposed(this); } this.listener.LobbyLost(); return(false); } }
/// <summary> /// Continues the connection procedure to the server. /// </summary> /// <returns> /// In case of error this function automatically shuts down the connection, notifies the listener and /// returns false. Otherwise it returns true. If the line state report arrives from the server, this /// function automatically notifies the listener. /// </returns> private bool ContinueConnectToTheServer() { RCPackage lineStateReport = null; if (this.connection.ContinueConnectToTheServer(out lineStateReport)) { if (lineStateReport != null) { short clientID = lineStateReport.ReadShort(0); byte[] lineStateBytes = lineStateReport.ReadByteArray(1); LobbyLineState[] lineStates = new LobbyLineState[lineStateBytes.Length]; bool lineStatesOK = true; for (int i = 0; i < lineStateBytes.Length; i++) { if (lineStateBytes[i] == (byte)LobbyLineState.Closed || lineStateBytes[i] == (byte)LobbyLineState.Engaged || lineStateBytes[i] == (byte)LobbyLineState.Opened) { lineStates[i] = (LobbyLineState)lineStateBytes[i]; } else { lineStatesOK = false; } } lineStatesOK = lineStatesOK && clientID > 0 && clientID < lineStateBytes.Length; if (!lineStatesOK) { /// Line state report error --> shutdown. this.connection.Shutdown(); if (this.Disposed != null) { this.Disposed(this); } this.listener.LobbyLost(); return(false); } else { /// Connection procedure finished --> send a line state report to the listener. this.clientID = clientID; this.memberCount = lineStates.Length; this.listener.LineStateReport(clientID, lineStates); return(true); } } /// No error but connection procedure not finished. return(true); } else { /// Connection rejected by the server or an error occured --> shutdown. this.connection.Shutdown(); if (this.Disposed != null) { this.Disposed(this); } this.listener.LobbyLost(); return(false); } }