예제 #1
0
        /// <summary>
        /// Initializes the isometric tiles of the map structure.
        /// </summary>
        /// <param name="isotileListPackage">The package that contains the isometric tile informations.</param>
        private void LoadIsoTiles(RCPackage isotileListPackage)
        {
            string[] terrainIndexTable = isotileListPackage.ReadStringArray(0);
            byte[]   isotileInfoBytes  = isotileListPackage.ReadByteArray(1);

            int offset = 0;

            while (offset < isotileInfoBytes.Length)
            {
                int       parsedBytes;
                RCPackage package = RCPackage.Parse(isotileInfoBytes, offset, isotileInfoBytes.Length - offset, out parsedBytes);
                if (package == null || !package.IsCommitted)
                {
                    throw new MapException("Syntax error!");
                }
                offset += parsedBytes;
                if (package.PackageFormat.ID == MapFileFormat.ISOTILE)
                {
                    RCIntVector        quadCoords   = new RCIntVector(package.ReadShort(0), package.ReadShort(1));
                    TerrainCombination terrainCombo = (TerrainCombination)package.ReadByte(4);
                    string             terrainA     = terrainIndexTable[package.ReadByte(2)];
                    string             terrainB     = terrainCombo != TerrainCombination.Simple ? terrainIndexTable[package.ReadByte(3)] : null;
                    int variantIdx = package.ReadByte(5);

                    this.mapStructure.InitIsoTile(quadCoords,
                                                  terrainCombo == TerrainCombination.Simple ?
                                                  this.mapStructure.Tileset.GetIsoTileType(terrainA) :
                                                  this.mapStructure.Tileset.GetIsoTileType(terrainA, terrainB, terrainCombo),
                                                  variantIdx);
                }
            }
        }
예제 #2
0
        public static void ReadBuffer(byte[] buffer)
        {
            int       pos         = 0;
            int       parsedBytes = 0;
            RCPackage currPackage = null;

            while (true)
            {
                pos        += parsedBytes;
                currPackage = RCPackage.Parse(buffer, pos, 4, out parsedBytes);
                if (currPackage != null)
                {
                    while (!currPackage.IsCommitted)
                    {
                        pos += parsedBytes;
                        if (!currPackage.ContinueParse(buffer, pos, 4, out parsedBytes))
                        {
                            TraceManager.WriteAllTrace("Syntax error", TraceManager.GetTraceFilterID("RC.NetworkingSystem.TestConsole.Info"));
                            return;
                        }
                    }
                    TraceManager.WriteAllTrace("Package arrived", TraceManager.GetTraceFilterID("RC.NetworkingSystem.TestConsole.Info"));
                }
                else
                {
                    TraceManager.WriteAllTrace("Syntax error", TraceManager.GetTraceFilterID("RC.NetworkingSystem.TestConsole.Info"));
                    return;
                }
            }
        }
예제 #3
0
        /// <see cref="IMapLoader.LoadMapHeader"/>
        public MapHeader LoadMapHeader(byte[] data)
        {
            if (!this.initThreadStarted)
            {
                throw new InvalidOperationException("Component has not yet been started!");
            }
            this.initThread.Join();

            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            int offset = 0;

            while (offset < data.Length)
            {
                int       parsedBytes;
                RCPackage package = RCPackage.Parse(data, offset, data.Length - offset, out parsedBytes);
                if (package == null || !package.IsCommitted)
                {
                    throw new MapException("Syntax error!");
                }
                offset += parsedBytes;
                if (package.PackageFormat.ID == MapFileFormat.MAP_HEADER)
                {
                    return(MapHeader.FromPackage(package));
                }
            }

            throw new MapException("Map header information not found!");
        }
예제 #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="byteArray"></param>
        private List <RCPackage> GetLogPackages(byte[] byteArray)
        {
            int offset                = 0;
            int remaining             = byteArray.Length;
            List <RCPackage> packages = new List <RCPackage>();

            while (offset < byteArray.Length)
            {
                int       parsedBytes;
                RCPackage logPackage = RCPackage.Parse(byteArray, offset, remaining, out parsedBytes);
                if (logPackage.IsCommitted &&
                    (logPackage.PackageFormat.ID == Program.EVENT_FORMAT ||
                     logPackage.PackageFormat.ID == Program.FORK_FORMAT ||
                     logPackage.PackageFormat.ID == Program.JOIN_FORMAT ||
                     logPackage.PackageFormat.ID == Program.EXCEPTION_FORMAT))
                {
                    packages.Add(logPackage);
                }
                else
                {
                    throw new Exception(string.Format("Unexpected package format ID: {0}", logPackage.PackageFormat.ID));
                }
                offset    += parsedBytes;
                remaining -= parsedBytes;
            }
            return(packages);
        }
