using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using GameSaver.Asset;
using GameSaver.Component;
using GameSaver.Menu;
using GameSaver.Network;
using GameSaver.Patches;
using GameSaver.Util;
using HarmonyLib;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using ModdingUtils.Utils;
using Photon.Pun;
using Photon.Realtime;
using RWF;
using Steamworks;
using TMPro;
using UnboundLib;
using UnboundLib.Extensions;
using UnboundLib.GameModes;
using UnboundLib.Networking;
using UnboundLib.Utils;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyFileVersion("1.1.1")]
[assembly: AssemblyInformationalVersion("1.1.1")]
[assembly: IgnoresAccessChecksTo("RoundsWithFriends")]
[assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace GameSaver
{
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("ot.dan.rounds.gamesaver", "GameSaver", "1.1.1")]
[BepInProcess("Rounds.exe")]
public class GameSaver : BaseUnityPlugin
{
private const string ModId = "ot.dan.rounds.gamesaver";
private const string ModName = "Game Saver";
public const string Version = "1.1.1";
public const string ModInitials = "GS";
private const string CompatibilityModName = "GameSaver";
public static GameSaver Instance { get; private set; }
internal static bool AssetsFailed { get; private set; }
internal void Awake()
{
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Expected O, but got Unknown
Instance = this;
ConfigManager.Initialize(((BaseUnityPlugin)this).Config);
try
{
AssetsFailed = !AssetManager.Initialize();
}
catch (Exception arg)
{
AssetsFailed = true;
LogError($"asset initialisation threw: {arg}");
}
if (AssetsFailed)
{
LogError("asset bundle failed to load - GameSaver is disabled for this session.");
return;
}
SaveManager.Initialize();
OpeningPickPatch.Apply(new Harmony("ot.dan.rounds.gamesaver"));
}
internal void Start()
{
if (!AssetsFailed)
{
GameModeManager.AddHook("GameStart", (Func<IGameModeHandler, IEnumerator>)SaveManager.GameStart, 0);
GameModeManager.AddHook("GameEnd", (Func<IGameModeHandler, IEnumerator>)SaveManager.GameEnd);
GameModeManager.AddHook("RoundStart", (Func<IGameModeHandler, IEnumerator>)SaveManager.RoundStart);
GameModeManager.AddHook("RoundEnd", (Func<IGameModeHandler, IEnumerator>)SaveManager.RoundEnd);
GameModeManager.AddHook("PickEnd", (Func<IGameModeHandler, IEnumerator>)SaveManager.PickEnd);
((Component)this).gameObject.AddComponent<LobbyMonitor>();
}
}
public void Log(string debug)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)debug);
}
internal static void LogInfo(string message)
{
if ((Object)(object)Instance != (Object)null)
{
((BaseUnityPlugin)Instance).Logger.LogInfo((object)message);
}
else
{
Debug.Log("[GameSaver] " + message);
}
}
internal static void LogWarning(string message)
{
if ((Object)(object)Instance != (Object)null)
{
((BaseUnityPlugin)Instance).Logger.LogWarning((object)message);
}
else
{
Debug.LogWarning("[GameSaver] " + message);
}
}
internal static void LogError(string message)
{
if ((Object)(object)Instance != (Object)null)
{
((BaseUnityPlugin)Instance).Logger.LogError((object)message);
}
else
{
Debug.LogError("[GameSaver] " + message);
}
}
}
}
namespace GameSaver.Util
{
internal static class ConfigManager
{
internal static ConfigEntry<bool> SaveEnabled { get; private set; }
internal static ConfigEntry<bool> SaveAsHostOnly { get; private set; }
internal static void Initialize(ConfigFile config)
{
SaveEnabled = config.Bind<bool>("General", "SaveEnabled", true, "Automatically save the state of the match after every card pick.");
SaveAsHostOnly = config.Bind<bool>("General", "SaveAsHostOnly", false, "Only write save files when you are the host. Only the host can load a save, so turning this on stops non-hosts filling their disk with saves they can never use.");
}
}
public class SaveManager
{
private class Match
{
public PlayerData Data;
public Player Player;
}
public class GameInfoData
{
public GameData gameData;
public List<SaveData> gameSaves;
private int _rounds = -1;
public string FilePath { get; }
public int rounds
{
get
{
if (_rounds == -1)
{
_rounds = ((gameSaves.Count != 0) ? gameSaves.OrderByDescending((SaveData save) => save.round).First().round : 0);
}
return _rounds;
}
}
internal void InvalidateRounds()
{
_rounds = -1;
}
public GameInfoData(string filePath, GameData gameData, List<SaveData> gameSaves)
{
FilePath = filePath;
this.gameData = gameData;
this.gameSaves = gameSaves;
}
}
[Serializable]
public class GameData
{
[NonSerialized]
public GameObject button;
public long _serializedStartTime;
public int playerAmount;
public string gameMode;
public GameType gameType;
public DateTime StartTime => DateTime.FromBinary(_serializedStartTime);
public GameData(DateTime startTime, int playerAmount, string gameMode, GameType gameType)
{
_serializedStartTime = startTime.ToBinary();
this.playerAmount = playerAmount;
this.gameMode = gameMode;
this.gameType = gameType;
}
}
[Serializable]
public class SaveData
{
[NonSerialized]
public GameObject button;
[NonSerialized]
public GameObject display;
[NonSerialized]
public TextMeshProUGUI loaded;
public long _serializedDateTime;
public SaveType saveType;
public int round;
public int pointsToWinRound = 2;
public int pointsToWin;
public List<string> seralizedPlayers;
private List<PlayerData> _players;
public DateTime Time => DateTime.FromBinary(_serializedDateTime);
public List<PlayerData> players
{
get
{
if (_players != null)
{
return _players;
}
List<PlayerData> list = new List<PlayerData>();
foreach (string item in seralizedPlayers ?? new List<string>())
{
try
{
PlayerData playerData = JsonUtility.FromJson<PlayerData>(item);
if (playerData != null)
{
list.Add(playerData);
}
}
catch (Exception ex)
{
GameSaver.LogWarning("skipping unreadable player entry in save: " + ex.Message);
}
}
return _players = list;
}
set
{
_players = value;
}
}
internal void InvalidateCards()
{
if (_players == null)
{
return;
}
foreach (PlayerData player in _players)
{
player?.InvalidateCards();
}
}
public SaveData(DateTime time, SaveType saveType, int round, int pointsToWinRound, int pointsToWin, List<string> players)
{
_serializedDateTime = time.ToBinary();
this.saveType = saveType;
this.round = round;
this.pointsToWinRound = pointsToWinRound;
this.pointsToWin = pointsToWin;
seralizedPlayers = players;
}
}
[Serializable]
public class PlayerData
{
[NonSerialized]
public GameObject display;
private List<CardInfo> _cards;
public int serializedTeamId;
public string name;
public int serializedColor;
public List<string> serializedCards;
public int rounds;
public int points;
public bool host;
public ulong steamId;
public List<CardInfo> Cards
{
get
{
if (_cards != null)
{
return _cards;
}
List<CardInfo> list = new List<CardInfo>();
foreach (string item in serializedCards ?? new List<string>())
{
list.Add(ResolveCard(item));
}
return _cards = list;
}
}
public PlayerSkin Color => PlayerSkinBank.GetPlayerSkinColors(serializedColor);
public int TeamId => serializedTeamId - 1;
public bool HasTeamId => serializedTeamId > 0;
internal void InvalidateCards()
{
_cards = null;
}
private static CardInfo ResolveCard(string objectName)
{
if (string.IsNullOrEmpty(objectName))
{
return null;
}
try
{
CardInfo cardWithObjectName = Cards.instance.GetCardWithObjectName(objectName);
if (Object.op_Implicit((Object)(object)cardWithObjectName))
{
return cardWithObjectName;
}
}
catch (Exception ex)
{
GameSaver.LogWarning("card lookup for '" + objectName + "' failed: " + ex.GetType().Name + ": " + ex.Message);
}
try
{
CardInfo cardInfoWithName = CardManager.GetCardInfoWithName(objectName);
if (Object.op_Implicit((Object)(object)cardInfoWithName))
{
return cardInfoWithName;
}
}
catch (Exception ex2)
{
GameSaver.LogWarning("card '" + objectName + "' is unresolvable on this client (mod not installed, or a random-card seed that was not generated this session): " + ex2.GetType().Name);
}
try
{
string b = Regex.Replace(objectName, "\\s+", "");
ReadOnlyCollection<CardInfo> hiddenCards = Cards.instance.HiddenCards;
IEnumerable<CardInfo> second;
if (!((Object)(object)CardChoice.instance != (Object)null))
{
IEnumerable<CardInfo> enumerable = (IEnumerable<CardInfo>)(object)new CardInfo[0];
second = enumerable;
}
else
{
IEnumerable<CardInfo> enumerable = CardChoice.instance.cards;
second = enumerable;
}
foreach (CardInfo item in hiddenCards.Concat(second))
{
if (Object.op_Implicit((Object)(object)item) && Object.op_Implicit((Object)(object)((Component)item).gameObject) && string.Equals(Regex.Replace(((Object)((Component)item).gameObject).name, "\\s+", ""), b, StringComparison.OrdinalIgnoreCase))
{
return item;
}
}
}
catch (Exception ex3)
{
GameSaver.LogWarning("fuzzy card lookup for '" + objectName + "' failed: " + ex3.GetType().Name + ": " + ex3.Message);
}
return null;
}
public PlayerData(string name, int color, int teamId, List<CardInfo> cards, int points, int rounds, bool host, ulong steamId)
{
this.name = name;
serializedColor = color;
serializedTeamId = teamId + 1;
serializedCards = new List<string>();
foreach (CardInfo card in cards)
{
if (Object.op_Implicit((Object)(object)card) && Object.op_Implicit((Object)(object)((Component)card).gameObject))
{
serializedCards.Add(((Object)((Component)card).gameObject).name);
}
}
this.points = points;
this.rounds = rounds;
this.host = host;
this.steamId = steamId;
}
}
public enum SaveType
{
PickStart,
PickEnd,
CardPicked,
RoundStart,
RoundEnd,
Manual
}
public enum GameType
{
Local,
Online
}
public static readonly string SavesPath = Path.Combine(Paths.ConfigPath, "Saves");
private static string _gameSavesPath;
private static int _round;
private static Guid _gameGuid;
public static List<GameInfoData> _games = new List<GameInfoData>();
public static SaveData _selectedSave;
private static GameObject _savingObject;
public static List<GameInfoData> orderedGames => (from game in _games
where game != null && game.gameData != null
orderby game.gameData._serializedStartTime descending
select game).ToList();
internal static bool SuppressOpeningPick { get; private set; }
internal static void Initialize()
{
Directory.CreateDirectory(SavesPath);
LoadGames();
}
private static IEnumerator RunGuarded(IEnumerator routine, string what)
{
while (true)
{
object current;
try
{
if (!routine.MoveNext())
{
break;
}
current = routine.Current;
}
catch (Exception arg)
{
GameSaver.LogError($"{what} failed: {arg}");
break;
}
yield return current;
}
}
public static void LoadGames()
{
string[] directories;
try
{
directories = Directory.GetDirectories(SavesPath);
}
catch (Exception ex)
{
GameSaver.LogError("could not enumerate saves folder: " + ex.Message);
return;
}
string[] array = directories;
foreach (string directoryPath in array)
{
if (!Path.GetFileName(directoryPath).StartsWith("Game-", StringComparison.Ordinal))
{
continue;
}
string path = Path.Combine(directoryPath, "game.json");
if (!File.Exists(path))
{
continue;
}
GameData gameData;
try
{
gameData = JsonUtility.FromJson<GameData>(File.ReadAllText(path));
}
catch (Exception ex2)
{
GameSaver.LogWarning("skipping unreadable game.json in '" + Path.GetFileName(directoryPath) + "': " + ex2.Message);
continue;
}
if (gameData == null)
{
continue;
}
string[] files;
try
{
files = Directory.GetFiles(directoryPath);
}
catch (Exception ex3)
{
GameSaver.LogWarning("could not read save folder '" + Path.GetFileName(directoryPath) + "': " + ex3.Message);
continue;
}
List<SaveData> list = new List<SaveData>();
string[] array2 = files;
foreach (string path2 in array2)
{
if (!Path.GetFileName(path2).Contains("save"))
{
continue;
}
try
{
SaveData saveData = JsonUtility.FromJson<SaveData>(File.ReadAllText(path2));
if (saveData != null)
{
list.Add(saveData);
}
}
catch (Exception ex4)
{
GameSaver.LogWarning("skipping unreadable save '" + Path.GetFileName(path2) + "': " + ex4.Message);
}
}
GameInfoData gameInfoData = _games.FirstOrDefault((GameInfoData g) => g?.gameData != null && string.Equals(g.FilePath, directoryPath, StringComparison.OrdinalIgnoreCase));
if (gameInfoData != null)
{
HashSet<long> known = new HashSet<long>(from s in gameInfoData.gameSaves
where s != null
select s._serializedDateTime);
int num = 0;
foreach (SaveData item in list.Where((SaveData save) => !known.Contains(save._serializedDateTime)))
{
gameInfoData.gameSaves.Add(item);
num++;
}
if (num > 0)
{
gameInfoData.InvalidateRounds();
}
}
else
{
_games.Add(new GameInfoData(directoryPath, gameData, list));
}
}
}
internal static IEnumerator PreSave()
{
string savesPath = SavesPath;
Guid gameGuid = _gameGuid;
_gameSavesPath = Path.Combine(savesPath, "Game-" + gameGuid);
Directory.CreateDirectory(_gameSavesPath);
string currentHandlerID = GameModeManager.CurrentHandlerID;
GameType gameType = ((!PhotonNetwork.OfflineMode && PhotonNetwork.CurrentRoom != null) ? GameType.Online : GameType.Local);
GameData gameData = new GameData(DateTime.Now, PlayerManager.instance.players.Count, currentHandlerID, gameType);
File.WriteAllText(Path.Combine(_gameSavesPath, "game.json"), JsonUtility.ToJson((object)gameData));
yield return null;
}
private static List<Match> MatchPlayers(SaveData save)
{
List<Match> list = new List<Match>();
List<Player> list2 = new List<Player>(PlayerManager.instance.players.Where((Player p) => (Object)(object)p?.data?.view != (Object)null));
Room room = (PhotonNetwork.OfflineMode ? null : PhotonNetwork.CurrentRoom);
List<PlayerData> list3 = new List<PlayerData>(save.players.Where((PlayerData p) => p != null));
foreach (PlayerData data in list3.ToList())
{
if (data.steamId > 1)
{
ulong value;
Player val = ((IEnumerable<Player>)list2).FirstOrDefault((Func<Player, bool>)((Player p) => SteamManager.steamIds.TryGetValue(p.data.view.OwnerActorNr, out value) && value == data.steamId));
if (!((Object)(object)val == (Object)null))
{
list.Add(new Match
{
Data = data,
Player = val
});
list2.Remove(val);
list3.Remove(data);
}
}
}
foreach (PlayerData data2 in list3.ToList())
{
if (room == null)
{
break;
}
Player val2 = ((IEnumerable<Player>)list2).FirstOrDefault((Func<Player, bool>)delegate(Player p)
{
Player player = room.GetPlayer(p.data.view.OwnerActorNr);
return player != null && player.NickName == data2.name;
});
if (!((Object)(object)val2 == (Object)null))
{
list.Add(new Match
{
Data = data2,
Player = val2
});
list2.Remove(val2);
list3.Remove(data2);
}
}
if (room == null && save.players.Count == PlayerManager.instance.players.Count)
{
foreach (PlayerData item in list3.ToList())
{
int num = save.players.IndexOf(item);
if (num >= 0 && num < PlayerManager.instance.players.Count)
{
Player val3 = PlayerManager.instance.players[num];
if (!((Object)(object)val3 == (Object)null) && list2.Contains(val3))
{
list.Add(new Match
{
Data = item,
Player = val3
});
list2.Remove(val3);
list3.Remove(item);
GameSaver.LogInfo($"matched saved player '{item.name}' by position {num} (no steam id or nickname match).");
}
}
}
}
foreach (PlayerData item2 in list3)
{
GameSaver.LogWarning("saved player '" + item2.name + "' could not be matched to anyone in this lobby - their cards and score were not restored.");
}
foreach (Player item3 in list2)
{
GameSaver.LogWarning("player '" + PlayerName(item3) + "' is in this lobby but not in the save - they start fresh.");
}
return list;
}
private static string PlayerName(Player player)
{
try
{
Room currentRoom = PhotonNetwork.CurrentRoom;
if (currentRoom == null)
{
return $"player {player.playerID}";
}
Player player2 = currentRoom.GetPlayer(player.data.view.OwnerActorNr);
return ((player2 != null) ? player2.NickName : null) ?? $"player {player.playerID}";
}
catch
{
return $"player {player.playerID}";
}
}
private static void RestorePlayerCards(Match match)
{
try
{
List<CardInfo> cards = match.Data.Cards;
CardInfo[] array = cards.Where((CardInfo c) => Object.op_Implicit((Object)(object)c)).ToArray();
if (array.Length != cards.Count)
{
GameSaver.LogWarning($"{match.Data.name}: {cards.Count - array.Length} of {cards.Count} cards could not be resolved on this client and were skipped.");
}
if (array.Length != 0)
{
Cards.instance.AddCardsToPlayer(match.Player, array, true, (string[])null, (float[])null, (float[])null, true);
}
}
catch (Exception arg)
{
GameSaver.LogError($"failed to restore cards for '{match.Data.name}': {arg}");
}
}
private static void ApplyTeamScores(List<Match> matches)
{
foreach (IGrouping<int, Match> item in from m in matches
group m by m.Player.teamID)
{
List<Match> source = item.ToList();
List<int> list = (from m in source
where m.Data.HasTeamId
select m.Data.TeamId).Distinct().ToList();
if (list.Count > 1)
{
GameSaver.LogWarning($"team {item.Key} now contains players who were on {list.Count} different teams " + "(" + string.Join(", ", source.Select((Match m) => m.Data.name).ToArray()) + "); applying the highest score of the group.");
}
Match match = (from m in source
orderby m.Data.rounds descending, m.Data.points descending
select m).First();
ShareSaveTeamSettings(item.Key, match.Data.points, match.Data.rounds);
}
}
internal static IEnumerator LoadSave()
{
if (_selectedSave == null)
{
yield break;
}
SaveData save = _selectedSave;
_selectedSave = null;
_round = save.round;
ShareSaveGameSettings(save.pointsToWin, save.pointsToWinRound);
yield return null;
List<Match> matches = MatchPlayers(save);
foreach (Match item in matches)
{
RestorePlayerCards(item);
yield return null;
}
ApplyTeamScores(matches);
SuppressOpeningPick = true;
GameSaver.LogInfo($"restored round {save.round} for {matches.Count} player(s); " + "skipping the opening pick so the match resumes straight into the round.");
}
public static void ShareSaveTeamSettings(int teamId, int points, int rounds)
{
NetworkingManager.RPC(typeof(SaveManager), "LoadSaveTeamSettings", new object[3] { teamId, points, rounds });
}
public static void ShareSaveGameSettings(int pointsToWin, int pointsToWinRound)
{
NetworkingManager.RPC(typeof(SaveManager), "LoadSaveGameSettings", new object[3] { pointsToWin, pointsToWinRound, _round });
}
[UnboundRPC]
private static void LoadSaveTeamSettings(int teamId, int points, int rounds)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
try
{
GameModeManager.CurrentHandler.SetTeamScore(teamId, new TeamScore(points, rounds));
if ((Object)(object)UIHandler.instance != (Object)null)
{
if ((Object)(object)UIHandler.instance.roundCounter != (Object)null)
{
ExtensionMethods.InvokeMethod((object)UIHandler.instance.roundCounter, "ReDraw", Array.Empty<object>());
}
if ((Object)(object)UIHandler.instance.roundCounterSmall != (Object)null)
{
ExtensionMethods.InvokeMethod((object)UIHandler.instance.roundCounterSmall, "ReDraw", Array.Empty<object>());
}
}
}
catch (Exception arg)
{
GameSaver.LogError($"could not apply team score for team {teamId}: {arg}");
}
}
[UnboundRPC]
private static void LoadSaveGameSettings(int pointsToWin, int pointsToWinRound, int currentRound)
{
try
{
GameModeManager.CurrentHandler.ChangeSetting("roundsToWinGame", (object)pointsToWin);
GameModeManager.CurrentHandler.ChangeSetting("pointsToWinRound", (object)pointsToWinRound);
_round = currentRound;
}
catch (Exception arg)
{
GameSaver.LogError($"could not apply game settings: {arg}");
}
}
private static void EnsureSavingObject()
{
if ((Object)(object)_savingObject != (Object)null)
{
return;
}
try
{
if ((Object)(object)AssetManager.Saving != (Object)null)
{
_savingObject = Object.Instantiate<GameObject>(AssetManager.Saving);
}
}
catch (Exception ex)
{
GameSaver.LogWarning("could not create the saving indicator: " + ex.Message);
}
}
private static void GameStartPrologue()
{
try
{
if ((Object)(object)SaveLoadMenu.instance != (Object)null)
{
SaveLoadMenu.instance.Reset();
}
EnsureSavingObject();
}
catch (Exception arg)
{
GameSaver.LogError($"preparing a new game failed: {arg}");
}
}
internal static IEnumerator GameStart(IGameModeHandler gm)
{
GameStartPrologue();
_round = 1;
_gameGuid = Guid.NewGuid();
yield return RunGuarded(LoadSave(), "restoring a save");
yield return RunGuarded(PreSave(), "creating the save folder");
}
internal static IEnumerator GameEnd(IGameModeHandler gm)
{
if ((Object)(object)_savingObject != (Object)null)
{
Object.Destroy((Object)(object)_savingObject);
_savingObject = null;
}
_selectedSave = null;
SuppressOpeningPick = false;
yield return null;
}
internal static void SelectSave(GameData gameData, SaveData selectedSave)
{
_selectedSave = selectedSave;
GameModeManager.SetGameMode(gameData.gameMode);
ExtensionMethods.InvokeMethod((object)PrivateRoomHandler.instance, "UnreadyAllPlayers", Array.Empty<object>());
ObjectExtensions.ExecuteAfterGameModeInitialized((MonoBehaviour)(object)PrivateRoomHandler.instance, gameData.gameMode, (Action)delegate
{
SyncMethodStatic.SyncMethod(typeof(PrivateRoomHandler), "SetGameSettings", (int[])null, new object[2]
{
GameModeManager.CurrentHandlerID,
GameModeManager.CurrentHandler.Settings
});
ExtensionMethods.InvokeMethod((object)PrivateRoomHandler.instance, "HandleTeamRules", Array.Empty<object>());
});
}
internal static IEnumerator RoundStart(IGameModeHandler gm)
{
if ((Object)(object)_savingObject != (Object)null)
{
_savingObject.SetActive(false);
}
yield return null;
}
internal static IEnumerator RoundEnd(IGameModeHandler gm)
{
_round++;
yield return null;
}
internal static IEnumerator PickEnd(IGameModeHandler gm)
{
SuppressOpeningPick = false;
yield return RunGuarded(Save(SaveType.PickEnd), "auto-saving after the pick phase");
}
internal static IEnumerator Save(SaveType saveType)
{
if ((ConfigManager.SaveEnabled != null && !ConfigManager.SaveEnabled.Value) || (ConfigManager.SaveAsHostOnly != null && ConfigManager.SaveAsHostOnly.Value && !PhotonNetwork.OfflineMode && !PhotonNetwork.IsMasterClient) || string.IsNullOrEmpty(_gameSavesPath))
{
yield break;
}
EnsureSavingObject();
if ((Object)(object)_savingObject != (Object)null)
{
_savingObject.SetActive(true);
ExtensionMethods.GetOrAddComponent<AnimationAutoDestroy>(_savingObject, false);
}
yield return null;
List<string> list = new List<string>();
bool flag = PhotonNetwork.OfflineMode || PhotonNetwork.CurrentRoom == null;
int num = 1;
foreach (Player item in PlayerManager.instance.players.Where((Player player) => (Object)(object)player != (Object)null))
{
Player val = (flag ? null : PhotonNetwork.CurrentRoom.GetPlayer(item.data.view.OwnerActorNr));
string name = (flag ? (SteamFriends.GetPersonaName() + "-" + num) : (((val != null) ? val.NickName : null) ?? ("Player " + num)));
List<CardInfo> cards = new List<CardInfo>(item.data.currentCards);
TeamScore teamScore = GameModeManager.CurrentHandler.GetTeamScore(item.teamID);
bool host = (flag ? (num == 1) : (val != null && val.IsMasterClient));
ulong value;
ulong steamId = (flag ? 1 : (SteamManager.steamIds.TryGetValue(item.data.view.OwnerActorNr, out value) ? value : 1));
list.Add(JsonUtility.ToJson((object)new PlayerData(name, PlayerExtensions.colorID(item), item.teamID, cards, teamScore.points, teamScore.rounds, host, steamId)));
num++;
}
int pointsToWinRound = (int)GameModeManager.CurrentHandler.Settings["pointsToWinRound"];
int pointsToWin = (int)GameModeManager.CurrentHandler.Settings["roundsToWinGame"];
SaveData saveData = new SaveData(DateTime.Now, saveType, _round, pointsToWinRound, pointsToWin, list);
try
{
File.WriteAllText(Path.Combine(_gameSavesPath, "save" + DateTime.Now.ToBinary() + ".json"), JsonUtility.ToJson((object)saveData, true));
}
catch (Exception ex)
{
GameSaver.LogError("could not write save file: " + ex.Message);
}
yield return null;
}
public static void DeleteGameSave(GameInfoData gameInfoData)
{
_games.Remove(gameInfoData);
if ((Object)(object)SaveLoadMenu.instance != (Object)null)
{
SaveLoadMenu.instance.RemoveGameSaveButtons(gameInfoData);
}
try
{
if (Directory.Exists(gameInfoData.FilePath))
{
Directory.Delete(gameInfoData.FilePath, recursive: true);
}
}
catch (Exception ex)
{
GameSaver.LogError("could not delete save folder: " + ex.Message);
}
}
}
internal static class ShareCodec
{
[Serializable]
private class Payload
{
public SaveManager.GameData game;
public SaveManager.SaveData save;
}
internal static string Encode(SaveManager.GameData game, SaveManager.SaveData save)
{
string s = JsonUtility.ToJson((object)new Payload
{
game = game,
save = save
});
return TextCodec.Frame(TextCodec.Deflate(Encoding.UTF8.GetBytes(s)));
}
internal static bool TryDecode(string code, out SaveManager.GameData game, out SaveManager.SaveData save, out string error)
{
game = null;
save = null;
if (!TextCodec.TryUnframe(code, out var compressed, out error))
{
return false;
}
try
{
Payload payload = JsonUtility.FromJson<Payload>(Encoding.UTF8.GetString(TextCodec.Inflate(compressed)));
if (payload?.game == null || payload.save == null)
{
error = "CODE UNREADABLE";
return false;
}
game = payload.game;
save = payload.save;
return true;
}
catch (Exception ex)
{
GameSaver.LogWarning("could not decode share code: " + ex.Message);
error = "CODE UNREADABLE";
return false;
}
}
}
internal static class ShareManager
{
internal class ExportResult
{
public bool Success;
public string Code;
public string FilePath;
public string Error;
public bool FitsInOneMessage
{
get
{
if (Code != null)
{
return Code.Length <= 2000;
}
return false;
}
}
}
internal class ImportResult
{
public bool Success;
public string Error;
public int Round;
public bool AlreadyHad;
}
internal const int ChatMessageLimit = 2000;
internal static string SharedFolder => Path.Combine(SaveManager.SavesPath, "_shared");
internal static ExportResult Export(SaveManager.GameData game, SaveManager.SaveData save)
{
ExportResult exportResult = new ExportResult();
try
{
exportResult.Code = ShareCodec.Encode(game, save);
try
{
GUIUtility.systemCopyBuffer = exportResult.Code;
}
catch (Exception ex)
{
GameSaver.LogWarning("could not copy the code to the clipboard: " + ex.Message);
}
try
{
Directory.CreateDirectory(SharedFolder);
string text = $"round{save.round}-{game.gameMode}-{save.Time:yyyyMMdd-HHmmss}.txt";
char[] invalidFileNameChars = Path.GetInvalidFileNameChars();
foreach (char oldChar in invalidFileNameChars)
{
text = text.Replace(oldChar, '_');
}
exportResult.FilePath = Path.Combine(SharedFolder, text);
File.WriteAllText(exportResult.FilePath, exportResult.Code);
}
catch (Exception ex2)
{
exportResult.FilePath = null;
GameSaver.LogWarning("could not write the share file: " + ex2.Message);
}
exportResult.Success = true;
GameSaver.LogInfo($"exported round {save.round} as a {exportResult.Code.Length} character code" + ((exportResult.FilePath != null) ? (" (also saved to " + exportResult.FilePath + ")") : ""));
}
catch (Exception arg)
{
exportResult.Error = "EXPORT FAILED";
GameSaver.LogError($"could not export the save: {arg}");
}
return exportResult;
}
internal static ImportResult Import(string code)
{
ImportResult importResult = new ImportResult();
if (!ShareCodec.TryDecode(code, out var game, out var save, out var error))
{
importResult.Error = error;
return importResult;
}
try
{
string text = FindFolderForGame(game) ?? CreateFolderForGame(game);
string path = "save" + save._serializedDateTime + ".json";
string path2 = Path.Combine(text, path);
if (File.Exists(path2))
{
importResult.Success = true;
importResult.AlreadyHad = true;
importResult.Round = save.round;
return importResult;
}
File.WriteAllText(path2, JsonUtility.ToJson((object)save, true));
SaveManager.LoadGames();
importResult.Success = true;
importResult.Round = save.round;
GameSaver.LogInfo($"imported round {save.round} ({game.gameMode}) into {text}");
}
catch (Exception arg)
{
importResult.Error = "IMPORT FAILED";
GameSaver.LogError($"could not import the save: {arg}");
}
return importResult;
}
private static string FindFolderForGame(SaveManager.GameData game)
{
if (!Directory.Exists(SaveManager.SavesPath))
{
return null;
}
string[] directories = Directory.GetDirectories(SaveManager.SavesPath);
foreach (string text in directories)
{
if (!Path.GetFileName(text).StartsWith("Game-", StringComparison.Ordinal))
{
continue;
}
string path = Path.Combine(text, "game.json");
if (!File.Exists(path))
{
continue;
}
try
{
SaveManager.GameData gameData = JsonUtility.FromJson<SaveManager.GameData>(File.ReadAllText(path));
if (gameData != null && gameData._serializedStartTime == game._serializedStartTime)
{
return text;
}
}
catch (Exception)
{
}
}
return null;
}
private static string CreateFolderForGame(SaveManager.GameData game)
{
string text = Path.Combine(SaveManager.SavesPath, "Game-" + Guid.NewGuid());
Directory.CreateDirectory(text);
File.WriteAllText(Path.Combine(text, "game.json"), JsonUtility.ToJson((object)game));
return text;
}
}
internal class SteamManager
{
public static Dictionary<int, ulong> steamIds = new Dictionary<int, ulong>();
public static Player GetPlayerFromSteamId(ulong steamId)
{
if (steamId <= 1 || steamIds.Count == 0)
{
return null;
}
foreach (Player player in PlayerManager.instance.players)
{
if (!((Object)(object)player?.data?.view == (Object)null) && steamIds.TryGetValue(player.data.view.OwnerActorNr, out var value) && value == steamId)
{
return player;
}
}
return null;
}
}
internal static class TextCodec
{
internal const string Prefix = "GS1";
private static uint[] _crcTable;
internal static string Frame(byte[] compressed)
{
return string.Format("{0}-{1:x8}-{2}", "GS1", Crc32(compressed), ToBase64Url(compressed));
}
internal static bool TryUnframe(string code, out byte[] compressed, out string error)
{
compressed = null;
error = null;
if (string.IsNullOrEmpty(code))
{
error = "NO CODE";
return false;
}
string[] array = StripWhitespace(code).Split(new char[1] { '-' }, 3);
if (array.Length != 3 || array[0] != "GS1")
{
error = "NOT A GAMESAVER CODE";
return false;
}
if (!uint.TryParse(array[1], NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var result))
{
error = "NOT A GAMESAVER CODE";
return false;
}
byte[] array2;
try
{
array2 = FromBase64Url(array[2]);
}
catch (Exception)
{
error = "CODE CORRUPTED";
return false;
}
if (Crc32(array2) != result)
{
error = "CODE INCOMPLETE";
return false;
}
compressed = array2;
return true;
}
internal static byte[] Deflate(byte[] data)
{
using MemoryStream memoryStream = new MemoryStream();
using (DeflateStream deflateStream = new DeflateStream(memoryStream, CompressionMode.Compress, leaveOpen: true))
{
deflateStream.Write(data, 0, data.Length);
}
return memoryStream.ToArray();
}
internal static byte[] Inflate(byte[] data)
{
using MemoryStream stream = new MemoryStream(data);
using DeflateStream deflateStream = new DeflateStream(stream, CompressionMode.Decompress);
using MemoryStream memoryStream = new MemoryStream();
byte[] array = new byte[8192];
int count;
while ((count = deflateStream.Read(array, 0, array.Length)) > 0)
{
memoryStream.Write(array, 0, count);
}
return memoryStream.ToArray();
}
internal static string ToBase64Url(byte[] data)
{
return Convert.ToBase64String(data).Replace('+', '-').Replace('/', '_')
.TrimEnd(new char[1] { '=' });
}
internal static byte[] FromBase64Url(string text)
{
string text2 = text.Replace('-', '+').Replace('_', '/');
switch (text2.Length % 4)
{
case 2:
text2 += "==";
break;
case 3:
text2 += "=";
break;
case 1:
throw new FormatException("bad base64url length");
}
return Convert.FromBase64String(text2);
}
internal static string StripWhitespace(string text)
{
StringBuilder stringBuilder = new StringBuilder(text.Length);
foreach (char c in text)
{
if (!char.IsWhiteSpace(c))
{
stringBuilder.Append(c);
}
}
return stringBuilder.ToString();
}
internal static uint Crc32(byte[] data)
{
if (_crcTable == null)
{
uint[] array = new uint[256];
for (uint num = 0u; num < 256; num++)
{
uint num2 = num;
for (int i = 0; i < 8; i++)
{
num2 = (((num2 & 1) == 1) ? (0xEDB88320u ^ (num2 >> 1)) : (num2 >> 1));
}
array[num] = num2;
}
_crcTable = array;
}
uint num3 = uint.MaxValue;
foreach (byte b in data)
{
num3 = _crcTable[(num3 ^ b) & 0xFF] ^ (num3 >> 8);
}
return num3 ^ 0xFFFFFFFFu;
}
}
}
namespace GameSaver.Patches
{
internal static class OpeningPickPatch
{
internal static void Apply(Harmony harmony)
{
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Expected O, but got Unknown
MethodInfo methodInfo = AccessTools.Method("RWF.PlayerManagerExtensions:GetPickOrder", (Type[])null, (Type[])null);
if (methodInfo == null)
{
GameSaver.LogWarning("could not find RWF.PlayerManagerExtensions.GetPickOrder - loading a save will still run the opening card pick.");
}
else
{
harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(OpeningPickPatch), "Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
}
private static void Postfix(int[] winningTeamIDs, ref List<Player> __result)
{
if (SaveManager.SuppressOpeningPick && winningTeamIDs == null)
{
GameSaver.LogInfo($"skipping the opening card pick for {__result?.Count ?? 0} player(s) - a save is being restored.");
__result = new List<Player>();
}
}
}
}
namespace GameSaver.Network
{
public class LobbyMonitor : MonoBehaviourPunCallbacks
{
private static GameObject _loadSaveRow;
private static SaveLoadMenu _menu;
private static TMP_FontAsset _menuFont;
public static LobbyMonitor Instance { get; private set; }
public static TMP_FontAsset MenuFont
{
get
{
if (Object.op_Implicit((Object)(object)_menuFont) || !Object.op_Implicit((Object)(object)MainMenuHandler.instance))
{
return _menuFont;
}
Transform val = ((Component)MainMenuHandler.instance).transform.Find("Canvas/ListSelector/Main/Group/Local");
if ((Object)(object)val == (Object)null)
{
return _menuFont;
}
TextMeshProUGUI componentInChildren = ((Component)val).GetComponentInChildren<TextMeshProUGUI>();
_menuFont = ((componentInChildren != null) ? ((TMP_Text)componentInChildren).font : null);
return _menuFont;
}
}
private void Awake()
{
Instance = this;
}
public override void OnCreatedRoom()
{
}
public override void OnJoinedRoom()
{
if (PhotonNetwork.OfflineMode)
{
return;
}
SteamManager.steamIds.Clear();
ExtensionMethods.ExecuteAfterFrames((MonoBehaviour)(object)Unbound.Instance, 1, (Action)LoadSaveButton);
ExtensionMethods.ExecuteAfterSeconds((MonoBehaviour)(object)Unbound.Instance, 2f, (Action)delegate
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
try
{
SendSteamId(PhotonNetwork.LocalPlayer.ActorNumber, SteamUser.GetSteamID().m_SteamID);
}
catch (Exception ex)
{
GameSaver.LogWarning("could not broadcast steam id: " + ex.Message);
}
});
}
public override void OnPlayerEnteredRoom(Player newPlayer)
{
if (!PhotonNetwork.IsMasterClient)
{
return;
}
ExtensionMethods.ExecuteAfterSeconds((MonoBehaviour)(object)Unbound.Instance, 2.5f, (Action)delegate
{
foreach (KeyValuePair<int, ulong> steamId in SteamManager.steamIds)
{
SendSteamId(steamId.Key, steamId.Value);
}
});
}
public override void OnLeftRoom()
{
SaveManagerResetSelection();
if (!((Object)(object)SaveLoadMenu.instance == (Object)null))
{
SaveLoadMenu.instance.Reset();
}
}
private static void SaveManagerResetSelection()
{
SaveManager._selectedSave = null;
}
public static void SendSteamId(int player, ulong steamId)
{
NetworkingManager.RPC(typeof(LobbyMonitor), "SyncSteamId", new object[2]
{
player,
steamId.ToString()
});
}
[UnboundRPC]
private static void SyncSteamId(int player, string serializedSteamId)
{
try
{
SteamManager.steamIds[player] = ulong.Parse(serializedSteamId);
}
catch (Exception ex)
{
GameSaver.LogWarning($"could not record steam id for actor {player}: {ex.Message}");
}
}
public void LoadSaveButton()
{
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
//IL_0098: Expected O, but got Unknown
//IL_00af: Unknown result type (might be due to invalid IL or missing references)
//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
//IL_0172: Unknown result type (might be due to invalid IL or missing references)
//IL_017c: Expected O, but got Unknown
if (!PhotonNetwork.IsMasterClient || GameSaver.AssetsFailed)
{
return;
}
GameObject val = GameObject.Find("PrivateRoom/Main/Group");
if ((Object)(object)val == (Object)null)
{
GameSaver.LogWarning("private room UI not found - the LOAD button was not added.");
return;
}
if ((Object)(object)_loadSaveRow != (Object)null)
{
Object.Destroy((Object)(object)_loadSaveRow);
}
if ((Object)(object)_menu != (Object)null)
{
Object.Destroy((Object)(object)((Component)_menu).gameObject);
}
Transform val2 = val.transform.Find("LOAD_SAVE");
if ((Object)(object)val2 != (Object)null)
{
Object.Destroy((Object)(object)((Component)val2).gameObject);
}
GameObject val3 = new GameObject("LOAD_SAVE");
val3.transform.SetParent(val.transform);
val3.transform.localScale = Vector3.one;
val3.transform.SetSiblingIndex(val3.transform.GetSiblingIndex() - 1);
GameObject text = GetText("LOAD");
text.transform.SetParent(val3.transform);
text.transform.localScale = Vector3.one;
val3.AddComponent<RectTransform>();
val3.AddComponent<CanvasRenderer>();
val3.AddComponent<LayoutElement>().minHeight = 92f;
ListMenuButton val4 = val3.AddComponent<ListMenuButton>();
val4.setBarHeight = 92f;
GameObject val5 = Object.Instantiate<GameObject>(AssetManager.ElementSection);
SaveLoadMenu saveLoadMenu = val5.AddComponent<SaveLoadMenu>();
saveLoadMenu.lobbyUi = val;
saveLoadMenu.listMenuButton = val4;
((UnityEvent)val3.AddComponent<Button>().onClick).AddListener((UnityAction)delegate
{
saveLoadMenu.Open();
});
_loadSaveRow = val3;
_menu = saveLoadMenu;
}
public GameObject GetText(string str)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Expected O, but got Unknown
GameObject val = new GameObject("Text");
val.AddComponent<CanvasRenderer>();
TextMeshProUGUI obj = val.AddComponent<TextMeshProUGUI>();
((TMP_Text)obj).text = str;
((Graphic)obj).color = Color32.op_Implicit(new Color32((byte)230, (byte)230, (byte)230, byte.MaxValue));
((TMP_Text)obj).font = MenuFont;
((TMP_Text)obj).fontSize = 60f;
((TMP_Text)obj).fontWeight = (FontWeight)400;
((TMP_Text)obj).alignment = (TextAlignmentOptions)514;
((TMP_Text)obj).rectTransform.sizeDelta = new Vector2(2050f, 92f);
return val;
}
}
}
namespace GameSaver.Menu
{
internal class SaveLoadMenu : MonoBehaviour
{
public static SaveLoadMenu instance;
public Camera gameCamera;
private Canvas canvas;
private CanvasGroup canvasGroup;
public GameObject lobbyUi;
public ListMenuButton listMenuButton;
private bool open;
private readonly List<GameObject> _hidden = new List<GameObject>();
private TextMeshProUGUI _selectedText;
private SaveManager.GameInfoData _selectedGame;
private SaveManager.SaveData _selectedSave;
private Coroutine _loadButtonsRoutine;
private Coroutine _gameRoutine;
private Coroutine _saveRoutine;
private Coroutine _swoopRoutine;
private Vector2 _lobbyRest;
private bool _lobbyRestCaptured;
private TextMeshProUGUI savedGamesText;
private TextMeshProUGUI _loadText;
private int lastGameCount = -1;
private Transform _gameButtonContainer;
private Transform _roundButtonContainer;
private Transform _roundDisplayContainer;
private Transform _playerContainer;
private void Start()
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0122: Unknown result type (might be due to invalid IL or missing references)
//IL_012c: Expected O, but got Unknown
//IL_0157: Unknown result type (might be due to invalid IL or missing references)
//IL_0161: Expected O, but got Unknown
//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
//IL_01d0: Expected O, but got Unknown
//IL_0207: Unknown result type (might be due to invalid IL or missing references)
//IL_0211: Expected O, but got Unknown
//IL_0235: Unknown result type (might be due to invalid IL or missing references)
//IL_023f: Expected O, but got Unknown
//IL_0256: Unknown result type (might be due to invalid IL or missing references)
//IL_0260: Expected O, but got Unknown
instance = this;
gameCamera = Camera.main;
((Transform)((Component)this).gameObject.GetComponent<RectTransform>()).localScale = Vector3.one;
canvas = ((Component)this).gameObject.GetComponent<Canvas>();
canvas.worldCamera = gameCamera;
canvasGroup = ((Component)this).gameObject.GetComponent<CanvasGroup>();
Transform child = ((Component)this).transform.GetChild(1);
_gameButtonContainer = child.GetChild(0).GetChild(0).GetChild(0);
Transform child2 = child.GetChild(1).GetChild(0);
_roundButtonContainer = child2.GetChild(0).GetChild(0).GetChild(0);
Transform child3 = child2.GetChild(1);
_roundDisplayContainer = child3.GetChild(0);
_playerContainer = child3.GetChild(0).GetChild(0).GetChild(0);
GameObject gameObject = ((Component)((Component)this).gameObject.transform.Find("Buttons/LoadButton")).gameObject;
_loadText = ((Component)gameObject.transform).GetComponentInChildren<TextMeshProUGUI>();
((UnityEvent)gameObject.GetComponent<Button>().onClick).AddListener(new UnityAction(OnLoadClicked));
((UnityEvent)((Component)((Component)this).gameObject.transform.Find("Buttons/BackButton")).gameObject.GetComponent<Button>().onClick).AddListener(new UnityAction(Close));
Transform child4 = ((Component)this).transform.GetChild(4);
Canvas uiExportImportCanvas = ((Component)child4).GetComponent<Canvas>();
((Component)child4.GetChild(4)).gameObject.SetActive(false);
Transform child5 = child4.GetChild(2);
Canvas uiExportCanvas = ((Component)child5).GetComponent<Canvas>();
TMP_InputField uiExportText = ((Component)child5).GetComponentInChildren<TMP_InputField>();
((UnityEvent)((Component)child5).GetComponentInChildren<Button>().onClick).AddListener((UnityAction)delegate
{
OnExportClicked(uiExportText);
});
Transform child6 = child4.GetChild(3);
Canvas uiImportCanvas = ((Component)child6).GetComponent<Canvas>();
TMP_InputField uiImportText = ((Component)child6).GetComponentInChildren<TMP_InputField>();
((UnityEvent)((Component)child6).GetComponentInChildren<Button>().onClick).AddListener((UnityAction)delegate
{
OnImportClicked(uiImportText, uiExportImportCanvas);
});
Transform child7 = ((Component)this).transform.GetChild(0);
((UnityEvent)((Component)child7.GetChild(0)).GetComponent<Button>().onClick).AddListener((UnityAction)delegate
{
((Behaviour)uiExportImportCanvas).enabled = true;
((Behaviour)uiImportCanvas).enabled = false;
((Behaviour)uiExportCanvas).enabled = true;
});
((UnityEvent)((Component)child7.GetChild(1)).GetComponent<Button>().onClick).AddListener((UnityAction)delegate
{
((Behaviour)uiExportImportCanvas).enabled = true;
((Behaviour)uiExportCanvas).enabled = false;
((Behaviour)uiImportCanvas).enabled = true;
});
savedGamesText = ((Component)((Component)this).transform.GetChild(3).GetChild(0)).GetComponentInChildren<TextMeshProUGUI>();
Active(active: false);
}
private void OnExportClicked(TMP_InputField field)
{
if (_selectedSave == null || _selectedGame?.gameData == null)
{
ShowFieldMessage(field, "SELECT A SAVE FIRST");
return;
}
ShareManager.ExportResult exportResult = ShareManager.Export(_selectedGame.gameData, _selectedSave);
if (!exportResult.Success)
{
ShowFieldMessage(field, exportResult.Error ?? "EXPORT FAILED");
}
else
{
ShowFieldMessage(field, exportResult.FitsInOneMessage ? $"COPIED - {exportResult.Code.Length} CHARS" : $"COPIED - {exportResult.Code.Length} CHARS, TOO LONG TO CHAT, SEND THE FILE IN {ShareManager.SharedFolder}");
}
}
private void OnImportClicked(TMP_InputField field, Canvas panel)
{
TextMeshProUGUI placeholder = (Object.op_Implicit((Object)(object)field.placeholder) ? ((Component)field.placeholder).GetComponent<TextMeshProUGUI>() : null);
string text = field.text;
if (string.IsNullOrEmpty(text) || text.Trim().Length == 0)
{
try
{
text = GUIUtility.systemCopyBuffer;
}
catch (Exception ex)
{
GameSaver.LogWarning("could not read the clipboard: " + ex.Message);
}
}
field.text = "";
ShareManager.ImportResult importResult = ShareManager.Import(text);
if (!importResult.Success)
{
FlashPlaceholder(placeholder, importResult.Error ?? "IMPORT FAILED");
return;
}
RefreshAfterImport();
FlashPlaceholder(placeholder, importResult.AlreadyHad ? $"ALREADY HAD ROUND {importResult.Round}" : $"IMPORTED ROUND {importResult.Round}");
if (!importResult.AlreadyHad && Object.op_Implicit((Object)(object)panel))
{
((Behaviour)panel).enabled = false;
}
}
private void ShowFieldMessage(TMP_InputField field, string message)
{
if (Object.op_Implicit((Object)(object)field))
{
field.text = message;
}
}
private void FlashPlaceholder(TextMeshProUGUI placeholder, string message)
{
if (!Object.op_Implicit((Object)(object)placeholder))
{
return;
}
string original = ((TMP_Text)placeholder).text;
((TMP_Text)placeholder).text = message;
ExtensionMethods.ExecuteAfterSeconds((MonoBehaviour)(object)Unbound.Instance, 2f, (Action)delegate
{
if (Object.op_Implicit((Object)(object)placeholder))
{
((TMP_Text)placeholder).text = original;
}
});
}
private void OnLoadClicked()
{
try
{
if (_selectedSave == null)
{
Flash("SAVE NOT SELECTED");
return;
}
if (SaveManager._selectedSave == _selectedSave)
{
SaveManager._selectedSave = null;
if (Object.op_Implicit((Object)(object)_selectedText))
{
((TMP_Text)_selectedText).text = "";
}
_selectedText = null;
Flash("UNLOADED");
return;
}
if (_selectedGame?.gameData == null)
{
Flash("SAVE NOT SELECTED");
return;
}
SaveManager.GameData gameData = _selectedGame.gameData;
if (!GameModeManager.GameModes.ContainsKey(gameData.gameMode))
{
Flash("UNKNOWN GAMEMODE");
return;
}
SaveManager.SelectSave(gameData, _selectedSave);
if (Object.op_Implicit((Object)(object)_selectedText))
{
((TMP_Text)_selectedText).text = "";
}
if (Object.op_Implicit((Object)(object)_selectedSave.loaded))
{
_selectedText = _selectedSave.loaded;
((TMP_Text)_selectedSave.loaded).text = "LOADED";
}
Close();
}
catch (Exception arg)
{
GameSaver.LogError($"loading the selected save failed: {arg}");
Flash("LOAD FAILED");
}
}
private void RefreshLoadButtonLabel()
{
if (Object.op_Implicit((Object)(object)_loadText))
{
((TMP_Text)_loadText).text = ((SaveManager._selectedSave != null) ? ("UNLOAD SAVE: " + SaveManager._selectedSave.Time) : "LOAD");
}
}
private void Flash(string message)
{
if (Object.op_Implicit((Object)(object)_loadText))
{
((TMP_Text)_loadText).text = message;
ExtensionMethods.ExecuteAfterSeconds((MonoBehaviour)(object)Unbound.Instance, 1f, (Action)RefreshLoadButtonLabel);
}
}
private void Hide(string objectName)
{
GameObject val = GameObject.Find(objectName);
if (!((Object)(object)val == (Object)null) && val.activeSelf)
{
val.SetActive(false);
_hidden.Add(val);
}
}
public void Open()
{
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
if (!open)
{
open = true;
CaptureLobbyRest();
Hide("Links(Clone)");
Hide("UIHolder");
Hide("LobbyImprovementsBG");
Hide("TimerLobbyUI(Clone)");
Hide("RoundCounterSmall");
_swoopRoutine = Restart(_swoopRoutine, Swoop(lobbyUi, _lobbyRest + new Vector2(0f, (float)(Screen.height * 2))));
if ((Object)(object)listMenuButton != (Object)null)
{
listMenuButton.OnPointerEnter((PointerEventData)null);
}
Active(active: true);
SaveManager.LoadGames();
UpdateGamesCount(SaveManager._games.Count);
RefreshLoadButtonLabel();
_loadButtonsRoutine = Restart(_loadButtonsRoutine, LoadGameButtons());
}
}
private void CaptureLobbyRest()
{
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
if (!_lobbyRestCaptured && Object.op_Implicit((Object)(object)lobbyUi))
{
RectTransform component = lobbyUi.GetComponent<RectTransform>();
if (Object.op_Implicit((Object)(object)component))
{
_lobbyRest = component.anchoredPosition;
_lobbyRestCaptured = true;
}
}
}
private void RestoreLobby()
{
//IL_0080: Unknown result type (might be due to invalid IL or missing references)
foreach (GameObject item in _hidden.Where((GameObject hidden) => Object.op_Implicit((Object)(object)hidden)))
{
item.SetActive(true);
}
_hidden.Clear();
if (Object.op_Implicit((Object)(object)lobbyUi) && _lobbyRestCaptured)
{
_swoopRoutine = Restart(_swoopRoutine, Swoop(lobbyUi, _lobbyRest));
}
Active(active: false);
}
public void Close()
{
if (!open)
{
return;
}
open = false;
try
{
RestoreLobby();
}
finally
{
_selectedGame = null;
_selectedSave = null;
StopMenuCoroutines();
}
}
private void StopMenuCoroutines()
{
Stop(ref _loadButtonsRoutine);
Stop(ref _gameRoutine);
Stop(ref _saveRoutine);
}
private void OnDestroy()
{
StopMenuCoroutines();
Stop(ref _swoopRoutine);
if ((Object)(object)instance == (Object)(object)this)
{
instance = null;
}
}
private static void Stop(ref Coroutine routine)
{
Coroutine val = routine;
routine = null;
if (val != null && (Object)(object)GameSaver.Instance != (Object)null)
{
((MonoBehaviour)GameSaver.Instance).StopCoroutine(val);
}
}
private static Coroutine Restart(Coroutine existing, IEnumerator routine)
{
if (existing != null && (Object)(object)GameSaver.Instance != (Object)null)
{
((MonoBehaviour)GameSaver.Instance).StopCoroutine(existing);
}
if (!((Object)(object)GameSaver.Instance != (Object)null))
{
return null;
}
return ((MonoBehaviour)GameSaver.Instance).StartCoroutine(routine);
}
public void Reset()
{
if (open)
{
RestoreLobby();
}
open = false;
StopMenuCoroutines();
foreach (SaveManager.GameInfoData orderedGame in SaveManager.orderedGames)
{
RemoveGameSaveButtons(orderedGame);
}
_selectedGame = null;
_selectedSave = null;
_selectedText = null;
lastGameCount = -1;
}
internal void RefreshAfterImport()
{
if (!open)
{
return;
}
_selectedGame = null;
_selectedSave = null;
HideAllRoundButtons();
HideAllPlayerAssets();
foreach (SaveManager.GameInfoData orderedGame in SaveManager.orderedGames)
{
RemoveGameSaveButtons(orderedGame);
}
UpdateGamesCount(SaveManager._games.Count);
_loadButtonsRoutine = Restart(_loadButtonsRoutine, LoadGameButtons());
}
public void RemoveGameSaveButtons(SaveManager.GameInfoData gameInfoData)
{
if (gameInfoData?.gameData == null)
{
return;
}
if (Object.op_Implicit((Object)(object)gameInfoData.gameData.button))
{
Object.Destroy((Object)(object)gameInfoData.gameData.button);
gameInfoData.gameData.button = null;
}
foreach (SaveManager.SaveData item in gameInfoData.gameSaves.Where((SaveManager.SaveData saveData) => saveData != null))
{
if (Object.op_Implicit((Object)(object)item.button))
{
Object.Destroy((Object)(object)item.button);
item.button = null;
}
if (Object.op_Implicit((Object)(object)item.display))
{
Object.Destroy((Object)(object)item.display);
item.display = null;
}
item.loaded = null;
foreach (SaveManager.PlayerData item2 in item.players.Where((SaveManager.PlayerData playerData) => playerData != null))
{
if (Object.op_Implicit((Object)(object)item2.display))
{
Object.Destroy((Object)(object)item2.display);
item2.display = null;
}
}
item.InvalidateCards();
}
}
private void Update()
{
if (SaveManager._games.Count != lastGameCount)
{
UpdateGamesCount(SaveManager._games.Count);
}
}
public void UpdateGamesCount(int amount)
{
if (Object.op_Implicit((Object)(object)savedGamesText))
{
((TMP_Text)savedGamesText).text = $"SAVED GAMES: {amount}";
}
lastGameCount = amount;
}
private void BuildPlayerRow(SaveManager.SaveData saveData, SaveManager.PlayerData playerData, Transform playerContainer)
{
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
//IL_011b: Unknown result type (might be due to invalid IL or missing references)
//IL_0145: Unknown result type (might be due to invalid IL or missing references)
//IL_014a: Unknown result type (might be due to invalid IL or missing references)
//IL_019a: Unknown result type (might be due to invalid IL or missing references)
//IL_0238: Unknown result type (might be due to invalid IL or missing references)
//IL_0244: Unknown result type (might be due to invalid IL or missing references)
//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
//IL_0201: Unknown result type (might be due to invalid IL or missing references)
GameObject val = (playerData.display = Object.Instantiate<GameObject>(AssetManager.Player, playerContainer));
try
{
((Component)val.transform.GetChild(0).GetChild(0).GetChild(0)).gameObject.SetActive(playerData.host);
((TMP_Text)((Component)val.transform.GetChild(0).GetChild(1)).GetComponent<TextMeshProUGUI>()).text = playerData.name;
TextMeshProUGUI component = ((Component)val.transform.GetChild(2)).GetComponent<TextMeshProUGUI>();
((TMP_Text)component).text = ExtraPlayerSkins.GetTeamColorName(playerData.serializedColor).ToUpper();
((Graphic)component).color = playerData.Color.color;
Transform child = ((Component)val.transform.GetChild(1).GetChild(0)).gameObject.transform.GetChild(0).GetChild(0);
foreach (CardInfo card in playerData.Cards)
{
GameObject obj = Object.Instantiate<GameObject>(AssetManager.Card, child);
((TMP_Text)((Component)obj.transform).GetComponentInChildren<TextMeshProUGUI>()).text = (Object.op_Implicit((Object)(object)card) ? CardInitials(card) : "???");
((Graphic)((Component)obj.transform).GetComponent<Image>()).color = playerData.Color.color;
CardDisplayMono orAddComponent = ExtensionMethods.GetOrAddComponent<CardDisplayMono>(obj, false);
orAddComponent.container = val.transform;
orAddComponent.card = card;
orAddComponent.color = playerData.Color.color;
}
Transform child2 = val.transform.GetChild(3);
for (int i = 0; i < saveData.pointsToWin; i++)
{
Image componentInChildren = Object.Instantiate<GameObject>(AssetManager.Point, child2).GetComponentInChildren<Image>();
((Graphic)componentInChildren).color = playerData.Color.color;
if (i == playerData.rounds)
{
float num = ((playerData.points == 0 || saveData.pointsToWinRound == 0) ? 0f : ((float)playerData.points / (float)saveData.pointsToWinRound));
if (num <= 0f)
{
((Component)componentInChildren).gameObject.GetComponent<RectTransform>().sizeDelta = new Vector2(5f, 5f);
((Graphic)componentInChildren).color = Color.gray;
}
else
{
componentInChildren.fillAmount = num;
}
}
else if (i > playerData.rounds)
{
((Component)componentInChildren).gameObject.GetComponent<RectTransform>().sizeDelta = new Vector2(5f, 5f);
((Graphic)componentInChildren).color = Color.gray;
}
}
}
catch (Exception arg)
{
GameSaver.LogError($"could not build the row for '{playerData.name}': {arg}");
Object.Destroy((Object)(object)val);
playerData.display = null;
}
}
private void BuildRoundButton(SaveManager.GameInfoData gameInfoData, SaveManager.SaveData saveData)
{
//IL_0250: Unknown result type (might be due to invalid IL or missing references)
//IL_025a: Expected O, but got Unknown
GameObject val = Object.Instantiate<GameObject>(AssetManager.SaveInfo, _roundDisplayContainer);
saveData.display = val;
try
{
((TMP_Text)((Component)val.transform.GetChild(0)).GetComponent<TextMeshProUGUI>()).text = $"ROUND {saveData.round}";
((TMP_Text)((Component)val.transform.GetChild(1).GetChild(1)).GetComponent<TextMeshProUGUI>()).text = $"{saveData.players.Count}/32";
((TMP_Text)((Component)val.transform.GetChild(2)).GetComponent<TextMeshProUGUI>()).text = gameInfoData.gameData.gameMode.ToUpper();
saveData.loaded = ((Component)val.transform.GetChild(3)).GetComponent<TextMeshProUGUI>();
((TMP_Text)saveData.loaded).text = "";
val.SetActive(false);
}
catch (Exception arg)
{
GameSaver.LogError($"could not build the round header for round {saveData.round}: {arg}");
Object.Destroy((Object)(object)val);
saveData.display = null;
return;
}
GameObject val2 = Object.Instantiate<GameObject>(AssetManager.RoundButton, _roundButtonContainer);
saveData.button = val2;
try
{
string[] array = $"{saveData.Time}".Split(new char[1] { ' ' });
((TMP_Text)((Component)val2.transform.GetChild(0)).GetComponent<TextMeshProUGUI>()).text = ((array.Length > 1) ? (array[1] + "\n" + array[0]) : $"{saveData.Time}");
((TMP_Text)((Component)val2.transform.GetChild(1).GetChild(0)).GetComponent<TextMeshProUGUI>()).text = $"ROUND {saveData.round}";
((TMP_Text)((Component)val2.transform.GetChild(3)).GetComponent<TextMeshProUGUI>()).text = Regex.Replace(saveData.saveType.ToString(), "([a-z])_?([A-Z])", "$1\n$2").ToUpper();
((UnityEvent)val2.GetComponent<Button>().onClick).AddListener((UnityAction)delegate
{
OnRoundClicked(saveData);
});
val2.SetActive(false);
}
catch (Exception arg2)
{
GameSaver.LogError($"could not build the round button for round {saveData.round}: {arg2}");
Object.Destroy((Object)(object)val2);
saveData.button = null;
}
}
private void OnRoundClicked(SaveManager.SaveData saveData)
{
if (_selectedSave != saveData)
{
_selectedSave = saveData;
HideAllPlayerAssets();
_saveRoutine = Restart(_saveRoutine, ShowSaveRoutine(saveData));
}
}
private IEnumerator ShowSaveRoutine(SaveManager.SaveData saveData)
{
if (Object.op_Implicit((Object)(object)saveData.display))
{
saveData.display.SetActive(true);
}
foreach (SaveManager.PlayerData item in saveData.players.Where((SaveManager.PlayerData playerData) => playerData != null))
{
if (!Object.op_Implicit((Object)(object)item.display))
{
BuildPlayerRow(saveData, item, _playerContainer);
}
if (Object.op_Implicit((Object)(object)item.display))
{
item.display.SetActive(true);
}
yield return null;
}
}
private void OnGameClicked(SaveManager.GameInfoData gameInfoData)
{
if (_selectedGame != gameInfoData)
{
_selectedGame = gameInfoData;
_selectedSave = null;
HideAllRoundButtons();
HideAllPlayerAssets();
Stop(ref _saveRoutine);
_gameRoutine = Restart(_gameRoutine, ShowGameRoutine(gameInfoData));
}
}
private IEnumerator ShowGameRoutine(SaveManager.GameInfoData gameInfoData)
{
foreach (SaveManager.SaveData item in from saveData in gameInfoData.gameSaves
where saveData != null
orderby saveData._serializedDateTime descending
select saveData)
{
if (!Object.op_Implicit((Object)(object)item.button))
{
BuildRoundButton(gameInfoData, item);
}
if (Object.op_Implicit((Object)(object)item.button))
{
item.button.SetActive(true);
}
yield return null;
}
}
private IEnumerator LoadGameButtons()
{
foreach (SaveManager.GameInfoData orderedGame in SaveManager.orderedGames)
{
if (orderedGame.rounds == 0)
{
continue;
}
if (Object.op_Implicit((Object)(object)orderedGame.gameData.button))
{
orderedGame.gameData.button.SetActive(true);
continue;
}
GameObject val = Object.Instantiate<GameObject>(AssetManager.GameButton, _gameButtonContainer);
orderedGame.gameData.button = val;
try
{
Transform transform = val.transform;
string[] array = $"{orderedGame.gameData.StartTime}".Split(new char[1] { ' ' });
((TMP_Text)((Component)transform.GetChild(0)).GetComponent<TextMeshProUGUI>()).text = ((array.Length > 1) ? (array[1] + " " + array[0]) : $"{orderedGame.gameData.StartTime}");
((TMP_Text)((Component)transform.GetChild(1).GetChild(1)).GetComponent<TextMeshProUGUI>()).text = orderedGame.rounds.ToString();
((TMP_Text)((Component)transform.GetChild(2).GetChild(1)).GetComponent<TextMeshProUGUI>()).text = $"{orderedGame.gameData.playerAmount}/32";
((TMP_Text)((Component)transform.GetChild(3)).GetComponent<TextMeshProUGUI>()).text = orderedGame.gameData.gameMode.ToUpper();
SaveManager.GameInfoData captured = orderedGame;
((UnityEvent)val.GetComponent<Button>().onClick).AddListener((UnityAction)delegate
{
OnGameClicked(captured);
});
}
catch (Exception arg)
{
GameSaver.LogError($"could not build the game button: {arg}");
Object.Destroy((Object)(object)val);
orderedGame.gameData.button = null;
}
yield return null;
}
}
internal string CardInitials(CardInfo card)
{
string cardName = card.cardName;
if (string.IsNullOrEmpty(cardName))
{
return "??";
}
cardName = ((cardName.Length >= 2) ? cardName.Substring(0, 2) : cardName.Substring(0, 1));
string text = cardName[0].ToString().ToUpper();
if (cardName.Length <= 1)
{
return text;
}
return text + cardName[1].ToString().ToLower();
}
private static void HideAllRoundButtons()
{
foreach (SaveManager.GameInfoData orderedGame in SaveManager.orderedGames)
{
foreach (SaveManager.SaveData item in orderedGame.gameSaves.Where((SaveManager.SaveData saveData) => saveData != null))
{
if (Object.op_Implicit((Object)(object)item.button))
{
item.button.SetActive(false);
}
if (Object.op_Implicit((Object)(object)item.display))
{
item.display.SetActive(false);
}
}
}
}
private static void HideAllPlayerAssets()
{
foreach (SaveManager.GameInfoData orderedGame in SaveManager.orderedGames)
{
foreach (SaveManager.SaveData item in orderedGame.gameSaves.Where((SaveManager.SaveData saveData) => saveData != null))
{
if (Object.op_Implicit((Object)(object)item.display))
{
item.display.SetActive(false);
}
if (!Object.op_Implicit((Object)(object)item.button))
{
continue;
}
foreach (SaveManager.PlayerData item2 in item.players.Where((SaveManager.PlayerData playerData) => playerData != null))
{
if (Object.op_Implicit((Object)(object)item2.display))
{
item2.display.SetActive(false);
}
}
}
}
}
private static IEnumerator Swoop(GameObject obj, Vector2 target)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
if (!Object.op_Implicit((Object)(object)obj))
{
yield break;
}
RectTransform rect = obj.GetComponent<RectTransform>();
if (!Object.op_Implicit((Object)(object)rect))
{
yield break;
}
float t = 0f;
Vector2 startPos = rect.anchoredPosition;
while (t < 0.25f)
{
t += Time.deltaTime;
if (!Object.op_Implicit((Object)(object)rect))
{
yield break;
}
rect.anchoredPosition = Vector2.Lerp(startPos, target, t * 4f);
yield return null;
}
if (Object.op_Implicit((Object)(object)rect))
{
rect.anchoredPosition = target;
}
}
private void Active(bool active)
{
if (Object.op_Implicit((Object)(object)canvas))
{
((Behaviour)canvas).enabled = active;
}
if (Object.op_Implicit((Object)(object)canvasGroup))
{
canvasGroup.blocksRaycasts = active;
}
}
}
}
namespace GameSaver.Component
{
public class AnimationAutoDestroy : MonoBehaviour
{
private Animator _animator;
private int _nextUpdate = 1;
private int _play;
private void Start()
{
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
_animator = ((Component)this).GetComponentInChildren<Animator>(true);
if ((Object)(object)_animator == (Object)null)
{
Object.Destroy((Object)(object)this);
return;
}
AnimatorStateInfo currentAnimatorStateInfo = _animator.GetCurrentAnimatorStateInfo(0);
_play = (int)((AnimatorStateInfo)(ref currentAnimatorStateInfo)).length;
}
private void Update()
{
if (Time.time >= (float)_nextUpdate)
{
_nextUpdate = Mathf.FloorToInt(Time.time) + 1;
UpdateSecond();
}
}
private void UpdateSecond()
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)_animator == (Object)null)
{
return;
}
AnimatorStateInfo currentAnimatorStateInfo = _animator.GetCurrentAnimatorStateInfo(0);
if (((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime > 1f && !_animator.IsInTransition(0))
{
if (_play > 0)
{
_play--;
return;
}
((Component)this).gameObject.SetActive(false);
Object.Destroy((Object)(object)this);
}
}
}
internal class CardDisplayMono : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler
{
private static Canvas cardPreviewCanvas;
private static GameObject cardPreview;
private static Image cardPreviewImage;
private static Image cardPreviewBackgroundImage;
private static GameObject cardObject;
private static TextMeshProUGUI noCardText;
private static Rect cardPreviewRect;
public Transform container;
public CardInfo card;
public Color color;
private void Start()
{
//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)cardPreview == (Object)null || (Object)(object)cardPreviewCanvas == (Object)null)
{
if ((Object)(object)AssetManager.CardPreview == (Object)null)
{
return;
}
GameObject val = Object.Instantiate<GameObject>(AssetManager.CardPreview);
Object.DontDestroyOnLoad((Object)(object)val);
cardPreviewCanvas = val.GetComponent<Canvas>();
if ((Object)(object)cardPreviewCanvas == (Object)null)
{
Object.Destroy((Object)(object)val);
return;
}
if ((Object)(object)SaveLoadMenu.instance != (Object)null)
{
cardPreviewCanvas.worldCamera = SaveLoadMenu.instance.gameCamera;
}
cardPreview = ((Component)((Component)cardPreviewCanvas).transform.GetChild(0)).gameObject;
cardPreviewRect = cardPreview.GetComponent<RectTransform>().rect;
cardPreviewBackgroundImage = cardPreview.GetComponent<Image>();
cardPreviewImage = ((Component)cardPreview.transform.GetChild(0)).GetComponent<Image>();
noCardText = cardPreview.GetComponentInChildren<TextMeshProUGUI>();
}
((Behaviour)cardPreviewCanvas).enabled = false;
}
public void OnPointerEnter(PointerEventData eventData)
{
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: Unknown result type (might be due to invalid IL or missing references)
//IL_0109: Unknown result type (might be due to invalid IL or missing references)
//IL_011d: Unknown result type (might be due to invalid IL or missing references)
//IL_015d: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)cardPreviewCanvas == (Object)null || (Object)(object)cardPreview == (Object)null)
{
return;
}
((Behaviour)cardPreviewCanvas).enabled = true;
((Graphic)cardPreviewImage).color = color;
((Graphic)cardPreviewBackgroundImage).color = new Color(color.r * 0.45f, color.g * 0.45f, color.b * 0.45f);
cardPreview.transform.position = ((Component)this).transform.position;
if ((Object)(object)cardObject != (Object)null)
{
Object.Destroy((Object)(object)cardObject);
}
if ((Object)(object)card == (Object)null)
{
((Behaviour)noCardText).enabled = true;
return;
}
((Behaviour)noCardText).enabled = false;
cardObject = Object.Instantiate<GameObject>(((Component)card).gameObject, cardPreview.transform);
RectTransform orAddComponent = ExtensionMethods.GetOrAddComponent<RectTransform>(cardObject, false);
orAddComponent.anchorMin = new Vector2(0f, 0f);
orAddComponent.anchorMax = new Vector2(0f, 0f);
cardObject.transform.localPosition = new Vector3(((Rect)(ref cardPreviewRect)).width / 2f, 0f - ((Rect)(ref cardPreviewRect)).height / 2f - 8f, 0f);
CardVisuals componentInChildren = cardObject.GetComponentInChildren<CardVisuals>();
if ((Object)(object)componentInChildren != (Object)null)
{
componentInChildren.firstValueToSet = true;
}
ScaleShake setScaleToZero = cardObject.GetComponentInChildren<ScaleShake>();
if ((Object)(object)setScaleToZero == (Object)null)
{
return;
}
ExtensionMethods.ExecuteAfterFrames((MonoBehaviour)(object)Unbound.Instance, 1, (Action)delegate
{
if ((Object)(object)setScaleToZero != (Object)null)
{
setScaleToZero.targetScale = 15f;
}
});
}
public void OnPointerExit(PointerEventData eventData)
{
if ((Object)(object)cardPreviewCanvas != (Object)null)
{
((Behaviour)cardPreviewCanvas).enabled = false;
}
}
private void OnDisable()
{
if ((Object)(object)cardPreviewCanvas != (Object)null)
{
((Behaviour)cardPreviewCanvas).enabled = false;
}
}
}
}
namespace GameSaver.Asset
{
public static class AssetManager
{
private static AssetBundle _bundle;
public static GameObject Saving { get; private set; }
public static GameObject ElementSection { get; private set; }
public static GameObject Section { get; private set; }
public static GameObject SaveInfo { get; private set; }
public static GameObject GameButton { get; private set; }
public static GameObject RoundButton { get; private set; }
public static GameObject Player { get; private set; }
public static GameObject Card { get; private set; }
public static GameObject Point { get; private set; }
public static GameObject CardPreview { get; private set; }
public static GameObject Delete { get; private set; }
public static Image Trash { get; private set; }
public static Image TrashOpen { get; private set; }
internal static bool Initialize()
{
try
{
_bundle = AssetUtils.LoadAssetBundleFromResources("gamesaver_assets", typeof(GameSaver).Assembly);
}
catch (Exception ex)
{
GameSaver.LogError("could not load asset bundle 'gamesaver_assets': " + ex.GetType().Name + ": " + ex.Message);
return false;
}
if ((Object)(object)_bundle == (Object)null)
{
GameSaver.LogError("asset bundle 'gamesaver_assets' resolved to null.");
return false;
}
Saving = Load<GameObject>("Saving");
ElementSection = Load<GameObject>("ElementSection");
Section = Load<GameObject>("Section");
SaveInfo = Load<GameObject>("SaveInfo");
GameButton = Load<GameObject>("GameButton");
RoundButton = Load<GameObject>("RoundButton");
Player = Load<GameObject>("Player");
Card = Load<GameObject>("Card");
Point = Load<GameObject>("Point");
CardPreview = Load<GameObject>("CardPreview");
Delete = Load<GameObject>("Delete");
Trash = Load<Image>("Trash");
TrashOpen = Load<Image>("TrashOpen");
if (Object.op_Implicit((Object)(object)ElementSection) && Object.op_Implicit((Object)(object)SaveInfo) && Object.op_Implicit((Object)(object)GameButton) && Object.op_Implicit((Object)(object)RoundButton) && Object.op_Implicit((Object)(object)Player) && Object.op_Implicit((Object)(object)Card))
{
return Object.op_Implicit((Object)(object)Point);
}
return false;
}
private static T Load<T>(string name) where T : Object
{
T val = _bundle.LoadAsset<T>(name);
if ((Object)(object)val == (Object)null)
{
GameSaver.LogError("asset '" + name + "' missing from bundle.");
}
return val;
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}