Beispiel #1
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;
                }
            }
        }
Beispiel #2
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);
            }
        }
        /// <summary>
        /// Continues the connection procedure to the server.
        /// </summary>
        /// <returns>False in case of any error or timeout, true otherwise.</returns>
        /// <remarks>
        /// Calling this function is only allowed on connecting, client-side connections.
        /// This function is called by the connection manager thread from the corresponding LobbyClient.
        /// After calling this function you have to check whether the connection procedure has been finished.
        /// You can do this by reading the out parameter lineStateReport. If this is not null then the
        /// connection procedure has been finished, otherwise you have to wait.
        /// </remarks>
        public bool ContinueConnectToTheServer(out RCPackage lineStateReport)
        {
            if (this.side != LobbyConnectionType.CLIENT_SIDE)
            {
                throw new NetworkingSystemException("Continue connect to server is only allowed on client side LobbyConnections!");
            }
            if (this.connectionState != LobbyConnectionState.Connecting)
            {
                throw new NetworkingSystemException("Continue connect to server is only allowed on connecting LobbyConnections!");
            }

            lineStateReport = null;
            RCPackage incomingMessage = null;

            do
            {
                if (ReceivePackage_i(out incomingMessage))
                {
                    if (incomingMessage != null)
                    {
                        if (incomingMessage.IsCommitted && incomingMessage.PackageType == RCPackageType.NETWORK_CONTROL_PACKAGE &&
                            incomingMessage.PackageFormat.ID == Network.FORMAT_LOBBY_LINE_STATE_REPORT)
                        {
                            lineStateReport = incomingMessage;
                            this.connectAckMsgTimer.Stop();
                            this.connectAckMsgTimer.Reset();
                            this.connectionState = LobbyConnectionState.Connected;
                            this.lastIncomingMsgTimer.Start();
                            this.lastOutgoingMsgTimer.Start();
                            return(true);
                        }
                        else if (incomingMessage.IsCommitted && incomingMessage.PackageType == RCPackageType.NETWORK_CONTROL_PACKAGE &&
                                 incomingMessage.PackageFormat.ID == Network.FORMAT_DISCONNECT_INDICATOR)
                        {
                            /// Connection request is rejected by the server.
                            this.connectAckMsgTimer.Stop();
                            this.connectAckMsgTimer.Reset();
                            this.connectionState = LobbyConnectionState.Disconnected;
                            return(false);
                        }
                    }
                }
                else
                {
                    /// Syntax error --> immediate shutdown
                    return(false);
                }
            } while (incomingMessage != null);

            if (this.connectAckMsgTimer.ElapsedMilliseconds > NetworkingSystemConstants.CONNECT_ACK_TIMEOUT)
            {
                /// Connection timeout --> immedate shutdown
                return(false);
            }
            else
            {
                /// Continue the connection procedure a bit later.
                return(true);
            }
        }
Beispiel #4
0
        /// <summary>
        /// Creates a LobbyInfo structure with custom data.
        /// </summary>
        public LobbyInfo(Guid id, string ipAddress, int portNumber, RCPackage customData)
        {
            if (id == Guid.Empty)
            {
                throw new ArgumentException("Guid.NULL", "id");
            }
            if (ipAddress == null)
            {
                throw new ArgumentNullException("ipAddress");
            }
            if (portNumber < IPEndPoint.MinPort || portNumber > IPEndPoint.MaxPort)
            {
                throw new ArgumentOutOfRangeException("portNumber");
            }

            this.ID         = id;
            this.IPAddress  = ipAddress;
            this.PortNumber = portNumber;
            if (null == customData)
            {
                this.CustomData = null;
            }
            else
            {
                if (customData.IsCommitted)
                {
                    this.CustomData = customData;
                }
                else
                {
                    TraceManager.WriteAllTrace("LobbyInfo.LobbyInfo warning: CustomData is not committed.", NetworkingSystemTraceFilters.INFO);
                    this.CustomData = null;
                }
            }
        }
