Example #1
0
        public static void SendGameData(GameDataSnapshot data, bool async)
        {
            var cache          = Multiplayer.session.dataSnapshot;
            var mapsData       = new Dictionary <int, byte[]>(cache.mapData);
            var gameData       = cache.gameData;
            var semiPersistent = cache.semiPersistentData;

            void Send()
            {
                var writer = new ByteWriter();

                writer.WriteInt32(mapsData.Count);
                foreach (var mapData in mapsData)
                {
                    writer.WriteInt32(mapData.Key);
                    writer.WritePrefixedBytes(GZipStream.CompressBuffer(mapData.Value));
                }

                writer.WritePrefixedBytes(GZipStream.CompressBuffer(gameData));
                writer.WritePrefixedBytes(GZipStream.CompressBuffer(semiPersistent));

                byte[] data = writer.ToArray();

                OnMainThread.Enqueue(() => Multiplayer.Client?.SendFragmented(Packets.Client_WorldDataUpload, data));
            };

            if (async)
            {
                ThreadPool.QueueUserWorkItem(c => Send());
            }
            else
            {
                Send();
            }
        }
Example #2
0
        public void WriteData(GameDataSnapshot gameData)
        {
            string sectionId = info.sections.Count.ToString("D3");

            using var zip = ZipFile;

            foreach (var(mapId, mapData) in gameData.mapData)
            {
                zip.AddEntry($"maps/{sectionId}_{mapId}_save", mapData);
            }

            foreach (var(mapId, mapCmdData) in gameData.mapCmds)
            {
                if (mapId >= 0)
                {
                    zip.AddEntry($"maps/{sectionId}_{mapId}_cmds", SerializeCmds(mapCmdData));
                }
            }

            if (gameData.mapCmds.TryGetValue(ScheduledCommand.Global, out var worldCmds))
            {
                zip.AddEntry($"world/{sectionId}_cmds", SerializeCmds(worldCmds));
            }

            zip.AddEntry($"world/{sectionId}_save", gameData.gameData);
            info.sections.Add(new ReplaySection(gameData.cachedAtTime, TickPatch.Timer));

            zip.UpdateEntry("info", DirectXmlSaver.XElementFromObject(info, typeof(ReplayInfo)).ToString());
            zip.Save();
        }
Example #3
0
        public static GameDataSnapshot CreateGameDataSnapshot(TempGameData data)
        {
            XmlNode gameNode = data.SaveData.DocumentElement["game"];
            XmlNode mapsNode = gameNode["maps"];

            var dataSnapshot = new GameDataSnapshot();

            foreach (XmlNode mapNode in mapsNode)
            {
                int    id      = int.Parse(mapNode["uniqueID"].InnerText);
                byte[] mapData = ScribeUtil.XmlToByteArray(mapNode);
                dataSnapshot.mapData[id] = mapData;
                dataSnapshot.mapCmds[id] = new List <ScheduledCommand>(Find.Maps.First(m => m.uniqueID == id).AsyncTime().cmds);
            }

            gameNode["currentMapIndex"].RemoveFromParent();
            mapsNode.RemoveAll();

            byte[] gameData = ScribeUtil.XmlToByteArray(data.SaveData);
            dataSnapshot.cachedAtTime       = TickPatch.Timer;
            dataSnapshot.gameData           = gameData;
            dataSnapshot.semiPersistentData = data.SemiPersistent;
            dataSnapshot.mapCmds[ScheduledCommand.Global] = new List <ScheduledCommand>(Multiplayer.WorldComp.cmds);

            return(dataSnapshot);
        }
Example #4
0
        public void LoadCurrentData(int sectionId)
        {
            var    dataSnapshot = new GameDataSnapshot();
            string sectionIdStr = sectionId.ToString("D3");

            using var zip = ZipFile;

            foreach (var mapCmds in zip.SelectEntries($"name = maps/{sectionIdStr}_*_cmds"))
            {
                int mapId = int.Parse(mapCmds.FileName.Split('_')[1]);
                dataSnapshot.mapCmds[mapId] = DeserializeCmds(mapCmds.GetBytes());
            }

            foreach (var mapSave in zip.SelectEntries($"name = maps/{sectionIdStr}_*_save"))
            {
                int mapId = int.Parse(mapSave.FileName.Split('_')[1]);
                dataSnapshot.mapData[mapId] = mapSave.GetBytes();
            }

            var worldCmds = zip[$"world/{sectionIdStr}_cmds"];

            if (worldCmds != null)
            {
                dataSnapshot.mapCmds[ScheduledCommand.Global] = DeserializeCmds(worldCmds.GetBytes());
            }

            dataSnapshot.gameData           = zip[$"world/{sectionIdStr}_save"].GetBytes();
            dataSnapshot.semiPersistentData = new byte[0];

            Multiplayer.session.dataSnapshot = dataSnapshot;
        }
Example #5
0
        public void HandleWorldData(ByteReader data)
        {
            connection.State = ConnectionStateEnum.ClientPlaying;
            Log.Message("Game data size: " + data.Length);

            int factionId = data.ReadInt32();

            Multiplayer.session.myFactionId = factionId;

            int tickUntil = data.ReadInt32();

            var dataSnapshot = new GameDataSnapshot();

            byte[] worldData = GZipStream.UncompressBuffer(data.ReadPrefixedBytes());
            dataSnapshot.gameData = worldData;

            byte[] semiPersistentData = GZipStream.UncompressBuffer(data.ReadPrefixedBytes());
            dataSnapshot.semiPersistentData = semiPersistentData;

            List <int> mapsToLoad = new List <int>();

            int mapCmdsCount = data.ReadInt32();

            for (int i = 0; i < mapCmdsCount; i++)
            {
                int mapId = data.ReadInt32();

                int mapCmdsLen = data.ReadInt32();
                List <ScheduledCommand> mapCmds = new List <ScheduledCommand>(mapCmdsLen);
                for (int j = 0; j < mapCmdsLen; j++)
                {
                    mapCmds.Add(ScheduledCommand.Deserialize(new ByteReader(data.ReadPrefixedBytes())));
                }

                dataSnapshot.mapCmds[mapId] = mapCmds;
            }

            int mapDataCount = data.ReadInt32();

            for (int i = 0; i < mapDataCount; i++)
            {
                int    mapId      = data.ReadInt32();
                byte[] rawMapData = data.ReadPrefixedBytes();

                byte[] mapData = GZipStream.UncompressBuffer(rawMapData);
                dataSnapshot.mapData[mapId] = mapData;
                mapsToLoad.Add(mapId);
            }

            Session.dataSnapshot           = dataSnapshot;
            Multiplayer.session.localCmdId = data.ReadInt32();
            TickPatch.shouldPause          = data.ReadBool();
            TickPatch.tickUntil            = tickUntil;

            TickPatch.SetSimulation(
                toTickUntil: true,
                onFinish: () => Multiplayer.Client.Send(Packets.Client_WorldReady),
                cancelButtonKey: "Quit",
                onCancel: GenScene.GoToMainMenu // Calls StopMultiplayer through a patch
                );

            ReloadGame(mapsToLoad, true, false);
        }