예제 #1
0
        /// <summary>
        /// Create a new buffered remote function call.
        /// </summary>

        public void CreateRFC(uint inID, string funcName, Buffer buffer)
        {
            if (closed || buffer == null)
            {
                return;
            }
            buffer.MarkAsUsed();

            for (int i = 0; i < rfcs.size; ++i)
            {
                RFC r = rfcs[i];

                if (r.id == inID && r.funcName == funcName)
                {
                    if (r.buffer != null)
                    {
                        r.buffer.Recycle();
                    }
                    r.buffer = buffer;
                    return;
                }
            }

            RFC rfc = new RFC();

            rfc.id       = inID;
            rfc.buffer   = buffer;
            rfc.funcName = funcName;
            rfcs.Add(rfc);
        }
예제 #2
0
        /// <summary>
        /// Create a new buffered remote function call.
        /// </summary>

        public void CreateRFC(uint inID, string funcName, Buffer buffer)
        {
            if (closed || buffer == null)
            {
                return;
            }

            Buffer b = Buffer.Create();

            b.BeginWriting(false).Write(buffer.buffer, buffer.position, buffer.size);
            b.BeginReading();

            for (int i = 0; i < rfcs.size; ++i)
            {
                RFC r = rfcs[i];

                if (r.uid == inID && r.functionName == funcName)
                {
                    if (r.buffer != null)
                    {
                        r.buffer.Recycle();
                    }
                    r.buffer = b;
                    return;
                }
            }

            RFC rfc = new RFC();

            rfc.uid          = inID;
            rfc.buffer       = b;
            rfc.functionName = funcName;
            rfcs.Add(rfc);
        }