예제 #5
0
        protected override RCPackage ReadPackage_i(ref IPAddress sender)
        {
            try
            {
                if (this.udpSocket.Available >= NetworkingSystemConstants.ANNOUNCEMENT_UDP_POCKET_SIZE)
                {
                    EndPoint rcvFrom       = new IPEndPoint(0, 0);
                    int      bytesReceived = this.udpSocket.ReceiveFrom(this.buffer,
                                                                        NetworkingSystemConstants.ANNOUNCEMENT_UDP_POCKET_SIZE,
                                                                        SocketFlags.None,
                                                                        ref rcvFrom);
                    if (bytesReceived == NetworkingSystemConstants.ANNOUNCEMENT_UDP_POCKET_SIZE)
                    {
                        int       parsedBytes = 0;
                        RCPackage retPackage  = RCPackage.Parse(this.buffer, 0, NetworkingSystemConstants.ANNOUNCEMENT_UDP_POCKET_SIZE, out parsedBytes);
                        if (retPackage != null && retPackage.IsCommitted)
                        {
                            IPEndPoint senderEndpoint = (IPEndPoint)rcvFrom;
                            sender = senderEndpoint.Address;
                            return(retPackage);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                TraceManager.WriteExceptionAllTrace(ex, false);
            }

            sender = IPAddress.Any;
            return(null);
        }
예제 #6
0
        /// <see cref="ITileSetLoader.LoadTileSet"/>
        public ITileSet LoadTileSet(byte[] data)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            int       parsedBytes;
            RCPackage package = RCPackage.Parse(data, 0, data.Length, out parsedBytes);

            if (!package.IsCommitted)
            {
                throw new ArgumentException("TileSet data package is not committed!", "data");
            }
            if (package.PackageType != RCPackageType.CUSTOM_DATA_PACKAGE)
            {
                throw new ArgumentException("TileSet data package must be RCPackageType.CUSTOM_DATA_PACKAGE!", "data");
            }
            if (package.PackageFormat.ID != PackageFormats.TILESET_FORMAT)
            {
                throw new ArgumentException("Format of TileSet data package must be RC.Engine.Maps.TileSetFormat!", "data");
            }

            TileSet tileset = XmlTileSetReader.Read(package.ReadString(0), package.ReadString(1));

            return(tileset);
        }
예제 #7
0
        /// <see cref="IScenarioLoader.LoadScenario"/>
        public Scenario LoadScenario(IMapAccess map, byte[] data)
        {
            if (map == null)
            {
                throw new ArgumentNullException("map");
            }
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            /// Load the packages from the byte array.
            int      offset   = 0;
            Scenario scenario = new Scenario(map);

            while (offset < data.Length)
            {
                int       parsedBytes;
                RCPackage package = RCPackage.Parse(data, offset, data.Length - offset, out parsedBytes);
                if (package == null || !package.IsCommitted)
                {
                    throw new SimulatorException("Syntax error!");
                }
                offset += parsedBytes;
                if (package.PackageFormat.ID == ScenarioFileFormat.MINERAL_FIELD)
                {
                    IQuadTile    quadTile     = map.GetQuadTile(new RCIntVector(package.ReadShort(0), package.ReadShort(1)));
                    MineralField mineralField = new MineralField();
                    mineralField.ResourceAmount.Write(package.ReadInt(2));
                    scenario.AddElementToScenario(mineralField);
                    mineralField.AttachToMap(quadTile);
                }
                else if (package.PackageFormat.ID == ScenarioFileFormat.VESPENE_GEYSER)
                {
                    IQuadTile     quadTile      = map.GetQuadTile(new RCIntVector(package.ReadShort(0), package.ReadShort(1)));
                    VespeneGeyser vespeneGeyser = new VespeneGeyser();
                    vespeneGeyser.ResourceAmount.Write(package.ReadInt(2));
                    scenario.AddElementToScenario(vespeneGeyser);
                    vespeneGeyser.AttachToMap(quadTile);
                }
                else if (package.PackageFormat.ID == ScenarioFileFormat.START_LOCATION)
                {
                    IQuadTile     quadTile      = map.GetQuadTile(new RCIntVector(package.ReadShort(0), package.ReadShort(1)));
                    StartLocation startLocation = new StartLocation(package.ReadByte(2));
                    scenario.AddElementToScenario(startLocation);
                    startLocation.AttachToMap(quadTile);
                }
            }

            /// Check the constraints of the visible entities.
            foreach (Entity entity in scenario.GetElementsOnMap <Entity>(MapObjectLayerEnum.GroundObjects, MapObjectLayerEnum.AirObjects))
            {
                if (entity.CheckPlacementConstraints(entity.MapObject.QuadraticPosition.Location, new RCSet <Entity>()).Count != 0)
                {
                    throw new MapException(string.Format("Entity at {0} is voilating its placement constraints!", entity.MapObject.QuadraticPosition.Location));
                }
            }
            return(scenario);
        }
예제 #8
0
        /// <summary>
        /// Initializes the terrain objects of the map.
        /// </summary>
        /// <param name="terrainObjListPackage">The package that contains the terrain object informations.</param>
        /// <param name="map">Reference to the map.</param>
        private void LoadTerrainObjects(RCPackage terrainObjListPackage, IMapAccess map)
        {
            /// TODO: Avoid this downcast!
            MapAccess mapObj = map as MapAccess;

            if (mapObj == null)
            {
                throw new ArgumentException("The given map cannot be handled by the MapEditor!", "map");
            }

            string[] terrainObjIndexTable = terrainObjListPackage.ReadStringArray(0);
            byte[]   terrainObjInfoBytes  = terrainObjListPackage.ReadByteArray(1);

            int offset = 0;

            while (offset < terrainObjInfoBytes.Length)
            {
                int       parsedBytes;
                RCPackage package = RCPackage.Parse(terrainObjInfoBytes, offset, terrainObjInfoBytes.Length - offset, out parsedBytes);
                if (package == null || !package.IsCommitted)
                {
                    throw new MapException("Syntax error!");
                }
                offset += parsedBytes;
                if (package.PackageFormat.ID == MapFileFormat.TERRAINOBJ)
                {
                    RCIntVector        quadCoords     = new RCIntVector(package.ReadShort(0), package.ReadShort(1));
                    ITerrainObjectType terrainObjType = this.mapStructure.Tileset.GetTerrainObjectType(terrainObjIndexTable[package.ReadByte(2)]);

                    /// TODO: Might be better to create the TerrainObject with a factory?
                    ITerrainObject newObj = new TerrainObject(map, terrainObjType, quadCoords);
                    foreach (ICellDataChangeSet changeset in newObj.Type.CellDataChangesets)
                    {
                        changeset.Apply(newObj);
                    }
                    mapObj.AttachTerrainObject(newObj);
                }
            }

            /// Check the constraints of the terrain objects.
            List <ITerrainObject> terrainObjects = new List <ITerrainObject>(map.TerrainObjects);

            foreach (ITerrainObject terrainObj in terrainObjects)
            {
                mapObj.DetachTerrainObject(terrainObj);
                if (terrainObj.Type.CheckConstraints(map, terrainObj.MapCoords).Count != 0)
                {
                    throw new MapException(string.Format("Terrain object at {0} is voilating the tileset constraints!", terrainObj.MapCoords));
                }
                if (terrainObj.Type.CheckTerrainObjectIntersections(map, terrainObj.MapCoords).Count != 0)
                {
                    throw new MapException(string.Format("Terrain object at {0} intersects other terrain objects!", terrainObj.MapCoords));
                }
                mapObj.AttachTerrainObject(terrainObj);
            }
        }
예제 #9
0
        /// <summary>
        /// Internal function to handle command packages and send them to the simulation manager.
        /// </summary>
        /// <param name="commandPackage">The package that contains the commands.</param>
        /// <param name="senderID">The ID of the sender peer.</param>
        /// <returns>True in case of success, false otherwise.</returns>
        private bool CommandPackageArrived(RCPackage commandPackage, int senderID)
        {
            if (commandPackage == null)
            {
                throw new ArgumentNullException("commandPackage");
            }
            if (!commandPackage.IsCommitted ||
                DssRoot.DSS_COMMAND != commandPackage.PackageFormat.ID)
            {
                throw new ArgumentException("commandPackage");
            }
            if (senderID < 0 || senderID >= this.root.OpCount)
            {
                throw new ArgumentException("senderID");
            }
            if (senderID == this.root.IdOfThisPeer)
            {
                throw new ArgumentException("senderID");
            }

            int roundIdx = commandPackage.ReadInt(0);
            int frameIdx = commandPackage.ReadInt(1);

            byte[] cmdBuffer = commandPackage.ReadByteArray(2);
            if (cmdBuffer.Length == 0)
            {
                return(false);
            }

            List <RCPackage> cmds = new List <RCPackage>();

            int offset         = 0;
            int remainingBytes = cmdBuffer.Length;

            while (offset < cmdBuffer.Length)
            {
                /// Parse and check the next command package.
                int       parsedBytes = 0;
                RCPackage currPackage = RCPackage.Parse(cmdBuffer, offset, remainingBytes, out parsedBytes);
                if (currPackage != null && currPackage.IsCommitted)
                {
                    cmds.Add(currPackage);
                    offset         += parsedBytes;
                    remainingBytes -= parsedBytes;
                }
                else
                {
                    /// Uncommitted command package.
                    return(false);
                }
            }

            return(this.root.SimulationMgr.RegisterCommands(cmds.ToArray(), roundIdx, frameIdx, senderID));
        }
예제 #10
0
        /// <summary>
        /// Constructs a LobbyInfo object from an RCPackage.
        /// </summary>
        /// <param name="source">The package that contains the LobbyInfo data.</param>
        /// <returns>The contructed LobbyInfo or null if no LobbyInfo can be constructed from the given RCPackage.</returns>
        public static LobbyInfo FromRCPackage(RCPackage source)
        {
            if (null != source && source.IsCommitted && source.PackageFormat.ID == Network.FORMAT_LOBBY_INFO)
            {
                string idStr = source.ReadString(0);
                Guid   id;
                if (!Guid.TryParse(idStr, out id))
                {
                    TraceManager.WriteAllTrace(string.Format("Unable to parse {0} as a GUID!", idStr), NetworkingSystemTraceFilters.INFO);
                    return(null);
                }

                byte[]    customDataBytes = source.ReadByteArray(3);
                int       parsedBytes     = 0;
                RCPackage customData      = null;

                if (customDataBytes.Length > 0)
                {
                    RCPackage.Parse(customDataBytes, 0, customDataBytes.Length, out parsedBytes);
                }
                if (customDataBytes.Length == 0 ||
                    (null != customData && customData.IsCommitted && parsedBytes == customDataBytes.Length))
                {
                    LobbyInfo retInfo = new LobbyInfo(id,                                               /// ID
                                                      source.ReadString(1),                             /// IPAddress
                                                      source.ReadInt(2),                                /// PortNumber
                                                      (customDataBytes.Length != 0) ? customData : null /// Custom infos about the lobby
                                                      );
                    return(retInfo);
                }
                else
                {
                    TraceManager.WriteAllTrace("LobbyInfo.FromRCPackage failed: unexpected CustomData package format!", NetworkingSystemTraceFilters.INFO);
                    return(null);
                }
            }
            else
            {
                TraceManager.WriteAllTrace("LobbyInfo.FromRCPackage failed: unexpected package format!", NetworkingSystemTraceFilters.INFO);
                return(null);
            }
        }
예제 #11
0
        /// <see cref="IMapLoader.LoadMap"/>
        public IMapAccess LoadMap(ITileSet tileset, byte[] data)
        {
            if (!this.initThreadStarted)
            {
                throw new InvalidOperationException("Component has not yet been started!");
            }
            this.initThread.Join();

            if (tileset == null)
            {
                throw new ArgumentNullException("tileset");
            }
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            /// Load the packages from the byte array.
            RCPackage mapHeaderPackage      = null;
            RCPackage isotileListPackage    = null;
            RCPackage terrainObjListPackage = null;
            int       offset = 0;

            while (offset < data.Length)
            {
                int       parsedBytes;
                RCPackage package = RCPackage.Parse(data, offset, data.Length - offset, out parsedBytes);
                if (package == null || !package.IsCommitted)
                {
                    throw new MapException("Syntax error!");
                }
                offset += parsedBytes;
                if (package.PackageFormat.ID == MapFileFormat.MAP_HEADER)
                {
                    mapHeaderPackage = package;
                }
                else if (package.PackageFormat.ID == MapFileFormat.ISOTILE_LIST)
                {
                    isotileListPackage = package;
                }
                else if (package.PackageFormat.ID == MapFileFormat.TERRAINOBJ_LIST)
                {
                    terrainObjListPackage = package;
                }
            }

            /// Validate the packages.
            if (mapHeaderPackage == null)
            {
                throw new MapException("Syntax error: map header is missing!");
            }
            if (isotileListPackage == null)
            {
                throw new MapException("Syntax error: isometric-tile-list is missing!");
            }
            if (terrainObjListPackage == null)
            {
                throw new MapException("Syntax error: terrain-object-list is missing!");
            }

            /// Validate the map header.
            MapHeader mapHeader = MapHeader.FromPackage(mapHeaderPackage);

            if (mapHeader.AppVersion > new Version(ConstantsTable.Get <string>("RC.App.Version")))
            {
                throw new MapException(string.Format("Incompatible map version: {0}!", mapHeader.AppVersion));
            }
            if (mapHeader.TilesetName != tileset.Name)
            {
                throw new ArgumentException(string.Format("The given tileset '{0}' has to equal with the map tileset '{1}'!", tileset.Name, mapHeader.TilesetName), "tileset");
            }
            if (mapHeader.MapSize.X > MapStructure.MAX_MAPSIZE || mapHeader.MapSize.Y > MapStructure.MAX_MAPSIZE)
            {
                throw new MapException(string.Format("Map size exceeds the limits: {0}x{0}!", MapStructure.MAX_MAPSIZE));
            }

            MapAccess retObj = new MapAccess(mapHeader.MapName, this.mapStructure);

            this.mapStructure.BeginOpen(tileset, mapHeader.MapSize);
            this.LoadIsoTiles(isotileListPackage);
            this.mapStructure.EndOpen();

            this.LoadTerrainObjects(terrainObjListPackage, retObj);

            // TODO: validate MapHeader.MaxPlayers!
            // TODO: validate the MapHeader checksums!
            return(retObj);
        }
예제 #12
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++)
 }
