public static FullGameState Create(GameCore game) { var state = new FullGameState(); //Be extra careful: this may cause a race condition: players are added from another thread and may be added while in the enumeration //which crashes the enumerator. If so, just start again try { state.SetPlayers(game.Players.Select(x => x as NetworkPlayer).Where(a => a != null).ToList()); } catch (InvalidOperationException) { //Start over, a player was added game.Logger.Error("[FullGameState.Create()] Recovering from player addition"); return(Create(game)); } state.SetObjects(game); foreach (var mod in ModDatabase.LoadedModulesList) { state.GameLoadedMods.Add(new ModInfo { ModName = mod.Name, ModMajor = mod.Version.Major, ModMinor = mod.Version.Minor }); } state.MapInfo = game.Map.AssetInfo; state.CurrentGameTimeMilliseconds = game.Time.TotalMilliseconds; state.GamemodeReflectionName = game.Gamemode.ReflectionName; state.HasStarted = game.HasStarted; state.GamemodeState = game.Gamemode.FullState; state.Status = game.Status; state.TimescaleString = game.Timescale.DisplayString; state.TimescaleValue = game.Timescale.Fractional; state.FriendlyFireEnabled = game.FriendlyFireEnabled; state.NextObjectId = (ushort)typeof(GameCore).GetField("_nextObjectId", System.Reflection.BindingFlags.Default | System.Reflection.BindingFlags.GetField | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(game); state.GameEndedTime = ((TimeSpan)(typeof(GameCore).GetField("_gameEndedTime", System.Reflection.BindingFlags.Default | System.Reflection.BindingFlags.GetField | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(game))) .TotalMilliseconds; return(state); }
public static FullGameState Read(NetIncomingMessage message) { var state = new FullGameState(); state.MapInfo = ModAssetInfo.Decode(message.ReadBytes(message.ReadUInt16())); state.GamemodeReflectionName = message.ReadString(); state.FriendlyFireEnabled = message.ReadBoolean(); state.HasStarted = message.ReadBoolean(); message.ReadPadBits(); state.GamemodeState = message.ReadBytes(message.ReadInt32()); state.Status = (GameCore.CurrentGameStatus)message.ReadByte(); state.TimescaleString = message.ReadString(); state.TimescaleValue = message.ReadDouble(); state.CurrentGameTimeMilliseconds = message.ReadDouble(); state.NextObjectId = message.ReadUInt16(); state.GameEndedTime = message.ReadDouble(); var objCount = message.ReadInt32(); for (var i = 0; i < objCount; i++) { state.ObjectStates.Add(new FullObjectState(message.ReadBytes(message.ReadInt32()))); } var playersCount = message.ReadInt32(); for (var i = 0; i < playersCount; i++) { state.Players.Add(FullStatePlayer.Read(message)); } var loadedModCount = message.ReadInt32(); for (var i = 0; i < loadedModCount; i++) { state.GameLoadedMods.Add(ModInfo.Decode(message.ReadBytes(message.ReadUInt16()))); } return(state); }