using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
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.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using JetBrains.Annotations;
using LocalizationManager;
using Managers;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using ServerSync;
using TMPro;
using Timekeeper.Managers;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.UI;
[assembly: Guid("4358610B-F3F4-4843-B7AF-98B7BC60DCDE")]
[assembly: ComVisible(false)]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCopyright("Copyright © 2021")]
[assembly: AssemblyProduct("Timekeeper")]
[assembly: AssemblyCompany("RustyMods")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyTitle("Timekeeper")]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyFileVersion("1.0.2")]
[assembly: AssemblyConfiguration("")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.2.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[<8b5605b8-2a90-4f12-892b-5b97acc01c23>Embedded]
internal sealed class <8b5605b8-2a90-4f12-892b-5b97acc01c23>EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[<8b5605b8-2a90-4f12-892b-5b97acc01c23>Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class <0e657ea4-f9a5-4535-99f9-133b42a018b4>NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public <0e657ea4-f9a5-4535-99f9-133b42a018b4>NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public <0e657ea4-f9a5-4535-99f9-133b42a018b4>NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[<8b5605b8-2a90-4f12-892b-5b97acc01c23>Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class <b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContextAttribute : Attribute
{
public readonly byte Flag;
public <b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
}
namespace LocalizationManager
{
[PublicAPI]
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(0)]
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)]
public class Localizer
{
private static readonly Dictionary<string, Dictionary<string, Func<string>>> PlaceholderProcessors;
private static readonly Dictionary<string, Dictionary<string, string>> loadedTexts;
private static readonly ConditionalWeakTable<Localization, string> localizationLanguage;
private static readonly List<WeakReference<Localization>> localizationObjects;
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(2)]
private static BaseUnityPlugin _plugin;
private static readonly List<string> fileExtensions;
private static BaseUnityPlugin plugin
{
get
{
//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: Expected O, but got Unknown
if (_plugin == null)
{
IEnumerable<TypeInfo> source;
try
{
source = Assembly.GetExecutingAssembly().DefinedTypes.ToList();
}
catch (ReflectionTypeLoadException ex)
{
source = from t in ex.Types
where t != null
select t.GetTypeInfo();
}
_plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First([<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(0)] (TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t)));
}
return _plugin;
}
}
private static void UpdatePlaceholderText(Localization localization, string key)
{
localizationLanguage.TryGetValue(localization, out var value);
string text = loadedTexts[value][key];
if (PlaceholderProcessors.TryGetValue(key, out var value2))
{
text = value2.Aggregate(text, [<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(0)] (string current, KeyValuePair<string, Func<string>> kv) => current.Replace("{" + kv.Key + "}", kv.Value()));
}
localization.AddWord(key, text);
}
public static void AddPlaceholder<T>(string key, string placeholder, ConfigEntry<T> config, [<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(new byte[] { 2, 1, 1 })] Func<T, string> convertConfigValue = null)
{
if (convertConfigValue == null)
{
convertConfigValue = [<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(0)] [return: <0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(1)] (T val) => val.ToString();
}
if (!PlaceholderProcessors.ContainsKey(key))
{
PlaceholderProcessors[key] = new Dictionary<string, Func<string>>();
}
config.SettingChanged += [<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(0)] (object _, EventArgs _) =>
{
UpdatePlaceholder();
};
if (loadedTexts.ContainsKey(Localization.instance.GetSelectedLanguage()))
{
UpdatePlaceholder();
}
void UpdatePlaceholder()
{
PlaceholderProcessors[key][placeholder] = () => convertConfigValue(config.Value);
UpdatePlaceholderText(Localization.instance, key);
}
}
public static void AddText(string key, string text)
{
List<WeakReference<Localization>> list = new List<WeakReference<Localization>>();
foreach (WeakReference<Localization> localizationObject in localizationObjects)
{
if (localizationObject.TryGetTarget(out var target))
{
Dictionary<string, string> dictionary = loadedTexts[localizationLanguage.GetOrCreateValue(target)];
if (!target.m_translations.ContainsKey(key))
{
dictionary[key] = text;
target.AddWord(key, text);
}
}
else
{
list.Add(localizationObject);
}
}
foreach (WeakReference<Localization> item in list)
{
localizationObjects.Remove(item);
}
}
public static void Load()
{
LoadLocalization(Localization.instance, Localization.instance.GetSelectedLanguage());
}
private static void LoadLocalization(Localization __instance, string language)
{
//IL_01a6: Expected O, but got Unknown
//IL_02a6: Expected O, but got Unknown
if (!localizationLanguage.Remove(__instance))
{
localizationObjects.Add(new WeakReference<Localization>(__instance));
}
localizationLanguage.Add(__instance, language);
Dictionary<string, string> dictionary = new Dictionary<string, string>();
foreach (string item in from f in Directory.GetFiles(Path.GetDirectoryName(Paths.PluginPath), plugin.Info.Metadata.Name + ".*", SearchOption.AllDirectories)
where fileExtensions.IndexOf(Path.GetExtension(f)) >= 0
select f)
{
string text = Path.GetFileNameWithoutExtension(item).Split(new char[1] { '.' })[1];
if (dictionary.ContainsKey(text))
{
Debug.LogWarning((object)("Duplicate key " + text + " found for " + plugin.Info.Metadata.Name + ". The duplicate file found at " + item + " will be skipped."));
}
else
{
dictionary[text] = item;
}
}
byte[] array = LoadTranslationFromAssembly("English");
if (array == null)
{
throw new Exception("Found no English localizations in mod " + plugin.Info.Metadata.Name + ". Expected an embedded resource translations/English.json.");
}
Dictionary<string, string> dictionary2;
try
{
dictionary2 = JsonConvert.DeserializeObject<Dictionary<string, string>>(Encoding.UTF8.GetString(array));
}
catch (JsonException val)
{
JsonException val2 = val;
throw new Exception("Localization for mod " + plugin.Info.Metadata.Name + " failed: Invalid JSON in English localization file. " + ((Exception)(object)val2).Message);
}
if (dictionary2 == null)
{
throw new Exception("Localization for mod " + plugin.Info.Metadata.Name + " failed: Localization file was empty.");
}
string text2 = null;
if (language != "English")
{
if (dictionary.ContainsKey(language))
{
text2 = File.ReadAllText(dictionary[language]);
}
else
{
byte[] array2 = LoadTranslationFromAssembly(language);
if (array2 != null)
{
text2 = Encoding.UTF8.GetString(array2);
}
}
}
if (text2 == null && dictionary.ContainsKey("English"))
{
text2 = File.ReadAllText(dictionary["English"]);
}
if (text2 != null)
{
Dictionary<string, string> dictionary3;
try
{
dictionary3 = JsonConvert.DeserializeObject<Dictionary<string, string>>(text2);
}
catch (JsonException val3)
{
JsonException val4 = val3;
throw new Exception("Localization for mod " + plugin.Info.Metadata.Name + " failed: Invalid JSON in " + language + " localization file. " + ((Exception)(object)val4).Message);
}
foreach (KeyValuePair<string, string> item2 in dictionary3 ?? new Dictionary<string, string>())
{
dictionary2[item2.Key] = item2.Value;
}
}
loadedTexts[language] = dictionary2;
foreach (KeyValuePair<string, string> item3 in dictionary2)
{
UpdatePlaceholderText(__instance, item3.Key);
}
}
static Localizer()
{
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Expected O, but got Unknown
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: Expected O, but got Unknown
PlaceholderProcessors = new Dictionary<string, Dictionary<string, Func<string>>>();
loadedTexts = new Dictionary<string, Dictionary<string, string>>();
localizationLanguage = new ConditionalWeakTable<Localization, string>();
localizationObjects = new List<WeakReference<Localization>>();
fileExtensions = new List<string> { ".json" };
Harmony val = new Harmony("org.bepinex.helpers.LocalizationManager");
val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "LoadCSV", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalization", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
[return: <0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(2)]
private static byte[] LoadTranslationFromAssembly(string language)
{
foreach (string fileExtension in fileExtensions)
{
byte[] array = ReadEmbeddedFileBytes("translations." + language + fileExtension);
if (array != null)
{
return array;
}
}
return null;
}
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(2)]
public static byte[] ReadEmbeddedFileBytes([<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(1)] string resourceFileName, Assembly containingAssembly = null)
{
using MemoryStream memoryStream = new MemoryStream();
if ((object)containingAssembly == null)
{
containingAssembly = Assembly.GetCallingAssembly();
}
string text = containingAssembly.GetManifestResourceNames().FirstOrDefault([<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(0)] (string str) => str.EndsWith(resourceFileName, StringComparison.Ordinal));
if (text != null)
{
containingAssembly.GetManifestResourceStream(text)?.CopyTo(memoryStream);
}
return (memoryStream.Length == 0L) ? null : memoryStream.ToArray();
}
}
}
namespace Timekeeper
{
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)]
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(0)]
[BepInPlugin("RustyMods.Timekeeper", "Timekeeper", "1.0.2")]
public class TimekeeperPlugin : BaseUnityPlugin
{
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(0)]
public enum Toggle
{
On = 1,
Off = 0
}
internal const string ModName = "Timekeeper";
internal const string ModVersion = "1.0.2";
internal const string Author = "RustyMods";
private const string ModGUID = "RustyMods.Timekeeper";
private static readonly string ConfigFileName = "RustyMods.Timekeeper.cfg";
private static readonly string ConfigFileFullPath;
internal static string ConnectionError;
private readonly Harmony _harmony = new Harmony("RustyMods.Timekeeper");
public static readonly ManualLogSource TimekeeperLogger;
public static readonly ConfigSync ConfigSync;
public static TimekeeperPlugin instance;
private static ConfigEntry<Toggle> _serverConfigLocked;
public void Awake()
{
instance = this;
Timekeeper.Setup();
TimeMan.Setup();
Localizer.Load();
Webhook.Setup();
CommandManager.Setup();
_serverConfigLocked = config("1 - General", "Lock Configuration", Toggle.On, "If on, the configuration is locked and can be changed by server admins only.");
ConfigSync.AddLockingConfigEntry<Toggle>(_serverConfigLocked);
Assembly executingAssembly = Assembly.GetExecutingAssembly();
_harmony.PatchAll(executingAssembly);
SetupWatcher();
}
private void OnDestroy()
{
((BaseUnityPlugin)this).Config.Save();
}
private void SetupWatcher()
{
FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, ConfigFileName);
fileSystemWatcher.Changed += ReadConfigValues;
fileSystemWatcher.Created += ReadConfigValues;
fileSystemWatcher.Renamed += ReadConfigValues;
fileSystemWatcher.IncludeSubdirectories = true;
fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
fileSystemWatcher.EnableRaisingEvents = true;
}
private void ReadConfigValues(object sender, FileSystemEventArgs e)
{
if (!File.Exists(ConfigFileFullPath))
{
return;
}
try
{
TimekeeperLogger.LogDebug((object)"ReadConfigValues called");
((BaseUnityPlugin)this).Config.Reload();
}
catch
{
TimekeeperLogger.LogError((object)("There was an issue loading your " + ConfigFileName));
TimekeeperLogger.LogError((object)"Please check your config entries for spelling and format!");
}
}
public ConfigEntry<T> config<[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(2)] T>(string group, string name, T value, ConfigDescription description, bool synchronizedSetting = true)
{
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Expected O, but got Unknown
ConfigDescription val = new ConfigDescription(description.Description + (synchronizedSetting ? " [Synced with Server]" : " [Not Synced with Server]"), description.AcceptableValues, description.Tags);
ConfigEntry<T> val2 = ((BaseUnityPlugin)this).Config.Bind<T>(group, name, value, val);
SyncedConfigEntry<T> syncedConfigEntry = ConfigSync.AddConfigEntry<T>(val2);
syncedConfigEntry.SynchronizedConfig = synchronizedSetting;
return val2;
}
public ConfigEntry<T> config<[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(2)] T>(string group, string name, T value, string description, bool synchronizedSetting = true)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Expected O, but got Unknown
return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting);
}
static TimekeeperPlugin()
{
string configPath = Paths.ConfigPath;
char directorySeparatorChar = Path.DirectorySeparatorChar;
ConfigFileFullPath = configPath + directorySeparatorChar + ConfigFileName;
ConnectionError = "";
TimekeeperLogger = Logger.CreateLogSource("Timekeeper");
ConfigSync = new ConfigSync("RustyMods.Timekeeper")
{
DisplayName = "Timekeeper",
CurrentVersion = "1.0.2",
MinimumRequiredVersion = "1.0.2"
};
instance = null;
_serverConfigLocked = null;
}
}
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)]
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(0)]
public static class Helpers
{
public static void SetText(this GameObject prefab, string childName, string text)
{
Transform val = Utils.FindChild(prefab.transform, childName, (IterativeSearchType)0);
Text val2 = default(Text);
if (!((Object)(object)val == (Object)null) && ((Component)val).TryGetComponent<Text>(ref val2))
{
val2.text = Localization.instance.Localize(text);
}
}
public static void CopySpriteAndMaterial(this GameObject prefab, GameObject source, string childName, string sourceChildName = "")
{
Image component = ((Component)prefab.transform.Find(childName)).GetComponent<Image>();
Image component2 = ((Component)source.transform.Find(Utility.IsNullOrWhiteSpace(sourceChildName) ? childName : sourceChildName)).GetComponent<Image>();
component.sprite = component2.sprite;
((Graphic)component).material = ((Graphic)component2).material;
}
public static void CopyButtonState(this GameObject prefab, GameObject source, string childName, string sourceChildName = "")
{
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
((Selectable)((Component)prefab.transform.Find(childName)).GetComponent<Button>()).spriteState = ((Selectable)((Component)source.transform.Find(Utility.IsNullOrWhiteSpace(sourceChildName) ? childName : sourceChildName)).GetComponent<Button>()).spriteState;
}
}
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(0)]
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)]
public class Timekeeper : MonoBehaviour
{
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(0)]
private enum PanelType
{
Opaque,
Transparent
}
[HarmonyPatch(typeof(Menu), "Start")]
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(0)]
private static class Menu_Start_Patch
{
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)]
private static void Postfix(Menu __instance)
{
//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
//IL_00cd: Expected O, but got Unknown
Sprite sprite = ((Component)((Component)((Component)__instance).transform.parent.Find("Inventory_screen")).GetComponent<InventoryGui>().m_trophieElementPrefab.transform.Find("icon_bkg")).GetComponent<Image>().sprite;
GameObject val = Object.Instantiate<GameObject>(((Component)((Transform)__instance.menuEntriesParent).Find("Settings")).gameObject, (Transform)(object)__instance.menuEntriesParent);
((Object)val).name = "Timekeeper";
val.transform.SetAsFirstSibling();
TMP_Text MenuLabel = val.GetComponentInChildren<TMP_Text>();
MenuLabel.text = Localization.instance.Localize("$label_timekeeper");
((UnityEventBase)val.GetComponent<Button>().onClick).RemoveAllListeners();
((UnityEvent)val.GetComponent<Button>().onClick).AddListener(new UnityAction(OnOpen));
GameObject sfxPrefab = __instance.m_settingsPrefab.GetComponentInChildren<ButtonSfx>().m_sfxPrefab;
ButtonSfx[] componentsInChildren = m_root.GetComponentsInChildren<ButtonSfx>(true);
foreach (ButtonSfx val2 in componentsInChildren)
{
val2.m_sfxPrefab = sfxPrefab;
}
m_item.GetComponent<ButtonSfx>().m_sfxPrefab = sfxPrefab;
((Component)m_item.transform.Find("Background")).GetComponent<Image>().sprite = sprite;
((Component)m_star.transform.Find("Day")).gameObject.SetActive(false);
m_root.CopySpriteAndMaterial(__instance.m_settingsPrefab, "Panel");
m_root.CopySpriteAndMaterial(__instance.m_settingsPrefab, "Panel/TabContent");
m_root.CopySpriteAndMaterial(__instance.m_settingsPrefab, "Panel/HeaderLine");
m_root.CopySpriteAndMaterial(__instance.m_settingsPrefab, "Panel/Back");
m_root.CopySpriteAndMaterial(__instance.m_settingsPrefab, "Panel/Collect", "Panel/Ok");
m_root.CopyButtonState(__instance.m_settingsPrefab, "Panel/Back");
m_root.CopyButtonState(__instance.m_settingsPrefab, "Panel/Collect", "Panel/Ok");
FontManager.SetFont(m_root.GetComponentsInChildren<Text>(true));
FontManager.SetFont(m_item.GetComponentsInChildren<Text>(true));
FontManager.SetFont(m_star.GetComponentsInChildren<Text>(true));
m_root.AddComponent<Timekeeper>();
Localization.OnLanguageChange = (Action)Delegate.Combine(Localization.OnLanguageChange, (Action)delegate
{
MenuLabel.text = Localization.instance.Localize("$label_timekeeper");
});
}
}
private static GameObject m_root;
private static GameObject m_item;
private static GameObject m_star;
private static ConfigEntry<float> m_scale;
private static ConfigEntry<PanelType> m_panelBackground;
private static ConfigEntry<TimekeeperPlugin.Toggle> m_sendOnCollect;
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(2)]
private static Timekeeper instance;
public Image m_panel = null;
public Image m_darken = null;
public Text m_title = null;
public Text m_description = null;
public Text m_timeLabel = null;
public Text m_time = null;
public GameObject m_tooltipParent = null;
public VerticalLayoutGroup m_tooltipContent = null;
public RectTransform m_tooltipRect = null;
public Text m_tooltip = null;
public RectTransform m_rewardListRoot = null;
public Image m_lineFill = null;
public RectTransform m_starListRoot = null;
public Button m_collectButton = null;
public Text m_collectButtonLabel = null;
public Text m_backButtonLabel = null;
private int m_selectedReward = -1;
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(2)]
private GameObject m_selectedRewardObject;
private readonly Dictionary<int, float> m_fillLevels = new Dictionary<int, float>
{
[0] = 0f,
[1] = 0.1f,
[2] = 0.23f,
[3] = 0.35f,
[4] = 0.48f,
[5] = 0.6f,
[6] = 0.73f,
[7] = 0.85f,
[8] = 1f
};
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(new byte[] { 2, 1 })]
[method: <0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(new byte[] { 2, 1 })]
[field: <0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(new byte[] { 2, 1 })]
private event Action<string> OnCollect;
public static void Setup()
{
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: Expected O, but got Unknown
//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
m_root = AssetManager.GetAssetBundle("timekeeperbundle").LoadAsset<GameObject>("Timekeeper_UI");
m_item = AssetManager.GetAssetBundle("timekeeperbundle").LoadAsset<GameObject>("Timekeeper_Item");
m_star = AssetManager.GetAssetBundle("timekeeperbundle").LoadAsset<GameObject>("Timekeeper_Star");
m_scale = TimekeeperPlugin.instance.config("Settings", "Panel Scale", 1f, new ConfigDescription("Set scale of panel", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 3f), Array.Empty<object>()));
m_panelBackground = TimekeeperPlugin.instance.config("Settings", "Background", PanelType.Opaque, "Set background panel");
m_panelBackground.SettingChanged += [<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(0)] (object _, EventArgs _) =>
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)instance == (Object)null))
{
((Graphic)instance.m_panel).color = ((m_panelBackground.Value == PanelType.Opaque) ? Color.white : Color.clear);
((Graphic)instance.m_darken).color = (Color)((m_panelBackground.Value == PanelType.Opaque) ? Color.clear : new Color(0f, 0f, 0f, 0.5f));
}
};
RectTransform rect = m_root.GetComponent<RectTransform>();
((Transform)rect).localScale = Vector3.one * m_scale.Value;
m_scale.SettingChanged += [<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(0)] (object _, EventArgs _) =>
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
((Transform)rect).localScale = Vector3.one * m_scale.Value;
if ((Object)(object)instance != (Object)null)
{
((Transform)((Component)instance).GetComponent<RectTransform>()).localScale = Vector3.one * m_scale.Value;
}
};
m_sendOnCollect = TimekeeperPlugin.instance.config("Discord", "On Collect", TimekeeperPlugin.Toggle.On, "If on, plugin will send message when player collects reward");
}
private static void OnOpen()
{
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
if (Object.op_Implicit((Object)(object)Settings.instance))
{
Settings.instance.OnBack();
}
Object.Instantiate<GameObject>(m_root, ((Component)Menu.instance).transform);
Menu.instance.m_closeMenuState = (CloseMenuState)0;
}
public void Awake()
{
//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
//IL_0206: Expected O, but got Unknown
//IL_022a: Unknown result type (might be due to invalid IL or missing references)
//IL_0234: Expected O, but got Unknown
//IL_024e: Unknown result type (might be due to invalid IL or missing references)
//IL_0247: Unknown result type (might be due to invalid IL or missing references)
//IL_0286: Unknown result type (might be due to invalid IL or missing references)
//IL_027f: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)instance != (Object)null)
{
Object.Destroy((Object)(object)instance);
}
instance = this;
m_panel = ((Component)((Component)this).transform.Find("Panel")).GetComponent<Image>();
m_darken = ((Component)((Component)this).transform.Find("Panel/darken")).GetComponent<Image>();
m_title = ((Component)((Component)this).transform.Find("Panel/Title")).GetComponent<Text>();
m_description = ((Component)((Component)this).transform.Find("Panel/TabContent/Rewards/Text")).GetComponent<Text>();
m_timeLabel = ((Component)((Component)this).transform.Find("Panel/TabContent/Rewards/TimeLabel")).GetComponent<Text>();
m_time = ((Component)((Component)this).transform.Find("Panel/TabContent/Rewards/Time")).GetComponent<Text>();
m_tooltipParent = ((Component)((Component)this).transform.Find("Panel/TabContent/Rewards/Tooltip")).gameObject;
m_tooltipContent = ((Component)((Component)this).transform.Find("Panel/TabContent/Rewards/Tooltip/Viewport/Content")).GetComponent<VerticalLayoutGroup>();
m_tooltip = ((Component)((Component)this).transform.Find("Panel/TabContent/Rewards/Tooltip/Viewport/Content/Text")).GetComponent<Text>();
m_tooltipRect = ((Component)m_tooltip).GetComponent<RectTransform>();
m_rewardListRoot = ((Component)((Component)this).transform.Find("Panel/TabContent/Rewards/RewardList/Viewport/Content")).GetComponent<RectTransform>();
m_lineFill = ((Component)((Component)this).transform.Find("Panel/TabContent/Rewards/Timeline/LineFill")).GetComponent<Image>();
m_starListRoot = ((Component)((Component)this).transform.Find("Panel/TabContent/Rewards/Timeline/StarGroup")).GetComponent<RectTransform>();
m_collectButton = ((Component)((Component)this).transform.Find("Panel/Collect")).GetComponent<Button>();
((Selectable)m_collectButton).interactable = false;
m_collectButtonLabel = ((Component)((Component)m_collectButton).transform.Find("Label")).GetComponent<Text>();
m_backButtonLabel = ((Component)((Component)this).transform.Find("Panel/Back/Label")).GetComponent<Text>();
Button component = ((Component)((Component)this).transform.Find("Panel/Back")).GetComponent<Button>();
((UnityEvent)component.onClick).AddListener(new UnityAction(OnBack));
Button component2 = ((Component)((Component)this).transform.Find("Panel/Collect")).GetComponent<Button>();
((UnityEvent)component2.onClick).AddListener(new UnityAction(Collect));
((Graphic)m_panel).color = ((m_panelBackground.Value == PanelType.Opaque) ? Color.white : Color.clear);
((Graphic)m_darken).color = (Color)((m_panelBackground.Value == PanelType.Opaque) ? Color.clear : new Color(0f, 0f, 0f, 0.5f));
m_title.text = Localization.instance.Localize("Glitnir $label_timekeeper");
m_collectButtonLabel.text = Localization.instance.Localize("$label_collect");
m_backButtonLabel.text = Localization.instance.Localize("$label_back");
OnCollect += Webhook.SendNotice;
}
public void Start()
{
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
LoadStars();
LoadRewardItems();
SetDescription();
m_timeLabel.text = Localization.instance.Localize("$msg_active_for: ");
m_tooltipParent.SetActive(false);
m_tooltip.text = "";
int day = TimeMan.GetDay();
string text = day + ((day > 1) ? " $msg_days" : " $msg_day") + " " + TimeMan.GetTimeDisplay();
m_time.text = Localization.instance.Localize(text);
((Graphic)m_time).color = new Color(1f, 0.5f, 0f, 1f);
}
public void OnDestroy()
{
instance = null;
}
public void Update()
{
if (ZInput.GetKey((KeyCode)304, true))
{
((Selectable)m_collectButton).interactable = true;
m_collectButtonLabel.text = Localization.instance.Localize("$label_collect_all");
}
else
{
((Selectable)m_collectButton).interactable = false;
m_collectButtonLabel.text = Localization.instance.Localize("$label_collect");
}
if (ZInput.GetKeyDown((KeyCode)27, true))
{
OnBack();
}
}
public void SetDescription()
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append("$msg_welcome_back " + Player.m_localPlayer.GetPlayerName() + "!\n");
stringBuilder.Append($"$msg_next_reward {TimeMan.GetNextRewardDay()}\n");
m_description.text = Localization.instance.Localize(stringBuilder.ToString());
}
public void LoadStars()
{
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Expected O, but got Unknown
if (((Transform)m_starListRoot).childCount > 0)
{
foreach (Transform item in (Transform)m_starListRoot)
{
Transform val = item;
Object.Destroy((Object)(object)((Component)val).gameObject);
}
}
int day = TimeMan.GetDay();
List<KeyValuePair<int, TimeMan.Reward>> list = (from r in TimeMan.GetRewards()
orderby r.Key
select r).ToList();
int num = ((day > 0) ? GetCurrentChunkIndex(list, day) : 0);
int num2 = num * 8;
int num3 = Math.Min(num2 + 8, list.Count);
int num4 = num3 - num2;
KeyValuePair<int, TimeMan.Reward>[] array = new KeyValuePair<int, TimeMan.Reward>[num4];
for (int i = 0; i < num4; i++)
{
array[i] = list[num2 + i];
}
if (num4 > 0)
{
float num5 = CalculateFillAmount(array, day, num4);
if (Math.Abs(num5 - 1f) < 0.01f)
{
num++;
num2 = num * 8;
num3 = Math.Min(num2 + 8, list.Count);
num4 = num3 - num2;
if (num4 > 0)
{
if (array.Length != num4)
{
array = new KeyValuePair<int, TimeMan.Reward>[num4];
}
for (int j = 0; j < num4; j++)
{
array[j] = list[num2 + j];
}
num5 = CalculateFillAmount(array, day, num4);
}
}
CreateStarsForRewards(array, num4, day);
m_lineFill.fillAmount = num5;
}
else
{
m_lineFill.fillAmount = 0f;
}
CreatePlaceholderStars(8 - num4);
}
private void CreateStarsForRewards([<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(new byte[] { 1, 0, 1 })] KeyValuePair<int, TimeMan.Reward>[] rewards, int count, int playerDay)
{
for (int i = 0; i < count; i++)
{
KeyValuePair<int, TimeMan.Reward> keyValuePair = rewards[i];
GameObject val = Object.Instantiate<GameObject>(m_star, (Transform)(object)m_starListRoot);
Text component = ((Component)val.transform.Find("Label")).GetComponent<Text>();
GameObject gameObject = ((Component)val.transform.Find("Star/Star_Lit")).gameObject;
component.text = keyValuePair.Key.ToString();
if (playerDay >= keyValuePair.Key)
{
gameObject.SetActive(true);
}
}
}
private void CreatePlaceholderStars(int count)
{
for (int i = 0; i < count; i++)
{
GameObject val = Object.Instantiate<GameObject>(m_star, (Transform)(object)m_starListRoot);
Text component = ((Component)val.transform.Find("Label")).GetComponent<Text>();
GameObject gameObject = ((Component)val.transform.Find("Star/Star_Lit")).gameObject;
component.text = "?";
gameObject.SetActive(false);
}
}
private static int GetCurrentChunkIndex([<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(new byte[] { 1, 0, 1 })] List<KeyValuePair<int, TimeMan.Reward>> rewards, int playerDay)
{
int count = rewards.Count;
int num = (count + 8 - 1) / 8;
for (int i = 0; i < num; i++)
{
int num2 = i * 8;
int num3 = Math.Min(num2 + 8, count);
if (num2 >= count)
{
break;
}
int key = rewards[num3 - 1].Key;
if (playerDay <= key)
{
return i;
}
}
return Math.Max(0, (count - 1) / 8);
}
private float CalculateFillAmount([<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(new byte[] { 1, 0, 1 })] KeyValuePair<int, TimeMan.Reward>[] chunkRewards, int playerDay, int count)
{
if (count == 0)
{
return 0f;
}
for (int i = 0; i < count; i++)
{
int key = chunkRewards[i].Key;
if (playerDay > key)
{
continue;
}
if (playerDay == key)
{
return m_fillLevels[i + 1];
}
if (i == 0)
{
if (playerDay >= key)
{
return m_fillLevels[1];
}
float num = (float)(playerDay - 1) / (float)(key - 1);
return Mathf.Lerp(m_fillLevels[0], m_fillLevels[1], num);
}
int key2 = chunkRewards[i - 1].Key;
float num2 = (float)(playerDay - key2) / (float)(key - key2);
return Mathf.Lerp(m_fillLevels[i], m_fillLevels[i + 1], num2);
}
return m_fillLevels[Math.Min(count, 8)];
}
public void LoadRewardItems()
{
//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
//IL_01af: Unknown result type (might be due to invalid IL or missing references)
//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
//IL_01d9: Expected O, but got Unknown
ItemDrop val = default(ItemDrop);
foreach (KeyValuePair<int, TimeMan.Reward> item2 in from kv in TimeMan.GetRewards()
orderby kv.Key
select kv)
{
int day = item2.Key;
if (TimeMan.IsRewardCollected(day))
{
continue;
}
TimeMan.Reward value = item2.Value;
GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(value.ItemPrefab);
if (itemPrefab != null && itemPrefab.TryGetComponent<ItemDrop>(ref val))
{
bool canInteract = TimeMan.CanCollectReward(day) && !TimeMan.IsRewardCollected(day);
GameObject item = Object.Instantiate<GameObject>(m_item, (Transform)(object)m_rewardListRoot);
Button component = item.GetComponent<Button>();
Text component2 = ((Component)item.transform.Find("Label")).GetComponent<Text>();
Image component3 = ((Component)item.transform.Find("Background/Icon")).GetComponent<Image>();
ItemData data = val.m_itemData.Clone();
data.m_stack = value.Amount;
data.m_quality = value.Quality;
data.m_variant = value.Variant;
component2.text = Localization.instance.Localize("$msg_day " + day);
component3.sprite = val.m_itemData.GetIcon();
((Graphic)component3).color = (canInteract ? Color.white : Color.black);
((UnityEvent)component.onClick).AddListener((UnityAction)delegate
{
SetTooltip(data);
m_selectedReward = day;
((Selectable)m_collectButton).interactable = canInteract;
m_selectedRewardObject = item;
});
}
}
}
public void OnBack()
{
Object.Destroy((Object)(object)((Component)this).gameObject);
if (Object.op_Implicit((Object)(object)Settings.instance))
{
Settings.instance.OnBack();
}
}
public void Collect()
{
if (ZInput.GetKey((KeyCode)304, true))
{
int day = TimeMan.GetDay();
ItemDrop val = default(ItemDrop);
foreach (KeyValuePair<int, TimeMan.Reward> item in from kvp in TimeMan.GetRewards()
orderby kvp.Key
select kvp)
{
if (item.Key > day)
{
break;
}
if (TimeMan.IsRewardCollected(item.Key))
{
continue;
}
GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(item.Value.ItemPrefab);
if (itemPrefab != null && itemPrefab.TryGetComponent<ItemDrop>(ref val))
{
ItemData val2 = val.m_itemData.Clone();
val2.m_dropPrefab = itemPrefab;
val2.m_stack = item.Value.Amount;
val2.m_quality = item.Value.Quality;
val2.m_variant = item.Value.Variant;
if (!((Humanoid)Player.m_localPlayer).GetInventory().CanAddItem(val2, -1))
{
((Character)Player.m_localPlayer).Message((MessageType)1, "$inventory_full", 0, (Sprite)null);
break;
}
if (!((Humanoid)Player.m_localPlayer).GetInventory().AddItem(val2))
{
break;
}
if (m_sendOnCollect.Value == TimekeeperPlugin.Toggle.On)
{
this.OnCollect?.Invoke($"{Player.m_localPlayer.GetPlayerName()} $msg_has_collected {m_selectedReward}");
}
TimeMan.SetRewardCollected(item.Key);
m_tooltipParent.SetActive(false);
m_selectedReward = -1;
m_tooltip.text = "";
((Selectable)m_collectButton).interactable = false;
((Character)Player.m_localPlayer).Message((MessageType)1, "$msg_added " + val2.m_shared.m_name, val2.m_stack, val2.GetIcon());
}
}
OnBack();
}
else
{
if (TimeMan.IsRewardCollected(m_selectedReward) || !TimeMan.GetRewards().TryGetValue(m_selectedReward, out var value))
{
return;
}
GameObject itemPrefab2 = ObjectDB.instance.GetItemPrefab(value.ItemPrefab);
ItemDrop val3 = default(ItemDrop);
if (itemPrefab2 == null || !itemPrefab2.TryGetComponent<ItemDrop>(ref val3))
{
return;
}
ItemData val4 = val3.m_itemData.Clone();
val4.m_dropPrefab = itemPrefab2;
val4.m_stack = value.Amount;
val4.m_quality = value.Quality;
val4.m_variant = value.Variant;
if (!((Humanoid)Player.m_localPlayer).GetInventory().CanAddItem(val4, -1))
{
((Character)Player.m_localPlayer).Message((MessageType)1, "$inventory_full", 0, (Sprite)null);
}
else if (((Humanoid)Player.m_localPlayer).GetInventory().AddItem(val4))
{
if (m_sendOnCollect.Value == TimekeeperPlugin.Toggle.On)
{
this.OnCollect?.Invoke($"{Player.m_localPlayer.GetPlayerName()} $msg_has_collected {m_selectedReward}");
}
TimeMan.SetRewardCollected(m_selectedReward);
m_tooltipParent.SetActive(false);
m_selectedReward = -1;
m_tooltip.text = "";
((Selectable)m_collectButton).interactable = false;
if ((Object)(object)m_selectedRewardObject != (Object)null)
{
Object.Destroy((Object)(object)m_selectedRewardObject);
}
((Character)Player.m_localPlayer).Message((MessageType)1, "$msg_added " + val4.m_shared.m_name, val4.m_stack, val4.GetIcon());
}
}
}
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(2)]
public void SetTooltip(ItemData item)
{
//IL_0121: Unknown result type (might be due to invalid IL or missing references)
//IL_0132: Unknown result type (might be due to invalid IL or missing references)
//IL_0137: Unknown result type (might be due to invalid IL or missing references)
if (item == null)
{
m_tooltip.text = "";
}
else
{
m_tooltipParent.SetActive(true);
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append("<color=yellow>" + item.m_shared.m_name + "</color>" + ((item.m_stack > 1) ? $" x{item.m_stack}" : "") + "\n\n");
stringBuilder.Append(item.GetTooltip(-1) + "\n\n");
m_tooltip.text = Localization.instance.Localize(stringBuilder.ToString());
}
Canvas.ForceUpdateCanvases();
float textPreferredHeight = GetTextPreferredHeight(m_tooltip, m_tooltipRect);
textPreferredHeight += (float)(((LayoutGroup)m_tooltipContent).padding.top + ((LayoutGroup)m_tooltipContent).padding.bottom);
float num = 260f;
float num2 = Mathf.Max(textPreferredHeight, num);
float x = m_tooltipRect.sizeDelta.x;
Vector2 sizeDelta = m_tooltipRect.sizeDelta;
((Vector2)(ref sizeDelta)).Set(x, num2);
}
private static float GetTextPreferredHeight(Text text, RectTransform rect)
{
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
if (string.IsNullOrEmpty(text.text))
{
return 0f;
}
TextGenerator cachedTextGenerator = text.cachedTextGenerator;
Rect rect2 = rect.rect;
TextGenerationSettings generationSettings = text.GetGenerationSettings(((Rect)(ref rect2)).size);
return cachedTextGenerator.GetPreferredHeight(text.text, generationSettings);
}
}
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)]
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(0)]
public static class TimeMan
{
[HarmonyPatch(typeof(Player), "SetControls")]
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(0)]
private static class Player_SetControls_Patch
{
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)]
private static void Postfix(Player __instance, Vector3 movedir, bool attack, bool attackHold, bool secondaryAttack, bool secondaryAttackHold, bool block, bool blockHold, bool jump, bool crouch, bool run, bool autoRun, bool dodge)
{
//IL_0032: 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)
if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
{
if (attack || attackHold || secondaryAttack || secondaryAttackHold || block || blockHold || jump || crouch || run || dodge || movedir != Vector3.zero)
{
m_active = true;
m_timeSinceLastInput = Time.fixedDeltaTime;
}
else if (Time.fixedDeltaTime > m_timeSinceLastInput + m_afkDuration.Value)
{
m_active = false;
}
if (m_active)
{
m_activeTimer = Math.Max(0.0, m_activeTimer);
m_activeTimer += Math.Max(0f, Time.fixedDeltaTime);
SendDayNotice();
}
}
}
}
[HarmonyPatch(typeof(Player), "Load")]
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(0)]
private static class Player_Load_Patch
{
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)]
private static void Postfix(Player __instance)
{
Load(__instance);
}
}
[HarmonyPatch(typeof(Player), "Save")]
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(0)]
private static class Player_Save_Patch
{
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)]
private static void Prefix(Player __instance)
{
Save(__instance);
}
}
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(0)]
[HarmonyPatch(typeof(ZNet), "Awake")]
private static class ZNet_Awake_Patch
{
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)]
private static void Postfix(ZNet __instance)
{
if (__instance.IsServer())
{
UpdateServerRewards();
}
}
}
[Serializable]
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(0)]
public class Reward
{
public string ItemPrefab;
public int Amount;
public int Quality;
public int Variant;
public Reward(string item, int amount = 1, int quality = 1, int variant = 0)
{
ItemPrefab = item;
Amount = amount;
Quality = quality;
Variant = variant;
}
}
private const string RootFolderName = "Timekeeper";
private const string FileName = "Rewards.json";
private static readonly string RootFolderPath;
private static readonly string FilePath;
private static readonly CustomSyncedValue<string> ServerRewards;
private static Dictionary<int, Reward> m_rewards;
private static List<int> m_collectedRewards;
private static bool m_active;
private static float m_timeSinceLastInput;
public static double m_activeTimer;
private static int m_lastDay;
private static ConfigEntry<float> m_afkDuration;
private static ConfigEntry<TimekeeperPlugin.Toggle> m_sendDay;
private static void SendDayNotice()
{
if (m_sendDay.Value != 0)
{
int day = GetDay();
if (day != m_lastDay)
{
m_lastDay = day;
Webhook.instance.SendNotification($"{Player.m_localPlayer.GetPlayerName()} $msg_has_been_active {day} $msg_days");
}
}
}
private static void UpdateServerRewards()
{
string value = JsonConvert.SerializeObject((object)m_rewards);
ServerRewards.Value = value;
}
public static Dictionary<int, Reward> GetRewards()
{
return m_rewards;
}
public static int GetDay()
{
if (m_activeTimer < 0.0)
{
TimekeeperPlugin.TimekeeperLogger.LogWarning((object)$"Active timer is negative: {m_activeTimer}, resetting to 0");
m_activeTimer = 0.0;
}
return (int)(m_activeTimer / 1800.0);
}
private static float GetTimeOfDay()
{
return (float)(m_activeTimer % 1800.0);
}
public static string GetTimeDisplay()
{
float timeOfDay = GetTimeOfDay();
float num = 1800f;
float num2 = num / 24f;
float num3 = num2 / 60f;
int num4 = Mathf.FloorToInt(timeOfDay / num2);
int num5 = Mathf.FloorToInt(timeOfDay % num2 / num3);
return $"{num4}:{num5:D2}";
}
public static void Clear(Player player)
{
player.m_customData.Remove("TimekeeperCollected");
player.m_customData.Remove("TimekeeperTime");
m_activeTimer = 0.0;
m_collectedRewards.Clear();
}
private static void Save(Player player)
{
player.m_customData["TimekeeperCollected"] = JsonConvert.SerializeObject((object)m_collectedRewards);
player.m_customData["TimekeeperTime"] = m_activeTimer.ToString(CultureInfo.CurrentCulture);
}
private static void Load(Player player)
{
m_activeTimer = 0.0;
if (player.m_customData.TryGetValue("TimekeeperCollected", out var value))
{
try
{
List<int> list = JsonConvert.DeserializeObject<List<int>>(value);
if (list != null)
{
m_collectedRewards = list;
}
}
catch
{
TimekeeperPlugin.TimekeeperLogger.LogWarning((object)"Failed to parse collected timekeeper keys");
player.m_customData.Remove("TimekeeperCollected");
}
}
if (player.m_customData.TryGetValue("TimekeeperTime", out var value2) && double.TryParse(value2, out var result))
{
m_activeTimer = Math.Max(0.0, result);
m_lastDay = GetDay();
}
}
public static bool IsRewardCollected(int key)
{
return m_collectedRewards.Contains(key);
}
public static void SetRewardCollected(int key)
{
m_collectedRewards.Add(key);
}
public static int GetNextRewardDay()
{
foreach (KeyValuePair<int, Reward> item in m_rewards.OrderBy([<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(0)] (KeyValuePair<int, Reward> kvp) => kvp.Key))
{
if (item.Key <= GetDay())
{
continue;
}
return item.Key;
}
return -1;
}
public static bool CanCollectReward(int key)
{
return key <= GetDay();
}
public static void Setup()
{
m_afkDuration = TimekeeperPlugin.instance.config("Settings", "AFK Duration", 10f, "Set seconds until no input triggers AFK status");
m_sendDay = TimekeeperPlugin.instance.config("Discord", "On New Day", TimekeeperPlugin.Toggle.Off, "If on, will send message when player reaches a new day");
ServerRewards.ValueChanged += delegate
{
if ((!Object.op_Implicit((Object)(object)ZNet.instance) || !ZNet.instance.IsServer()) && !Utility.IsNullOrWhiteSpace(ServerRewards.Value))
{
Dictionary<int, Reward> dictionary3 = JsonConvert.DeserializeObject<Dictionary<int, Reward>>(ServerRewards.Value);
if (dictionary3 != null)
{
m_rewards = dictionary3;
}
}
};
LoadDefaults();
if (!Directory.Exists(RootFolderPath))
{
Directory.CreateDirectory(RootFolderPath);
}
if (!File.Exists(FilePath))
{
UpdateRewardFile();
}
else
{
try
{
Dictionary<int, Reward> dictionary = JsonConvert.DeserializeObject<Dictionary<int, Reward>>(File.ReadAllText(FilePath));
if (dictionary != null)
{
m_rewards = dictionary;
}
}
catch
{
TimekeeperPlugin.TimekeeperLogger.LogWarning((object)"Failed to parse file: Rewards.json");
}
}
FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(RootFolderPath, "Rewards.json");
fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
fileSystemWatcher.EnableRaisingEvents = true;
fileSystemWatcher.Changed += OnFileChange;
fileSystemWatcher.Created += OnFileChange;
static void OnFileChange(object sender, FileSystemEventArgs args)
{
if (Object.op_Implicit((Object)(object)ZNet.instance) && !ZNet.instance.IsServer())
{
return;
}
TimekeeperPlugin.TimekeeperLogger.LogDebug((object)"Timekeeper config changed, reloading rewards");
try
{
Dictionary<int, Reward> dictionary2 = JsonConvert.DeserializeObject<Dictionary<int, Reward>>(File.ReadAllText(FilePath));
if (dictionary2 != null)
{
m_rewards = dictionary2;
}
UpdateServerRewards();
}
catch
{
TimekeeperPlugin.TimekeeperLogger.LogWarning((object)"Failed to parse file: Rewards.json");
}
}
}
private static void LoadDefaults()
{
m_rewards[1] = new Reward("Coins");
m_rewards[2] = new Reward("Coins");
m_rewards[4] = new Reward("Coins");
m_rewards[6] = new Reward("Coins");
m_rewards[8] = new Reward("Coins");
m_rewards[10] = new Reward("Coins");
m_rewards[12] = new Reward("Coins");
m_rewards[14] = new Reward("Coins");
m_rewards[16] = new Reward("Coins");
m_rewards[18] = new Reward("Coins");
m_rewards[21] = new Reward("Coins");
m_rewards[24] = new Reward("Coins");
m_rewards[27] = new Reward("Coins");
m_rewards[30] = new Reward("Coins");
m_rewards[33] = new Reward("Coins");
m_rewards[36] = new Reward("Coins");
m_rewards[39] = new Reward("Coins");
m_rewards[42] = new Reward("Coins");
m_rewards[45] = new Reward("Coins");
m_rewards[48] = new Reward("Coins");
m_rewards[51] = new Reward("Coins");
m_rewards[54] = new Reward("Coins");
m_rewards[57] = new Reward("Coins");
m_rewards[60] = new Reward("Coins");
m_rewards[63] = new Reward("Coins");
m_rewards[66] = new Reward("Coins");
m_rewards[69] = new Reward("Coins");
m_rewards[72] = new Reward("Coins");
m_rewards[75] = new Reward("Coins");
m_rewards[78] = new Reward("Coins");
m_rewards[81] = new Reward("Coins");
m_rewards[84] = new Reward("Coins");
m_rewards[87] = new Reward("Coins");
m_rewards[90] = new Reward("Coins");
m_rewards[94] = new Reward("Coins");
m_rewards[98] = new Reward("Coins");
m_rewards[102] = new Reward("Coins");
m_rewards[106] = new Reward("Coins");
m_rewards[110] = new Reward("Coins");
m_rewards[114] = new Reward("Coins");
m_rewards[118] = new Reward("Coins");
m_rewards[122] = new Reward("Coins");
m_rewards[126] = new Reward("Coins");
m_rewards[130] = new Reward("Coins");
m_rewards[134] = new Reward("Coins");
m_rewards[138] = new Reward("Coins");
m_rewards[142] = new Reward("Coins");
m_rewards[146] = new Reward("Coins");
m_rewards[150] = new Reward("Coins");
m_rewards[154] = new Reward("Coins");
m_rewards[158] = new Reward("Coins");
m_rewards[162] = new Reward("Coins");
m_rewards[166] = new Reward("Coins");
m_rewards[170] = new Reward("Coins");
m_rewards[174] = new Reward("Coins");
m_rewards[178] = new Reward("Coins");
m_rewards[182] = new Reward("Coins");
m_rewards[187] = new Reward("Coins");
m_rewards[192] = new Reward("Coins");
m_rewards[197] = new Reward("Coins");
m_rewards[202] = new Reward("Coins");
m_rewards[207] = new Reward("Coins");
m_rewards[212] = new Reward("Coins");
m_rewards[217] = new Reward("Coins");
m_rewards[222] = new Reward("Coins");
m_rewards[227] = new Reward("Coins");
m_rewards[232] = new Reward("Coins");
m_rewards[237] = new Reward("Coins");
m_rewards[242] = new Reward("Coins");
m_rewards[247] = new Reward("Coins");
m_rewards[252] = new Reward("Coins");
m_rewards[257] = new Reward("Coins");
m_rewards[262] = new Reward("Coins");
m_rewards[267] = new Reward("Coins");
m_rewards[272] = new Reward("Coins");
m_rewards[277] = new Reward("Coins");
m_rewards[282] = new Reward("Coins");
m_rewards[287] = new Reward("Coins");
m_rewards[292] = new Reward("Coins");
m_rewards[297] = new Reward("Coins");
m_rewards[302] = new Reward("Coins");
m_rewards[307] = new Reward("Coins");
m_rewards[312] = new Reward("Coins");
m_rewards[317] = new Reward("Coins");
m_rewards[322] = new Reward("Coins");
m_rewards[326] = new Reward("Coins");
m_rewards[330] = new Reward("Coins");
m_rewards[334] = new Reward("Coins");
m_rewards[338] = new Reward("Coins");
m_rewards[341] = new Reward("Coins");
m_rewards[344] = new Reward("Coins");
m_rewards[347] = new Reward("Coins");
m_rewards[350] = new Reward("Coins");
m_rewards[353] = new Reward("Coins");
m_rewards[356] = new Reward("Coins");
m_rewards[358] = new Reward("Coins");
m_rewards[360] = new Reward("Coins");
m_rewards[362] = new Reward("Coins");
m_rewards[364] = new Reward("Coins");
m_rewards[365] = new Reward("Coins");
}
public static void AddReward(int day, Reward reward)
{
m_rewards[day] = reward;
}
public static void UpdateRewardFile()
{
string contents = JsonConvert.SerializeObject((object)m_rewards, (Formatting)1);
File.WriteAllText(FilePath, contents);
}
static TimeMan()
{
string configPath = Paths.ConfigPath;
char directorySeparatorChar = Path.DirectorySeparatorChar;
RootFolderPath = configPath + directorySeparatorChar + "Timekeeper";
string rootFolderPath = RootFolderPath;
directorySeparatorChar = Path.DirectorySeparatorChar;
FilePath = rootFolderPath + directorySeparatorChar + "Rewards.json";
ServerRewards = new CustomSyncedValue<string>(TimekeeperPlugin.ConfigSync, "ServerTimekeeperRewards", "");
m_rewards = new Dictionary<int, Reward>();
m_collectedRewards = new List<int>();
m_activeTimer = 0.0;
m_lastDay = -1;
m_afkDuration = null;
m_sendDay = null;
}
}
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(0)]
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)]
public class Webhook : MonoBehaviour
{
[Serializable]
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(2)]
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(0)]
public class DiscordWebhookData
{
public string content;
public bool tts;
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(new byte[] { 2, 1 })]
public Embed[] embeds;
public string username;
public string avatar_url;
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)]
public DiscordWebhookData(string content)
{
this.content = Localization.instance.Localize(content);
}
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)]
public DiscordWebhookData(params Embed[] embeds)
{
this.embeds = embeds;
}
}
[Serializable]
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(2)]
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(0)]
public class Embed
{
public string title;
public string description;
public string url;
public string timestamp;
public int? color;
public Footer footer;
public EmbedImage image;
public EmbedImage thumbnail;
public EmbedVideo video;
public EmbedProvider provider;
public EmbedAuthor author;
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(new byte[] { 2, 1 })]
public EmbedField[] fields;
public Embed()
{
timestamp = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ");
}
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)]
public Embed(string title, string description)
{
this.title = Localization.instance.Localize(title);
this.description = Localization.instance.Localize(description);
timestamp = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ");
}
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)]
public Embed(string title, params EmbedField[] fields)
{
this.title = title;
this.fields = fields;
timestamp = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ");
}
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)]
public Embed(string description)
{
this.description = Localization.instance.Localize(description);
timestamp = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ");
}
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)]
public Embed(string title, List<EmbedField> fields)
: this(title, fields.ToArray())
{
}
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)]
public void AddImage(string imageUrl)
{
if (!string.IsNullOrEmpty(imageUrl))
{
image = new EmbedImage(imageUrl);
}
}
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)]
public void AddThumbnail(string thumbnailUrl)
{
if (!string.IsNullOrEmpty(thumbnailUrl))
{
thumbnail = new EmbedImage(thumbnailUrl);
}
}
public void SetColor(Color Color)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
color = ColorToInt(Color);
}
}
[Serializable]
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(0)]
[Description("Discord image json object")]
public class EmbedImage
{
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(2)]
public string url;
public int width;
public int height;
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)]
public EmbedImage(string url, int width = 256, int height = 256)
{
this.url = url;
this.width = width;
this.height = height;
}
}
[Serializable]
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(0)]
public class EmbedVideo
{
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(2)]
public string url;
public int height;
public int width;
}
[Serializable]
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(2)]
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(0)]
public class EmbedProvider
{
public string name;
public string url;
}
[Serializable]
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(2)]
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(0)]
[Description("Discord author json object")]
public class EmbedAuthor
{
public string name;
public string icon_url;
}
[Serializable]
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(2)]
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(0)]
[Description("Discord embed json object")]
public class EmbedField
{
public string name;
public string value;
public bool inline;
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)]
public EmbedField(string name, string value, bool inline = true)
{
this.name = Localization.instance.Localize(name);
this.value = Localization.instance.Localize(value);
this.inline = inline;
}
}
[Serializable]
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(0)]
[Description("Discord footer json object")]
public class Footer
{
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(2)]
public string text;
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(2)]
public string icon_url;
public Footer(string text)
{
this.text = Localization.instance.Localize(text);
}
public void AddIcon(string url)
{
if (!string.IsNullOrEmpty(url))
{
icon_url = url;
}
}
}
[Serializable]
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(2)]
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(0)]
[Description("Discord message json object")]
public class Message
{
public string id;
public string channel_id;
public User author;
public string content;
public string timestamp;
public string edited_timestamp;
public bool tts;
public bool mention_everyone;
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(new byte[] { 2, 1 })]
public User[] mentions;
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(new byte[] { 2, 1 })]
public User[] mention_roles;
public int type;
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(new byte[] { 2, 1 })]
public Embed[] embeds;
}
[Serializable]
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(2)]
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(0)]
[Description("Discord user json object")]
public class User
{
public string id;
public string username;
public string global_name;
public string discriminator;
public bool bot;
public string avatar;
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)]
public string GetDisplayName()
{
return ((!string.IsNullOrEmpty(global_name)) ? global_name : username) ?? string.Empty;
}
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)]
public string GetFullUsername()
{
return (!string.IsNullOrEmpty(discriminator) && discriminator != "0") ? (username + "#" + discriminator) : (username ?? string.Empty);
}
}
private static ConfigEntry<string> m_webhookURL;
public static Webhook instance;
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(new byte[] { 2, 1 })]
[method: <0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(new byte[] { 2, 1 })]
[field: <0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(new byte[] { 2, 1 })]
public event Action<string> OnError;
public static void Setup()
{
m_webhookURL = TimekeeperPlugin.instance.config("Discord", "Webhook URL", "", "Set webhook to receive notifications about timekeeper");
((Component)TimekeeperPlugin.instance).gameObject.AddComponent<Webhook>();
}
public void Awake()
{
instance = this;
OnError += HandleError;
}
private static void HandleError(string message)
{
TimekeeperPlugin.TimekeeperLogger.LogWarning((object)message);
}
public static void SendNotice(string message)
{
instance.SendNotification(message);
}
public void SendNotification(string message)
{
DiscordWebhookData data = new DiscordWebhookData(message);
((MonoBehaviour)this).StartCoroutine(SendWebhookMessage(data, m_webhookURL.Value));
}
public static void SendEmbedNotice(string title, string content, string thumbnail = "")
{
instance.SendEmbedMessage(title, content, thumbnail);
}
public void SendEmbedMessage(string title, string content, string thumbnail = "")
{
Embed embed = new Embed(title, content);
embed.AddThumbnail(thumbnail);
DiscordWebhookData data = new DiscordWebhookData(embed);
((MonoBehaviour)this).StartCoroutine(SendWebhookMessage(data, m_webhookURL.Value));
}
private IEnumerator SendWebhookMessage(DiscordWebhookData data, string webhookURL)
{
if (string.IsNullOrEmpty(webhookURL))
{
this.OnError?.Invoke("Webhook URL is not set!");
yield break;
}
string jsonData = JsonConvert.SerializeObject((object)data);
byte[] bodyRaw = Encoding.UTF8.GetBytes(jsonData);
UnityWebRequest request = new UnityWebRequest(webhookURL, "POST");
try
{
request.uploadHandler = (UploadHandler)new UploadHandlerRaw(bodyRaw);
request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
request.SetRequestHeader("Content-Type", "application/json");
yield return request.SendWebRequest();
if ((int)request.result != 1)
{
string error = "Failed to send message: " + request.error + " - " + request.downloadHandler.text;
this.OnError?.Invoke(error);
}
}
finally
{
((IDisposable)request)?.Dispose();
}
}
public static int ColorToInt(Color color)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
int num = Mathf.RoundToInt(color.r * 255f);
int num2 = Mathf.RoundToInt(color.g * 255f);
int num3 = Mathf.RoundToInt(color.b * 255f);
return (num << 16) + (num2 << 8) + num3;
}
}
[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
public static class RegisterAndCheckVersion
{
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)]
private static void Prefix(ZNetPeer peer, ref ZNet __instance)
{
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Expected O, but got Unknown
TimekeeperPlugin.TimekeeperLogger.LogDebug((object)"Registering version RPC handler");
peer.m_rpc.Register<ZPackage>("Timekeeper_VersionCheck", (Action<ZRpc, ZPackage>)RpcHandlers.RPC_Timekeeper_Version);
TimekeeperPlugin.TimekeeperLogger.LogInfo((object)"Invoking version check");
ZPackage val = new ZPackage();
val.Write("1.0.2");
peer.m_rpc.Invoke("Timekeeper_VersionCheck", new object[1] { val });
}
}
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)]
[HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")]
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(0)]
public static class VerifyClient
{
private static bool Prefix(ZRpc rpc, ZPackage pkg, ref ZNet __instance)
{
if (!__instance.IsServer() || RpcHandlers.ValidatedPeers.Contains(rpc))
{
return true;
}
TimekeeperPlugin.TimekeeperLogger.LogWarning((object)("Peer (" + rpc.m_socket.GetHostName() + ") never sent version or couldn't due to previous disconnect, disconnecting"));
rpc.Invoke("Error", new object[1] { 3 });
return false;
}
private static void Postfix(ZNet __instance)
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Expected O, but got Unknown
ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), "TimekeeperRequestAdminSync", new object[1] { (object)new ZPackage() });
}
}
[HarmonyPatch(typeof(FejdStartup), "ShowConnectError")]
public class ShowConnectionError
{
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)]
private static void Postfix(FejdStartup __instance)
{
if (__instance.m_connectionFailedPanel.activeSelf)
{
__instance.m_connectionFailedError.fontSizeMax = 25f;
__instance.m_connectionFailedError.fontSizeMin = 15f;
TMP_Text connectionFailedError = __instance.m_connectionFailedError;
connectionFailedError.text = connectionFailedError.text + "\n" + TimekeeperPlugin.ConnectionError;
}
}
}
[HarmonyPatch(typeof(ZNet), "Disconnect")]
public static class RemoveDisconnectedPeerFromVerified
{
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)]
private static void Prefix(ZNetPeer peer, ref ZNet __instance)
{
if (__instance.IsServer())
{
TimekeeperPlugin.TimekeeperLogger.LogInfo((object)("Peer (" + peer.m_rpc.m_socket.GetHostName() + ") disconnected, removing from validated list"));
RpcHandlers.ValidatedPeers.Remove(peer.m_rpc);
}
}
}
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(0)]
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)]
public static class RpcHandlers
{
public static readonly List<ZRpc> ValidatedPeers = new List<ZRpc>();
public static void RPC_Timekeeper_Version(ZRpc rpc, ZPackage pkg)
{
string text = pkg.ReadString();
TimekeeperPlugin.TimekeeperLogger.LogInfo((object)("Version check, local: 1.0.2, remote: " + text));
if (text != "1.0.2")
{
TimekeeperPlugin.ConnectionError = "Timekeeper Installed: 1.0.2\n Needed: " + text;
if (ZNet.instance.IsServer())
{
TimekeeperPlugin.TimekeeperLogger.LogWarning((object)("Peer (" + rpc.m_socket.GetHostName() + ") has incompatible version, disconnecting..."));
rpc.Invoke("Error", new object[1] { 3 });
}
}
else if (!ZNet.instance.IsServer())
{
TimekeeperPlugin.TimekeeperLogger.LogInfo((object)"Received same version from server!");
}
else
{
TimekeeperPlugin.TimekeeperLogger.LogInfo((object)("Adding peer (" + rpc.m_socket.GetHostName() + ") to validated list"));
ValidatedPeers.Add(rpc);
}
}
public static string ComputeHashForMod()
{
using SHA256 sHA = SHA256.Create();
byte[] array = sHA.ComputeHash(File.ReadAllBytes(Assembly.GetExecutingAssembly().Location));
StringBuilder stringBuilder = new StringBuilder();
byte[] array2 = array;
foreach (byte b in array2)
{
stringBuilder.Append(b.ToString("X2"));
}
return stringBuilder.ToString();
}
}
}
namespace Timekeeper.Managers
{
public static class CommandManager
{
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(0)]
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)]
public class CommandData
{
[HarmonyPatch(typeof(Terminal), "updateSearch")]
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(0)]
private static class Terminal_UpdateSearch_Patch
{
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)]
private static bool Prefix(Terminal __instance, string word)
{
if ((Object)(object)__instance.m_search == (Object)null)
{
return true;
}
string[] array = ((TMP_InputField)__instance.m_input).text.Split(new char[1] { ' ' });
if (array.Length < 3)
{
return true;
}
if (array[0] != m_startCommand)
{
return true;
}
return HandleSearch(__instance, word, array);
}
}
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(0)]
[HarmonyPatch(typeof(Terminal), "tabCycle")]
private static class Terminal_TabCycle_Patch
{
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)]
private static bool Prefix(Terminal __instance, string word, [<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(new byte[] { 2, 1 })] List<string> options, bool usePrefix)
{
if (options == null || options.Count == 0)
{
return true;
}
usePrefix = usePrefix && __instance.m_tabPrefix > '\0';
if (usePrefix)
{
if (word.Length < 1 || word[0] != __instance.m_tabPrefix)
{
return true;
}
word = word.Substring(1);
}
return HandleTabCycle(__instance, word, options, usePrefix);
}
}
public static readonly string m_startCommand = "timekeeper";
public static readonly Dictionary<string, CommandData> m_commands = new Dictionary<string, CommandData>();
public readonly string m_description;
private readonly bool m_isSecret;
private readonly bool m_adminOnly;
private readonly Func<ConsoleEventArgs, bool> m_command;
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(new byte[] { 2, 1, 1 })]
private readonly Func<List<string>> m_optionFetcher;
public bool Run(ConsoleEventArgs args)
{
return !IsAdmin() || m_command(args);
}
private bool IsAdmin()
{
if (!Object.op_Implicit((Object)(object)ZNet.m_instance))
{
return true;
}
if (!m_adminOnly || ZNet.m_instance.LocalPlayerIsAdminOrHost())
{
return true;
}
Debug.LogWarning((object)"Admin only command");
return false;
}
public bool IsSecret()
{
return m_isSecret;
}
public List<string> FetchOptions()
{
return (m_optionFetcher == null) ? new List<string>() : m_optionFetcher();
}
public bool HasOptions()
{
return m_optionFetcher != null;
}
public CommandData(string input, string description, Func<ConsoleEventArgs, bool> command, [<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(new byte[] { 2, 1, 1 })] Func<List<string>> optionsFetcher = null, bool isSecret = false, bool adminOnly = false)
{
m_description = description;
m_command = command;
m_isSecret = isSecret;
m_commands[input] = this;
m_optionFetcher = optionsFetcher;
m_adminOnly = adminOnly;
}
private static bool HandleSearch(Terminal __instance, string word, string[] strArray)
{
if (!m_commands.TryGetValue(strArray[1], out var value))
{
return true;
}
if (value.HasOptions() && strArray.Length == 3)
{
List<string> list = value.FetchOptions();
string currentSearch = strArray[2];
List<string> list2;
if (!Utility.IsNullOrWhiteSpace(currentSearch))
{
int num = list.IndexOf(currentSearch);
list2 = ((num != -1) ? list.GetRange(num, list.Count - num) : list);
list2 = list2.FindAll((string x) => x.ToLower().Contains(currentSearch.ToLower()));
}
else
{
list2 = list;
}
if (list2.Count <= 0)
{
__instance.m_search.text = value.m_description;
}
else
{
__instance.m_lastSearch.Clear();
__instance.m_lastSearch.AddRange(list2);
__instance.m_lastSearch.Remove(word);
__instance.m_search.text = "";
int num2 = 10;
int num3 = Math.Min(__instance.m_lastSearch.Count, num2);
for (int i = 0; i < num3; i++)
{
string text = __instance.m_lastSearch[i];
TMP_Text search = __instance.m_search;
search.text = search.text + text + " ";
}
if (__instance.m_lastSearch.Count <= num2)
{
return false;
}
int num4 = __instance.m_lastSearch.Count - num2;
TMP_Text search2 = __instance.m_search;
search2.text += $"... {num4} more.";
}
}
else
{
__instance.m_search.text = value.m_description;
}
return false;
}
private static bool HandleTabCycle(Terminal __instance, string word, List<string> options, bool usePrefix)
{
string text = ((TMP_InputField)__instance.m_input).text;
string[] array = text.Split(new char[1] { ' ' });
if (array.Length < 2 || !string.Equals(array[0], m_startCommand, StringComparison.CurrentCultureIgnoreCase) || !m_commands.ContainsKey(array[1].ToLower()))
{
return true;
}
if (__instance.m_tabCaretPosition == -1)
{
__instance.m_tabOptions.Clear();
__instance.m_tabCaretPosition = ((TMP_InputField)__instance.m_input).caretPosition;
word = word.ToLower();
__instance.m_tabLength = word.Length;
if (__instance.m_tabLength == 0)
{
__instance.m_tabOptions.AddRange(options);
}
else
{
foreach (string option in options)
{
if (option != null && option.Length > __instance.m_tabLength && option.Substring(0, __instance.m_tabLength).ToLower() == word)
{
__instance.m_tabOptions.Add(option);
}
}
}
__instance.m_tabOptions.Sort();
__instance.m_tabIndex = -1;
}
if (__instance.m_tabOptions.Count == 0)
{
__instance.m_tabOptions.AddRange(__instance.m_lastSearch);
}
if (__instance.m_tabOptions.Count == 0)
{
return false;
}
if (++__instance.m_tabIndex >= __instance.m_tabOptions.Count)
{
__instance.m_tabIndex = 0;
}
if (__instance.m_tabCaretPosition - __instance.m_tabLength >= 0)
{
int num = 0;
int num2 = 0;
for (int i = 0; i < text.Length; i++)
{
if (text[i] == ' ')
{
num++;
if (num == 2)
{
num2 = i + 1;
break;
}
}
}
if (array.Length >= 3 && num2 > 0)
{
string text2 = text.Substring(0, num2);
((TMP_InputField)__instance.m_input).text = text2 + __instance.m_tabOptions[__instance.m_tabIndex];
}
else if (array.Length == 2)
{
((TMP_InputField)__instance.m_input).text = text + " " + __instance.m_tabOptions[__instance.m_tabIndex];
}
}
int tabCaretPositionEnd = (((TMP_InputField)__instance.m_input).caretPosition = ((TMP_InputField)__instance.m_input).text.Length);
__instance.m_tabCaretPositionEnd = tabCaretPositionEnd;
return false;
}
}
[Serializable]
[CompilerGenerated]
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static ConsoleEventFailable <>9__0_0;
public static Func<KeyValuePair<string, CommandData>, bool> <>9__0_1;
public static Func<KeyValuePair<string, CommandData>, string> <>9__0_2;
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(new byte[] { 0, 1 })]
public static Func<ConsoleEventArgs, bool> <>9__0_3;
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(new byte[] { 0, 1 })]
public static Func<ConsoleEventArgs, bool> <>9__0_4;
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(new byte[] { 0, 1 })]
public static Func<ConsoleEventArgs, bool> <>9__0_5;
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(new byte[] { 0, 1 })]
public static Func<ConsoleEventArgs, bool> <>9__0_6;
internal object <Setup>b__0_0(ConsoleEventArgs args)
{
if (args.Length < 2)
{
return false;
}
if (!CommandData.m_commands.TryGetValue(args[1], out var value))
{
return false;
}
return value.Run(args);
}
internal bool <Setup>b__0_1(KeyValuePair<string, CommandData> x)
{
return !x.Value.IsSecret();
}
internal string <Setup>b__0_2(KeyValuePair<string, CommandData> x)
{
return x.Key;
}
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)]
internal bool <Setup>b__0_3(ConsoleEventArgs args)
{
if (args.Length < 3)
{
return false;
}
if (!float.TryParse(args[2], out var result))
{
return false;
}
TimeMan.m_activeTimer += result;
TimekeeperPlugin.TimekeeperLogger.LogInfo((object)("Added " + result + " seconds to local player"));
return true;
}
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)]
internal bool <Setup>b__0_4(ConsoleEventArgs _)
{
if (!Object.op_Implicit((Object)(object)Player.m_localPlayer))
{
return false;
}
TimeMan.Clear(Player.m_localPlayer);
TimekeeperPlugin.TimekeeperLogger.LogInfo((object)"Cleared local player timekeeper data");
return true;
}
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)]
internal bool <Setup>b__0_5(ConsoleEventArgs _)
{
if (!Object.op_Implicit((Object)(object)EnvMan.instance))
{
return false;
}
TimeMan.m_activeTimer += EnvMan.instance.m_dayLengthSec;
TimekeeperPlugin.TimekeeperLogger.LogInfo((object)("Added " + EnvMan.instance.m_dayLengthSec + " seconds to local player"));
return true;
}
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)]
internal bool <Setup>b__0_6(ConsoleEventArgs args)
{
if (args.Length < 5)
{
return false;
}
if (!int.TryParse(args[2], out var result))
{
return false;
}
GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(args[3].Trim());
if (itemPrefab == null)
{
return false;
}
if (!int.TryParse(args[4], out var result2))
{
return false;
}
int num = 1;
int num2 = 0;
if (args.Length > 5)
{
num = (int.TryParse(args[5], out var result3) ? result3 : num);
}
if (args.Length > 6)
{
num2 = (int.TryParse(args[6], out var result4) ? result4 : num2);
}
TimeMan.Reward reward = new TimeMan.Reward(((Object)itemPrefab).name, result2, num, num2);
TimeMan.AddReward(result, reward);
TimeMan.UpdateRewardFile();
TimekeeperPlugin.TimekeeperLogger.LogInfo((object)"Updated rewards");
return true;
}
}
public static void Setup()
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Expected O, but got Unknown
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: Expected O, but got Unknown
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: Expected O, but got Unknown
string startCommand = CommandData.m_startCommand;
object obj = <>c.<>9__0_0;
if (obj == null)
{
ConsoleEventFailable val = delegate(ConsoleEventArgs args)
{
if (args.Length < 2)
{
return false;
}
CommandData value;
return (!CommandData.m_commands.TryGetValue(args[1], out value)) ? ((object)false) : ((object)value.Run(args));
};
<>c.<>9__0_0 = val;
obj = (object)val;
}
ConsoleCommand val2 = new ConsoleCommand(startCommand, "Use help to find commands", (ConsoleEventFailable)obj, false, false, false, false, false, new ConsoleOptionsFetcher(Enumerable.ToList), false, false, false);
new CommandData("add", "adds seconds to player counter", [<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)] (ConsoleEventArgs args) =>
{
if (args.Length < 3)
{
return false;
}
if (!float.TryParse(args[2], out var result5))
{
return false;
}
TimeMan.m_activeTimer += result5;
TimekeeperPlugin.TimekeeperLogger.LogInfo((object)("Added " + result5 + " seconds to local player"));
return true;
}, null, isSecret: false, adminOnly: true);
new CommandData("reset", "clears data from player save", [<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)] (ConsoleEventArgs _) =>
{
if (!Object.op_Implicit((Object)(object)Player.m_localPlayer))
{
return false;
}
TimeMan.Clear(Player.m_localPlayer);
TimekeeperPlugin.TimekeeperLogger.LogInfo((object)"Cleared local player timekeeper data");
return true;
});
new CommandData("add_day", "adds a full day (1800) to the player counter", [<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)] (ConsoleEventArgs _) =>
{
if (!Object.op_Implicit((Object)(object)EnvMan.instance))
{
return false;
}
TimeMan.m_activeTimer += EnvMan.instance.m_dayLengthSec;
TimekeeperPlugin.TimekeeperLogger.LogInfo((object)("Added " + EnvMan.instance.m_dayLengthSec + " seconds to local player"));
return true;
}, null, isSecret: false, adminOnly: true);
new CommandData("add_reward", "[day] [itemName] [Amount] [Quality] [Variant], add a new reward", [<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)] (ConsoleEventArgs args) =>
{
if (args.Length < 5)
{
return false;
}
if (!int.TryParse(args[2], out var result))
{
return false;
}
GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(args[3].Trim());
if (itemPrefab == null)
{
return false;
}
if (!int.TryParse(args[4], out var result2))
{
return false;
}
int num = 1;
int num2 = 0;
if (args.Length > 5)
{
num = (int.TryParse(args[5], out var result3) ? result3 : num);
}
if (args.Length > 6)
{
num2 = (int.TryParse(args[6], out var result4) ? result4 : num2);
}
TimeMan.Reward reward = new TimeMan.Reward(((Object)itemPrefab).name, result2, num, num2);
TimeMan.AddReward(result, reward);
TimeMan.UpdateRewardFile();
TimekeeperPlugin.TimekeeperLogger.LogInfo((object)"Updated rewards");
return true;
}, null, isSecret: false, adminOnly: true);
}
}
}
namespace Managers
{
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(0)]
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)]
public static class AssetManager
{
private static readonly Dictionary<string, AssetBundle> m_assetBundles = new Dictionary<string, AssetBundle>();
public static AssetBundle GetAssetBundle(string fileName)
{
if (m_assetBundles.TryGetValue(fileName, out var value))
{
return value;
}
Assembly executingAssembly = Assembly.GetExecutingAssembly();
string name = executingAssembly.GetManifestResourceNames().Single([<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(0)] (string str) => str.EndsWith(fileName));
using Stream stream = executingAssembly.GetManifestResourceStream(name);
value = AssetBundle.LoadFromStream(stream);
m_assetBundles[fileName] = value;
return value;
}
}
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(0)]
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(1)]
public static class FontManager
{
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(0)]
public enum FontOptions
{
Norse,
NorseBold,
AveriaSerifLibre,
AveriaSerifLibreBold,
AveriaSerifLibreLight,
LegacyRuntime
}
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(0)]
private class TextFont
{
private readonly Text m_text;
public TextFont(Text text, [<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(2)] Font font)
{
m_text = text;
Update(font);
m_allTexts.Add(this);
}
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(2)]
public void Update(Font font)
{
m_text.font = font;
}
}
[<0e657ea4-f9a5-4535-99f9-133b42a018b4>Nullable(new byte[] { 1, 2 })]
private static readonly Dictionary<FontOptions, Font> m_fonts = new Dictionary<FontOptions, Font>();
private static readonly List<TextFont> m_allTexts = new List<TextFont>();
private static string GetFontName(FontOptions option)
{
if (1 == 0)
{
}
string result = option switch
{
FontOptions.Norse => "Norse",
FontOptions.AveriaSerifLibre => "AveriaSerifLibre-Regular",
FontOptions.AveriaSerifLibreBold => "AveriaSerifLibre-Bold",
FontOptions.AveriaSerifLibreLight => "AveriaSerifLibre-Light",
FontOptions.NorseBold => "Norsebold",
FontOptions.LegacyRuntime => "LegacyRuntime",
_ => "AveriaSerifLibre-Regular",
};
if (1 == 0)
{
}
return result;
}
[<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(2)]
public static Font GetFont(FontOptions option)
{
if (m_fonts.TryGetValue(option, out var value))
{
return value;
}
Font[] source = Resources.FindObjectsOfTypeAll<Font>();
Font val = ((IEnumerable<Font>)source).FirstOrDefault((Func<Font, bool>)([<b11550e8-a346-4c7f-ace6-76ca3e1977f2>NullableContext(0)] (Font x) => ((Object)x).name == GetFontName(option)));
m_fonts[option] = val;
return val;
}
public static void OnFontChange(object sender, EventArgs args)
{
Font font = GetFont(FontOptions.AveriaSerifLibre);
foreach (TextFont allText in m_allTexts)
{
allText.Update(font);
}
}
public static void SetFont(Text[] array)
{
foreach (Text text in array)
{
TextFont textFont = new TextFont(text, GetFont(FontOptions.AveriaSerifLibre));
}
}
}
}
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
[Microsoft.CodeAnalysis.Embedded]
[CompilerGenerated]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
[Microsoft.CodeAnalysis.Embedded]
[CompilerGenerated]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace ServerSync
{
[PublicAPI]
internal abstract class OwnConfigEntryBase
{
public object? LocalBaseValue;
public bool SynchronizedConfig = true;
public abstract ConfigEntryBase BaseConfig { get; }
}
[PublicAPI]
internal class SyncedConfigEntry<T> : OwnConfigEntryBase
{
public readonly ConfigEntry<T> SourceConfig;
public override ConfigEntryBase BaseConfig => (ConfigEntryBase)(object)SourceConfig;
public T Value
{
get
{
return SourceConfig.Value;
}
set
{
SourceConfig.Value = value;
}
}
public SyncedConfigEntry(ConfigEntry<T> sourceConfig)
{
SourceConfig = sourceConfig;
base..ctor();
}
public void AssignLocalValue(T value)
{
if (LocalBaseValue == null)
{
Value = value;
}
else
{
LocalBaseValue = value;
}
}
}
internal abstract class CustomSyncedValueBase
{
public object? LocalBaseValue;
public readonly string Identifier;
public readonly Type Type;
private object? boxedValue;
protected bool localIsOwner;
public readonly int Priority;
public object? BoxedValue
{
get
{
return boxedValue;
}
set
{
boxedValue = value;
this.ValueChanged?.Invoke();
}
}
public event Action? ValueChanged;
protected CustomSyncedValueBase(ConfigSync configSync, string identifier, Type type, int priority)
{
Priority = priority;
Identifier = identifier;
Type = type;
configSync.AddCustomValue(this);
localIsOwner = configSync.IsSourceOfTruth;
configSync.SourceOfTruthChanged += delegate(bool truth)
{
localIsOwner = truth;
};
}
}
[PublicAPI]
internal sealed class CustomSyncedValue<T> : CustomSyncedValueBase
{
public T Value
{
get
{
return (T)base.BoxedValue;
}
set
{
base.BoxedValue = value;
}
}
public CustomSyncedValue(ConfigSync configSync, string identifier, T value = default(T), int priority = 0)
: base(configSync, identifier, typeof(T), priority)
{
Value = value;
}
public void AssignLocalValue(T value)
{
if (localIsOwner)
{
Value = value;
}
else
{
LocalBaseValue = value;
}
}
}
internal class ConfigurationManagerAttributes
{
[UsedImplicitly]
public bool? ReadOnly = false;
}
[PublicAPI]
internal class ConfigSync
{
[HarmonyPatch(typeof(ZRpc), "HandlePackage")]
private static class SnatchCurrentlyHandlingRPC
{
public static ZRpc? currentRpc;
[HarmonyPrefix]
private static void Prefix(ZRpc __instance)
{
currentRpc = __instance;
}
}
[HarmonyPatch(typeof(ZNet), "Awake")]
internal static class RegisterRPCPatch
{
[HarmonyPostfix]
private static void Postfix(ZNet __instance)
{
isServer = __instance.IsServer();
foreach (ConfigSync configSync2 in configSyncs)
{
ZRoutedRpc.instance.Register<ZPackage>(configSync2.Name + " ConfigSync", (Action<long, ZPackage>)configSync2.RPC_FromOtherClientConfigSync);
if (isServer)
{
configSync2.InitialSyncDone = true;
Debug.Log((object)("Registered '" + configSync2.Name + " ConfigSync' RPC - waiting for incoming connections"));
}
}
if (isServer)
{
((MonoBehaviour)__instance).StartCoroutine(WatchAdminListChanges());
}
static void SendAdmin(List<ZNetPeer> peers, bool isAdmin)
{
ZPackage package = ConfigsToPackage(null, null, new PackageEntry[1]
{
new PackageEntry
{
section = "Internal",
key = "lockexempt",
type = typeof(bool),
value = isAdmin
}
});
ConfigSync configSync = configSyncs.First();
if (configSync != null)
{
((MonoBehaviour)ZNet.instance).StartCoroutine(configSync.sendZPackage(peers, package));
}
}
static IEnumerator WatchAdminListChanges()
{
MethodInfo listContainsId = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null);
SyncedList adminList = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance);
List<string> CurrentList = new List<string>(adminList.GetList());
while (true)
{
yield return (object)new WaitForSeconds(30f);
if (!adminList.GetList().SequenceEqual(CurrentList))
{
CurrentList = new List<string>(adminList.GetList());
List<ZNetPeer> adminPeer = ZNet.instance.GetPeers().Where(delegate(ZNetPeer p)
{
string hostName = p.m_rpc.GetSocket().GetHostName();
return ((object)listContainsId == null) ? adminList.Contains(hostName) : ((bool)listContainsId.Invoke(ZNet.instance, new object[2] { adminList, hostName }));
}).ToList();
List<ZNetPeer> nonAdminPeer = ZNet.instance.GetPeers().Except(adminPeer).ToList();
SendAdmin(nonAdminPeer, isAdmin: false);
SendAdmin(adminPeer, isAdmin: true);
}
}
}
}
}
[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
private static class RegisterClientRPCPatch
{
[HarmonyPostfix]
private static void Postfix(ZNet __instance, ZNetPeer peer)
{
if (__instance.IsServer())
{
return;
}
foreach (ConfigSync configSync in configSyncs)
{
peer.m_rpc.Register<ZPackage>(configSync.Name + " ConfigSync", (Action<ZRpc, ZPackage>)configSync.RPC_FromServerConfigSync);
}
}
}
private class ParsedConfigs
{
public readonly Dictionary<OwnConfigEntryBase, object?> configValues = new Dictionary<OwnConfigEntryBase, object>();
public readonly Dictionary<CustomSyncedValueBase, object?> customValues = new Dictionary<CustomSyncedValueBase, object>();
}
[HarmonyPatch(typeof(ZNet), "Shutdown")]
private class ResetConfigsOnShutdown
{
[HarmonyPostfix]
private static void Postfix()
{
ProcessingServerUpdate = true;
foreach (ConfigSync configSync in configSyncs)
{
configSync.resetConfigsFromServer();
configSync.IsSourceOfTruth = true;
configSync.InitialSyncDone = false;
}
ProcessingServerUpdate = false;
}
}
[HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")]
private class SendConfigsAfterLogin
{
private class BufferingSocket : ZPlayFabSocket, ISocket
{
public volatile bool finished = false;
public volatile int versionMatchQueued = -1;
public readonly List<ZPackage> Package = new List<ZPackage>();
public readonly ISocket Original;
public BufferingSocket(ISocket original)
{
Original = original;
((ZPlayFabSocket)this)..ctor();
}
public bool IsConnected()
{
return Original.IsConnected();
}
public ZPackage Recv()
{
return Original.Recv();
}
public int GetSendQueueSize()
{
return Original.GetSendQueueSize();
}
public int GetCurrentSendRate()
{
return Original.GetCurrentSendRate();
}
public bool IsHost()
{
return Original.IsHost();
}
public void Dispose()
{
Original.Dispose();
}
public bool GotNewData()
{
return Original.GotNewData();
}
public void Close()
{
Original.Close();
}
public string GetEndPointString()
{
return Original.GetEndPointString();
}
public void GetAndResetStats(out int totalSent, out int totalRecv)
{
Original.GetAndResetStats(ref totalSent, ref totalRecv);
}
public void GetConnectionQuality(out float localQuality, out float remoteQuality, out int ping, out float outByteSec, out float inByteSec)
{
Original.GetConnectionQuality(ref localQuality, ref remoteQuality, ref ping, ref outByteSec, ref inByteSec);
}
public ISocket Accept()
{
return Original.Accept();
}
public int GetHostPort()
{
return Original.GetHostPort();
}
public bool Flush()
{
return Original.Flush();
}
public string GetHostName()
{
return Original.GetHostName();
}
public void VersionMatch()
{
if (finished)
{
Original.VersionMatch();
}
else
{
versionMatchQueued = Package.Count;
}
}
public void Send(ZPackage pkg)
{
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Expected O, but got Unknown
int pos = pkg.GetPos();
pkg.SetPos(0);
int num = pkg.ReadInt();
if ((num == StringExtensionMethods.GetStableHashCode("PeerInfo") || num == StringExtensionMethods.GetStableHashCode("RoutedRPC") || num == StringExtensionMethods.GetStableHashCode("ZDOData")) && !finished)
{
ZPackage val = new ZPackage(pkg.GetArray());
val.SetPos(pos);
Package.Add(val);
}
else
{
pkg.SetPos(pos);
Original.Send(pkg);
}
}
}
[HarmonyPriority(800)]
[HarmonyPrefix]
private static void Prefix(ref Dictionary<Assembly, BufferingSocket>? __state, ZNet __instance, ZRpc rpc)
{
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Invalid comparison between Unknown and I4
if (!__instance.IsServer())
{
return;
}
BufferingSocket bufferingSocket = new BufferingSocket(rpc.GetSocket());
AccessTools.DeclaredField(typeof(ZRpc), "m_socket").SetValue(rpc, bufferingSocket);
object? obj = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance, new object[1] { rpc });
ZNetPeer val = (ZNetPeer)((obj is ZNetPeer) ? obj : null);
if (val != null && (int)ZNet.m_onlineBackend > 0)
{
FieldInfo fieldInfo = AccessTools.DeclaredField(typeof(ZNetPeer), "m_socket");
object? value = fieldInfo.GetValue(val);
ZPlayFabSocket val2 = (ZPlayFabSocket)((value is ZPlayFabSocket) ? value : null);
if (val2 != null)
{
typeof(ZPlayFabSocket).GetField("m_remotePlayerId").SetValue(bufferingSocket, val2.m_remotePlayerId);
}
fieldInfo.SetValue(val, bufferingSocket);
}
if (__state == null)
{
__state = new Dictionary<Assembly, BufferingSocket>();
}
__state[Assembly.GetExecutingAssembly()] = bufferingSocket;
}
[HarmonyPostfix]
private static void Postfix(Dictionary<Assembly, BufferingSocket> __state, ZNet __instance, ZRpc rpc)
{
ZRpc rpc2 = rpc;
ZNet __instance2 = __instance;
Dictionary<Assembly, BufferingSocket> __state2 = __state;
ZNetPeer peer;
if (__instance2.IsServer())
{
object obj = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance2, new object[1] { rpc2 });
peer = (ZNetPeer)((obj is ZNetPeer) ? obj : null);
if (peer == null)
{
SendBufferedData();
}
else
{
((MonoBehaviour)__instance2).StartCoroutine(sendAsync());
}
}
void SendBufferedData()
{
if (rpc2.GetSocket() is BufferingSocket bufferingSocket)
{
AccessTools.DeclaredField(typeof(ZRpc), "m_socket").SetValue(rpc2, bufferingSocket.Original);
object? obj2 = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance2, new object[1] { rpc2 });
ZNetPeer val = (ZNetPeer)((obj2 is ZNetPeer) ? obj2 : null);
if (val != null)
{
AccessTools.DeclaredField(typeof(ZNetPeer), "m_socket").SetValue(val, bufferingSocket.Original);
}
}
BufferingSocket bufferingSocket2 = __state2[Assembly.GetExecutingAssembly()];
bufferingSocket2.finished = true;
for (int i = 0; i < bufferingSocket2.Package.Count; i++)
{
if (i == bufferingSocket2.versionMatchQueued)
{
bufferingSocket2.Original.VersionMatch();
}
bufferingSocket2.Original.Send(bufferingSocket2.Package[i]);
}
if (bufferingSocket2.Package.Count == bufferingSocket2.versionMatchQueued)
{
bufferingSocket2.Original.VersionMatch();
}
}
IEnumerator sendAsync()
{
foreach (ConfigSync configSync in configSyncs)
{
List<PackageEntry> entries = new List<PackageEntry>();
if (configSync.CurrentVersion != null)
{
entries.Add(new PackageEntry
{
section = "Internal",
key = "serverversion",
type = typeof(string),
value = configSync.CurrentVersion
});
}
MethodInfo listContainsId = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null);
SyncedList adminList = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance);
entries.Add(new PackageEntry
{
section = "Internal",
key = "lockexempt",
type = typeof(bool),
value = (((object)listContainsId == null) ? ((object)adminList.Contains(rpc2.GetSocket().GetHostName())) : listContainsId.Invoke(ZNet.instance, new object[2]