예제 #13
0
        /// <see cref="LobbyConnection.ReceivePackage_i"/>
        protected override bool ReceivePackage_i(out RCPackage receivedPackage)
        {
            receivedPackage = null;
            while (true)
            {
                /// First we parse the unparsed bytes.
                while (this.unparsedCount != 0)
                {
                    if (this.lastUncommittedPackage != null)
                    {
                        /// Continue parse the old package
                        int  parsedBytes = 0;
                        bool success     = this.lastUncommittedPackage.ContinueParse(this.inBuffer,
                                                                                     this.unparsedOffset,
                                                                                     this.unparsedCount,
                                                                                     out parsedBytes);
                        if (success)
                        {
                            this.unparsedCount  -= parsedBytes;
                            this.unparsedOffset += parsedBytes;
                            if (this.lastUncommittedPackage.IsCommitted)
                            {
                                /// Package has been received
                                receivedPackage             = this.lastUncommittedPackage;
                                this.lastUncommittedPackage = null;
                                return(true);
                            }
                        }
                        else
                        {
                            /// Syntax error
                            return(false);
                        }
                    }
                    else
                    {
                        /// Start a new package
                        int parsedBytes = 0;
                        this.lastUncommittedPackage =
                            RCPackage.Parse(this.inBuffer, this.unparsedOffset, this.unparsedCount, out parsedBytes);
                        if (this.lastUncommittedPackage != null)
                        {
                            this.unparsedCount  -= parsedBytes;
                            this.unparsedOffset += parsedBytes;
                            if (this.lastUncommittedPackage.IsCommitted)
                            {
                                /// Package has been received
                                receivedPackage             = this.lastUncommittedPackage;
                                this.lastUncommittedPackage = null;
                                return(true);
                            }
                        }
                        else
                        {
                            /// Syntax error
                            return(false);
                        }
                    }
                } /// end-while (this.unparsedCount != 0)

                try
                {
                    /// Now we have parsed all bytes remained from the previous turn. Read from the network.
                    if (this.stream.DataAvailable)
                    {
                        int readBytes = this.stream.Read(this.inBuffer, 0, this.inBuffer.Length);
                        this.unparsedOffset = 0;
                        this.unparsedCount  = readBytes;
                    }
                    else
                    {
                        /// No more data available on the network stream.
                        return(true);
                    }
                } /// end-try
                catch (Exception ex)
                {
                    TraceManager.WriteExceptionAllTrace(ex, false);
                    return(false);
                }
            } /// end-while (true)
        }