Beispiel #5
0
        /// <see cref="ILobby.SendPackage"/>
        public bool SendPackage(RCPackage package, int[] targets)
        {
            if (package == null)
            {
                throw new ArgumentNullException("package");
            }
            if (targets == null || targets.Length == 0)
            {
                throw new ArgumentNullException("targets");
            }

            if (package.IsCommitted && package.PackageType == RCPackageType.NETWORK_CUSTOM_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)
            {
                lock (this.tasks)
                {
                    package.Sender = 0; /// Indicate that this package is sent by the server
                    this.tasks.Add(NetworkingTaskType.OUTGOING_MESSAGE);
                    this.outgoingPackages.Push(package);
                    this.outgoingPackageTargets.Push(targets);
                    return(true);
                }
            }
            return(false);
        }
Beispiel #6
0
        /// <summary>
        /// Creates an RCCommand object from the given RCPackage.
        /// </summary>
        /// <param name="cmdPackage">The RCPackage to be deserialized.</param>
        /// <returns>The created RCCommand.</returns>
        public static RCCommand FromPackage(RCPackage cmdPackage)
        {
            if (cmdPackage == null)
            {
                throw new ArgumentNullException("cmdPackage");
            }
            if (!cmdPackage.IsCommitted)
            {
                throw new ArgumentException("The incoming package is not committed!", "cmdPackage");
            }
            if (cmdPackage.PackageFormat.ID != RCCommand.COMMAND_PACKAGEFORMAT)
            {
                throw new ArgumentException("The incoming package is not a command package!", "cmdPackage");
            }

            RCNumVector targetPosition  = RCNumVector.Undefined;
            int         targetPositionX = cmdPackage.ReadInt(2);
            int         targetPositionY = cmdPackage.ReadInt(3);

            if (targetPositionX != -1 && targetPositionY != -1)
            {
                targetPosition = new RCNumVector(new RCNumber(targetPositionX), new RCNumber(targetPositionY));
            }

            return(new RCCommand(
                       cmdPackage.ReadString(0),
                       cmdPackage.ReadIntArray(1),
                       targetPosition,
                       cmdPackage.ReadInt(4),
                       cmdPackage.ReadString(5)));
        }
Beispiel #7
0
        /// <see cref="IMapLoader.SaveMap"/>
        public byte[] SaveMap(IMapAccess map)
        {
            if (!this.initThreadStarted)
            {
                throw new InvalidOperationException("Component has not yet been started!");
            }
            this.initThread.Join();

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

            RCPackage mapHeader      = this.CreateMapHeaderPackage(map);
            RCPackage isotileList    = this.CreateIsoTileListPackage(map);
            RCPackage terrainObjList = this.CreateTerrainObjListPackage(map);

            byte[] retArray = new byte[mapHeader.PackageLength + isotileList.PackageLength + terrainObjList.PackageLength];
            int    offset   = 0;

            offset += mapHeader.WritePackageToBuffer(retArray, offset);
            offset += isotileList.WritePackageToBuffer(retArray, offset);
            offset += terrainObjList.WritePackageToBuffer(retArray, offset);

            return(retArray);
        }
Beispiel #8
0
        /// <see cref="ILobbyListener.PackageArrived"/>
        public void PackageArrived(RCPackage package, int senderID)
        {
            //lock (this.disposeLock) { if (this.objectDisposed) { throw new ObjectDisposedException("DssEventQueue"); } }

            int timestamp = DssRoot.Time;

            /// Preprocess the event in the context of the caller thread.
            lock (this.eventPreprocessors)
            {
                foreach (DssEventPreprocessor preprocessor in this.eventPreprocessors)
                {
                    if (!preprocessor.PackageArrivedPre(package, senderID))
                    {
                        TraceManager.WriteAllTrace(string.Format("Ignoring PACKAGE_ARRIVED({0} ; {1})", package, senderID), DssTraceFilters.EVENT_QUEUE_INFO);
                        return;
                    }
                }
            }

            /// Insert the event to the queue after a successfull preprocess.
            lock (this.queueLock)
            {
                this.eventTypeFifo.Push(DssEventType.PACKAGE_ARRIVED);
                this.packageArgFifo.Push(package);
                this.intArgFifo.Push(senderID);
                this.eventTimestamps.Push(timestamp);
                this.readSemaphore.Release();
            }
        }
