/// <see cref="ITrace.WriteLine"/> public void WriteException(Exception ex, bool isFatal) { if (ex == null) { throw new ArgumentNullException("ex"); } string strToWrite = ex.ToString(); if (strToWrite == null) { strToWrite = string.Empty; } RCPackage packageToWrite = RCPackage.CreateCustomDataPackage(RCL_EXCEPTION_FORMAT); packageToWrite.WriteInt(0, RCThread.CurrentThread.WrappedThread.ManagedThreadId); packageToWrite.WriteString(1, RCThread.CurrentThread.Name); packageToWrite.WriteLong(2, timer.ElapsedMilliseconds); packageToWrite.WriteByte(3, isFatal ? (byte)0x01 : (byte)0x00); packageToWrite.WriteString(4, strToWrite); byte[] buffer = new byte[packageToWrite.PackageLength]; packageToWrite.WritePackageToBuffer(buffer, 0); this.outputWriter.Write(buffer); this.outputWriter.Flush(); this.outputStream.Flush(); }
/// <see cref="ITrace.WriteFork"/> public void WriteFork(RCThread newThread, RCThread parentThread) { if (newThread == null) { throw new ArgumentNullException("newThread"); } if (parentThread == null) { throw new ArgumentNullException("parentThread"); } RCPackage packageToWrite = RCPackage.CreateCustomDataPackage(RCL_FORK_FORMAT); packageToWrite.WriteInt(0, newThread.WrappedThread.ManagedThreadId); packageToWrite.WriteString(1, newThread.Name); packageToWrite.WriteInt(2, parentThread.WrappedThread.ManagedThreadId); packageToWrite.WriteString(3, parentThread.Name); packageToWrite.WriteLong(4, timer.ElapsedMilliseconds); byte[] buffer = new byte[packageToWrite.PackageLength]; packageToWrite.WritePackageToBuffer(buffer, 0); this.outputWriter.Write(buffer); this.outputWriter.Flush(); this.outputStream.Flush(); }
/// <see cref="ITrace.WriteLine"/> public void WriteLine(object obj) { if (obj == null) { throw new ArgumentNullException("obj"); } string strToWrite = obj.ToString(); if (strToWrite == null) { strToWrite = string.Empty; } RCPackage packageToWrite = RCPackage.CreateCustomDataPackage(RCL_EVENT_FORMAT); packageToWrite.WriteInt(0, RCThread.CurrentThread.WrappedThread.ManagedThreadId); packageToWrite.WriteString(1, RCThread.CurrentThread.Name); packageToWrite.WriteLong(2, timer.ElapsedMilliseconds); packageToWrite.WriteString(3, strToWrite); byte[] buffer = new byte[packageToWrite.PackageLength]; packageToWrite.WritePackageToBuffer(buffer, 0); this.outputWriter.Write(buffer); this.outputWriter.Flush(); this.outputStream.Flush(); }
/// <see cref="IComponent.Start"/> public void Start() { this.tilesetLoader = ComponentManager.GetInterface <ITileSetLoader>(); /// Load the tilesets from the configured directory DirectoryInfo rootDir = new DirectoryInfo(BizLogicConstants.TILESET_DIR); FileInfo[] tilesetFiles = rootDir.GetFiles("*.xml", SearchOption.AllDirectories); foreach (FileInfo tilesetFile in tilesetFiles) { /// TODO: this is a hack! Later we will have binary tileset format. string xmlStr = File.ReadAllText(tilesetFile.FullName); string imageDir = tilesetFile.DirectoryName; RCPackage tilesetPackage = RCPackage.CreateCustomDataPackage(PackageFormats.TILESET_FORMAT); tilesetPackage.WriteString(0, xmlStr); tilesetPackage.WriteString(1, imageDir); byte[] buffer = new byte[tilesetPackage.PackageLength]; tilesetPackage.WritePackageToBuffer(buffer, 0); ITileSet tileset = this.tilesetLoader.LoadTileSet(buffer); if (this.loadedTilesets.ContainsKey(tileset.Name)) { throw new InvalidOperationException(string.Format("Tileset with name '{0}' already loaded!", tileset.Name)); } this.loadedTilesets.Add(tileset.Name, tileset); } }
/// <see cref="ITrace.WriteJoin"/> public void WriteJoin(RCThread runningThread, RCThread waitingThread) { if (runningThread == null) { throw new ArgumentNullException("runningThread"); } if (waitingThread == null) { throw new ArgumentNullException("waitingThread"); } RCPackage packageToWrite = RCPackage.CreateCustomDataPackage(RCL_JOIN_FORMAT); packageToWrite.WriteInt(0, runningThread.WrappedThread.ManagedThreadId); packageToWrite.WriteString(1, runningThread.Name); packageToWrite.WriteInt(2, waitingThread.WrappedThread.ManagedThreadId); packageToWrite.WriteString(3, waitingThread.Name); packageToWrite.WriteLong(4, timer.ElapsedMilliseconds); byte[] buffer = new byte[packageToWrite.PackageLength]; packageToWrite.WritePackageToBuffer(buffer, 0); this.outputWriter.Write(buffer); this.outputWriter.Flush(); this.outputStream.Flush(); }
/// <summary> /// Creates an RCPackage from this command. /// </summary> /// <returns>The created RCPackage.</returns> public RCPackage ToPackage() { RCPackage package = RCPackage.CreateCustomDataPackage(RCCommand.COMMAND_PACKAGEFORMAT); package.WriteString(0, this.commandType ?? string.Empty); package.WriteIntArray(1, this.recipientEntities); package.WriteInt(2, this.targetPosition != RCNumVector.Undefined ? this.targetPosition.X.Bits : -1); package.WriteInt(3, this.targetPosition != RCNumVector.Undefined ? this.targetPosition.Y.Bits : -1); package.WriteInt(4, this.targetEntity); package.WriteString(5, this.parameter ?? string.Empty); return(package); }
/// <summary> /// The starting function of the announcer thread. /// </summary> private void AnnounceProc() { while (!this.announcementFinished.WaitOne(NetworkingSystemConstants.ANNOUNCEMENT_FREQUENCY)) { LobbyInfo lobbyInfo = new LobbyInfo(this.announcedLobby.Id, "", this.announcedLobby.PortNum); if (null != this.customDataProvider) { lobbyInfo.CustomData = this.customDataProvider.CustomData; } RCPackage lobbyInfoPackage = lobbyInfo.Package; BroadcastPackage_i(lobbyInfoPackage); } /// Announce finished so we broadcast a FORMAT_LOBBY_INFO_VANISHED message. RCPackage lobbyVanishedPackage = RCPackage.CreateCustomDataPackage(Network.FORMAT_LOBBY_INFO_VANISHED); lobbyVanishedPackage.WriteString(0, this.announcedLobby.Id.ToString()); for (int i = 0; i < NetworkingSystemConstants.ANNOUNCEMENT_BROADCAST_MULTIPLICITY; i++) { /// Broadcast more than once because of possible package lost on UDP. BroadcastPackage_i(lobbyVanishedPackage); } }
/// <summary> /// Call this function when an error occurs during the simulation stage. /// </summary> /// <param name="reason">The reason of the error.</param> /// <param name="customData">Custom data about the error.</param> public void SimulationStageError(string reason, byte[] customData) { if (!this.initialized) { throw new DssException("DssSimulationMgr is uninitialized!"); } /// If we are currently finishing the simulation --> do nothing if (this.hostLeft) { return; } /// Stop the alarm clocks StopCommitTimeoutClock(); StopSimulationFrameClock(); UnregisterAllCommitMonitors(); /// Send the DSS_SIM_ERROR message to the others RCPackage errPackage = RCPackage.CreateNetworkCustomPackage(DssRoot.DSS_SIM_ERROR); errPackage.WriteString(0, reason); errPackage.WriteByteArray(1, customData); this.root.LobbyIface.SendPackage(errPackage); /// Quit from the DSS immediately this.root.SimulatorIface.SimulationError(reason, customData); this.root.EventQueue.ExitEventLoop(); }
/// <summary> /// Creates the header package of the given map. /// </summary> /// <param name="map">Reference to the map.</param> /// <returns>The data package that contains the header of the given map.</returns> private RCPackage CreateMapHeaderPackage(IMapAccess map) { RCPackage mapHeader = RCPackage.CreateCustomDataPackage(MapFileFormat.MAP_HEADER); Version appVersion = new Version(ConstantsTable.Get <string>("RC.App.Version")); mapHeader.WriteInt(0, appVersion.Major); mapHeader.WriteInt(1, appVersion.Minor); mapHeader.WriteInt(2, appVersion.Build); mapHeader.WriteInt(3, appVersion.Revision); mapHeader.WriteString(4, map.MapName); mapHeader.WriteString(5, map.Tileset.Name); mapHeader.WriteShort(6, (short)map.Size.X); mapHeader.WriteShort(7, (short)map.Size.Y); mapHeader.WriteByte(8, (byte)8); // TODO: get the maximum number of players mapHeader.WriteIntArray(9, new int[0] { }); // TODO: get checksum values of the map return(mapHeader); }
/// <summary> /// Sends a DSS_LEAVE message to the other side of this session. /// </summary> /// <param name="reason">The reason of leaving the DSS.</param> /// <param name="customData">Custom data about leaving the DSS.</param> public void SendLeaveMsg(string reason, byte[] customData) { if (this.sm.CurrentState == this.SendingSetupStepRQ) { RCPackage leaveMsg = RCPackage.CreateNetworkControlPackage(DssRoot.DSS_LEAVE); leaveMsg.WriteString(0, reason); leaveMsg.WriteByteArray(1, customData); this.manager.HostRoot.Lobby.SendControlPackage(leaveMsg, this.channel.Index + 1); } }
private void Form1_Load(object sender, EventArgs e) { ComponentManager.RegisterComponents("RC.Engine.Maps, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", new string[3] { "RC.Engine.Maps.TileSetLoader", "RC.Engine.Maps.MapLoader", "RC.Engine.Maps.MapEditor" }); ComponentManager.StartComponents(); this.tilesetLoader = ComponentManager.GetInterface <ITileSetLoader>(); this.mapLoader = ComponentManager.GetInterface <IMapLoader>(); this.mapEditor = ComponentManager.GetInterface <IMapEditor>(); /// TODO: this is a hack! FileInfo tilesetFile = new FileInfo("../../../../tilesets/test/test.xml"); string xmlStr = File.ReadAllText(tilesetFile.FullName); string imageDir = tilesetFile.DirectoryName; RCPackage tilesetPackage = RCPackage.CreateCustomDataPackage(PackageFormats.TILESET_FORMAT); tilesetPackage.WriteString(0, xmlStr); tilesetPackage.WriteString(1, imageDir); byte[] buffer = new byte[tilesetPackage.PackageLength]; tilesetPackage.WritePackageToBuffer(buffer, 0); ITileSet tileset = this.tilesetLoader.LoadTileSet(buffer); this.map = this.mapLoader.NewMap("TestMap", tileset, "Yellow", new RCIntVector(64, 32)); this.draw = new IsoDraw(); this.replacedTiles = new RCSet <IIsoTile>(); this.terrainTypes = new List <string>(); foreach (ITerrainType terrainType in tileset.TerrainTypes) { this.terrainTypes.Add(terrainType.Name); } this.selectedTerrain = 0; this.Text = this.terrainTypes[this.selectedTerrain]; }
/// <summary> /// Leaves the DSS. /// </summary> private void LeaveDss() { /// Send the DSS_LEAVE message to the host. RCPackage leavePackage = RCPackage.CreateNetworkControlPackage(DssRoot.DSS_LEAVE); leavePackage.WriteString(0, "Guest left DSS!"); leavePackage.WriteByteArray(1, new byte[0] { }); this.guestRoot.Lobby.SendControlPackage(leavePackage); /// Stop the timeout clocks and exit from the event-loop. StopTimeouts(); this.guestRoot.EventQueue.ExitEventLoop(); }
public bool ExecuteNextStep(IDssHostChannel channelToHost) { TraceManager.WriteAllTrace("SETUP_CALL:", TestConsoleTraceFilters.TEST_INFO); TraceManager.WriteAllTrace(string.Format("Guest index: {0}", channelToHost.GuestIndex), TestConsoleTraceFilters.TEST_INFO); TraceManager.WriteAllTrace("Request from host:", TestConsoleTraceFilters.TEST_INFO); RCPackage[] request = channelToHost.RequestFromHost; for (int i = 0; i < request.Length; i++) { TraceManager.WriteAllTrace(request[i], TestConsoleTraceFilters.TEST_INFO); } TraceManager.WriteAllTrace("Channel states:", TestConsoleTraceFilters.TEST_INFO); for (int i = 0; i < channelToHost.ChannelStates.Length; i++) { if (channelToHost.ChannelStates[i] == DssChannelState.GUEST_CONNECTED) { TraceManager.WriteAllTrace(string.Format("Channel-{0}: ENGAGED", i), TestConsoleTraceFilters.TEST_INFO); } else if (channelToHost.ChannelStates[i] == DssChannelState.CHANNEL_OPENED) { TraceManager.WriteAllTrace(string.Format("Channel-{0}: OPENED", i), TestConsoleTraceFilters.TEST_INFO); } else if (channelToHost.ChannelStates[i] == DssChannelState.CHANNEL_CLOSED) { TraceManager.WriteAllTrace(string.Format("Channel-{0}: CLOSED", i), TestConsoleTraceFilters.TEST_INFO); } } List <RCPackage> answer = new List <RCPackage>(); while (true) { string input = Console.ReadLine(); if (input.CompareTo("Continue") == 0) { channelToHost.AnswerToHost = answer.ToArray(); return(true); } else if (input.CompareTo("Leave") == 0) { return(false); } else { RCPackage package = RCPackage.CreateNetworkControlPackage(Program.MY_FORMAT); package.WriteString(0, input); answer.Add(package); } } }
/// <summary> /// Sends a DSS_LEAVE message to the lobby and leaves the DSS. /// </summary> private void SendLeaveMessage() { if (!this.initialized) { throw new DssException("DssSimulationMgr is uninitialized!"); } StopCommitTimeoutClock(); StopSimulationFrameClock(); UnregisterAllCommitMonitors(); if (!this.hostLeft) { RCPackage leaveMessage = RCPackage.CreateNetworkCustomPackage(DssRoot.DSS_LEAVE); leaveMessage.WriteString(0, "Leave DSS during simulation stage!"); leaveMessage.WriteByteArray(1, new byte[0] { }); this.root.LobbyIface.SendPackage(leaveMessage); } }
private void txtIO_TextChanged(object sender, EventArgs e) { if (!this.textChangingFromNetwork && this.textBoxMap[(TextBox)sender] == this.lastKnownIdOfThisPeer) { /// Get an interface for sending the message ILobby sendIface = null; if (this.joinedLobby != null && this.createdLobby == null) { sendIface = this.joinedLobby; } else if (this.joinedLobby == null && this.createdLobby != null) { sendIface = this.createdLobby; } if (sendIface != null) { /// Create the package RCPackage package = RCPackage.CreateNetworkCustomPackage(MY_FORMAT); package.WriteString(0, ((TextBox)sender).Text); /// Get the targets of the package List <int> targets = new List <int>(); for (int i = 0; i < this.lastKnownLineStates.Length; i++) { if (i != this.lastKnownIdOfThisPeer && this.targetSelectors[i].Checked) { targets.Add(i); } } if (targets.Count != 0) { /// Send a dedicated message. sendIface.SendPackage(package, targets.ToArray()); } else { /// Send the message to the whole lobby. sendIface.SendPackage(package); } } } }
/// <summary> /// Internal function to send a DSS_CTRL_DROP_GUEST message to the other side of this session. /// </summary> public void DropGuest() { if (this.sm.CurrentState == this.SendingSetupStepRQ) { RCPackage dropGuestMsg = RCPackage.CreateNetworkControlPackage(DssRoot.DSS_CTRL_DROP_GUEST); dropGuestMsg.WriteString(0, "Dropped from the DSS by the host."); dropGuestMsg.WriteByteArray(1, new byte[0] { }); /// Send the DSS_CTRL_DROP_GUEST message to the guest and close the line immediately this.manager.HostRoot.Lobby.SendControlPackage(dropGuestMsg, this.channel.Index + 1); this.manager.HostRoot.Lobby.CloseLine(this.channel.Index + 1); /// Move the session back to inactive state. this.SendingSetupStepRQ_Inactive.Fire(); } else { throw new DssException("Illegal call to DssHostSessionSM.DropGuest"); } }
private void btnTest_Click(object sender, EventArgs e) { int index = this.testButtonMap[(Button)sender]; if (this.joinedLobby == null && this.createdLobby != null && index < this.lastKnownLineStates.Length && index != this.lastKnownIdOfThisPeer && !this.connectingToLobby && this.lastKnownLineStates[index] == LobbyLineState.Engaged) { /// Create the package RCPackage package = RCPackage.CreateNetworkControlPackage(MY_FORMAT); package.WriteString(0, "INTERNAL MESSAGE: " + this.internalCount); this.createdLobby.SendControlPackage(package, index); } else if (this.joinedLobby != null && this.createdLobby == null && index == 0 && !this.connectingToLobby) { /// Create the package RCPackage package = RCPackage.CreateNetworkControlPackage(MY_FORMAT); package.WriteString(0, "INTERNAL MESSAGE: " + this.internalCount); this.joinedLobby.SendControlPackage(package); } this.internalCount++; }
/// <summary> /// Starts the disconnection procedure of this connection. /// </summary> /// <returns>True if the disconnection procedure has been successfully started, false otherwise.</returns> /// <remarks> /// If this function returns false that means that an underlying network error occured and the connection /// has been shutdown immediately. /// </remarks> public bool BeginDisconnect() { if (this.connectionState == LobbyConnectionState.Connected) { /// Send a disconnect indicator message to the other side. RCPackage disconnectIndicator = RCPackage.CreateNetworkControlPackage(Network.FORMAT_DISCONNECT_INDICATOR); disconnectIndicator.WriteString(0, string.Empty); disconnectIndicator.WriteByteArray(1, new byte[0] { }); if (!SendPackage(disconnectIndicator)) { /// Shutdown the connection immediately in case of any error. Shutdown(); return(false); } this.connectionState = LobbyConnectionState.Disconnecting; this.disconnectAckMsgTimer.Start(); return(true); } else { throw new NetworkingSystemException("Unexpected call to LobbyConnection.BeginDisconnect()!"); } }
public DssSetupResult ExecuteNextStep(IDssGuestChannel[] channelsToGuests) { TraceManager.WriteAllTrace("SETUP_CALL:", TestConsoleTraceFilters.TEST_INFO); List <RCPackage>[] requests = new List <RCPackage> [channelsToGuests.Length]; for (int i = 0; i < requests.Length; i++) { requests[i] = new List <RCPackage>(); } while (true) { for (int i = 0; i < channelsToGuests.Length; i++) { if (channelsToGuests[i].ChannelState == DssChannelState.GUEST_CONNECTED) { TraceManager.WriteAllTrace(string.Format("SETUP_CALL: Channel-{0}: ENGAGED", i), TestConsoleTraceFilters.TEST_INFO); RCPackage[] answer = channelsToGuests[i].AnswerFromGuest; for (int j = 0; j < answer.Length; j++) { Console.WriteLine(" " + answer[j]); } } else if (channelsToGuests[i].ChannelState == DssChannelState.CHANNEL_OPENED) { TraceManager.WriteAllTrace(string.Format("SETUP_CALL: Channel-{0}: OPENED", i), TestConsoleTraceFilters.TEST_INFO); } else if (channelsToGuests[i].ChannelState == DssChannelState.CHANNEL_CLOSED) { TraceManager.WriteAllTrace(string.Format("SETUP_CALL: Channel-{0}: CLOSED", i), TestConsoleTraceFilters.TEST_INFO); } } string input = Console.ReadLine(); string[] inputTokens = input.Split(new char[1] { ' ' }); if (inputTokens.Length == 2) { if (inputTokens[0].CompareTo("CloseChannel") == 0) { channelsToGuests[int.Parse(inputTokens[1])].CloseChannel(); } else if (inputTokens[0].CompareTo("OpenChannel") == 0) { channelsToGuests[int.Parse(inputTokens[1])].OpenChannel(); } else if (inputTokens[0].CompareTo("DropAndClose") == 0) { channelsToGuests[int.Parse(inputTokens[1])].DropGuest(false); } else if (inputTokens[0].CompareTo("DropAndOpen") == 0) { channelsToGuests[int.Parse(inputTokens[1])].DropGuest(true); } else { int idx = int.Parse(inputTokens[1]); RCPackage package = RCPackage.CreateNetworkControlPackage(Program.MY_FORMAT); package.WriteString(0, input); requests[idx].Add(package); } } else if (inputTokens.Length == 1) { if (inputTokens[0].CompareTo("Continue") == 0) { for (int i = 0; i < channelsToGuests.Length; i++) { channelsToGuests[i].RequestToGuest = requests[i].ToArray(); } return(DssSetupResult.CONTINUE_SETUP); } else if (inputTokens[0].CompareTo("StartSim") == 0) { return(DssSetupResult.START_SIMULATION); } else if (inputTokens[0].CompareTo("Leave") == 0) { return(DssSetupResult.LEAVE_DSS); } } } }
/// <summary> /// Process all incoming messages arrived from all connections. /// </summary> private void ProcessIncomingMessages() { for (int i = 0; i < this.connections.Length; i++) { if (this.connections[i].ConnectionState == LobbyConnectionState.Connected) { /// The connection is in connected state --> it's incoming messages will be processed by the server List <RCPackage> incomingPackages = new List <RCPackage>(); if (this.connections[i].ReceiveIncomingPackages(ref incomingPackages)) { /// Process the incoming messages foreach (RCPackage package in incomingPackages) { if (package.PackageType == RCPackageType.NETWORK_CUSTOM_PACKAGE) { /// This is a custom message, forward it to every other clients package.Sender = i + 1; for (int j = 0; j < this.connections.Length; j++) { if (i != j && this.connections[j].ConnectionState == LobbyConnectionState.Connected) { if (!this.connections[j].SendPackage(package)) { /// Unable to forward the message to a client --> Shutdown the connection this.connections[j].Shutdown(); this.connections[j].LineState = LobbyLineState.Opened; /// Keep it opened for other clients. SendLineStateReports(); } } } /// Notify the listener object about the arrived package this.listener.PackageArrived(package, i + 1); } else if (package.PackageType == RCPackageType.NETWORK_CONTROL_PACKAGE && package.PackageFormat.ID == Network.FORMAT_DEDICATED_MESSAGE) { /// This is a dedicated message, forward only to the targets byte[] targets = package.ReadByteArray(0); /// List of the targets byte[] theMessageBytes = package.ReadByteArray(1); /// The embedded message int parsedBytes = 0; RCPackage theMessage = RCPackage.Parse(theMessageBytes, 0, theMessageBytes.Length, out parsedBytes); if (theMessage != null && theMessage.IsCommitted && theMessage.PackageType == RCPackageType.NETWORK_CUSTOM_PACKAGE) { /// The embedded message is OK --> forward it to the dedicated targets theMessage.Sender = i + 1; for (int j = 0; j < targets.Length; j++) { int target = targets[j]; if (target == 0) { /// This server is the target this.listener.PackageArrived(theMessage, i + 1); } else if (target - 1 >= 0 && target - 1 < this.connections.Length && target - 1 != i) { /// Another client is the target --> forward the message to it LobbyConnection targetConn = this.connections[target - 1]; if (targetConn.ConnectionState == LobbyConnectionState.Connected) { if (!targetConn.SendPackage(theMessage)) { /// Unable to forward the message to a target --> Shutdown the connection targetConn.Shutdown(); targetConn.LineState = LobbyLineState.Opened; /// Keep it opened for other clients. SendLineStateReports(); } } } } } else { /// The embedded message has unexpected format --> Shutdown the connection this.connections[i].Shutdown(); this.connections[i].LineState = LobbyLineState.Opened; /// Keep it opened for other clients. SendLineStateReports(); break; /// Stop processing the messages of the closed connection } } else if (this.connections[i].ConnectionState == LobbyConnectionState.Connected && package.PackageType == RCPackageType.NETWORK_CONTROL_PACKAGE && package.PackageFormat.ID == Network.FORMAT_DISCONNECT_INDICATOR) { /// The client at the other side of the connection wants to disconnect. /// Acknowledge this request and shutdown the connection. RCPackage disconnAck = RCPackage.CreateNetworkControlPackage(Network.FORMAT_DISCONNECT_ACK); disconnAck.WriteString(0, string.Empty); disconnAck.WriteByteArray(1, new byte[0] { }); this.connections[i].SendPackage(disconnAck); this.connections[i].Shutdown(); this.connections[i].LineState = LobbyLineState.Opened; /// Keep it opened for other clients. SendLineStateReports(); break; /// Stop processing the messages of the closed connection } 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 a client --> notify the listener this.listener.ControlPackageArrived(package, i + 1); } else { /// Unexpected message from the current connection this.connections[i].Shutdown(); this.connections[i].LineState = LobbyLineState.Opened; /// Keep it opened for other clients. SendLineStateReports(); break; /// Stop processing the messages of the closed connection } } /// end-foreach (RCPackage package in incomingPackages) } else { /// In case of receive error, we shutdown the connection. this.connections[i].Shutdown(); this.connections[i].LineState = LobbyLineState.Opened; /// Keep it opened for other clients. SendLineStateReports(); } } else if (this.connections[i].ConnectionState == LobbyConnectionState.Disconnecting) { /// The connection is about to disconnect --> incoming messages will be handled by the connection itself if (this.connections[i].ContinueDisconnect()) { /// This connection remains closed because disconnection is initiated by the server. SendLineStateReports(); } } } /// end-for (int i = 0; i < this.connections.Length; i++) }
/// <summary> /// This function is called when a control package arrives at setup stage. /// </summary> /// <param name="package">The arrived control package.</param> public void SetupStageCtrlPackage(RCPackage package) { bool error = false; if (this.sm.CurrentState == this.WaitingConnectionRQ) { if (package.PackageFormat.ID == DssRoot.DSS_CTRL_CONN_REQUEST) { RCPackage rejPackage = null; int otherMajor = package.ReadInt(0); int otherMinor = package.ReadInt(1); int otherBuild = package.ReadInt(2); int otherRevision = package.ReadInt(3); if (otherMajor >= 0 && otherMinor >= 0 && otherBuild >= 0 && otherRevision >= 0) { Version otherVer = new Version(otherMajor, otherMinor, otherBuild, otherRevision); if (DssRoot.IsCompatibleVersion(otherVer)) { /// We send back a DSS_CTRL_CONN_ACK package. RCPackage ackPackage = RCPackage.CreateNetworkControlPackage(DssRoot.DSS_CTRL_CONN_ACK); ackPackage.WriteInt(0, DssRoot.APPLICATION_VERSION.Major); ackPackage.WriteInt(1, DssRoot.APPLICATION_VERSION.Minor); ackPackage.WriteInt(2, DssRoot.APPLICATION_VERSION.Build); ackPackage.WriteInt(3, DssRoot.APPLICATION_VERSION.Revision); this.manager.HostRoot.Lobby.SendControlPackage(ackPackage, this.channel.Index + 1); this.WaitingConnectionRQ_SendingSetupStepRQ.Fire(); } else { /// We send back a DSS_CTRL_CONN_REJECT package rejPackage = RCPackage.CreateNetworkControlPackage(DssRoot.DSS_CTRL_CONN_REJECT); string reason = string.Format("Incompatible with host version: {0} (RC.DssServices)", DssRoot.APPLICATION_VERSION.ToString()); rejPackage.WriteString(0, reason); rejPackage.WriteByteArray(1, new byte[0]); } } else { /// We create a DSS_CTRL_CONN_REJECT package rejPackage = RCPackage.CreateNetworkControlPackage(DssRoot.DSS_CTRL_CONN_REJECT); rejPackage.WriteString(0, "Unable to parse version information!"); rejPackage.WriteByteArray(1, new byte[0]); } /// We send back a DSS_CTRL_CONN_REJECT package if necessary. if (rejPackage != null && rejPackage.IsCommitted) { this.manager.HostRoot.Lobby.SendControlPackage(rejPackage, this.channel.Index + 1); error = true; } } /// end-if (package.PackageFormat.ID == DssRoot.DSS_CTRL_CONN_REQUEST) } /// end-if (this.sm.CurrentState == this.WaitingConnectionRQ) else if (this.sm.CurrentState == this.WaitingSetupStepAW) { if (package.PackageFormat.ID == DssRoot.DSS_LEAVE) { string leaveReason = package.ReadString(0); string trcMsg = string.Format("Guest-{0} has left the DSS. Reason: {1}", this.channel.Index, leaveReason.Length != 0 ? leaveReason : "-"); TraceManager.WriteAllTrace(trcMsg, DssTraceFilters.SETUP_STAGE_INFO); this.WaitingSetupStepAW_Inactive.Fire(); this.channel.GuestLeaveSetupStage(); } /// end-if (package.PackageFormat.ID == DssRoot.DSS_LEAVE) else { SetupStep currentStep = this.manager.HostRoot.GetStep(this.channel.Index); currentStep.IncomingPackage(package); if (currentStep.State == SetupStepState.READY) { /// Setup step answer arrived. this.WaitingSetupStepAW_SendingSetupStepRQ.Fire(); } else if (currentStep.State == SetupStepState.ERROR) { /// Setup step answer error. error = true; } else { /// Setup step answer not finished yet, more packages to wait. } } } /// end-if (this.sm.CurrentState == this.WaitingSetupStepAW) if (error) { /// Go to error state if the package cannot be handled until now. SetupStageError(); this.channel.SetupStageError(); return; } }
/// <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); } }
public static RCPackage GenerateRandomPackage() { int rndType = rnd.Next(0, 3); int rndFormat = rnd.Next(0, 3); RCPackage retPack = null; if (rndType == 0) { retPack = RCPackage.CreateNetworkPingPackage(); return(retPack); } else if (rndType == 1) { retPack = RCPackage.CreateCustomDataPackage(rndFormat); } else if (rndType == 2) { retPack = RCPackage.CreateNetworkCustomPackage(rndFormat); } RCPackageFormat format = RCPackageFormat.GetPackageFormat(rndFormat); for (int i = 0; i < format.NumOfFields; i++) { RCPackageFieldType datatype = format.GetFieldType(i); if (datatype == RCPackageFieldType.BYTE) { retPack.WriteByte(i, (byte)rnd.Next(byte.MinValue, byte.MaxValue)); } else if (datatype == RCPackageFieldType.SHORT) { retPack.WriteShort(i, (short)rnd.Next(short.MinValue, short.MaxValue)); } else if (datatype == RCPackageFieldType.INT) { retPack.WriteInt(i, (int)rnd.Next(int.MinValue, int.MaxValue)); } else if (datatype == RCPackageFieldType.LONG) { retPack.WriteLong(i, (long)rnd.Next(int.MinValue, int.MaxValue)); } else if (datatype == RCPackageFieldType.STRING) { int strIdx = rnd.Next(0, 10); retPack.WriteString(i, strCollection[strIdx]); } else if (datatype == RCPackageFieldType.BYTE_ARRAY) { int arrLen = rnd.Next(0, 10); byte[] arr = new byte[arrLen]; rnd.NextBytes(arr); retPack.WriteByteArray(i, arr); } else if (datatype == RCPackageFieldType.SHORT_ARRAY) { int arrLen = rnd.Next(0, 10); short[] arr = new short[arrLen]; for (int j = 0; j < arrLen; ++j) { arr[j] = (short)rnd.Next(short.MinValue, short.MaxValue); } retPack.WriteShortArray(i, arr); } else if (datatype == RCPackageFieldType.INT_ARRAY) { int arrLen = rnd.Next(0, 10); int[] arr = new int[arrLen]; for (int j = 0; j < arrLen; ++j) { arr[j] = (int)rnd.Next(int.MinValue, int.MaxValue); } retPack.WriteIntArray(i, arr); } else if (datatype == RCPackageFieldType.LONG_ARRAY) { int arrLen = rnd.Next(0, 10); long[] arr = new long[arrLen]; for (int j = 0; j < arrLen; ++j) { arr[j] = (long)rnd.Next(int.MinValue, int.MaxValue); } retPack.WriteLongArray(i, arr); } else if (datatype == RCPackageFieldType.STRING_ARRAY) { int arrLen = rnd.Next(0, 10); string[] arr = new string[arrLen]; for (int j = 0; j < arrLen; ++j) { int strIdx = rnd.Next(0, 10); arr[j] = strCollection[strIdx]; } retPack.WriteStringArray(i, arr); } else { throw new NetworkingSystemException("Unknown datatype"); } } return(retPack); }