Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of AdminMenu v0.9.6
plugins/AdminMenu.dll
Decompiled 5 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; 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.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using SoftReferenceableAssets; using Splatform; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyVersion("0.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace AdminMenu { internal static class AdminRights { internal static readonly HashSet<string> OwnCharacterCommands = new HashSet<string> { "confirmcheats", "fly", "nocost", "debugmode", "raiseskill", "resetskill", "resetcharacter", "exploremap", "resetmap", "goto", "spawn", "wind", "resetwind", "forcedelete", "env", "resetenv", "addstatus", "stopfire" }; private static readonly FieldRef<ZNet, SyncedList> AdminList = AccessTools.FieldRefAccess<ZNet, SyncedList>("m_adminList"); private static readonly Action<ZNet> SendAdminList = AccessTools.MethodDelegate<Action<ZNet>>(AccessTools.Method(typeof(ZNet), "SendAdminList", (Type[])null, (Type[])null), (object)null, true); private static readonly List<string> entries = new List<string>(); private static int entriesFrame = -1; private static int adminFrame = -1; private static bool clientAdmin; private static int unlockedFrame = -1; private static bool unlocked; internal static bool CanEdit { get { if (Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.instance.IsServer()) { return AdminList.Invoke(ZNet.instance) != null; } return false; } } internal static bool IsClientAdmin { get { if (Time.frameCount == adminFrame) { return clientAdmin; } adminFrame = Time.frameCount; clientAdmin = Object.op_Implicit((Object)(object)ZNet.instance) && !ZNet.instance.IsServer() && Contains(ZNet.instance.GetAdminList(), ((object)Unsafe.As<PlatformUserID, PlatformUserID>(ref UserInfo.GetLocalUser().UserId)/*cast due to .constrained prefix*/).ToString()); return clientAdmin; } } internal static List<string> Entries { get { if (Time.frameCount == entriesFrame) { return entries; } entriesFrame = Time.frameCount; entries.Clear(); if (CanEdit) { entries.AddRange(AdminList.Invoke(ZNet.instance).GetList()); } return entries; } } internal static bool MayUsePanel { get { if (Unlocked) { if (Object.op_Implicit((Object)(object)ZNet.instance) && !ZNet.instance.IsServer()) { return IsClientAdmin; } return true; } return false; } } internal static bool Unlocked { get { if (Time.frameCount == unlockedFrame) { return unlocked; } unlockedFrame = Time.frameCount; return unlocked = ReadUnlocked(); } } private static bool ReadUnlocked() { if (!Plugin.PanelLocked.Value) { return true; } string value = Plugin.UnlockedFor.Value; if (string.IsNullOrEmpty(value)) { return false; } string text = LocalId(); object obj; if (!Object.op_Implicit((Object)(object)Game.instance)) { obj = null; } else { PlayerProfile playerProfile = Game.instance.GetPlayerProfile(); obj = ((playerProfile != null) ? playerProfile.GetName() : null); } string text2 = (string)obj; string[] array = value.Split(new char[2] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < array.Length; i++) { string text3 = array[i].Trim(); if ((text != null && Plain(text3) == Plain(text)) || (text2 != null && string.Equals(text3, text2, StringComparison.OrdinalIgnoreCase))) { return true; } } return false; } internal static string LocalId() { try { return ((object)Unsafe.As<PlatformUserID, PlatformUserID>(ref UserInfo.GetLocalUser().UserId)/*cast due to .constrained prefix*/).ToString(); } catch (Exception) { return null; } } internal static void LockPanel(bool keepMine) { string text = LocalId(); if (keepMine && !string.IsNullOrEmpty(text)) { string value = Plugin.UnlockedFor.Value; bool flag = false; string[] array = value.Split(new char[2] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < array.Length; i++) { if (Plain(array[i].Trim()) == Plain(text)) { flag = true; } } if (!flag) { Plugin.UnlockedFor.Value = ((value.Trim().Length == 0) ? text : (value.Trim() + "," + text)); } } Plugin.PanelLocked.Value = true; Plugin.Log("panel locked by its own button" + (keepMine ? (", still open for " + text) : "")); } internal static bool IsHost(string user) { if (!Object.op_Implicit((Object)(object)ZNet.instance) || !ZNet.instance.IsServer() || !Object.op_Implicit((Object)(object)Player.m_localPlayer) || string.IsNullOrEmpty(user)) { return false; } user = user.Trim(); if (string.Equals(user, Game.instance.GetPlayerProfile().GetName(), StringComparison.OrdinalIgnoreCase)) { return true; } return Plain(user) == Plain(((object)Unsafe.As<PlatformUserID, PlatformUserID>(ref UserInfo.GetLocalUser().UserId)/*cast due to .constrained prefix*/).ToString()); } internal static bool Has(string id) { return Contains(CanEdit ? Entries : (Object.op_Implicit((Object)(object)ZNet.instance) ? ZNet.instance.GetAdminList() : entries), id); } internal static void Set(string id, bool admin) { if (!CanEdit || string.IsNullOrEmpty(id)) { return; } SyncedList val = AdminList.Invoke(ZNet.instance); if (admin && !Contains(val.GetList(), id)) { val.Add(id); } if (!admin) { foreach (string item in new List<string>(val.GetList())) { if (Plain(item) == Plain(id)) { val.Remove(item); } } } entriesFrame = -1; SendAdminList(ZNet.instance); } private static bool Contains(List<string> list, string id) { string text = Plain(id); foreach (string item in list) { if (Plain(item) == text) { return true; } } return false; } internal static string Plain(string id) { id = (id ?? "").Trim(); if (!id.StartsWith("Steam_", StringComparison.OrdinalIgnoreCase)) { return id; } return id.Substring(6); } } internal static class Bookmarks { internal sealed class Mark { internal string World; internal string Name; internal Vector3 Place; } private static readonly string FilePath = Path.Combine(Paths.ConfigPath, "AdminMenu.bookmarks.txt"); private static List<Mark> all; private static List<Mark> All { get { if (all == null) { Load(); } return all; } } internal static string World { get { if (!Object.op_Implicit((Object)(object)ZNet.instance)) { return ""; } return ZNet.instance.GetWorldName(); } } internal static List<Mark> Here() { List<Mark> list = new List<Mark>(); string world = World; foreach (Mark item in All) { if (item.World == world) { list.Add(item); } } return list; } internal static void Add(string name, Vector3 place) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) All.Add(new Mark { World = World, Name = Clean(name), Place = place }); Save(); } internal static void Remove(Mark mark) { All.Remove(mark); Save(); } private static string Clean(string name) { name = (name ?? "").Replace('\t', ' ').Replace('\n', ' ').Replace('\r', ' ') .Trim(); if (name.Length <= 0) { return L.T("bookmarks.default_name"); } return name; } private static void Load() { //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) all = new List<Mark>(); try { if (!File.Exists(FilePath)) { return; } string[] array = File.ReadAllLines(FilePath); for (int i = 0; i < array.Length; i++) { string[] array2 = array[i].Split('\t'); if (array2.Length >= 5 && float.TryParse(array2[2], NumberStyles.Float, CultureInfo.InvariantCulture, out var result) && float.TryParse(array2[3], NumberStyles.Float, CultureInfo.InvariantCulture, out var result2) && float.TryParse(array2[4], NumberStyles.Float, CultureInfo.InvariantCulture, out var result3)) { all.Add(new Mark { World = array2[0], Name = array2[1], Place = new Vector3(result, result2, result3) }); } } } catch (Exception ex) { Plugin.Error("bookmarks not read: " + ex.Message); } } private static void Save() { try { List<string> list = new List<string>(); foreach (Mark item in all) { list.Add(string.Join("\t", item.World, item.Name, F(item.Place.x), F(item.Place.y), F(item.Place.z))); } File.WriteAllLines(FilePath, list); } catch (Exception ex) { Plugin.Error("bookmarks not saved: " + ex.Message); } } private static string F(float value) { return value.ToString("0.##", CultureInfo.InvariantCulture); } } internal sealed class CharacterAppearance { internal string Beard; internal string Hair; internal Vector3 Skin = Vector3.one; internal Vector3 HairColor = Vector3.one; internal int Model; internal void Apply(Player player) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) player.SetPlayerModel(Model); ((Humanoid)player).SetBeard(Beard); ((Humanoid)player).SetHair(Hair); player.SetSkinColor(Skin); player.SetHairColor(HairColor); } internal static void Write(ZPackage p, CharacterAppearance appearance) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) p.Write(appearance != null); if (appearance != null) { p.Write(appearance.Beard); p.Write(appearance.Hair); p.Write(appearance.Skin); p.Write(appearance.HairColor); p.Write(appearance.Model); } } internal static CharacterAppearance Read(ZPackage p) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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_003a: Unknown result type (might be due to invalid IL or missing references) if (!p.ReadBool()) { return null; } CharacterAppearance characterAppearance = new CharacterAppearance(); characterAppearance.Beard = p.ReadString(); characterAppearance.Hair = p.ReadString(); characterAppearance.Skin = p.ReadVector3(); characterAppearance.HairColor = p.ReadVector3(); characterAppearance.Model = p.ReadInt(); characterAppearance.Validate(); return characterAppearance; } private void Validate() { if (Beard == null || Hair == null || Beard.Length > 256 || Hair.Length > 256 || Model < 0 || Model > 255) { throw new InvalidDataException("Invalid character appearance"); } float[] array = new float[6] { Skin.x, Skin.y, Skin.z, HairColor.x, HairColor.y, HairColor.z }; foreach (float num in array) { if (float.IsNaN(num) || float.IsInfinity(num) || Mathf.Abs(num) > 16f) { throw new InvalidDataException("Invalid character color"); } } } internal static CharacterAppearance FromPlayerData(byte[] data) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Invalid comparison between Unknown and I4 //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Invalid comparison between Unknown and I4 //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Invalid comparison between Unknown and I4 //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Invalid comparison between Unknown and I4 //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Invalid comparison between Unknown and I4 //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Invalid comparison between Unknown and I4 //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Invalid comparison between Unknown and I4 //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Invalid comparison between Unknown and I4 //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Invalid comparison between Unknown and I4 //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Invalid comparison between Unknown and I4 //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Invalid comparison between Unknown and I4 //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Invalid comparison between Unknown and I4 //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Invalid comparison between Unknown and I4 //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Invalid comparison between Unknown and I4 //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Invalid comparison between Unknown and I4 //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Invalid comparison between Unknown and I4 //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Invalid comparison between Unknown and I4 //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Invalid comparison between Unknown and I4 //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Invalid comparison between Unknown and I4 //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Invalid comparison between Unknown and I4 //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Invalid comparison between Unknown and I4 if (data == null) { return null; } if (data.Length < 4 || data.Length > 16777216) { throw new InvalidDataException("Invalid player data"); } ZPackage val = new ZPackage(data); PlayerData val2 = (PlayerData)val.ReadInt(); if ((int)val2 < 2 || (int)val2 > 34) { throw new InvalidDataException("Unsupported player appearance version"); } if ((int)val2 < 4) { return null; } if ((int)val2 >= 7) { val.ReadSingle(); } val.ReadSingle(); if ((int)val2 >= 10) { val.ReadSingle(); } if ((int)val2 >= 8 && (int)val2 < 28) { val.ReadBool(); } if ((int)val2 >= 20) { val.ReadSingle(); } if ((int)val2 >= 23) { val.ReadString(); } if ((int)val2 >= 24) { val.ReadSingle(); } SkipInventory(val); SkipStrings(val); int num = Count(val); for (int i = 0; i < num; i++) { val.ReadString(); if ((int)val2 >= 15) { val.ReadInt(); } } SkipStrings(val); if ((int)val2 < 19 || (int)val2 >= 21) { SkipStrings(val); } if ((int)val2 >= 6) { SkipStrings(val); } if ((int)val2 >= 9) { SkipStrings(val); } if ((int)val2 >= 18) { num = Count(val); for (int j = 0; j < num; j++) { if ((int)val2 >= 33 || (int)val2 == 31) { val.ReadString(); } else { val.ReadInt(); } } } if ((int)val2 >= 22) { num = Count(val); for (int k = 0; k < num; k++) { val.ReadString(); val.ReadString(); } } CharacterAppearance characterAppearance = new CharacterAppearance { Beard = val.ReadString(), Hair = val.ReadString() }; if ((int)val2 >= 5) { characterAppearance.Skin = val.ReadVector3(); characterAppearance.HairColor = val.ReadVector3(); } if ((int)val2 >= 11) { characterAppearance.Model = val.ReadInt(); } characterAppearance.Validate(); return characterAppearance; } private static int Count(ZPackage p) { int num = p.ReadInt(); if (num < 0 || num > 100000 || num > p.Size() - p.GetPos()) { throw new InvalidDataException("Invalid appearance collection"); } return num; } private static void SkipStrings(ZPackage p) { int num = Count(p); for (int i = 0; i < num; i++) { p.ReadString(); } } private static void SkipInventory(ZPackage p) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Invalid comparison between Unknown and I4 //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Invalid comparison between Unknown and I4 //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Invalid comparison between Unknown and I4 //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Invalid comparison between Unknown and I4 //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Invalid comparison between Unknown and I4 //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Invalid comparison between Unknown and I4 //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Invalid comparison between Unknown and I4 //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Invalid comparison between Unknown and I4 Item val = (Item)p.ReadInt(); if ((int)val > 110) { throw new InvalidDataException("Unsupported inventory version"); } if ((int)val >= 108) { int num = p.ReadUShort(); if (num > p.Size() - p.GetPos()) { throw new InvalidDataException("Invalid inventory count"); } for (int i = 0; i < num; i++) { ItemData.Load(p, val); } return; } int num2 = Count(p); for (int j = 0; j < num2; j++) { p.ReadString(); p.ReadInt(); p.ReadSingle(); p.ReadVector2i(); p.ReadBool(); if ((int)val >= 101) { p.ReadInt(); } if ((int)val >= 102) { p.ReadInt(); } if ((int)val >= 103) { p.ReadLong(); p.ReadString(); } if ((int)val >= 104) { int num3 = Count(p); for (int k = 0; k < num3; k++) { p.ReadString(); p.ReadString(); } } if ((int)val >= 105) { p.ReadInt(); } if ((int)val >= 106) { p.ReadBool(); } if ((int)val == 107 || (int)val >= 109) { p.ReadBool(); } } } } internal static class CharacterManualSavePolicy { internal static bool ShouldPush(int cooldownBefore, int cooldownAfter, long requestedBefore, long requestedAfter) { if (cooldownAfter > cooldownBefore) { return requestedBefore == requestedAfter; } return false; } } internal sealed class CharacterMapCodec { private int[] own; private int[] others; private int[] previousOwn; private int[] previousOthers; private byte[] raw; private byte[] previousTail; private byte[] cached; private int length; private int texture; private int previousTexture; private byte[] tail; internal void Capture(int size, BitArray explored, BitArray shared, byte[] pins) { if (explored == null || shared == null || explored.Length != shared.Length || explored.Length != checked(size * size)) { throw new InvalidDataException("Invalid map dimensions"); } int num = (explored.Length + 31) / 32; if (own == null || own.Length != num) { own = new int[num]; others = new int[num]; cached = null; } explored.CopyTo(own, 0); shared.CopyTo(others, 0); length = explored.Length; texture = size; tail = pins; } private static bool Equal(int[] a, int[] b) { if (b == null || a.Length != b.Length) { return false; } for (int i = 0; i < a.Length; i++) { if (a[i] != b[i]) { return false; } } return true; } private static bool Equal(byte[] a, byte[] b) { if (b == null || a.Length != b.Length) { return false; } for (int i = 0; i < a.Length; i++) { if (a[i] != b[i]) { return false; } } return true; } internal byte[] Encode() { if (cached != null && texture == previousTexture && Equal(own, previousOwn) && Equal(others, previousOthers) && Equal(tail, previousTail)) { return cached; } int num = checked(4 + length * 2 + tail.Length); if (num > 16777216) { throw new InvalidDataException("Map is too large"); } if (raw == null || raw.Length != num) { raw = new byte[num]; } Buffer.BlockCopy(BitConverter.GetBytes(texture), 0, raw, 0, 4); Expand(own, raw, 4, length); Expand(others, raw, 4 + length, length); Buffer.BlockCopy(tail, 0, raw, 4 + length * 2, tail.Length); using (MemoryStream memoryStream = new MemoryStream()) { using (GZipStream gZipStream = new GZipStream(memoryStream, CompressionLevel.Fastest, leaveOpen: true)) { gZipStream.Write(raw, 0, num); } byte[] array = memoryStream.ToArray(); using MemoryStream memoryStream2 = new MemoryStream(8 + array.Length); using BinaryWriter binaryWriter = new BinaryWriter(memoryStream2); binaryWriter.Write(8); binaryWriter.Write(array.Length); binaryWriter.Write(array); cached = memoryStream2.ToArray(); } if (previousOwn == null || previousOwn.Length != own.Length) { previousOwn = new int[own.Length]; previousOthers = new int[others.Length]; } Array.Copy(own, previousOwn, own.Length); Array.Copy(others, previousOthers, others.Length); previousTail = tail; previousTexture = texture; return cached; } private static void Expand(int[] bits, byte[] target, int offset, int count) { for (int i = 0; i < count; i++) { target[offset + i] = (byte)((bits[i >> 5] >>> i) & 1); } } } internal sealed class CharacterPayload { private readonly byte[] bytes; private readonly int mapOffset; internal CharacterPayload(byte[] captured, int offset) { bytes = captured; mapOffset = offset; } internal byte[] WithMap(byte[] map) { if (map == null) { return bytes; } int num = checked(bytes.Length + 4 + map.Length); if (num > 16777216) { throw new InvalidDataException("Character is too large"); } using MemoryStream memoryStream = new MemoryStream(num); using BinaryWriter binaryWriter = new BinaryWriter(memoryStream); binaryWriter.Write(bytes, 0, mapOffset); binaryWriter.Write(value: true); binaryWriter.Write(map.Length); binaryWriter.Write(map); binaryWriter.Write(bytes, mapOffset + 1, bytes.Length - mapOffset - 1); return memoryStream.ToArray(); } } internal static class CharacterSnapshot { private const int Format = 2; private static readonly ConditionalWeakTable<PlayerProfile, CharacterAppearance> pendingAppearance = new ConditionalWeakTable<PlayerProfile, CharacterAppearance>(); private static readonly FieldInfo PlayerData = typeof(PlayerProfile).GetField("m_playerData", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo PlayerId = typeof(PlayerProfile).GetField("m_playerID", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo Seed = typeof(PlayerProfile).GetField("m_startSeed", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly MethodInfo WorldData = typeof(PlayerProfile).GetMethod("GetWorldData", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly Type WorldDataType = typeof(PlayerProfile).GetNestedType("WorldPlayerData", BindingFlags.NonPublic); private static readonly string[] WorldFields = new string[8] { "m_haveCustomSpawnPoint", "m_spawnPoint", "m_haveLogoutPoint", "m_logoutPoint", "m_haveDeathPoint", "m_deathPoint", "m_homePoint", "m_mapData" }; internal static CharacterAppearance Appearance(PlayerProfile profile) { if (!pendingAppearance.TryGetValue(profile, out var value)) { return CharacterAppearance.FromPlayerData((byte[])PlayerData.GetValue(profile)); } return value; } internal static bool HasPendingAppearance(PlayerProfile profile) { CharacterAppearance value; return pendingAppearance.TryGetValue(profile, out value); } internal static PlayerProfile Fresh(PlayerProfile original) { return Fresh(original, Appearance(original)); } internal static PlayerProfile Fresh(PlayerProfile original, CharacterAppearance appearance) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown PlayerProfile val = new PlayerProfile(original.GetFilename(), original.m_fileSource); val.SetName(original.GetName()); PlayerId.SetValue(val, original.GetPlayerID()); if (appearance != null) { pendingAppearance.Add(val, appearance); } return val; } internal static void ApplyAppearance(PlayerProfile profile, Player player) { if (pendingAppearance.TryGetValue(profile, out var value)) { value.Apply(player); profile.SavePlayerData(player); pendingAppearance.Remove(profile); if (!string.IsNullOrEmpty(profile.GetFilename()) && !profile.Save()) { throw new IOException("Could not save the character cache with preserved appearance"); } } } internal static byte[] Encode(PlayerProfile profile, long world) { int mapOffset; return Encode(profile, world, omitMap: false, out mapOffset); } internal static CharacterPayload Capture(PlayerProfile profile, long world) { int mapOffset; return new CharacterPayload(Encode(profile, world, omitMap: true, out mapOffset), mapOffset); } private static byte[] Encode(PlayerProfile profile, long world, bool omitMap, out int mapOffset) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Expected O, but got Unknown //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Expected I4, but got Unknown mapOffset = -1; ZPackage val = new ZPackage(); val.Write(2); val.Write(47); val.Write(world); val.Write(profile.GetName()); val.Write(profile.GetPlayerID()); val.Write(profile.m_firstSpawn); val.Write(profile.m_usedCheats); val.Write(profile.m_dateCreated.ToBinary()); val.Write(((string)Seed.GetValue(profile)) ?? ""); byte[] array = (byte[])PlayerData.GetValue(profile); val.Write(array != null); if (array != null) { val.Write(array); } object obj = WorldData.Invoke(profile, new object[1] { world }); string[] worldFields = WorldFields; foreach (string text in worldFields) { object value = WorldDataType.GetField(text).GetValue(obj); if (text == "m_mapData") { mapOffset = val.Size(); val.Write(!omitMap && value != null); if (!omitMap && value != null) { val.Write((byte[])value); } } else if (value is bool flag) { val.Write(flag); } else { val.Write((Vector3)value); } } val.Write(profile.m_playerStats.Length); PlayerStats[] playerStats = profile.m_playerStats; foreach (PlayerStats val2 in playerStats) { val.Write(val2.m_stats.Count); foreach (KeyValuePair<PlayerStatType, float> stat in val2.m_stats) { val.Write((int)stat.Key); val.Write(stat.Value); } WriteTable(val, val2.m_knownWorlds); WriteTable(val, val2.m_knownWorldKeys); WriteTable(val, val2.m_knownCommands); val.Write(val2.m_enemyStats.Length); Dictionary<string, float>[] enemyStats = val2.m_enemyStats; foreach (Dictionary<string, float> table in enemyStats) { WriteTable(val, table); } WriteTable(val, val2.m_itemPickupStats); WriteTable(val, val2.m_itemCraftStats); WriteTable(val, val2.m_pickableStats); WriteTable(val, val2.m_foodEatenStats); WriteTable(val, val2.m_piecesPlacedStats); } CharacterAppearance.Write(val, pendingAppearance.TryGetValue(profile, out var value2) ? value2 : null); byte[] array2 = val.GetArray(); if (array2.Length > 16777216) { throw new InvalidDataException("Character is too large"); } return array2; } internal static PlayerProfile Decode(byte[] bytes, string filename, FileSource source, long world) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_006a: 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_0071: Expected O, but got Unknown //IL_0149: Unknown result type (might be due to invalid IL or missing references) if (bytes == null || bytes.Length == 0 || bytes.Length > 16777216) { throw new InvalidDataException("Invalid character length"); } ZPackage val = new ZPackage(bytes); int num = val.ReadInt(); if (num != 1 && num != 2) { throw new InvalidDataException("Unknown snapshot format"); } if (!Version.IsPlayerVersionCompatible((Player)val.ReadInt())) { throw new InvalidDataException("Incompatible Valheim character version"); } if (val.ReadLong() != world) { throw new InvalidDataException("Character belongs to another world"); } PlayerProfile val2 = new PlayerProfile(filename, source); val2.SetName(val.ReadString()); PlayerId.SetValue(val2, val.ReadLong()); val2.m_firstSpawn = val.ReadBool(); val2.m_usedCheats = val.ReadBool(); val2.m_dateCreated = DateTime.FromBinary(val.ReadLong()); Seed.SetValue(val2, val.ReadString()); if (val.ReadBool()) { PlayerData.SetValue(val2, ReadBlob(val)); } object obj = WorldData.Invoke(val2, new object[1] { world }); string[] worldFields = WorldFields; foreach (string text in worldFields) { FieldInfo field = WorldDataType.GetField(text); object value = ((text == "m_mapData") ? (val.ReadBool() ? ReadBlob(val) : null) : ((field.FieldType == typeof(bool)) ? ((object)val.ReadBool()) : ((object)val.ReadVector3()))); field.SetValue(obj, value); } if (val.ReadInt() != val2.m_playerStats.Length) { throw new InvalidDataException("Invalid statistics count"); } PlayerStats[] playerStats = val2.m_playerStats; foreach (PlayerStats val3 in playerStats) { int num2 = Count(val); for (int j = 0; j < num2; j++) { val3.m_stats[(PlayerStatType)val.ReadInt()] = val.ReadSingle(); } ReadTable(val, val3.m_knownWorlds); ReadTable(val, val3.m_knownWorldKeys); ReadTable(val, val3.m_knownCommands); if (val.ReadInt() != val3.m_enemyStats.Length) { throw new InvalidDataException("Invalid enemy statistics count"); } Dictionary<string, float>[] enemyStats = val3.m_enemyStats; foreach (Dictionary<string, float> table in enemyStats) { ReadTable(val, table); } ReadTable(val, val3.m_itemPickupStats); ReadTable(val, val3.m_itemCraftStats); ReadTable(val, val3.m_pickableStats); ReadTable(val, val3.m_foodEatenStats); ReadTable(val, val3.m_piecesPlacedStats); } if (num >= 2) { CharacterAppearance characterAppearance = CharacterAppearance.Read(val); if (characterAppearance != null) { pendingAppearance.Add(val2, characterAppearance); } } if (val.GetPos() != val.Size()) { throw new InvalidDataException("Unexpected snapshot data"); } return val2; } private static int Count(ZPackage p) { int num = p.ReadInt(); if (num < 0 || num > 100000 || num > p.Size() - p.GetPos()) { throw new InvalidDataException("Invalid collection size"); } return num; } internal static byte[] ReadBlob(ZPackage p) { int pos = p.GetPos(); int num = p.ReadInt(); if (num < 0 || num > 16777216 || num > p.Size() - p.GetPos()) { throw new InvalidDataException("Invalid byte array length"); } p.SetPos(pos); return p.ReadByteArray(); } private static void WriteTable(ZPackage p, Dictionary<string, float> table) { p.Write(table.Count); foreach (KeyValuePair<string, float> item in table) { p.Write(item.Key); p.Write(item.Value); } } private static void ReadTable(ZPackage p, Dictionary<string, float> table) { table.Clear(); int num = Count(p); for (int i = 0; i < num; i++) { table.Add(p.ReadString(), p.ReadSingle()); } } } internal static class CharacterStorage { internal const int MaxBytes = 16777216; private const int Magic = 1095582513; private static readonly object[] gates = MakeGates(); private static object[] MakeGates() { object[] array = new object[32]; for (int i = 0; i < array.Length; i++) { array[i] = new object(); } return array; } private static object Gate(string path) { return gates[(StringComparer.OrdinalIgnoreCase.GetHashCode(Path.GetFullPath(path)) & 0x7FFFFFFF) % gates.Length]; } internal static string Hash(string text) { using SHA256 sHA = SHA256.Create(); return BitConverter.ToString(sHA.ComputeHash(Encoding.UTF8.GetBytes(text))).Replace("-", "").ToLowerInvariant(); } internal static byte[] Read(string path) { lock (Gate(path)) { return ReadCore(path); } } private static byte[] ReadCore(string path) { using FileStream fileStream = File.OpenRead(path); using BinaryReader binaryReader = new BinaryReader(fileStream); if (fileStream.Length < 40) { throw new InvalidDataException("Truncated character file"); } if (binaryReader.ReadInt32() != 1095582513) { throw new InvalidDataException("Unknown character file format"); } int num = binaryReader.ReadInt32(); if (num <= 0 || num > 16777216 || fileStream.Length != (long)num + 40L) { throw new InvalidDataException("Invalid character file length"); } byte[] array = binaryReader.ReadBytes(32); byte[] array2 = binaryReader.ReadBytes(num); using (SHA256 sHA = SHA256.Create()) { if (BitConverter.ToString(array) != BitConverter.ToString(sHA.ComputeHash(array2))) { throw new InvalidDataException("Character file checksum mismatch"); } } return array2; } internal static void Write(string path, byte[] data) { lock (Gate(path)) { WriteCore(path, data); } } private static void WriteCore(string path, byte[] data) { if (data == null || data.Length == 0 || data.Length > 16777216) { throw new InvalidDataException("Character is too large"); } Directory.CreateDirectory(Path.GetDirectoryName(path)); string text = path + ".new"; using (FileStream fileStream = new FileStream(text, FileMode.Create, FileAccess.Write, FileShare.None)) { using BinaryWriter binaryWriter = new BinaryWriter(fileStream); using SHA256 sHA = SHA256.Create(); binaryWriter.Write(1095582513); binaryWriter.Write(data.Length); binaryWriter.Write(sHA.ComputeHash(data)); binaryWriter.Write(data); binaryWriter.Flush(); fileStream.Flush(flushToDisk: true); } if (File.Exists(path)) { File.Replace(text, path, path + ".old", ignoreMetadataErrors: true); } else { File.Move(text, path); } } } internal static class CharacterWorkQueue { private static Task tail = Task.FromResult(0); internal static bool IsIdle => tail.IsCompleted; internal static Task<T> Run<T>(Func<T> action) { return (Task<T>)(tail = tail.ContinueWith(delegate(Task previous) { if (previous.IsFaulted) { _ = previous.Exception; } return action(); }, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Default)); } } internal static class Commands { private const int LogLimit = 80; internal static readonly List<string> Log = new List<string>(); internal static int LogVersion; private static readonly List<string> queue = new List<string>(); private static Dictionary<string, ConsoleCommand> table; private static Dictionary<string, ConsoleCommand> Table => table ?? (table = (Dictionary<string, ConsoleCommand>)AccessTools.Field(typeof(Terminal), "commands").GetValue(null)); internal static string Blocker(string name) { Console instance = Console.instance; if (!Object.op_Implicit((Object)(object)instance) || !Table.TryGetValue(name, out var value)) { return L.F("block.no_command", name); } if (value.IsCheat && !Terminal.m_cheat) { return L.T("block.cheats_off"); } if (value.RemoteCommand && Object.op_Implicit((Object)(object)ZNet.instance) && !ZNet.instance.IsServer()) { return null; } if (!value.IsValid((Terminal)(object)instance, false)) { if (value.IsCheat && Object.op_Implicit((Object)(object)ZNet.instance) && !ZNet.instance.IsServer() && !AdminRights.IsClientAdmin) { return L.T("block.need_rights"); } return L.T("block.host_only"); } if (value.IsCheat && name != "confirmcheats" && !Achievements.IsCheatedAtAll()) { return L.T("block.confirm_cheats"); } return null; } internal static bool IsCheat(string name) { if (Table.TryGetValue(name, out var value)) { return value.IsCheat; } return false; } internal static bool Exists(string name) { if (Object.op_Implicit((Object)(object)Console.instance)) { return Table.ContainsKey(name); } return false; } internal static void Run(string line) { queue.Add(line); } internal static void RunDirect(string line) { if (Object.op_Implicit((Object)(object)Console.instance)) { AddLog("<color=#8a857c>» " + line + "</color>"); ((Terminal)Console.instance).TryRunCommand(line, false, false); } } internal static void Flush() { if (queue.Count == 0) { return; } string[] array = queue.ToArray(); queue.Clear(); if (Object.op_Implicit((Object)(object)Console.instance) && Object.op_Implicit((Object)(object)Player.m_localPlayer)) { string[] array2 = array; foreach (string text in array2) { AddLog("<color=#8a857c>» " + text + "</color>"); ((Terminal)Console.instance).TryRunCommand(text, false, false); } } } internal static void AddLog(string text) { if (!string.IsNullOrEmpty(text) && (Object.op_Implicit((Object)(object)Player.m_localPlayer) || Object.op_Implicit((Object)(object)FejdStartup.instance))) { Log.Add(text.TrimEnd()); if (Log.Count > 80) { Log.RemoveRange(0, Log.Count - 80); } LogVersion++; } } } internal static class CreatureIcons { private const int Size = 128; private const int Layer = 31; private const int PerFrame = 2; private static readonly Vector3 Stage = new Vector3(0f, 5000f, 0f); private static readonly Dictionary<GameObject, Sprite> done = new Dictionary<GameObject, Sprite>(); private static readonly List<GameObject> wanted = new List<GameObject>(); private static Camera camera; private static Light light; private static RenderTexture target; internal static Sprite Get(GameObject prefab) { if (!Object.op_Implicit((Object)(object)prefab)) { return null; } if (done.TryGetValue(prefab, out var value)) { return value; } if (!wanted.Contains(prefab)) { wanted.Add(prefab); } return null; } internal static void Update() { for (int i = 0; i < 2; i++) { if (wanted.Count <= 0) { break; } GameObject val = wanted[0]; wanted.RemoveAt(0); Sprite value = null; try { value = Render(val); } catch (Exception ex) { Plugin.Log("no icon for " + (Object.op_Implicit((Object)(object)val) ? ((Object)val).name : "?") + ": " + ex.Message); } if (Object.op_Implicit((Object)(object)val)) { done[val] = value; } } } private static Sprite Render(GameObject prefab) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Expected O, but got Unknown Setup(); GameObject val = new GameObject("AdminMenu icon"); val.SetActive(false); val.transform.position = Stage; bool forceDisableInit = ZNetView.m_forceDisableInit; ZNetView.m_forceDisableInit = true; GameObject val2; try { val2 = Object.Instantiate<GameObject>(prefab, val.transform, false); } finally { ZNetView.m_forceDisableInit = forceDisableInit; } try { Strip(val2); if (val2.GetComponentsInChildren<MonoBehaviour>(true).Length != 0) { return null; } val2.transform.localPosition = Vector3.zero; val2.transform.localRotation = Quaternion.Euler(0f, 145f, 0f); Transform[] componentsInChildren = val2.GetComponentsInChildren<Transform>(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Component)componentsInChildren[i]).gameObject.layer = 31; } val.SetActive(true); Animator[] componentsInChildren2 = val2.GetComponentsInChildren<Animator>(); foreach (Animator obj in componentsInChildren2) { obj.cullingMode = (AnimatorCullingMode)0; obj.Update(0.1f); } if (!Bounds(val2, out var bounds)) { return null; } Vector3 extents = ((Bounds)(ref bounds)).extents; float num = Mathf.Max(0.1f, ((Vector3)(ref extents)).magnitude); float num2 = num / Mathf.Sin(camera.fieldOfView * 0.5f * ((float)Math.PI / 180f)); ((Component)camera).transform.rotation = Quaternion.Euler(12f, 0f, 0f); ((Component)camera).transform.position = ((Bounds)(ref bounds)).center - ((Component)camera).transform.forward * num2; camera.nearClipPlane = Mathf.Max(0.01f, num2 - num * 1.5f); camera.farClipPlane = num2 + num * 1.5f; ((Component)light).transform.rotation = Quaternion.Euler(35f, -30f, 0f); ((Behaviour)light).enabled = true; camera.Render(); ((Behaviour)light).enabled = false; RenderTexture active = RenderTexture.active; RenderTexture.active = target; Texture2D val3 = new Texture2D(128, 128, (TextureFormat)4, false) { hideFlags = (HideFlags)61 }; val3.ReadPixels(new Rect(0f, 0f, 128f, 128f), 0, 0); val3.Apply(false, false); RenderTexture.active = active; return Sprite.Create(val3, new Rect(0f, 0f, 128f, 128f), new Vector2(0.5f, 0.5f)); } finally { Object.DestroyImmediate((Object)(object)val); } } private static void Strip(GameObject copy) { for (int i = 0; i < 4; i++) { MonoBehaviour[] componentsInChildren = copy.GetComponentsInChildren<MonoBehaviour>(true); if (componentsInChildren.Length == 0) { break; } for (int num = componentsInChildren.Length - 1; num >= 0; num--) { if (Object.op_Implicit((Object)(object)componentsInChildren[num]) && CanRemove(componentsInChildren[num])) { Object.DestroyImmediate((Object)(object)componentsInChildren[num]); } } } ParticleSystem[] componentsInChildren2 = copy.GetComponentsInChildren<ParticleSystem>(true); for (int j = 0; j < componentsInChildren2.Length; j++) { ((Component)componentsInChildren2[j]).gameObject.SetActive(false); } Light[] componentsInChildren3 = copy.GetComponentsInChildren<Light>(true); for (int j = 0; j < componentsInChildren3.Length; j++) { ((Behaviour)componentsInChildren3[j]).enabled = false; } AudioSource[] componentsInChildren4 = copy.GetComponentsInChildren<AudioSource>(true); for (int j = 0; j < componentsInChildren4.Length; j++) { Object.DestroyImmediate((Object)(object)componentsInChildren4[j]); } Joint[] componentsInChildren5 = copy.GetComponentsInChildren<Joint>(true); for (int j = 0; j < componentsInChildren5.Length; j++) { Object.DestroyImmediate((Object)(object)componentsInChildren5[j]); } Rigidbody[] componentsInChildren6 = copy.GetComponentsInChildren<Rigidbody>(true); for (int j = 0; j < componentsInChildren6.Length; j++) { componentsInChildren6[j].isKinematic = true; } Collider[] componentsInChildren7 = copy.GetComponentsInChildren<Collider>(true); for (int j = 0; j < componentsInChildren7.Length; j++) { componentsInChildren7[j].enabled = false; } } private static bool CanRemove(MonoBehaviour script) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown MonoBehaviour[] components = ((Component)script).GetComponents<MonoBehaviour>(); foreach (MonoBehaviour val in components) { if (!Object.op_Implicit((Object)(object)val) || (Object)(object)val == (Object)(object)script) { continue; } object[] customAttributes = ((object)val).GetType().GetCustomAttributes(typeof(RequireComponent), inherit: true); for (int j = 0; j < customAttributes.Length; j++) { RequireComponent val2 = (RequireComponent)customAttributes[j]; Type type = ((object)script).GetType(); if ((val2.m_Type0 != null && val2.m_Type0.IsAssignableFrom(type)) || (val2.m_Type1 != null && val2.m_Type1.IsAssignableFrom(type)) || (val2.m_Type2 != null && val2.m_Type2.IsAssignableFrom(type))) { return false; } } } return true; } private static bool Bounds(GameObject copy, out Bounds bounds) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) bounds = default(Bounds); bool flag = false; Renderer[] componentsInChildren = copy.GetComponentsInChildren<Renderer>(); foreach (Renderer val in componentsInChildren) { if (val.enabled && !(val is ParticleSystemRenderer)) { if (!flag) { bounds = val.bounds; } else { ((Bounds)(ref bounds)).Encapsulate(val.bounds); } flag = true; } } if (flag) { Vector3 size = ((Bounds)(ref bounds)).size; return ((Vector3)(ref size)).sqrMagnitude > 0.0001f; } return false; } private static void Setup() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)camera)) { GameObject val = new GameObject("AdminMenu icon camera") { hideFlags = (HideFlags)61 }; Object.DontDestroyOnLoad((Object)val); target = new RenderTexture(128, 128, 24, (RenderTextureFormat)0) { antiAliasing = 4, hideFlags = (HideFlags)61 }; camera = val.AddComponent<Camera>(); ((Behaviour)camera).enabled = false; camera.cullingMask = int.MinValue; camera.clearFlags = (CameraClearFlags)2; camera.backgroundColor = new Color(0f, 0f, 0f, 0f); camera.fieldOfView = 25f; camera.allowHDR = false; camera.allowMSAA = true; camera.targetTexture = target; GameObject val2 = new GameObject("AdminMenu icon light") { hideFlags = (HideFlags)61 }; Object.DontDestroyOnLoad((Object)val2); light = val2.AddComponent<Light>(); light.type = (LightType)1; light.intensity = 1.3f; light.cullingMask = int.MinValue; ((Behaviour)light).enabled = false; } } } internal static class DropRules { internal static Dictionary<string, List<DropCellRule>> Rules = new Dictionary<string, List<DropCellRule>>(); private static readonly Dictionary<CharacterDrop, List<Drop>> originals = new Dictionary<CharacterDrop, List<Drop>>(); private static readonly HashSet<CharacterDrop> changed = new HashSet<CharacterDrop>(); private static readonly HashSet<string> reported = new HashSet<string>(); private static ZNetScene appliedScene; internal static bool Stale { get { if (Object.op_Implicit((Object)(object)ZNetScene.instance)) { return appliedScene != ZNetScene.instance; } return false; } } internal static void Apply() { foreach (CharacterDrop item in changed) { if (Object.op_Implicit((Object)(object)item) && originals.TryGetValue(item, out var value)) { item.m_drops = new List<Drop>(value); } } changed.Clear(); ZNetScene val = (appliedScene = ZNetScene.instance); if (!Object.op_Implicit((Object)(object)val) || Rules.Count == 0) { return; } Dictionary<string, GameObject> dictionary = new Dictionary<string, GameObject>(StringComparer.Ordinal); if (Object.op_Implicit((Object)(object)ObjectDB.instance)) { foreach (GameObject item2 in ObjectDB.instance.m_items) { if (Object.op_Implicit((Object)(object)item2)) { dictionary[((Object)item2).name.ToLowerInvariant()] = item2; } } } Dictionary<string, List<Drop>> dictionary2 = new Dictionary<string, List<Drop>>(StringComparer.Ordinal); foreach (GameObject prefab in val.m_prefabs) { if (Object.op_Implicit((Object)(object)prefab) && Rules.TryGetValue(((Object)prefab).name.ToLowerInvariant(), out var value2)) { CharacterDrop component = prefab.GetComponent<CharacterDrop>(); if (!Object.op_Implicit((Object)(object)component)) { Report("drop list on " + ((Object)prefab).name); continue; } List<Drop> value3 = (component.m_drops = Build(Remember(component), value2, dictionary, ((Object)prefab).name)); changed.Add(component); dictionary2[((Object)prefab).name] = value3; } } CharacterDrop[] array = Object.FindObjectsByType<CharacterDrop>((FindObjectsSortMode)0); foreach (CharacterDrop val2 in array) { if (Object.op_Implicit((Object)(object)val2) && dictionary2.TryGetValue(Utils.GetPrefabName(((Component)val2).gameObject), out var value4)) { Remember(val2); val2.m_drops = new List<Drop>(value4); changed.Add(val2); } } } internal static List<DropCellRule> Original(GameObject prefab) { List<DropCellRule> list = new List<DropCellRule>(); CharacterDrop val = (Object.op_Implicit((Object)(object)prefab) ? prefab.GetComponent<CharacterDrop>() : null); if (!Object.op_Implicit((Object)(object)val)) { return list; } List<Drop> value; List<Drop> list2 = (originals.TryGetValue(val, out value) ? value : val.m_drops); if (list2 != null) { foreach (Drop item in list2) { if (Object.op_Implicit((Object)(object)item?.m_prefab)) { list.Add(new DropCellRule(((Object)item.m_prefab).name, item.m_amountMin, item.m_amountMax, item.m_chance)); } } } return list; } internal static bool HasDropList(GameObject prefab) { if (Object.op_Implicit((Object)(object)prefab)) { return Object.op_Implicit((Object)(object)prefab.GetComponent<CharacterDrop>()); } return false; } internal static void Set(string prefab, List<DropCellRule> cells, RuleScope scope) { Dictionary<string, List<DropCellRule>> dictionary = new Dictionary<string, List<DropCellRule>>(WorldRules.Layer(scope).Drops); string key = prefab.ToLowerInvariant(); GameObject prefab2 = (Object.op_Implicit((Object)(object)ZNetScene.instance) ? ZNetScene.instance.GetPrefab(prefab) : null); if (cells == null || DropRuleText.Same(cells, Original(prefab2))) { dictionary.Remove(key); } else { dictionary[key] = cells; } WorldRules.SetDrops(scope, DropRuleText.FormatTable(dictionary)); } private static List<Drop> Remember(CharacterDrop drop) { if (!originals.TryGetValue(drop, out var value)) { value = (originals[drop] = new List<Drop>(drop.m_drops ?? new List<Drop>())); } return value; } private static List<Drop> Build(List<Drop> original, List<DropCellRule> cells, Dictionary<string, GameObject> items, string creature) { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Expected O, but got Unknown List<Drop> list = new List<Drop>(); foreach (DropCellRule cell in cells) { if (!items.TryGetValue(cell.Item, out var item)) { Report("item " + cell.Item + " for " + creature); continue; } Drop val = original.Find((Drop d) => d != null && (Object)(object)d.m_prefab == (Object)(object)item); list.Add(new Drop { m_prefab = item, m_amountMin = cell.Min, m_amountMax = cell.Max, m_chance = cell.Chance, m_onePerPlayer = (val?.m_onePerPlayer ?? false), m_levelMultiplier = (val?.m_levelMultiplier ?? true), m_levelMultiplierNotAmount = (val?.m_levelMultiplierNotAmount ?? false), m_dontScale = (val?.m_dontScale ?? false) }); } return list; } private static void Report(string what) { if (reported.Add(what)) { Plugin.Warning("drop rule: no " + what + " in this game; left as it was"); } } } internal struct DropCellRule : IEquatable<DropCellRule> { internal string Item; internal int Min; internal int Max; internal float Chance; internal DropCellRule(string item, int min, int max, float chance) { Item = (item ?? "").ToLowerInvariant(); Min = Math.Max(0, Math.Min(min, 10000)); Max = Math.Max(Min, Math.Min(max, 10000)); Chance = (float.IsNaN(chance) ? 0f : Math.Max(0f, Math.Min(chance, 1f))); } public bool Equals(DropCellRule other) { if (Item == other.Item && Min == other.Min && Max == other.Max) { return Math.Abs(Chance - other.Chance) < 5E-05f; } return false; } public override bool Equals(object other) { if (other is DropCellRule other2) { return Equals(other2); } return false; } public override int GetHashCode() { return (Item ?? "").GetHashCode() ^ (Min * 31) ^ (Max * 977); } } internal static class DropRuleText { internal const int MaxCells = 128; internal const int MaxAmount = 10000; internal static string Encode(List<DropCellRule> cells) { if (cells.Count == 0) { return "-"; } StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < cells.Count && i < 128; i++) { DropCellRule dropCellRule = cells[i]; if (i > 0) { stringBuilder.Append('/'); } stringBuilder.Append(dropCellRule.Item).Append('*').Append(dropCellRule.Min) .Append('*') .Append(dropCellRule.Max) .Append('*') .Append(dropCellRule.Chance.ToString("0.####", CultureInfo.InvariantCulture)); } return stringBuilder.ToString(); } internal static List<DropCellRule> Decode(string text) { if (string.IsNullOrEmpty(text)) { return null; } List<DropCellRule> list = new List<DropCellRule>(); if (text.Trim() == "-") { return list; } string[] array = text.Split('/'); for (int i = 0; i < array.Length; i++) { string[] array2 = array[i].Split('*'); if (array2.Length != 4 || array2[0].Trim().Length == 0 || !int.TryParse(array2[1].Trim(), NumberStyles.Integer, CultureInfo.InvariantCulture, out var result) || !int.TryParse(array2[2].Trim(), NumberStyles.Integer, CultureInfo.InvariantCulture, out var result2) || !float.TryParse(array2[3].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result3)) { return null; } if (list.Count < 128) { list.Add(new DropCellRule(array2[0].Trim(), result, result2, result3)); } } return list; } internal static Dictionary<string, List<DropCellRule>> ParseTable(string raw) { Dictionary<string, List<DropCellRule>> dictionary = new Dictionary<string, List<DropCellRule>>(StringComparer.Ordinal); if (string.IsNullOrEmpty(raw)) { return dictionary; } string[] array = raw.Split(';'); foreach (string text in array) { int num = text.IndexOf('='); if (num > 0) { List<DropCellRule> list = Decode(text.Substring(num + 1).Trim()); if (list != null) { dictionary[text.Substring(0, num).Trim().ToLowerInvariant()] = list; } } } return dictionary; } internal static string FormatTable(IDictionary<string, List<DropCellRule>> rules) { if (rules.Count == 0) { return null; } SortedDictionary<string, List<DropCellRule>> sortedDictionary = new SortedDictionary<string, List<DropCellRule>>(StringComparer.Ordinal); foreach (KeyValuePair<string, List<DropCellRule>> rule in rules) { sortedDictionary[rule.Key.ToLowerInvariant()] = rule.Value; } StringBuilder stringBuilder = new StringBuilder(); foreach (KeyValuePair<string, List<DropCellRule>> item in sortedDictionary) { if (stringBuilder.Length > 0) { stringBuilder.Append(';'); } stringBuilder.Append(item.Key).Append('=').Append(Encode(item.Value)); } return stringBuilder.ToString(); } internal static bool Same(List<DropCellRule> a, List<DropCellRule> b) { if (a == null || b == null || a.Count != b.Count) { return false; } for (int i = 0; i < a.Count; i++) { if (!a[i].Equals(b[i])) { return false; } } return true; } } internal static class Effects { internal sealed class Entry { internal string Asset; internal string Name; internal string Category; internal int Hash; internal float Duration; internal Sprite Icon; } internal const string Good = "fx.cat_good"; internal const string Powers = "fx.cat_powers"; internal const string Bad = "fx.cat_bad"; internal static readonly string[] Categories = new string[3] { "fx.cat_good", "fx.cat_powers", "fx.cat_bad" }; private static readonly HashSet<string> BadTypes = new HashSet<string> { "SE_Burning", "SE_Frost", "SE_Harpooned", "SE_Poison", "SE_Puke", "SE_Smoke", "SE_Wet" }; private static readonly HashSet<string> BadNames = new HashSet<string> { "Cold", "Freezing", "Encumbered", "Tared", "Wet", "Smoked", "Burning", "Poison", "Frost", "Lightning", "Spirit", "Slimed", "Staggering" }; internal static readonly List<Entry> All = new List<Entry>(); private static ObjectDB readFrom; private static int readCount = -1; internal static void Forget() { readFrom = null; } internal static void Refresh() { ObjectDB instance = ObjectDB.instance; if (!Object.op_Implicit((Object)(object)instance) || (instance == readFrom && instance.m_StatusEffects.Count == readCount)) { return; } readFrom = instance; readCount = instance.m_StatusEffects.Count; All.Clear(); foreach (StatusEffect statusEffect in instance.m_StatusEffects) { if (Object.op_Implicit((Object)(object)statusEffect)) { string text = ((string.IsNullOrEmpty(statusEffect.m_name) || Localization.instance == null) ? "" : Localization.instance.Localize(statusEffect.m_name)); if (string.IsNullOrEmpty(text) || text.StartsWith("[")) { text = ((Object)statusEffect).name; } All.Add(new Entry { Asset = ((Object)statusEffect).name, Name = text, Hash = StringExtensionMethods.GetStableHashCode(((Object)statusEffect).name), Duration = statusEffect.m_ttl, Icon = statusEffect.m_icon, Category = (((Object)statusEffect).name.StartsWith("GP_") ? "fx.cat_powers" : ((BadTypes.Contains(((object)statusEffect).GetType().Name) || BadNames.Contains(((Object)statusEffect).name)) ? "fx.cat_bad" : "fx.cat_good")) }); } } All.Sort((Entry a, Entry b) => string.Compare(a.Name, b.Name, StringComparison.CurrentCulture)); } internal static void Apply(Entry entry, Character target, float duration) { Apply(entry.Hash, entry.Name, target, duration); } internal static void Apply(int hash, string name, Character target, float duration) { SEMan val = (Object.op_Implicit((Object)(object)target) ? target.GetSEMan() : null); if (val != null) { val.AddStatusEffect(hash, true, 0, 0f, (short)(-1)); StatusEffect val2 = (Owned(target) ? val.GetStatusEffect(hash) : null); if (Object.op_Implicit((Object)(object)val2) && duration > 0f) { val2.m_ttl = duration; val2.ResetTime(); } Commands.AddLog("<color=#8a857c>» " + L.F("log.effect", name, Name(target)) + ((duration > 0f && Object.op_Implicit((Object)(object)val2)) ? (", " + L.F("unit.seconds", Mathf.RoundToInt(duration))) : "") + "</color>"); } } internal static void Remove(StatusEffect effect, Character target) { if (Object.op_Implicit((Object)(object)target) && Owned(target)) { target.GetSEMan().RemoveStatusEffect(effect, false); } } internal static bool Owned(Character target) { ZNetView val = (Object.op_Implicit((Object)(object)target) ? ((Component)target).GetComponent<ZNetView>() : null); if (Object.op_Implicit((Object)(object)val) && val.IsValid()) { return val.IsOwner(); } return false; } internal static string Name(Character target) { if (!Object.op_Implicit((Object)(object)target)) { return "—"; } if ((Object)(object)target == (Object)(object)Player.m_localPlayer) { return L.T("fx.you"); } Player val = (Player)(object)((target is Player) ? target : null); if (val != null) { return val.GetPlayerName(); } if (Localization.instance == null) { return target.m_name; } return Localization.instance.Localize(target.m_name); } } internal static class FreeFlyLoader { private static readonly FieldRef<Character, float> MaxAirAltitude = AccessTools.FieldRefAccess<Character, float>("m_maxAirAltitude"); private static Player held; private static ZNetView heldView; private static Rigidbody heldBody; private static Vector3 anchor; private static bool cameraLeads; private static float returnedAt; internal static string Note { get; private set; } internal static string Unavailable() { if (!Object.op_Implicit((Object)(object)Console.instance) || !((Terminal)Console.instance).IsCheatsEnabled()) { return L.T("freefly.need_cheats"); } return null; } internal static void Tick() { //IL_00a9: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (held != null && (!Object.op_Implicit((Object)(object)held) || (Object)(object)held != (Object)(object)localPlayer)) { Forget(); } bool flag = Object.op_Implicit((Object)(object)localPlayer) && WantsLead(localPlayer); if (flag && !cameraLeads) { if (held == null) { Grab(localPlayer); } cameraLeads = true; } else if (!flag && cameraLeads) { cameraLeads = false; returnedAt = Time.time; } if (held != null && !cameraLeads) { float num = Time.time - returnedAt; if ((num > 0.5f && Object.op_Implicit((Object)(object)ZNetScene.instance) && ZNetScene.instance.IsAreaReady(anchor)) || num > 15f || ((Character)held).IsDead() || ((Character)held).IsTeleporting()) { Release(); } } } private static bool WantsLead(Player player) { Note = null; if (!GameCamera.InFreeFly() || !Plugin.FreeFlyLoadsWorld.Value || Unavailable() != null) { return false; } if (((Character)player).IsDead() || ((Character)player).IsTeleporting()) { return false; } if (cameraLeads) { return true; } if (((Character)player).IsAttached() || (Object)(object)((Character)player).GetStandingOnShip() != (Object)null) { Note = L.T("freefly.attached"); return false; } return true; } private static void Grab(Player player) { //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) held = player; heldView = ((Component)player).GetComponent<ZNetView>(); heldBody = ((Component)player).GetComponent<Rigidbody>(); anchor = ((Component)player).transform.position; } private static void Release() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)held)) { MaxAirAltitude.Invoke((Character)(object)held) = ((Component)held).transform.position.y; } Forget(); } private static void Forget() { held = null; heldView = null; heldBody = null; cameraLeads = false; } internal static void Hold() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)held) && !((Character)held).IsTeleporting()) { ((Component)held).transform.position = anchor; if (Object.op_Implicit((Object)(object)heldBody)) { heldBody.linearVelocity = Vector3.zero; heldBody.angularVelocity = Vector3.zero; } } } internal static void MoveReference() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) if (cameraLeads && Object.op_Implicit((Object)(object)ZNet.instance) && Object.op_Implicit((Object)(object)GameCamera.instance)) { ZNet.instance.SetReferencePosition(((Component)GameCamera.instance).transform.position); } } internal static void KeepHeld(List<ZDO> nearObjects) { if (held != null && Object.op_Implicit((Object)(object)heldView)) { ZDO zDO = heldView.GetZDO(); if (zDO != null) { nearObjects.Add(zDO); } } } } internal static class HostLink { private enum Op { Hello = 1, Teleport, Locations, Event, RandomEvent, StopEvent, Players, Message, SkipTime, GameRules } private const string RequestRpc = "AdminMenu_Request"; private const string ReplyRpc = "AdminMenu_Reply"; private static readonly FieldRef<ZNet, SyncedList> AdminList = AccessTools.FieldRefAccess<ZNet, SyncedList>("m_adminList"); private static readonly Func<ZNet, SyncedList, string, bool> ListContainsId = AccessTools.MethodDelegate<Func<ZNet, SyncedList, string, bool>>(AccessTools.Method(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null), (object)null, true); private static ZRoutedRpc registered; private static int hellos; private static float nextHello; private static float locationsAsked = -100f; private static float helloAnsweredAt; internal static bool HostHasMenu; internal static readonly List<KeyValuePair<string, Vector3>> Locations = new List<KeyValuePair<string, Vector3>>(); internal static int LocationsVersion; private const float Grace = 40f; private const float KickDelay = 5f; private static readonly Dictionary<long, string> clientVersions = new Dictionary<long, string>(); private static readonly Dictionary<long, float> firstSeen = new Dictionary<long, float>(); private static readonly Dictionary<long, float> kickAt = new Dictionary<long, float>(); private static readonly Action<ZNet, ZNetPeer> InternalKick = AccessTools.MethodDelegate<Action<ZNet, ZNetPeer>>(AccessTools.Method(typeof(ZNet), "InternalKick", new Type[1] { typeof(ZNetPeer) }, (Type[])null), (object)null, true); private static float requiredSince = -1f; private static float nextCheck; internal static bool Client { get { if (Object.op_Implicit((Object)(object)ZNet.instance)) { return !ZNet.instance.IsServer(); } return false; } } internal static bool Relayed { get { if (Client) { return HostHasMenu; } return false; } } internal static void Update() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance == null) { registered = null; return; } if (instance != registered) { registered = instance; HostHasMenu = false; hellos = 0; nextHello = 0f; Locations.Clear(); LocationsVersion = 0; WorldRules.ResetHostRules(Object.op_Implicit((Object)(object)ZNet.instance) && !ZNet.instance.IsServer()); instance.Register<ZPackage>("AdminMenu_Request", (Action<long, ZPackage>)OnRequest); instance.Register<ZPackage>("AdminMenu_Reply", (Action<long, ZPackage>)OnReply); PlayerLink.Register(instance); } if (Client && !HostHasMenu && hellos < 3 && Object.op_Implicit((Object)(object)Player.m_localPlayer) && Time.unscaledTime > nextHello) { hellos++; nextHello = Time.unscaledTime + 10f; Send(Op.Hello, delegate(ZPackage p) { p.Write("0.9.6"); }); } if (WorldRules.HostRulesPending && Client && ((hellos >= 3 && Time.unscaledTime > nextHello) || (HostHasMenu && Time.unscaledTime > helloAnsweredAt + 5f))) { WorldRules.ResetHostRules(pending: false); } if (Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.instance.IsServer()) { CheckClients(); } else if (clientVersions.Count > 0) { clientVersions.Clear(); } } internal static string ClientVersion(long session) { if (!clientVersions.TryGetValue(session, out var value)) { return null; } return value; } private static void CheckClients() { if (Time.unscaledTime < nextCheck) { return; } nextCheck = Time.unscaledTime + 1f; List<ZNetPeer> peers = ZNet.instance.GetPeers(); HashSet<long> hashSet = new HashSet<long>(); foreach (ZNetPeer item in peers) { hashSet.Add(item.m_uid); } Forget(clientVersions, hashSet); Forget(firstSeen, hashSet); Forget(kickAt, hashSet); if (!WorldRules.NeedModEverywhere) { requiredSince = -1f; kickAt.Clear(); return; } if (requiredSince < 0f) { requiredSince = Time.unscaledTime; } foreach (ZNetPeer item2 in peers) { if (((ZDOID)(ref item2.m_characterID)).IsNone()) { continue; } if (!firstSeen.ContainsKey(item2.m_uid)) { firstSeen[item2.m_uid] = Time.unscaledTime; } if (kickAt.TryGetValue(item2.m_uid, out var value)) { if (Time.unscaledTime >= value) { kickAt.Remove(item2.m_uid); Plugin.Log("kicking " + item2.m_playerName + ": AdminMenu " + (ClientVersion(item2.m_uid) ?? "missing")); InternalKick(ZNet.instance, item2); } continue; } string text = ClientVersion(item2.m_uid); bool flag = Time.unscaledTime - Mathf.Max(firstSeen[item2.m_uid], requiredSince) > 40f; if (!(text == "0.9.6") && (text != null || flag)) { string text2 = ((text == null) ? L.Both("host.need_mod", "0.9.6") : L.Both("host.wrong_version", "0.9.6", text)); ZRoutedRpc.instance.InvokeRoutedRPC(item2.m_uid, "ShowMessage", new object[2] { 2, text2 }); kickAt[item2.m_uid] = Time.unscaledTime + 5f; } } } private static void Forget<T>(Dictionary<long, T> map, HashSet<long> here) { List<long> list = new List<long>(); foreach (long key in map.Keys) { if (!here.Contains(key)) { list.Add(key); } } foreach (long item in list) { map.Remove(item); } } internal static void SendGameRules(long to) { if (!Object.op_Implicit((Object)(object)ZNet.instance) || !ZNet.instance.IsServer() || ZRoutedRpc.instance == null) { return; } Dictionary<string, string> rules = WorldRules.GameRulesToSend(); List<long> list = new List<long>(); if (to != 0L) { list.Add(to); } else { foreach (KeyValuePair<long, string> clientVersion in clientVersions) { if (L.KnowsKeys(clientVersion.Value)) { list.Add(clientVersion.Key); } } } foreach (long item in list) { Reply(item, Op.GameRules, delegate(ZPackage p) { p.Write(rules.Count); foreach (KeyValuePair<string, string> item2 in rules) { p.Write(item2.Key); p.Write(item2.Value); } }); } } internal static void DrawWaiting() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) if (WorldRules.HostRulesPending && Client && hellos != 0 && Object.op_Implicit((Object)(object)Player.m_localPlayer)) { GUIContent val = new GUIContent(L.T("host.rules_waiting")); GUIStyle box = GUI.skin.box; Vector2 val2 = box.CalcSize(val); GUI.Box(new Rect(((float)Screen.width - val2.x - 24f) / 2f, 12f, val2.x + 24f, val2.y + 8f), val, box); } } internal static void AskAgain() { if (Client) { hellos = 0; nextHello = 0f; HostHasMenu = false; WorldRules.ResetHostRules(pending: true); } } internal static string Blocker() { if (!Terminal.m_cheat) { return L.T("block.cheats_off"); } if (!AdminRights.IsClientAdmin) { return L.T("block.need_rights"); } if (!HostHasMenu) { return L.T("host.server_lacks_mod"); } if (!Achievements.IsCheatedAtAll()) { return L.T("block.confirm_cheats"); } return null; } internal static void Teleport(long who, ZDOID to) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) Send(Op.Teleport, L.T("host.log_move"), delegate(ZPackage p) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) p.Write(who); p.Write(to); }); } internal static void RequestLocations() { if (!(Time.unscaledTime - locationsAsked < 15f)) { locationsAsked = Time.unscaledTime; Send(Op.Locations, null, null); } } internal static void StartEvent(string name) { Send(Op.Event, L.F("host.log_event", name), delegate(ZPackage p) { p.Write(name); }); } internal static void RandomEvent() { Send(Op.RandomEvent, L.T("host.log_random_event"), null); } internal static void StopEvent() { Send(Op.StopEvent, L.T("host.log_stop_event"), null); } internal static void Players(int players) { Send(Op.Players, L.F("host.log_difficulty", players), delegate(ZPackage p) { p.Write(players); }); } internal static void SkipTime(double seconds) { Send(Op.SkipTime, L.F("host.log_time", ((seconds >= 0.0) ? "+" : "") + Mathf.RoundToInt((float)seconds)), delegate(ZPackage p) { p.Write(seconds); }); } private static void Send(Op op, Action<ZPackage> write) { Send(op, null, write); } private static void Send(Op op, string log, Action<ZPackage> write) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown ZNetPeer val = (Object.op_Implicit((Object)(object)ZNet.instance) ? ZNet.instance.GetServerPeer() : null); if (val != null && ZRoutedRpc.instance != null) { if (log != null) { Commands.AddLog("<color=#8a857c>» " + L.F("host.log_sent", log) + "</color>"); } ZPackage val2 = new ZPackage(); val2.Write((int)op); write?.Invoke(val2); ZRoutedRpc.instance.InvokeRoutedRPC(val.m_uid, "AdminMenu_Request", new object[1] { val2 }); } } private static void Reply(long to, Op op, Action<ZPackage> write) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write((int)op); write?.Invoke(val); ZRoutedRpc.instance.InvokeRoutedRPC(to, "AdminMenu_Reply", new object[1] { val }); } private static void Tell(long to, string key, params object[] args) { Reply(to, Op.Message, delegate(ZPackage p) { p.Write(L.ForVersion(ClientVersion(to), key, args)); }); } private static void OnRequest(long sender, ZPackage pkg) { //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: 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_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) try { if (!Object.op_Implicit((Object)(object)ZNet.instance) || !ZNet.instance.IsServer()) { return; } Op op = (Op)pkg.ReadInt(); if (op == Op.Hello) { clientVersions[sender] = ((pkg.GetPos() < pkg.Size()) ? pkg.ReadString() : "0.1.0"); Reply(sender, Op.Hello, null); if (L.KnowsKeys(clientVersions[sender])) { SendGameRules(sender); } return; } ZNetPeer peer = ZNet.instance.GetPeer(sender); SyncedList val = AdminList.Invoke(ZNet.instance); if (peer == null || val == null || !ListContainsId(ZNet.instance, val, peer.m_socket.GetHostName())) { Tell(sender, "host.no_rights"); return; } switch (op) { case Op.Teleport: { long num2 = pkg.ReadLong(); ZDOID val2 = pkg.ReadZDOID(); if (num2 == ZNet.GetUID() && Object.op_Implicit((Object)(object)Player.m_localPlayer)) { Tell(sender, "host.no_move_host"); break; } ZDO zDO = ZDOMan.instance.GetZDO(val2); if (zDO == null) { Tell(sender, "host.no_player"); break; } ZRoutedRpc.instance.InvokeRoutedRPC(num2, "RPC_TeleportPlayer", new object[3] { zDO.GetPosition(), zDO.GetRotation(), true }); Plugin.Log(peer.m_playerName + " teleports " + NameOf(num2) + " to " + NameOf(((ZDOID)(ref val2)).UserID)); break; } case Op.Locations: Reply(sender, Op.Locations, WriteLocations); break; case Op.Event: { string text = pkg.ReadString(); if (!Object.op_Implicit((Object)(object)RandEventSystem.instance) || !RandEventSystem.instance.HaveEvent(text)) { Tell(sender, "host.no_event", text); } else { ZDO zDO2 = ZDOMan.instance.GetZDO(peer.m_characterID); RandEventSystem.instance.SetRandomEventByName(text, (zDO2 != null) ? zDO2.GetPosition() : peer.GetRefPos()); Plugin.Log(peer.m_playerName + " starts event " + text); } break; } case Op.RandomEvent: if (Object.op_Implicit((Object)(object)RandEventSystem.instance)) { RandEventSystem.instance.StartRandomEvent(); } break; case Op.StopEvent: if (Object.op_Implicit((Object)(object)RandEventSystem.instance)) { RandEventSystem.instance.ResetRandomEvent(); } break; case Op.SkipTime: { double num3 = pkg.ReadDouble(); ZNet.instance.SetNetTime(Math.Max(0.0, ZNet.instance.GetTimeSeconds() + num3)); Plugin.Log(peer.m_playerName + " moves time by " + num3.ToString("0") + " s"); break; } case Op.Players: { int num = pkg.ReadInt(); if (Object.op_Implicit((Object)(object)Game.instance)) { Game.instance.SetForcePlayerDifficulty(num); } Tell(sender, (num > 0) ? "host.difficulty_set" : "host.difficulty_auto", num); break; } case Op.Message: break; } } catch (Exception e) { Guard.Report("host request", e); } } private static void WriteLocations(ZPackage pkg) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Expected O, but got Unknown //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) List<string> list = new List<string>(); Dictionary<string, int> dictionary = new Dictionary<string, int>(); ZPackage val = new ZPackage(); int num = 0; foreach (LocationInstance location in ZoneSystem.instance.GetLocationList()) { string text = location.m_location?.m_prefab.Name; if (!string.IsNullOrEmpty(text)) { if (!dictionary.TryGetValue(text, out var value)) { value = (dictionary[text] = list.Count); list.Add(text); } val.Write(value); val.Write(location.m_position); num++; } } ZPackage val2 = new ZPackage(); val2.Write(list.Count); foreach (string item in list) { val2.Write(item); } val2.Write(num); val2.Write(val); pkg.WriteCompressed(val2); } private static void OnReply(long sender, ZPackage pkg) { //IL_0182: Unknown result type (might be due to invalid IL or missing references) try { ZNetPeer val = (Object.op_Implicit((Object)(object)ZNet.instance) ? ZNet.instance.GetServerPeer() : null); if (val == null || sender != val.m_uid) { return; } switch ((Op)pkg.ReadInt()) { case Op.Hello: HostHasMenu = true; helloAnsweredAt = Time.unscaledTime; break; case Op.GameRules: { Dictionary<string, string> dictionary = new Dictionary<string, string>(); for (int num3 = pkg.ReadInt(); num3 > 0; num3--) { dictionary[pkg.ReadString()] = pkg.ReadString(); } bool hostRulesPending = WorldRules.HostRulesPending; WorldRules.SetHostRules(dictionary); int num4 = WorldRules.CountOf(dictionary); if (hostRulesPending && num4 > 0 && Object.op_Implicit((Object)(object)Player.m_localPlayer)) { ((Character)Player.m_localPlayer).Message((MessageType)1, L.F("host.rules_received", num4), 0, (Sprite)null, false); } break; } case Op.Message: Commands.AddLog("<color=#e0a040>" + L.Decode(pkg.ReadString()) + "</color>"); break; case Op.Locations: { ZPackage val2 = pkg.ReadCompressedPackage(); string[] array = new string[val2.ReadInt()]; for (int i = 0; i < array.Length; i++) { array[i] = val2.ReadString(); } int num = val2.ReadInt(); ZPackage val3 = val2.ReadPackage(); Locations.Clear(); for (int j = 0; j < num; j++) { int num2 = val3.ReadInt(); Locations.Add(new KeyValuePair<string, Vector3>(array[num2], val3.ReadVector3())); } LocationsVersion++; break; } } } catch (Exception e) { Guard.Report("host reply", e); } } private static string NameOf(long session) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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) foreach (PlayerInfo player in ZNet.instance.GetPlayerList()) { ZDOID characterID = player.m_characterID; if (((ZDOID)(ref characterID)).UserID == session) { return player.m_name; } } return session.ToString(); } } internal static class InputBlocker { private static GameObject root; private static RectTransform panelArea; private static RectTransform tabArea; private static RectTransform windowArea; internal static void Cover(Rect panel, Rect tab, Rect window = default(Rect)) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)root)) { Create(); } if (!root.activeSelf) { root.SetActive(true); } Place(panelArea, panel); Place(tabArea, tab); Place(windowArea, window); } internal static void Hide() { if (Object.op_Implicit((Object)(object)root) && root.activeSelf) { root.SetActive(false); } } internal static void Remove() { if (Object.op_Implicit((Object)(object)root)) { Object.Destroy((Object)(object)root); } } private static void Place(RectTransform area, Rect guiRect) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) area.anchoredPosition = new Vector2(((Rect)(ref guiRect)).x, (float)Screen.height - ((Rect)(ref guiRect)).yMax); area.sizeDelta = ((Rect)(ref guiRect)).size; } private static void Create() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown root = new GameObject("AdminMenu.InputBlocker"); Object.DontDestroyOnLoad((Object)(object)root); Canvas obj = root.AddComponent<Canvas>(); obj.renderMode = (RenderMode)0; obj.sortingOrder = 32000; root.AddComponent<GraphicRaycaster>(); panelArea = AddArea("Panel"); tabArea = AddArea("Tab"); windowArea = AddArea("Window"); } private static RectTransform AddArea(string name) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.transform.SetParent(root.transform, false); RectTransform val2 = (RectTransform)val.transform; Vector2 val3 = (val2.pivot = Vector2.zero); Vector2 anchorMin = (val2.anchorMax = val3); val2.anchorMin = anchorMin; Image obj = val.AddComponent<Image>(); ((Graphic)obj).color = Color.clear; ((Graphic)obj).canvasRenderer.cullTransparentMesh = true; return val2; } } public enum LanguageMode { Auto, English, Russian } internal static class L { private static Dictionary<string, string[]> table; private static readonly HashSet<string> reported = new HashSet<string>(); internal static Action<string> Missing; private const char WireMark = '\u0001'; private const char WireArg = '\u0002'; internal static bool Russian { get; private set; } internal static int Generation { get; private set; } = 1; internal static IEnumerable<string> Keys => Table.Keys; private static Dictionary<string, string[]> Table { get { if (table != null) { return table; } Dictionary<string, string[]> dictionary = new Dictionary<string, string[]>(StringComparer.Ordinal); for (int i = 0; i < Strings.Entries.GetLength(0); i++) { dictionary[Strings.Entries[i, 0]] = new string[2] { Strings.Entries[i, 1], Strings.Entries[i, 2] }; } return table = dictionary; } } internal static void Set(LanguageMode mode, string gameLanguage) { bool flag = mode switch { LanguageMode.Auto => string.Equals(gameLanguage, "Russian", StringComparison.OrdinalIgnoreCase), LanguageMode.Russian => true, _ => false, }; if (flag != Russian) { Russian = flag; Generation++; } } internal static string T(string key) { return Text(key, Russian); } internal static string Ru(string key) { return Text(key, russian: true); } internal static string En(string key) { return Text(key, russian: false); } internal static string F(string key, params object[] args) { return Format(T(key), args); } internal static string N(string key, long n) { return Plural(T(key), n, Russian); } internal static string Both(string key, params object[] args) { return Format(En(key), args) + "\n" + Format(Ru(key), args); } internal static string Wire(string key, params object[] args) { StringBuilder stringBuilder = new StringBuilder().Append('\u0001').Append(key); foreach (object obj in args) { stringBuilder.Append('\u0002').Append(Convert.ToString(obj, CultureInfo.InvariantCulture)); } return stringBuilder.ToString(); } internal static string Decode(string text) { if (string.IsNullOrEmpty(text) || text[0] != '\u0001') { return text; } string[] array = text.Substring(1).Split('\u0002'); if (!Table.ContainsKey(array[0])) { return string.Join(" ", array); } object[] array2 = new object[array.Length - 1]; Array.Copy(array, 1, array2, 0, array2.Length); return F(array[0], array2); } internal static bool KnowsKeys(string version) { if (version != null && Version.TryParse(version, out Version result)) { return result >= new Version(0, 4, 0); } return false; } internal static string ForVersion(string version, string key, params object[] args) { if (!KnowsKeys(version)) { return Format(Ru(key), args); } return Wire(key, args); } private static string Text(string key, bool russian) { if (key != null && Table.TryGetValue(key, out var value)) { return value[(!russian) ? 1u : 0u]; } if (reported.Add(key ?? "")) { Missing?.Invoke("no text for key " + key); } return key ?? ""; } private static string Format(string text, object[] args) { if (args != null && args.Length != 0) { return string.Format(CultureInfo.InvariantCulture, text, args); } return text; } internal static string Plural(string forms, long n, bool russian) { string[] array = forms.Split('|'); long num = Math.Abs(n) % 10; long num2 = Math.Abs(n) % 100; int val = ((!russian) ? ((n != 1) ? 1 : 0) : ((num != 1 || num2 == 11) ? ((num >= 2 && num <= 4 && (num2 < 12 || num2 > 14)) ? 1 : 2) : 0)); return array[Math.Min(val, array.Length - 1)]; } } internal static class LocationFinder { internal sealed class Kind { internal string Key; internal string Category; internal string Name; internal string Note; internal PinType Icon; internal readonly List<string> PrefabNames = new List<string>(); internal readonly List<Vector3> Places = new List<Vector3>(); internal readonly List<PinData> Pins = new List<PinData>(); internal readonly List<string> Sometimes = new List<string>(); internal readonly List<string> InRooms = new List<string>(); internal bool Marked; internal float Nearest = float.MaxValue; internal Vector3 NearestPlace; internal int InRadius; } internal const string Bosses = "loc.bosses"; internal const string Hints = "loc.hints"; internal const string Dungeons = "loc.dungeons"; internal const string Camps = "loc.camps"; internal const string Lore = "loc.lore"; internal const string Traders = "loc.traders"; internal const string Other = "loc.other"; internal const string Prefabs = "loc.prefabs"; internal static readonly string[] Categories = new string[8] { "loc.bosses", "loc.hints", "loc.dungeons", "loc.camps", "loc.lore", "loc.traders", "loc.other", "loc.prefabs" }; private const int MaxPinsPerKind = 300; private const PinType BossPin = (PinType)9; private const PinType HintPin = (PinType)6; private const PinType PlacePin = (PinType)3; private const PinType HousePin = (PinType)1; private static readonly Dictionary<string, string> CampNames = new Dictionary<string, string> { { "WoodVillage1", "loc.draugr_village" }, { "WoodVillage2", "loc.draugr_village" }, { "GoblinCamp2", "loc.fuling_camp" }, { "Greydwarf_camp1", "loc.greydwarf_camp" }, { "FortressRuins", "loc.fortress_ruins" }, { "AshlandRuins", "loc.ashlands_ruins" }, { "CharredFortress", "$charredfortress" }, { "NorthVillage", "loc.north_village" }, { "HalfBurried_ForestCrypt", "loc.half_buried_crypt" } }; private static readonly Dictionary<string, string> TraderNames = new Dictionary<string, string> { { "BogWitch_Camp", "$npc_bogwitch" } }; internal static readonly List<Kind> Kinds = new List<Kind>(); internal static float Radius = 1000f; internal static string Summary = ""; internal static bool Wanted; private static ZoneSystem indexed; private static int indexedCount = -1; private static int builtVersion = -1; private static int builtLanguage; private static Minimap pinsOn; private static float measuredAt = -10f; private static float radiusChangedAt = -10f; private static bool remarkPending; internal static string Unavailable() { if (!Object.op_Implicit((Object)(object)ZoneSystem.instance) || !Object.op_Implicit((Object)(object)ZNet.instance)) { return L.T("common.world_not_loaded"); } if (HostLink.Client) { return HostLink.Blocker() ?? Commands.Blocker("find"); } return Commands.Blocker("find"); } internal static void Update() { if (Wanted && Object.op_Implicit((Object)(object)Player.m_localPlayer) && Unavailable() == null) { if (pinsOn != Minimap.instance) { ForgetPins(); } LocationScanner.Update(); ZoneSystem instance = ZoneSystem.instance; if (HostLink.Client && HostLink.LocationsVersion == 0) { HostLink.RequestLocations(); } int num = (HostLink.Client ? HostLink.LocationsVersion : instance.GetLocationList().Count); if (instance != indexed || num != indexedCount || LocationScanner.Version != builtVersion || L.Generation != builtLanguage) { Rebuild(instance, num); } if (remarkPending && Time.unscaledTime - radiusChangedAt > 0.35f && !ZInput.GetMouseButton(0)) { remarkPending = false; MarkAll(); } if (Time.unscaledTime - measuredAt > 0.5f) { Measure(); } } } internal static void Forget() { builtVersion = int.MinValue; } internal static void SetRadius(float radius) { radius = Mathf.Max(1f, radius); if (!Mathf.Approximately(radius, Radius)) { Radius = radius; radiusChangedAt = Time.unscaledTime; remarkPending = true; measuredAt = -10f; } } internal static void Toggle(Kind kind) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) kind.Marked