Beispiel #9
0
        /// <see cref="ILobbyListener.ControlPackageArrived"/>
        public void ControlPackageArrived(RCPackage package)
        {
            //lock (this.disposeLock) { if (this.objectDisposed) { throw new ObjectDisposedException("DssEventQueue"); } }

            int timestamp = DssRoot.Time;

            /// Preprocess the event in the context of the caller thread.
            lock (this.eventPreprocessors)
            {
                foreach (DssEventPreprocessor preprocessor in this.eventPreprocessors)
                {
                    if (!preprocessor.ControlPackageFromServerPre(package))
                    {
                        TraceManager.WriteAllTrace(string.Format("Ignoring CONTROL_PACKAGE_FROM_SERVER({0})", package), DssTraceFilters.EVENT_QUEUE_INFO);
                        return;
                    }
                }
            }

            /// Insert the event to the queue after a successfull preprocess.
            lock (this.queueLock)
            {
                this.eventTypeFifo.Push(DssEventType.CONTROL_PACKAGE_FROM_SERVER);
                this.packageArgFifo.Push(package);
                this.eventTimestamps.Push(timestamp);
                this.readSemaphore.Release();
            }
        }
Beispiel #10
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);
                }
            }
        }
        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);
        }
Beispiel #12
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!");
        }
Beispiel #13
0
        /// <summary>
        /// Sends reports about the given line states to all connected clients and to the listener of this server.
        /// </summary>
        private void SendLineStateReports(LobbyLineState[] lineStates)
        {
            for (int i = 0; i < this.connections.Length; i++)
            {
                if (this.connections[i].ConnectionState == LobbyConnectionState.Connected)
                {
                    RCPackage lineStateReport = RCPackage.CreateNetworkControlPackage(Network.FORMAT_LOBBY_LINE_STATE_REPORT);
                    lineStateReport.WriteShort(0, (short)(i + 1));   /// The ID of the client that receives the report.
                    byte[] lineStatesBytes = new byte[lineStates.Length];
                    for (int j = 0; j < lineStatesBytes.Length; j++)
                    {
                        lineStatesBytes[j] = (byte)lineStates[j];
                    }
                    lineStateReport.WriteByteArray(1, lineStatesBytes);     /// The list of the line states on this server.

                    /// Send the package
                    if (!this.connections[i].SendPackage(lineStateReport))
                    {
                        /// In case of error, shutdown the connection and notify the other clients again.
                        this.connections[i].Shutdown();
                        this.connections[i].LineState = LobbyLineState.Opened; /// Keep it opened for other clients.
                        SendLineStateReports();
                    }
                }
            }
            this.listener.LineStateReport(0, lineStates);
        }
Beispiel #14
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 #15
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);
        }
Beispiel #16
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 #17
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 #18
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();
        }
        /// <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 #20
0
        /// <see cref="ILobby.SendPackage"/>
        public bool SendPackage(RCPackage package, int[] targets)
        {
            if (package == null)
            {
                throw new ArgumentNullException("package");
            }
            if (targets == null || targets.Length == 0)
            {
                throw new ArgumentNullException("targets");
            }

            if (package.IsCommitted && package.PackageType == RCPackageType.NETWORK_CUSTOM_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)
            {
                lock (this.outgoingPackages)
                {
                    this.outgoingPackages.Add(package);
                    this.outgoingPackageTargets.Add(targets);
                    return(true);
                }
            }
            return(false);
        }
Beispiel #21
0
        /// <see cref="ILobbyServer.SendControlPackage"/>
        public bool SendControlPackage(RCPackage package, int target)
        {
            if (package == null)
            {
                throw new ArgumentNullException("package");
            }
            if (target == 0)
            {
                throw new ArgumentException("Internal message can only be sent to a client!", "target");
            }

            if (package.IsCommitted && 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)
            {
                lock (this.tasks)
                {
                    this.tasks.Add(NetworkingTaskType.OUTGOING_MESSAGE);
                    this.outgoingPackages.Push(package);
                    this.outgoingPackageTargets.Push(new int[1] {
                        target
                    });
                    return(true);
                }
            }
            return(false);
        }
Beispiel #22
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);
            }
        }
Beispiel #23
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);
        }