예제 #3
0
        /// <summary>
        /// Remove the specified player from the channel.
        /// </summary>

        public void RemovePlayer(TcpPlayer p, List <uint> destroyedObjects)
        {
            destroyedObjects.Clear();

            if (players.Remove(p))
            {
                // When the host leaves, clear the host (it gets changed in SendLeaveChannel)
                if (p == host)
                {
                    host = null;
                }

                // Remove all of the non-persistent objects that were created by this player
                for (int i = created.size; i > 0;)
                {
                    Channel.CreatedObject obj = created[--i];

                    if (obj.playerID == p.id)
                    {
                        if (obj.type == 2)
                        {
                            if (obj.buffer != null)
                            {
                                obj.buffer.Recycle();
                            }
                            uint objID = obj.objectID;
                            created.RemoveAt(i);
                            destroyedObjects.Add(objID);
                            if (objID >= 32768)
                            {
                                mCreatedObjectDictionary.Remove(objID);
                            }
                            DestroyObjectRFCs(objID);
                        }
                        else if (players.size != 0)
                        {
                            // The same operation happens on the client as well
                            obj.playerID = players[0].id;
                        }
                    }
                }

                // Close the channel if it wasn't persistent
                if ((!persistent || playerLimit < 1) && players.size == 0)
                {
                    closed = true;

                    for (int i = 0; i < rfcs.size; ++i)
                    {
                        RFC r = rfcs[i];
                        if (r.data != null)
                        {
                            r.data.Recycle();
                        }
                    }
                    rfcs.Clear();
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Import a previously exported object. Returns its object ID, or '0' if failed.
        /// </summary>

        public uint ImportObject(int playerID, BinaryReader reader)
        {
#if !MODDING
            // Create a new object and read its RCC data
            var co = new CreatedObject();
            co.objectID = GetUniqueID();
            co.type     = 1;
            co.buffer   = Buffer.Create();
            var data = reader.ReadBytes(reader.ReadInt32());
            co.buffer.BeginWriting(false).Write(data);
            co.buffer.EndWriting();
            AddCreatedObject(co);

            // We need to inform all the players in the channel of this object's creation
            var packet = Buffer.Create();
            var writer = packet.BeginPacket(Packet.ResponseCreateObject);
            writer.Write(playerID);
            writer.Write(id);
            writer.Write(co.objectID);
            writer.Write(data);
            packet.EndPacket();
            SendToAll(packet);
            packet.Recycle();

            // Now read all the RFCs
            var size = reader.ReadInt32();

            if (size != 0)
            {
                for (int i = 0; i < size; ++i)
                {
                    var rfc = new RFC();
                    rfc.uid      = reader.ReadUInt32();
                    rfc.objectID = co.objectID;
                    if (rfc.functionID == 0)
                    {
                        rfc.functionName = reader.ReadString();
                    }
                    data = reader.ReadBytes(reader.ReadInt32());

                    var b = Buffer.Create();
                    b.BeginWriting(false).Write(data);
                    b.EndWriting();
                    rfc.data = b;
                    rfcs.Add(rfc);

                    packet = Buffer.Create();
                    rfc.WritePacket(id, packet, 0);
                    SendToAll(packet);
                    packet.Recycle();
                }
            }
            return(co.objectID);
#else
            return(0);
#endif
        }
예제 #5
0
        /// <summary>
        /// Transfer the specified object to another channel, changing its Object ID in the process.
        /// </summary>

        public CreatedObject TransferObject(uint objectID, Channel other)
        {
            if (objectID < 32768)
            {
                Tools.LogError("Transferring objects only works with objects that were instantiated at run-time.");
            }
            else if (mCreatedObjectDictionary.Remove(objectID))
            {
                for (int i = 0; i < created.size; ++i)
                {
                    CreatedObject obj = created[i];

                    if (obj.objectID == objectID)
                    {
                        // Move the created object over to the other channel
                        obj.objectID = other.GetUniqueID();

                        // If the other channel doesn't contain the object's owner, assign a new owner
                        bool changeOwner = true;

                        for (int b = 0; b < other.players.size; ++b)
                        {
                            if (other.players[b].id == obj.playerID)
                            {
                                changeOwner = false;
                                break;
                            }
                        }

                        if (changeOwner)
                        {
                            obj.playerID = (other.host != null) ? other.host.id : 0;
                        }

                        created.RemoveAt(i);
                        other.created.Add(obj);
                        other.mCreatedObjectDictionary[obj.objectID] = true;

                        // Move RFCs over to the other channel
                        for (int b = rfcs.size; b > 0;)
                        {
                            RFC r = rfcs[--b];

                            if (r.objectID == objectID)
                            {
                                r.objectID = obj.objectID;
                                rfcs.RemoveAt(b);
                                other.rfcs.Add(r);
                            }
                        }
                        return(obj);
                    }
                }
            }
            return(null);
        }
예제 #6
0
        /// <summary>
        /// Add a new saved remote function call.
        /// </summary>

        public void AddRFC(uint uid, string funcName, Buffer buffer)
        {
#if !MODDING
            if (closed || buffer == null)
            {
                return;
            }
            uint objID = (uid >> 8);

            // Ignore objects that don't exist
            if (objID < 32768)
            {
                if (destroyed.Contains(objID))
                {
                    return;
                }
            }
            else if (!mCreatedObjectDictionary.ContainsKey(objID))
            {
                return;
            }

            var b = Buffer.Create();
            b.BeginWriting(false).Write(buffer.buffer, buffer.position, buffer.size);
            b.EndWriting();

            for (int i = 0; i < rfcs.size; ++i)
            {
                var r = rfcs[i];

                if (r.uid == uid && r.functionName == funcName)
                {
                    if (r.data != null)
                    {
                        r.data.Recycle();
                    }
                    r.data = b;

                    // Move this RFC to the end of the list so that it gets called in correct order on load
                    rfcs.RemoveAt(i);
                    rfcs.Add(r);
                    return;
                }
            }

            var rfc = new RFC();
            rfc.uid          = uid;
            rfc.data         = b;
            rfc.functionName = funcName;
            rfcs.Add(rfc);
#endif
        }
예제 #7
0
        /// <summary>
        /// Delete the specified remote function call.
        /// </summary>

        public void DeleteRFC(uint inID, string funcName)
        {
            for (int i = 0; i < rfcs.size; ++i)
            {
                RFC r = rfcs[i];

                if (r.uid == inID && r.functionName == funcName)
                {
                    rfcs.RemoveAt(i);
                    r.data.Recycle();
                }
            }
        }
예제 #8
0
        /// <summary>
        /// Delete the specified remote function call.
        /// </summary>

        public void DestroyObjectRFCs(uint objectID)
        {
            for (int i = rfcs.size; i > 0;)
            {
                RFC r = rfcs[--i];

                if (r.objectID == objectID)
                {
                    rfcs.RemoveAt(i);
                    r.data.Recycle();
                }
            }
        }
예제 #9
0
        /// <summary>
        /// Delete the specified remote function call.
        /// </summary>

        public void DestroyObjectRFCs(uint objectID)
        {
            for (int i = 0; i < rfcs.size;)
            {
                RFC r = rfcs[i];

                if ((r.id >> 8) == objectID)
                {
                    rfcs.RemoveAt(i);
                    r.buffer.Recycle();
                    continue;
                }
                ++i;
            }
        }
예제 #10
0
        /// <summary>
        /// Rebuild the list of known RFC calls.
        /// </summary>

        void RebuildMethodList()
        {
            rebuildMethodList = false;
            mDict0.Clear();
            mDict1.Clear();
            MonoBehaviour[] mbs = GetComponentsInChildren <MonoBehaviour>(true);

            for (int i = 0, imax = mbs.Length; i < imax; ++i)
            {
                MonoBehaviour mb   = mbs[i];
                System.Type   type = mb.GetType();

                MethodInfo[] methods = type.GetMethods(
                    BindingFlags.Public |
                    BindingFlags.NonPublic |
                    BindingFlags.Instance);

                for (int b = 0, bmax = methods.Length; b < bmax; ++b)
                {
                    MethodInfo method = methods[b];

                    if (method.IsDefined(typeof(RFC), true))
                    {
                        CachedFunc ent = new CachedFunc();
                        ent.obj  = mb;
                        ent.func = method;

                        RFC tnc = (RFC)ent.func.GetCustomAttributes(typeof(RFC), true)[0];

                        if (tnc.id > 0)
                        {
                            if (tnc.id < 256)
                            {
                                mDict0[tnc.id] = ent;
                            }
                            else
                            {
                                Debug.LogError("RFC IDs need to be between 1 and 255 (1 byte). If you need more, just don't specify an ID and use the function's name instead.");
                            }
                        }
                        else
                        {
                            mDict1[method.Name] = ent;
                        }
                    }
                }
            }
        }
예제 #11
0
        /// <summary>
        /// Add a new saved remote function call.
        /// </summary>

        public void AddRFC(uint uid, string funcName, Buffer buffer)
        {
            if (closed || buffer == null)
            {
                return;
            }
            uint objID = (uid >> 8);

            // Ignore objects that don't exist
            if (objID < 32768)
            {
                if (destroyed.Contains(objID))
                {
                    return;
                }
            }
            else if (!mCreatedObjectDictionary.ContainsKey(objID))
            {
                return;
            }

            Buffer b = Buffer.Create();

            b.BeginWriting(false).Write(buffer.buffer, buffer.position, buffer.size);
            b.EndWriting();

            for (int i = 0; i < rfcs.size; ++i)
            {
                RFC r = rfcs[i];

                if (r.uid == uid && r.functionName == funcName)
                {
                    if (r.data != null)
                    {
                        r.data.Recycle();
                    }
                    r.data = b;
                    return;
                }
            }

            RFC rfc = new RFC();

            rfc.uid          = uid;
            rfc.data         = b;
            rfc.functionName = funcName;
            rfcs.Add(rfc);
        }
예제 #12
0
        /// <summary>
        /// Save the channel's data into the specified file.
        /// </summary>

        public void SaveTo(BinaryWriter writer)
        {
            writer.Write(Player.version);
            writer.Write(level);
            writer.Write(data);
            writer.Write(objectCounter);
            writer.Write(password);
            writer.Write(persistent);
            writer.Write(playerLimit);
            writer.Write(rfcs.size);

            for (int i = 0; i < rfcs.size; ++i)
            {
                RFC rfc = rfcs[i];
                writer.Write(rfc.id);
                writer.Write(rfc.buffer.size);

                if (rfc.buffer.size > 0)
                {
                    rfc.buffer.BeginReading();
                    writer.Write(rfc.buffer.buffer, rfc.buffer.position, rfc.buffer.size);
                }
            }

            writer.Write(created.size);

            for (int i = 0; i < created.size; ++i)
            {
                CreatedObject co = created[i];
                writer.Write(co.playerID);
                writer.Write(co.uniqueID);
                writer.Write(co.objectID);
                writer.Write(co.buffer.size);

                if (co.buffer.size > 0)
                {
                    co.buffer.BeginReading();
                    writer.Write(co.buffer.buffer, co.buffer.position, co.buffer.size);
                }
            }

            writer.Write(destroyed.size);
            for (int i = 0; i < destroyed.size; ++i)
            {
                writer.Write(destroyed[i]);
            }
        }
예제 #13
0
        /// <summary>
        /// Remove the specified player from the channel.
        /// </summary>

        public void RemovePlayer(TcpPlayer p, List <uint> destroyedObjects)
        {
            destroyedObjects.Clear();

            if (p == host)
            {
                host = null;
            }

            if (players.Remove(p))
            {
                // Remove all of the non-persistent objects that were created by this player
                for (int i = created.size; i > 0;)
                {
                    Channel.CreatedObject obj = created[--i];

                    if (obj.type == 2 && obj.playerID == p.id)
                    {
                        if (obj.buffer != null)
                        {
                            obj.buffer.Recycle();
                        }
                        created.RemoveAt(i);
                        destroyedObjects.Add(obj.uniqueID);
                        DestroyObjectRFCs(obj.uniqueID);
                    }
                }

                // Close the channel if it wasn't persistent
                if ((!persistent || playerLimit < 1) && players.size == 0)
                {
                    closed = true;

                    for (int i = 0; i < rfcs.size; ++i)
                    {
                        RFC r = rfcs[i];
                        if (r.buffer != null)
                        {
                            r.buffer.Recycle();
                        }
                    }
                    rfcs.Clear();
                }
            }
        }
예제 #14
0
        /// <summary>
        /// Create a new buffered remote function call.
        /// </summary>
        public void CreateRFC(uint inID, string funcName, Buffer buffer)
        {
            if (closed || buffer == null) return;
            buffer.MarkAsUsed();

            for (int i = 0; i < rfcs.size; ++i)
            {
            RFC r = rfcs[i];

            if (r.id == inID && r.funcName == funcName)
            {
                if (r.buffer != null) r.buffer.Recycle();
                r.buffer = buffer;
                return;
            }
            }

            RFC rfc = new RFC();
            rfc.id = inID;
            rfc.buffer = buffer;
            rfc.funcName = funcName;
            rfcs.Add(rfc);
        }
예제 #15
0
        /// <summary>
        /// Load the channel's data from the specified file.
        /// </summary>

        public bool LoadFrom(BinaryReader reader, bool keepInMemory = false)
        {
#if !MODDING
            var start   = reader.BaseStream.Position;
            int version = reader.ReadInt32();

            if (version < 20160207)
            {
#if UNITY_EDITOR
                UnityEngine.Debug.LogWarning("Incompatible data: " + version);
#endif
                return(false);
            }

            // Clear all RFCs, just in case
            for (int i = 0; i < rfcs.size; ++i)
            {
                var r = rfcs[i];
                if (r.data != null)
                {
                    r.data.Recycle();
                }
            }

            rfcs.Clear();
            created.Clear();
            destroyed.Clear();
            mCreatedObjectDictionary.Clear();

            level         = reader.ReadString();
            dataNode      = reader.ReadDataNode();
            objectCounter = reader.ReadUInt32();
            password      = reader.ReadString();
            persistent    = reader.ReadBoolean();
            playerLimit   = reader.ReadUInt16();

            int size = reader.ReadInt32();

            for (int i = 0; i < size; ++i)
            {
                var rfc = new RFC();
                rfc.uid = reader.ReadUInt32();
                if (rfc.functionID == 0)
                {
                    rfc.functionName = reader.ReadString();
                }
                var b = Buffer.Create();
                b.BeginWriting(false).Write(reader.ReadBytes(reader.ReadInt32()));
                b.EndWriting();
                rfc.data = b;
                rfcs.Add(rfc);
            }

            size = reader.ReadInt32();

            for (int i = 0; i < size; ++i)
            {
                var co = new CreatedObject();
                co.playerID = reader.ReadInt32();
                co.objectID = reader.ReadUInt32();
                co.playerID = 0;                 // The player ID is no longer valid as player IDs reset on reload
                co.type     = 1;

                var b = Buffer.Create();
                b.BeginWriting(false).Write(reader.ReadBytes(reader.ReadInt32()));
                b.EndWriting();
                co.buffer = b;
                AddCreatedObject(co);

                // TODO: Remove

                /*var r = b.BeginReading();
                 * var rccID = r.ReadByte();
                 * var funcName = (rccID == 0) ? r.ReadString() : null;
                 *
                 * if (funcName == "OnSpawn")
                 * {
                 *      var prefab = r.ReadString();
                 *
                 *      if (prefab == "Vehicle S0")
                 *      {
                 *              var pos = ProceduralTerrain.GetTilePosition(id);
                 *              pos.x = Game.UnitsToMeters(pos.x);
                 *              pos.y = Game.UnitsToMeters(pos.y);
                 *              Debug.Log("/goto " + MathD.RoundToInt(pos.x) + " " + MathD.RoundToInt(pos.y));
                 *      }
                 * }
                 * b.position = 0;*/
            }

            size = reader.ReadInt32();

            for (int i = 0; i < size; ++i)
            {
                uint uid = reader.ReadUInt32();
                if (uid < 32768)
                {
                    destroyed.Add(uid);
                }
            }

            isLocked = reader.ReadBoolean();
            mSource  = null;

#if STANDALONE
            if (!keepInMemory && players.size == 0)
            {
                Reset();
                var end = reader.BaseStream.Position;
                reader.BaseStream.Position = start;
                mSourceSize = (int)(end - start);
                mSource     = reader.ReadBytes(mSourceSize);
            }
#endif
#endif
            return(true);
        }
예제 #16
0
        /// <summary>
        /// Load the channel's data from the specified file.
        /// </summary>
        public bool LoadFrom(BinaryReader reader)
        {
            int version = reader.ReadInt32();
            if (version != Player.version) return false;

            // Clear all RFCs, just in case
            for (int i = 0; i < rfcs.size; ++i)
            {
            RFC r = rfcs[i];
            if (r.buffer != null) r.buffer.Recycle();
            }
            rfcs.Clear();
            created.Clear();
            destroyed.Clear();

            level = reader.ReadString();
            data = reader.ReadString();
            objectCounter = reader.ReadUInt32();
            password = reader.ReadString();
            persistent = reader.ReadBoolean();
            playerLimit = reader.ReadUInt16();

            int size = reader.ReadInt32();

            for (int i = 0; i < size; ++i)
            {
            RFC rfc = new RFC();
            rfc.id = reader.ReadUInt32();
            Buffer b = Buffer.Create();
            b.BeginWriting(false).Write(reader.ReadBytes(reader.ReadInt32()));
            rfc.buffer = b;
            rfcs.Add(rfc);
            }

            size = reader.ReadInt32();

            for (int i = 0; i < size; ++i)
            {
            CreatedObject co = new CreatedObject();
            co.playerID = reader.ReadInt32();
            co.uniqueID = reader.ReadUInt32();
            co.objectID = reader.ReadUInt16();
            Buffer b = Buffer.Create();
            b.BeginWriting(false).Write(reader.ReadBytes(reader.ReadInt32()));
            co.buffer = b;
            created.Add(co);
            }

            size = reader.ReadInt32();
            for (int i = 0; i < size; ++i) destroyed.Add(reader.ReadUInt32());
            return true;
        }
예제 #17
0
        /// <summary>
        /// Load the channel's data from the specified file.
        /// </summary>

        public bool LoadFrom(BinaryReader reader)
        {
            int version = reader.ReadInt32();

            if (version != Player.version)
            {
                return(false);
            }

            // Clear all RFCs, just in case
            for (int i = 0; i < rfcs.size; ++i)
            {
                RFC r = rfcs[i];
                if (r.buffer != null)
                {
                    r.buffer.Recycle();
                }
            }
            rfcs.Clear();
            created.Clear();
            destroyed.Clear();

            level         = reader.ReadString();
            data          = reader.ReadString();
            objectCounter = reader.ReadUInt32();
            password      = reader.ReadString();
            persistent    = reader.ReadBoolean();
            playerLimit   = reader.ReadUInt16();

            int size = reader.ReadInt32();

            for (int i = 0; i < size; ++i)
            {
                RFC rfc = new RFC();
                rfc.id = reader.ReadUInt32();
                Buffer b = Buffer.Create();
                b.BeginWriting(false).Write(reader.ReadBytes(reader.ReadInt32()));
                rfc.buffer = b;
                rfcs.Add(rfc);
            }

            size = reader.ReadInt32();

            for (int i = 0; i < size; ++i)
            {
                CreatedObject co = new CreatedObject();
                co.playerID = reader.ReadInt32();
                co.uniqueID = reader.ReadUInt32();
                co.objectID = reader.ReadUInt16();
                Buffer b = Buffer.Create();
                b.BeginWriting(false).Write(reader.ReadBytes(reader.ReadInt32()));
                co.buffer = b;
                created.Add(co);
            }

            size = reader.ReadInt32();
            for (int i = 0; i < size; ++i)
            {
                destroyed.Add(reader.ReadUInt32());
            }
            return(true);
        }
예제 #18
0
        /// <summary>
        /// Load the channel's data from the specified file.
        /// </summary>

        public bool LoadFrom(BinaryReader reader)
        {
            int version = reader.ReadInt32();

            if (version < 20160207)
            {
#if UNITY_EDITOR
                UnityEngine.Debug.LogWarning("Incompatible data: " + version);
#endif
                return(false);
            }

            // Clear all RFCs, just in case
            for (int i = 0; i < rfcs.size; ++i)
            {
                RFC r = rfcs[i];
                if (r.data != null)
                {
                    r.data.Recycle();
                }
            }

            rfcs.Clear();
            created.Clear();
            destroyed.Clear();
            mCreatedObjectDictionary.Clear();

            level         = reader.ReadString();
            dataNode      = reader.ReadDataNode();
            objectCounter = reader.ReadUInt32();
            password      = reader.ReadString();
            persistent    = reader.ReadBoolean();
            playerLimit   = reader.ReadUInt16();

            int size = reader.ReadInt32();

            for (int i = 0; i < size; ++i)
            {
                RFC rfc = new RFC();
                rfc.uid = reader.ReadUInt32();
                if (rfc.functionID == 0)
                {
                    rfc.functionName = reader.ReadString();
                }
                Buffer b = Buffer.Create();
                b.BeginWriting(false).Write(reader.ReadBytes(reader.ReadInt32()));
                b.EndWriting();
                rfc.data = b;
                rfcs.Add(rfc);
            }

            size = reader.ReadInt32();

            for (int i = 0; i < size; ++i)
            {
                CreatedObject co = new CreatedObject();
                co.playerID = reader.ReadInt32();
                co.objectID = reader.ReadUInt32();
                co.type     = 1;
                Buffer b = Buffer.Create();
                b.BeginWriting(false).Write(reader.ReadBytes(reader.ReadInt32()));
                b.EndWriting();
                co.buffer = b;
                AddCreatedObject(co);
            }

            size = reader.ReadInt32();

            for (int i = 0; i < size; ++i)
            {
                uint uid = reader.ReadUInt32();
                if (uid < 32768)
                {
                    destroyed.Add(uid);
                }
            }

            isLocked = reader.ReadBoolean();
            return(true);
        }
예제 #19
0
        /// <summary>
        /// Save the channel's data into the specified file.
        /// </summary>

        public void SaveTo(BinaryWriter writer)
        {
            writer.Write(Player.version);
            writer.Write(level);
            writer.Write(dataNode);
            writer.Write(objectCounter);
            writer.Write(password);
            writer.Write(persistent);
            writer.Write(playerLimit);

            // Record which objects are temporary and which ones are not
            for (int i = 0; i < created.size; ++i)
            {
                CreatedObject co = created[i];

                if (co.type == 1)
                {
                    mCreatedOBJs.Add(co);
                    mCleanedOBJs.Add(co.objectID);
                }
            }

            // Record all RFCs that don't belong to temporary objects
            for (int i = 0; i < rfcs.size; ++i)
            {
                RFC  rfc   = rfcs[i];
                uint objID = rfc.objectID;

                if (objID < 32768)
                {
                    mCreatedRFCs.Add(rfc);
                }
                else
                {
                    for (int b = 0; b < mCleanedOBJs.size; ++b)
                    {
                        if (mCleanedOBJs.buffer[b] == objID)
                        {
                            mCreatedRFCs.Add(rfc);
                            break;
                        }
                    }
                }
            }

            writer.Write(mCreatedRFCs.size);

            for (int i = 0; i < mCreatedRFCs.size; ++i)
            {
                RFC rfc = mCreatedRFCs[i];
                writer.Write(rfc.uid);
                if (rfc.functionID == 0)
                {
                    writer.Write(rfc.functionName);
                }
                writer.Write(rfc.data.size);
                if (rfc.data.size > 0)
                {
                    writer.Write(rfc.data.buffer, rfc.data.position, rfc.data.size);
                }
            }

            writer.Write(mCreatedOBJs.size);

            for (int i = 0; i < mCreatedOBJs.size; ++i)
            {
                CreatedObject co = mCreatedOBJs[i];
                writer.Write(co.playerID);
                writer.Write(co.objectID);
                writer.Write(co.buffer.size);
                if (co.buffer.size > 0)
                {
                    writer.Write(co.buffer.buffer, co.buffer.position, co.buffer.size);
                }
            }

            writer.Write(destroyed.size);
            for (int i = 0; i < destroyed.size; ++i)
            {
                writer.Write(destroyed[i]);
            }

            mCleanedOBJs.Clear();
            mCreatedOBJs.Clear();
            mCreatedRFCs.Clear();

            writer.Write(isLocked);
        }
예제 #20
0
        /// <summary>
        /// Save the channel's data into the specified file.
        /// </summary>

        public void SaveTo(BinaryWriter writer)
        {
            writer.Write(Player.version);
            writer.Write(level);
            writer.Write(data);
            writer.Write(objectCounter);
            writer.Write(password);
            writer.Write(persistent);
            writer.Write(playerLimit);

            List <uint>          tempObjs    = new List <uint>();
            List <CreatedObject> cleanedObjs = new List <CreatedObject>();
            List <RFC>           cleanedRFCs = new List <RFC>();

            // Record which objects are temporary and which ones are not
            for (int i = 0; i < created.size; ++i)
            {
                CreatedObject co = created[i];
                if (co.type == 1)
                {
                    cleanedObjs.Add(co);
                }
                else
                {
                    tempObjs.Add(co.uniqueID);
                }
            }

            // Record all RFCs that don't belong to temporary objects
            for (int i = 0; i < rfcs.size; ++i)
            {
                RFC rfc = rfcs[i];
                if (!tempObjs.Contains(rfc.objectID))
                {
                    cleanedRFCs.Add(rfc);
                }
            }

            writer.Write(cleanedRFCs.size);

            for (int i = 0; i < cleanedRFCs.size; ++i)
            {
                RFC rfc = cleanedRFCs[i];
                writer.Write(rfc.uid);
                if (rfc.functionID == 0)
                {
                    writer.Write(rfc.functionName);
                }
                writer.Write(rfc.buffer.size);

                if (rfc.buffer.size > 0)
                {
                    rfc.buffer.BeginReading();
                    writer.Write(rfc.buffer.buffer, rfc.buffer.position, rfc.buffer.size);
                }
            }

            writer.Write(cleanedObjs.size);

            for (int i = 0; i < cleanedObjs.size; ++i)
            {
                CreatedObject co = cleanedObjs[i];
                writer.Write(co.playerID);
                writer.Write(co.uniqueID);
                writer.Write(co.objectID);
                writer.Write(co.buffer.size);

                if (co.buffer.size > 0)
                {
                    co.buffer.BeginReading();
                    writer.Write(co.buffer.buffer, co.buffer.position, co.buffer.size);
                }
            }

            writer.Write(destroyed.size);
            for (int i = 0; i < destroyed.size; ++i)
            {
                writer.Write(destroyed[i]);
            }
        }