Beispiel #1
0
        /// <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();
        }
Beispiel #2
0
        /// <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();
        }
Beispiel #3
0
        /// <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();
        }
Beispiel #4
0
        /// <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);
            }
        }
Beispiel #5
0
        /// <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();
        }
Beispiel #6
0
        /// <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);
        }
Beispiel #7
0
        /// <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();
        }
Beispiel #9
0
        /// <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);
        }
Beispiel #10
0
 /// <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);
     }
 }
Beispiel #11
0
        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];
        }
Beispiel #12
0
        /// <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();
        }
Beispiel #13
0
        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);
            }
        }
Beispiel #15
0
        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);
                    }
                }
            }
        }
Beispiel #16
0
        /// <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");
            }
        }
Beispiel #17
0
        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()!");
     }
 }
Beispiel #19
0
        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);
                    }
                }
            }
        }
Beispiel #20
0
 /// <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++)
 }
Beispiel #21
0
        /// <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;
            }
        }
Beispiel #22
0
        /// <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);
            }
        }
Beispiel #23
0
        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);
        }