Beispiel #24
0
 /// <summary>
 /// Called when a NETWORK_CUSTOM_PACKAGE has arrived from the lobby.
 /// </summary>
 /// <remarks>Must be implemented at both server and client side.</remarks>
 public virtual void PackageArrivedHdl(int timestamp, RCPackage package, int senderID)
 {
     if (IsSimulationRunning_i())
     {
         /// Package arrived during simulation stage must be handled.
         if (package.PackageFormat.ID == DssRoot.DSS_COMMAND)
         {
             if (!CommandPackageArrived(package, senderID))
             {
                 this.root.SimulationMgr.SimulationStageError(string.Format("Processing incoming DSS_COMMAND package failed. Sender: {0}. Package: {1}", senderID, package.ToString()),
                                                              new byte[] { });
             }
         }
         else if (package.PackageFormat.ID == DssRoot.DSS_COMMIT)
         {
             if (!this.root.SimulationMgr.RegisterCommit(package, senderID))
             {
                 this.root.SimulationMgr.SimulationStageError(string.Format("Processing incoming DSS_COMMIT package failed. Sender: {0}. Package: {1}", senderID, package.ToString()),
                                                              new byte[] { });
             }
         }
         else if (package.PackageFormat.ID == DssRoot.DSS_COMMIT_ANSWER)
         {
             if (!this.root.SimulationMgr.RegisterCommitAnswer(package, senderID))
             {
                 this.root.SimulationMgr.SimulationStageError(string.Format("Processing incoming DSS_COMMIT_ANSWER package failed. Sender: {0}. Package: {1}", senderID, package.ToString()),
                                                              new byte[] { });
             }
         }
         else if (package.PackageFormat.ID == DssRoot.DSS_LEAVE)
         {
             if (this.root.SimulationMgr.RegisterLeaveMessage(package, senderID))
             {
                 this.root.OperatorLeftSimulationStage(senderID);
             }
             else
             {
                 this.root.SimulationMgr.SimulationStageError(string.Format("Processing incoming DSS_LEAVE package failed. Sender: {0}. Package: {1}", senderID, package.ToString()),
                                                              new byte[] { });
             }
         }
         else if (package.PackageFormat.ID == DssRoot.DSS_SIM_ERROR)
         {
             string errorDescr = package.ReadString(0);
             byte[] customData = package.ReadByteArray(1);
             this.root.SimulationMgr.SimulationStageErrorReceived(string.Format("DSS_SIM_ERROR received from operator-{0}: {1}", senderID, errorDescr), customData);
         }
         else
         {
             this.root.SimulationMgr.SimulationStageError(string.Format("Unexpected package arrived from operator-{0}: {1}", senderID, package.ToString()),
                                                          new byte[] { });
         }
     }
     else
     {
         /// Package arrived during setup stage is not allowed.
         PackageArrivedDuringSetupStage_i(package, senderID);
     }
 }
Beispiel #25
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);
        }
 /// <summary>
 /// Pushes a command into the incoming command queue.
 /// </summary>
 /// <param name="commandPackage">The command to push.</param>
 public void PushIncomingCommand(RCPackage commandPackage)
 {
     if (commandPackage == null)
     {
         throw new ArgumentNullException("commandPackage");
     }
     this.incomingCommands.Add(commandPackage);
 }
Beispiel #27
0
 public void GuestCommand(int guestIndex, RCPackage command)
 {
     if (command.PackageFormat.ID == TestClientMessages.COMMAND)
     {
         PlayerDirection dir = (PlayerDirection)command.ReadByte(0);
         this.simulator.GetPlayer(guestIndex + 1).Direction = dir;
     }
 }