예제 #14
0
        static void Main(string[] args)
        {
            ConfigurationManager.Initialize("../../../../config/RC.NetworkingSystem.TestConsole/RC.NetworkingSystem.TestConsole.root");

            RCPackageFormat f0 = new RCPackageFormat();
            RCPackageFormat f1 = new RCPackageFormat();
            RCPackageFormat f2 = new RCPackageFormat();

            f0.DefineField(RCPackageFieldType.SHORT);
            f0.DefineField(RCPackageFieldType.SHORT_ARRAY);
            f0.DefineField(RCPackageFieldType.STRING_ARRAY);
            f0.DefineField(RCPackageFieldType.STRING);
            f0.DefineField(RCPackageFieldType.INT);
            f0.DefineField(RCPackageFieldType.INT_ARRAY);

            f1.DefineField(RCPackageFieldType.LONG);
            f1.DefineField(RCPackageFieldType.LONG_ARRAY);
            f1.DefineField(RCPackageFieldType.BYTE_ARRAY);
            f1.DefineField(RCPackageFieldType.BYTE);
            f1.DefineField(RCPackageFieldType.STRING);

            f2.DefineField(RCPackageFieldType.BYTE);
            f2.DefineField(RCPackageFieldType.BYTE_ARRAY);
            f2.DefineField(RCPackageFieldType.LONG_ARRAY);
            f2.DefineField(RCPackageFieldType.LONG);
            f2.DefineField(RCPackageFieldType.INT);
            f2.DefineField(RCPackageFieldType.STRING_ARRAY);

            RCPackageFormat.RegisterFormat(f0, 65000);
            RCPackageFormat.RegisterFormat(f1, 65001);
            RCPackageFormat.RegisterFormat(f2, 65002);

            /// WRITING
            TextWriter writer = new StreamWriter("write.txt");

            byte[] buffer = new byte[10000000];
            int    pos    = 0;

            for (int i = 0; i < 10000; i++)
            {
                RCPackage newPackage = GenerateRandomPackage();
                TraceManager.WriteAllTrace(string.Format("{0}: {1}", i, newPackage.ToString()), TraceManager.GetTraceFilterID("RC.NetworkingSystem.TestConsole.Info"));
                writer.WriteLine(i + ": " + newPackage.ToString());
                pos += newPackage.WritePackageToBuffer(buffer, pos);
            }
            writer.Close();
            /// WRITING BINARY DATA0
            FileStream binStr = new FileStream("bin0.txt", FileMode.Create);

            binStr.Write(buffer, 0, pos);
            binStr.Close();

            /// READING
            pos = 0;
            int       parsedBytes = 0;
            RCPackage currPackage = null;
            int       count       = 0;

            writer = new StreamWriter("read.txt");
            byte[] buffer2 = new byte[10000000];
            int    pos2    = 0;

            while (true)
            {
                int burst = rnd.Next(1, 50);
                pos        += parsedBytes;
                currPackage = RCPackage.Parse(buffer, pos, burst, out parsedBytes);
                if (currPackage != null)
                {
                    bool error = false;
                    while (!currPackage.IsCommitted)
                    {
                        pos  += parsedBytes;
                        burst = rnd.Next(1, 50);
                        if (!currPackage.ContinueParse(buffer, pos, burst, out parsedBytes))
                        {
                            TraceManager.WriteAllTrace("Syntax error", TraceManager.GetTraceFilterID("RC.NetworkingSystem.TestConsole.Info"));
                            writer.WriteLine("Syntax error");
                            error = true;
                        }
                    }
                    if (!error)
                    {
                        TraceManager.WriteAllTrace(string.Format("{0}: {1}", count, currPackage.ToString()), TraceManager.GetTraceFilterID("RC.NetworkingSystem.TestConsole.Info"));
                        writer.WriteLine(count + ": " + currPackage.ToString());
                        pos2 += currPackage.WritePackageToBuffer(buffer2, pos2);
                        count++;
                    }
                    else
                    {
                        break;
                    }
                }
                else
                {
                    TraceManager.WriteAllTrace("Syntax error", TraceManager.GetTraceFilterID("RC.NetworkingSystem.TestConsole.Info"));
                    writer.WriteLine("Syntax error");
                    break;
                }
            }
            writer.Close();

            /// WRITING BINARY DATA1
            binStr = new FileStream("bin1.txt", FileMode.Create);
            binStr.Write(buffer2, 0, pos2);
            binStr.Close();

            TraceManager.WriteAllTrace("READY", TraceManager.GetTraceFilterID("RC.NetworkingSystem.TestConsole.Info"));
            Console.ReadLine();
        }