Beispiel #28
0
        /// <summary>
        /// Creates the package that contains the description of the isometric tiles of the given map.
        /// </summary>
        /// <param name="map">Reference to the map.</param>
        /// <returns>The data package that contains the description of the isometric tiles of the given map.</returns>
        private RCPackage CreateIsoTileListPackage(IMapAccess map)
        {
            RCPackage isotileList = RCPackage.CreateCustomDataPackage(MapFileFormat.ISOTILE_LIST);

            /// Create the terrain type index table.
            List <string> terrainTypeList = new List <string>();
            Dictionary <ITerrainType, int> terrainTypeIndexTable = new Dictionary <ITerrainType, int>();
            int terrainTypeIndex = 0;

            foreach (ITerrainType terrainType in map.Tileset.TerrainTypes)
            {
                terrainTypeList.Add(terrainType.Name);
                terrainTypeIndexTable.Add(terrainType, terrainTypeIndex);
                terrainTypeIndex++;
            }
            isotileList.WriteStringArray(0, terrainTypeList.ToArray());

            /// Create the packages of the isometric tiles.
            RCSet <IIsoTile> processedIsoTiles = new RCSet <IIsoTile>();
            List <RCPackage> isotilePackages   = new List <RCPackage>();
            int isotileInfoLength = 0;

            for (int row = 0; row < map.Size.Y; row++)
            {
                for (int column = 0; column < map.Size.X; column++)
                {
                    IIsoTile currIsoTile = map.GetQuadTile(new RCIntVector(column, row)).PrimaryIsoTile;
                    if (!processedIsoTiles.Contains(currIsoTile))
                    {
                        RCPackage isotilePackage = RCPackage.CreateCustomDataPackage(MapFileFormat.ISOTILE);
                        isotilePackage.WriteShort(0, (short)column);
                        isotilePackage.WriteShort(1, (short)row);
                        isotilePackage.WriteByte(2, (byte)terrainTypeIndexTable[currIsoTile.Type.TerrainA]);
                        isotilePackage.WriteByte(3, currIsoTile.Type.TerrainB != null ?
                                                 (byte)terrainTypeIndexTable[currIsoTile.Type.TerrainB] :
                                                 (byte)0);
                        isotilePackage.WriteByte(4, (byte)currIsoTile.Type.Combination);
                        isotilePackage.WriteByte(5, (byte)currIsoTile.VariantIdx);

                        isotilePackages.Add(isotilePackage);
                        processedIsoTiles.Add(currIsoTile);
                        isotileInfoLength += isotilePackage.PackageLength;
                    }
                }
            }

            /// Write the isometric tile packages into the final package
            byte[] isotileInfoBytes = new byte[isotileInfoLength];
            int    offset           = 0;

            foreach (RCPackage isotilePackage in isotilePackages)
            {
                offset += isotilePackage.WritePackageToBuffer(isotileInfoBytes, offset);
            }

            isotileList.WriteByteArray(1, isotileInfoBytes);
            return(isotileList);
        }
        /// <summary>
        /// Registers the given commit answer arrived from the given operator.
        /// </summary>
        /// <param name="commit">The arrived commit answer package.</param>
        /// <param name="senderID">The sender operator.</param>
        /// <returns>True in case of success, false otherwise.</returns>
        public bool RegisterCommitAnswer(RCPackage commitAw, int senderID)
        {
            if (!this.initialized)
            {
                throw new DssException("DssSimulationMgr is uninitialized!");
            }

            /// If we are currently finishing the simulation --> do nothing
            if (this.hostLeft)
            {
                return(true);
            }

            if (commitAw == null || !commitAw.IsCommitted)
            {
                throw new ArgumentException("commitAw");
            }
            if (senderID == this.root.IdOfThisPeer)
            {
                throw new DssException("Unexpected commit answer sender!");
            }
            if (senderID < 0 || senderID >= this.root.OpCount)
            {
                throw new ArgumentException("senderID");
            }

            if (commitAw.PackageFormat.ID != DssRoot.DSS_COMMIT_ANSWER)
            {
                /// Package format error.
                return(false);
            }

            int ticket = commitAw.ReadInt(0);

            if (!this.commitAwMonitors.ContainsKey(ticket))
            {
                /// Unexpected ticket.
                return(false);
            }

            CommitMonitor monitor  = this.commitAwMonitors[ticket];
            int           pingTime = -1;

            if (monitor.AnswerArrived(senderID, out pingTime))
            {
                this.aptCalculators[senderID].NewItem(pingTime);
                if (monitor.IsCommitAnswered)
                {
                    UnregisterCommitMonitor(ticket);
                }
                return(true);
            }
            else
            {
                /// Ping already answered by the sender.
                return(false);
            }
        }
Beispiel #30
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);
            }
        }