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 MEL Modpack v0.1.4
plugins/VSM.AdminPortals/VSM.AdminPortals.dll
Decompiled 3 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ConditionalConfigSync; using HarmonyLib; using Microsoft.CodeAnalysis; using Splatform; using TMPro; using UnityEngine; using UnityEngine.UI; using VSM.Core.Config; using VSM.Core.Harmony; using VSM.Core.Localization; using VSM.Core.Reflection; using VSM.Core.Runtime; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: <977d6cca-7cff-4fb7-a12c-37e7012c14b1>IgnoresAccessChecksTo("assembly_guiutils")] [assembly: <977d6cca-7cff-4fb7-a12c-37e7012c14b1>IgnoresAccessChecksTo("assembly_utils")] [assembly: <977d6cca-7cff-4fb7-a12c-37e7012c14b1>IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("VSM.AdminPortals")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("0.1.4.0")] [assembly: AssemblyInformationalVersion("0.1.4+ff27bc889ccf218c61c45d3417d48ab708a5ba8f")] [assembly: AssemblyProduct("VSM.AdminPortals")] [assembly: AssemblyTitle("VSM.AdminPortals")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.4.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace VSM.AdminPortals { [BepInPlugin("vsm.adminportals", "MEL AdminPortals", "0.1.4")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class AdminPortalsPlugin : BaseUnityPlugin { internal static ManualLogSource Log; private static ConfigSync s_sync; private static CustomSyncedValue<bool> s_gateOk; private Harmony _harmony; public static ConfigEntry<bool> Enabled; public static ConfigEntry<bool> BlockNonAdminPlacement; public static ConfigEntry<bool> AdminOnlyTravel; public static ConfigEntry<bool> LockTagsForNonAdmins; public static ConfigEntry<bool> ServerLock; public static ConfigEntry<bool> VerboseLog; internal static bool ServerPatchesOk; private static readonly Dictionary<string, string> s_spanish = new Dictionary<string, string> { { "vsm_adminportals_onlyadmin", "Solo un administrador puede construir portales en este servidor" }, { "vsm_adminportals_hover_off", "Portales desactivados: solo funcionan los que construye un administrador" }, { "vsm_adminportals_travel_adminonly", "Solo los administradores pueden usar los portales en este servidor" }, { "vsm_adminportals_tag_locked", "Solo un administrador puede cambiar el nombre de los portales" } }; public static bool IsConfigReady => s_sync != null && (((ConditionalConfigSync)s_sync).IsSourceOfTruth || ((ConditionalConfigSync)s_sync).InitialSyncDone); public static bool Active => Enabled != null && Enabled.Value && IsConfigReady && s_gateOk != null && s_gateOk.Value && (Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGlobalKey((GlobalKeys)32); public static bool LocalIsAdmin => ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer()) || (s_sync != null && ((ConditionalConfigSync)s_sync).IsAdmin); private void Awake() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0044: Expected O, but got Unknown //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; s_sync = new ConfigSync("vsm.adminportals") { DisplayName = "MEL AdminPortals", CurrentVersion = "0.1.4", MinimumRequiredVersion = "0.1.4", ModRequired = true }; Enabled = Synced<bool>(Bind("1. General", "Enabled", value: true, "Con el modificador de portales de Valheim activo (noportals), funcionan los portales construidos por un administrador. Con false, los portales quedan como en vanilla.", 100)); BlockNonAdminPlacement = Synced<bool>(Bind("1. General", "BlockNonAdminPlacement", value: true, "Con noportals activo, un jugador que no es administrador no puede colocar portales (aviso, sin gastar materiales). Con false puede colocarlos, pero nunca se conectan.", 99)); AdminOnlyTravel = Synced<bool>(Bind("1. General", "AdminOnlyTravel", value: false, "Solo los administradores pueden cruzar los portales de administrador. Con false (por defecto) los cruza cualquiera.", 98)); LockTagsForNonAdmins = Synced<bool>(Bind("1. General", "LockTagsForNonAdmins", value: false, "Solo los administradores pueden cambiar el nombre de un portal mientras noportals esté activo (evita reenlazar portales de admin).", 97)); ServerLock = Bind("1. General", "ServerLock", value: true, "Bloquea la configuración sincronizada: solo los administradores del servidor pueden cambiarla.", 96); ((ConditionalConfigSync)s_sync).AddLockingConfigEntry<bool>(ServerLock); VerboseLog = Bind("2. Depuración", "VerboseLog", value: false, "Registro detallado de conexiones y desconexiones de portales (local).", 90); s_gateOk = new CustomSyncedValue<bool>((ConditionalConfigSync)(object)s_sync, "vsm.adminportals.gate", false, 0, (IEqualityComparer<bool>)null); Log.LogInfo((object)("vsm.adminportals 0.1.4 | Valheim " + GameConstants.GameVersionString + " | headless=" + Headless.IsHeadless)); if (!Headless.IsHeadless) { VsmLocalization.Register(Log, Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), s_spanish); } _harmony = new Harmony("vsm.adminportals"); ServerPatchesOk = PatchUtil.PatchClassSafely(Log, _harmony, typeof(ServerPatches.FindRandomUnconnectedPortalPatch)) & PatchUtil.PatchClassSafely(Log, _harmony, typeof(ServerPatches.ConnectPortalsPatch)) & PatchUtil.PatchClassSafely(Log, _harmony, typeof(ServerPatches.GameStartPatch)); PatchUtil.PatchClassSafely(Log, _harmony, typeof(ClientPatches.TeleportPatch)); PatchUtil.PatchClassSafely(Log, _harmony, typeof(ClientPatches.TryPlacePiecePatch)); PatchUtil.PatchClassSafely(Log, _harmony, typeof(ClientPatches.HoverPatch)); PatchUtil.PatchClassSafely(Log, _harmony, typeof(ClientPatches.InteractPatch)); if (PatchUtil.IsDegraded) { Log.LogError((object)"vsm.adminportals: hay parches sin aplicar (ver arriba). Con noportals, los portales quedan bloqueados como en vanilla."); } } internal static void PublishGate() { if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer() && s_gateOk != null) { if (s_gateOk.Value != ServerPatchesOk) { s_gateOk.Value = ServerPatchesOk; } if (!ServerPatchesOk) { Log.LogError((object)"vsm.adminportals: faltan parches de servidor: con noportals ningún portal se conectará."); } } } private ConfigEntry<T> Bind<T>(string section, string key, T value, string description, int order) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown return ((BaseUnityPlugin)this).Config.Bind<T>(section, key, value, new ConfigDescription(description, (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = order } })); } private static ConfigEntry<T> Synced<T>(ConfigEntry<T> entry) { ((ConditionalConfigSync)s_sync).AddConfigEntry<T>(entry, (ConfigSyncMode)0); return entry; } private void OnDestroy() { if (_harmony != null) { _harmony.UnpatchSelf(); } } internal static void Verbose(string message) { if (VerboseLog != null && VerboseLog.Value && Log != null) { Log.LogInfo((object)("vsm.adminportals: " + message)); } } } internal static class ClientPatches { [HarmonyPatch(typeof(TeleportWorld), "Teleport", new Type[] { typeof(Player) })] internal static class TeleportPatch { [HarmonyPrefix] [HarmonyPriority(800)] private unsafe static bool Prefix(TeleportWorld __instance, Player player) { //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) if (!AdminPortalsPlugin.Active || (Object)(object)player == (Object)null) { return true; } try { if (!__instance.TargetFound()) { return true; } if (AdminPortalsPlugin.AdminOnlyTravel.Value && !AdminPortalsPlugin.LocalIsAdmin) { ((Character)player).Message((MessageType)2, "$vsm_adminportals_travel_adminonly", 0, (Sprite)null, false); return false; } float num = default(float); if (ZoneSystem.instance.GetGlobalKey((GlobalKeys)33) && (RandEventSystem.instance.GetBossEvent() != null || (ZoneSystem.instance.GetGlobalKey((GlobalKeys)47, ref num) && num > 0f))) { ((Character)player).Message((MessageType)2, "$msg_blockedbyboss", 0, (Sprite)null, false); return false; } if (!((Humanoid)player).IsTeleportable(__instance.m_allowAllItems)) { ((Character)player).Message((MessageType)2, "$msg_noteleport", 0, (Sprite)null, false); return false; } ZDO zDO = ZDOMan.instance.GetZDO(__instance.m_nview.GetZDO().GetConnectionZDOID((ConnectionType)1)); if (zDO == null) { return false; } Vector3 position = zDO.GetPosition(); Quaternion rotation = zDO.GetRotation(); Vector3 val = rotation * Vector3.forward; ((Character)player).TeleportTo(position + val * __instance.m_exitDistance + Vector3.up, rotation, true); Game.instance.IncrementPlayerStat((PlayerStatType)15, 1f, false); Vector3 val2 = position; AdminPortalsPlugin.Verbose("cruza un portal de admin hacia " + ((object)(*(Vector3*)(&val2))/*cast due to .constrained prefix*/).ToString()); return false; } catch (Exception ex) { AdminPortalsPlugin.Log.LogError((object)("vsm.adminportals: Teleport: " + ex.Message)); return true; } } } [HarmonyPatch(typeof(Player), "TryPlacePiece", new Type[] { typeof(Piece) })] internal static class TryPlacePiecePatch { [HarmonyPrefix] private static bool Prefix(Player __instance, Piece piece, ref bool __result) { try { if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || !Gate.RefusePlacement(AdminPortalsPlugin.Active, AdminPortalsPlugin.BlockNonAdminPlacement.Value, IsPortalPiece(piece), AdminPortalsPlugin.LocalIsAdmin)) { return true; } ((Character)__instance).Message((MessageType)2, "$vsm_adminportals_onlyadmin", 0, (Sprite)null, false); __result = false; return false; } catch (Exception ex) { AdminPortalsPlugin.Log.LogError((object)("vsm.adminportals: colocar: " + ex.Message)); return true; } } } [HarmonyPatch(typeof(TeleportWorld), "GetHoverText", new Type[] { })] internal static class HoverPatch { [HarmonyPostfix] private static void Postfix(TeleportWorld __instance, ref string __result) { try { if (AdminPortalsPlugin.Active && !__instance.HaveTarget()) { __result = __result + "\n" + Localization.instance.Localize("$vsm_adminportals_hover_off"); } } catch (Exception) { } } } [HarmonyPatch(typeof(TeleportWorld), "Interact", new Type[] { typeof(Humanoid), typeof(bool), typeof(bool) })] internal static class InteractPatch { [HarmonyPrefix] private static bool Prefix(Humanoid human, bool hold, ref bool __result) { if (hold || !AdminPortalsPlugin.Active || !AdminPortalsPlugin.LockTagsForNonAdmins.Value || AdminPortalsPlugin.LocalIsAdmin) { return true; } if ((Object)(object)human != (Object)null) { ((Character)human).Message((MessageType)2, "$vsm_adminportals_tag_locked", 0, (Sprite)null, false); } __result = true; return false; } } private static bool IsPortalPiece(Piece piece) { if ((Object)(object)piece == (Object)null) { return false; } if ((Object)(object)((Component)piece).GetComponentInChildren<TeleportWorld>(true) != (Object)null) { return true; } return (Object)(object)Game.instance != (Object)null && Game.instance.PortalPrefabHash.Contains(StringExtensionMethods.GetStableHashCode(Utils.GetPrefabName(((Component)piece).gameObject))); } } public static class Gate { public static bool IsAdminIndex(int creatorIndex, int historyCount, Func<int, bool> isAdminAt) { if (creatorIndex < 0 || creatorIndex >= historyCount || isAdminAt == null) { return false; } return isAdminAt(creatorIndex); } public static bool KeepPair(bool sourceIsAdmin, bool targetExists, bool targetIsAdmin) { return sourceIsAdmin && targetExists && targetIsAdmin; } public static bool RefusePlacement(bool gateActive, bool blockNonAdmins, bool isPortalPiece, bool localIsAdmin) { return gateActive && blockNonAdmins && isPortalPiece && !localIsAdmin; } } internal static class ServerPatches { [HarmonyPatch(typeof(Game), "FindRandomUnconnectedPortal", new Type[] { typeof(List<ZDO>), typeof(ZDO), typeof(string) })] internal static class FindRandomUnconnectedPortalPatch { [HarmonyPrefix] private static bool Prefix(Game __instance, List<ZDO> portals, ZDO skip, string tag, ref ZDO __result) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) if (!Applies) { return true; } try { __result = null; if (!IsAdminPortal(skip)) { return false; } List<ZDO> list = new List<ZDO>(); foreach (ZDO portal in portals) { if (portal != skip && portal.GetString(ZDOVars.s_tag, "") == tag && portal.GetConnectionZDOID((ConnectionType)1) == ZDOID.None && !__instance.IsCurrentlyConnectingPortal(portal) && IsAdminPortal(portal)) { list.Add(portal); } } if (list.Count > 0) { __result = list[Random.Range(0, list.Count)]; AdminPortalsPlugin.Verbose("empareja portales de admin con nombre '" + tag + "'"); } } catch (Exception ex) { AdminPortalsPlugin.Log.LogError((object)("vsm.adminportals: emparejar: " + ex.Message)); __result = null; } return false; } } [HarmonyPatch(typeof(Game), "ConnectPortals", new Type[] { })] internal static class ConnectPortalsPatch { [HarmonyPrefix] private static void Prefix() { s_adminByIndex.Clear(); } [HarmonyPostfix] private static void Postfix(Game __instance) { //IL_004a: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) if (!Applies || ZDOMan.instance == null) { return; } try { int num = 0; HashSet<ZDOID> hashSet = new HashSet<ZDOID>(); foreach (ZDO portal in ZDOMan.instance.GetPortalList()) { if (hashSet.Contains(portal.m_uid)) { continue; } ZDOID connectionZDOID = portal.GetConnectionZDOID((ConnectionType)1); if (((ZDOID)(ref connectionZDOID)).IsNone()) { continue; } ZDO zDO = ZDOMan.instance.GetZDO(connectionZDOID); if (!Gate.KeepPair(IsAdminPortal(portal), zDO != null, zDO != null && IsAdminPortal(zDO))) { __instance.SetConnection(portal, ZDOID.None, false); hashSet.Add(portal.m_uid); if (zDO != null && zDO.GetConnectionZDOID((ConnectionType)1) == portal.m_uid) { __instance.SetConnection(zDO, ZDOID.None, false); hashSet.Add(zDO.m_uid); } num++; } } if (num > 0) { AdminPortalsPlugin.Verbose("desconectados " + num + " portales que no son admin↔admin"); } } catch (Exception ex) { AdminPortalsPlugin.Log.LogError((object)("vsm.adminportals: revisar pares: " + ex.Message)); } } } [HarmonyPatch(typeof(Game), "Start")] internal static class GameStartPatch { [HarmonyPostfix] private static void Postfix() { AdminPortalsPlugin.PublishGate(); } } private static readonly Dictionary<int, bool> s_adminByIndex = new Dictionary<int, bool>(); private static bool Applies => (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && AdminPortalsPlugin.Active; internal static bool IsAdminPortal(ZDO portal) { if (portal == null) { return false; } World world = ZNet.World; if (world == null || world.m_playerHistory == null) { return false; } int num = portal.GetInt(ZDOVars.s_creatorIndex, -1); if (s_adminByIndex.TryGetValue(num, out var value)) { return value; } bool flag = Gate.IsAdminIndex(num, world.m_playerHistory.Count, (int i) => IsAdminId(world.m_playerHistory[i].m_id)); s_adminByIndex[num] = flag; return flag; } private unsafe static bool IsAdminId(PlatformUserID id) { //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) if (!ZNet.instance.IsDedicated() && UserInfo.GetLocalUser().UserId == id) { return true; } return ZNet.instance.IsAdmin(((object)(*(PlatformUserID*)(&id))/*cast due to .constrained prefix*/).ToString()); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "vsm.adminportals"; public const string PLUGIN_NAME = "MEL AdminPortals"; public const string PLUGIN_VERSION = "0.1.4"; } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class <977d6cca-7cff-4fb7-a12c-37e7012c14b1>IgnoresAccessChecksToAttribute : Attribute { public <977d6cca-7cff-4fb7-a12c-37e7012c14b1>IgnoresAccessChecksToAttribute(string assemblyName) { } } } namespace VSM.Core.Ui { internal static class VanillaStyle { public static TMP_Text TitleFont => ((Object)(object)InventoryGui.instance != (Object)null) ? InventoryGui.instance.m_playerName : null; public static TMP_Text BodyFont => (!((Object)(object)InventoryGui.instance != (Object)null)) ? null : (((Object)(object)InventoryGui.instance.m_armor != (Object)null) ? InventoryGui.instance.m_armor : InventoryGui.instance.m_playerName); public static Image FindBackground(Transform root, Transform exclude1, Transform exclude2) { //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)root == (Object)null) { return null; } Image result = null; float num = 0f; Image[] componentsInChildren = ((Component)root).GetComponentsInChildren<Image>(true); foreach (Image val in componentsInChildren) { if ((Object)(object)val == (Object)null || (Object)(object)val.sprite == (Object)null) { continue; } Transform transform = ((Component)val).transform; if ((!((Object)(object)exclude1 != (Object)null) || !transform.IsChildOf(exclude1)) && (!((Object)(object)exclude2 != (Object)null) || !transform.IsChildOf(exclude2))) { Rect rect = ((Graphic)val).rectTransform.rect; float num2 = Mathf.Abs(((Rect)(ref rect)).width * ((Rect)(ref rect)).height); if (num2 > num) { num = num2; result = val; } } } return result; } public static bool CopyImage(Image source, Image target) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target == (Object)null) { return false; } if ((Object)(object)source == (Object)null) { ((Graphic)target).color = new Color(0f, 0f, 0f, 0.6f); return false; } target.sprite = source.sprite; target.type = source.type; ((Graphic)target).material = ((Graphic)source).material; ((Graphic)target).color = ((Graphic)source).color; target.fillCenter = source.fillCenter; target.pixelsPerUnitMultiplier = source.pixelsPerUnitMultiplier; target.preserveAspect = false; return true; } public static Image InventoryBackground(Transform exclude) { InventoryGui instance = InventoryGui.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.m_player == (Object)null) { return null; } Transform exclude2 = (Transform)(object)(((Object)(object)instance.m_playerGrid != (Object)null) ? instance.m_playerGrid.m_gridRoot : null); return FindBackground((Transform)(object)instance.m_player, exclude2, exclude); } public static void CopyFont(TMP_Text source, TMP_Text target) { //IL_0037: 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) if (!((Object)(object)source == (Object)null) && !((Object)(object)target == (Object)null)) { target.font = source.font; target.fontSharedMaterial = source.fontSharedMaterial; ((Graphic)target).color = ((Graphic)source).color; target.fontStyle = source.fontStyle; } } public static TextMeshProUGUI NewText(Transform parent, string name, TMP_Text style, float size, TextAlignmentOptions align) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0041: 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(parent, false); TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>(); CopyFont(style, (TMP_Text)(object)val2); ((TMP_Text)val2).fontSize = size; ((TMP_Text)val2).alignment = align; ((Graphic)val2).raycastTarget = false; ((TMP_Text)val2).enableWordWrapping = false; ((TMP_Text)val2).richText = true; return val2; } } } namespace VSM.Core.Runtime { internal static class Headless { private static bool? s_isHeadless; public static bool IsHeadless { get { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 if (!s_isHeadless.HasValue) { s_isHeadless = (int)SystemInfo.graphicsDeviceType == 4 || Application.isBatchMode; } return s_isHeadless.Value; } } public static bool IsServerProcess => (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer(); public static bool IsDedicatedServer => (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && ZNet.instance.IsDedicated(); public static bool IsListenHost => (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && !ZNet.instance.IsDedicated(); public static bool IsRemoteClient => (Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer(); } internal static class Keys { public static bool Pressed(KeyboardShortcut shortcut) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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) KeyCode mainKey = ((KeyboardShortcut)(ref shortcut)).MainKey; return (int)mainKey != 0 && ZInput.GetKeyDown(mainKey, false) && ((KeyboardShortcut)(ref shortcut)).Modifiers.All((KeyCode m) => ZInput.GetKey(m, false)); } } } namespace VSM.Core.Reflection { internal static class GameConstants { private static uint? s_networkVersion; private static long? s_routedEverybody; public static uint NetworkVersion { get { if (!s_networkVersion.HasValue) { s_networkVersion = ReadConstant<uint>(typeof(Version), new string[2] { "c_networkVersion", "m_networkVersion" }); } return s_networkVersion.Value; } } public static long RoutedRpcEverybody { get { if (!s_routedEverybody.HasValue) { s_routedEverybody = ReadConstant<long>(typeof(ZRoutedRpc), new string[1] { "Everybody" }); } return s_routedEverybody.Value; } } public static string GameVersionString { get { //IL_0002: 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) try { return ((object)Version.CurrentVersion/*cast due to .constrained prefix*/).ToString(); } catch (Exception) { return "?"; } } } private static T ReadConstant<T>(Type type, params string[] names) where T : struct { foreach (string name in names) { FieldInfo field = type.GetField(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (!(field == null)) { object obj = (field.IsLiteral ? field.GetRawConstantValue() : field.GetValue(null)); if (obj is T result) { return result; } try { return (T)Convert.ChangeType(obj, typeof(T)); } catch (Exception) { } } } return default(T); } } } namespace VSM.Core.Net { internal static class ZPackageExt { public static bool HasMore(this ZPackage pkg) { return pkg != null && pkg.GetPos() < pkg.Size(); } public static int ReadIntOr(this ZPackage pkg, int fallback) { return pkg.HasMore() ? pkg.ReadInt() : fallback; } public static string ReadStringOr(this ZPackage pkg, string fallback) { return pkg.HasMore() ? pkg.ReadString() : fallback; } public static bool ReadBoolOr(this ZPackage pkg, bool fallback) { return pkg.HasMore() ? pkg.ReadBool() : fallback; } public static string ReadBoundedString(this ZPackage pkg, int maxLength) { string text = pkg.ReadString(); return (text != null && text.Length <= maxLength) ? text : null; } } } namespace VSM.Core.Localization { internal static class VsmLocalization { public static void Register(ManualLogSource log, string pluginDirectory, IDictionary<string, string> embeddedSpanish) { Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.Ordinal); if (embeddedSpanish != null) { foreach (KeyValuePair<string, string> item in embeddedSpanish) { dictionary[item.Key] = item.Value; } } string path = Path.Combine(pluginDirectory ?? string.Empty, "Translations"); MergeFile(log, Path.Combine(path, "Spanish.json"), dictionary); string text = SafeSelectedLanguage(); if (!string.Equals(text, "Spanish", StringComparison.OrdinalIgnoreCase)) { MergeFile(log, Path.Combine(path, text + ".json"), dictionary); } Apply(log, dictionary); } public static string Localize(string token, params object[] args) { string text = token; try { if (Localization.instance != null && !string.IsNullOrEmpty(token)) { bool flag = token[0] != '$' && token.IndexOf(' ') < 0 && token.IndexOf('\n') < 0; string text2 = Localization.instance.Localize(flag ? ("$" + token) : token); text = ((flag && text2.Length > 1 && text2[0] == '[' && text2[text2.Length - 1] == ']') ? token : text2); } } catch (Exception) { text = token; } if (args != null && args.Length != 0) { try { text = string.Format(text, args); } catch (FormatException) { } } return text; } private static string SafeSelectedLanguage() { try { return (Localization.instance != null) ? Localization.instance.GetSelectedLanguage() : "Spanish"; } catch (Exception) { return "Spanish"; } } private static void Apply(ManualLogSource log, Dictionary<string, string> words) { if (Localization.instance == null) { if (log != null) { log.LogWarning((object)"Localization.instance aún no existe; las traducciones no se han aplicado."); } return; } foreach (KeyValuePair<string, string> word in words) { string text = (word.Key.StartsWith("$", StringComparison.Ordinal) ? word.Key.Substring(1) : word.Key); Localization.instance.AddWord(text, word.Value); } } private static void MergeFile(ManualLogSource log, string path, Dictionary<string, string> into) { if (!File.Exists(path)) { return; } try { foreach (KeyValuePair<string, string> item in ParseFlatJson(File.ReadAllText(path, Encoding.UTF8))) { into[item.Key] = item.Value; } } catch (Exception ex) { if (log != null) { log.LogWarning((object)("No se pudo leer " + path + ": " + ex.Message)); } } } public static Dictionary<string, string> ParseFlatJson(string json) { Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.Ordinal); if (string.IsNullOrEmpty(json)) { return dictionary; } int i = 0; SkipWs(json, ref i); if (i >= json.Length || json[i] != '{') { return dictionary; } i++; while (true) { SkipWs(json, ref i); if (i >= json.Length || json[i] == '}') { break; } if (json[i] == ',') { i++; continue; } string text = ReadString(json, ref i); if (text == null) { i++; continue; } SkipWs(json, ref i); if (i < json.Length && json[i] == ':') { i++; } SkipWs(json, ref i); if (i < json.Length && json[i] == '"') { string text2 = ReadString(json, ref i); dictionary[text] = text2 ?? string.Empty; } else { for (; i < json.Length && json[i] != ',' && json[i] != '}'; i++) { } } } return dictionary; } private static void SkipWs(string s, ref int i) { while (i < s.Length && char.IsWhiteSpace(s[i])) { i++; } } private static string ReadString(string s, ref int i) { if (i >= s.Length || s[i] != '"') { return null; } i++; StringBuilder stringBuilder = new StringBuilder(); while (i < s.Length) { char c = s[i++]; switch (c) { case '"': return stringBuilder.ToString(); case '\\': { if (i >= s.Length) { break; } char c2 = s[i++]; switch (c2) { case 'n': stringBuilder.Append('\n'); break; case 't': stringBuilder.Append('\t'); break; case 'r': stringBuilder.Append('\r'); break; case 'b': stringBuilder.Append('\b'); break; case 'f': stringBuilder.Append('\f'); break; case 'u': if (i + 4 <= s.Length) { stringBuilder.Append((char)Convert.ToInt32(s.Substring(i, 4), 16)); i += 4; } break; default: stringBuilder.Append(c2); break; } continue; } } stringBuilder.Append(c); } return stringBuilder.ToString(); } } } namespace VSM.Core.Harmony { internal static class PatchUtil { private static readonly List<string> s_failed = new List<string>(); public static IReadOnlyList<string> FailedTargets => s_failed; public static bool IsDegraded => s_failed.Count > 0; public static MethodInfo DeclaredMethodOrNull(ManualLogSource log, Type type, string name, Type[] parameters, string owner) { if (type == null) { Fail(log, owner, name + " (tipo nulo)"); return null; } MethodInfo methodInfo = AccessTools.DeclaredMethod(type, name, parameters, (Type[])null); if (methodInfo == null) { Fail(log, owner, type.FullName + "." + name + "(" + Describe(parameters) + ")"); } return methodInfo; } public static void PatchAllSafely(ManualLogSource log, Harmony harmony, Assembly assembly) { Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(assembly); foreach (Type type in typesFromAssembly) { if (type.GetCustomAttributes(typeof(HarmonyPatch), inherit: true).Length != 0) { PatchClassSafely(log, harmony, type); } } } public static bool PatchClassSafely(ManualLogSource log, Harmony harmony, Type patchClass) { try { harmony.CreateClassProcessor(patchClass).Patch(); return true; } catch (Exception ex) { Fail(log, harmony.Id, patchClass.FullName + " -> " + ex.GetType().Name + ": " + ex.Message); return false; } } private static void Fail(ManualLogSource log, string owner, string what) { s_failed.Add(what); if (log != null) { log.LogError((object)("[" + owner + "] No se pudo aplicar el parche (¿cambió el juego?): " + what + ". El mod sigue cargado en modo degradado.")); } } private static string Describe(Type[] parameters) { if (parameters == null || parameters.Length == 0) { return string.Empty; } string[] array = new string[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { array[i] = ((parameters[i] == null) ? "?" : parameters[i].Name); } return string.Join(", ", array); } } } namespace VSM.Core.Config { internal sealed class ConfigurationManagerAttributes { public bool? ShowRangeAsPercent; public Action<ConfigEntryBase> CustomDrawer; public bool? Browsable; public string Category; public object DefaultValue; public bool? HideDefaultButton; public bool? HideSettingName; public string Description; public string DispName; public int? Order; public bool? ReadOnly; public bool? IsAdvanced; public bool? IsAdminOnly; public Func<object, string> ObjToStr; public Func<string, object> StrToObj; } } namespace VSM.Core.Camera { internal struct RigSettings { public float Speed; public float FastMultiplier; public bool MoveRelativeToView; } internal sealed class CameraRig { public const float MaxPitch = 89f; public float Yaw; public float Pitch; public Vector3 Position; public Vector3 Velocity; public Vector3 ForwardVector => Forward(Yaw, Pitch); public Quaternion Rotation => Quaternion.Euler(Pitch, Yaw, 0f); public static Vector3 Forward(float yawDeg, float pitchDeg) { //IL_002f: 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) //IL_0037: Unknown result type (might be due to invalid IL or missing references) float num = yawDeg * ((float)Math.PI / 180f); float num2 = pitchDeg * ((float)Math.PI / 180f); float num3 = Mathf.Cos(num2); return new Vector3(Mathf.Sin(num) * num3, 0f - Mathf.Sin(num2), Mathf.Cos(num) * num3); } public static Vector3 FlatForward(float yawDeg) { //IL_001a: 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_0022: Unknown result type (might be due to invalid IL or missing references) float num = yawDeg * ((float)Math.PI / 180f); return new Vector3(Mathf.Sin(num), 0f, Mathf.Cos(num)); } public static Vector3 Right(float yawDeg) { //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_0023: Unknown result type (might be due to invalid IL or missing references) float num = yawDeg * ((float)Math.PI / 180f); return new Vector3(Mathf.Cos(num), 0f, 0f - Mathf.Sin(num)); } public void Reset(Vector3 position, Vector3 forward) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) Position = position; Velocity = Vector3.zero; SetFromDirection(forward); } public void SetFromDirection(Vector3 forward) { //IL_0035: 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_005c: Unknown result type (might be due to invalid IL or missing references) if (((Vector3)(ref forward)).sqrMagnitude < 1E-08f) { Yaw = 0f; Pitch = 0f; } else { ((Vector3)(ref forward)).Normalize(); Yaw = Mathf.Repeat(Mathf.Atan2(forward.x, forward.z) * 57.29578f, 360f); Pitch = Mathf.Clamp((0f - Mathf.Asin(Mathf.Clamp(forward.y, -1f, 1f))) * 57.29578f, -89f, 89f); } } public void ApplyLook(Vector2 delta) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) Yaw = Mathf.Repeat(Yaw + delta.x, 360f); Pitch = Mathf.Clamp(Pitch - delta.y, -89f, 89f); } public Vector3 DesiredVelocity(Vector3 move, float vertical, bool fast, RigSettings settings) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //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_0083: 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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: 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_00df: 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) Vector3 val = (settings.MoveRelativeToView ? Forward(Yaw, Pitch) : FlatForward(Yaw)); Vector3 val2 = Right(Yaw) * Mathf.Clamp(move.x, -1f, 1f) + val * Mathf.Clamp(move.z, -1f, 1f) + Vector3.up * Mathf.Clamp(vertical, -1f, 1f); if (((Vector3)(ref val2)).sqrMagnitude > 1f) { ((Vector3)(ref val2)).Normalize(); } float num = Mathf.Max(0f, settings.Speed) * (fast ? Mathf.Max(1f, settings.FastMultiplier) : 1f); return val2 * num; } public void Integrate(Vector3 desiredVelocity, float dt, float smoothing) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0047: 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) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) if (!(dt <= 0f)) { float num = ((smoothing <= 0f) ? 1f : (1f - Mathf.Exp((0f - dt) / smoothing))); Velocity = Vector3.Lerp(Velocity, desiredVelocity, num); Position += Velocity * dt; } } public static Vector3 ClampToSphere(Vector3 pos, Vector3 center, float radius) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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) Vector3 val = pos - center; float num = Mathf.Max(0f, radius); if (((Vector3)(ref val)).sqrMagnitude <= num * num) { return pos; } return center + ((Vector3)(ref val)).normalized * num; } } internal static class CameraWorld { public const float CollisionRadius = 0.25f; public static Vector3 Anchor(Player player) { //IL_0033: 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_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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) Transform eye = ((Character)player).m_eye; return ((Object)(object)eye != (Object)null) ? eye.position : (((Component)player).transform.position + Vector3.up * 1.6f); } public static Vector3 Constrain(Vector3 from, Vector3 to, Vector3 anchor, float maxDistance, float clearance, GameCamera cam) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0038: 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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) Vector3 pos = CameraRig.ClampToSphere(to, anchor, maxDistance); pos = Lift(pos, clearance, cam); pos = CameraRig.ClampToSphere(pos, anchor, maxDistance + 1f); LayerMask blockCameraMask = cam.m_blockCameraMask; Vector3 val = (Overlaps(from, blockCameraMask) ? anchor : from); return Collide(val, pos, blockCameraMask); } public static Vector3 Lift(Vector3 pos, float clearance, GameCamera cam) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) clearance = Mathf.Max(0f, clearance); ZoneSystem instance = ZoneSystem.instance; float num = default(float); if ((Object)(object)instance != (Object)null && instance.GetGroundHeight(pos, ref num)) { pos.y = Mathf.Max(pos.y, num + clearance); } float num2 = Floating.GetLiquidLevel(pos, 1f, (LiquidType)10); if ((Object)(object)instance != (Object)null && !Character.InInterior(pos)) { num2 = Mathf.Max(num2, instance.m_waterLevel); } if (num2 > -9000f) { pos.y = Mathf.Max(pos.y, num2 + Mathf.Max(clearance, cam.m_minWaterDistance)); } return pos; } public static bool Overlaps(Vector3 pos, LayerMask mask) { //IL_0001: 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) return Physics.CheckSphere(pos, 0.225f, LayerMask.op_Implicit(mask), (QueryTriggerInteraction)1); } public static Vector3 Collide(Vector3 from, Vector3 to, LayerMask mask) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0033: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) Vector3 val = to - from; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude < 1E-05f) { return to; } Vector3 val2 = val / magnitude; RaycastHit val3 = default(RaycastHit); if (Physics.SphereCast(from, 0.25f, val2, ref val3, magnitude, LayerMask.op_Implicit(mask), (QueryTriggerInteraction)1)) { return from + val2 * Mathf.Max(0f, ((RaycastHit)(ref val3)).distance - 0.02f); } return to; } } internal static class CameraLock { private const string Prefix = "vsm_camera_lock:"; public static string Holder() { GameCamera instance = GameCamera.instance; if ((Object)(object)instance == (Object)null) { return null; } Transform transform = ((Component)instance).transform; for (int i = 0; i < transform.childCount; i++) { string name = ((Object)transform.GetChild(i)).name; if (name.StartsWith("vsm_camera_lock:", StringComparison.Ordinal)) { return name.Substring("vsm_camera_lock:".Length); } } return null; } public static bool TryAcquire(string owner) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown GameCamera instance = GameCamera.instance; if ((Object)(object)instance == (Object)null) { return false; } string text = Holder(); if (text != null) { return text == owner; } GameObject val = new GameObject("vsm_camera_lock:" + owner); val.transform.SetParent(((Component)instance).transform, false); return true; } public static void Release(string owner) { GameCamera instance = GameCamera.instance; if ((Object)(object)instance == (Object)null) { return; } Transform transform = ((Component)instance).transform; for (int num = transform.childCount - 1; num >= 0; num--) { Transform child = transform.GetChild(num); if (((Object)child).name == "vsm_camera_lock:" + owner) { Object.Destroy((Object)(object)((Component)child).gameObject); ((Object)child).name = "vsm_camera_lock_released"; } } } } internal sealed class BodyHider { private readonly List<Renderer> _hidden = new List<Renderer>(); private float _nextScan; public void Update(Player player, bool hide) { if (!hide || (Object)(object)player == (Object)null) { Restore(); } else { if (Time.unscaledTime < _nextScan) { return; } _nextScan = Time.unscaledTime + 0.5f; Renderer[] componentsInChildren = ((Component)player).GetComponentsInChildren<Renderer>(false); foreach (Renderer val in componentsInChildren) { if ((Object)(object)val != (Object)null && val.enabled && (val is SkinnedMeshRenderer || val is MeshRenderer)) { val.enabled = false; _hidden.Add(val); } } } } public void Restore() { foreach (Renderer item in _hidden) { if ((Object)(object)item != (Object)null) { item.enabled = true; } } _hidden.Clear(); _nextScan = 0f; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }
plugins/VSM.Arrows/VSM.Arrows.dll
Decompiled 3 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ConditionalConfigSync; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.UI; using VSM.Core.Config; using VSM.Core.Harmony; using VSM.Core.Reflection; using VSM.Core.Runtime; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: <7734a844-bde8-4f04-b0d4-94c0f4e57bbe>IgnoresAccessChecksTo("assembly_guiutils")] [assembly: <7734a844-bde8-4f04-b0d4-94c0f4e57bbe>IgnoresAccessChecksTo("assembly_utils")] [assembly: <7734a844-bde8-4f04-b0d4-94c0f4e57bbe>IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("VSM.Arrows")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("0.1.4.0")] [assembly: AssemblyInformationalVersion("0.1.4+ff27bc889ccf218c61c45d3417d48ab708a5ba8f")] [assembly: AssemblyProduct("VSM.Arrows")] [assembly: AssemblyTitle("VSM.Arrows")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.4.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace VSM.Arrows { internal static class ArrowCapture { private const float RayBack = 0.6f; private const float RayLength = 1.6f; private const float MaxBoneDistance = 0.4f; private const float MaxFromAxis = 0.05f; private const float BodyRadius = 0.07f; private const float ShieldSink = 0.03f; public static void OnHit(Projectile projectile, Collider collider) { try { StickMessage stickMessage = Build(projectile, collider); if (stickMessage != null) { ArrowNet.Broadcast(stickMessage); } } catch (Exception ex) { ArrowsPlugin.Log.LogWarning((object)("vsm.arrows: no se pudo clavar la flecha: " + ex.Message)); } } private static StickMessage Build(Projectile projectile, Collider collider) { //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_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_011a: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0176: 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_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) if (!ArrowsPlugin.Active || (Object)(object)projectile == (Object)null || (Object)(object)collider == (Object)null) { return null; } if (!IsArrow(projectile)) { return null; } GameObject val = Projectile.FindHitObject(collider); Character val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<Character>() : null); if ((Object)(object)val2 == (Object)null || val2.IsDead() || (!val2.IsPlayer() && !ArrowsPlugin.Creatures.Value)) { return null; } ZNetView component = ((Component)val2).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return null; } Transform transform = ((Component)projectile).transform; Vector3 forward = transform.forward; if (projectile.m_dodgeable && val2.IsDodgeInvincible()) { return null; } int stableHashCode = StringExtensionMethods.GetStableHashCode(Utils.GetPrefabName(((Component)projectile).gameObject)); Vector3 origin = transform.position - forward * 0.6f; if (projectile.m_blockable && val2.IsBlocking() && Vector3.Dot(forward, ((Component)val2).transform.forward) <= 0f) { return ArrowsPlugin.Shields.Value ? OnShield(val2, component, stableHashCode, origin, forward) : null; } return OnBody(val2, component, stableHashCode, origin, forward); } private static bool IsArrow(Projectile p) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Invalid comparison between Unknown and I4 //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Invalid comparison between Unknown and I4 if (p.m_attachToClosestBone || p.m_attachToRigidBody || p.m_aoe > 0f) { return false; } if ((int)p.m_skill == 8 || (int)p.m_skill == 14) { return true; } return p.m_damage.m_pierce > 0f && p.m_spawnItem == null && !p.m_respawnItemOnHit; } private static float SizeFactor(Character target) { if (target.IsPlayer()) { return 1f; } float num = (((Object)(object)Player.m_localPlayer != (Object)null) ? ((Character)Player.m_localPlayer).GetRadius() : 0.4f); return (num > 0.01f) ? Mathf.Clamp(target.GetRadius() / num, 1f, 6f) : 1f; } private static StickMessage OnBody(Character target, ZNetView nview, int projectileHash, Vector3 origin, Vector3 dir) { //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) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0075: 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_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: 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) float num = SizeFactor(target); Vector3 onRay; Vector3 onBone; float distance; Transform val = ArrowRig.ClosestBone(ArrowRig.Bones(target), origin, dir, 1.6f * num, out onRay, out onBone, out distance); if ((Object)(object)val == (Object)null || distance > 0.4f * num || !StickMessage.IsBoneName(((Object)val).name)) { return null; } Vector3 val2 = StickGeometry.PullToward(onRay, onBone, 0.05f * num); Vector3 val3 = val2 - dir * (0.07f * num); return new StickMessage { Target = nview.GetZDO().m_uid, ProjectileHash = projectileHash, Mode = StickMode.Body, Bone = ((Object)val).name, LocalPosition = val.InverseTransformPoint(val3), LocalRotation = Quaternion.Inverse(val.rotation) * Quaternion.LookRotation(dir) }; } private static StickMessage OnShield(Character target, ZNetView nview, int projectileHash, Vector3 origin, Vector3 dir) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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_0048: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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_0067: 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_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: 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_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: 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_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: 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_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010b: 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_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015c: 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_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) GameObject instance; int num = ArrowRig.ShieldHash(target, out instance); MeshFilter val = ArrowRig.ShieldMesh(instance); if (num == 0 || (Object)(object)val == (Object)null) { return null; } Transform transform = ((Component)val).transform; Bounds bounds = val.sharedMesh.bounds; Vector3 val2 = transform.InverseTransformPoint(origin); Vector3 dir2 = transform.InverseTransformPoint(origin + dir) - val2; Vector3 val3; if (StickGeometry.RayBox(val2, dir2, ((Bounds)(ref bounds)).min, ((Bounds)(ref bounds)).max, out var tEnter) && tEnter <= 1.6f) { val3 = origin + dir * tEnter; } else { Vector3 val4 = transform.TransformPoint(((Bounds)(ref bounds)).center); Vector3 val5 = origin + dir * Mathf.Max(0f, Vector3.Dot(val4 - origin, dir)); val3 = transform.TransformPoint(StickGeometry.ClampToBox(transform.InverseTransformPoint(val5), ((Bounds)(ref bounds)).min, ((Bounds)(ref bounds)).max)); } Vector3 val6 = val3 + dir * 0.03f; return new StickMessage { Target = nview.GetZDO().m_uid, ProjectileHash = projectileHash, Mode = StickMode.Shield, ShieldHash = num, LocalPosition = transform.InverseTransformPoint(val6), LocalRotation = Quaternion.Inverse(transform.rotation) * Quaternion.LookRotation(dir) }; } } internal static class ArrowNet { public const string Stick = "VSM_Arrows_Stick"; private const int MaxPerSecondPerSender = 30; private static ZRoutedRpc s_registeredFor; private static readonly Dictionary<long, KeyValuePair<float, int>> s_rate = new Dictionary<long, KeyValuePair<float, int>>(); public static void Register() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null && instance != s_registeredFor) { instance.Register<ZPackage>("VSM_Arrows_Stick", (Action<long, ZPackage>)RPC_Stick); s_registeredFor = instance; s_rate.Clear(); } } public static void Broadcast(StickMessage msg) { if (ZRoutedRpc.instance != null && msg != null) { ZRoutedRpc.instance.InvokeRoutedRPC(GameConstants.RoutedRpcEverybody, "VSM_Arrows_Stick", new object[1] { msg.Write() }); } } private static void RPC_Stick(long sender, ZPackage pkg) { if (Headless.IsHeadless || !ArrowsPlugin.Active || !Allow(sender)) { return; } try { StickMessage stickMessage = StickMessage.Read(pkg); if (stickMessage != null) { StuckArrows.Apply(stickMessage); } } catch (Exception ex) { ArrowsPlugin.Log.LogWarning((object)("vsm.arrows: aviso de flecha inválido de " + sender + ": " + ex.Message)); } } private static bool Allow(long sender) { float unscaledTime = Time.unscaledTime; if (!s_rate.TryGetValue(sender, out var value) || unscaledTime - value.Key >= 1f) { value = new KeyValuePair<float, int>(unscaledTime, 0); } if (value.Value >= 30) { return false; } s_rate[sender] = new KeyValuePair<float, int>(value.Key, value.Value + 1); return true; } } internal static class ArrowRig { public static Transform[] Bones(Character character) { if ((Object)(object)character == (Object)null) { return null; } VisEquipment component = ((Component)character).GetComponent<VisEquipment>(); if ((Object)(object)component != (Object)null && (Object)(object)component.m_bodyModel != (Object)null && HasBones(component.m_bodyModel)) { return component.m_bodyModel.bones; } SkinnedMeshRenderer val = null; SkinnedMeshRenderer[] componentsInChildren = ((Component)character).GetComponentsInChildren<SkinnedMeshRenderer>(); foreach (SkinnedMeshRenderer val2 in componentsInChildren) { if (HasBones(val2) && ((Object)(object)val == (Object)null || val2.bones.Length > val.bones.Length)) { val = val2; } } return ((Object)(object)val != (Object)null) ? val.bones : null; } public static Transform FindBone(Character character, string name) { Transform[] array = Bones(character); if (array == null || string.IsNullOrEmpty(name)) { return null; } Transform[] array2 = array; foreach (Transform val in array2) { if ((Object)(object)val != (Object)null && ((Object)val).name == name) { return val; } } return null; } public static Transform ClosestBone(Transform[] bones, Vector3 origin, Vector3 dir, float length, out Vector3 onRay, out Vector3 onBone, out float distance) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000b: 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_006b: Unknown result type (might be due to invalid IL or missing references) //IL_006c: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: 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_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: 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_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: 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_010c: Unknown result type (might be due to invalid IL or missing references) //IL_010e: 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_0117: Unknown result type (might be due to invalid IL or missing references) onRay = origin; onBone = origin; distance = float.MaxValue; if (bones == null) { return null; } HashSet<Transform> hashSet = new HashSet<Transform>(); foreach (Transform val in bones) { if ((Object)(object)val != (Object)null) { hashSet.Add(val); } } Vector3 q = origin + dir * length; Transform val2 = null; float num = float.MaxValue; foreach (Transform item in hashSet) { Transform val3 = (((Object)(object)item.parent != (Object)null && hashSet.Contains(item.parent)) ? item.parent : item); Vector3 position = val3.position; Vector3 position2 = item.position; float s; float t; Vector3 c; Vector3 c2; float num2 = StickGeometry.ClosestSegmentSegment(origin, q, position, position2, out s, out t, out c, out c2); if (num2 < num) { num = num2; val2 = ((t >= 0.98f) ? item : val3); onRay = c; onBone = c2; } } distance = (((Object)(object)val2 != (Object)null) ? Mathf.Sqrt(num) : float.MaxValue); return val2; } public static int ShieldHash(Character character, out GameObject instance) { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Invalid comparison between Unknown and I4 instance = null; VisEquipment val = (((Object)(object)character != (Object)null) ? ((Component)character).GetComponent<VisEquipment>() : null); if ((Object)(object)val == (Object)null || (Object)(object)val.m_leftItemInstance == (Object)null || val.m_currentLeftItemHash == 0 || (Object)(object)ObjectDB.instance == (Object)null) { return 0; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(val.m_currentLeftItemHash); ItemDrop val2 = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent<ItemDrop>() : null); if ((Object)(object)val2 == (Object)null || val2.m_itemData == null || val2.m_itemData.m_shared == null || (int)val2.m_itemData.m_shared.m_itemType != 5) { return 0; } instance = val.m_leftItemInstance; return val.m_currentLeftItemHash; } public static MeshFilter ShieldMesh(GameObject shield) { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)shield == (Object)null) { return null; } MeshFilter val = null; float num = 0f; MeshFilter[] componentsInChildren = shield.GetComponentsInChildren<MeshFilter>(); foreach (MeshFilter val2 in componentsInChildren) { MeshRenderer component = ((Component)val2).GetComponent<MeshRenderer>(); if (!((Object)(object)val2.sharedMesh == (Object)null) && !((Object)(object)component == (Object)null) && ((Renderer)component).enabled) { Bounds bounds = val2.sharedMesh.bounds; Vector3 val3 = Vector3.Scale(((Bounds)(ref bounds)).size, ((Component)val2).transform.lossyScale); float num2 = Mathf.Abs(val3.x * val3.y * val3.z) + ((Vector3)(ref val3)).sqrMagnitude * 0.0001f; if ((Object)(object)val == (Object)null || num2 > num) { val = val2; num = num2; } } } return val; } private static bool HasBones(SkinnedMeshRenderer smr) { return (Object)(object)smr != (Object)null && smr.bones != null && smr.bones.Length != 0; } } internal static class ArrowsPatches { [HarmonyPatch(typeof(Game), "Start")] private static class GameStartPatch { [HarmonyPostfix] private static void Postfix() { ArrowNet.Register(); } } [HarmonyPatch(typeof(Projectile), "OnHit", new Type[] { typeof(Collider), typeof(Vector3), typeof(bool), typeof(Vector3) })] private static class ProjectileOnHitPatch { [HarmonyPrefix] private static void Prefix(Projectile __instance, out bool __state) { __state = __instance.m_didHit; } [HarmonyPostfix] private static void Postfix(Projectile __instance, Collider collider, bool water, bool __state) { if (!__state && !water && (Object)(object)collider != (Object)null && __instance.m_didHit) { ArrowCapture.OnHit(__instance, collider); } } } } [BepInPlugin("vsm.arrows", "MEL Flechas", "0.1.4")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class ArrowsPlugin : BaseUnityPlugin { internal static ManualLogSource Log; private static ConfigSync s_sync; private Harmony _harmony; public static ConfigEntry<bool> Enabled; public static ConfigEntry<float> StuckSeconds; public static ConfigEntry<int> MaxPerCharacter; public static ConfigEntry<bool> Shields; public static ConfigEntry<bool> Creatures; public static ConfigEntry<bool> ServerLock; public static bool IsConfigReady => s_sync != null && (((ConditionalConfigSync)s_sync).IsSourceOfTruth || ((ConditionalConfigSync)s_sync).InitialSyncDone); public static bool Active => Enabled != null && Enabled.Value && IsConfigReady; private void Awake() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0044: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Expected O, but got Unknown //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Expected O, but got Unknown //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Expected O, but got Unknown //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Expected O, but got Unknown //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; s_sync = new ConfigSync("vsm.arrows") { DisplayName = "MEL Flechas", CurrentVersion = "0.1.4", MinimumRequiredVersion = "0.1.4", ModRequired = true }; Enabled = Synced<bool>(((BaseUnityPlugin)this).Config.Bind<bool>("1. General (servidor)", "Enabled", true, new ConfigDescription("Las flechas que pegan a un jugador se quedan clavadas donde entraron.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 100 } }))); StuckSeconds = Synced<float>(((BaseUnityPlugin)this).Config.Bind<float>("1. General (servidor)", "StuckSeconds", 60f, new ConfigDescription("Segundos que una flecha queda clavada antes de caerse.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 600f), new object[1] { new ConfigurationManagerAttributes { Order = 99 } }))); MaxPerCharacter = Synced<int>(((BaseUnityPlugin)this).Config.Bind<int>("1. General (servidor)", "MaxPerCharacter", 12, new ConfigDescription("Máximo de flechas clavadas a la vez en un mismo personaje (cuerpo y escudo); al pasarse se cae la más vieja.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 40), new object[1] { new ConfigurationManagerAttributes { Order = 98 } }))); Shields = Synced<bool>(((BaseUnityPlugin)this).Config.Bind<bool>("1. General (servidor)", "Shields", true, new ConfigDescription("Si el jugador bloquea de frente con escudo, la flecha queda clavada en el escudo.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 97 } }))); Creatures = Synced<bool>(((BaseUnityPlugin)this).Config.Bind<bool>("1. General (servidor)", "Creatures", false, new ConfigDescription("También en las criaturas (no solo en los jugadores).", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 96 } }))); ServerLock = ((BaseUnityPlugin)this).Config.Bind<bool>("1. General (servidor)", "ServerLock", true, "Bloquea la configuración sincronizada: solo los administradores del servidor pueden cambiarla."); ((ConditionalConfigSync)s_sync).AddLockingConfigEntry<bool>(ServerLock); Log.LogInfo((object)("vsm.arrows 0.1.4 | Valheim " + GameConstants.GameVersionString + " | headless=" + Headless.IsHeadless)); _harmony = new Harmony("vsm.arrows"); PatchUtil.PatchAllSafely(Log, _harmony, Assembly.GetExecutingAssembly()); if (PatchUtil.IsDegraded) { Log.LogError((object)"vsm.arrows: hay parches sin aplicar (ver arriba)."); } } private static ConfigEntry<T> Synced<T>(ConfigEntry<T> entry) { ((ConditionalConfigSync)s_sync).AddConfigEntry<T>(entry, (ConfigSyncMode)0); return entry; } private void OnDestroy() { ArrowVisuals.Clear(); if (_harmony != null) { _harmony.UnpatchSelf(); } } } internal static class ArrowVisuals { private static readonly Dictionary<int, GameObject> s_templates = new Dictionary<int, GameObject>(); private static GameObject s_root; public static GameObject Create(int projectileHash) { GameObject val = Template(projectileHash); if ((Object)(object)val == (Object)null) { return null; } GameObject val2 = Object.Instantiate<GameObject>(val); ((Object)val2).name = "vsm_arrow_stuck"; return val2; } public static void Clear() { s_templates.Clear(); if ((Object)(object)s_root != (Object)null) { Object.Destroy((Object)(object)s_root); s_root = null; } } private static GameObject Template(int projectileHash) { if (s_templates.TryGetValue(projectileHash, out var value)) { return value; } if ((Object)(object)ZNetScene.instance == (Object)null) { return null; } GameObject prefab = ZNetScene.instance.GetPrefab(projectileHash); if ((Object)(object)prefab == (Object)null) { return null; } value = Build(prefab); s_templates[projectileHash] = value; if ((Object)(object)value == (Object)null) { ArrowsPlugin.Log.LogWarning((object)("vsm.arrows: el proyectil '" + ((Object)prefab).name + "' no tiene malla que clavar.")); } return value; } private static GameObject Build(GameObject prefab) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown Projectile component = prefab.GetComponent<Projectile>(); if ((Object)(object)component == (Object)null) { return null; } if ((Object)(object)s_root == (Object)null) { s_root = new GameObject("vsm_arrows_templates"); s_root.SetActive(false); Object.DontDestroyOnLoad((Object)(object)s_root); } Transform visual = (((Object)(object)component.m_visual != (Object)null) ? component.m_visual.transform : null); Transform val = (((Object)(object)component.m_hideOnHit != (Object)null) ? component.m_hideOnHit.transform : null); GameObject val2 = Copy(prefab, visual, val); if ((Object)(object)val2 == (Object)null && (Object)(object)val != (Object)null) { val2 = Copy(prefab, visual, null); } return val2; } private static GameObject Copy(GameObject prefab, Transform visual, Transform hidden) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("vsm_arrow_" + ((Object)prefab).name); val.transform.SetParent(s_root.transform, false); val.transform.localScale = prefab.transform.localScale; val.layer = prefab.layer; int meshes = 0; CopyChildren(prefab.transform, val.transform, (Object)(object)visual == (Object)null || (Object)(object)visual == (Object)(object)prefab.transform, visual, hidden, ref meshes); if (meshes == 0) { Object.DestroyImmediate((Object)(object)val); return null; } return val; } private static void CopyChildren(Transform source, Transform target, bool insideVisual, Transform visual, Transform hidden, ref int meshes) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0084: 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_011a: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < source.childCount; i++) { Transform child = source.GetChild(i); if (!((Component)child).gameObject.activeSelf || (Object)(object)child == (Object)(object)hidden) { continue; } bool flag = insideVisual || (Object)(object)child == (Object)(object)visual; GameObject val = new GameObject(((Object)child).name); val.layer = ((Component)child).gameObject.layer; Transform transform = val.transform; transform.SetParent(target, false); transform.localPosition = child.localPosition; transform.localRotation = child.localRotation; transform.localScale = child.localScale; if (flag) { MeshFilter component = ((Component)child).GetComponent<MeshFilter>(); MeshRenderer component2 = ((Component)child).GetComponent<MeshRenderer>(); if ((Object)(object)component != (Object)null && (Object)(object)component2 != (Object)null && ((Renderer)component2).enabled && (Object)(object)component.sharedMesh != (Object)null) { val.AddComponent<MeshFilter>().sharedMesh = component.sharedMesh; MeshRenderer val2 = val.AddComponent<MeshRenderer>(); ((Renderer)val2).sharedMaterials = ((Renderer)component2).sharedMaterials; ((Renderer)val2).shadowCastingMode = ((Renderer)component2).shadowCastingMode; ((Renderer)val2).receiveShadows = ((Renderer)component2).receiveShadows; meshes++; } } CopyChildren(child, transform, flag, visual, hidden, ref meshes); } } } public static class StickGeometry { public static float ClosestSegmentSegment(Vector3 p1, Vector3 q1, Vector3 p2, Vector3 q2, out float s, out float t, out Vector3 c1, out Vector3 c2) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: 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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017c: 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_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) Vector3 val = q1 - p1; Vector3 val2 = q2 - p2; Vector3 val3 = p1 - p2; float num = Vector3.Dot(val, val); float num2 = Vector3.Dot(val2, val2); float num3 = Vector3.Dot(val2, val3); if (num <= 1E-08f && num2 <= 1E-08f) { s = 0f; t = 0f; } else if (num <= 1E-08f) { s = 0f; t = Clamp01(num3 / num2); } else { float num4 = Vector3.Dot(val, val3); if (num2 <= 1E-08f) { t = 0f; s = Clamp01((0f - num4) / num); } else { float num5 = Vector3.Dot(val, val2); float num6 = num * num2 - num5 * num5; s = ((num6 > 1E-08f) ? Clamp01((num5 * num3 - num4 * num2) / num6) : 0f); t = (num5 * s + num3) / num2; if (t < 0f) { t = 0f; s = Clamp01((0f - num4) / num); } else if (t > 1f) { t = 1f; s = Clamp01((num5 - num4) / num); } } } c1 = p1 + val * s; c2 = p2 + val2 * t; Vector3 val4 = c1 - c2; return ((Vector3)(ref val4)).sqrMagnitude; } public static Vector3 PullToward(Vector3 point, Vector3 anchor, float maxDistance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0026: 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) Vector3 val = point - anchor; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude <= maxDistance || magnitude < 1E-06f) { return point; } return anchor + val * (maxDistance / magnitude); } public static bool RayBox(Vector3 origin, Vector3 dir, Vector3 min, Vector3 max, out float tEnter) { float num = 0f; float num2 = float.MaxValue; for (int i = 0; i < 3; i++) { float num3 = ((Vector3)(ref origin))[i]; float num4 = ((Vector3)(ref dir))[i]; if (num4 > -1E-08f && num4 < 1E-08f) { if (num3 < ((Vector3)(ref min))[i] || num3 > ((Vector3)(ref max))[i]) { tEnter = 0f; return false; } continue; } float num5 = 1f / num4; float num6 = (((Vector3)(ref min))[i] - num3) * num5; float num7 = (((Vector3)(ref max))[i] - num3) * num5; if (num6 > num7) { float num8 = num6; num6 = num7; num7 = num8; } if (num6 > num) { num = num6; } if (num7 < num2) { num2 = num7; } if (num > num2) { tEnter = 0f; return false; } } tEnter = num; return true; } public static Vector3 ClampToBox(Vector3 p, Vector3 min, Vector3 max) { //IL_0001: 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_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_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: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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_004e: Unknown result type (might be due to invalid IL or missing references) return new Vector3(Clamp(p.x, min.x, max.x), Clamp(p.y, min.y, max.y), Clamp(p.z, min.z, max.z)); } public static bool IsSane(Vector3 v, float maxMagnitude) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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) return IsFinite(v.x) && IsFinite(v.y) && IsFinite(v.z) && ((Vector3)(ref v)).sqrMagnitude <= maxMagnitude * maxMagnitude; } public static bool IsFinite(float f) { return !float.IsNaN(f) && !float.IsInfinity(f); } private static float Clamp01(float v) { return (v < 0f) ? 0f : ((v > 1f) ? 1f : v); } private static float Clamp(float v, float min, float max) { return (v < min) ? min : ((v > max) ? max : v); } } public enum StickMode : byte { Body, Shield } public sealed class StickMessage { public const int ProtocolVersion = 1; public const int MaxBoneNameLength = 64; public const float MaxLocalDistance = 10000f; public const float MaxWorldDistance = 2f; public ZDOID Target; public int ProjectileHash; public StickMode Mode; public string Bone = string.Empty; public int ShieldHash; public Vector3 LocalPosition; public Quaternion LocalRotation = Quaternion.identity; public ZPackage Write() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) ZPackage val = new ZPackage(); val.Write(1); val.Write(Target); val.Write(ProjectileHash); val.Write((byte)Mode); val.Write(Bone ?? string.Empty); val.Write(ShieldHash); val.Write(LocalPosition); val.Write(LocalRotation); return val; } public static StickMessage Read(ZPackage pkg) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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_0095: Unknown result type (might be due to invalid IL or missing references) if (pkg == null) { return null; } try { if (pkg.ReadInt() != 1) { return null; } StickMessage stickMessage = new StickMessage { Target = pkg.ReadZDOID(), ProjectileHash = pkg.ReadInt() }; byte b = pkg.ReadByte(); if (b > 1) { return null; } stickMessage.Mode = (StickMode)b; stickMessage.Bone = pkg.ReadString(); stickMessage.ShieldHash = pkg.ReadInt(); stickMessage.LocalPosition = pkg.ReadVector3(); Quaternion q = pkg.ReadQuaternion(); return (stickMessage.TrySetRotation(q) && stickMessage.IsValid()) ? stickMessage : null; } catch (Exception) { return null; } } public bool TrySetRotation(Quaternion q) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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_0045: 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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: 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_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: 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) if (!StickGeometry.IsFinite(q.x) || !StickGeometry.IsFinite(q.y) || !StickGeometry.IsFinite(q.z) || !StickGeometry.IsFinite(q.w)) { return false; } float num = (float)Math.Sqrt(q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w); if (num < 0.5f || num > 1.5f) { return false; } LocalRotation = new Quaternion(q.x / num, q.y / num, q.z / num, q.w / num); return true; } public bool IsValid() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (((ZDOID)(ref Target)).IsNone() || ProjectileHash == 0 || !StickGeometry.IsSane(LocalPosition, 10000f)) { return false; } if (Mode == StickMode.Body) { return IsBoneName(Bone); } return ShieldHash != 0 && string.IsNullOrEmpty(Bone); } public static bool IsBoneName(string name) { if (string.IsNullOrEmpty(name) || name.Length > 64) { return false; } foreach (char c in name) { if (char.IsControl(c) || c == '/' || c == '\\') { return false; } } return true; } } internal static class StuckArrows { public const int MaxTotal = 300; public static void Apply(StickMessage msg) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: 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_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZNetScene.instance == (Object)null || StuckArrowHost.Total >= 300) { return; } GameObject val = ZNetScene.instance.FindInstance(msg.Target); Character val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<Character>() : null); if ((Object)(object)val2 == (Object)null || val2.IsDead() || (!val2.IsPlayer() && !ArrowsPlugin.Creatures.Value)) { return; } Transform val3 = Anchor(val2, msg); if ((Object)(object)val3 == (Object)null) { return; } GameObject val4 = ArrowVisuals.Create(msg.ProjectileHash); if ((Object)(object)val4 == (Object)null) { return; } Transform transform = val4.transform; Vector3 localScale = transform.localScale; transform.SetParent(val3, false); transform.localPosition = msg.LocalPosition; transform.localRotation = msg.LocalRotation; transform.localScale = Divide(localScale, val3.lossyScale); Vector3 val5 = transform.position - val3.position; if (((Vector3)(ref val5)).sqrMagnitude > 4f) { Object.Destroy((Object)(object)val4); return; } StuckArrowHost stuckArrowHost = val.GetComponent<StuckArrowHost>(); if ((Object)(object)stuckArrowHost == (Object)null) { stuckArrowHost = val.AddComponent<StuckArrowHost>(); } stuckArrowHost.Add(val4, ArrowsPlugin.StuckSeconds.Value, ArrowsPlugin.MaxPerCharacter.Value); } private static Transform Anchor(Character character, StickMessage msg) { if (msg.Mode == StickMode.Body) { return ArrowRig.FindBone(character, msg.Bone); } if (!ArrowsPlugin.Shields.Value) { return null; } if (ArrowRig.ShieldHash(character, out var instance) != msg.ShieldHash) { return null; } MeshFilter val = ArrowRig.ShieldMesh(instance); return ((Object)(object)val != (Object)null) ? ((Component)val).transform : null; } private static Vector3 Divide(Vector3 a, Vector3 b) { //IL_0001: 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_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: 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) //IL_0029: 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) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) return new Vector3(SafeDiv(a.x, b.x), SafeDiv(a.y, b.y), SafeDiv(a.z, b.z)); } private static float SafeDiv(float a, float b) { return (Mathf.Abs(b) > 0.0001f) ? (a / b) : a; } } internal sealed class StuckArrowHost : MonoBehaviour { private struct Entry { public GameObject Arrow; public Vector3 Scale; public float Expires; } private const float ShrinkSeconds = 0.35f; private readonly List<Entry> _arrows = new List<Entry>(); public static int Total { get; private set; } public void Add(GameObject arrow, float seconds, int max) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) _arrows.Add(new Entry { Arrow = arrow, Scale = arrow.transform.localScale, Expires = Time.time + seconds }); Total++; ((Behaviour)this).enabled = true; while (_arrows.Count > Mathf.Max(1, max)) { RemoveAt(0); } } private void Update() { //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) float time = Time.time; for (int num = _arrows.Count - 1; num >= 0; num--) { Entry entry = _arrows[num]; if ((Object)(object)entry.Arrow == (Object)null) { RemoveAt(num); } else { float num2 = time - entry.Expires; if (!(num2 <= 0f)) { if (num2 >= 0.35f) { RemoveAt(num); } else { entry.Arrow.transform.localScale = entry.Scale * (1f - num2 / 0.35f); } } } } if (_arrows.Count == 0) { ((Behaviour)this).enabled = false; } } private void RemoveAt(int i) { GameObject arrow = _arrows[i].Arrow; _arrows.RemoveAt(i); Total = Mathf.Max(0, Total - 1); if ((Object)(object)arrow != (Object)null) { Object.Destroy((Object)(object)arrow); } } private void OnDestroy() { for (int num = _arrows.Count - 1; num >= 0; num--) { RemoveAt(num); } } } public static class MyPluginInfo { public const string PLUGIN_GUID = "vsm.arrows"; public const string PLUGIN_NAME = "MEL Flechas"; public const string PLUGIN_VERSION = "0.1.4"; } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class <7734a844-bde8-4f04-b0d4-94c0f4e57bbe>IgnoresAccessChecksToAttribute : Attribute { public <7734a844-bde8-4f04-b0d4-94c0f4e57bbe>IgnoresAccessChecksToAttribute(string assemblyName) { } } } namespace VSM.Core.Ui { internal static class VanillaStyle { public static TMP_Text TitleFont => ((Object)(object)InventoryGui.instance != (Object)null) ? InventoryGui.instance.m_playerName : null; public static TMP_Text BodyFont => (!((Object)(object)InventoryGui.instance != (Object)null)) ? null : (((Object)(object)InventoryGui.instance.m_armor != (Object)null) ? InventoryGui.instance.m_armor : InventoryGui.instance.m_playerName); public static Image FindBackground(Transform root, Transform exclude1, Transform exclude2) { //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)root == (Object)null) { return null; } Image result = null; float num = 0f; Image[] componentsInChildren = ((Component)root).GetComponentsInChildren<Image>(true); foreach (Image val in componentsInChildren) { if ((Object)(object)val == (Object)null || (Object)(object)val.sprite == (Object)null) { continue; } Transform transform = ((Component)val).transform; if ((!((Object)(object)exclude1 != (Object)null) || !transform.IsChildOf(exclude1)) && (!((Object)(object)exclude2 != (Object)null) || !transform.IsChildOf(exclude2))) { Rect rect = ((Graphic)val).rectTransform.rect; float num2 = Mathf.Abs(((Rect)(ref rect)).width * ((Rect)(ref rect)).height); if (num2 > num) { num = num2; result = val; } } } return result; } public static bool CopyImage(Image source, Image target) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target == (Object)null) { return false; } if ((Object)(object)source == (Object)null) { ((Graphic)target).color = new Color(0f, 0f, 0f, 0.6f); return false; } target.sprite = source.sprite; target.type = source.type; ((Graphic)target).material = ((Graphic)source).material; ((Graphic)target).color = ((Graphic)source).color; target.fillCenter = source.fillCenter; target.pixelsPerUnitMultiplier = source.pixelsPerUnitMultiplier; target.preserveAspect = false; return true; } public static Image InventoryBackground(Transform exclude) { InventoryGui instance = InventoryGui.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.m_player == (Object)null) { return null; } Transform exclude2 = (Transform)(object)(((Object)(object)instance.m_playerGrid != (Object)null) ? instance.m_playerGrid.m_gridRoot : null); return FindBackground((Transform)(object)instance.m_player, exclude2, exclude); } public static void CopyFont(TMP_Text source, TMP_Text target) { //IL_0037: 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) if (!((Object)(object)source == (Object)null) && !((Object)(object)target == (Object)null)) { target.font = source.font; target.fontSharedMaterial = source.fontSharedMaterial; ((Graphic)target).color = ((Graphic)source).color; target.fontStyle = source.fontStyle; } } public static TextMeshProUGUI NewText(Transform parent, string name, TMP_Text style, float size, TextAlignmentOptions align) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0041: 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(parent, false); TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>(); CopyFont(style, (TMP_Text)(object)val2); ((TMP_Text)val2).fontSize = size; ((TMP_Text)val2).alignment = align; ((Graphic)val2).raycastTarget = false; ((TMP_Text)val2).enableWordWrapping = false; ((TMP_Text)val2).richText = true; return val2; } } } namespace VSM.Core.Runtime { internal static class Headless { private static bool? s_isHeadless; public static bool IsHeadless { get { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 if (!s_isHeadless.HasValue) { s_isHeadless = (int)SystemInfo.graphicsDeviceType == 4 || Application.isBatchMode; } return s_isHeadless.Value; } } public static bool IsServerProcess => (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer(); public static bool IsDedicatedServer => (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && ZNet.instance.IsDedicated(); public static bool IsListenHost => (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && !ZNet.instance.IsDedicated(); public static bool IsRemoteClient => (Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer(); } internal static class Keys { public static bool Pressed(KeyboardShortcut shortcut) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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) KeyCode mainKey = ((KeyboardShortcut)(ref shortcut)).MainKey; return (int)mainKey != 0 && ZInput.GetKeyDown(mainKey, false) && ((KeyboardShortcut)(ref shortcut)).Modifiers.All((KeyCode m) => ZInput.GetKey(m, false)); } } } namespace VSM.Core.Reflection { internal static class GameConstants { private static uint? s_networkVersion; private static long? s_routedEverybody; public static uint NetworkVersion { get { if (!s_networkVersion.HasValue) { s_networkVersion = ReadConstant<uint>(typeof(Version), new string[2] { "c_networkVersion", "m_networkVersion" }); } return s_networkVersion.Value; } } public static long RoutedRpcEverybody { get { if (!s_routedEverybody.HasValue) { s_routedEverybody = ReadConstant<long>(typeof(ZRoutedRpc), new string[1] { "Everybody" }); } return s_routedEverybody.Value; } } public static string GameVersionString { get { //IL_0002: 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) try { return ((object)Version.CurrentVersion/*cast due to .constrained prefix*/).ToString(); } catch (Exception) { return "?"; } } } private static T ReadConstant<T>(Type type, params string[] names) where T : struct { foreach (string name in names) { FieldInfo field = type.GetField(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (!(field == null)) { object obj = (field.IsLiteral ? field.GetRawConstantValue() : field.GetValue(null)); if (obj is T result) { return result; } try { return (T)Convert.ChangeType(obj, typeof(T)); } catch (Exception) { } } } return default(T); } } } namespace VSM.Core.Net { internal static class ZPackageExt { public static bool HasMore(this ZPackage pkg) { return pkg != null && pkg.GetPos() < pkg.Size(); } public static int ReadIntOr(this ZPackage pkg, int fallback) { return pkg.HasMore() ? pkg.ReadInt() : fallback; } public static string ReadStringOr(this ZPackage pkg, string fallback) { return pkg.HasMore() ? pkg.ReadString() : fallback; } public static bool ReadBoolOr(this ZPackage pkg, bool fallback) { return pkg.HasMore() ? pkg.ReadBool() : fallback; } public static string ReadBoundedString(this ZPackage pkg, int maxLength) { string text = pkg.ReadString(); return (text != null && text.Length <= maxLength) ? text : null; } } } namespace VSM.Core.Localization { internal static class VsmLocalization { public static void Register(ManualLogSource log, string pluginDirectory, IDictionary<string, string> embeddedSpanish) { Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.Ordinal); if (embeddedSpanish != null) { foreach (KeyValuePair<string, string> item in embeddedSpanish) { dictionary[item.Key] = item.Value; } } string path = Path.Combine(pluginDirectory ?? string.Empty, "Translations"); MergeFile(log, Path.Combine(path, "Spanish.json"), dictionary); string text = SafeSelectedLanguage(); if (!string.Equals(text, "Spanish", StringComparison.OrdinalIgnoreCase)) { MergeFile(log, Path.Combine(path, text + ".json"), dictionary); } Apply(log, dictionary); } public static string Localize(string token, params object[] args) { string text = token; try { if (Localization.instance != null && !string.IsNullOrEmpty(token)) { bool flag = token[0] != '$' && token.IndexOf(' ') < 0 && token.IndexOf('\n') < 0; string text2 = Localization.instance.Localize(flag ? ("$" + token) : token); text = ((flag && text2.Length > 1 && text2[0] == '[' && text2[text2.Length - 1] == ']') ? token : text2); } } catch (Exception) { text = token; } if (args != null && args.Length != 0) { try { text = string.Format(text, args); } catch (FormatException) { } } return text; } private static string SafeSelectedLanguage() { try { return (Localization.instance != null) ? Localization.instance.GetSelectedLanguage() : "Spanish"; } catch (Exception) { return "Spanish"; } } private static void Apply(ManualLogSource log, Dictionary<string, string> words) { if (Localization.instance == null) { if (log != null) { log.LogWarning((object)"Localization.instance aún no existe; las traducciones no se han aplicado."); } return; } foreach (KeyValuePair<string, string> word in words) { string text = (word.Key.StartsWith("$", StringComparison.Ordinal) ? word.Key.Substring(1) : word.Key); Localization.instance.AddWord(text, word.Value); } } private static void MergeFile(ManualLogSource log, string path, Dictionary<string, string> into) { if (!File.Exists(path)) { return; } try { foreach (KeyValuePair<string, string> item in ParseFlatJson(File.ReadAllText(path, Encoding.UTF8))) { into[item.Key] = item.Value; } } catch (Exception ex) { if (log != null) { log.LogWarning((object)("No se pudo leer " + path + ": " + ex.Message)); } } } public static Dictionary<string, string> ParseFlatJson(string json) { Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.Ordinal); if (string.IsNullOrEmpty(json)) { return dictionary; } int i = 0; SkipWs(json, ref i); if (i >= json.Length || json[i] != '{') { return dictionary; } i++; while (true) { SkipWs(json, ref i); if (i >= json.Length || json[i] == '}') { break; } if (json[i] == ',') { i++; continue; } string text = ReadString(json, ref i); if (text == null) { i++; continue; } SkipWs(json, ref i); if (i < json.Length && json[i] == ':') { i++; } SkipWs(json, ref i); if (i < json.Length && json[i] == '"') { string text2 = ReadString(json, ref i); dictionary[text] = text2 ?? string.Empty; } else { for (; i < json.Length && json[i] != ',' && json[i] != '}'; i++) { } } } return dictionary; } private static void SkipWs(string s, ref int i) { while (i < s.Length && char.IsWhiteSpace(s[i])) { i++; } } private static string ReadString(string s, ref int i) { if (i >= s.Length || s[i] != '"') { return null; } i++; StringBuilder stringBuilder = new StringBuilder(); while (i < s.Length) { char c = s[i++]; switch (c) { case '"': return stringBuilder.ToString(); case '\\': { if (i >= s.Length) { break; } char c2 = s[i++]; switch (c2) { case 'n': stringBuilder.Append('\n'); break; case 't': stringBuilder.Append('\t'); break; case 'r': stringBuilder.Append('\r'); break; case 'b': stringBuilder.Append('\b'); break; case 'f': stringBuilder.Append('\f'); break; case 'u': if (i + 4 <= s.Length) { stringBuilder.Append((char)Convert.ToInt32(s.Substring(i, 4), 16)); i += 4; } break; default: stringBuilder.Append(c2); break; } continue; } } stringBuilder.Append(c); } return stringBuilder.ToString(); } } } namespace VSM.Core.Harmony { internal static class PatchUtil { private static readonly List<string> s_failed = new List<string>(); public static IReadOnlyList<string> FailedTargets => s_failed; public static bool IsDegraded => s_failed.Count > 0; public static MethodInfo DeclaredMethodOrNull(ManualLogSource log, Type type, string name, Type[] parameters, string owner) { if (type == null) { Fail(log, owner, name + " (tipo nulo)"); return null; } MethodInfo methodInfo = AccessTools.DeclaredMethod(type, name, parameters, (Type[])null); if (methodInfo == null) { Fail(log, owner, type.FullName + "." + name + "(" + Describe(parameters) + ")"); } return methodInfo; } public static void PatchAllSafely(ManualLogSource log, Harmony harmony, Assembly assembly) { Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(assembly); foreach (Type type in typesFromAssembly) { if (type.GetCustomAttributes(typeof(HarmonyPatch), inherit: true).Length != 0) { PatchClassSafely(log, harmony, type); } } } public static bool PatchClassSafely(ManualLogSource log, Harmony harmony, Type patchClass) { try { harmony.CreateClassProcessor(patchClass).Patch(); return true; } catch (Exception ex) { Fail(log, harmony.Id, patchClass.FullName + " -> " + ex.GetType().Name + ": " + ex.Message); return false; } } private static void Fail(ManualLogSource log, string owner, string what) { s_failed.Add(what); if (log != null) { log.LogError((object)("[" + owner + "] No se pudo aplicar el parche (¿cambió el juego?): " + what + ". El mod sigue cargado en modo degradado.")); } } private static string Describe(Type[] parameters) { if (parameters == null || parameters.Length == 0) { return string.Empty; } string[] array = new string[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { array[i] = ((parameters[i] == null) ? "?" : parameters[i].Name); } return string.Join(", ", array); } } } namespace VSM.Core.Config { internal sealed class ConfigurationManagerAttributes { public bool? ShowRangeAsPercent; public Action<ConfigEntryBase> CustomDrawer; public bool? Browsable; public string Category; public object DefaultValue; public bool? HideDefaultButton; public bool? HideSettingName; public string Description; public string DispName; public int? Order; public bool? ReadOnly; public bool? IsAdvanced; public bool? IsAdminOnly; public Func<object, string> ObjToStr; public Func<string, object> StrToObj; } } namespace VSM.Core.Camera { internal struct RigSettings { public float Speed; public float FastMultiplier; public bool MoveRelativeToView; } internal sealed class CameraRig { public const float MaxPitch = 89f; public float Yaw; public float Pitch; public Vector3 Position; public Vector3 Velocity; public Vector3 ForwardVector => Forward(Yaw, Pitch); public Quaternion Rotation => Quaternion.Euler(Pitch, Yaw, 0f); public static Vector3 Forward(float yawDeg, float pitchDeg) { //IL_002f: 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) //IL_0037: Unknown result type (might be due to invalid IL or missing references) float num = yawDeg * ((float)Math.PI / 180f); float num2 = pitchDeg * ((float)Math.PI / 180f); float num3 = Mathf.Cos(num2); return new Vector3(Mathf.Sin(num) * num3, 0f - Mathf.Sin(num2), Mathf.Cos(num) * num3); } public static Vector3 FlatForward(float yawDeg) { //IL_001a: 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_0022: Unknown result type (might be due to invalid IL or missing references) float num = yawDeg * ((float)Math.PI / 180f); return new Vector3(Mathf.Sin(num), 0f, Mathf.Cos(num)); } public static Vector3 Right(float yawDeg) { //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_0023: Unknown result type (might be due to invalid IL or missing references) float num = yawDeg * ((float)Math.PI / 180f); return new Vector3(Mathf.Cos(num), 0f, 0f - Mathf.Sin(num)); } public void Reset(Vector3 position, Vector3 forward) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) Position = position; Velocity = Vector3.zero; SetFromDirection(forward); } public void SetFromDirection(Vector3 forward) { //IL_0035: 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_005c: Unknown result type (might be due to invalid IL or missing references) if (((Vector3)(ref forward)).sqrMagnitude < 1E-08f) { Yaw = 0f; Pitch = 0f; } else { ((Vector3)(ref forward)).Normalize(); Yaw = Mathf.Repeat(Mathf.Atan2(forward.x, forward.z) * 57.29578f, 360f); Pitch = Mathf.Clamp((0f - Mathf.Asin(Mathf.Clamp(forward.y, -1f, 1f))) * 57.29578f, -89f, 89f); } } public void ApplyLook(Vector2 delta) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) Yaw = Mathf.Repeat(Yaw + delta.x, 360f); Pitch = Mathf.Clamp(Pitch - delta.y, -89f, 89f); } public Vector3 DesiredVelocity(Vector3 move, float vertical, bool fast, RigSettings settings) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //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_0083: 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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: 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_00df: 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) Vector3 val = (settings.MoveRelativeToView ? Forward(Yaw, Pitch) : FlatForward(Yaw)); Vector3 val2 = Right(Yaw) * Mathf.Clamp(move.x, -1f, 1f) + val * Mathf.Clamp(move.z, -1f, 1f) + Vector3.up * Mathf.Clamp(vertical, -1f, 1f); if (((Vector3)(ref val2)).sqrMagnitude > 1f) { ((Vector3)(ref val2)).Normalize(); } float num = Mathf.Max(0f, settings.Speed) * (fast ? Mathf.Max(1f, settings.FastMultiplier) : 1f); return val2 * num; } public void Integrate(Vector3 desiredVelocity, float dt, float smoothing) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0047: 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) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) if (!(dt <= 0f)) { float num = ((smoothing <= 0f) ? 1f : (1f - Mathf.Exp((0f - dt) / smoothing))); Velocity = Vector3.Lerp(Velocity, desiredVelocity, num); Position += Velocity * dt; } } public static Vector3 ClampToSphere(Vector3 pos, Vector3 center, float radius) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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) Vector3 val = pos - center; float num = Mathf.Max(0f, radius); if (((Vector3)(ref val)).sqrMagnitude <= num * num) { return pos; } return center + ((Vector3)(ref val)).normalized * num; } } internal static class CameraWorld { public const float CollisionRadius = 0.25f; public static Vector3 Anchor(Player player) { //IL_0033: 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_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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) Transform eye = ((Character)player).m_eye; return ((Object)(object)eye != (Object)null) ? eye.position : (((Component)player).transform.position + Vector3.up * 1.6f); } public static Vector3 Constrain(Vector3 from, Vector3 to, Vector3 anchor, float maxDistance, float clearance, GameCamera cam) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0038: 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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) Vector3 pos = CameraRig.ClampToSphere(to, anchor, maxDistance); pos = Lift(pos, clearance, cam); pos = CameraRig.ClampToSphere(pos, anchor, maxDistance + 1f); LayerMask blockCameraMask = cam.m_blockCameraMask; Vector3 val = (Overlaps(from, blockCameraMask) ? anchor : from); return Collide(val, pos, blockCameraMask); } public static Vector3 Lift(Vector3 pos, float clearance, GameCamera cam) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) clearance = Mathf.Max(0f, clearance); ZoneSystem instance = ZoneSystem.instance; float num = default(float); if ((Object)(object)instance != (Object)null && instance.GetGroundHeight(pos, ref num)) { pos.y = Mathf.Max(pos.y, num + clearance); } float num2 = Floating.GetLiquidLevel(pos, 1f, (LiquidType)10); if ((Object)(object)instance != (Object)null && !Character.InInterior(pos)) { num2 = Mathf.Max(num2, instance.m_waterLevel); } if (num2 > -9000f) { pos.y = Mathf.Max(pos.y, num2 + Mathf.Max(clearance, cam.m_minWaterDistance)); } return pos; } public static bool Overlaps(Vector3 pos, LayerMask mask) { //IL_0001: 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) return Physics.CheckSphere(pos, 0.225f, LayerMask.op_Implicit(mask), (QueryTriggerInteraction)1); } public static Vector3 Collide(Vector3 from, Vector3 to, LayerMask mask) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0033: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) Vector3 val = to - from; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude < 1E-05f) { return to; } Vector3 val2 = val / magnitude; RaycastHit val3 = default(RaycastHit); if (Physics.SphereCast(from, 0.25f, val2, ref val3, magnitude, LayerMask.op_Implicit(mask), (QueryTriggerInteraction)1)) { return from + val2 * Mathf.Max(0f, ((RaycastHit)(ref val3)).distance - 0.02f); } return to; } } internal static class CameraLock { private const string Prefix = "vsm_camera_lock:"; public static string Holder() { GameCamera instance = GameCamera.instance; if ((Object)(object)instance == (Object)null) { return null; } Transform transform = ((Component)instance).transform; for (int i = 0; i < transform.childCount; i++) { string name = ((Object)transform.GetChild(i)).name; if (name.StartsWith("vsm_camera_lock:", StringComparison.Ordinal)) { return name.Substring("vsm_camera_lock:".Length); } } return null; } public static bool TryAcquire(string owner) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown GameCamera instance = GameCamera.instance; if ((Object)(object)instance == (Object)null) { return false; } string text = Holder(); if (text != null) { return text == owner; } GameObject val = new GameObject("vsm_camera_lock:" + owner); val.transform.SetParent(((Component)instance).transform, false); return true; } public static void Release(string owner) { GameCamera instance = GameCamera.instance; if ((Object)(object)instance == (Object)null) { return; } Transform transform = ((Component)instance).transform; for (int num = transform.childCount - 1; num >= 0; num--) { Transform child = transform.GetChild(num); if (((Object)child).name == "vsm_camera_lock:" + owner) { Object.Destroy((Object)(object)((Component)child).gameObject); ((Object)child).name = "vsm_camera_lock_released"; } } } } internal sealed class BodyHider { private readonly List<Renderer> _hidden = new List<Renderer>(); private float _nextScan; public void Update(Player player, bool hide) { if (!hide || (Object)(object)player == (Object)null) { Restore(); } else { if (Time.unscaledTime < _nextScan) { return; } _nextScan = Time.unscaledTime + 0.5f; Renderer[] componentsInChildren = ((Component)player).GetComponentsInChildren<Renderer>(false); foreach (Renderer val in componentsInChildren) { if ((Object)(object)val != (Object)null && val.enabled && (val is SkinnedMeshRenderer || val is MeshRenderer)) { val.enabled = false; _hidden.Add(val); } } } } public void Restore() { foreach (Renderer item in _hidden) { if ((Object)(object)item != (Object)null) { item.enabled = true; } } _hidden.Clear(); _nextScan = 0f; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }
plugins/VSM.BuildCam/VSM.BuildCam.dll
Decompiled 3 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ConditionalConfigSync; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.UI; using VSM.Core.Camera; using VSM.Core.Config; using VSM.Core.Harmony; using VSM.Core.Localization; using VSM.Core.Reflection; using VSM.Core.Runtime; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: <e8ce6e11-cfd4-4a54-b4bb-a6a898b34399>IgnoresAccessChecksTo("assembly_guiutils")] [assembly: <e8ce6e11-cfd4-4a54-b4bb-a6a898b34399>IgnoresAccessChecksTo("assembly_utils")] [assembly: <e8ce6e11-cfd4-4a54-b4bb-a6a898b34399>IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("VSM.BuildCam")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("0.1.4.0")] [assembly: AssemblyInformationalVersion("0.1.4+ff27bc889ccf218c61c45d3417d48ab708a5ba8f")] [assembly: AssemblyProduct("VSM.BuildCam")] [assembly: AssemblyTitle("VSM.BuildCam")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.4.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace VSM.BuildCam { internal static class BuildCamPatches { [HarmonyPatch(typeof(GameCamera), "UpdateCamera", new Type[] { typeof(float) })] private static class UpdateCameraPatch { [HarmonyPrefix] [HarmonyPriority(600)] private static bool Prefix(GameCamera __instance, float dt) { return Session.UpdateCamera(__instance, dt); } } [HarmonyPatch(typeof(Player), "SetMouseLook", new Type[] { typeof(Vector2) })] private static class SetMouseLookPatch { [HarmonyPrefix] private static bool Prefix(Player __instance, Vector2 mouseLook) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (!Session.Owns(__instance)) { return true; } Session.OnLook(mouseLook); return false; } } [HarmonyPatch(typeof(Player), "SetControls", new Type[] { typeof(Vector3), typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(bool) })] private static class SetControlsPatch { [HarmonyPrefix] private static void Prefix(Player __instance, ref Vector3 movedir, ref bool attack, ref bool attackHold, ref bool secondaryAttack, ref bool secondaryAttackHold, ref bool block, ref bool blockHold, ref bool jump, ref bool crouch, ref bool run, ref bool autoRun, ref bool dodge) { //IL_0012: 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_0033: Unknown result type (might be due to invalid IL or missing references) if (Session.Owns(__instance)) { Session.OnControls(movedir, jump, crouch, run); __instance.m_autoRun = false; movedir = Vector3.zero; attack = false; attackHold = false; secondaryAttack = false; secondaryAttackHold = false; block = false; blockHold = false; jump = false; crouch = false; run = false; autoRun = false; dodge = false; } } } [HarmonyPatch] private static class ReachPatch { private static IEnumerable<MethodBase> TargetMethods() { List<MethodBase> list = new List<MethodBase>(); Add(list, "PieceRayTest", new Type[6] { typeof(Vector3).MakeByRefType(), typeof(Vector3).MakeByRefType(), typeof(Piece).MakeByRefType(), typeof(Heightmap).MakeByRefType(), typeof(Collider).MakeByRefType(), typeof(bool) }); Add(list, "RemovePiece", Type.EmptyTypes); Add(list, "CopyPiece", Type.EmptyTypes); Add(list, "UpdateWearNTearHover", Type.EmptyTypes); BuildCamPlugin.ReachPatched = list.Count == 4; return list; } private static void Add(List<MethodBase> targets, string name, Type[] parameters) { MethodBase methodBase = AccessTools.DeclaredMethod(typeof(Player), name, parameters, (Type[])null); if (methodBase == null) { BuildCamPlugin.Log.LogError((object)("vsm.buildcam: no existe Player." + name + " en esta versión; el alcance de construcción no se ampliará en ese caso.")); } else { targets.Add(methodBase); } } [HarmonyPrefix] private static void Prefix(Player __instance, out float __state) { __state = __instance.m_maxPlaceDistance; if (Session.Owns(__instance)) { __instance.m_maxPlaceDistance = Session.EffectiveReach; } } [HarmonyFinalizer] private static void Finalizer(Player __instance, float __state) { __instance.m_maxPlaceDistance = __state; } } [HarmonyPatch(typeof(CraftingStation), "HaveBuildStationInRange", new Type[] { typeof(string), typeof(Vector3) })] private static class StationRangePatch { [ThreadStatic] private static bool s_reentrant; [HarmonyPostfix] private static void Postfix(string name, ref CraftingStation __result) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) if (s_reentrant || (Object)(object)__result != (Object)null || !Session.Active || !BuildCamPlugin.StationRangeFromPlayer.Value) { return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } s_reentrant = true; try { __result = CraftingStation.HaveBuildStationInRange(name, ((Component)localPlayer).transform.position); } finally { s_reentrant = false; } } } [HarmonyPatch(typeof(Player), "SetLocalPlayer")] private static class SetLocalPlayerPatch { [HarmonyPostfix] private static void Postfix() { Session.Reset(); } } [HarmonyPatch(typeof(Player), "OnDestroy")] private static class PlayerDestroyPatch { [HarmonyPrefix] private static void Prefix(Player __instance) { if (Session.Owns(__instance)) { Session.Reset(); } } } [HarmonyPatch(typeof(GameCamera), "OnDestroy")] private static class CameraDestroyPatch { [HarmonyPrefix] private static void Prefix() { Session.Reset(); } } [HarmonyPatch(typeof(Terminal), "InitTerminal")] private static class TerminalInitPatch { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__1_0; public static ConsoleEvent <>9__1_1; internal void <Postfix>b__1_0(ConsoleEventArgs args) { foreach (string item in Session.StatusLines()) { args.Context.AddString(item); } } internal void <Postfix>b__1_1(ConsoleEventArgs args) { Session.Exit(Denial.User); args.Context.AddString("vsm.buildcam: cámara cerrada"); } } private static bool s_registered; [HarmonyPostfix] private static void Postfix() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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_0075: Expected O, but got Unknown if (s_registered) { return; } s_registered = true; object obj = <>c.<>9__1_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { foreach (string item in Session.StatusLines()) { args.Context.AddString(item); } }; <>c.<>9__1_0 = val; obj = (object)val; } new ConsoleCommand("vsm_buildcam", "Estado y límites de la cámara de construcción (vsm.buildcam)", (ConsoleEvent)obj, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj2 = <>c.<>9__1_1; if (obj2 == null) { ConsoleEvent val2 = delegate(ConsoleEventArgs args) { Session.Exit(Denial.User); args.Context.AddString("vsm.buildcam: cámara cerrada"); }; <>c.<>9__1_1 = val2; obj2 = (object)val2; } new ConsoleCommand("vsm_buildcam_exit", "Cierra la cámara de construcción si está activa", (ConsoleEvent)obj2, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } } internal static readonly Type[] SetControlsSignature = new Type[12] { typeof(Vector3), typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(bool) }; internal static MethodBase UpdateCameraMethod => AccessTools.DeclaredMethod(typeof(GameCamera), "UpdateCamera", new Type[1] { typeof(float) }, (Type[])null); internal static MethodBase GetCameraPositionMethod => AccessTools.DeclaredMethod(typeof(GameCamera), "GetCameraPosition", new Type[3] { typeof(float), typeof(Vector3).MakeByRefType(), typeof(Quaternion).MakeByRefType() }, (Type[])null); internal static MethodBase SetMouseLookMethod => AccessTools.DeclaredMethod(typeof(Player), "SetMouseLook", new Type[1] { typeof(Vector2) }, (Type[])null); internal static MethodBase SetControlsMethod => AccessTools.DeclaredMethod(typeof(Player), "SetControls", SetControlsSignature, (Type[])null); } [BepInPlugin("vsm.buildcam", "MEL BuildCam", "0.1.4")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class BuildCamPlugin : BaseUnityPlugin { internal static ManualLogSource Log; private static ConfigSync s_sync; private Harmony _harmony; internal static bool PatchesOk; internal static bool ReachPatched; internal static string ForeignOwners = string.Empty; public static ConfigEntry<bool> Enabled; public static ConfigEntry<float> MaxCameraDistance; public static ConfigEntry<float> BuildReach; public static ConfigEntry<float> MinTerrainClearance; public static ConfigEntry<float> CombatCooldownSeconds; public static ConfigEntry<float> IdleTimeoutSeconds; public static ConfigEntry<bool> RequireCraftingStationNearby; public static ConfigEntry<bool> StationRangeFromPlayer; public static ConfigEntry<bool> ExitOnDamage; public static ConfigEntry<bool> ServerLock; public static ConfigEntry<KeyboardShortcut> ToggleKey; public static ConfigEntry<float> MoveSpeed; public static ConfigEntry<float> FastMultiplier; public static ConfigEntry<bool> MoveRelativeToView; public static ConfigEntry<float> MoveSmoothing; public static ConfigEntry<float> FieldOfView; public static ConfigEntry<bool> HideLocalPlayer; public static ConfigEntry<bool> ShowMessages; public static ConfigEntry<bool> RefuseIfForeignCameraPatches; public static ConfigEntry<bool> VerboseLog; private static readonly Dictionary<string, string> s_spanish = new Dictionary<string, string> { { "vsm_buildcam_on", "Cámara de construcción activada" }, { "vsm_buildcam_off", "Cámara de construcción desactivada" }, { "vsm_buildcam_deny_notool", "Equipa el martillo (o la herramienta de construcción) primero" }, { "vsm_buildcam_deny_combat", "Hay enemigos cerca: cámara bloqueada {0} s" }, { "vsm_buildcam_deny_nostation", "Necesitas un banco de trabajo en rango" }, { "vsm_buildcam_deny_confignotready", "Esperando la configuración del servidor…" }, { "vsm_buildcam_deny_disabled", "El servidor tiene desactivada la cámara de construcción" }, { "vsm_buildcam_exit_idle", "Cámara cerrada por inactividad" }, { "vsm_buildcam_exit_damaged", "Cámara cerrada: has recibido daño" }, { "vsm_buildcam_exit_combat", "Cámara cerrada: enemigo cerca" } }; public static bool IsConfigReady => s_sync != null && (((ConditionalConfigSync)s_sync).IsSourceOfTruth || ((ConditionalConfigSync)s_sync).InitialSyncDone); private void Awake() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0044: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Expected O, but got Unknown //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Expected O, but got Unknown //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Expected O, but got Unknown //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Expected O, but got Unknown //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Expected O, but got Unknown //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Expected O, but got Unknown //IL_02ba: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Expected O, but got Unknown //IL_0300: Unknown result type (might be due to invalid IL or missing references) //IL_030a: Expected O, but got Unknown //IL_035e: Unknown result type (might be due to invalid IL or missing references) //IL_03a0: Unknown result type (might be due to invalid IL or missing references) //IL_03aa: Expected O, but got Unknown //IL_03dd: Unknown result type (might be due to invalid IL or missing references) //IL_03e7: Expected O, but got Unknown //IL_043a: Unknown result type (might be due to invalid IL or missing references) //IL_0444: Expected O, but got Unknown //IL_0477: Unknown result type (might be due to invalid IL or missing references) //IL_0481: Expected O, but got Unknown //IL_0577: Unknown result type (might be due to invalid IL or missing references) //IL_0581: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; s_sync = new ConfigSync("vsm.buildcam") { DisplayName = "MEL BuildCam", CurrentVersion = "0.1.4", MinimumRequiredVersion = "0.1.4", ModRequired = true }; Enabled = Synced<bool>(((BaseUnityPlugin)this).Config.Bind<bool>("1. Límites (servidor)", "Enabled", true, new ConfigDescription("Permite usar la cámara de construcción. Con false nadie puede activarla y las cámaras activas se cierran.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 100 } }))); MaxCameraDistance = Synced<float>(((BaseUnityPlugin)this).Config.Bind<float>("1. Límites (servidor)", "MaxCameraDistance", 25f, new ConfigDescription("Distancia máxima (m) de la cámara al jugador. La cámara nunca sale de esa esfera (tope duro 45).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(3f, 45f), new object[1] { new ConfigurationManagerAttributes { Order = 99 } }))); BuildReach = Synced<float>(((BaseUnityPlugin)this).Config.Bind<float>("1. Límites (servidor)", "BuildReach", 35f, new ConfigDescription("Alcance de construcción (m, medido desde el jugador) mientras la cámara está activa. Vanilla: 8. Se sube al menos a MaxCameraDistance + 5; tope 50.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(8f, 50f), new object[1] { new ConfigurationManagerAttributes { Order = 98 } }))); MinTerrainClearance = Synced<float>(((BaseUnityPlugin)this).Config.Bind<float>("1. Límites (servidor)", "MinTerrainClearance", 1f, new ConfigDescription("Altura mínima (m) de la cámara sobre el terreno y el agua. Evita mirar bajo el suelo.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), new object[1] { new ConfigurationManagerAttributes { Order = 97 } }))); CombatCooldownSeconds = Synced<float>(((BaseUnityPlugin)this).Config.Bind<float>("1. Límites (servidor)", "CombatCooldownSeconds", 10f, new ConfigDescription("Segundos desde que un enemigo detectó al jugador hasta poder activar la cámara. Si un enemigo lo detecta con la cámara activa, se cierra.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 120f), new object[1] { new ConfigurationManagerAttributes { Order = 96 } }))); IdleTimeoutSeconds = Synced<float>(((BaseUnityPlugin)this).Config.Bind<float>("1. Límites (servidor)", "IdleTimeoutSeconds", 120f, new ConfigDescription("Segundos sin mover la cámara ni pulsar nada hasta cerrarla (0 = sin límite).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 900f), new object[1] { new ConfigurationManagerAttributes { Order = 95 } }))); RequireCraftingStationNearby = Synced<bool>(((BaseUnityPlugin)this).Config.Bind<bool>("1. Límites (servidor)", "RequireCraftingStationNearby", true, new ConfigDescription("Exige un banco (cualquier estación de crafteo) cuyo rango de construcción cubra al jugador para activar la cámara. Impide usarla para explorar.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 94 } }))); StationRangeFromPlayer = Synced<bool>(((BaseUnityPlugin)this).Config.Bind<bool>("1. Límites (servidor)", "StationRangeFromPlayer", false, new ConfigDescription("Con la cámara activa, si el punto de construcción queda fuera del rango del banco pero el jugador está dentro, se permite construir igualmente.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 93 } }))); ExitOnDamage = Synced<bool>(((BaseUnityPlugin)this).Config.Bind<bool>("1. Límites (servidor)", "ExitOnDamage", true, new ConfigDescription("Cerrar la cámara al recibir daño.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 92 } }))); ServerLock = ((BaseUnityPlugin)this).Config.Bind<bool>("1. Límites (servidor)", "ServerLock", true, "Bloquea la configuración sincronizada: solo los administradores del servidor pueden cambiarla."); ((ConditionalConfigSync)s_sync).AddLockingConfigEntry<bool>(ServerLock); ToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("2. Controles", "ToggleKey", new KeyboardShortcut((KeyCode)287, Array.Empty<KeyCode>()), "Tecla para activar/desactivar la cámara (con el martillo equipado)."); MoveSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("2. Controles", "MoveSpeed", 8f, new ConfigDescription("Velocidad de la cámara (m/s).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 30f), Array.Empty<object>())); FastMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("2. Controles", "FastMultiplier", 2.5f, new ConfigDescription("Multiplicador de velocidad al mantener correr.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 5f), Array.Empty<object>())); MoveRelativeToView = ((BaseUnityPlugin)this).Config.Bind<bool>("2. Controles", "MoveRelativeToView", true, "Avanzar sigue la dirección de la mirada (incluida la inclinación). Con false, avanzar es horizontal y solo saltar/agacharse cambian la altura."); MoveSmoothing = ((BaseUnityPlugin)this).Config.Bind<float>("2. Controles", "MoveSmoothing", 0.15f, new ConfigDescription("Suavizado del movimiento (s). 0 = respuesta inmediata.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); FieldOfView = ((BaseUnityPlugin)this).Config.Bind<float>("2. Controles", "FieldOfView", 0f, new ConfigDescription("Campo de visión con la cámara activa (0 = el del juego).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 120f), Array.Empty<object>())); HideLocalPlayer = ((BaseUnityPlugin)this).Config.Bind<bool>("2. Controles", "HideLocalPlayer", false, "Ocultar tu propio cuerpo mientras la cámara está activa."); ShowMessages = ((BaseUnityPlugin)this).Config.Bind<bool>("2. Controles", "ShowMessages", true, "Avisos en pantalla al activar, cerrar o denegar la cámara."); RefuseIfForeignCameraPatches = ((BaseUnityPlugin)this).Config.Bind<bool>("2. Controles", "RefuseIfForeignCameraPatches", true, "No activar la cámara si otro mod también parchea GameCamera (evita cámaras peleándose)."); VerboseLog = ((BaseUnityPlugin)this).Config.Bind<bool>("3. Depuración", "VerboseLog", false, "Registro detallado en LogOutput.log."); Log.LogInfo((object)("vsm.buildcam 0.1.4 | Valheim " + GameConstants.GameVersionString + " | headless=" + Headless.IsHeadless)); if (Headless.IsHeadless) { Log.LogInfo((object)"vsm.buildcam: servidor dedicado: solo configuración, sin parches."); return; } VsmLocalization.Register(Log, Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), s_spanish); _harmony = new Harmony("vsm.buildcam"); PatchUtil.PatchAllSafely(Log, _harmony, Assembly.GetExecutingAssembly()); PatchesOk = OwnsPatch(BuildCamPatches.UpdateCameraMethod) && OwnsPatch(BuildCamPatches.SetMouseLookMethod) && OwnsPatch(BuildCamPatches.SetControlsMethod); ForeignOwners = string.Join(", ", ForeignPatchOwners(BuildCamPatches.UpdateCameraMethod, BuildCamPatches.GetCameraPositionMethod, BuildCamPatches.SetMouseLookMethod)); if (!PatchesOk) { Log.LogError((object)"vsm.buildcam: faltan parches críticos (UpdateCamera/SetMouseLook/SetControls); la cámara queda desactivada."); _harmony.UnpatchSelf(); _harmony = null; return; } if (!ReachPatched) { Log.LogWarning((object)"vsm.buildcam: el alcance de construcción no se pudo ampliar en todos los lectores; la cámara funciona pero con alcance vanilla en ellos."); } if (ForeignOwners.Length > 0) { Log.LogWarning((object)("vsm.buildcam: otros mods parchean la cámara: " + ForeignOwners + (RefuseIfForeignCameraPatches.Value ? " → la cámara no se activará (RefuseIfForeignCameraPatches)." : "."))); } } private static ConfigEntry<T> Synced<T>(ConfigEntry<T> entry) { ((ConditionalConfigSync)s_sync).AddConfigEntry<T>(entry, (ConfigSyncMode)0); return entry; } private static bool OwnsPatch(MethodBase method) { if (method == null) { return false; } Patches patchInfo = Harmony.GetPatchInfo(method); return patchInfo != null && patchInfo.Owners.Contains("vsm.buildcam"); } private static IEnumerable<string> ForeignPatchOwners(params MethodBase[] methods) { HashSet<string> hashSet = new HashSet<string>(); foreach (MethodBase methodBase in methods) { if (methodBase == null) { continue; } Patches patchInfo = Harmony.GetPatchInfo(methodBase); if (patchInfo == null) { continue; } foreach (string owner in patchInfo.Owners) { if (owner != "vsm.buildcam" && !owner.StartsWith("vsm.", StringComparison.Ordinal)) { hashSet.Add(owner); } } } return hashSet.OrderBy((string o) => o); } private void Update() { //IL_000e: Unknown result type (might be due to invalid IL or missing references) if (_harmony == null || !Keys.Pressed(ToggleKey.Value)) { return; } Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && !Console.IsVisible() && (!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus()) && !TextInput.IsVisible()) { Denial denial; if (Session.Active) { Session.Exit(Denial.User); } else if (!Session.TryEnter(localPlayer, out denial)) { Session.Notify(localPlayer, denial); } } } private void OnDestroy() { Session.Reset(); if (_harmony != null) { _harmony.UnpatchSelf(); } } internal static void Verbose(string message) { if (VerboseLog != null && VerboseLog.Value && Log != null) { Log.LogInfo((object)("vsm.buildcam: " + message)); } } } internal static class Session { public static Denial LastExit = Denial.None; public static readonly CameraRig Rig = new CameraRig(); private static Player s_player; private static float s_savedFov; private static float s_savedNear; private static bool s_savedValid; private static Vector3 s_move; private static float s_vertical; private static bool s_fast; private static float s_lastInputTime; private static bool s_damaged; private static Vector3 s_lastPos; private static float s_enteredAt; private static readonly BodyHider s_body = new BodyHider(); private static readonly Action<float, Character> s_damageHandler = OnDamaged; public static bool Active { get; private set; } public static float EffectiveReach => Mathf.Clamp(Mathf.Max(BuildCamPlugin.BuildReach.Value, EffectiveDistance + 5f), 8f, 50f); public static float EffectiveDistance => Mathf.Clamp(BuildCamPlugin.MaxCameraDistance.Value, 3f, 45f); public unsafe static bool TryEnter(Player player, out Denial denial) { //IL_009f: 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_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) denial = Guards.CanEnter(player); if (denial != Denial.None) { return false; } GameCamera instance = GameCamera.instance; if ((Object)(object)instance == (Object)null) { denial = Denial.Error; return false; } if (!CameraLock.TryAcquire("vsm.buildcam")) { denial = Denial.CameraBusy; return false; } try { s_player = player; s_savedFov = instance.m_fov; s_savedNear = (((Object)(object)instance.m_camera != (Object)null) ? instance.m_camera.nearClipPlane : instance.m_nearClipPlaneMin); s_savedValid = true; Rig.Reset(((Component)instance).transform.position, ((Component)instance).transform.forward); s_lastPos = Rig.Position; s_move = Vector3.zero; s_vertical = 0f; s_fast = false; s_damaged = false; s_lastInputTime = Time.time; s_enteredAt = Time.time; ((Character)player).m_onDamaged = (Action<float, Character>)Delegate.Combine(((Character)player).m_onDamaged, s_damageHandler); Active = true; LastExit = Denial.None; Message(player, (MessageType)2, "vsm_buildcam_on"); Vector3 position = Rig.Position; BuildCamPlugin.Verbose("cámara activada en " + ((object)(*(Vector3*)(&position))/*cast due to .constrained prefix*/).ToString()); return true; } catch (Exception ex) { BuildCamPlugin.Log.LogError((object)("vsm.buildcam: error al activar la cámara: " + ex)); Active = false; s_player = null; CameraLock.Release("vsm.buildcam"); denial = Denial.Error; return false; } } public static void Exit(Denial reason) { if (!Active) { return; } Active = false; LastExit = reason; Player val = s_player; s_player = null; try { GameCamera instance = GameCamera.instance; if ((Object)(object)instance != (Object)null && s_savedValid) { if ((Object)(object)instance.m_camera != (Object)null) { instance.m_camera.fieldOfView = s_savedFov; instance.m_camera.nearClipPlane = s_savedNear; } if ((Object)(object)instance.m_skyCamera != (Object)null) { instance.m_skyCamera.fieldOfView = s_savedFov; } } s_savedValid = false; s_body.Restore(); CameraLock.Release("vsm.buildcam"); if ((Object)(object)val != (Object)null) { ((Character)val).m_onDamaged = (Action<float, Character>)Delegate.Remove(((Character)val).m_onDamaged, s_damageHandler); Message(val, (MessageType)1, Guards.ExitToken(reason)); } BuildCamPlugin.Verbose("cámara cerrada: " + reason); } catch (Exception ex) { BuildCamPlugin.Log.LogWarning((object)("vsm.buildcam: error al cerrar la cámara: " + ex.Message)); } } public static void Reset() { if (Active) { Active = false; LastExit = Denial.NoPlayer; Player val = s_player; s_player = null; if ((Object)(object)val != (Object)null) { try { ((Character)val).m_onDamaged = (Action<float, Character>)Delegate.Remove(((Character)val).m_onDamaged, s_damageHandler); } catch (Exception) { } } } s_savedValid = false; s_body.Restore(); CameraLock.Release("vsm.buildcam"); } public static bool Owns(Player player) { return Active && (Object)(object)player != (Object)null && (Object)(object)player == (Object)(object)s_player; } public static void OnLook(Vector2 delta) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) if (!Guards.InputPaused() && !(delta == Vector2.zero)) { Rig.ApplyLook(delta); s_lastInputTime = Time.time; } } public static void OnControls(Vector3 movedir, bool jump, bool crouch, bool run) { //IL_0001: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) s_move = new Vector3(Mathf.Clamp(movedir.x, -1f, 1f), 0f, Mathf.Clamp(movedir.z, -1f, 1f)); bool flag = ZInput.GetButton("Jump") || ZInput.GetButton("JoyJump"); bool flag2 = ZInput.GetButton("Crouch") || ZInput.GetButton("JoyCrouch"); s_vertical = (flag ? 1f : 0f) - (flag2 ? 1f : 0f); s_fast = run; } public static bool UpdateCamera(GameCamera cam, float dt) { //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017d: 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_0182: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: 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) if (!Active) { return true; } try { Player player = s_player; Denial denial = Guards.MustExit(player, Time.time - s_lastInputTime, s_damaged); if (denial != Denial.None) { Exit(denial); return true; } bool flag = Guards.InputPaused(); RigSettings settings = new RigSettings { Speed = BuildCamPlugin.MoveSpeed.Value, FastMultiplier = BuildCamPlugin.FastMultiplier.Value, MoveRelativeToView = BuildCamPlugin.MoveRelativeToView.Value }; Vector3 val = (flag ? Vector3.zero : Rig.DesiredVelocity(s_move, s_vertical, s_fast, settings)); if (val != Vector3.zero) { s_lastInputTime = Time.time; } else if (!flag && (ZInput.GetMouseButton(0) || ZInput.GetMouseButton(1) || Mathf.Abs(ZInput.GetMouseScrollWheel()) > 0.0001f)) { s_lastInputTime = Time.time; } Rig.Integrate(val, dt, BuildCamPlugin.MoveSmoothing.Value); Vector3 val2 = CameraWorld.Constrain(s_lastPos, Rig.Position, CameraWorld.Anchor(player), EffectiveDistance, BuildCamPlugin.MinTerrainClearance.Value, cam); Rig.Velocity = ((dt > 0f) ? ((val2 - s_lastPos) / dt) : Vector3.zero); Rig.Position = val2; s_lastPos = val2; Transform transform = ((Component)cam).transform; transform.position = val2; transform.rotation = Rig.Rotation; float fieldOfView = ((BuildCamPlugin.FieldOfView.Value > 0f) ? BuildCamPlugin.FieldOfView.Value : cam.m_fov); if ((Object)(object)cam.m_camera != (Object)null) { cam.m_camera.fieldOfView = fieldOfView; cam.m_camera.nearClipPlane = cam.m_nearClipPlaneMin; } if ((Object)(object)cam.m_skyCamera != (Object)null) { cam.m_skyCamera.fieldOfView = fieldOfView; } s_body.Update(player, BuildCamPlugin.HideLocalPlayer.Value); return false; } catch (Exception ex) { BuildCamPlugin.Log.LogError((object)("vsm.buildcam: error en la cámara, se vuelve a la vanilla: " + ex)); Exit(Denial.Error); return true; } } private static void OnDamaged(float damage, Character attacker) { if (damage > 0f) { s_damaged = true; } } public static void Message(Player player, MessageType type, string token, params object[] args) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)player == (Object)null) && BuildCamPlugin.ShowMessages.Value) { ((Character)player).Message(type, VsmLocalization.Localize(token, args), 0, (Sprite)null, false); } } public static void Notify(Player player, Denial denial) { switch (denial) { case Denial.Combat: Message(player, (MessageType)1, Guards.DenialToken(denial), Mathf.CeilToInt(Guards.CombatRemaining(player))); break; case Denial.ForeignPatches: Message(player, (MessageType)1, Guards.DenialToken(denial), BuildCamPlugin.ForeignOwners); break; default: Message(player, (MessageType)1, Guards.DenialToken(denial)); break; } } public unsafe static IEnumerable<string> StatusLines() { yield return "vsm.buildcam 0.1.4 | parches=" + (BuildCamPlugin.PatchesOk ? "ok" : "FALTAN") + " | alcance ampliado=" + (BuildCamPlugin.ReachPatched ? "sí" : "no") + " | config lista=" + BuildCamPlugin.IsConfigReady; string[] obj = new string[5] { "activa=", Active.ToString(), " | última salida=", LastExit.ToString(), null }; string text; if (!Active) { text = string.Empty; } else { string[] obj2 = new string[8] { " | tiempo=", Mathf.RoundToInt(Time.time - s_enteredAt).ToString(), " s | pos=", null, null, null, null, null }; Vector3 position = Rig.Position; obj2[3] = ((object)(*(Vector3*)(&position))/*cast due to .constrained prefix*/).ToString(); obj2[4] = " yaw="; obj2[5] = Mathf.RoundToInt(Rig.Yaw).ToString(); obj2[6] = " pitch="; obj2[7] = Mathf.RoundToInt(Rig.Pitch).ToString(); text = string.Concat(obj2); } obj[4] = text; yield return string.Concat(obj); yield return "límites: enabled=" + BuildCamPlugin.Enabled.Value + " distancia=" + EffectiveDistance + " alcance=" + EffectiveReach + " holgura=" + BuildCamPlugin.MinTerrainClearance.Value + " combate=" + BuildCamPlugin.CombatCooldownSeconds.Value + "s inactividad=" + BuildCamPlugin.IdleTimeoutSeconds.Value + "s banco=" + BuildCamPlugin.RequireCraftingStationNearby.Value + " bancoDesdeJugador=" + BuildCamPlugin.StationRangeFromPlayer.Value + " salirConDaño=" + BuildCamPlugin.ExitOnDamage.Value; yield return "otros parches en la cámara: " + ((BuildCamPlugin.ForeignOwners.Length > 0) ? BuildCamPlugin.ForeignOwners : "ninguno"); Player p = Player.m_localPlayer; if ((Object)(object)p != (Object)null) { yield return "jugador: herramienta=" + ((Character)p).InPlaceMode() + " banco cerca=" + Guards.StationNearby(((Component)p).transform.position) + " combate restante=" + Guards.CombatRemaining(p).ToString("0.0") + "s m_maxPlaceDistance=" + p.m_maxPlaceDistance; } } } public enum Denial { None, User, PatchesMissing, Disabled, ConfigNotReady, NoPlayer, ForeignPatches, CameraBusy, FreeFly, UiOpen, Dead, Cutscene, Teleporting, Swimming, Attached, NoTool, Combat, NoStation, Damaged, Idle, Error } internal static class Guards { public static bool UiOpen() { if ((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus()) { return true; } if (Console.IsVisible() || TextInput.IsVisible() || StoreGui.IsVisible() || InventoryGui.IsVisible() || Menu.IsVisible() || Minimap.IsOpen() || Hud.IsPieceSelectionVisible() || Hud.InRadial() || UnifiedPopup.IsVisible() || PlayerCustomizaton.IsBarberGuiVisible()) { return true; } if ((Object)(object)TextViewer.instance != (Object)null && TextViewer.instance.IsVisible()) { return true; } if ((Object)(object)Hud.instance != (Object)null && (Object)(object)Hud.instance.m_buildUi != (Object)null && Hud.instance.m_buildUi.SearchFieldFocused) { return true; } return false; } public static bool InputPaused() { return UiOpen(); } public static float CombatRemaining(Player player) { return Mathf.Max(0f, BuildCamPlugin.CombatCooldownSeconds.Value - player.m_timeSinceSensed); } public static Denial CanEnter(Player player) { //IL_00f5: Unknown result type (might be due to invalid IL or missing references) if (!BuildCamPlugin.PatchesOk) { return Denial.PatchesMissing; } if (!BuildCamPlugin.Enabled.Value) { return Denial.Disabled; } if (!BuildCamPlugin.IsConfigReady) { return Denial.ConfigNotReady; } if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer) { return Denial.NoPlayer; } if (BuildCamPlugin.RefuseIfForeignCameraPatches.Value && BuildCamPlugin.ForeignOwners.Length > 0) { return Denial.ForeignPatches; } if (GameCamera.InFreeFly()) { return Denial.FreeFly; } if (UiOpen()) { return Denial.UiOpen; } Denial denial = BodyState(player); if (denial != Denial.None) { return denial; } if (CombatRemaining(player) > 0f) { return Denial.Combat; } if (BuildCamPlugin.RequireCraftingStationNearby.Value && !StationNearby(((Component)player).transform.position)) { return Denial.NoStation; } return Denial.None; } public static Denial MustExit(Player player, float idleSeconds, bool damaged) { if (!BuildCamPlugin.PatchesOk) { return Denial.PatchesMissing; } if (!BuildCamPlugin.Enabled.Value) { return Denial.Disabled; } if (!BuildCamPlugin.IsConfigReady) { return Denial.ConfigNotReady; } if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer) { return Denial.NoPlayer; } if (GameCamera.InFreeFly()) { return Denial.FreeFly; } Denial denial = BodyState(player); if (denial != Denial.None) { return denial; } if (player.IsSensed()) { return Denial.Combat; } if (damaged && BuildCamPlugin.ExitOnDamage.Value) { return Denial.Damaged; } float value = BuildCamPlugin.IdleTimeoutSeconds.Value; if (value > 0f && idleSeconds > value) { return Denial.Idle; } return Denial.None; } private static Denial BodyState(Player player) { if (((Character)player).IsDead()) { return Denial.Dead; } if (((Character)player).InCutscene() || ((Character)player).InIntro()) { return Denial.Cutscene; } if (((Character)player).IsTeleporting()) { return Denial.Teleporting; } if (((Character)player).IsSwimming()) { return Denial.Swimming; } if (((Character)player).IsAttached() || ((Character)player).IsRiding() || ((Character)player).InBed() || ((Character)player).IsSitting() || player.GetDoodadController() != null) { return Denial.Attached; } if (!((Character)player).InPlaceMode()) { return Denial.NoTool; } return Denial.None; } public static bool StationNearby(Vector3 point) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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_0054: Unknown result type (might be due to invalid IL or missing references) List<CraftingStation> allStations = CraftingStation.m_allStations; if (allStations == null) { return false; } for (int i = 0; i < allStations.Count; i++) { CraftingStation val = allStations[i]; if (!((Object)(object)val == (Object)null)) { Vector3 position = ((Component)val).transform.position; Vector3 val2 = point; val2.y = position.y; if (Vector3.Distance(position, val2) < val.GetStationBuildRange()) { return true; } } } return false; } public static string DenialToken(Denial denial) { return "vsm_buildcam_deny_" + denial.ToString().ToLowerInvariant(); } public static string ExitToken(Denial denial) { return (denial == Denial.User) ? "vsm_buildcam_off" : ("vsm_buildcam_exit_" + denial.ToString().ToLowerInvariant()); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "vsm.buildcam"; public const string PLUGIN_NAME = "MEL BuildCam"; public const string PLUGIN_VERSION = "0.1.4"; } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class <e8ce6e11-cfd4-4a54-b4bb-a6a898b34399>IgnoresAccessChecksToAttribute : Attribute { public <e8ce6e11-cfd4-4a54-b4bb-a6a898b34399>IgnoresAccessChecksToAttribute(string assemblyName) { } } } namespace VSM.Core.Ui { internal static class VanillaStyle { public static TMP_Text TitleFont => ((Object)(object)InventoryGui.instance != (Object)null) ? InventoryGui.instance.m_playerName : null; public static TMP_Text BodyFont => (!((Object)(object)InventoryGui.instance != (Object)null)) ? null : (((Object)(object)InventoryGui.instance.m_armor != (Object)null) ? InventoryGui.instance.m_armor : InventoryGui.instance.m_playerName); public static Image FindBackground(Transform root, Transform exclude1, Transform exclude2) { //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)root == (Object)null) { return null; } Image result = null; float num = 0f; Image[] componentsInChildren = ((Component)root).GetComponentsInChildren<Image>(true); foreach (Image val in componentsInChildren) { if ((Object)(object)val == (Object)null || (Object)(object)val.sprite == (Object)null) { continue; } Transform transform = ((Component)val).transform; if ((!((Object)(object)exclude1 != (Object)null) || !transform.IsChildOf(exclude1)) && (!((Object)(object)exclude2 != (Object)null) || !transform.IsChildOf(exclude2))) { Rect rect = ((Graphic)val).rectTransform.rect; float num2 = Mathf.Abs(((Rect)(ref rect)).width * ((Rect)(ref rect)).height); if (num2 > num) { num = num2; result = val; } } } return result; } public static bool CopyImage(Image source, Image target) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target == (Object)null) { return false; } if ((Object)(object)source == (Object)null) { ((Graphic)target).color = new Color(0f, 0f, 0f, 0.6f); return false; } target.sprite = source.sprite; target.type = source.type; ((Graphic)target).material = ((Graphic)source).material; ((Graphic)target).color = ((Graphic)source).color; target.fillCenter = source.fillCenter; target.pixelsPerUnitMultiplier = source.pixelsPerUnitMultiplier; target.preserveAspect = false; return true; } public static Image InventoryBackground(Transform exclude) { InventoryGui instance = InventoryGui.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.m_player == (Object)null) { return null; } Transform exclude2 = (Transform)(object)(((Object)(object)instance.m_playerGrid != (Object)null) ? instance.m_playerGrid.m_gridRoot : null); return FindBackground((Transform)(object)instance.m_player, exclude2, exclude); } public static void CopyFont(TMP_Text source, TMP_Text target) { //IL_0037: 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) if (!((Object)(object)source == (Object)null) && !((Object)(object)target == (Object)null)) { target.font = source.font; target.fontSharedMaterial = source.fontSharedMaterial; ((Graphic)target).color = ((Graphic)source).color; target.fontStyle = source.fontStyle; } } public static TextMeshProUGUI NewText(Transform parent, string name, TMP_Text style, float size, TextAlignmentOptions align) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0041: 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(parent, false); TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>(); CopyFont(style, (TMP_Text)(object)val2); ((TMP_Text)val2).fontSize = size; ((TMP_Text)val2).alignment = align; ((Graphic)val2).raycastTarget = false; ((TMP_Text)val2).enableWordWrapping = false; ((TMP_Text)val2).richText = true; return val2; } } } namespace VSM.Core.Runtime { internal static class Headless { private static bool? s_isHeadless; public static bool IsHeadless { get { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 if (!s_isHeadless.HasValue) { s_isHeadless = (int)SystemInfo.graphicsDeviceType == 4 || Application.isBatchMode; } return s_isHeadless.Value; } } public static bool IsServerProcess => (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer(); public static bool IsDedicatedServer => (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && ZNet.instance.IsDedicated(); public static bool IsListenHost => (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && !ZNet.instance.IsDedicated(); public static bool IsRemoteClient => (Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer(); } internal static class Keys { public static bool Pressed(KeyboardShortcut shortcut) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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) KeyCode mainKey = ((KeyboardShortcut)(ref shortcut)).MainKey; return (int)mainKey != 0 && ZInput.GetKeyDown(mainKey, false) && ((KeyboardShortcut)(ref shortcut)).Modifiers.All((KeyCode m) => ZInput.GetKey(m, false)); } } } namespace VSM.Core.Reflection { internal static class GameConstants { private static uint? s_networkVersion; private static long? s_routedEverybody; public static uint NetworkVersion { get { if (!s_networkVersion.HasValue) { s_networkVersion = ReadConstant<uint>(typeof(Version), new string[2] { "c_networkVersion", "m_networkVersion" }); } return s_networkVersion.Value; } } public static long RoutedRpcEverybody { get { if (!s_routedEverybody.HasValue) { s_routedEverybody = ReadConstant<long>(typeof(ZRoutedRpc), new string[1] { "Everybody" }); } return s_routedEverybody.Value; } } public static string GameVersionString { get { //IL_0002: 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) try { return ((object)Version.CurrentVersion/*cast due to .constrained prefix*/).ToString(); } catch (Exception) { return "?"; } } } private static T ReadConstant<T>(Type type, params string[] names) where T : struct { foreach (string name in names) { FieldInfo field = type.GetField(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (!(field == null)) { object obj = (field.IsLiteral ? field.GetRawConstantValue() : field.GetValue(null)); if (obj is T result) { return result; } try { return (T)Convert.ChangeType(obj, typeof(T)); } catch (Exception) { } } } return default(T); } } } namespace VSM.Core.Net { internal static class ZPackageExt { public static bool HasMore(this ZPackage pkg) { return pkg != null && pkg.GetPos() < pkg.Size(); } public static int ReadIntOr(this ZPackage pkg, int fallback) { return pkg.HasMore() ? pkg.ReadInt() : fallback; } public static string ReadStringOr(this ZPackage pkg, string fallback) { return pkg.HasMore() ? pkg.ReadString() : fallback; } public static bool ReadBoolOr(this ZPackage pkg, bool fallback) { return pkg.HasMore() ? pkg.ReadBool() : fallback; } public static string ReadBoundedString(this ZPackage pkg, int maxLength) { string text = pkg.ReadString(); return (text != null && text.Length <= maxLength) ? text : null; } } } namespace VSM.Core.Localization { internal static class VsmLocalization { public static void Register(ManualLogSource log, string pluginDirectory, IDictionary<string, string> embeddedSpanish) { Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.Ordinal); if (embeddedSpanish != null) { foreach (KeyValuePair<string, string> item in embeddedSpanish) { dictionary[item.Key] = item.Value; } } string path = Path.Combine(pluginDirectory ?? string.Empty, "Translations"); MergeFile(log, Path.Combine(path, "Spanish.json"), dictionary); string text = SafeSelectedLanguage(); if (!string.Equals(text, "Spanish", StringComparison.OrdinalIgnoreCase)) { MergeFile(log, Path.Combine(path, text + ".json"), dictionary); } Apply(log, dictionary); } public static string Localize(string token, params object[] args) { string text = token; try { if (Localization.instance != null && !string.IsNullOrEmpty(token)) { bool flag = token[0] != '$' && token.IndexOf(' ') < 0 && token.IndexOf('\n') < 0; string text2 = Localization.instance.Localize(flag ? ("$" + token) : token); text = ((flag && text2.Length > 1 && text2[0] == '[' && text2[text2.Length - 1] == ']') ? token : text2); } } catch (Exception) { text = token; } if (args != null && args.Length != 0) { try { text = string.Format(text, args); } catch (FormatException) { } } return text; } private static string SafeSelectedLanguage() { try { return (Localization.instance != null) ? Localization.instance.GetSelectedLanguage() : "Spanish"; } catch (Exception) { return "Spanish"; } } private static void Apply(ManualLogSource log, Dictionary<string, string> words) { if (Localization.instance == null) { if (log != null) { log.LogWarning((object)"Localization.instance aún no existe; las traducciones no se han aplicado."); } return; } foreach (KeyValuePair<string, string> word in words) { string text = (word.Key.StartsWith("$", StringComparison.Ordinal) ? word.Key.Substring(1) : word.Key); Localization.instance.AddWord(text, word.Value); } } private static void MergeFile(ManualLogSource log, string path, Dictionary<string, string> into) { if (!File.Exists(path)) { return; } try { foreach (KeyValuePair<string, string> item in ParseFlatJson(File.ReadAllText(path, Encoding.UTF8))) { into[item.Key] = item.Value; } } catch (Exception ex) { if (log != null) { log.LogWarning((object)("No se pudo leer " + path + ": " + ex.Message)); } } } public static Dictionary<string, string> ParseFlatJson(string json) { Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.Ordinal); if (string.IsNullOrEmpty(json)) { return dictionary; } int i = 0; SkipWs(json, ref i); if (i >= json.Length || json[i] != '{') { return dictionary; } i++; while (true) { SkipWs(json, ref i); if (i >= json.Length || json[i] == '}') { break; } if (json[i] == ',') { i++; continue; } string text = ReadString(json, ref i); if (text == null) { i++; continue; } SkipWs(json, ref i); if (i < json.Length && json[i] == ':') { i++; } SkipWs(json, ref i); if (i < json.Length && json[i] == '"') { string text2 = ReadString(json, ref i); dictionary[text] = text2 ?? string.Empty; } else { for (; i < json.Length && json[i] != ',' && json[i] != '}'; i++) { } } } return dictionary; } private static void SkipWs(string s, ref int i) { while (i < s.Length && char.IsWhiteSpace(s[i])) { i++; } } private static string ReadString(string s, ref int i) { if (i >= s.Length || s[i] != '"') { return null; } i++; StringBuilder stringBuilder = new StringBuilder(); while (i < s.Length) { char c = s[i++]; switch (c) { case '"': return stringBuilder.ToString(); case '\\': { if (i >= s.Length) { break; } char c2 = s[i++]; switch (c2) { case 'n': stringBuilder.Append('\n'); break; case 't': stringBuilder.Append('\t'); break; case 'r': stringBuilder.Append('\r'); break; case 'b': stringBuilder.Append('\b'); break; case 'f': stringBuilder.Append('\f'); break; case 'u': if (i + 4 <= s.Length) { stringBuilder.Append((char)Convert.ToInt32(s.Substring(i, 4), 16)); i += 4; } break; default: stringBuilder.Append(c2); break; } continue; } } stringBuilder.Append(c); } return stringBuilder.ToString(); } } } namespace VSM.Core.Harmony { internal static class PatchUtil { private static readonly List<string> s_failed = new List<string>(); public static IReadOnlyList<string> FailedTargets => s_failed; public static bool IsDegraded => s_failed.Count > 0; public static MethodInfo DeclaredMethodOrNull(ManualLogSource log, Type type, string name, Type[] parameters, string owner) { if (type == null) { Fail(log, owner, name + " (tipo nulo)"); return null; } MethodInfo methodInfo = AccessTools.DeclaredMethod(type, name, parameters, (Type[])null); if (methodInfo == null) { Fail(log, owner, type.FullName + "." + name + "(" + Describe(parameters) + ")"); } return methodInfo; } public static void PatchAllSafely(ManualLogSource log, Harmony harmony, Assembly assembly) { Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(assembly); foreach (Type type in typesFromAssembly) { if (type.GetCustomAttributes(typeof(HarmonyPatch), inherit: true).Length != 0) { PatchClassSafely(log, harmony, type); } } } public static bool PatchClassSafely(ManualLogSource log, Harmony harmony, Type patchClass) { try { harmony.CreateClassProcessor(patchClass).Patch(); return true; } catch (Exception ex) { Fail(log, harmony.Id, patchClass.FullName + " -> " + ex.GetType().Name + ": " + ex.Message); return false; } } private static void Fail(ManualLogSource log, string owner, string what) { s_failed.Add(what); if (log != null) { log.LogError((object)("[" + owner + "] No se pudo aplicar el parche (¿cambió el juego?): " + what + ". El mod sigue cargado en modo degradado.")); } } private static string Describe(Type[] parameters) { if (parameters == null || parameters.Length == 0) { return string.Empty; } string[] array = new string[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { array[i] = ((parameters[i] == null) ? "?" : parameters[i].Name); } return string.Join(", ", array); } } } namespace VSM.Core.Config { internal sealed class ConfigurationManagerAttributes { public bool? ShowRangeAsPercent; public Action<ConfigEntryBase> CustomDrawer; public bool? Browsable; public string Category; public object DefaultValue; public bool? HideDefaultButton; public bool? HideSettingName; public string Description; public string DispName; public int? Order; public bool? ReadOnly; public bool? IsAdvanced; public bool? IsAdminOnly; public Func<object, string> ObjToStr; public Func<string, object> StrToObj; } } namespace VSM.Core.Camera { internal struct RigSettings { public float Speed; public float FastMultiplier; public bool MoveRelativeToView; } internal sealed class CameraRig { public const float MaxPitch = 89f; public float Yaw; public float Pitch; public Vector3 Position; public Vector3 Velocity; public Vector3 ForwardVector => Forward(Yaw, Pitch); public Quaternion Rotation => Quaternion.Euler(Pitch, Yaw, 0f); public static Vector3 Forward(float yawDeg, float pitchDeg) { //IL_002f: 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) //IL_0037: Unknown result type (might be due to invalid IL or missing references) float num = yawDeg * ((float)Math.PI / 180f); float num2 = pitchDeg * ((float)Math.PI / 180f); float num3 = Mathf.Cos(num2); return new Vector3(Mathf.Sin(num) * num3, 0f - Mathf.Sin(num2), Mathf.Cos(num) * num3); } public static Vector3 FlatForward(float yawDeg) { //IL_001a: 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_0022: Unknown result type (might be due to invalid IL or missing references) float num = yawDeg * ((float)Math.PI / 180f); return new Vector3(Mathf.Sin(num), 0f, Mathf.Cos(num)); } public static Vector3 Right(float yawDeg) { //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_0023: Unknown result type (might be due to invalid IL or missing references) float num = yawDeg * ((float)Math.PI / 180f); return new Vector3(Mathf.Cos(num), 0f, 0f - Mathf.Sin(num)); } public void Reset(Vector3 position, Vector3 forward) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) Position = position; Velocity = Vector3.zero; SetFromDirection(forward); } public void SetFromDirection(Vector3 forward) { //IL_0035: 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_005c: Unknown result type (might be due to invalid IL or missing references) if (((Vector3)(ref forward)).sqrMagnitude < 1E-08f) { Yaw = 0f; Pitch = 0f; } else { ((Vector3)(ref forward)).Normalize(); Yaw = Mathf.Repeat(Mathf.Atan2(forward.x, forward.z) * 57.29578f, 360f); Pitch = Mathf.Clamp((0f - Mathf.Asin(Mathf.Clamp(forward.y, -1f, 1f))) * 57.29578f, -89f, 89f); } } public void ApplyLook(Vector2 delta) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) Yaw = Mathf.Repeat(Yaw + delta.x, 360f); Pitch = Mathf.Clamp(Pitch - delta.y, -89f, 89f); } public Vector3 DesiredVelocity(Vector3 move, float vertical, bool fast, RigSettings settings) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //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_0083: 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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: 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_00df: 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) Vector3 val = (settings.MoveRelativeToView ? Forward(Yaw, Pitch) : FlatForward(Yaw)); Vector3 val2 = Right(Yaw) * Mathf.Clamp(move.x, -1f, 1f) + val * Mathf.Clamp(move.z, -1f, 1f) + Vector3.up * Mathf.Clamp(vertical, -1f, 1f); if (((Vector3)(ref val2)).sqrMagnitude > 1f) { ((Vector3)(ref val2)).Normalize(); } float num = Mathf.Max(0f, settings.Speed) * (fast ? Mathf.Max(1f, settings.FastMultiplier) : 1f); return val2 * num; } public void Integrate(Vector3 desiredVelocity, float dt, float smoothing) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0047: 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) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) if (!(dt <= 0f)) { float num = ((smoothing <= 0f) ? 1f : (1f - Mathf.Exp((0f - dt) / smoothing))); Velocity = Vector3.Lerp(Velocity, desiredVelocity, num); Position += Velocity * dt; } } public static Vector3 ClampToSphere(Vector3 pos, Vector3 center, float radius) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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) Vector3 val = pos - center; float num = Mathf.Max(0f, radius); if (((Vector3)(ref val)).sqrMagnitude <= num * num) { return pos; } return center + ((Vector3)(ref val)).normalized * num; } } internal static class CameraWorld { public const float CollisionRadius = 0.25f; public static Vector3 Anchor(Player player) { //IL_0033: 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_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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) Transform eye = ((Character)player).m_eye; return ((Object)(object)eye != (Object)null) ? eye.position : (((Component)player).transform.position + Vector3.up * 1.6f); } public static Vector3 Constrain(Vector3 from, Vector3 to, Vector3 anchor, float maxDistance, float clearance, GameCamera cam) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0038: 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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) Vector3 pos = CameraRig.ClampToSphere(to, anchor, maxDistance); pos = Lift(pos, clearance, cam); pos = CameraRig.ClampToSphere(pos, anchor, maxDistance + 1f); LayerMask blockCameraMask = cam.m_blockCameraMask; Vector3 val = (Overlaps(from, blockCameraMask) ? anchor : from); return Collide(val, pos, blockCameraMask); } public static Vector3 Lift(Vector3 pos, float clearance, GameCamera cam) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) clearance = Mathf.Max(0f, clearance); ZoneSystem instance = ZoneSystem.instance; float num = default(float); if ((Object)(object)instance != (Object)null && instance.GetGroundHeight(pos, ref num)) { pos.y = Mathf.Max(pos.y, num + clearance); } float num2 = Floating.GetLiquidLevel(pos, 1f, (LiquidType)10); if ((Object)(object)instance != (Object)null && !Character.InInterior(pos)) { num2 = Mathf.Max(num2, instance.m_waterLevel); } if (num2 > -9000f) { pos.y = Mathf.Max(pos.y, num2 + Mathf.Max(clearance, cam.m_minWaterDistance)); } return pos; } public static bool Overlaps(Vector3 pos, LayerMask mask) { //IL_0001: 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) return Physics.CheckSphere(pos, 0.225f, LayerMask.op_Implicit(mask), (QueryTriggerInteraction)1); } public static Vector3 Collide(Vector3 from, Vector3 to, LayerMask mask) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0033: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) Vector3 val = to - from; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude < 1E-05f) { return to; } Vector3 val2 = val / magnitude; RaycastHit val3 = default(RaycastHit); if (Physics.SphereCast(from, 0.25f, val2, ref val3, magnitude, LayerMask.op_Implicit(mask), (QueryTriggerInteraction)1)) { return from + val2 * Mathf.Max(0f, ((RaycastHit)(ref val3)).distance - 0.02f); } return to; } } internal static class CameraLock { private const string Prefix = "vsm_camera_lock:"; public static string Holder() { GameCamera instance = GameCamera.instance; if ((Object)(object)instance == (Object)null) { return null; } Transform transform = ((Component)instance).transform; for (int i = 0; i < transform.childCount; i++) { string name = ((Object)transform.GetChild(i)).name; if (name.StartsWith("vsm_camera_lock:", StringComparison.Ordinal)) { return name.Substring("vsm_camera_lock:".Length); } } return null; } public static bool TryAcquire(string owner) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown GameCamera instance = GameCamera.instance; if ((Object)(object)instance == (Object)null) { return false; } string text = Holder(); if (text != null) { return text == owner; } GameObject val = new GameObject("vsm_camera_lock:" + owner); val.transform.SetParent(((Component)instance).transform, false); return true; } public static void Release(string owner) { GameCamera instance = GameCamera.instance; if ((Object)(object)instance == (Object)null) { return; } Transform transform = ((Component)instance).transform; for (int num = transform.childCount - 1; num >= 0; num--) { Transform child = transform.GetChild(num); if (((Object)child).name == "vsm_camera_lock:" + owner) { Object.Destroy((Object)(object)((Component)child).gameObject); ((Object)child).name = "vsm_camera_lock_released"; } } } } internal sealed class BodyHider { private readonly List<Renderer> _hidden = new List<Renderer>(); private float _nextScan; public void Update(Player player, bool hide) { if (!hide || (Object)(object)player == (Object)null) { Restore(); } else { if (Time.unscaledTime < _nextScan) { return; } _nextScan = Time.unscaledTime + 0.5f; Renderer[] componentsInChildren = ((Component)player).GetComponentsInChildren<Renderer>(false); foreach (Renderer val in componentsInChildren) { if ((Object)(object)val != (Object)null && val.enabled && (val is SkinnedMeshRenderer || val is MeshRenderer)) { val.enabled = false; _hidden.Add(val); } } } } public void Restore() { foreach (Renderer item in _hidden) { if ((Object)(object)item != (Object)null) { item.enabled = true; } } _hidden.Clear(); _nextScan = 0f; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }
plugins/VSM.Carto/VSM.Carto.dll
Decompiled 3 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; 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.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ConditionalConfigSync; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.Rendering; using UnityEngine.UI; using VSM.Carto.Canvas; using VSM.Carto.Net; using VSM.Core.Config; using VSM.Core.Harmony; using VSM.Core.Localization; using VSM.Core.Reflection; using VSM.Core.Runtime; using VSM.Core.Ui; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: <30f83a53-8a06-4361-bc63-eb849fdfbd64>IgnoresAccessChecksTo("assembly_guiutils")] [assembly: <30f83a53-8a06-4361-bc63-eb849fdfbd64>IgnoresAccessChecksTo("assembly_utils")] [assembly: <30f83a53-8a06-4361-bc63-eb849fdfbd64>IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("VSM.Carto")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("0.1.4.0")] [assembly: AssemblyInformationalVersion("0.1.4+ff27bc889ccf218c61c45d3417d48ab708a5ba8f")] [assembly: AssemblyProduct("VSM.Carto")] [assembly: AssemblyTitle("VSM.Carto")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.4.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace VSM.Carto { internal static class CartoPatches { [HarmonyPatch(typeof(ZNetScene), "Awake")] private static class ZNetSceneAwakePatch { [HarmonyPostfix] [HarmonyPriority(0)] private static void Postfix(ZNetScene __instance) { CartoPrefabs.EnsureClones(); CartoPrefabs.Register(__instance); CanvasServer.SetTablePrefabs(__instance.m_prefabs); if ((Object)(object)ObjectDB.instance != (Object)null) { CartoPrefabs.RegisterItems(ObjectDB.instance); } CartoPlugin.Log.LogInfo((object)("vsm.carto: prefabs listos=" + CartoPrefabs.Ready + ", mesas de cartografía reconocidas=" + CanvasServer.TablePrefabCount)); } } [HarmonyPatch(typeof(ObjectDB), "Awake")] private static class ObjectDbAwakePatch { [HarmonyPostfix] [HarmonyPriority(0)] private static void Postfix(ObjectDB __instance) { CartoPrefabs.EnsureClones(); CartoPrefabs.RegisterItems(__instance); } } [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB", new Type[] { typeof(ObjectDB) })] private static class ObjectDbCopyPatch { [HarmonyPostfix] [HarmonyPriority(0)] private static void Postfix(ObjectDB __instance) { CartoPrefabs.EnsureClones(); CartoPrefabs.RegisterItems(__instance); } } [HarmonyPatch(typeof(Game), "Start")] private static class GameStartPatch { [HarmonyPostfix] private static void Postfix() { CartoNet.Register(); } } [HarmonyPatch(typeof(ZNet), "Save", new Type[] { typeof(bool), typeof(bool), typeof(bool) })] private static class ZNetSavePatch { [HarmonyPostfix] private static void Postfix() { if (CanvasServer.IsServer) { CanvasServer.SaveAll(); } } } [HarmonyPatch(typeof(ZNet), "OnDestroy")] private static class ZNetDestroyPatch { [HarmonyPrefix] private static void Prefix() { CanvasServer.Reset(); if (CanvasClient.Active) { CanvasClient.End(); } } } [HarmonyPatch(typeof(MapTable), "Start")] private static class MapTableStartPatch { [HarmonyPostfix] private static void Postfix(MapTable __instance) { //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Expected O, but got Unknown //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Expected O, but got Unknown //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Expected O, but got Unknown //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Expected O, but got Unknown if ((Object)(object)__instance.m_readSwitch != (Object)null) { Callback vanillaUse = __instance.m_readSwitch.m_onUse; TooltipCallback vanillaHover = __instance.m_readSwitch.m_onHover; __instance.m_readSwitch.m_onUse = (Callback)((Switch caller, Humanoid user, ItemData item) => (!Disabled()) ? OnDraw(__instance, user, item) : (vanillaUse != null && vanillaUse.Invoke(caller, user, item))); __instance.m_readSwitch.m_onHover = (TooltipCallback)(() => (Disabled() && vanillaHover != null) ? vanillaHover.Invoke() : Hover(__instance, "vsm_carto_draw")); } if ((Object)(object)__instance.m_writeSwitch != (Object)null) { Callback vanillaUse2 = __instance.m_writeSwitch.m_onUse; TooltipCallback vanillaHover2 = __instance.m_writeSwitch.m_onHover; __instance.m_writeSwitch.m_onUse = (Callback)((Switch caller, Humanoid user, ItemData item) => (!Disabled()) ? OnPrint(__instance, user, item) : (vanillaUse2 != null && vanillaUse2.Invoke(caller, user, item))); __instance.m_writeSwitch.m_onHover = (TooltipCallback)(() => (Disabled() && vanillaHover2 != null) ? vanillaHover2.Invoke() : Hover(__instance, "vsm_carto_print_hover")); } } } [HarmonyPatch(typeof(GameCamera), "UpdateMouseCapture")] private static class MouseCapturePatch { [HarmonyPostfix] private static void Postfix() { if (CartoWindow.IsOpen) { ZCursor.LockState = (CursorLockMode)0; ZCursor.Show(); } } } [HarmonyPatch(typeof(Player), "TakeInput")] private static class TakeInputPatch { [HarmonyPostfix] private static void Postfix(ref bool __result) { if (CartoWindow.IsOpen) { __result = false; } } } [HarmonyPatch(typeof(Player), "SetMouseLook", new Type[] { typeof(Vector2) })] private static class MouseLookPatch { [HarmonyPrefix] private static bool Prefix(Player __instance) { return !CartoWindow.IsOpen || !((Object)(object)__instance == (Object)(object)Player.m_localPlayer); } } [HarmonyPatch(typeof(Player), "SetControls", new Type[] { typeof(Vector3), typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(bool) })] private static class SetControlsPatch { [HarmonyPrefix] private static void Prefix(Player __instance, ref Vector3 movedir, ref bool attack, ref bool attackHold, ref bool secondaryAttack, ref bool secondaryAttackHold, ref bool block, ref bool blockHold, ref bool jump, ref bool crouch, ref bool run, ref bool autoRun, ref bool dodge) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) if (CartoWindow.IsOpen && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { __instance.m_autoRun = false; movedir = Vector3.zero; attack = (attackHold = (secondaryAttack = (secondaryAttackHold = false))); block = (blockHold = (jump = (crouch = (run = (autoRun = (dodge = false)))))); } } } [HarmonyPatch(typeof(Menu), "Update")] private static class MenuUpdatePatch { [HarmonyPrefix] private static bool Prefix() { return !CartoWindow.IsOpen; } } [HarmonyPatch(typeof(Humanoid), "UseItem", new Type[] { typeof(Inventory), typeof(ItemData), typeof(bool) })] private static class UseItemPatch { [HarmonyPrefix] private static bool Prefix(Humanoid __instance, ItemData item, bool fromInventoryGui) { if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || !MapData.IsMap(item)) { return true; } if (!fromInventoryGui) { GameObject hoverObject = __instance.GetHoverObject(); if ((Object)(object)hoverObject != (Object)null && ((Object)(object)hoverObject.GetComponentInParent<MapFrame>() != (Object)null || (Object)(object)hoverObject.GetComponentInParent<ItemStand>() != (Object)null)) { return true; } } CartoPlugin.LastViewedMap = item; item.m_customData.TryGetValue("vsm_carto_author", out var value); CartoWindow.OpenView(MapData.FromItem(item), MapData.Title(item), value); return false; } } [HarmonyPatch(typeof(ItemData), "GetTooltip", new Type[] { typeof(ItemData), typeof(int), typeof(bool), typeof(float), typeof(int), typeof(bool) })] private static class TooltipPatch { [HarmonyPostfix] private static void Postfix(ItemData item, ref string __result) { try { if (MapData.IsMap(item)) { item.m_customData.TryGetValue("vsm_carto_author", out var value); __result = "<color=orange>" + MapData.Title(item) + "</color>" + (string.IsNullOrEmpty(value) ? string.Empty : (" (" + value + ")")) + "\n" + __result; } } catch (Exception) { } } } [HarmonyPatch(typeof(ItemStand), "CanAttach")] private static class CanAttachPatch { [HarmonyPrefix] private static bool Prefix(ItemStand __instance, ItemData item, ref bool __result) { if (item == null || !MapData.IsMap(item) || !CartoPlugin.Active) { return true; } __result = IsMapStand(__instance) && (Object)(object)item.m_dropPrefab != (Object)null && (Object)(object)ItemStand.GetAttachPrefab(item.m_dropPrefab) != (Object)null; return false; } } [HarmonyPatch(typeof(ItemStand), "GetHoverText")] private static class StandHoverPatch { [HarmonyPostfix] private static void Postfix(ItemStand __instance, ref string __result) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) try { if (HasMap(__instance) && !((Object)(object)Player.m_localPlayer == (Object)null) && PrivateArea.CheckAccess(((Component)__instance).transform.position, 0f, false, false)) { MapStandVisual mapStandVisual = (((Object)(object)__instance.m_visualItem != (Object)null) ? __instance.m_visualItem.GetComponent<MapStandVisual>() : null); string text = (((Object)(object)mapStandVisual != (Object)null && !string.IsNullOrEmpty(mapStandVisual.Title)) ? mapStandVisual.Title : VsmLocalization.Localize("$vsm_carto_mapitem")); string text2 = (((Object)(object)mapStandVisual != (Object)null && !string.IsNullOrEmpty(mapStandVisual.Author)) ? (" <color=#bbbbbb>(" + mapStandVisual.Author + ")</color>") : string.Empty); float num = (((Object)(object)mapStandVisual != (Object)null) ? mapStandVisual.SizeMeters : MapStandVisual.Sizes[0]); string text3 = num.ToString((num % 1f == 0f) ? "0" : "0.##", CultureInfo.GetCultureInfo("es-ES")); __result = Localization.instance.Localize("<color=orange>" + text + "</color>" + text2 + "\n[<color=yellow><b>$ui_hold $KEY_Use</b></color>] $vsm_carto_stand_take\n[<color=yellow><b>$KEY_AltPlace + $KEY_Use</b></color>] ") + VsmLocalization.Localize("$vsm_carto_stand_size", text3); } } catch (Exception) { } } } [HarmonyPatch(typeof(Terminal), "InitTerminal")] private static class TerminalInitPatch { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__1_0; internal void <Postfix>b__1_0(ConsoleEventArgs args) { args.Context.AddString("vsm.carto 0.1.4 | activo=" + CartoPlugin.Active + " | prefabs=" + CartoPrefabs.Ready + " | ventana=" + CartoWindow.IsOpen + " | sesión=" + CanvasClient.Active); foreach (string item in CanvasServer.Status()) { args.Context.AddString(item); } } } private static bool s_registered; [HarmonyPostfix] private static void Postfix() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown if (s_registered) { return; } s_registered = true; object obj = <>c.<>9__1_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { args.Context.AddString("vsm.carto 0.1.4 | activo=" + CartoPlugin.Active + " | prefabs=" + CartoPrefabs.Ready + " | ventana=" + CartoWindow.IsOpen + " | sesión=" + CanvasClient.Active); foreach (string item in CanvasServer.Status()) { args.Context.AddString(item); } }; <>c.<>9__1_0 = val; obj = (object)val; } new ConsoleCommand("vsm_carto", "Estado de los lienzos de cartografía (vsm.carto)", (ConsoleEvent)obj, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } } private static bool Disabled() { return CartoPlugin.IsConfigReady && !CartoPlugin.Enabled.Value; } private static string Hover(MapTable table, string actionToken) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) if (!CartoPlugin.Active) { return Localization.instance.Localize(table.m_name + "\n$vsm_carto_waiting"); } if (CartoPlugin.RespectWards.Value && !PrivateArea.CheckAccess(((Component)table).transform.position, 0f, false, false)) { return Localization.instance.Localize(table.m_name + "\n$piece_noaccess"); } return Localization.instance.Localize(table.m_name + "\n[<color=yellow><b>$KEY_Use</b></color>] $" + actionToken); } private static bool OnDraw(MapTable table, Humanoid user, ItemData item) { if (item != null || (Object)(object)user != (Object)(object)Player.m_localPlayer) { return false; } if (!CartoPlugin.Active) { ((Character)user).Message((MessageType)2, VsmLocalization.Localize("vsm_carto_waiting"), 0, (Sprite)null, false); return true; } PrintFlow.PendingFromTable = false; CartoWindow.OpenDraw(table); return true; } private static bool OnPrint(MapTable table, Humanoid user, ItemData item) { if (item != null || (Object)(object)user != (Object)(object)Player.m_localPlayer) { return false; } if (!CartoPlugin.Active) { ((Character)user).Message((MessageType)2, VsmLocalization.Localize("vsm_carto_waiting"), 0, (Sprite)null, false); return true; } PrintFlow.PendingFromTable = true; CanvasClient.OnSnapshot = delegate { CanvasClient.OnSnapshot = null; if (PrintFlow.PendingFromTable) { PrintFlow.PendingFromTable = false; PrintFlow.Begin(CanvasClient.Model); } }; CartoWindow.OpenDraw(table); return true; } private static bool IsMapStand(ItemStand stand) { return (Object)(object)stand != (Object)null && stand.m_canBeRemoved && (Object)(object)stand.m_guardianPower == (Object)null && !stand.m_autoAttach && (Object)(object)((Component)stand).GetComponentInParent<Piece>() != (Object)null; } private static bool HasMap(ItemStand stand) { return (Object)(object)stand != (Object)null && stand.GetAttachedItem() == CartoPrefabs.MapItemHash; } } [BepInPlugin("vsm.carto", "MEL Carto", "0.1.4")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class CartoPlugin : BaseUnityPlugin { internal static ManualLogSource Log; private static ConfigSync s_sync; private Harmony _harmony; public static ConfigEntry<bool> Enabled; public static ConfigEntry<int> CanvasSize; public static ConfigEntry<string> PrintCost; public static ConfigEntry<string> FrameCost; public static ConfigEntry<bool> RespectWards; public static ConfigEntry<bool> AllowClear; public static ConfigEntry<int> MaxPrintKB; public static ConfigEntry<float> MaxDrawDistance; public static ConfigEntry<bool> ServerLock; internal static ItemData LastViewedMap; private static readonly Dictionary<string, string> s_spanish = new Dictionary<string, string> { { "vsm_carto_table_title", "Mesa de cartografía" }, { "vsm_carto_draw", "Dibujar en el lienzo" }, { "vsm_carto_print_hover", "Imprimir una copia" }, { "vsm_carto_mapitem", "Mapa" }, { "vsm_carto_frame", "Marco de mapa" } }; public static bool IsConfigReady => s_sync != null && (((ConditionalConfigSync)s_sync).IsSourceOfTruth || ((ConditionalConfigSync)s_sync).InitialSyncDone); public static bool Active => Enabled != null && Enabled.Value && IsConfigReady; private void Awake() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0044: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Expected O, but got Unknown //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Expected O, but got Unknown //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Expected O, but got Unknown //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Expected O, but got Unknown //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Expected O, but got Unknown //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Expected O, but got Unknown //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Expected O, but got Unknown //IL_0369: Unknown result type (might be due to invalid IL or missing references) //IL_0373: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; s_sync = new ConfigSync("vsm.carto") { DisplayName = "MEL Carto", CurrentVersion = "0.1.4", MinimumRequiredVersion = "0.1.4", ModRequired = true }; Enabled = Synced<bool>(((BaseUnityPlugin)this).Config.Bind<bool>("1. General (servidor)", "Enabled", true, new ConfigDescription("Usar la mesa de cartografía como lienzo compartido. Con false vuelve el comportamiento vanilla.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 100 } }))); CanvasSize = Synced<int>(((BaseUnityPlugin)this).Config.Bind<int>("1. General (servidor)", "CanvasSize", 512, new ConfigDescription("Tamaño en píxeles de los lienzos NUEVOS (los existentes conservan el suyo).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(128, 1024), new object[1] { new ConfigurationManagerAttributes { Order = 99 } }))); PrintCost = Synced<string>(((BaseUnityPlugin)this).Config.Bind<string>("1. General (servidor)", "PrintCost", "DeerHide:1", new ConfigDescription("Coste de imprimir una copia: 'Prefab:cantidad,...' (vacío = gratis).", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 98 } }))); FrameCost = Synced<string>(((BaseUnityPlugin)this).Config.Bind<string>("1. General (servidor)", "FrameCost", "Wood:4", new ConfigDescription("Coste del Marco de mapa en el martillo: 'Prefab:cantidad,...'.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 97 } }))); RespectWards = Synced<bool>(((BaseUnityPlugin)this).Config.Bind<bool>("1. General (servidor)", "RespectWards", true, new ConfigDescription("Dentro de una guarda solo quien tenga permiso puede dibujar en la mesa y colgar o descolgar mapas.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 96 } }))); AllowClear = Synced<bool>(((BaseUnityPlugin)this).Config.Bind<bool>("1. General (servidor)", "AllowClear", true, new ConfigDescription("Permitir el botón 'Borrar todo' del lienzo (con doble confirmación).", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 95 } }))); MaxPrintKB = Synced<int>(((BaseUnityPlugin)this).Config.Bind<int>("1. General (servidor)", "MaxPrintKB", 160, new ConfigDescription("Tamaño máximo (KB, comprimido) de un mapa impreso: evita objetos enormes en inventarios y marcos.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(16, 512), new object[1] { new ConfigurationManagerAttributes { Order = 94 } }))); MaxDrawDistance = Synced<float>(((BaseUnityPlugin)this).Config.Bind<float>("1. General (servidor)", "MaxDrawDistance", 4f, new ConfigDescription("Distancia máxima (m) a la mesa para seguir dibujando.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 20f), new object[1] { new ConfigurationManagerAttributes { Order = 93 } }))); ServerLock = ((BaseUnityPlugin)this).Config.Bind<bool>("1. General (servidor)", "ServerLock", true, "Bloquea la configuración sincronizada: solo los administradores del servidor pueden cambiarla."); ((ConditionalConfigSync)s_sync).AddLockingConfigEntry<bool>(ServerLock); FrameCost.SettingChanged += delegate { CartoPrefabs.ApplyFrameCost(); }; Log.LogInfo((object)("vsm.carto 0.1.4 | Valheim " + GameConstants.GameVersionString + " | headless=" + Headless.IsHeadless)); if (!Headless.IsHeadless) { VsmLocalization.Register(Log, Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), s_spanish); } _harmony = new Harmony("vsm.carto"); PatchUtil.PatchAllSafely(Log, _harmony, Assembly.GetExecutingAssembly()); if (PatchUtil.IsDegraded) { Log.LogError((object)"vsm.carto: hay parches sin aplicar (ver arriba)."); } } private static ConfigEntry<T> Synced<T>(ConfigEntry<T> entry) { ((ConditionalConfigSync)s_sync).AddConfigEntry<T>(entry, (ConfigSyncMode)0); return entry; } private void Update() { CanvasServer.Tick(); if (!Headless.IsHeadless) { CartoWindow.Tick(); } } private void OnDestroy() { CanvasServer.Reset(); if (!Headless.IsHeadless) { CartoWindow.Destroy(); } if (_harmony != null) { _harmony.UnpatchSelf(); } } } internal static class CartoPrefabs { public const string MapItemName = "vsm_MapScroll"; public const string FrameName = "vsm_MapFrame"; private static GameObject s_container; private static GameObject s_item; private static GameObject s_frame; private static Texture2D s_parchment; private static Material s_baseMaterial; public static bool Ready => (Object)(object)s_item != (Object)null && (Object)(object)s_frame != (Object)null; private static GameObject Container { get { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown if ((Object)(object)s_container == (Object)null) { s_container = new GameObject("vsm_carto_prefabs"); s_container.SetActive(false); Object.DontDestroyOnLoad((Object)(object)s_container); } return s_container; } } public static int MapItemHash => StringExtensionMethods.GetStableHashCode("vsm_MapScroll"); public static void EnsureClones() { try { if ((Object)(object)s_item == (Object)null) { GameObject val = FindSource("DeerHide"); if ((Object)(object)val != (Object)null) { s_item = MakeItem(val); } } if ((Object)(object)s_frame == (Object)null) { GameObject val2 = FindSignSource(); if ((Object)(object)val2 != (Object)null) { s_frame = MakeFrame(val2); } } } catch (Exception ex) { CartoPlugin.Log.LogError((object)("vsm.carto: error creando prefabs: " + ex)); } } private static GameObject FindSource(string name) { GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(name) : null); if ((Object)(object)val == (Object)null && (Object)(object)ObjectDB.instance != (Object)null) { val = ObjectDB.instance.GetItemPrefab(name); } return val; } private static GameObject FindSignSource() { GameObject val = FindSource("sign"); if ((Object)(object)val != (Object)null && (Object)(object)val.GetComponent<Sign>() != (Object)null) { return val; } PieceTable val2 = HammerTable(ObjectDB.instance); if ((Object)(object)val2 != (Object)null) { foreach (GameObject piece in val2.m_pieces) { if ((Object)(object)piece != (Object)null && (Object)(object)piece.GetComponent<Sign>() != (Object)null) { return piece; } } } return null; } private static PieceTable HammerTable(ObjectDB db) { if ((Object)(object)db == (Object)null) { return null; } GameObject itemPrefab = db.GetItemPrefab("Hammer"); ItemDrop val = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent<ItemDrop>() : null); return ((Object)(object)val != (Object)null && val.m_itemData != null && val.m_itemData.m_shared != null) ? val.m_itemData.m_shared.m_buildPieces : null; } private static GameObject Clone(GameObject source, string name) { GameObject val = Object.Instantiate<GameObject>(source, Container.transform); ((Object)val).name = name; return val; } private static GameObject MakeItem(GameObject hide) { //IL_0060: 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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Expected O, but got Unknown //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Expected O, but got Unknown GameObject val = Clone(hide, "vsm_MapScroll"); ItemDrop component = val.GetComponent<ItemDrop>(); SharedData shared = component.m_itemData.m_shared; shared.m_name = "$vsm_carto_mapitem"; shared.m_description = "$vsm_carto_mapitem_desc"; shared.m_maxStackSize = 1; shared.m_weight = 0.2f; shared.m_value = 0; shared.m_teleportable = true; shared.m_questItem = false; shared.m_itemType = (ItemType)16; component.m_itemData.m_stack = 1; shared.m_itemStandOffsets = new List<OrientationSettings>(); for (int i = 0; i < MapStandVisual.Sizes.Length; i++) { shared.m_itemStandOffsets.Add(new OrientationSettings { m_orientations = (Orientation)3 }); } GameObject val2 = new GameObject("attach"); val2.transform.SetParent(val.transform, false); val2.AddComponent<MapStandVisual>(); if (!Headless.IsHeadless) { shared.m_icons = (Sprite[])(object)new Sprite[1] { MapArt.GenericIcon() }; ReplaceModel(val); } return val; } private static void ReplaceModel(GameObject go) { //IL_00b5: 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_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) LODGroup component = go.GetComponent<LODGroup>(); if ((Object)(object)component != (Object)null) { Object.DestroyImmediate((Object)(object)component); } MeshRenderer val = null; MeshRenderer[] componentsInChildren = go.GetComponentsInChildren<MeshRenderer>(true); foreach (MeshRenderer val2 in componentsInChildren) { if ((Object)(object)val == (Object)null) { val = val2; } else { ((Renderer)val2).enabled = false; } } if (!((Object)(object)val == (Object)null)) { s_baseMaterial = ((Renderer)val).sharedMaterial; MeshFilter component2 = ((Component)val).GetComponent<MeshFilter>(); if ((Object)(object)component2 != (Object)null) { component2.sharedMesh = MapArt.ScrollMesh(0.035f, 0.34f); } ((Component)val).transform.localRotation = Quaternion.identity; ((Component)val).transform.localScale = Vector3.one; ((Renderer)val).sharedMaterial = NewMaterial((Texture)(object)MapArt.ScrollTexture()); BoxCollider component3 = ((Component)val).GetComponent<BoxCollider>(); if ((Object)(object)component3 != (Object)null) { component3.center = Vector3.zero; component3.size = new Vector3(0.36f, 0.08f, 0.08f); } } } public static Material NewMaterial(Texture texture) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_00a4: Unknown result type (might be due to invalid IL or missing references) Material val = (((Object)(object)s_baseMaterial != (Object)null) ? new Material(s_baseMaterial) : new Material(Shader.Find("Standard"))); val.mainTexture = texture; if (val.HasProperty("_BumpMap")) { val.SetTexture("_BumpMap", (Texture)null); } if (val.HasProperty("_MetallicGlossMap")) { val.SetTexture("_MetallicGlossMap", (Texture)null); } if (val.HasProperty("_EmissionMap")) { val.SetTexture("_EmissionMap", (Texture)null); } if (val.HasProperty("_Color")) { val.SetColor("_Color", Color.white); } return val; } public static ItemData NewItemData() { GameObject val = (((Object)(object)s_item != (Object)null) ? s_item : (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab("vsm_MapScroll") : null)); ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null); if ((Object)(object)val2 == (Object)null) { return null; } ItemData val3 = val2.m_itemData.Clone(); val3.m_dropPrefab = val; return val3; } private static Texture2D Parchment() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)s_parchment == (Object)null) { s_parchment = new Texture2D(2, 2, (TextureFormat)4, false); Color32 val = MapData.Colors[0]; s_parchment.SetPixels32((Color32[])(object)new Color32[4] { val, val, val, val }); s_parchment.Apply(false); } return s_parchment; } private static GameObject MakeFrame(GameObject sign) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_02f4: Expected O, but got Unknown //IL_033d: Unknown result type (might be due to invalid IL or missing references) //IL_03a8: Unknown result type (might be due to invalid IL or missing references) GameObject val = Clone(sign, "vsm_MapFrame"); Sign component = val.GetComponent<Sign>(); Transform val2 = (((Object)(object)component != (Object)null && (Object)(object)component.m_textWidget != (Object)null) ? ((TMP_Text)component.m_textWidget).transform : null); Vector3 val3 = Vector3.zero; Quaternion val4 = Quaternion.identity; if ((Object)(object)val2 != (Object)null) { val3 = val.transform.InverseTransformPoint(val2.position); val4 = Quaternion.Inverse(val.transform.rotation) * val2.rotation; Canvas componentInParent = ((Component)val2).GetComponentInParent<Canvas>(); Object.DestroyImmediate((Object)(object)(((Object)(object)componentInParent != (Object)null) ? ((Component)componentInParent).gameObject : ((Component)val2).gameObject)); } if ((Object)(object)component != (Object)null) { Object.DestroyImmediate((Object)(object)component); } Renderer val5 = null; float num = 0f; MeshRenderer[] componentsInChildren = val.GetComponentsInChildren<MeshRenderer>(true); Bounds bounds; foreach (MeshRenderer val6 in componentsInChildren) { MeshFilter component2 = ((Component)val6).GetComponent<MeshFilter>(); if (!((Object)(object)component2 == (Object)null) && !((Object)(object)component2.sharedMesh == (Object)null)) { bounds = component2.sharedMesh.bounds; Vector3 val7 = Vector3.Scale(((Bounds)(ref bounds)).size, ((Component)val6).transform.lossyScale); float num2 = val7.x * val7.y + val7.y * val7.z + val7.x * val7.z; if (num2 > num) { num = num2; val5 = (Renderer)(object)val6; } } } float num3 = 0.8f; if ((Object)(object)val5 != (Object)null) { bounds = ((Component)val5).GetComponent<MeshFilter>().sharedMesh.bounds; Vector3 val8 = Vector3.Scale(((Bounds)(ref bounds)).size, ((Component)val5).transform.lossyScale); float[] array = new float[3] { val8.x, val8.y, val8.z }; Array.Sort(array); num3 = Mathf.Clamp(array[1] * 0.85f, 0.3f, 2f); } GameObject val9 = GameObject.CreatePrimitive((PrimitiveType)5); ((Object)val9).name = "vsm_map"; Collider component3 = val9.GetComponent<Collider>(); if ((Object)(object)component3 != (Object)null) { Object.DestroyImmediate((Object)(object)component3); } val9.transform.SetParent(val.transform, false); val9.transform.localRotation = val4; val9.transform.localPosition = val3 + val4 * new Vector3(0f, 0f, -0.01f); val9.transform.localScale = new Vector3(num3, num3, 1f); MeshRenderer component4 = val9.GetComponent<MeshRenderer>(); Material val10 = (((Object)(object)val5 != (Object)null) ? new Material(val5.sharedMaterial) : new Material(Shader.Find("Standard"))); val10.mainTexture = (Texture)(object)Parchment(); if (val10.HasProperty("_BumpMap")) { val10.SetTexture("_BumpMap", (Texture)null); } if (val10.HasProperty("_Color")) { val10.SetColor("_Color", Color.white); } ((Renderer)component4).sharedMaterial = val10; ((Renderer)component4).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)component4).enabled = false; MapFrame mapFrame = val.AddComponent<MapFrame>(); mapFrame.m_quad = (Renderer)(object)component4; Piece component5 = val.GetComponent<Piece>(); if ((Object)(object)component5 != (Object)null) { component5.m_name = "$vsm_carto_frame"; component5.m_description = "$vsm_carto_frame_desc"; component5.m_category = (PieceCategory)4; } return val; } public static void Register(ZNetScene scene) { if ((Object)(object)scene == (Object)null) { return; } GameObject[] array = (GameObject[])(object)new GameObject[2] { s_item, s_frame }; foreach (GameObject val in array) { if (!((Object)(object)val == (Object)null)) { int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)val).name); if (!scene.m_namedPrefabs.ContainsKey(stableHashCode)) { scene.m_prefabs.Add(val); scene.m_namedPrefabs.Add(stableHashCode, val); } } } } public static void RegisterItems(ObjectDB db) { if (!((Object)(object)db == (Object)null)) { if ((Object)(object)s_item != (Object)null && (Object)(object)db.GetItemPrefab(StringExtensionMethods.GetStableHashCode(((Object)s_item).name)) == (Object)null) { db.m_items.Add(s_item); db.UpdateRegisters(); } PieceTable val = HammerTable(db); if ((Object)(object)s_frame != (Object)null && (Object)(object)val != (Object)null) { val.m_pieces.Remove(s_frame); } ApplyFrameCost(); } } public static void ApplyFrameCost() { //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Expected O, but got Unknown Piece val = (((Object)(object)s_frame != (Object)null) ? s_frame.GetComponent<Piece>() : null); if ((Object)(object)val == (Object)null || (Object)(object)ObjectDB.instance == (Object)null || ObjectDB.instance.m_items.Count == 0) { return; } List<Requirement> list = new List<Requirement>(); string[] array = (CartoPlugin.FrameCost.Value ?? string.Empty).Split(new char[2] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries); foreach (string text in array) { string[] array2 = text.Split(new char[1] { ':' }); if (array2.Length == 2 && int.TryParse(array2[1].Trim(), out var result) && result > 0) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(array2[0].Trim()); ItemDrop val2 = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent<ItemDrop>() : null); if ((Object)(object)val2 != (Object)null) { list.Add(new Requirement { m_resItem = val2, m_amount = result, m_recover = true }); } } } if (list.Count > 0) { val.m_resources = list.ToArray(); } } } internal static class CartoWindow { private enum Mode { Draw, View } private enum Tool { Brush, Eraser, Fill, Line } private static readonly int[] Sizes = new int[5] { 0, 1, 2, 4, 8 }; private const float MaxZoom = 8f; private const float StrokeFlush = 0.05f; private const float WindowW = 1340f; private const float WindowH = 900f; private const float PanelW = 270f; private const float ImageSize = 790f; private const float ViewTop = 58f; private const float StatusH = 24f; private static GameObject s_root; private static Canvas s_canvas; private static RectTransform s_imageRect; private static RawImage s_image; private static TextMeshProUGUI s_title; private static TextMeshProUGUI s_status; private static GameObject s_tools; private static Texture2D s_tex; private static Color32[] s_buffer; private static CanvasModel s_texFor; private static Mode s_mode; private static CanvasModel s_viewModel; private static MapTable s_table; private static Tool s_tool = Tool.Brush; private static byte s_color = 1; private static int s_sizeIndex = 1; private static float s_zoom = 1f; private static Vector2 s_center = new Vector2(0.5f, 0.5f); private static bool s_drawing; private static int s_lastX; private static int s_lastY; private static int s_lineX; private static int s_lineY; private static readonly List<int> s_xs = new List<int>(); private static readonly List<int> s_ys = new List<int>(); private static float s_lastFlush; private static bool s_panning; private static Vector2 s_panFrom; private static float s_clearArmed; private static readonly Dictionary<Tool, Button> s_toolButtons = new Dictionary<Tool, Button>(); private static readonly List<Button> s_sizeButtons = new List<Button>(); private static readonly List<Outline> s_swatchOutlines = new List<Outline>(); private static Button s_clearButton; private static string s_toast; private static float s_toastUntil; public static bool IsOpen => (Object)(object)s_root != (Object)null && s_root.activeSelf; public static bool IsDrawing => IsOpen && s_mode == Mode.Draw; public static CanvasModel CurrentModel => (s_mode == Mode.Draw) ? CanvasClient.Model : s_viewModel; public static MapTable CurrentTable => (s_mode == Mode.Draw) ? s_table : null; private static byte BrushColor => (byte)((s_tool != Tool.Eraser) ? s_color : 0); public static void OpenDraw(MapTable table) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) ZNetView val = (((Object)(object)table != (Object)null) ? ((Component)table).GetComponent<ZNetView>() : null); if (!((Object)(object)val == (Object)null) && val.IsValid() && Ensure()) { s_mode = Mode.Draw; s_table = table; s_viewModel = null; CanvasClient.Begin(val.GetZDO().m_uid); s_tools.SetActive(true); ((TMP_Text)s_title).text = L("vsm_carto_table_title"); ResetView(); Show(); } } public static void OpenView(CanvasModel model, string title, string author) { if (model != null && Ensure()) { if (s_mode == Mode.Draw && CanvasClient.Active) { CanvasClient.End(); } s_mode = Mode.View; s_table = null; s_viewModel = model; s_tools.SetActive(false); ((TMP_Text)s_title).text = (string.IsNullOrEmpty(title) ? L("vsm_carto_map") : title) + (string.IsNullOrEmpty(author) ? string.Empty : (" <size=70%>" + L("vsm_carto_by", author) + "</size>")); ResetView(); Show(); } } private static void Show() { if ((Object)(object)InventoryGui.instance != (Object)null && InventoryGui.IsVisible()) { InventoryGui.instance.Hide(); } s_drawing = false; s_panning = false; if ((Object)(object)s_canvas != (Object)null) { ((Behaviour)s_canvas).enabled = !TextInput.IsVisible() && !Console.IsVisible(); } s_root.SetActive(true); } public static void Close() { if (s_mode == Mode.Draw) { FinishStroke(); CanvasClient.End(); } s_table = null; s_viewModel = null; if ((Object)(object)s_root != (Object)null) { s_root.SetActive(false); } } public static void Destroy() { Close(); if ((Object)(object)s_root != (Object)null) { Object.Destroy((Object)(object)s_root); } s_root = null; if ((Object)(object)s_tex != (Object)null) { Object.Destroy((Object)(object)s_tex); } s_tex = null; s_texFor = null; s_buffer = null; s_toolButtons.Clear(); s_sizeButtons.Clear(); s_swatchOutlines.Clear(); } private static void ResetView() { //IL_0015: 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) s_zoom = 1f; s_center = new Vector2(0.5f, 0.5f); s_texFor = null; } private static bool Ensure() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Unknown result type (might be due to invalid IL or missing references) //IL_0488: Unknown result type (might be due to invalid IL or missing references) //IL_048f: Expected O, but got Unknown //IL_04b1: Unknown result type (might be due to invalid IL or missing references) //IL_04b6: Unknown result type (might be due to invalid IL or missing references) //IL_04e3: Unknown result type (might be due to invalid IL or missing references) //IL_04ed: Expected O, but got Unknown //IL_050d: Unknown result type (might be due to invalid IL or missing references) //IL_0524: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)s_root != (Object)null) { return true; } if ((Object)(object)InventoryGui.instance == (Object)null) { return false; } s_root = new GameObject("vsm_carto_window", new Type[1] { typeof(RectTransform) }); Object.DontDestroyOnLoad((Object)(object)s_root); s_canvas = s_root.AddComponent<Canvas>(); s_canvas.renderMode = (RenderMode)0; s_canvas.sortingOrder = 31000; CanvasScaler val = s_root.AddComponent<CanvasScaler>(); val.uiScaleMode = (ScaleMode)1; val.referenceResolution = new Vector2(1920f, 1080f); val.screenMatchMode = (ScreenMatchMode)1; s_root.AddComponent<GraphicRaycaster>(); RectTransform val2 = Rect("window", s_root.transform, new Vector2(1340f, 900f)); Image target = ((Component)val2).gameObject.AddComponent<Image>(); VanillaStyle.CopyImage(VanillaStyle.InventoryBackground(null), target); s_title = VanillaStyle.NewText((Transform)(object)val2, "title", VanillaStyle.TitleFont, 30f, (TextAlignmentOptions)514); Place(((TMP_Text)s_title).rectTransform, 20f, 14f, 1300f, 40f); s_status = VanillaStyle.NewText((Transform)(object)val2, "status", VanillaStyle.BodyFont, 16f, (TextAlignmentOptions)513); Place(((TMP_Text)s_status).rectTransform, 320f, 852f, 996f, 24f); ((TMP_Text)s_status).overflowMode = (TextOverflowModes)1; RectTransform val3 = Rect("viewport", (Transform)(object)val2, new Vector2(790f, 790f)); Place(val3, 320f, 58f, 790f, 790f); ((Component)val3).gameObject.AddComponent<RectMask2D>(); Image val4 = ((Component)val3).gameObject.AddComponent<Image>(); ((Graphic)val4).color = new Color(0f, 0f, 0f, 0.35f); s_image = new GameObject("image", new Type[1] { typeof(RectTransform) }).AddComponent<RawImage>(); s_imageRect = ((Graphic)s_image).rectTransform; ((Transform)s_imageRect).SetParent((Transform)(object)val3, false); s_imageRect.anchorMin = Vector2.zero; s_imageRect.anchorMax = Vector2.one; s_imageRect.offsetMin = new Vector2(6f, 6f); s_imageRect.offsetMax = new Vector2(-6f, -6f); RectTransform val5 = Rect("tools", (Transform)(object)val2, new Vector2(270f, 820f)); Place(val5, 24f, 58f, 270f, 820f); s_tools = ((Component)val5).gameObject; float y = 0f; Header(val5, L("vsm_carto_tools"), ref y); AddTool(val5, Tool.Brush, L("vsm_carto_brush"), 0, ref y); AddTool(val5, Tool.Eraser, L("vsm_carto_eraser"), 1, ref y); y += 44f; AddTool(val5, Tool.Fill, L("vsm_carto_fill"), 0, ref y); AddTool(val5, Tool.Line, L("vsm_carto_line"), 1, ref y); y += 52f; Header(val5, L("vsm_carto_size"), ref y); for (int i = 0; i < Sizes.Length; i++) { int idx = i; Button val6 = MakeButton((Transform)(object)val5, (Sizes[i] * 2 + 1).ToString(), delegate { s_sizeIndex = idx; RefreshSelection(); }); Place(((Component)val6).GetComponent<RectTransform>(), (float)i * 53f, y, 48f, 38f); s_sizeButtons.Add(val6); } y += 50f; Header(val5, L("vsm_carto_inks"), ref y); for (int num = 0; num < 16; num++) { byte c = (byte)num; GameObject val7 = new GameObject("ink" + num, new Type[1] { typeof(RectTransform) }); val7.transform.SetParent((Transform)(object)val5, false); Image val8 = val7.AddComponent<Image>(); ((Graphic)val8).color = Color32.op_Implicit(MapData.Colors[num]); Button val9 = val7.AddComponent<Button>(); ((Selectable)val9).targetGraphic = (Graphic)(object)val8; ((UnityEvent)val9.onClick).AddListener((UnityAction)delegate { s_color = c; if (s_tool == Tool.Eraser) { s_tool = Tool.Brush; } RefreshSelection(); }); Outline val10 = val7.AddComponent<Outline>(); ((Shadow)val10).effectColor = new Color(1f, 0.85f, 0.4f, 1f); ((Shadow)val10).effectDistance = new Vector2(3f, -3f); s_swatchOutlines.Add(val10); Place(val7.GetComponent<RectTransform>(), (float)(num % 4) * 66f, y + (float)(num / 4) * 50f, 58f, 42f); } y += 214f; Button val11 = MakeButton((Transform)(object)val5, L("vsm_carto_undo"), CanvasClient.RequestUndo); Place(((Component)val11).GetComponent<RectTransform>(), 0f, y, 128f, 40f); Button val12 = MakeButton((Transform)(object)val5, L("vsm_carto_print"), delegate { PrintFlow.Begin(CanvasClient.Model); }); Place(((Component)val12).GetComponent<RectTransform>(), 136f, y, 128f, 40f); y += 48f; s_clearButton = MakeButton((Transform)(object)val5, L("vsm_carto_clear"), OnClear); Place(((Component)s_clearButton).GetComponent<RectTransform>(), 0f, y, 264f, 40f); Button val13 = MakeButton((Transform)(object)val2, L("vsm_carto_close"), Close); Place(((Component)val13).GetComponent<RectTransform>(), 24f, 842f, 270f, 40f); ((TMP_Text)s_status).transform.SetAsLastSibling(); RefreshSelection(); s_root.SetActive(false); return true; } private static RectTransform Rect(string name, Transform parent, Vector2 size) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0031: 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(parent, false); RectTransform component = val.GetComponent<RectTransform>(); component.sizeDelta = size; return component; } private static void Place(RectTransform rt, float x, float y, float w, float h) { //IL_0014: 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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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) Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0f, 1f); rt.anchorMax = val; rt.anchorMin = val; rt.pivot = new Vector2(0f, 1f); rt.sizeDelta = new Vector2(w, h); rt.anchoredPosition = new Vector2(x, 0f - y); } private static void Header(RectTransform parent, string text, ref float y) { TextMeshProUGUI val = VanillaStyle.NewText((Transform)(object)parent, "header", VanillaStyle.TitleFont, 19f, (TextAlignmentOptions)513); Place(((TMP_Text)val).rectTransform, 0f, y, 270f, 26f); ((TMP_Text)val).text = text; y += 30f; } private static void AddTool(RectTransform parent, Tool tool, string label, int column, ref float y) { Button val = MakeButton((Transform)(object)parent, label, delegate { s_tool = tool; RefreshSelection(); }); Place(((Component)val).GetComponent<RectTransform>(), (float)column * 136f, y, 128f, 40f); s_toolButtons[tool] = val; } private static Button MakeButton(Transform parent, string label, Action onClick) { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Expected O, but got Unknown //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Expected O, but got Unknown //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) Button val = (((Object)(object)InventoryGui.instance != (Object)null) ? InventoryGui.instance.m_craftButton : null); GameObject val2; if ((Object)(object)val != (Object)null) { val2 = Object.Instantiate<GameObject>(((Component)val).gameObject, parent, false); UIGamePad[] componentsInChildren = val2.GetComponentsInChildren<UIGamePad>(true); foreach (UIGamePad val3 in componentsInChildren) { Object.Destroy((Object)(object)val3); } } else { val2 = new GameObject("button", new Type[1] { typeof(RectTransform) }); val2.transform.SetParent(parent, false); ((Graphic)val2.AddComponent<Image>()).color = new Color(0.2f, 0.15f, 0.1f, 0.9f); val2.AddComponent<Button>(); } ((Object)val2).name = "vsm_btn"; val2.SetActive(true); Button component = val2.GetComponent<Button>(); component.onClick = new ButtonClickedEvent(); ((UnityEvent)component.onClick).AddListener((UnityAction)delegate { onClick(); }); ((Selectable)component).interactable = true; TMP_Text val4 = val2.GetComponentInChildren<TMP_Text>(true); if ((Object)(object)val4 == (Object)null) { val4 = (TMP_Text)(object)VanillaStyle.NewText(val2.transform, "label", VanillaStyle.BodyFont, 18f, (TextAlignmentOptions)514); RectTransform rectTransform = val4.rectTransform; rectTransform.anchorMin = Vector2.zero; rectTransform.anchorMax = Vector2.one; Vector2 offsetMin = (rectTransform.offsetMax = Vector2.zero); rectTransform.offsetMin = offsetMin; } val4.text = label; val4.enableAutoSizing = true; val4.fontSizeMin = 12f; val4.fontSizeMax = 20f; return component; } private static void RefreshSelection() { foreach (KeyValuePair<Tool, Button> s_toolButton in s_toolButtons) { Tint(s_toolButton.Value, s_toolButton.Key == s_tool); } for (int i = 0; i < s_sizeButtons.Count; i++) { Tint(s_sizeButtons[i], i == s_sizeIndex); } for (int j = 0; j < s_swatchOutlines.Count; j++) { ((Behaviour)s_swatchOutlines[j]).enabled = j == s_color && s_tool != Tool.Eraser; } } private static void Tint(Button b, bool selected) { //IL_0042: 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) if ((Object)(object)b != (Object)null && (Object)(object)((Selectable)b).targetGraphic != (Object)null) { ((Selectable)b).targetGraphic.color = (Color)(selected ? new Color(1f, 0.8f, 0.45f, 1f) : Color.white); } } private static void OnClear() { if (!CartoPlugin.AllowClear.Value) { Toast(L("vsm_carto_clear_disabled")); } else if (Time.unscaledTime - s_clearArmed > 3f) { s_clearArmed = Time.unscaledTime; Toast(L("vsm_carto_clear_confirm")); } else { s_clearArmed = 0f; CanvasClient.Submit(Op.ClearAll(0)); } } public static void Toast(string text) { s_toast = text; s_toastUntil = Time.unscaledTime + 3f; } public static void Tick() { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) if (!IsOpen) { return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead() || Menu.IsVisible()) { Close(); return; } if (s_mode == Mode.Draw && ((Object)(object)s_table == (Object)null || Vector3.Distance(((Component)localPlayer).transform.position, ((Component)s_table).transform.position) > CartoPlugin.MaxDrawDistance.Value)) { Close(); return; } if (ZInput.GetKeyDown((KeyCode)27, false) && ((Object)(object)s_canvas == (Object)null || ((Behaviour)s_canvas).enabled) && !TextInput.IsVisible()) { Close(); return; } CanvasModel currentModel = CurrentModel; UpdateTexture(currentModel); bool flag = TextInput.IsVisible() || Console.IsVisible(); if ((Object)(object)s_canvas != (Object)null && ((Behaviour)s_canvas).enabled == flag) { ((Behaviour)s_canvas).enabled = !flag; } if (!flag && (!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus()) && currentModel != null) { HandleView(currentModel); if (s_mode == Mode.Draw) { HandleDrawing(currentModel); HandleShortcuts(); } } CanvasClient.Tick(); UpdateStatus(currentModel); } private static void UpdateTexture(CanvasModel model) { //IL_014a: Unknown result type (might be due to invalid IL or missing references) if (model == null) { s_image.texture = null; return; } if (s_texFor != model || (Object)(object)s_tex == (Object)null || ((Texture)s_tex).width != model.Width || ((Texture)s_tex).height != model.Height) { if ((Object)(object)s_tex != (Object)null) { Object.Destroy((Object)(object)s_tex); } s_tex = MapData.NewTexture(model, (FilterMode)0); s_buffer = null; s_texFor = model; s_image.texture = (Texture)(object)s_tex; } s_buffer = MapData.Upload(model, s_tex, s_buffer); float num = 1f / s_zoom; s_center.x = Mathf.Clamp(s_center.x, num / 2f, 1f - num / 2f); s_center.y = Mathf.Clamp(s_center.y, num / 2f, 1f - num / 2f); s_image.uvRect = new Rect(s_center.x - num / 2f, s_center.y - num / 2f, num, num); } private static bool PointerUv(out Vector2 uv) { //IL_0002: 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_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) uv = Vector2.zero; Vector2 val = default(Vector2); if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(s_imageRect, Vector2.op_Implicit(ZInput.pointerPosition), (Camera)null, ref val)) { return false; } Rect rect = s_imageRect.rect; Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor((val.x - ((Rect)(ref rect)).xMin) / ((Rect)(ref rect)).width, (val.y - ((Rect)(ref rect)).yMin) / ((Rect)(ref rect)).height); if (val2.x < 0f || val2.y < 0f || val2.x > 1f || val2.y > 1f) { return false; } Rect uvRect = s_image.uvRect; uv = new Vector2(((Rect)(ref uvRect)).x + val2.x * ((Rect)(ref uvRect)).width, ((Rect)(ref uvRect)).y + val2.y * ((Rect)(ref uvRect)).height); return true; } private static bool PointerPixel(CanvasModel model, out int x, out int y) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) x = (y = 0); if (!PointerUv(out var uv)) { return false; } x = Mathf.Clamp(Mathf.FloorToInt(uv.x * (float)model.Width), 0, model.Width - 1); y = Mathf.Clamp(model.Height - 1 - Mathf.FloorToInt(uv.y * (float)model.Height), 0, model.Height - 1); return true; } private static void HandleView(CanvasModel model) { //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: 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_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) Vector2 uv; bool flag = PointerUv(out uv); float mouseScrollWheel = ZInput.GetMouseScrollWheel(); if (flag && Mathf.Abs(mouseScrollWheel) > 0.0001f) { float num = s_zoom; s_zoom = Mathf.Clamp(s_zoom * ((mouseScrollWheel > 0f) ? 1.25f : 0.8f), 1f, 8f); s_center = uv + (s_center - uv) * (num / s_zoom); } bool flag2 = ZInput.GetMouseButton(1) || ZInput.GetMouseButton(2); Vector2 val = Vector2.op_Implicit(ZInput.pointerPosition); if (flag2 && (s_panning || flag)) { if (s_panning) { Vector2 val2 = val - s_panFrom; Rect rect = s_imageRect.rect; float num2 = ((Rect)(ref rect)).width * s_zoom * s_root.transform.lossyScale.x; if (num2 > 0f) { s_center -= val2 / num2; } } s_panning = true; s_panFrom = val; } else { s_panning = false; } } private static void HandleDrawing(CanvasModel model) { int x; int y; bool flag = PointerPixel(model, out x, out y); bool mouseButtonDown = ZInput.GetMouseButtonDown(0); bool mouseButton = ZInput.GetMouseButton(0); if (!s_drawing) { if (mouseButtonDown && flag && !s_panning && CanDraw()) { if (s_tool == Tool.Fill) { CanvasClient.Submit(Op.FillAt(s_color, x, y)); return; } s_drawing = true; s_lastX = x; s_lastY = y; s_lineX = x; s_lineY = y; s_xs.Clear(); s_ys.Clear(); s_xs.Add(x); s_ys.Add(y); s_lastFlush = Time.unscaledTime; } } else if (!mouseButton) { if (s_tool == Tool.Line) { if (flag) { s_lastX = x; s_lastY = y; } CanvasClient.Submit(Op.Stroke(s_color, Sizes[s_sizeIndex], new int[2] { s_lineX, s_lastX }, new int[2] { s_lineY, s_lastY })); } FinishStroke(); } else if (s_tool == Tool.Line) { if (flag) { s_lastX = x; s_lastY = y; } } else { if (flag && (x != s_lastX || y != s_lastY)) { s_xs.Add(x); s_ys.Add(y); s_lastX = x; s_lastY = y; } if (s_xs.Count >= 256 || Time.unscaledTime - s_lastFlush >= 0.05f) { SubmitStrokeSegment(); } } } private static void SubmitStrokeSegment() { if (s_xs.Count > 0) { CanvasClient.Submit(Op.Stroke(BrushColor, Sizes[s_sizeIndex], s_xs, s_ys)); int item = s_xs[s_xs.Count - 1]; int item2 = s_ys[s_ys.Count - 1]; s_xs.Clear(); s_ys.Clear(); s_xs.Add(item); s_ys.Add(item2); } s_lastFlush = Time.unscaledTime; } private static void FinishStroke() { if (s_drawing && s_tool != Tool.Line && s_xs.Count > 0) { SubmitStrokeSegment(); } s_drawing = false; s_xs.Clear(); s_ys.Clear(); CanvasClient.Flush(); } private static bool CanDraw() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)s_table != (Object)null && CartoPlugin.RespectWards.Value && !PrivateArea.CheckAccess(((Component)s_table).transform.position, 0f, true, false)) { Toast(L("vsm_carto_noaccess")); return false; } return true; } private static void HandleShortcuts() { if ((ZInput.GetKey((KeyCode)306, false) || ZInput.GetKey((KeyCode)305, false)) && ZInput.GetKeyDown((KeyCode)122, false)) { CanvasClient.RequestUndo(); } if (ZInput.GetKeyDown((KeyCode)91, false)) { s_sizeIndex = Mathf.Max(0, s_sizeIndex - 1); RefreshSelection(); } if (ZInput.GetKeyDown((KeyCode)93, false)) { s_sizeIndex = Mathf.Min(Sizes.Length - 1, s_sizeIndex + 1); RefreshSelection(); } } private static void UpdateStatus(CanvasModel model) { string text = ((s_mode == Mode.Draw && model == null) ? L(CanvasClient.Waiting ? "vsm_carto_loading" : "vsm_carto_unavailable") : ((s_mode != Mode.Draw) ? (L("vsm_carto_view_help") + " · zoom x" + s_zoom.ToString("0.#")) : (L("vsm_carto_drawing_now", string.IsNullOrEmpty(CanvasClient.Drawers) ? "-" : CanvasClient.Drawers.Replace(",", ", ")) + " · zoom x" + s_zoom.ToString("0.#")))); if (Time.unscaledTime < s_toastUntil && !string.IsNullOrEmpty(s_toast)) { text = "<color=#FFC95C>" + s_toast + "</color> · " + text; } ((TMP_Text)s_status).text = text; } private static string L(string token, params object[] args) { return VsmLocalization.Localize(token, args); } } internal static class MapArt { private const int IconSize = 128; private static readonly Color32 Clear = new Color32((byte)0, (byte)0, (byte)0, (byte)0); private static readonly Color32 Outline = new Color32((byte)38, (byte)24, (byte)12, byte.MaxValue); private static readonly Color32 PaperLight = new Color32((byte)236, (byte)214, (byte)170, byte.MaxValue); private static readonly Color32 PaperDark = new Color32((byte)186, (byte)150, (byte)98, byte.MaxValue); private static readonly Color32 RollLight = new Color32((byte)222, (byte)196, (byte)146, byte.MaxValue); private static readonly Color32 RollDark = new Color32((byte)130, (byte)96, (byte)58, byte.MaxValue); private static readonly Color32 Ink = new Color32((byte)92, (byte)56, (byte)28, byte.MaxValue); private static readonly Color32 Ribbon = new Color32((byte)150, (byte)36, (byte)28, byte.MaxValue); private static Sprite s_genericIcon; private static Texture2D s_scrollTexture; public static Sprite GenericIcon() { if ((Object)(object)s_genericIcon == (Object)null) { s_genericIcon = MakeIcon(); } return s_genericIcon; } private static Sprite MakeIcon() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) Color32[] array = (Color32[])(object)new Color32[16384]; for (int i = 0; i < array.Length; i++) { array[i] = Clear; } DrawSheet(array, 24, 22, 104, 106); DrawRoll(array, 14, 114, 100, 116); DrawRoll(array, 14, 114, 12, 28); AddOutline(array); Texture2D val = new Texture2D(128, 128, (TextureFormat)4, false) { name = "vsm_carto_icon", filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1 }; val.SetPixels32(array); val.Apply(false, false); return Sprite.Create(val, new Rect(0f, 0f, 128f, 128f), new Vector2(0.5f, 0.5f), 100f); } private static void DrawSheet(Color32[] px, int x0, int y0, int x1, int y1) { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) int num = x1 - x0; int num2 = y1 - y0; for (int i = y0; i < y1; i++) { for (int j = x0; j < x1; j++) { int num3 = (int)(Noise(j * 3, i * 7) * 2.2f); if (j >= x0 + num3 && j < x1 - num3) { float num4 = (float)(j - x0) / (float)num; float num5 = (float)(i - y0) / (float)num2; float num6 = Mathf.Min(Mathf.Min(num4, 1f - num4), Mathf.Min(num5, 1f - num5)); float num7 = Mathf.Clamp01(num6 * 6f) * 0.75f + Noise(j, i) * 0.25f; Color32 val = Color32.Lerp(PaperDark, PaperLight, num7); Color32? val2 = SampleDoodle(num4, num5); if (val2.HasValue) { val = Multiply(val, val2.Value); } px[i * 128 + j] = val; } } } } private static Color32? SampleDoodle(float u, float v) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: 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) float num = 0.55f + 0.12f * Mathf.Sin(u * 9f) + 0.05f * Mathf.Sin(u * 23f + 1f); if (Mathf.Abs(v - num) < 0.018f && u > 0.1f && u < 0.9f) { return Ink; } float num2 = 0.3f + 0.1f * Mathf.Sin(u * 6f + 2f); if (Mathf.Abs(v - num2) < 0.015f && u > 0.15f && u < 0.72f && (int)(u * 40f) % 2 == 0) { return Ink; } float num3 = u - 0.76f; float num4 = v - 0.3f; if ((Mathf.Abs(num3 - num4) < 0.022f || Mathf.Abs(num3 + num4) < 0.022f) && Mathf.Abs(num3) < 0.06f) { return Ribbon; } return null; } private static void DrawRoll(Color32[] px, int x0, int x1, int y0, int y1) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: 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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: 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) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) float num = y1 - y0; for (int i = y0; i < y1; i++) { float num2 = (float)(i - y0) / num; float num3 = Mathf.Sin(num2 * (float)Math.PI); float num4 = Mathf.Clamp01(num3 * 1.1f - 0.1f + ((num2 > 0.55f) ? 0.12f : 0f)); for (int j = x0; j < x1; j++) { bool flag = j < x0 + 4 || j >= x1 - 4; Color32 val = Color32.Lerp(RollDark, RollLight, num4 * (flag ? 0.55f : 1f)); if (!flag && (j - x0) % 23 == 11) { val = Color32.Lerp(val, RollDark, 0.35f); } px[i * 128 + j] = val; } } } private static void AddOutline(Color32[] px) { //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) bool[] array = new bool[px.Length]; for (int i = 0; i < px.Length; i++) { array[i] = px[i].a > 0; } for (int j = 0; j < 128; j++) { for (int k = 0; k < 128; k++) { int num = j * 128 + k; if (array[num]) { continue; } bool flag = false; for (int l = -1; l <= 1; l++) { if (flag) { break; } for (int m = -1; m <= 1; m++) { int num2 = k + m; int num3 = j + l; if (num2 >= 0 && num3 >= 0 && num2 < 128 && num3 < 128 && array[num3 * 128 + num2]) { flag = true; break; } } } if (flag) { px[num] = Outline; } } } } public static Texture2D ScrollTexture() { //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0156: 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_016b: Expected O, but got Unknown //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: 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_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)s_scrollTexture != (Object)null) { return s_scrollTexture; } Color32[] array = (Color32[])(object)new Color32[32768]; for (int i = 0; i < 256; i++) { float num = (float)i / 256f; float num2 = Mathf.Min(num, 1f - num); for (int j = 0; j < 128; j++) { float num3 = Noise(j, i * 3) * 0.3f; float num4 = (((j + i / 3) % 32 < 2) ? 0.25f : 0f); Color32 val = Color32.Lerp(PaperLight, PaperDark, Mathf.Clamp01(num3 + num4 + ((num2 < 0.05f) ? 0.4f : 0f))); if (Mathf.Abs(num - 0.5f) < 0.07f) { val = Color32.Lerp(Ribbon, new Color32((byte)96, (byte)20, (byte)16, byte.MaxValue), Noise(j * 2, i) * 0.5f); } array[i * 128 + j] = val; } } s_scrollTexture = new Texture2D(128, 256, (TextureFormat)4, true) { name = "vsm_carto_scroll", filterMode = (FilterMode)2, wrapMode = (TextureWrapMode)0 }; s_scrollTexture.SetPixels32(array); s_scrollTexture.Apply(true, false); return s_scrollTexture; } public static Mesh ScrollMesh(float radius, float length) { //IL_006a: 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_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: 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) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_02d9: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_02ec: Expected O, but got Unknown //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_0216: 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) List<Vector3> list = new List<Vector3>(); List<Vector3> list2 = new List<Vector3>(); List<Vector2> list3 = new List<Vector2>(); List<int> list4 = new List<int>(); float num = length * 0.5f; Vector3 val = default(Vector3); for (int i = 0; i <= 20; i++) { float num2 = (float)i / 20f * (float)Math.PI * 2f; ((Vector3)(ref val))..ctor(0f, Mathf.Cos(num2), Mathf.Sin(num2)); list.Add(new Vector3(0f - num, 0f, 0f) + val * radius); list.Add(new Vector3(num, 0f, 0f) + val * radius); list2.Add(val); list2.Add(val); list3.Add(new Vector2((float)i / 20f, 0f)); list3.Add(new Vector2((float)i / 20f, 1f)); } for (int j = 0; j < 20; j++) { int num3 = j * 2; int num4 = num3 + 1; int num5 = num3 + 2; int num6 = num3 + 3; list4.AddRange(new int[6] { num3, num5, num4, num4, num5, num6 }); } Vector3 item = default(Vector3); for (int k = 0; k < 2; k++) { float num7 = ((k == 0) ? (0f - num) : num); ((Vector3)(ref item))..ctor((k == 0) ? (-1f) : 1f, 0f, 0f); int count = list.Count; list.Add(new Vector3(num7, 0f, 0f)); list2.Add(item); list3.Add(new Vector2(0.5f, 0.02f)); for (int l = 0; l <= 20; l++) { float num8 = (float)l / 20f * (float)Math.PI * 2f; list.Add(new Vector3(num7, Mathf.Cos(num8) * radius, Mathf.Sin(num8) * radius)); list2.Add(item); list3.Add(new Vector2((float)l / 20f, 0f)); } for (int m = 0; m < 20; m++) { if (k == 0) { list4.AddRange(new int[3] { count, count + 2 + m, count + 1 + m }); } else { list4.AddRange(new int[3] { count, count + 1 + m, count + 2 + m }); } } } Mesh val2 = new Mesh { name = "vsm_carto_scroll" }; val2.SetVertices(list); val2.SetNormals(list2); val2.SetUVs(0, list3); val2.SetTriangles(list4, 0); val2.RecalculateBounds(); val2.RecalculateTangents(); return val2; } public static Texture2D SheetTexture(CanvasModel model) { //IL_0164: 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_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Expected O, but got Unknown //IL_007e: 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) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0131: 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_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.Max(8, model.Width / 16); int num2 = model.Width + num * 2; int num3 = model.Height + num * 2; Color32[] array = (Color32[])(object)new Color32[num2 * num3]; Color32[] colors = MapData.Colors; for (int i = 0; i < num3; i++) { for (int j = 0; j < num2; j++) { float num4 = (float)j / (float)num2; float num5 = (float)i / (float)num3; float num6 = Mathf.Min(Mathf.Min(num4, 1f - num4), Mathf.Min(num5, 1f - num5)); Color32 val = Color32.Lerp(PaperDark, PaperLight, Mathf.Clamp01(num6 * 9f) * 0.8f + Noise(j, i) * 0.2f); int num7 = j - num; int num8 = model.Height - 1 - (i - num); if (num7 >= 0 && num8 >= 0 && num7 < model.Width && num8 < model.Height) { byte b = model.Pixels[num8 * model.Width + num7]; if (b != 0) { val = Multiply(val, colors[b & 0xF]); } } array[i * num2 + j] = val; } } Texture2D val2 = new Texture2D(num2, num3, (TextureFormat)4, true) { name = "vsm_carto_sheet", filterMode = (FilterMode)2, anisoLevel = 4, wrapMode = (TextureWrapMode)1 }; val2.SetPixels32(array); val2.Apply(true, false); return val2; } private static Color32 Multiply(Color32 a, Color32 b) { //IL_0001: 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_0015: 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_0029: 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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: 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) return new Color32((byte)(a.r * b.r / 255), (byte)(a.g * b.g / 255), (byte)(a.b * b.b / 255), byte.MaxValue); } private static float Noise(int x, int y) { uint num = (uint)(x * 374761393 + y * 668265263); num = (num ^ (num >> 13)) * 1274126177; return (float)((num ^ (num >> 16)) & 0xFFFF) / 65535f; } } public sealed class MapFrame : MonoBehaviour, Hoverable, Interactable { public const string ZImage = "vsm_carto_img"; public const string ZTitle = "vsm_carto_title"; public const string ZAuthor = "vsm_carto_author"; public Renderer m_quad; private ZNetView m_nview; private Texture2D m_tex; private Material m_material; private int m_shownHash; private float m_nextCheck; private ItemData m_pendingItem; private string Image => ((Object)(object)m_nview != (Object)null && m_nview.IsValid()) ? m_nview.GetZDO().GetString("vsm_carto_img", "") : string.Empty; public bool HasMap => !string.IsNullOrEmpty(Image); private void Awake() { m_nview = ((Component)this).GetComponent<ZNetView>(); if ((Object)(object)m_nview == (Object)null || m_nview.GetZDO() == null) { ((Behaviour)this).enabled = false; return; } m_nview.Register<string, string, string>("VSM_Carto_Hang", (Action<long, string, string, string>)RPC_Hang); m_nview.Register<bool>("VSM_Carto_HangResult", (Action<long, bool>)RPC_HangResult); m_nview.Register("VSM_Carto_Take", (Action<long>)RPC_Take); m_nview.Register<string, string, string>("VSM_Carto_Taken", (Action<long, string, string, string>)RPC_Taken); Refresh(force: true); } private void OnDestroy() { if ((Object)(object)m_tex != (Object)null) { Object.Destroy((Object)(object)m_tex); } if ((Object)(object)m_material != (Object)null) { Object.Destroy((Object)(object)m_material); } } private void Update() { if (Time.time >= m_nextCheck) { m_nextCheck = Time.time + 0.5f; Refresh(force: false); } } private void Refresh(bool force) { //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Expected O, but got Unknown if ((Object)(object)m_quad == (Object)null || (Object)(object)m_nview == (Object)null || !m_nview.IsValid()) { return; } string image = Image; int num = ((!string.IsNullOrEmpty(image)) ? image.GetHashCode() : 0); if (!force && num == m_shownHash) { return; } m_shownHash = num; CanvasModel canvasModel = (string.IsNullOrEmpty(image) ? null : MapData.Decode(image)); if (canvasModel == null) { m_quad.enabled = false; return; } if ((Object)(object)m_material == (Object)null) { m_material = new Material(m_quad.sharedMaterial); m_quad.sharedMaterial = m_material; } if ((Object)(object)m_tex != (Object)null) { Object.Destroy((Object)(object)m_tex); } m_tex = MapData.NewTexture(canvasModel, (FilterMode)1); m_material.mainTexture = (Texture)(object)m_tex; m_quad.enabled = true; } public string GetHoverText() { string text = "$vsm_carto_frame"; if (!HasMap) { return Localization.instance.Localize(text + "\n[<color=yellow><b>$KEY_Use</b></color>] $vsm_carto_frame_hang"); } string text2 = m_nview.GetZDO().GetString("vsm_carto_title", ""); return Localization.instance.Localize(text + ": " + text2 + "\n[<color=yellow><b>$KEY_Use</b></color>] $vsm_carto_frame_view\n[<color=yellow><b>$KEY_AltPlace + $KEY_Use</b></color>] $vsm_carto_frame_take"); } public float GetHoverOffset() { return 0f; } public string GetHoverName() { return Localization.instance.Localize("$vsm_carto_frame"); } public bool Interact(Humanoid user, bool hold, bool alt) { if (hold || !(user is Player) || (Object)(object)user != (Object)(object)Player.m_localPlayer) { return false; } if (!HasMap) { ItemData val = FindMap(user.GetInventory()); if (val == null) { ((Character)user).Message((MessageType)2, VsmLocalization.Localize("vsm_carto_frame_nomap"), 0, (Sprite)null, false); return true; } return TryHang(user, val); } if (!alt) { ZDO zDO = m_nview.GetZDO(); CartoWindow.OpenView(MapData.Decode(zDO.GetString("vsm_carto_img", "")), zDO.GetString("vsm_carto_title", ""), zDO.GetString("vsm_carto_author", "")); return true; } if (!CheckAccess(user)) { return true; } m_nview.InvokeRPC("VSM_Carto_Take", Array.Empty<object>()); return true; } public bool UseItem(Humanoid user, ItemData item) { if (!MapData.IsMap(item) || (Object)(object)user != (Object)(object)Player.m_localPlayer) { return false; } if (HasMap) { ((Character)user).Message((MessageType)2, VsmLocalization.Localize("vsm_carto_frame_full"), 0, (Sprite)null, false); return true; } return TryHang(user, item); } private bool TryHang(Humanoid user, ItemData map) { if (!CheckAccess(user)) { return true; } map.m_customData.TryGetValue("vsm_carto_img", out var value); map.m_customData.TryGetValue("vsm_carto_title", out var value2); map.m_customData.TryGetValue("vsm_carto_author", out var value3); m_pendingItem = map; m_nview.InvokeRPC("VSM_Carto_Hang", new object[3] { value ?? string.Empty, value2 ?? string.Empty, value3 ?? string.Empty }); return true; } private bool CheckAccess(Humanoid user) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (CartoPlugin.RespectWards.Value && !PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false)) { ((Character)user).Message((MessageType)2, "$piece_noaccess", 0, (Sprite)null, false); return false; } return true; } private static ItemData FindMap(Inventory inv) { ItemData lastViewedMap = CartoPlugin.LastViewedMap; if (lastViewedMap != null && inv.ContainsItem(lastViewedMap) && MapData.IsMap(lastViewedMap)) { return lastViewedMap; } foreach (ItemData allItem in inv.GetAllItems()) { if (MapData.IsMap(allItem)) { return allItem; } } return null; } private void RPC_Hang(long sender, string data, string title, string author) { if (m_nview.IsOwner()) { bool flag = !HasMap && !string.IsNullOrEmpty(data) && data.Length <= CartoPlugin.MaxPrintKB.Value * 1024 * 2; if (flag) { ZDO zDO = m_nview.GetZDO(); zDO.Set("vsm_carto_img", data); zDO.Set("vsm_carto_title", title ?? string.Empty); zDO.Set("vsm_carto_author", author ?? string.Empty); Refresh(force: true); } m_nview.InvokeRPC(sender, "VSM_Carto_HangResult", new object[1] { flag }); } } private void RPC_HangResult(long sender, bool ok) { Player localPlayer = Player.m_localPlayer; ItemData pendingItem = m_pendingItem; m_pendingItem = null; if (!((Object)(object)localPlayer == (Object)null) && pendingItem != null) { if (ok && ((Humanoid)localPlayer).GetInventory().ContainsItem(pendingItem)) { ((Humanoid)localPlayer).GetInventory().RemoveItem(pendingItem); ((Character)localPlayer).Message((MessageType)1, VsmLocalization.Localize("vsm_carto_frame_hung"), 0, (Sprite)null, false); } else if (!ok) { ((Character)localPlayer).Message((MessageType)2, VsmLocalization.Localize("vsm_carto_frame_full"), 0, (Sprite)null, false); } } } private void RPC_Take(long sender) { if (m_nview.IsOwner() && HasMap) { ZDO zDO = m_nview.GetZDO(); string text = zDO.GetString("vsm_carto_img", ""); string text2 = zDO.GetString("vsm_carto_title", ""); string text3 = zDO.GetString("vsm_carto_author", ""); zDO.Set("vsm_carto_img", string.Empty); zDO.Set("vsm_carto_title", string.Empty); zDO.Set("vsm_carto_author", string.Empty); Refresh(force: true); m_nview.InvokeRPC(sender, "VSM_Carto_Taken", new object[3] { text, text2, text3 }); } } private void RPC_Taken(long sender, string data, string title, string author) { //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: 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_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && !string.IsNullOrEmpty(data)) { ItemData val = ((Humanoid)localPlayer).GetInventory().AddItem("vsm_MapScroll", 1, 1, 0, localPlayer.GetPlayerID(), localPlayer.GetPlayerName(), false, false); if (val == null) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("vsm_MapScroll"); ItemData val2 = itemPrefab.GetComponent<ItemDrop>().m_itemData.Clone(); val2.m_dropPrefab = itemPrefab; val2.m_customData["vsm_carto_img"] = data; val2.m_customData["vsm_carto_title"] = title; val2.m_customData["vsm_carto_author"] = author; ItemDrop.DropItem(val2, 1, ((Component)this).transform.position + ((Component)this).transform.forward * -0.6f + Vector3.up * 0.3f, Quaternion.identity); } else { val.m_customData["vsm_carto_img"] = data; val.m_customData["vsm_carto_title"] = title; val.m_customData["vsm_carto_author"] = author; ((Humanoid)localPlayer).GetInventory().Changed(false, false); ((Character)localPlayer).Message((MessageType)1, VsmLocalization.Localize("vsm_carto_frame_taken"), 0, (Sprite)null, false); } } } } internal sealed class MapStandVisual : MonoBehaviour { public static readonly float[] Sizes = new float[7] { 1f, 1.5f, 2f, 3f, 4f, 0.5f, 0.75f }; private static readonly Dictionary<ItemStand, List<Renderer>> s_hiddenByStand = new Dictionary<ItemStand, List<Renderer>>(); private ItemStand m_stand; private ZNetView m_nview; private GameObject m_sheet; private Material m_material; private Texture2D m_texture; private float m_aspect = 1f; private float m_unfold = 1f; private int m_size = -1; private float m_nextCheck; private bool m_dying; public string Title { get; private set; } public string Author { get; private set; } public float SizeMeters => Sizes[Mathf.Clamp(m_size, 0, Sizes.Length - 1)]; private void Awake() { m_stand = ((Component)this).GetComponentInParent<ItemStand>(); m_unfold = (((Object)(object)m_stand != (Object)null && m_stand.m_updateCount > 0 && !HasOtherVisual(m_stand)) ? 0f : 1f); } private bool HasOtherVisual(ItemStand stand) { MapStandVisual[] componentsInChildren = ((Component)stand).GetComponentsInChildren<MapStandVisual>(true); foreach (MapStandVisual mapStandVisual in componentsInChildren) { if ((Object)(object)mapStandVisual != (Object)(object)this && !mapStandVisual.m_dying) { return true; } } return false; } private void Start() { if ((Object)(object)m_stand == (Object)null || Headless.IsHeadless || (Object)(object)m_stand.m_nview == (Object)null || !m_stand.m_nview.IsValid()) { ((Behaviour)this).enabled = false; return; } m_nview = m_stand.m_nview; ItemData val = CartoPrefabs.NewItemData(); CanvasModel canvasModel = null; if (val != null) { ItemDrop.LoadFromZDO(val, m_nview.GetZDO(), -1); canvasModel = MapData.FromItem(val); Title = MapData.Title(val); Author = (val.m_customData.TryGetValue("vsm_carto_author", out var value) ? value : string.Empty); } if (canvasModel == null) { ((Behaviour)this).enabled = false; return; } m_texture = MapArt.SheetTexture(canvasModel); m_aspect = (float)canvasModel.Width / (float)canvasModel.Height; BuildSheet(); HideStand(); m_size = SizeIndex(); Place(); } private void LateUpdate() { if ((Object)(object)m_sheet == (Object)null) { return; } bool flag = false; if (Time.time >= m_nextCheck) { m_nextCheck = Time.time + 0.25f; KeepStandHidden(); int num = SizeIndex(); if (num != m_size) { m_size = num; flag = true; } } if (m_unfold < 1f) { m_unfold = Mathf.MoveTowards(m_unfold, 1f, Time.deltaTime / 0.7f); flag = true; } if (flag) { Place(); } } private void OnDestroy() { m_dying = true; if (m_stand != null && s_hiddenByStand.TryGetValue(m_stand, out var value)) { if ((Object)(object)m_stand == (Object)null) { s_hiddenByStand.Remove(m_stand); } else if (!HasOtherVisual(m_stand)) { foreach (Renderer item in value) { if ((Object)(object)item != (Object)null) { item.enabled = true; } } s_hiddenByStand.Remove(m_stand); } } if ((Object)(object)m_sheet != (Object)null) { Object.Destroy((Object)(object)m_sheet); } if ((Object)(object)m_material != (Object)null) { Object.Destroy((Object)(object)m_material); } if ((Object)(object)m_
plugins/VSM.Connect/VSM.Connect.dll
Decompiled 3 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; using VSM.Core.Harmony; using VSM.Core.Localization; using VSM.Core.Reflection; using VSM.Core.Runtime; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: <9adc67d1-0dc2-4f98-a089-74d06f7bb1af>IgnoresAccessChecksTo("assembly_guiutils")] [assembly: <9adc67d1-0dc2-4f98-a089-74d06f7bb1af>IgnoresAccessChecksTo("assembly_utils")] [assembly: <9adc67d1-0dc2-4f98-a089-74d06f7bb1af>IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("VSM.Connect")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("0.1.4.0")] [assembly: AssemblyInformationalVersion("0.1.4+ff27bc889ccf218c61c45d3417d48ab708a5ba8f")] [assembly: AssemblyProduct("VSM.Connect")] [assembly: AssemblyTitle("VSM.Connect")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.4.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace VSM.Connect { [BepInPlugin("vsm.connect", "MEL Connect", "0.1.4")] public sealed class ConnectPlugin : BaseUnityPlugin { [HarmonyPatch(typeof(ZNet), "RPC_ClientHandshake", new Type[] { typeof(ZRpc), typeof(bool), typeof(string) })] private static class ClientHandshakePatch { [HarmonyPostfix] [HarmonyPriority(200)] private static void Postfix(ZNet __instance, bool needPassword) { if (needPassword) { OnPasswordRequested(__instance); } } } [HarmonyPatch(typeof(ZNet), "OnPasswordEntered", new Type[] { typeof(string) })] private static class PasswordEnteredPatch { [HarmonyPrefix] private static void Prefix(string pwd) { if (s_pendingServer == null || s_pendingPassword != pwd) { OnPasswordSubmitted(pwd, fromStore: false); } } } [HarmonyPatch(typeof(Terminal), "InitTerminal")] private static class TerminalInitPatch { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__1_0; public static ConsoleEvent <>9__1_1; public static ConsoleEvent <>9__1_2; internal void <Postfix>b__1_0(ConsoleEventArgs args) { if (Store == null) { args.Context.AddString("vsm.connect no activo."); return; } args.Context.AddString("vsm.connect: " + Store.Count + " servidores (" + StorePath + ")"); foreach (string server in Store.Servers) { args.Context.AddString(" " + server); } } internal void <Postfix>b__1_1(ConsoleEventArgs args) { if (Store == null) { args.Context.AddString("vsm.connect no activo."); return; } if (args.Length < 2) { args.Context.AddString("uso: vsm_connect_forget <host:puerto> | all (ver vsm_connect_list)"); return; } string text = args.Args[1]; bool flag; if (string.Equals(text, "all", StringComparison.OrdinalIgnoreCase)) { flag = Store.Count > 0; Store.Clear(); } else { flag = Store.Remove(text); } if (flag) { Store.SaveTo(StorePath); } args.Context.AddString(flag ? "vsm.connect: olvidado." : ("vsm.connect: no había contraseña para " + text)); } internal void <Postfix>b__1_2(ConsoleEventArgs args) { if (args.Length >= 2 && string.Equals(args.Args[1], "forget", StringComparison.OrdinalIgnoreCase)) { QuickJoin.Forget(); args.Context.AddString("vsm.connect: último servidor olvidado (el botón desaparece)."); return; } LastServer last = QuickJoin.Last; args.Context.AddString((last == null) ? "vsm.connect: todavía no hay último servidor (entra una vez a uno)." : ("vsm.connect: último servidor = " + last.Label + " [" + last.Kind.ToString() + " " + last.Address + ((last.Kind == ServerKind.Dedicated) ? (":" + last.Port) : string.Empty) + "] con " + (string.IsNullOrEmpty(last.Character) ? "?" : last.Character))); } } private static bool s_registered; [HarmonyPostfix] private static void Postfix() { //IL_0049: 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) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Expected O, but got Unknown if (s_registered) { return; } s_registered = true; object obj = <>c.<>9__1_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { if (Store == null) { args.Context.AddString("vsm.connect no activo."); return; } args.Context.AddString("vsm.connect: " + Store.Count + " servidores (" + StorePath + ")"); foreach (string server in Store.Servers) { args.Context.AddString(" " + server); } }; <>c.<>9__1_0 = val; obj = (object)val; } new ConsoleCommand("vsm_connect_list", "Servidores con contraseña guardada (vsm.connect)", (ConsoleEvent)obj, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj2 = <>c.<>9__1_1; if (obj2 == null) { ConsoleEvent val2 = delegate(ConsoleEventArgs args) { if (Store == null) { args.Context.AddString("vsm.connect no activo."); } else if (args.Length < 2) { args.Context.AddString("uso: vsm_connect_forget <host:puerto> | all (ver vsm_connect_list)"); } else { string text = args.Args[1]; bool flag; if (string.Equals(text, "all", StringComparison.OrdinalIgnoreCase)) { flag = Store.Count > 0; Store.Clear(); } else { flag = Store.Remove(text); } if (flag) { Store.SaveTo(StorePath); } args.Context.AddString(flag ? "vsm.connect: olvidado." : ("vsm.connect: no había contraseña para " + text)); } }; <>c.<>9__1_1 = val2; obj2 = (object)val2; } new ConsoleCommand("vsm_connect_forget", "Olvida la contraseña de un servidor: vsm_connect_forget <host:puerto> | all", (ConsoleEvent)obj2, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj3 = <>c.<>9__1_2; if (obj3 == null) { ConsoleEvent val3 = delegate(ConsoleEventArgs args) { if (args.Length >= 2 && string.Equals(args.Args[1], "forget", StringComparison.OrdinalIgnoreCase)) { QuickJoin.Forget(); args.Context.AddString("vsm.connect: último servidor olvidado (el botón desaparece)."); } else { LastServer last = QuickJoin.Last; args.Context.AddString((last == null) ? "vsm.connect: todavía no hay último servidor (entra una vez a uno)." : ("vsm.connect: último servidor = " + last.Label + " [" + last.Kind.ToString() + " " + last.Address + ((last.Kind == ServerKind.Dedicated) ? (":" + last.Port) : string.Empty) + "] con " + (string.IsNullOrEmpty(last.Character) ? "?" : last.Character))); } }; <>c.<>9__1_2 = val3; obj3 = (object)val3; } new ConsoleCommand("vsm_connect_last", "Último servidor del botón de entrada rápida: vsm_connect_last [forget]", (ConsoleEvent)obj3, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } } internal static ManualLogSource Log; private Harmony _harmony; public static ConfigEntry<bool> RememberPasswords; public static ConfigEntry<bool> AutoSubmit; public static ConfigEntry<bool> ShowMessages; public static ConfigEntry<bool> QuickJoinButton; internal static PasswordStore Store; internal static string StorePath; private static string s_pendingServer; private static string s_pendingPassword; private static bool s_pendingFromStore; private static ConnectionStatus s_lastStatus = (ConnectionStatus)0; private static string s_queuedMessage; private static readonly Dictionary<string, string> s_spanish = new Dictionary<string, string> { { "vsm_connect_saved", "Contraseña del servidor guardada: la próxima vez entrarás sin escribirla" }, { "vsm_connect_used", "Contraseña guardada usada para {0}" }, { "vsm_connect_forgotten", "La contraseña guardada para {0} ya no es válida y se borró" }, { "vsm_connect_quick", "Entrar a {0}" } }; internal static bool CanUse => Store != null && Dpapi.Available && RememberPasswords.Value; private void Awake() { //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; RememberPasswords = ((BaseUnityPlugin)this).Config.Bind<bool>("1. Contraseñas", "RememberPasswords", true, "Guardar la contraseña de cada servidor tras entrar con éxito y rellenarla sola la próxima vez."); AutoSubmit = ((BaseUnityPlugin)this).Config.Bind<bool>("1. Contraseñas", "AutoSubmit", true, "Enviar la contraseña guardada sin mostrar el cuadro de contraseña. Con false se rellena pero tienes que pulsar Enter."); ShowMessages = ((BaseUnityPlugin)this).Config.Bind<bool>("2. Interfaz", "ShowMessages", true, "Avisos en pantalla al guardar, usar o borrar una contraseña."); QuickJoinButton = ((BaseUnityPlugin)this).Config.Bind<bool>("3. Entrada rápida", "QuickJoinButton", true, "Botón 'Entrar a <servidor>' en el menú principal: vuelve al último servidor en el que entraste, con el mismo personaje (la contraseña guardada se envía sola)."); Log.LogInfo((object)("vsm.connect 0.1.4 | Valheim " + GameConstants.GameVersionString + " | headless=" + Headless.IsHeadless)); if (Headless.IsHeadless) { Log.LogInfo((object)"vsm.connect: servidor dedicado: nada que hacer (mod de cliente)."); return; } StorePath = Path.Combine(Paths.ConfigPath, "vsm.connect.passwords.txt"); QuickJoin.Load(Path.Combine(Paths.ConfigPath, "vsm.connect.last.txt")); QuickJoinButton.SettingChanged += delegate { if ((Object)(object)FejdStartup.instance != (Object)null) { QuickJoin.Refresh(FejdStartup.instance); } }; Store = new PasswordStore(Dpapi.Protect, Dpapi.Unprotect); if (!Dpapi.Available) { Log.LogWarning((object)"vsm.connect: DPAPI no disponible (no es Windows): no se guardarán contraseñas."); } else { try { int num = Store.LoadFrom(StorePath); Log.LogInfo((object)("vsm.connect: " + Store.Count + " servidores con contraseña guardada" + ((num > 0) ? (" (" + num + " líneas dañadas ignoradas)") : string.Empty) + ".")); } catch (Exception ex) { Log.LogError((object)("vsm.connect: no se pudo leer " + StorePath + ": " + ex.Message)); } } VsmLocalization.Register(Log, Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), s_spanish); _harmony = new Harmony("vsm.connect"); PatchUtil.PatchAllSafely(Log, _harmony, Assembly.GetExecutingAssembly()); } private void OnDestroy() { if (_harmony != null) { _harmony.UnpatchSelf(); } } internal static string CurrentServerKey() { string serverHost = ZNet.m_serverHost; if (!string.IsNullOrEmpty(serverHost)) { return serverHost + ":" + ZNet.m_serverHostPort; } return ZNet.GetServerString(true); } internal static void OnPasswordSubmitted(string password, bool fromStore) { if (CanUse && !string.IsNullOrEmpty(password)) { s_pendingServer = CurrentServerKey(); s_pendingPassword = password; s_pendingFromStore = fromStore; } } internal static void OnPasswordRequested(ZNet znet) { if (!CanUse || (Object)(object)znet == (Object)null || !znet.InPasswordDialog()) { return; } string text = CurrentServerKey(); string text2 = Store.Get(text); if (text2 != null) { TMP_InputField componentInChildren = ((Component)znet.m_passwordDialog).GetComponentInChildren<TMP_InputField>(); if (AutoSubmit.Value) { Log.LogInfo((object)("vsm.connect: usando la contraseña guardada para " + text + ".")); s_queuedMessage = VsmLocalization.Localize("vsm_connect_used", text); OnPasswordSubmitted(text2, fromStore: true); znet.OnPasswordEntered(text2); } else if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.text = text2; componentInChildren.MoveTextEnd(false); } } } private void Update() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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) if (_harmony == null) { return; } ConnectionStatus connectionStatus = ZNet.GetConnectionStatus(); if (connectionStatus != s_lastStatus) { s_lastStatus = connectionStatus; OnStatus(connectionStatus); } if (s_queuedMessage != null && (Object)(object)Player.m_localPlayer != (Object)null) { if (ShowMessages.Value) { ((Character)Player.m_localPlayer).Message((MessageType)1, s_queuedMessage, 0, (Sprite)null, false); } s_queuedMessage = null; } } private static void OnStatus(ConnectionStatus status) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Invalid comparison between Unknown and I4 //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Invalid comparison between Unknown and I4 //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Invalid comparison between Unknown and I4 //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Invalid comparison between Unknown and I4 if ((int)status == 2) { QuickJoin.OnConnected(); } else if ((int)status >= 3) { QuickJoin.OnFailed(); } if (s_pendingServer == null) { return; } try { if ((int)status == 2) { if (!s_pendingFromStore || Store.Get(s_pendingServer) != s_pendingPassword) { Store.Set(s_pendingServer, s_pendingPassword); Store.SaveTo(StorePath); Log.LogInfo((object)("vsm.connect: contraseña guardada para " + s_pendingServer + ".")); s_queuedMessage = VsmLocalization.Localize("vsm_connect_saved"); } Clear(); } else if ((int)status == 6) { if (s_pendingFromStore && Store.Remove(s_pendingServer)) { Store.SaveTo(StorePath); Log.LogWarning((object)("vsm.connect: el servidor " + s_pendingServer + " rechazó la contraseña guardada; se borró.")); s_queuedMessage = VsmLocalization.Localize("vsm_connect_forgotten", s_pendingServer); } Clear(); } else if ((int)status >= 3) { Clear(); } } catch (Exception ex) { Log.LogError((object)("vsm.connect: error guardando la contraseña: " + ex.Message)); Clear(); } } private static void Clear() { s_pendingServer = null; s_pendingPassword = null; s_pendingFromStore = false; } } public static class Dpapi { [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] private struct DataBlob { public int cbData; public IntPtr pbData; } private static readonly byte[] s_entropy = Encoding.UTF8.GetBytes("vsm.connect/v1"); private const int CRYPTPROTECT_UI_FORBIDDEN = 1; public static bool Available => Environment.OSVersion.Platform == PlatformID.Win32NT; [DllImport("crypt32.dll", CharSet = CharSet.Unicode, SetLastError = true)] private static extern bool CryptProtectData(ref DataBlob dataIn, string description, ref DataBlob entropy, IntPtr reserved, IntPtr prompt, int flags, out DataBlob dataOut); [DllImport("crypt32.dll", CharSet = CharSet.Unicode, SetLastError = true)] private static extern bool CryptUnprotectData(ref DataBlob dataIn, IntPtr description, ref DataBlob entropy, IntPtr reserved, IntPtr prompt, int flags, out DataBlob dataOut); [DllImport("kernel32.dll")] private static extern IntPtr LocalFree(IntPtr mem); public static byte[] Protect(byte[] plain) { return Run(plain, protect: true); } public static byte[] Unprotect(byte[] cipher) { return Run(cipher, protect: false); } private static byte[] Run(byte[] input, bool protect) { if (!Available) { throw new PlatformNotSupportedException("DPAPI solo existe en Windows"); } if (input == null) { throw new ArgumentNullException("input"); } GCHandle gCHandle = GCHandle.Alloc(input, GCHandleType.Pinned); GCHandle gCHandle2 = GCHandle.Alloc(s_entropy, GCHandleType.Pinned); DataBlob dataOut = default(DataBlob); try { DataBlob dataIn = new DataBlob { cbData = input.Length, pbData = gCHandle.AddrOfPinnedObject() }; DataBlob entropy = new DataBlob { cbData = s_entropy.Length, pbData = gCHandle2.AddrOfPinnedObject() }; if (!(protect ? CryptProtectData(ref dataIn, "vsm.connect", ref entropy, IntPtr.Zero, IntPtr.Zero, 1, out dataOut) : CryptUnprotectData(ref dataIn, IntPtr.Zero, ref entropy, IntPtr.Zero, IntPtr.Zero, 1, out dataOut))) { throw new InvalidOperationException("DPAPI falló (error " + Marshal.GetLastWin32Error() + ")"); } byte[] array = new byte[dataOut.cbData]; Marshal.Copy(dataOut.pbData, array, 0, dataOut.cbData); return array; } finally { if (dataOut.pbData != IntPtr.Zero) { LocalFree(dataOut.pbData); } gCHandle.Free(); gCHandle2.Free(); } } } public enum ServerKind { Dedicated, Steam, PlayFab } public sealed class LastServer { private const string Version = "v1"; public ServerKind Kind; public string Address = string.Empty; public int Port; public string Name = string.Empty; public string Character = string.Empty; public int CharacterSource; public string Label { get { if (!string.IsNullOrEmpty(Name)) { return Name; } return (Kind == ServerKind.Dedicated) ? (Address + ":" + Port.ToString(CultureInfo.InvariantCulture)) : Address; } } public bool IsValid { get { if (string.IsNullOrEmpty(Address)) { return false; } ulong result; return Kind switch { ServerKind.Dedicated => Port > 0 && Port <= 65535, ServerKind.Steam => ulong.TryParse(Address, NumberStyles.None, CultureInfo.InvariantCulture, out result) && result != 0, _ => true, }; } } public string Serialize() { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("v1").Append('\t').Append(Kind.ToString()) .Append('\t') .Append(Clean(Address)) .Append('\t') .Append(Port.ToString(CultureInfo.InvariantCulture)) .Append('\t') .Append(Clean(Name)) .Append('\t') .Append(Clean(Character)) .Append('\t') .Append(CharacterSource.ToString(CultureInfo.InvariantCulture)); return stringBuilder.ToString(); } public static LastServer Parse(string text) { if (string.IsNullOrEmpty(text)) { return null; } string text2 = text.Trim('\ufeff', '\r', '\n', ' '); int num = text2.IndexOf('\n'); if (num >= 0) { text2 = text2.Substring(0, num).TrimEnd(new char[1] { '\r' }); } string[] array = text2.Split(new char[1] { '\t' }); if (array.Length < 7 || array[0] != "v1") { return null; } if (!TryKind(array[1], out var kind) || !int.TryParse(array[3], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result) || !int.TryParse(array[6], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result2)) { return null; } LastServer lastServer = new LastServer { Kind = kind, Address = array[2].Trim(), Port = result, Name = array[4].Trim(), Character = array[5].Trim(), CharacterSource = result2 }; return lastServer.IsValid ? lastServer : null; } public void SaveTo(string path) { string text = path + ".tmp"; File.WriteAllText(text, Serialize() + "\n", new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)); if (File.Exists(path)) { File.Delete(path); } File.Move(text, path); } public static LastServer LoadFrom(string path) { return File.Exists(path) ? Parse(File.ReadAllText(path, Encoding.UTF8)) : null; } private static bool TryKind(string text, out ServerKind kind) { ServerKind[] array = (ServerKind[])Enum.GetValues(typeof(ServerKind)); for (int i = 0; i < array.Length; i++) { ServerKind serverKind = array[i]; if (string.Equals(serverKind.ToString(), text, StringComparison.OrdinalIgnoreCase)) { kind = serverKind; return true; } } kind = ServerKind.Dedicated; return false; } private static string Clean(string s) { if (string.IsNullOrEmpty(s)) { return string.Empty; } StringBuilder stringBuilder = new StringBuilder(s.Length); foreach (char c in s) { stringBuilder.Append((c == '\t' || c == '\r' || c == '\n') ? ' ' : c); } string text = stringBuilder.ToString().Trim(); return (text.Length > 120) ? text.Substring(0, 120) : text; } } public sealed class PasswordStore { public const string Header = "# vsm.connect: contraseñas de servidor cifradas con DPAPI (solo este usuario de Windows en esta PC puede leerlas)."; private readonly Dictionary<string, string> _entries = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); private readonly Func<byte[], byte[]> _protect; private readonly Func<byte[], byte[]> _unprotect; public int Count => _entries.Count; public IEnumerable<string> Servers => _entries.Keys; public PasswordStore(Func<byte[], byte[]> protect, Func<byte[], byte[]> unprotect) { _protect = protect ?? throw new ArgumentNullException("protect"); _unprotect = unprotect ?? throw new ArgumentNullException("unprotect"); } public static string NormalizeKey(string server) { return (server ?? string.Empty).Trim().ToLowerInvariant(); } public void Set(string server, string password) { string text = NormalizeKey(server); if (text.Length == 0 || text.IndexOf('\t') >= 0 || text.IndexOf('\n') >= 0 || string.IsNullOrEmpty(password)) { throw new ArgumentException("servidor o contraseña inválidos"); } _entries[text] = Convert.ToBase64String(_protect(Encoding.UTF8.GetBytes(password))); } public string Get(string server) { if (!_entries.TryGetValue(NormalizeKey(server), out var value)) { return null; } try { return Encoding.UTF8.GetString(_unprotect(Convert.FromBase64String(value))); } catch (Exception) { return null; } } public bool Contains(string server) { return _entries.ContainsKey(NormalizeKey(server)); } public bool Remove(string server) { return _entries.Remove(NormalizeKey(server)); } public void Clear() { _entries.Clear(); } public string Serialize() { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("# vsm.connect: contraseñas de servidor cifradas con DPAPI (solo este usuario de Windows en esta PC puede leerlas)."); List<string> list = new List<string>(_entries.Keys); list.Sort(StringComparer.OrdinalIgnoreCase); foreach (string item in list) { stringBuilder.Append(item).Append('\t').Append(_entries[item]) .Append('\n'); } return stringBuilder.ToString(); } public int Load(string text) { _entries.Clear(); int num = 0; if (string.IsNullOrEmpty(text)) { return 0; } string[] array = text.Split(new char[1] { '\n' }); foreach (string text2 in array) { string text3 = text2.TrimEnd(new char[1] { '\r' }); if (text3.Length == 0 || text3.StartsWith("#", StringComparison.Ordinal)) { continue; } int num2 = text3.IndexOf('\t'); if (num2 <= 0 || num2 == text3.Length - 1) { num++; continue; } string key = NormalizeKey(text3.Substring(0, num2)); string text4 = text3.Substring(num2 + 1).Trim(); try { Convert.FromBase64String(text4); } catch (FormatException) { num++; continue; } _entries[key] = text4; } return num; } public void SaveTo(string path) { string text = path + ".tmp"; File.WriteAllText(text, Serialize(), new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)); if (File.Exists(path)) { File.Delete(path); } File.Move(text, path); } public int LoadFrom(string path) { return File.Exists(path) ? Load(File.ReadAllText(path, Encoding.UTF8)) : 0; } } internal static class QuickJoin { [HarmonyPatch(typeof(FejdStartup), "Start")] private static class MenuStartPatch { [HarmonyPostfix] private static void Postfix(FejdStartup __instance) { try { Refresh(__instance); } catch (Exception ex) { ConnectPlugin.Log.LogError((object)("vsm.connect: botón de entrada rápida: " + ex)); } } } [HarmonyPatch(typeof(FejdStartup), "JoinServer")] private static class JoinServerPatch { [HarmonyPostfix] private static void Postfix(FejdStartup __instance) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected I4, but got Unknown try { if (!((MonoBehaviour)__instance).IsInvoking("LoadMainSceneIfBackendSelected")) { return; } LastServer lastServer = FromJoinData(__instance.m_joinServer); if (lastServer != null) { List<PlayerProfile> profiles = __instance.m_profiles; int profileIndex = __instance.m_profileIndex; if (profiles != null && profileIndex >= 0 && profileIndex < profiles.Count && profiles[profileIndex] != null) { lastServer.Character = profiles[profileIndex].GetFilename(); lastServer.CharacterSource = (int)profiles[profileIndex].m_fileSource; } s_pendingData = __instance.m_joinServer; s_pending = lastServer; } } catch (Exception ex) { ConnectPlugin.Log.LogWarning((object)("vsm.connect: no se pudo recordar el servidor: " + ex.Message)); } } } private const string ButtonName = "vsm_connect_quickjoin"; internal static string FilePath; internal static LastServer Last; private static LastServer s_pending; private static ServerJoinData s_pendingData; public static void Load(string path) { FilePath = path; try { Last = LastServer.LoadFrom(path); } catch (Exception ex) { ConnectPlugin.Log.LogWarning((object)("vsm.connect: no se pudo leer " + path + ": " + ex.Message)); Last = null; } } public static void OnConnected() { //IL_0041: Unknown result type (might be due to invalid IL or missing references) LastServer lastServer = s_pending; s_pending = null; if (lastServer == null || (Object)(object)ZNet.instance == (Object)null || ZNet.instance.IsServer()) { return; } string text = default(string); if (string.IsNullOrEmpty(lastServer.Name) && MultiBackendMatchmaking.TryGetServerName(s_pendingData, ref text) && !string.IsNullOrEmpty(text)) { lastServer.Name = text; } try { Last = lastServer; Last.SaveTo(FilePath); ConnectPlugin.Log.LogInfo((object)("vsm.connect: último servidor = " + Last.Label + " (" + Last.Character + ").")); } catch (Exception ex) { ConnectPlugin.Log.LogWarning((object)("vsm.connect: no se pudo guardar el último servidor: " + ex.Message)); } } public static void OnFailed() { s_pending = null; } public static void Forget() { Last = null; s_pending = null; try { if (FilePath != null && File.Exists(FilePath)) { File.Delete(FilePath); } } catch (Exception ex) { ConnectPlugin.Log.LogWarning((object)("vsm.connect: no se pudo borrar " + FilePath + ": " + ex.Message)); } FejdStartup instance = FejdStartup.instance; if ((Object)(object)instance != (Object)null) { Refresh(instance); } } private static LastServer FromJoinData(ServerJoinData data) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected I4, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) if (!((ServerJoinData)(ref data)).IsValid) { return null; } LastServer lastServer = new LastServer(); ServerJoinDataType type = data.m_type; ServerJoinDataType val = type; switch (val - 1) { case 2: { lastServer.Kind = ServerKind.Dedicated; ServerJoinDataDedicated dedicated = ((ServerJoinData)(ref data)).Dedicated; lastServer.Address = ((ServerJoinDataDedicated)(ref dedicated)).m_host; lastServer.Port = ((ServerJoinData)(ref data)).Dedicated.m_port; break; } case 0: lastServer.Kind = ServerKind.Steam; lastServer.Address = ((ulong)((ServerJoinData)(ref data)).SteamUser.m_joinUserID).ToString(CultureInfo.InvariantCulture); break; case 1: lastServer.Kind = ServerKind.PlayFab; lastServer.Address = ((ServerJoinData)(ref data)).PlayFabUser.m_remotePlayerId; break; default: return null; } string text = default(string); if (MultiBackendMatchmaking.TryGetServerName(data, ref text) && !string.IsNullOrEmpty(text)) { lastServer.Name = text; } return lastServer.IsValid ? lastServer : null; } private static ServerJoinData ToJoinData(LastServer s) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //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_0049: 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_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) return (ServerJoinData)(s.Kind switch { ServerKind.Dedicated => new ServerJoinData(new ServerJoinDataDedicated(s.Address, (ushort)s.Port)), ServerKind.Steam => new ServerJoinData(new ServerJoinDataSteamUser(ulong.Parse(s.Address, CultureInfo.InvariantCulture))), _ => new ServerJoinData(new ServerJoinDataPlayFabUser(s.Address)), }); } public static void Refresh(FejdStartup menu) { if ((Object)(object)menu == (Object)null || (Object)(object)menu.m_menuList == (Object)null) { return; } Button val = null; Button[] componentsInChildren = menu.m_menuList.GetComponentsInChildren<Button>(true); foreach (Button val2 in componentsInChildren) { if (((Object)val2).name == "vsm_connect_quickjoin") { val = val2; break; } } bool flag = ConnectPlugin.QuickJoinButton.Value && Last != null; if ((Object)(object)val == (Object)null) { if (!flag) { return; } val = CreateButton(menu); if ((Object)(object)val == (Object)null) { return; } } ((Component)val).gameObject.SetActive(flag); if (flag) { SetLabel(val, VsmLocalization.Localize("vsm_connect_quick", Last.Label), ReferenceText(menu, val)); } List<Button> list = new List<Button>(); Button[] componentsInChildren2 = menu.m_menuList.GetComponentsInChildren<Button>(); foreach (Button item in componentsInChildren2) { list.Add(item); } menu.m_menuButtons = list.ToArray(); } private static Button CreateButton(FejdStartup menu) { //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Expected O, but got Unknown //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Expected O, but got Unknown Button val = null; Button[] componentsInChildren = menu.m_menuList.GetComponentsInChildren<Button>(true); foreach (Button val2 in componentsInChildren) { if (((Component)val2).gameObject.activeSelf) { val = val2; break; } } if ((Object)(object)val == (Object)null) { ConnectPlugin.Log.LogWarning((object)"vsm.connect: no se encontró el botón 'Comenzar' del menú; sin botón de entrada rápida."); return null; } GameObject val3 = Object.Instantiate<GameObject>(((Component)val).gameObject, ((Component)val).transform.parent, false); ((Object)val3).name = "vsm_connect_quickjoin"; val3.transform.SetSiblingIndex(((Component)val).transform.GetSiblingIndex() + 1); Localize[] componentsInChildren2 = val3.GetComponentsInChildren<Localize>(true); foreach (Localize val4 in componentsInChildren2) { Object.Destroy((Object)(object)val4); } UIGamePad[] componentsInChildren3 = val3.GetComponentsInChildren<UIGamePad>(true); foreach (UIGamePad val5 in componentsInChildren3) { if ((Object)(object)val5.m_hint != (Object)null) { Object.Destroy((Object)(object)val5.m_hint); } Object.Destroy((Object)(object)val5); } Button component = val3.GetComponent<Button>(); component.onClick = new ButtonClickedEvent(); ((UnityEvent)component.onClick).AddListener((UnityAction)delegate { Join(menu); }); return component; } private static TMP_Text ReferenceText(FejdStartup menu, Button ours) { Button[] componentsInChildren = menu.m_menuList.GetComponentsInChildren<Button>(); foreach (Button val in componentsInChildren) { if (!((Object)(object)val == (Object)(object)ours)) { TMP_Text componentInChildren = ((Component)val).GetComponentInChildren<TMP_Text>(); if ((Object)(object)componentInChildren != (Object)null) { return componentInChildren; } } } return null; } private static void SetLabel(Button button, string text, TMP_Text reference) { TMP_Text[] componentsInChildren = ((Component)button).GetComponentsInChildren<TMP_Text>(true); foreach (TMP_Text val in componentsInChildren) { float num = (((Object)(object)reference != (Object)null && reference.fontSize > 0f) ? reference.fontSize : val.fontSize); val.text = text; val.enableAutoSizing = true; val.fontSizeMax = num; val.fontSizeMin = Mathf.Min(12f, num); val.enableWordWrapping = false; val.overflowMode = (TextOverflowModes)1; } } public static void Join(FejdStartup menu) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Invalid comparison between Unknown and I4 //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) LastServer last = Last; if ((Object)(object)menu == (Object)null || last == null) { return; } try { ServerJoinData queuedJoinServer = ToJoinData(last); if (!((ServerJoinData)(ref queuedJoinServer)).IsValid) { ConnectPlugin.Log.LogWarning((object)"vsm.connect: el último servidor guardado no es válido; se olvida."); Forget(); return; } if (menu.m_profiles == null) { menu.m_profiles = SaveSystem.GetAllPlayerProfiles(); } int num = -1; for (int i = 0; i < menu.m_profiles.Count; i++) { PlayerProfile val = menu.m_profiles[i]; if (val != null && string.Equals(val.GetFilename(), last.Character, StringComparison.OrdinalIgnoreCase) && (int)val.m_fileSource == last.CharacterSource) { num = i; break; } } ConnectPlugin.Log.LogInfo((object)("vsm.connect: entrada rápida a " + last.Label + ((num >= 0) ? (" con " + last.Character) : " (elige personaje)") + ".")); menu.m_queuedJoinServer = queuedJoinServer; if (num < 0) { menu.OnStartGame(); return; } menu.m_mainMenu.SetActive(false); menu.m_profileIndex = num; menu.OnCharacterStart(); } catch (Exception ex) { ConnectPlugin.Log.LogError((object)("vsm.connect: no se pudo entrar al último servidor: " + ex)); } } } public static class MyPluginInfo { public const string PLUGIN_GUID = "vsm.connect"; public const string PLUGIN_NAME = "MEL Connect"; public const string PLUGIN_VERSION = "0.1.4"; } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class <9adc67d1-0dc2-4f98-a089-74d06f7bb1af>IgnoresAccessChecksToAttribute : Attribute { public <9adc67d1-0dc2-4f98-a089-74d06f7bb1af>IgnoresAccessChecksToAttribute(string assemblyName) { } } } namespace VSM.Core.Ui { internal static class VanillaStyle { public static TMP_Text TitleFont => ((Object)(object)InventoryGui.instance != (Object)null) ? InventoryGui.instance.m_playerName : null; public static TMP_Text BodyFont => (!((Object)(object)InventoryGui.instance != (Object)null)) ? null : (((Object)(object)InventoryGui.instance.m_armor != (Object)null) ? InventoryGui.instance.m_armor : InventoryGui.instance.m_playerName); public static Image FindBackground(Transform root, Transform exclude1, Transform exclude2) { //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)root == (Object)null) { return null; } Image result = null; float num = 0f; Image[] componentsInChildren = ((Component)root).GetComponentsInChildren<Image>(true); foreach (Image val in componentsInChildren) { if ((Object)(object)val == (Object)null || (Object)(object)val.sprite == (Object)null) { continue; } Transform transform = ((Component)val).transform; if ((!((Object)(object)exclude1 != (Object)null) || !transform.IsChildOf(exclude1)) && (!((Object)(object)exclude2 != (Object)null) || !transform.IsChildOf(exclude2))) { Rect rect = ((Graphic)val).rectTransform.rect; float num2 = Mathf.Abs(((Rect)(ref rect)).width * ((Rect)(ref rect)).height); if (num2 > num) { num = num2; result = val; } } } return result; } public static bool CopyImage(Image source, Image target) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target == (Object)null) { return false; } if ((Object)(object)source == (Object)null) { ((Graphic)target).color = new Color(0f, 0f, 0f, 0.6f); return false; } target.sprite = source.sprite; target.type = source.type; ((Graphic)target).material = ((Graphic)source).material; ((Graphic)target).color = ((Graphic)source).color; target.fillCenter = source.fillCenter; target.pixelsPerUnitMultiplier = source.pixelsPerUnitMultiplier; target.preserveAspect = false; return true; } public static Image InventoryBackground(Transform exclude) { InventoryGui instance = InventoryGui.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.m_player == (Object)null) { return null; } Transform exclude2 = (Transform)(object)(((Object)(object)instance.m_playerGrid != (Object)null) ? instance.m_playerGrid.m_gridRoot : null); return FindBackground((Transform)(object)instance.m_player, exclude2, exclude); } public static void CopyFont(TMP_Text source, TMP_Text target) { //IL_0037: 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) if (!((Object)(object)source == (Object)null) && !((Object)(object)target == (Object)null)) { target.font = source.font; target.fontSharedMaterial = source.fontSharedMaterial; ((Graphic)target).color = ((Graphic)source).color; target.fontStyle = source.fontStyle; } } public static TextMeshProUGUI NewText(Transform parent, string name, TMP_Text style, float size, TextAlignmentOptions align) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0041: 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(parent, false); TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>(); CopyFont(style, (TMP_Text)(object)val2); ((TMP_Text)val2).fontSize = size; ((TMP_Text)val2).alignment = align; ((Graphic)val2).raycastTarget = false; ((TMP_Text)val2).enableWordWrapping = false; ((TMP_Text)val2).richText = true; return val2; } } } namespace VSM.Core.Runtime { internal static class Headless { private static bool? s_isHeadless; public static bool IsHeadless { get { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 if (!s_isHeadless.HasValue) { s_isHeadless = (int)SystemInfo.graphicsDeviceType == 4 || Application.isBatchMode; } return s_isHeadless.Value; } } public static bool IsServerProcess => (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer(); public static bool IsDedicatedServer => (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && ZNet.instance.IsDedicated(); public static bool IsListenHost => (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && !ZNet.instance.IsDedicated(); public static bool IsRemoteClient => (Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer(); } internal static class Keys { public static bool Pressed(KeyboardShortcut shortcut) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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) KeyCode mainKey = ((KeyboardShortcut)(ref shortcut)).MainKey; return (int)mainKey != 0 && ZInput.GetKeyDown(mainKey, false) && ((KeyboardShortcut)(ref shortcut)).Modifiers.All((KeyCode m) => ZInput.GetKey(m, false)); } } } namespace VSM.Core.Reflection { internal static class GameConstants { private static uint? s_networkVersion; private static long? s_routedEverybody; public static uint NetworkVersion { get { if (!s_networkVersion.HasValue) { s_networkVersion = ReadConstant<uint>(typeof(Version), new string[2] { "c_networkVersion", "m_networkVersion" }); } return s_networkVersion.Value; } } public static long RoutedRpcEverybody { get { if (!s_routedEverybody.HasValue) { s_routedEverybody = ReadConstant<long>(typeof(ZRoutedRpc), new string[1] { "Everybody" }); } return s_routedEverybody.Value; } } public static string GameVersionString { get { //IL_0002: 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) try { return ((object)Version.CurrentVersion/*cast due to .constrained prefix*/).ToString(); } catch (Exception) { return "?"; } } } private static T ReadConstant<T>(Type type, params string[] names) where T : struct { foreach (string name in names) { FieldInfo field = type.GetField(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (!(field == null)) { object obj = (field.IsLiteral ? field.GetRawConstantValue() : field.GetValue(null)); if (obj is T result) { return result; } try { return (T)Convert.ChangeType(obj, typeof(T)); } catch (Exception) { } } } return default(T); } } } namespace VSM.Core.Net { internal static class ZPackageExt { public static bool HasMore(this ZPackage pkg) { return pkg != null && pkg.GetPos() < pkg.Size(); } public static int ReadIntOr(this ZPackage pkg, int fallback) { return pkg.HasMore() ? pkg.ReadInt() : fallback; } public static string ReadStringOr(this ZPackage pkg, string fallback) { return pkg.HasMore() ? pkg.ReadString() : fallback; } public static bool ReadBoolOr(this ZPackage pkg, bool fallback) { return pkg.HasMore() ? pkg.ReadBool() : fallback; } public static string ReadBoundedString(this ZPackage pkg, int maxLength) { string text = pkg.ReadString(); return (text != null && text.Length <= maxLength) ? text : null; } } } namespace VSM.Core.Localization { internal static class VsmLocalization { public static void Register(ManualLogSource log, string pluginDirectory, IDictionary<string, string> embeddedSpanish) { Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.Ordinal); if (embeddedSpanish != null) { foreach (KeyValuePair<string, string> item in embeddedSpanish) { dictionary[item.Key] = item.Value; } } string path = Path.Combine(pluginDirectory ?? string.Empty, "Translations"); MergeFile(log, Path.Combine(path, "Spanish.json"), dictionary); string text = SafeSelectedLanguage(); if (!string.Equals(text, "Spanish", StringComparison.OrdinalIgnoreCase)) { MergeFile(log, Path.Combine(path, text + ".json"), dictionary); } Apply(log, dictionary); } public static string Localize(string token, params object[] args) { string text = token; try { if (Localization.instance != null && !string.IsNullOrEmpty(token)) { bool flag = token[0] != '$' && token.IndexOf(' ') < 0 && token.IndexOf('\n') < 0; string text2 = Localization.instance.Localize(flag ? ("$" + token) : token); text = ((flag && text2.Length > 1 && text2[0] == '[' && text2[text2.Length - 1] == ']') ? token : text2); } } catch (Exception) { text = token; } if (args != null && args.Length != 0) { try { text = string.Format(text, args); } catch (FormatException) { } } return text; } private static string SafeSelectedLanguage() { try { return (Localization.instance != null) ? Localization.instance.GetSelectedLanguage() : "Spanish"; } catch (Exception) { return "Spanish"; } } private static void Apply(ManualLogSource log, Dictionary<string, string> words) { if (Localization.instance == null) { if (log != null) { log.LogWarning((object)"Localization.instance aún no existe; las traducciones no se han aplicado."); } return; } foreach (KeyValuePair<string, string> word in words) { string text = (word.Key.StartsWith("$", StringComparison.Ordinal) ? word.Key.Substring(1) : word.Key); Localization.instance.AddWord(text, word.Value); } } private static void MergeFile(ManualLogSource log, string path, Dictionary<string, string> into) { if (!File.Exists(path)) { return; } try { foreach (KeyValuePair<string, string> item in ParseFlatJson(File.ReadAllText(path, Encoding.UTF8))) { into[item.Key] = item.Value; } } catch (Exception ex) { if (log != null) { log.LogWarning((object)("No se pudo leer " + path + ": " + ex.Message)); } } } public static Dictionary<string, string> ParseFlatJson(string json) { Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.Ordinal); if (string.IsNullOrEmpty(json)) { return dictionary; } int i = 0; SkipWs(json, ref i); if (i >= json.Length || json[i] != '{') { return dictionary; } i++; while (true) { SkipWs(json, ref i); if (i >= json.Length || json[i] == '}') { break; } if (json[i] == ',') { i++; continue; } string text = ReadString(json, ref i); if (text == null) { i++; continue; } SkipWs(json, ref i); if (i < json.Length && json[i] == ':') { i++; } SkipWs(json, ref i); if (i < json.Length && json[i] == '"') { string text2 = ReadString(json, ref i); dictionary[text] = text2 ?? string.Empty; } else { for (; i < json.Length && json[i] != ',' && json[i] != '}'; i++) { } } } return dictionary; } private static void SkipWs(string s, ref int i) { while (i < s.Length && char.IsWhiteSpace(s[i])) { i++; } } private static string ReadString(string s, ref int i) { if (i >= s.Length || s[i] != '"') { return null; } i++; StringBuilder stringBuilder = new StringBuilder(); while (i < s.Length) { char c = s[i++]; switch (c) { case '"': return stringBuilder.ToString(); case '\\': { if (i >= s.Length) { break; } char c2 = s[i++]; switch (c2) { case 'n': stringBuilder.Append('\n'); break; case 't': stringBuilder.Append('\t'); break; case 'r': stringBuilder.Append('\r'); break; case 'b': stringBuilder.Append('\b'); break; case 'f': stringBuilder.Append('\f'); break; case 'u': if (i + 4 <= s.Length) { stringBuilder.Append((char)Convert.ToInt32(s.Substring(i, 4), 16)); i += 4; } break; default: stringBuilder.Append(c2); break; } continue; } } stringBuilder.Append(c); } return stringBuilder.ToString(); } } } namespace VSM.Core.Harmony { internal static class PatchUtil { private static readonly List<string> s_failed = new List<string>(); public static IReadOnlyList<string> FailedTargets => s_failed; public static bool IsDegraded => s_failed.Count > 0; public static MethodInfo DeclaredMethodOrNull(ManualLogSource log, Type type, string name, Type[] parameters, string owner) { if (type == null) { Fail(log, owner, name + " (tipo nulo)"); return null; } MethodInfo methodInfo = AccessTools.DeclaredMethod(type, name, parameters, (Type[])null); if (methodInfo == null) { Fail(log, owner, type.FullName + "." + name + "(" + Describe(parameters) + ")"); } return methodInfo; } public static void PatchAllSafely(ManualLogSource log, Harmony harmony, Assembly assembly) { Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(assembly); foreach (Type type in typesFromAssembly) { if (type.GetCustomAttributes(typeof(HarmonyPatch), inherit: true).Length != 0) { PatchClassSafely(log, harmony, type); } } } public static bool PatchClassSafely(ManualLogSource log, Harmony harmony, Type patchClass) { try { harmony.CreateClassProcessor(patchClass).Patch(); return true; } catch (Exception ex) { Fail(log, harmony.Id, patchClass.FullName + " -> " + ex.GetType().Name + ": " + ex.Message); return false; } } private static void Fail(ManualLogSource log, string owner, string what) { s_failed.Add(what); if (log != null) { log.LogError((object)("[" + owner + "] No se pudo aplicar el parche (¿cambió el juego?): " + what + ". El mod sigue cargado en modo degradado.")); } } private static string Describe(Type[] parameters) { if (parameters == null || parameters.Length == 0) { return string.Empty; } string[] array = new string[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { array[i] = ((parameters[i] == null) ? "?" : parameters[i].Name); } return string.Join(", ", array); } } } namespace VSM.Core.Config { internal sealed class ConfigurationManagerAttributes { public bool? ShowRangeAsPercent; public Action<ConfigEntryBase> CustomDrawer; public bool? Browsable; public string Category; public object DefaultValue; public bool? HideDefaultButton; public bool? HideSettingName; public string Description; public string DispName; public int? Order; public bool? ReadOnly; public bool? IsAdvanced; public bool? IsAdminOnly; public Func<object, string> ObjToStr; public Func<string, object> StrToObj; } } namespace VSM.Core.Camera { internal struct RigSettings { public float Speed; public float FastMultiplier; public bool MoveRelativeToView; } internal sealed class CameraRig { public const float MaxPitch = 89f; public float Yaw; public float Pitch; public Vector3 Position; public Vector3 Velocity; public Vector3 ForwardVector => Forward(Yaw, Pitch); public Quaternion Rotation => Quaternion.Euler(Pitch, Yaw, 0f); public static Vector3 Forward(float yawDeg, float pitchDeg) { //IL_002f: 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) //IL_0037: Unknown result type (might be due to invalid IL or missing references) float num = yawDeg * ((float)Math.PI / 180f); float num2 = pitchDeg * ((float)Math.PI / 180f); float num3 = Mathf.Cos(num2); return new Vector3(Mathf.Sin(num) * num3, 0f - Mathf.Sin(num2), Mathf.Cos(num) * num3); } public static Vector3 FlatForward(float yawDeg) { //IL_001a: 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_0022: Unknown result type (might be due to invalid IL or missing references) float num = yawDeg * ((float)Math.PI / 180f); return new Vector3(Mathf.Sin(num), 0f, Mathf.Cos(num)); } public static Vector3 Right(float yawDeg) { //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_0023: Unknown result type (might be due to invalid IL or missing references) float num = yawDeg * ((float)Math.PI / 180f); return new Vector3(Mathf.Cos(num), 0f, 0f - Mathf.Sin(num)); } public void Reset(Vector3 position, Vector3 forward) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) Position = position; Velocity = Vector3.zero; SetFromDirection(forward); } public void SetFromDirection(Vector3 forward) { //IL_0035: 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_005c: Unknown result type (might be due to invalid IL or missing references) if (((Vector3)(ref forward)).sqrMagnitude < 1E-08f) { Yaw = 0f; Pitch = 0f; } else { ((Vector3)(ref forward)).Normalize(); Yaw = Mathf.Repeat(Mathf.Atan2(forward.x, forward.z) * 57.29578f, 360f); Pitch = Mathf.Clamp((0f - Mathf.Asin(Mathf.Clamp(forward.y, -1f, 1f))) * 57.29578f, -89f, 89f); } } public void ApplyLook(Vector2 delta) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) Yaw = Mathf.Repeat(Yaw + delta.x, 360f); Pitch = Mathf.Clamp(Pitch - delta.y, -89f, 89f); } public Vector3 DesiredVelocity(Vector3 move, float vertical, bool fast, RigSettings settings) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //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_0083: 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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: 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_00df: 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) Vector3 val = (settings.MoveRelativeToView ? Forward(Yaw, Pitch) : FlatForward(Yaw)); Vector3 val2 = Right(Yaw) * Mathf.Clamp(move.x, -1f, 1f) + val * Mathf.Clamp(move.z, -1f, 1f) + Vector3.up * Mathf.Clamp(vertical, -1f, 1f); if (((Vector3)(ref val2)).sqrMagnitude > 1f) { ((Vector3)(ref val2)).Normalize(); } float num = Mathf.Max(0f, settings.Speed) * (fast ? Mathf.Max(1f, settings.FastMultiplier) : 1f); return val2 * num; } public void Integrate(Vector3 desiredVelocity, float dt, float smoothing) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0047: 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) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) if (!(dt <= 0f)) { float num = ((smoothing <= 0f) ? 1f : (1f - Mathf.Exp((0f - dt) / smoothing))); Velocity = Vector3.Lerp(Velocity, desiredVelocity, num); Position += Velocity * dt; } } public static Vector3 ClampToSphere(Vector3 pos, Vector3 center, float radius) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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) Vector3 val = pos - center; float num = Mathf.Max(0f, radius); if (((Vector3)(ref val)).sqrMagnitude <= num * num) { return pos; } return center + ((Vector3)(ref val)).normalized * num; } } internal static class CameraWorld { public const float CollisionRadius = 0.25f; public static Vector3 Anchor(Player player) { //IL_0033: 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_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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) Transform eye = ((Character)player).m_eye; return ((Object)(object)eye != (Object)null) ? eye.position : (((Component)player).transform.position + Vector3.up * 1.6f); } public static Vector3 Constrain(Vector3 from, Vector3 to, Vector3 anchor, float maxDistance, float clearance, GameCamera cam) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0038: 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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) Vector3 pos = CameraRig.ClampToSphere(to, anchor, maxDistance); pos = Lift(pos, clearance, cam); pos = CameraRig.ClampToSphere(pos, anchor, maxDistance + 1f); LayerMask blockCameraMask = cam.m_blockCameraMask; Vector3 val = (Overlaps(from, blockCameraMask) ? anchor : from); return Collide(val, pos, blockCameraMask); } public static Vector3 Lift(Vector3 pos, float clearance, GameCamera cam) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) clearance = Mathf.Max(0f, clearance); ZoneSystem instance = ZoneSystem.instance; float num = default(float); if ((Object)(object)instance != (Object)null && instance.GetGroundHeight(pos, ref num)) { pos.y = Mathf.Max(pos.y, num + clearance); } float num2 = Floating.GetLiquidLevel(pos, 1f, (LiquidType)10); if ((Object)(object)instance != (Object)null && !Character.InInterior(pos)) { num2 = Mathf.Max(num2, instance.m_waterLevel); } if (num2 > -9000f) { pos.y = Mathf.Max(pos.y, num2 + Mathf.Max(clearance, cam.m_minWaterDistance)); } return pos; } public static bool Overlaps(Vector3 pos, LayerMask mask) { //IL_0001: 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) return Physics.CheckSphere(pos, 0.225f, LayerMask.op_Implicit(mask), (QueryTriggerInteraction)1); } public static Vector3 Collide(Vector3 from, Vector3 to, LayerMask mask) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0033: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) Vector3 val = to - from; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude < 1E-05f) { return to; } Vector3 val2 = val / magnitude; RaycastHit val3 = default(RaycastHit); if (Physics.SphereCast(from, 0.25f, val2, ref val3, magnitude, LayerMask.op_Implicit(mask), (QueryTriggerInteraction)1)) { return from + val2 * Mathf.Max(0f, ((RaycastHit)(ref val3)).distance - 0.02f); } return to; } } internal static class CameraLock { private const string Prefix = "vsm_camera_lock:"; public static string Holder() { GameCamera instance = GameCamera.instance; if ((Object)(object)instance == (Object)null) { return null; } Transform transform = ((Component)instance).transform; for (int i = 0; i < transform.childCount; i++) { string name = ((Object)transform.GetChild(i)).name; if (name.StartsWith("vsm_camera_lock:", StringComparison.Ordinal)) { return name.Substring("vsm_camera_lock:".Length); } } return null; } public static bool TryAcquire(string owner) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown GameCamera instance = GameCamera.instance; if ((Object)(object)instance == (Object)null) { return false; } string text = Holder(); if (text != null) { return text == owner; } GameObject val = new GameObject("vsm_camera_lock:" + owner); val.transform.SetParent(((Component)instance).transform, false); return true; } public static void Release(string owner) { GameCamera instance = GameCamera.instance; if ((Object)(object)instance == (Object)null) { return; } Transform transform = ((Component)instance).transform; for (int num = transform.childCount - 1; num >= 0; num--) { Transform child = transform.GetChild(num); if (((Object)child).name == "vsm_camera_lock:" + owner) { Object.Destroy((Object)(object)((Component)child).gameObject); ((Object)child).name = "vsm_camera_lock_released"; } } } } internal sealed class BodyHider { private readonly List<Renderer> _hidden = new List<Renderer>(); private float _nextScan; public void Update(Player player, bool hide) { if (!hide || (Object)(object)player == (Object)null) { Restore(); } else { if (Time.unscaledTime < _nextScan) { return; } _nextScan = Time.unscaledTime + 0.5f; Renderer[] componentsInChildren = ((Component)player).GetComponentsInChildren<Renderer>(false); foreach (Renderer val in componentsInChildren) { if ((Object)(object)val != (Object)null && val.enabled && (val is SkinnedMeshRenderer || val is MeshRenderer)) { val.enabled = false; _hidden.Add(val); } } } } public void Restore() { foreach (Renderer item in _hidden) { if ((Object)(object)item != (Object)null) { item.enabled = true; } } _hidden.Clear(); _nextScan = 0f; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }
plugins/VSM.Drops/VSM.Drops.dll
Decompiled 3 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ConditionalConfigSync; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.UI; using VSM.Core.Config; using VSM.Core.Harmony; using VSM.Core.Reflection; using VSM.Core.Runtime; using VSM.Drops.Categories; using VSM.Drops.Scaling; using VSM.Drops.Stats; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: <e4741b38-e643-416f-af8a-811427b5b3c8>IgnoresAccessChecksTo("assembly_guiutils")] [assembly: <e4741b38-e643-416f-af8a-811427b5b3c8>IgnoresAccessChecksTo("assembly_utils")] [assembly: <e4741b38-e643-416f-af8a-811427b5b3c8>IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("VSM.Drops")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("0.1.4.0")] [assembly: AssemblyInformationalVersion("0.1.4+ff27bc889ccf218c61c45d3417d48ab708a5ba8f")] [assembly: AssemblyProduct("VSM.Drops")] [assembly: AssemblyTitle("VSM.Drops")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.4.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace VSM.Drops { internal static class DropsPatches { [HarmonyPatch(typeof(DropTable), "GetDropList", new Type[] { typeof(int) })] private static class GetDropListPatch { [HarmonyPostfix] private static void Postfix(DropTable __instance, List<GameObject> __result) { try { DropScaler.ScaleDropList(__instance, __result); } catch (Exception ex) { DropsPlugin.Log.LogError((object)("vsm.drops: GetDropList: " + ex)); } } } [HarmonyPatch(typeof(DropTable), "AddItemToList", new Type[] { typeof(List<ItemData>), typeof(DropData) })] private static class AddItemToListPatch { [HarmonyPostfix] private static void Postfix(List<ItemData> toDrop, DropData data) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) try { DropScaler.ScaleAddedStack(toDrop, data); } catch (Exception ex) { DropsPlugin.Log.LogError((object)("vsm.drops: AddItemToList: " + ex)); } } } [HarmonyPatch(typeof(CharacterDrop), "GenerateDropList")] private static class GenerateDropListPatch { [HarmonyPrefix] private static void Prefix() { DropScope.Enter(DropSource.CharacterDrop, Neutralize); } [HarmonyPostfix] private static void Postfix(CharacterDrop __instance, List<KeyValuePair<GameObject, int>> __result) { try { DropScaler.ScaleCharacterDrops(__instance, __result); } catch (Exception ex) { DropsPlugin.Log.LogError((object)("vsm.drops: GenerateDropList: " + ex)); } } [HarmonyFinalizer] private static Exception Finalizer(Exception __exception) { DropScope.Exit(); return __exception; } } [HarmonyPatch(typeof(Pickable), "RPC_Pick", new Type[] { typeof(long), typeof(int) })] private static class RpcPickPatch { [HarmonyPrefix] private static void Prefix(Pickable __instance, out int __state) { __state = int.MinValue; DropScope.Enter(DropSource.Pickable, Neutralize); try { int num = DropScaler.ScaledPickableAmount(__instance); if (num >= 0 && num != __instance.m_amount) { __state = __instance.m_amount; __instance.m_amount = num; } } catch (Exception ex) { DropsPlugin.Log.LogError((object)("vsm.drops: RPC_Pick: " + ex)); } } [HarmonyFinalizer] private static Exception Finalizer(Pickable __instance, int __state, Exception __exception) { if (__state != int.MinValue && (Object)(object)__instance != (Object)null) { __instance.m_amount = __state; } DropScope.Exit(); return __exception; } } [HarmonyPatch(typeof(Game), "ScaleDrops", new Type[] { typeof(ItemData), typeof(int) })] private static class ScaleDropsProducerPatch { [HarmonyPostfix] private static void Postfix(ItemData data, int amount, ref int __result) { try { __result = DropScaler.ScaleProducer(data, __result); } catch (Exception ex) { DropsPlugin.Log.LogError((object)("vsm.drops: ScaleDrops: " + ex)); } } } [HarmonyPatch(typeof(MineRock), "RPC_Hit", new Type[] { typeof(long), typeof(HitData), typeof(int) })] private static class MineRockScope { [HarmonyPrefix] private static void Prefix() { DropScope.Enter(DropSource.MineRock, Neutralize); } [HarmonyFinalizer] private static Exception Finalizer(Exception __exception) { DropScope.Exit(); return __exception; } } [HarmonyPatch(typeof(MineRock5), "DamageArea", new Type[] { typeof(int), typeof(HitData) })] private static class MineRock5Scope { [HarmonyPrefix] private static void Prefix() { DropScope.Enter(DropSource.MineRock5, Neutralize); } [HarmonyFinalizer] private static Exception Finalizer(Exception __exception) { DropScope.Exit(); return __exception; } } [HarmonyPatch(typeof(TreeBase), "RPC_Damage", new Type[] { typeof(long), typeof(HitData) })] private static class TreeBaseScope { [HarmonyPrefix] private static void Prefix() { DropScope.Enter(DropSource.TreeBase, Neutralize); } [HarmonyFinalizer] private static Exception Finalizer(Exception __exception) { DropScope.Exit(); return __exception; } } [HarmonyPatch(typeof(TreeLog), "Destroy", new Type[] { typeof(HitData), typeof(bool) })] private static class TreeLogScope { [HarmonyPrefix] private static void Prefix() { DropScope.Enter(DropSource.TreeLog, Neutralize); } [HarmonyFinalizer] private static Exception Finalizer(Exception __exception) { DropScope.Exit(); return __exception; } } [HarmonyPatch(typeof(DropOnDestroyed), "OnDestroyed")] private static class DropOnDestroyedScope { [HarmonyPrefix] private static void Prefix() { DropScope.Enter(DropSource.DropOnDestroyed, Neutralize); } [HarmonyFinalizer] private static Exception Finalizer(Exception __exception) { DropScope.Exit(); return __exception; } } [HarmonyPatch(typeof(LootSpawner), "UpdateSpawner")] private static class LootSpawnerScope { [HarmonyPrefix] private static void Prefix() { DropScope.Enter(DropSource.LootSpawner, Neutralize); } [HarmonyFinalizer] private static Exception Finalizer(Exception __exception) { DropScope.Exit(); return __exception; } } [HarmonyPatch(typeof(Container), "AddDefaultItems")] private static class ContainerScope { [HarmonyPrefix] private static void Prefix() { DropScope.Enter(DropSource.Container, Neutralize); } [HarmonyFinalizer] private static Exception Finalizer(Exception __exception) { DropScope.Exit(); return __exception; } } [HarmonyPatch(typeof(FishingFloat), "Catch", new Type[] { typeof(Fish), typeof(Character) })] private static class FishingScope { [HarmonyPrefix] private static void Prefix() { DropScope.Enter(DropSource.Fishing, Neutralize); } [HarmonyFinalizer] private static Exception Finalizer(Exception __exception) { DropScope.Exit(); return __exception; } } [HarmonyPatch(typeof(Beehive), "RPC_Extract", new Type[] { typeof(long) })] private static class BeehiveScope { [HarmonyPrefix] private static void Prefix() { DropScope.Enter(DropSource.Beehive, Neutralize); } [HarmonyFinalizer] private static Exception Finalizer(Exception __exception) { DropScope.Exit(); return __exception; } } [HarmonyPatch(typeof(SapCollector), "RPC_Extract", new Type[] { typeof(long) })] private static class SapScope { [HarmonyPrefix] private static void Prefix() { DropScope.Enter(DropSource.Sap, Neutralize); } [HarmonyFinalizer] private static Exception Finalizer(Exception __exception) { DropScope.Exit(); return __exception; } } [HarmonyPatch(typeof(ObjectDB), "Awake")] private static class ObjectDbAwakePatch { [HarmonyPostfix] private static void Postfix() { DropsPlugin.OnObjectDbReady(); } } [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB", new Type[] { typeof(ObjectDB) })] private static class ObjectDbCopyPatch { [HarmonyPostfix] private static void Postfix() { DropsPlugin.OnObjectDbReady(); } } [HarmonyPatch(typeof(ZNetScene), "Awake")] private static class ZNetSceneAwakePatch { [HarmonyPostfix] private static void Postfix() { DropsPlugin.OnWorldEnter(); } } [HarmonyPatch(typeof(Terminal), "InitTerminal")] private static class InitTerminalPatch { private static bool s_registered; [HarmonyPostfix] private static void Postfix() { if (!s_registered) { s_registered = true; DropsPlugin.RegisterCommands(); } } } private static bool Neutralize => DropsPlugin.IgnoreWorldResourceRate.Value; } [BepInPlugin("vsm.drops", "MEL Drops", "0.1.4")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class DropsPlugin : BaseUnityPlugin { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static EventHandler <>9__31_0; public static Converter<ItemType, string> <>9__36_0; public static ConsoleEvent <>9__40_0; public static ConsoleEvent <>9__40_1; public static ConsoleEvent <>9__40_2; public static ConsoleEvent <>9__40_3; internal void <Awake>b__31_0(object s, EventArgs e) { ItemClassifier.InvalidateCache(); } internal unsafe string <OnObjectDbReady>b__36_0(ItemType t) { return ((object)(*(ItemType*)(&t))/*cast due to .constrained prefix*/).ToString(); } internal void <RegisterCommands>b__40_0(ConsoleEventArgs args) { if (args.Length < 2) { args.Context.AddString("Uso: vsm_drops_class <nombre de prefab>"); return; } string text = args[1]; DropCategory category = ItemClassifier.Classify(text, null); string text2 = (ItemClassifier.Overrides.ContainsKey(text) ? "override del servidor" : (CategoryRules.Defaults.ContainsKey(text) ? "tabla por defecto" : "regla")); args.Context.AddString(text + " → " + DropCategoryNames.Display(category) + " (" + text2 + ", x" + Multiplier(category).ToString("0.00") + ")"); } internal void <RegisterCommands>b__40_1(ConsoleEventArgs args) { args.Context.AddString("vsm.drops 0.1.4 | activo=" + (Enabled.Value && IsConfigReady) + " | config lista=" + IsConfigReady + " | Recursos mundo=" + Game.m_resourceRate + (PatchUtil.IsDegraded ? (" | DEGRADADO: " + string.Join(" | ", new List<string>(PatchUtil.FailedTargets).ToArray())) : string.Empty)); args.Context.AddString("Multiplicadores: Madera x" + Madera.Value + " Ores x" + Ores.Value + " Piedras x" + Piedras.Value + " Mobs x" + DropsDeMobs.Value + " Cosecha x" + Cosecha.Value + " Otros x" + Otros.Value); bool flag = false; foreach (string item in SessionStats.Lines()) { flag = true; args.Context.AddString(item); } if (!flag) { args.Context.AddString("(sin eventos de drop escalados todavía)"); } } internal void <RegisterCommands>b__40_2(ConsoleEventArgs args) { if (!((ConditionalConfigSync)s_sync).IsSourceOfTruth) { args.Context.AddString("Solo el servidor/anfitrión puede recargar las excepciones."); return; } LoadOverridesFromDisk(); args.Context.AddString("vsm.drops: excepciones recargadas (" + ItemClassifier.Overrides.Count + ")"); } internal void <RegisterCommands>b__40_3(ConsoleEventArgs args) { if ((Object)(object)ObjectDB.instance == (Object)null) { args.Context.AddString("ObjectDB no disponible."); return; } string text = Path.Combine(Paths.ConfigPath, "vsm.drops.categories.generated.txt"); ItemClassifier.WriteGeneratedFile(text, ObjectDB.instance); args.Context.AddString("vsm.drops: escrito " + text); } } public const string CcsGuid = "_shudnal.ConditionalConfigSync"; public const string OverrideFileName = "vsm.drops.categories.txt"; public const string GeneratedFileName = "vsm.drops.categories.generated.txt"; internal static ManualLogSource Log; private static ConfigSync s_sync; private static CustomSyncedValue<string> s_overridesBlob; private static string s_lastAppliedOverrides; private Harmony _harmony; public static ConfigEntry<bool> Enabled; public static ConfigEntry<bool> ServerLock; public static ConfigEntry<bool> IgnoreWorldResourceRate; public static ConfigEntry<bool> IgnoreDontScale; public static ConfigEntry<bool> IgnoreNonScaledDropTypes; public static ConfigEntry<int> MaxUnitsPerEvent; public static ConfigEntry<float> Madera; public static ConfigEntry<float> Ores; public static ConfigEntry<float> Piedras; public static ConfigEntry<float> DropsDeMobs; public static ConfigEntry<float> Cosecha; public static ConfigEntry<float> Otros; public static ConfigEntry<bool> MultiplyChestLoot; public static ConfigEntry<bool> MultiplyLootSpawners; public static ConfigEntry<bool> MultiplyFishing; public static ConfigEntry<bool> MultiplyBeehiveAndSap; public static ConfigEntry<bool> MultiplyUnknownCallers; public static ConfigEntry<bool> WriteGeneratedCategoryFile; public static ConfigEntry<bool> LogUnclassifiedItems; public static ConfigEntry<bool> DebugLogging; public static bool IsConfigReady => s_sync != null && (((ConditionalConfigSync)s_sync).IsSourceOfTruth || ((ConditionalConfigSync)s_sync).InitialSyncDone); public static float Multiplier(DropCategory category) { return category switch { DropCategory.Madera => Madera.Value, DropCategory.Ores => Ores.Value, DropCategory.Piedras => Piedras.Value, DropCategory.DropsDeMobs => DropsDeMobs.Value, DropCategory.Cosecha => Cosecha.Value, DropCategory.Otros => Otros.Value, _ => 1f, }; } private void Awake() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0044: Expected O, but got Unknown //IL_03df: Unknown result type (might be due to invalid IL or missing references) //IL_03e9: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; s_sync = new ConfigSync("vsm.drops") { DisplayName = "MEL Drops", CurrentVersion = "0.1.4", MinimumRequiredVersion = "0.1.4", ModRequired = true }; Enabled = Synced<bool>(Bind("1. General", "Enabled", value: true, "Activa o desactiva todos los multiplicadores de drops. Con false el juego se comporta como vanilla.", 100)); ServerLock = Bind("1. General", "ServerLock", value: true, "Bloquea la configuración: solo los administradores del servidor pueden cambiarla desde el cliente.", 99); ((ConditionalConfigSync)s_sync).AddLockingConfigEntry<bool>(ServerLock); IgnoreWorldResourceRate = Synced<bool>(Bind("1. General", "IgnoreWorldResourceRate", value: true, "Neutraliza el modificador de mundo 'Recursos' dentro de cada evento de drop para que NO se multiplique dos veces. Recomendado: mundo en Recursos=Normal y controlar todo desde aquí.", 98)); IgnoreDontScale = Synced<bool>(Bind("1. General", "IgnoreDontScale", value: false, "Si es true, multiplica también los ítems que el juego marca como 'no escalables' (drops de jefes, llaves...). Los trofeos NUNCA se multiplican.", 97)); IgnoreNonScaledDropTypes = Synced<bool>(Bind("1. General", "IgnoreNonScaledDropTypes", value: false, "Si es true, ignora la lista vanilla de tipos de ítem no escalables (normalmente Trofeo y Pez). Los trofeos siguen excluidos siempre.", 96)); IgnoreNonScaledDropTypes.SettingChanged += delegate { ItemClassifier.InvalidateCache(); }; MaxUnitsPerEvent = Synced<int>(Bind("1. General", "MaxUnitsPerEvent", 40, "Tope de unidades de un mismo ítem por evento de drop (por árbol, por sección de veta, por criatura, por planta). Protege el rendimiento. 0 = sin tope.", 95, (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 200))); Madera = Synced<float>(Bind("2. Multiplicadores", "Madera", 2f, "Multiplicador para madera de todos los tipos (Wood, FineWood, RoundLog, ElderBark, YggdrasilWood, Blackwood, Frostwood...). 1.0 = vanilla.", 90, (AcceptableValueBase)(object)Range())); Ores = Synced<float>(Bind("2. Multiplicadores", "Ores", 1.5f, "Multiplicador para menas y chatarra metálica (CopperOre, TinOre, IronScrap, SilverOre, BlackMetalScrap, FlametalOre, GoldOre, Chitin...). Incluye BlackMetalScrap aunque lo suelten criaturas.", 89, (AcceptableValueBase)(object)Range())); Piedras = Synced<float>(Bind("2. Multiplicadores", "Piedras", 1f, "Multiplicador para piedras de todos los tipos (Stone, Flint, Obsidian, Grausten, BlackMarble, Ice, Crystal...).", 88, (AcceptableValueBase)(object)Range())); DropsDeMobs = Synced<float>(Bind("2. Multiplicadores", "DropsDeMobs", 1f, "Multiplicador para materiales que sueltan las criaturas y que no son mena, piedra ni madera (pieles, carne, huesos, glándulas, colmillos, plumas...). Los trofeos no se multiplican.", 87, (AcceptableValueBase)(object)Range())); Cosecha = Synced<float>(Bind("2. Multiplicadores", "Cosecha", 1f, "Multiplicador para bayas, hongos, cultivos, semillas, piñas, cardo y diente de león (y miel/savia si se activa esa fuente).", 86, (AcceptableValueBase)(object)Range())); Otros = Synced<float>(Bind("2. Multiplicadores", "Otros", 1f, "Multiplicador para todo ítem escalable que no cae en otra categoría (carbón, resina, alquitrán, núcleos, ámbar, monedas, gemas...).", 85, (AcceptableValueBase)(object)Range())); MultiplyChestLoot = Synced<bool>(Bind("3. Fuentes opcionales", "MultiplyChestLoot", value: false, "Multiplicar también el contenido inicial de cofres del mundo. Por defecto los cofres quedan vanilla.", 80)); MultiplyLootSpawners = Synced<bool>(Bind("3. Fuentes opcionales", "MultiplyLootSpawners", value: false, "Multiplicar también los montones de botín que reaparecen en mazmorras y campamentos.", 79)); MultiplyFishing = Synced<bool>(Bind("3. Fuentes opcionales", "MultiplyFishing", value: false, "Multiplicar los ítems extra de la tabla de pesca. Los peces en sí nunca se multiplican.", 78)); MultiplyBeehiveAndSap = Synced<bool>(Bind("3. Fuentes opcionales", "MultiplyBeehiveAndSap", value: false, "Multiplicar la miel de panales y la savia de extractores con el multiplicador de su categoría (Cosecha por defecto).", 77)); MultiplyUnknownCallers = Synced<bool>(Bind("3. Fuentes opcionales", "MultiplyUnknownCallers", value: true, "Aplicar multiplicadores cuando la tabla de drops la invoca código desconocido (p. ej. otro mod). Se clasifica por ítem igual que siempre.", 76)); WriteGeneratedCategoryFile = Bind("4. Categorías", "WriteGeneratedCategoryFile", value: true, "Escribir vsm.drops.categories.generated.txt con la clasificación completa detectada al cargar (informativo, no se lee).", 70); LogUnclassifiedItems = Bind("4. Categorías", "LogUnclassifiedItems", value: true, "Registrar en el log cada ítem que cae en 'Otros' solo por regla de respaldo, para revisarlo tras cada parche del juego.", 69); DebugLogging = Bind("5. Depuración", "DebugLogging", value: false, "Registrar cada evento de drop escalado (fuente, ítem, categoría, base → final). Solo para pruebas; genera mucho log.", 60); s_overridesBlob = new CustomSyncedValue<string>((ConditionalConfigSync)(object)s_sync, "vsm.drops.categories", string.Empty, 0, (IEqualityComparer<string>)null); ((CustomSyncedValueBase)s_overridesBlob).ValueChanged += OnOverridesChanged; ItemClassifier.Init(Log); Log.LogInfo((object)("vsm.drops 0.1.4 | Valheim " + GameConstants.GameVersionString + " | headless=" + Headless.IsHeadless)); _harmony = new Harmony("vsm.drops"); PatchUtil.PatchAllSafely(Log, _harmony, Assembly.GetExecutingAssembly()); if (Game.m_resourceRate != 1f) { Log.LogWarning((object)("vsm.drops: el modificador de mundo 'Recursos' no es Normal (" + Game.m_resourceRate + "). Con IgnoreWorldResourceRate=true se neutraliza dentro de cada evento de drop.")); } } private void OnDestroy() { if (_harmony != null) { _harmony.UnpatchSelf(); } } private ConfigEntry<T> Bind<T>(string section, string key, T value, string description, int order, AcceptableValueBase range = null) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown return ((BaseUnityPlugin)this).Config.Bind<T>(section, key, value, new ConfigDescription(description, range, new object[1] { new ConfigurationManagerAttributes { Order = order } })); } private static ConfigEntry<T> Synced<T>(ConfigEntry<T> entry) { ((ConditionalConfigSync)s_sync).AddConfigEntry<T>(entry, (ConfigSyncMode)0); return entry; } private static AcceptableValueRange<float> Range() { return new AcceptableValueRange<float>(0f, 10f); } internal unsafe static void OnObjectDbReady() { try { ObjectDB instance = ObjectDB.instance; if ((Object)(object)instance == (Object)null || instance.m_items == null || instance.m_items.Count == 0) { return; } ItemClassifier.Rebuild(instance); if (((ConditionalConfigSync)s_sync).IsSourceOfTruth) { LoadOverridesFromDisk(); } else if (!string.IsNullOrEmpty(s_lastAppliedOverrides)) { ItemClassifier.SetOverrides(CategoryFile.Parse(s_lastAppliedOverrides, null)); } if ((Object)(object)Game.instance != (Object)null && Game.instance.m_nonScaledDropTypes != null) { Log.LogInfo((object)("vsm.drops: tipos no escalables vanilla = " + string.Join(", ", Game.instance.m_nonScaledDropTypes.ConvertAll((ItemType t) => ((object)(*(ItemType*)(&t))/*cast due to .constrained prefix*/).ToString()).ToArray()))); } } catch (Exception ex) { Log.LogError((object)("vsm.drops: error preparando el clasificador: " + ex)); } } internal static void OnWorldEnter() { SessionStats.Reset(); try { ItemClassifier.BuildSourceHints(ZNetScene.instance); if (WriteGeneratedCategoryFile.Value && (Object)(object)ObjectDB.instance != (Object)null) { ItemClassifier.WriteGeneratedFile(Path.Combine(Paths.ConfigPath, "vsm.drops.categories.generated.txt"), ObjectDB.instance); } } catch (Exception ex) { Log.LogError((object)("vsm.drops: error construyendo pistas de origen: " + ex)); } if (Game.m_resourceRate != 1f) { Log.LogWarning((object)("vsm.drops: Recursos del mundo = " + Game.m_resourceRate + " (se neutraliza: " + IgnoreWorldResourceRate.Value + ")")); } } private static void LoadOverridesFromDisk() { string text = Path.Combine(Paths.ConfigPath, "vsm.drops.categories.txt"); try { if (!File.Exists(text)) { File.WriteAllText(text, CategoryFile.Template(), new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)); Log.LogInfo((object)("vsm.drops: creado " + text + " (plantilla comentada)")); } List<string> list = new List<string>(); Dictionary<string, DropCategory> dictionary = CategoryFile.Parse(File.ReadAllText(text, Encoding.UTF8), list); foreach (string item in list) { Log.LogWarning((object)("vsm.drops: vsm.drops.categories.txt: " + item)); } string text2 = CategoryFile.Normalize(dictionary); ItemClassifier.SetOverrides(dictionary); s_lastAppliedOverrides = text2; if (s_overridesBlob.Value != text2) { s_overridesBlob.Value = text2; } Log.LogInfo((object)("vsm.drops: " + dictionary.Count + " excepciones de categoría cargadas (sha " + CategoryFile.Sha256(text2).Substring(0, 12) + ")")); } catch (Exception ex) { Log.LogError((object)("vsm.drops: no se pudo leer " + text + ": " + ex.Message)); } } private static void OnOverridesChanged() { try { string text = s_overridesBlob.Value ?? string.Empty; if (!(text == s_lastAppliedOverrides)) { s_lastAppliedOverrides = text; Dictionary<string, DropCategory> dictionary = CategoryFile.Parse(text, null); ItemClassifier.SetOverrides(dictionary); Log.LogInfo((object)("vsm.drops: excepciones de categoría del servidor aplicadas (" + dictionary.Count + ")")); } } catch (Exception ex) { Log.LogError((object)("vsm.drops: error aplicando excepciones: " + ex.Message)); } } internal static void RegisterCommands() { //IL_0034: 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_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Expected O, but got Unknown object obj = <>c.<>9__40_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { if (args.Length < 2) { args.Context.AddString("Uso: vsm_drops_class <nombre de prefab>"); } else { string text = args[1]; DropCategory category = ItemClassifier.Classify(text, null); string text2 = (ItemClassifier.Overrides.ContainsKey(text) ? "override del servidor" : (CategoryRules.Defaults.ContainsKey(text) ? "tabla por defecto" : "regla")); args.Context.AddString(text + " → " + DropCategoryNames.Display(category) + " (" + text2 + ", x" + Multiplier(category).ToString("0.00") + ")"); } }; <>c.<>9__40_0 = val; obj = (object)val; } new ConsoleCommand("vsm_drops_class", "vsm_drops_class <prefab> — muestra la categoría de un ítem", (ConsoleEvent)obj, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj2 = <>c.<>9__40_1; if (obj2 == null) { ConsoleEvent val2 = delegate(ConsoleEventArgs args) { args.Context.AddString("vsm.drops 0.1.4 | activo=" + (Enabled.Value && IsConfigReady) + " | config lista=" + IsConfigReady + " | Recursos mundo=" + Game.m_resourceRate + (PatchUtil.IsDegraded ? (" | DEGRADADO: " + string.Join(" | ", new List<string>(PatchUtil.FailedTargets).ToArray())) : string.Empty)); args.Context.AddString("Multiplicadores: Madera x" + Madera.Value + " Ores x" + Ores.Value + " Piedras x" + Piedras.Value + " Mobs x" + DropsDeMobs.Value + " Cosecha x" + Cosecha.Value + " Otros x" + Otros.Value); bool flag = false; foreach (string item in SessionStats.Lines()) { flag = true; args.Context.AddString(item); } if (!flag) { args.Context.AddString("(sin eventos de drop escalados todavía)"); } }; <>c.<>9__40_1 = val2; obj2 = (object)val2; } new ConsoleCommand("vsm_drops_stats", "Estadísticas de drops escalados en esta sesión", (ConsoleEvent)obj2, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj3 = <>c.<>9__40_2; if (obj3 == null) { ConsoleEvent val3 = delegate(ConsoleEventArgs args) { if (!((ConditionalConfigSync)s_sync).IsSourceOfTruth) { args.Context.AddString("Solo el servidor/anfitrión puede recargar las excepciones."); } else { LoadOverridesFromDisk(); args.Context.AddString("vsm.drops: excepciones recargadas (" + ItemClassifier.Overrides.Count + ")"); } }; <>c.<>9__40_2 = val3; obj3 = (object)val3; } new ConsoleCommand("vsm_drops_reload", "Recarga vsm.drops.categories.txt y lo reenvía a los clientes (solo servidor/admin)", (ConsoleEvent)obj3, false, false, true, false, false, false, (ConsoleOptionsFetcher)null, false, false, true); object obj4 = <>c.<>9__40_3; if (obj4 == null) { ConsoleEvent val4 = delegate(ConsoleEventArgs args) { if ((Object)(object)ObjectDB.instance == (Object)null) { args.Context.AddString("ObjectDB no disponible."); } else { string text = Path.Combine(Paths.ConfigPath, "vsm.drops.categories.generated.txt"); ItemClassifier.WriteGeneratedFile(text, ObjectDB.instance); args.Context.AddString("vsm.drops: escrito " + text); } }; <>c.<>9__40_3 = val4; obj4 = (object)val4; } new ConsoleCommand("vsm_drops_dump", "Vuelve a escribir vsm.drops.categories.generated.txt", (ConsoleEvent)obj4, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "vsm.drops"; public const string PLUGIN_NAME = "MEL Drops"; public const string PLUGIN_VERSION = "0.1.4"; } } namespace VSM.Drops.Stats { public static class SessionStats { private static readonly int s_count = Enum.GetValues(typeof(DropCategory)).Length; private static readonly long[] s_events = new long[s_count]; private static readonly long[] s_base = new long[s_count]; private static readonly long[] s_scaled = new long[s_count]; public static void Record(DropCategory category, int baseUnits, int scaledUnits) { if (category >= DropCategory.Otros && (int)category < s_count) { s_events[(int)category]++; s_base[(int)category] += baseUnits; s_scaled[(int)category] += scaledUnits; } } public static void Reset() { Array.Clear(s_events, 0, s_count); Array.Clear(s_base, 0, s_count); Array.Clear(s_scaled, 0, s_count); } public static IEnumerable<string> Lines() { for (int i = 0; i < s_count; i++) { if (s_events[i] != 0) { double ratio = ((s_base[i] > 0) ? ((double)s_scaled[i] / (double)s_base[i]) : 0.0); yield return DropCategoryNames.Display((DropCategory)i) + ": " + s_events[i] + " eventos, " + s_base[i] + " → " + s_scaled[i] + " unidades (x" + ratio.ToString("0.00") + ")"; } } } } } namespace VSM.Drops.Scaling { public static class DropMath { private static readonly Random s_rng = new Random(Environment.TickCount ^ (int)DateTime.UtcNow.Ticks); public static int ScaleUnits(int n, float m) { return ScaleUnits(n, m, s_rng.NextDouble()); } public static int ScaleUnits(int n, float m, double roll) { if (n <= 0 || m == 1f || float.IsNaN(m) || float.IsInfinity(m)) { return n; } if (m < 0f) { m = 0f; } double num = (double)n * (double)m; int num2 = (int)Math.Floor(num); double num3 = num - (double)num2; if (roll < num3) { num2++; } if (m >= 1f && num2 < n) { num2 = n; } return Math.Max(0, num2); } public static int Cap(int scaled, int vanilla, int maxUnitsPerEvent) { if (maxUnitsPerEvent <= 0) { return scaled; } if (scaled <= maxUnitsPerEvent) { return scaled; } return Math.Max(vanilla, maxUnitsPerEvent); } } public static class DropScaler { private static bool Neutralize => DropsPlugin.IgnoreWorldResourceRate.Value; public static bool IsActive() { return DropsPlugin.Enabled.Value && DropsPlugin.IsConfigReady; } public static void ScaleDropList(DropTable table, List<GameObject> list) { if (!IsActive() || table == null || list == null || list.Count == 0) { return; } DropSource source = DropScope.Source; if ((source == DropSource.LootSpawner && !DropsPlugin.MultiplyLootSpawners.Value) || (source == DropSource.None && !DropsPlugin.MultiplyUnknownCallers.Value)) { return; } float num = DropScope.UnknownCallerRateFix(Neutralize); List<GameObject> list2 = new List<GameObject>(4); List<int> list3 = new List<int>(4); foreach (GameObject item in list) { int num2 = IndexOf(list2, item); if (num2 < 0) { list2.Add(item); list3.Add(1); } else { list3[num2]++; } } for (int i = 0; i < list2.Count; i++) { GameObject val = list2[i]; int num3 = list3[i]; if ((Object)(object)val == (Object)null || !ItemClassifier.HasItemDrop(val) || (!DropsPlugin.IgnoreDontScale.Value && IsDontScale(table, val))) { continue; } DropCategory dropCategory = ItemClassifier.Classify(val); if (dropCategory == DropCategory.Excluido) { continue; } float m = DropsPlugin.Multiplier(dropCategory) * num; int num4 = DropMath.Cap(DropMath.ScaleUnits(num3, m), num3, DropsPlugin.MaxUnitsPerEvent.Value); if (num4 > num3) { for (int j = num3; j < num4; j++) { list.Add(val); } } else if (num4 < num3) { RemoveFromEnd(list, val, num3 - num4); } SessionStats.Record(dropCategory, num3, num4); Debug(source, ((Object)val).name, dropCategory, num3, num4); } } private static int IndexOf(List<GameObject> list, GameObject go) { for (int i = 0; i < list.Count; i++) { if (list[i] == go) { return i; } } return -1; } private static void RemoveFromEnd(List<GameObject> list, GameObject prefab, int count) { int num = list.Count - 1; while (num >= 0 && count > 0) { if (list[num] == prefab) { list.RemoveAt(num); count--; } num--; } } private static bool IsDontScale(DropTable table, GameObject prefab) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (table.m_drops == null) { return false; } foreach (DropData drop in table.m_drops) { if (drop.m_item == prefab && drop.m_dontScale) { return true; } } return false; } public static void ScaleCharacterDrops(CharacterDrop characterDrop, List<KeyValuePair<GameObject, int>> result) { if (!IsActive() || (Object)(object)characterDrop == (Object)null || result == null) { return; } for (int i = 0; i < result.Count; i++) { KeyValuePair<GameObject, int> keyValuePair = result[i]; GameObject key = keyValuePair.Key; if ((Object)(object)key == (Object)null || keyValuePair.Value <= 0 || !ItemClassifier.HasItemDrop(key) || IsCharacterDropExcluded(characterDrop, key)) { continue; } DropCategory dropCategory = ItemClassifier.Classify(key); if (dropCategory != DropCategory.Excluido) { float m = DropsPlugin.Multiplier(dropCategory); int num = DropMath.Cap(DropMath.ScaleUnits(keyValuePair.Value, m), keyValuePair.Value, DropsPlugin.MaxUnitsPerEvent.Value); if (num != keyValuePair.Value) { result[i] = new KeyValuePair<GameObject, int>(key, num); } SessionStats.Record(dropCategory, keyValuePair.Value, num); Debug(DropSource.CharacterDrop, ((Object)key).name, dropCategory, keyValuePair.Value, num); } } } private static bool IsCharacterDropExcluded(CharacterDrop characterDrop, GameObject prefab) { if (characterDrop.m_drops == null) { return false; } foreach (Drop drop in characterDrop.m_drops) { if (drop.m_prefab == prefab) { if (drop.m_onePerPlayer) { return true; } if (drop.m_dontScale && !DropsPlugin.IgnoreDontScale.Value) { return true; } } } return false; } public static int ScaledPickableAmount(Pickable pickable) { if (!IsActive() || (Object)(object)pickable == (Object)null || (Object)(object)pickable.m_itemPrefab == (Object)null) { return -1; } if (pickable.m_dontScale && !DropsPlugin.IgnoreDontScale.Value) { return -1; } DropCategory dropCategory = ItemClassifier.Classify(pickable.m_itemPrefab); if (dropCategory == DropCategory.Excluido) { return -1; } int amount = pickable.m_amount; int num = DropMath.Cap(DropMath.ScaleUnits(amount, DropsPlugin.Multiplier(dropCategory)), amount, DropsPlugin.MaxUnitsPerEvent.Value); SessionStats.Record(dropCategory, amount, num); Debug(DropSource.Pickable, ((Object)pickable.m_itemPrefab).name, dropCategory, amount, num); return num; } public static void ScaleAddedStack(List<ItemData> toDrop, DropData data) { //IL_0013: 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_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) if (!IsActive() || toDrop == null || toDrop.Count == 0 || (Object)(object)data.m_item == (Object)null) { return; } DropSource source = DropScope.Source; if ((source != DropSource.Pickable && (source != DropSource.Container || !DropsPlugin.MultiplyChestLoot.Value) && (source != DropSource.Fishing || !DropsPlugin.MultiplyFishing.Value)) || (data.m_dontScale && !DropsPlugin.IgnoreDontScale.Value)) { return; } ItemData val = toDrop[toDrop.Count - 1]; if (val == null || val.m_dropPrefab != data.m_item) { return; } DropCategory dropCategory = ItemClassifier.Classify(data.m_item); if (dropCategory == DropCategory.Excluido) { return; } int stack = val.m_stack; int num = DropMath.Cap(DropMath.ScaleUnits(stack, DropsPlugin.Multiplier(dropCategory)), stack, DropsPlugin.MaxUnitsPerEvent.Value); SessionStats.Record(dropCategory, stack, num); Debug(source, ((Object)data.m_item).name, dropCategory, stack, num); if (num == stack) { return; } if (num <= 0) { toDrop.RemoveAt(toDrop.Count - 1); return; } int val2 = Math.Max(1, val.m_shared.m_maxStackSize); val.m_stack = Math.Min(num, val2); int num2 = num - val.m_stack; while (num2 > 0) { ItemData val3 = val.Clone(); val3.m_stack = Math.Min(num2, val2); toDrop.Add(val3); num2 -= val3.m_stack; } } public static int ScaleProducer(ItemData item, int amount) { if (!IsActive() || item == null || !DropsPlugin.MultiplyBeehiveAndSap.Value) { return amount; } DropSource source = DropScope.Source; if (source != DropSource.Beehive && source != DropSource.Sap) { return amount; } string text = (((Object)(object)item.m_dropPrefab != (Object)null) ? ((Object)item.m_dropPrefab).name : ItemClassifier.PrefabNameFromToken((item.m_shared != null) ? item.m_shared.m_name : null)); if (string.IsNullOrEmpty(text)) { return amount; } DropCategory dropCategory = ItemClassifier.Classify(text, item.m_dropPrefab); if (dropCategory == DropCategory.Excluido) { return amount; } int num = DropMath.Cap(DropMath.ScaleUnits(amount, DropsPlugin.Multiplier(dropCategory)), amount, DropsPlugin.MaxUnitsPerEvent.Value); SessionStats.Record(dropCategory, amount, num); Debug(source, text, dropCategory, amount, num); return num; } private static void Debug(DropSource src, string prefab, DropCategory category, int n, int target) { if (DropsPlugin.DebugLogging.Value && n != target) { DropsPlugin.Log.LogInfo((object)("[vsm.drops] " + src.ToString() + " " + prefab + " (" + DropCategoryNames.Display(category) + ") " + n + " → " + target)); } } } public enum DropSource { None, MineRock, MineRock5, TreeBase, TreeLog, DropOnDestroyed, LootSpawner, Pickable, Container, Fishing, Beehive, Sap, CharacterDrop } public static class DropScope { [ThreadStatic] private static int t_depth; [ThreadStatic] private static DropSource t_source; [ThreadStatic] private static float t_savedRate; [ThreadStatic] private static bool t_rateOverridden; public static int Depth => t_depth; public static DropSource Source => (t_depth > 0) ? t_source : DropSource.None; public static void Enter(DropSource source, bool neutralizeWorldRate) { if (t_depth++ == 0) { t_source = source; if (neutralizeWorldRate && Game.m_resourceRate != 1f) { t_savedRate = Game.m_resourceRate; Game.m_resourceRate = 1f; t_rateOverridden = true; } } } public static void Exit() { if (t_depth <= 0) { t_depth = 0; } else { if (--t_depth != 0) { return; } if (t_rateOverridden) { if (Game.m_resourceRate == 1f) { Game.m_resourceRate = t_savedRate; } t_rateOverridden = false; } t_source = DropSource.None; } } public static float UnknownCallerRateFix(bool neutralizeWorldRate) { if (!neutralizeWorldRate || t_depth > 0) { return 1f; } float resourceRate = Game.m_resourceRate; return (resourceRate > 0f && resourceRate != 1f) ? (1f / resourceRate) : 1f; } } } namespace VSM.Drops.Categories { public static class CategoryFile { public static Dictionary<string, DropCategory> Parse(string text, List<string> errors) { Dictionary<string, DropCategory> dictionary = new Dictionary<string, DropCategory>(StringComparer.OrdinalIgnoreCase); if (string.IsNullOrEmpty(text)) { return dictionary; } string[] array = text.Replace("\r\n", "\n").Split(new char[1] { '\n' }); for (int i = 0; i < array.Length; i++) { string text2 = array[i]; int num = text2.IndexOf('#'); if (num >= 0) { text2 = text2.Substring(0, num); } text2 = text2.Trim(); if (text2.Length == 0) { continue; } int num2 = text2.IndexOf('='); if (num2 <= 0) { errors?.Add("línea " + (i + 1) + ": falta '=' → " + text2); continue; } string key = text2.Substring(0, num2).Trim(); string text3 = text2.Substring(num2 + 1).Trim(); if (!DropCategoryNames.TryParse(text3, out var category)) { errors?.Add("línea " + (i + 1) + ": categoría desconocida '" + text3 + "' (Madera, Ores, Piedras, DropsDeMobs, Cosecha, Otros, Excluido)"); } else { dictionary[key] = category; } } return dictionary; } public static string Normalize(Dictionary<string, DropCategory> map) { if (map == null || map.Count == 0) { return string.Empty; } return string.Join("\n", (from p in map.OrderBy<KeyValuePair<string, DropCategory>, string>((KeyValuePair<string, DropCategory> p) => p.Key, StringComparer.OrdinalIgnoreCase) select p.Key.ToLowerInvariant() + "=" + DropCategoryNames.Display(p.Value)).ToArray()); } public static string Sha256(string text) { using SHA256 sHA = SHA256.Create(); return BitConverter.ToString(sHA.ComputeHash(Encoding.UTF8.GetBytes(text ?? string.Empty))).Replace("-", string.Empty).ToLowerInvariant(); } public static string Template() { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("# vsm.drops.categories.txt — excepciones de categoría por ítem (una por línea: Prefab = Categoria)."); stringBuilder.AppendLine("# Categorías: Madera, Ores, Piedras, DropsDeMobs, Cosecha, Otros, Excluido (Excluido = nunca se multiplica)."); stringBuilder.AppendLine("# Solo lo lee el servidor (o el anfitrión) y se envía a todos los clientes. Los trofeos siempre quedan excluidos."); stringBuilder.AppendLine("# Descomenta (quita el #) la línea que quieras cambiar. La clasificación completa detectada está en vsm.drops.categories.generated.txt."); stringBuilder.AppendLine(); foreach (KeyValuePair<string, DropCategory> item in CategoryRules.Defaults.OrderBy((KeyValuePair<string, DropCategory> p) => p.Value).ThenBy<KeyValuePair<string, DropCategory>, string>((KeyValuePair<string, DropCategory> p) => p.Key, StringComparer.OrdinalIgnoreCase)) { stringBuilder.AppendLine("# " + item.Key + " = " + DropCategoryNames.Display(item.Value)); } return stringBuilder.ToString(); } } public static class CategoryRules { private static readonly Dictionary<string, DropCategory> s_defaults = BuildDefaults(); public static IReadOnlyDictionary<string, DropCategory> Defaults => s_defaults; private static Dictionary<string, DropCategory> BuildDefaults() { Dictionary<string, DropCategory> dictionary = new Dictionary<string, DropCategory>(StringComparer.OrdinalIgnoreCase); Add(dictionary, DropCategory.Madera, "Wood", "FineWood", "RoundLog", "ElderBark", "YggdrasilWood", "Blackwood", "Frostwood", "Ashwood"); Add(dictionary, DropCategory.Ores, "CopperOre", "TinOre", "IronOre", "SilverOre", "FlametalOre", "FlametalOreNew", "GoldOre", "BloodGoldOre", "BlackMetalScrap", "IronScrap", "CopperScrap", "BronzeScrap", "Chitin", "SulfurStone", "ProustitePowder", "Softtissue", "SoftTissue", "Copper", "Tin", "Iron", "Bronze", "Silver", "BlackMetal", "Flametal", "FlametalNew", "Gold", "BloodGold"); Add(dictionary, DropCategory.Piedras, "Stone", "StoneRock", "Flint", "Obsidian", "Grausten", "BlackMarble", "Ice", "IceShoreShard", "Crystal", "SharpeningStone"); Add(dictionary, DropCategory.DropsDeMobs, "LeatherScraps", "Leatherstraps", "DeerHide", "TrollHide", "WolfPelt", "LoxPelt", "ScaleHide", "AskHide", "BjornHide", "MooseHide", "SealHide", "MooseSinew", "MorgenSinew", "RawMeat", "DeerMeat", "NeckTail", "WolfMeat", "LoxMeat", "ChickenMeat", "HareMeat", "SerpentMeat", "BugMeat", "VoltureMeat", "MooseMeat", "AsksvinMeat", "BjornMeat", "BoneMawSerpentMeat", "RottenMeat", "BjornPaw", "AskBladder", "MorgenHeart", "CelestialFeather", "UndeadBjornRibcage", "AsksvinCarrionNeck", "AsksvinCarrionPelvic", "AsksvinCarrionRibcage", "AsksvinCarrionSkull", "Entrails", "BoneFragments", "GreydwarfEye", "Guck", "Ooze", "OozeMork", "Feathers", "WolfFang", "WolfClaw", "Mandible", "Needle", "DvergrNeedle", "FreezeGland", "Bloodbag", "Bilebag", "GiantBloodSack", "ElakingHairBundle", "WolfHairBundle", "NornThread", "Carapace", "SerpentScale", "BonemawSerpentScale", "BonemawSerpentTooth", "Ectoplasm", "Voidplasm", "CharredBone", "WitheredBone", "SealBlubber", "MoleClaws", "QueenBee", "Root", "BarkaBranch", "JuteRed", "JuteBlue", "Chain"); Add(dictionary, DropCategory.Cosecha, "Raspberry", "Blueberries", "Cloudberry", "Lingonberry", "Vineberry", "Pukeberries", "Mushroom", "MushroomBlue", "MushroomYellow", "MushroomJotunPuffs", "MushroomMagecap", "MushroomSmokePuff", "Carrot", "Onion", "Turnip", "Barley", "Flax", "Thistle", "Dandelion", "Honey", "Sap", "RoyalJelly", "WrithanRoots", "Fiddleheadfern", "Kale", "Oat", "Poteitr", "VoltureEgg", "AsksvinEgg", "CarrotSeeds", "TurnipSeeds", "OnionSeeds", "KaleSeeds", "OatSeeds", "PoteitrSeeds", "VineGreenSeeds", "VineberrySeeds", "Acorn", "BeechSeeds", "BirchSeeds", "PineCone", "FirCone", "FirConeFrost"); Add(dictionary, DropCategory.Otros, "Coal", "MemorialCoal", "CharcoalResin", "Resin", "Tar", "SurtlingCore", "BlackCore", "MoltenCore", "FrostCore", "Eitr", "Amber", "AmberPearl", "Ruby", "Coins", "SilverNecklace", "AncientCoin", "AncientGemstoneBlack", "AncientGemstoneGreen", "AncientGemstoneOrange", "AncientGemstonePurple", "GemstoneBlue", "GemstoneGreen", "GemstoneRed", "Hook", "FrozenFuel", "OrbFrostFire", "OrbThunderBlood", "Wisp", "YmirRemains", "Thunderstone", "ChickenEgg", "Snowball", "GlowWorm", "Charredskull", "BellFragment", "CharredCogwheel", "Pot_Shard_Green"); Add(dictionary, DropCategory.Excluido, "CryptKey", "BloodGoldKey", "Wishbone", "DragonEgg", "AncientSeed", "GoblinTotem", "HardAntler", "DragonTear", "CrownJewel", "YagluthDrop", "QueenDrop", "FaderDrop", "FrozenKingDrop", "FaderEmber", "DyrnwynHiltFragment", "DyrnwynBladeFragment", "DyrnwynTipFragment", "HildirKey_forestcrypt", "HildirKey_mountaincave", "HildirKey_plainsfortress", "chest_hildir1", "chest_hildir2", "chest_hildir3", "MoldKeys"); return dictionary; } private static void Add(Dictionary<string, DropCategory> d, DropCategory c, params string[] names) { foreach (string key in names) { d[key] = c; } } public static DropCategory? ByName(string prefabName, string token) { string text = (prefabName ?? string.Empty).ToLowerInvariant(); string text2 = (token ?? string.Empty).ToLowerInvariant(); if (text.Length == 0) { return null; } if (text.StartsWith("vsm_")) { return DropCategory.Excluido; } if (text.Contains("trophy") || text2.Contains("trophy")) { return DropCategory.Excluido; } if (text.EndsWith("ore") || text.EndsWith("scrap") || text.Contains("flametal")) { return DropCategory.Ores; } if (text.EndsWith("wood") || text.EndsWith("log") || text.EndsWith("bark")) { return DropCategory.Madera; } if (Contains(text, "seed", "berry", "berries", "mushroom", "cone", "acorn", "puffs", "magecap")) { return DropCategory.Cosecha; } if (Contains(text, "hide", "pelt", "meat", "bone", "gland", "fang", "claw", "eye", "sinew", "tail", "entrails", "blubber", "feather", "carapace", "scale", "plasm", "needle", "mandible", "guck", "ooze")) { return DropCategory.DropsDeMobs; } if (Contains(text, "stone", "marble", "flint", "obsidian", "crystal", "grausten") || text == "ice") { return DropCategory.Piedras; } return null; } private static bool Contains(string s, params string[] parts) { foreach (string value in parts) { if (s.Contains(value)) { return true; } } return false; } } public enum DropCategory { Otros, Madera, Ores, Piedras, DropsDeMobs, Cosecha, Excluido } public static class DropCategoryNames { public static bool TryParse(string text, out DropCategory category) { category = DropCategory.Otros; if (string.IsNullOrEmpty(text)) { return false; } switch (Normalize(text)) { case "otros": case "otro": case "other": category = DropCategory.Otros; return true; case "madera": case "maderas": case "wood": category = DropCategory.Madera; return true; case "ores": case "ore": case "menas": case "mena": case "minerales": case "mineral": case "metales": category = DropCategory.Ores; return true; case "piedras": case "piedra": case "stone": case "stones": category = DropCategory.Piedras; return true; case "dropsdemobs": case "mobs": case "mob": case "criaturas": case "criatura": case "monstruos": category = DropCategory.DropsDeMobs; return true; case "cosecha": case "cosechas": case "harvest": case "cultivo": case "cultivos": category = DropCategory.Cosecha; return true; case "excluido": case "excluidos": case "excluir": case "excluded": case "nunca": category = DropCategory.Excluido; return true; default: return false; } } public static string Normalize(string text) { string text2 = text.Trim().ToLowerInvariant(); return text2.Replace('á', 'a').Replace('é', 'e').Replace('í', 'i') .Replace('ó', 'o') .Replace('ú', 'u') .Replace('ü', 'u') .Replace('ñ', 'n') .Replace(" ", string.Empty) .Replace("_", string.Empty); } public static string Display(DropCategory category) { return category switch { DropCategory.Madera => "Madera", DropCategory.Ores => "Ores", DropCategory.Piedras => "Piedras", DropCategory.DropsDeMobs => "DropsDeMobs", DropCategory.Cosecha => "Cosecha", DropCategory.Excluido => "Excluido", _ => "Otros", }; } } public static class ItemClassifier { private static readonly Dictionary<string, DropCategory> s_cache = new Dictionary<string, DropCategory>(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary<string, string> s_tokenToPrefab = new Dictionary<string, string>(StringComparer.Ordinal); private static readonly HashSet<string> s_loggedUnclassified = new HashSet<string>(StringComparer.OrdinalIgnoreCase); private static bool s_quiet; private static Dictionary<string, DropCategory> s_overrides = new Dictionary<string, DropCategory>(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary<string, DropCategory> s_sourceHints = new Dictionary<string, DropCategory>(StringComparer.OrdinalIgnoreCase); private static ManualLogSource s_log; public static IReadOnlyDictionary<string, DropCategory> Overrides => s_overrides; public static void BuildSourceHints(ZNetScene scene) { s_sourceHints.Clear(); if ((Object)(object)scene == (Object)null || scene.m_prefabs == null) { return; } foreach (GameObject prefab in scene.m_prefabs) { if ((Object)(object)prefab == (Object)null) { continue; } CharacterDrop component = prefab.GetComponent<CharacterDrop>(); if ((Object)(object)component != (Object)null && component.m_drops != null) { foreach (Drop drop in component.m_drops) { Hint(drop.m_prefab, DropCategory.DropsDeMobs); } } Pickable component2 = prefab.GetComponent<Pickable>(); if ((Object)(object)component2 != (Object)null) { Hint(component2.m_itemPrefab, DropCategory.Cosecha); } HintTable(((Object)(object)prefab.GetComponent<TreeBase>() != (Object)null) ? prefab.GetComponent<TreeBase>().m_dropWhenDestroyed : null, DropCategory.Madera); HintTable(((Object)(object)prefab.GetComponent<TreeLog>() != (Object)null) ? prefab.GetComponent<TreeLog>().m_dropWhenDestroyed : null, DropCategory.Madera); HintTable(((Object)(object)prefab.GetComponent<MineRock>() != (Object)null) ? prefab.GetComponent<MineRock>().m_dropItems : null, DropCategory.Ores); HintTable(((Object)(object)prefab.GetComponent<MineRock5>() != (Object)null) ? prefab.GetComponent<MineRock5>().m_dropItems : null, DropCategory.Ores); } s_cache.Clear(); } private static void HintTable(DropTable table, DropCategory category) { //IL_0028: 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_002f: Unknown result type (might be due to invalid IL or missing references) if (table == null || table.m_drops == null) { return; } foreach (DropData drop in table.m_drops) { Hint(drop.m_item, category); } } private static void Hint(GameObject prefab, DropCategory category) { if (!((Object)(object)prefab == (Object)null)) { string name = ((Object)prefab).name; if (s_sourceHints.TryGetValue(name, out var value) && value != category) { s_sourceHints[name] = DropCategory.Otros; } else { s_sourceHints[name] = category; } } } public static void Init(ManualLogSource log) { s_log = log; } public static void InvalidateCache() { s_cache.Clear(); } public static void SetOverrides(Dictionary<string, DropCategory> overrides) { s_overrides = overrides ?? new Dictionary<string, DropCategory>(StringComparer.OrdinalIgnoreCase); s_cache.Clear(); } public static void Rebuild(ObjectDB db) { s_cache.Clear(); s_tokenToPrefab.Clear(); if ((Object)(object)db == (Object)null || db.m_items == null) { return; } foreach (GameObject item in db.m_items) { if ((Object)(object)item == (Object)null) { continue; } ItemDrop component = item.GetComponent<ItemDrop>(); if (!((Object)(object)component == (Object)null) && component.m_itemData != null && component.m_itemData.m_shared != null) { string name = component.m_itemData.m_shared.m_name; if (!string.IsNullOrEmpty(name) && !s_tokenToPrefab.ContainsKey(name)) { s_tokenToPrefab[name] = ((Object)item).name; } } } } public static string PrefabNameFromToken(string token) { string value; return (!string.IsNullOrEmpty(token) && s_tokenToPrefab.TryGetValue(token, out value)) ? value : null; } public static bool HasItemDrop(GameObject prefab) { return (Object)(object)prefab != (Object)null && (Object)(object)prefab.GetComponent<ItemDrop>() != (Object)null; } public static DropCategory Classify(GameObject prefab) { return ((Object)(object)prefab == (Object)null) ? DropCategory.Excluido : Classify(((Object)prefab).name, prefab); } public static DropCategory Classify(string prefabName, GameObject prefabOrNull) { if (string.IsNullOrEmpty(prefabName)) { return DropCategory.Excluido; } if (s_cache.TryGetValue(prefabName, out var value)) { return value; } SharedData val = SharedOf(prefabName, prefabOrNull); bool fallback; DropCategory dropCategory = Resolve(prefabName, val, out fallback); if (fallback && dropCategory == DropCategory.Otros && !s_quiet && DropsPlugin.LogUnclassifiedItems.Value && s_loggedUnclassified.Add(prefabName) && s_log != null) { s_log.LogInfo((object)("[vsm.drops] Sin clasificar → Otros: " + prefabName + " (" + ((val != null) ? (val.m_name + ", " + ((object)Unsafe.As<ItemType, ItemType>(ref val.m_itemType)/*cast due to .constrained prefix*/).ToString()) : "sin ItemDrop") + ")")); } s_cache[prefabName] = dropCategory; return dropCategory; } private static DropCategory Resolve(string prefabName, SharedData shared, out bool fallback) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Invalid comparison between Unknown and I4 //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Invalid comparison between Unknown and I4 //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Invalid comparison between Unknown and I4 //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Invalid comparison between Unknown and I4 //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Invalid comparison between Unknown and I4 fallback = false; if (shared != null && (int)shared.m_itemType == 13) { return DropCategory.Excluido; } if (s_overrides.TryGetValue(prefabName, out var value)) { return value; } if (CategoryRules.Defaults.TryGetValue(prefabName, out var value2)) { return value2; } if (shared != null) { if (shared.m_questItem || (int)shared.m_itemType == 21) { return DropCategory.Excluido; } if (!DropsPlugin.IgnoreNonScaledDropTypes.Value && (Object)(object)Game.instance != (Object)null && Game.instance.m_nonScaledDropTypes != null && Game.instance.m_nonScaledDropTypes.Contains(shared.m_itemType)) { return DropCategory.Excluido; } ItemType itemType = shared.m_itemType; if ((int)itemType != 1 && (int)itemType != 2 && (int)itemType != 16) { return DropCategory.Excluido; } } DropCategory? dropCategory = CategoryRules.ByName(prefabName, shared?.m_name); if (dropCategory.HasValue) { return dropCategory.Value; } if (s_sourceHints.TryGetValue(prefabName, out var value3) && value3 != DropCategory.Otros) { if (value3 == DropCategory.Ores && shared != null && (int)shared.m_itemType == 1) { string text = prefabName.ToLowerInvariant(); return (text.EndsWith("ore") || text.EndsWith("scrap")) ? DropCategory.Ores : DropCategory.Piedras; } return value3; } fallback = true; return DropCategory.Otros; } private static SharedData SharedOf(string prefabName, GameObject prefabOrNull) { try { GameObject val = prefabOrNull; if ((Object)(object)val == (Object)null && (Object)(object)ObjectDB.instance != (Object)null) { val = ObjectDB.instance.GetItemPrefab(prefabName); } if ((Object)(object)val == (Object)null && (Object)(object)ZNetScene.instance != (Object)null) { val = ZNetScene.instance.GetPrefab(prefabName); } if ((Object)(object)val == (Object)null) { return null; } ItemDrop component = val.GetComponent<ItemDrop>(); return ((Object)(object)component != (Object)null && component.m_itemData != null) ? component.m_itemData.m_shared : null; } catch (Exception) { return null; } } public static void WriteGeneratedFile(string path, ObjectDB db) { if ((Object)(object)db == (Object)null || db.m_items == null) { return; } StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("# Clasificación detectada por vsm.drops (informativo; edita vsm.drops.categories.txt para cambiarla)."); stringBuilder.AppendLine("# origen: override = archivo del admin | tabla = tabla por defecto | regla = tipo/nombre | fallback = sin regla → Otros"); stringBuilder.AppendLine("# Prefab = Categoria # token, tipo, maxStack"); List<string> list = new List<string>(); s_quiet = true; try { foreach (GameObject item in db.m_items) { if (!((Object)(object)item == (Object)null)) { ItemDrop component = item.GetComponent<ItemDrop>(); if (!((Object)(object)component == (Object)null) && component.m_itemData != null && component.m_itemData.m_shared != null) { SharedData shared = component.m_itemData.m_shared; DropCategory dropCategory = Classify(((Object)item).name, item); string text = (s_overrides.ContainsKey(((Object)item).name) ? "override" : (CategoryRules.Defaults.ContainsKey(((Object)item).name) ? "tabla" : ((CategoryRules.ByName(((Object)item).name, shared.m_name).HasValue || dropCategory == DropCategory.Excluido) ? "regla" : (s_sourceHints.ContainsKey(((Object)item).name) ? ("origen:" + DropCategoryNames.Display(s_sourceHints[((Object)item).name])) : "fallback")))); list.Add(((Object)item).name + " = " + DropCategoryNames.Display(dropCategory) + " # " + shared.m_name + ", " + ((object)Unsafe.As<ItemType, ItemType>(ref shared.m_itemType)/*cast due to .constrained prefix*/).ToString() + ", x" + shared.m_maxStackSize + ", " + text); } } } } finally { s_quiet = false; } list.Sort(StringComparer.OrdinalIgnoreCase); foreach (string item2 in list) { stringBuilder.AppendLine(item2); } File.WriteAllText(path, stringBuilder.ToString(), new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)); } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class <e4741b38-e643-416f-af8a-811427b5b3c8>IgnoresAccessChecksToAttribute : Attribute { public <e4741b38-e643-416f-af8a-811427b5b3c8>IgnoresAccessChecksToAttribute(string assemblyName) { } } } namespace VSM.Core.Ui { internal static class VanillaStyle { public static TMP_Text TitleFont => ((Object)(object)InventoryGui.instance != (Object)null) ? InventoryGui.instance.m_playerName : null; public static TMP_Text BodyFont => (!((Object)(object)InventoryGui.instance != (Object)null)) ? null : (((Object)(object)InventoryGui.instance.m_armor != (Object)null) ? InventoryGui.instance.m_armor : InventoryGui.instance.m_playerName); public static Image FindBackground(Transform root, Transform exclude1, Transform exclude2) { //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)root == (Object)null) { return null; } Image result = null; float num = 0f; Image[] componentsInChildren = ((Component)root).GetComponentsInChildren<Image>(true); foreach (Image val in componentsInChildren) { if ((Object)(object)val == (Object)null || (Object)(object)val.sprite == (Object)null) { continue; } Transform transform = ((Component)val).transform; if ((!((Object)(object)exclude1 != (Object)null) || !transform.IsChildOf(exclude1)) && (!((Object)(object)exclude2 != (Object)null) || !transform.IsChildOf(exclude2))) { Rect rect = ((Graphic)val).rectTransform.rect; float num2 = Mathf.Abs(((Rect)(ref rect)).width * ((Rect)(ref rect)).height); if (num2 > num) { num = num2; result = val; } } } return result; } public static bool CopyImage(Image source, Image target) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target == (Object)null) { return false; } if ((Object)(object)source == (Object)null) { ((Graphic)target).color = new Color(0f, 0f, 0f, 0.6f); return false; } target.sprite = source.sprite; target.type = source.type; ((Graphic)target).material = ((Graphic)source).material; ((Graphic)target).color = ((Graphic)source).color; target.fillCenter = source.fillCenter; target.pixelsPerUnitMultiplier = source.pixelsPerUnitMultiplier; target.preserveAspect = false; return true; } public static Image InventoryBackground(Transform exclude) { InventoryGui instance = InventoryGui.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.m_player == (Object)null) { return null; } Transform exclude2 = (Transform)(object)(((Object)(object)instance.m_playerGrid != (Object)null) ? instance.m_playerGrid.m_gridRoot : null); return FindBackground((Transform)(object)instance.m_player, exclude2, exclude); } public static void CopyFont(TMP_Text source, TMP_Text target) { //IL_0037: 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) if (!((Object)(object)source == (Object)null) && !((Object)(object)target == (Object)null)) { target.font = source.font; target.fontSharedMaterial = source.fontSharedMaterial; ((Graphic)target).color = ((Graphic)source).color; target.fontStyle = source.fontStyle; } } public static TextMeshProUGUI NewText(Transform parent, string name, TMP_Text style, float size, TextAlignmentOptions align) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0041: 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(parent, false); TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>(); CopyFont(style, (TMP_Text)(object)val2); ((TMP_Text)val2).fontSize = size; ((TMP_Text)val2).alignment = align; ((Graphic)val2).raycastTarget = false; ((TMP_Text)val2).enableWordWrapping = false; ((TMP_Text)val2).richText = true; return val2; } } } namespace VSM.Core.Runtime { internal static class Headless { private static bool? s_isHeadless; public static bool IsHeadless { get { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 if (!s_isHeadless.HasValue) { s_isHeadless = (int)SystemInfo.graphicsDeviceType == 4 || Application.isBatchMode; } return s_isHeadless.Value; } } public static bool IsServerProcess => (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer(); public static bool IsDedicatedServer => (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && ZNet.instance.IsDedicated(); public static bool IsListenHost => (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && !ZNet.instance.IsDedicated(); public static bool IsRemoteClient => (Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer(); } internal static class Keys { public static bool Pressed(KeyboardShortcut shortcut) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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) KeyCode mainKey = ((KeyboardShortcut)(ref shortcut)).MainKey; return (int)mainKey != 0 && ZInput.GetKeyDown(mainKey, false) && ((KeyboardShortcut)(ref shortcut)).Modifiers.All((KeyCode m) => ZInput.GetKey(m, false)); } } } namespace VSM.Core.Reflection { internal static class GameConstants { private static uint? s_networkVersion; private static long? s_routedEverybody; public static uint NetworkVersion { get { if (!s_networkVersion.HasValue) { s_networkVersion = ReadConstant<uint>(typeof(Version), new string[2] { "c_networkVersion", "m_networkVersion" }); } return s_networkVersion.Value; } } public static long RoutedRpcEverybody { get { if (!s_routedEverybody.HasValue) { s_routedEverybody = ReadConstant<long>(typeof(ZRoutedRpc), new string[1] { "Everybody" }); } return s_routedEverybody.Value; } } public static string GameVersionString { get { //IL_0002: 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) try { return ((object)Version.CurrentVersion/*cast due to .constrained prefix*/).ToString(); } catch (Exception) { return "?"; } } } private static T ReadConstant<T>(Type type, params string[] names) where T : struct { foreach (string name in names) { FieldInfo field = type.GetField(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (!(field == null)) { object obj = (field.IsLiteral ? field.GetRawConstantValue() : field.GetValue(null)); if (obj is T result) { return result; } try { return (T)Convert.ChangeType(obj, typeof(T)); } catch (Exception) { } } } return default(T); } } } namespace VSM.Core.Net { internal static class ZPackageExt { public static bool HasMore(this ZPackage pkg) { return pkg != null && pkg.GetPos() < pkg.Size(); } public static int ReadIntOr(this ZPackage pkg, int fallback) { return pkg.HasMore() ? pkg.ReadInt() : fallback; } public static string ReadStringOr(this ZPackage pkg, string fallback) { return pkg.HasMore() ? pkg.ReadString() : fallback; } public static bool ReadBoolOr(this ZPackage pkg, bool fallback) { return pkg.HasMore() ? pkg.ReadBool() : fallback; } public static string ReadBoundedString(this ZPackage pkg, int maxLength) { string text = pkg.ReadString(); return (text != null && text.Length <= maxLength) ? text : null; } } } namespace VSM.Core.Localization { internal static class VsmLocalization { public static void Register(ManualLogSource log, string pluginDirectory, IDictionary<string, string> embeddedSpanish) { Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.Ordinal); if (embeddedSpanish != null) { foreach (KeyValuePair<string, string> item in embeddedSpanish) { dictionary[item.Key] = item.Value; } } string path = Path.Combine(pluginDirectory ?? string.Empty, "Translations"); MergeFile(log, Path.Combine(path, "Spanish.json"), dictionary); string text = SafeSelectedLanguage(); if (!string.Equals(text, "Spanish", StringComparison.OrdinalIgnoreCase)) { MergeFile(log, Path.Combine(path, text + ".json"), dictionary); } Apply(log, dictionary); } public static string Localize(string token, params object[] args) { string text = token; try { if (Localization.instance != null && !string.IsNullOrEmpty(token)) { bool flag = token[0] != '$' && token.IndexOf(' ') < 0 && token.IndexOf('\n') < 0; string text2 = Localization.instance.Localize(flag ? ("$" + token) : token); text = ((flag && text2.Length > 1 && text2[0] == '[' && text2[text2.Length - 1] == ']') ? token : text2); } } catch (Exception) { text = token; } if (args != null && args.Length != 0) { try { text = string.Format(text, args); } catch (FormatException) { } } return text; } private static string SafeSelectedLanguage() { try { return (Localization.instance != null) ? Localization.instance.GetSelectedLanguage() : "Spanish"; } catch (Exception) { return "Spanish"; } } private static void Apply(ManualLogSource log, Dictionary<string, string> words) { if (Localization.instance == null) { if (log != null) { log.LogWarning((object)"Localization.instance aún no existe; las traducciones no se han aplicado."); } return; } foreach (KeyValuePair<string, string> word in words) { string text = (word.Key.StartsWith("$", StringComparison.Ordinal) ? word.Key.Substring(1) : word.Key); Localization.instance.AddWord(text, word.Value); } } private static void MergeFile(ManualLogSource log, string path, Dictionary<string, string> into) { if (!File.Exists(path)) { return; } try { foreach (KeyValuePair<string, string> item in ParseFlatJson(File.ReadAllText(path, Encoding.UTF8))) { into[item.Key] = item.Value; } } catch (Exception ex) { if (log != null) { log.LogWarning((object)("No se pudo leer " + path + ": " + ex.Message)); } } } public static Dictionary<string, string> ParseFlatJson(string json) { Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.Ordinal); if (string.IsNullOrEmpty(json)) { return dictionary; } int i = 0; SkipWs(json, ref i); if (i >= json.Length || json[i] != '{') { return dictionary; } i++; while (true) { SkipWs(json, ref i); if (i >= json.Length || json[i] == '}') { break; } if (json[i] == ',') { i++; continue; } string text = ReadString(json, ref i); if (text == null) { i++; continue; } SkipWs(json, ref i); if (i < json.Length && json[i] == ':') { i++; } SkipWs(json, ref i); if (i < json.Length && json[i] == '"') { string text2 = ReadString(json, ref i); dictionary[text] = text2 ?? string.Empty; } else { for (; i < json.Length && json[i] != ',' && json[i] != '}'; i++) { } } } return dictionary; } private static void SkipWs(string s, ref int i) { while (i < s.Length && char.IsWhiteSpace(s[i])) { i++; } } private static string ReadString(string s, ref int i) { if (i >= s.Length || s[i] != '"') { return null; } i++; StringBuilder stringBuilder = new StringBuilder(); while (i < s.Length) { char c = s[i++]; switch (c) { case '"': return stringBuilder.ToString(); case '\\': { if (i >= s.Length) { break; } char c2 = s[i++]; switch (c2) { case 'n': stringBuilder.Append('\n'); break; case 't': stringBuilder.Append('\t'); break; case 'r': stringBuilder.Append('\r'); break; case 'b': stringBuilder.Append('\b'); break; case 'f': stringBuilder.Append('\f'); break; case 'u': if (i + 4 <= s.Length) { stringBuilder.Append((char)Convert.ToInt32(s.Substring(i, 4), 16)); i += 4; } break; default: stringBuilder.Append(c2); break; } continue; } } stringBuilder.Append(c); } return stringBuilder.ToString(); } } } namespace VSM.Core.Harmony { internal static class PatchUtil { private static readonly List<string> s_failed = new List<string>(); public static IReadOnlyList<string> FailedTargets => s_failed; public static bool IsDegraded => s_failed.Count > 0; public static MethodInfo DeclaredMethodOrNull(ManualLogSource log, Type type, string name, Type[] parameters, string owner) { if (type == null) { Fail(log, owner, name + " (tipo nulo)"); return null; } MethodInfo methodInfo = AccessTools.DeclaredMethod(type, name, parameters, (Type[])null); if (methodInfo == null) { Fail(log, owner, type.FullName + "." + name + "(" + Describe(parameters) + ")"); } return methodInfo; } public static void PatchAllSafely(ManualLogSource log, Harmony harmony, Assembly assembly) { Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(assembly); foreach (Type type in typesFromAssembly) { if (type.GetCustomAttributes(typeof(HarmonyPatch), inherit: true).Length != 0) { PatchClassSafely(log, harmony, type); } } } public static bool PatchClassSafely(ManualLogSource log, Harmony harmony, Type patchClass) { try { harmony.CreateClassProcessor(patchClass).Patch(); return true; } catch (Exception ex) { Fail(log, harmony.Id, patchClass.FullName + " -> " + ex.GetType().Name + ": " + ex.Message); return false; } } private static void Fail(ManualLogSource log, string owner, string what) { s_failed.Add(what); if (log != null) { log.LogError((object)("[" + owner + "] No se pudo aplicar el parche (¿cambió el juego?): " + what + ". El mod sigue cargado en modo degradado.")); } } private static string Describe(Type[] parameters) { if (parameters == null || parameters.Length == 0) { return string.Empty; } string[] array = new string[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { array[i] = ((parameters[i] == null) ? "?" : parameters[i].Name); } return string.Join(", ", array); } } } namespace VSM.Core.Config { internal sealed class ConfigurationManagerAttributes { public bool? ShowRangeAsPercent; public Action<ConfigEntryBase> CustomDrawer; public bool? Browsable; public string Category; public object DefaultValue; public bool? HideDefaultButton; public bool? HideSettingName; public string Description; public string DispName; public int? Order; public bool? ReadOnly; public bool? IsAdvanced; public bool? IsAdminOnly; public Func<object, string> ObjToStr; public Func<string, object> StrToObj; } } namespace VSM.Core.Camera { internal struct RigSettings { public float Speed; public float FastMultiplier; public bool MoveRelativeToView; } internal sealed class CameraRig { public const float MaxPitch = 89f; public float Yaw; public float Pitch; public Vector3 Position; public Vector3 Velocity; public Vector3 ForwardVector => Forward(Yaw, Pitch); public Quaternion Rotation => Quaternion.Euler(Pitch, Yaw, 0f); public static Vector3 Forward(float yawDeg, float pitchDeg) { //IL_002f: 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) //IL_0037: Unknown result type (might be due to invalid IL or missing references) float num = yawDeg * ((float)Math.PI / 180f); float num2 = pitchDeg * ((float)Math.PI / 180f); float num3 = Mathf.Cos(num2); return new Vector3(Mathf.Sin(num) * num3, 0f - Mathf.Sin(num2), Mathf.Cos(num) * num3); } public static Vector3 FlatForward(float yawDeg) { //IL_001a: 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_0022: Unknown result type (might be due to invalid IL or missing references) float num = yawDeg * ((float)Math.PI / 180f); return new Vector3(Mathf.Sin(num), 0f, Mathf.Cos(num)); } public static Vector3 Right(float yawDeg) { //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_0023: Unknown result type (might be due to invalid IL or missing references) float num = yawDeg * ((float)Math.PI / 180f); return new Vector3(Mathf.Cos(num), 0f, 0f - Mathf.Sin(num)); } public void Reset(Vector3 position, Vector3 forward) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) Position = position; Velocity = Vector3.zero; SetFromDirection(forward); } public void SetFromDirection(Vector3 forward) { //IL_0035: 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_005c: Unknown result type (might be due to invalid IL or missing references) if (((Vector3)(ref forward)).sqrMagnitude < 1E-08f) { Yaw = 0f; Pitch = 0f; } else { ((Vector3)(ref forward)).Normalize(); Yaw = Mathf.Repeat(Mathf.Atan2(forward.x, forward.z) * 57.29578f, 360f); Pitch = Mathf.Clamp((0f - Mathf.Asin(Mathf.Clamp(forward.y, -1f, 1f))) * 57.29578f, -89f, 89f); } } public void ApplyLook(Vector2 delta) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) Yaw = Mathf.Repeat(Yaw + delta.x, 360f); Pitch = Mathf.Clamp(Pitch - delta.y, -89f, 89f); } public Vector3 DesiredVelocity(Vector3 move, float vertical, bool fast, RigSettings settings) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //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_0083: 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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: 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_00df: 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) Vector3 val = (settings.MoveRelativeToView ? Forward(Yaw, Pitch) : FlatForward(Yaw)); Vector3 val2 = Right(Yaw) * Mathf.Clamp(move.x, -1f, 1f) + val * Mathf.Clamp(move.z, -1f, 1f) + Vector3.up * Mathf.Clamp(vertical, -1f, 1f); if (((Vector3)(ref val2)).sqrMagnitude > 1f) { ((Vector3)(ref val2)).Normalize(); } float num = Mathf.Max(0f, settings.Speed) * (fast ? Mathf.Max(1f, settings.FastMultiplier) : 1f); return val2 * num; } public void Integrate(Vector3 desiredVelocity, float dt, float smoothing) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0047: 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) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) if (!(dt <= 0f)) { float num = ((smoothing <= 0f) ? 1f : (1f - Mathf.Exp((0f - dt) / smoothing))); Velocity = Vector3.Lerp(Velocity, desiredVelocity, num); Position += Velocity * dt; } } public static Vector3 ClampToSphere(Vector3 pos, Vector3 center, float radius) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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) Vector3 val = pos - center; float num = Mathf.Max(0f, radius); if (((Vector3)(ref val)).sqrMagnitude <= num * num) { return pos; } return center + ((Vector3)(ref val)).normalized * num; } } internal static class CameraWorld { public const float CollisionRadius = 0.25f; public static Vector3 Anchor(Player player) { //IL_0033: 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_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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) Transform eye = ((Character)player).m_eye; return ((Object)(object)eye != (Object)null) ? eye.position : (((Component)player).transform.position + Vector3.up * 1.6f); } public static Vector3 Constrain(Vector3 from, Vector3 to, Vector3 anchor, float maxDistance, float clearance, GameCamera cam) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0038: 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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) Vector3 pos = CameraRig.ClampToSphere(to, anchor, maxDistance); pos = Lift(pos, clearance, cam); pos = CameraRig.ClampToSphere(pos, anchor, maxDistance + 1f); LayerMask blockCameraMask = cam.m_blockCameraMask; Vector3 val = (Overlaps(from, blockCameraMask) ? anchor : from); return Collide(val, pos, blockCameraMask); } public static Vector3 Lift(Vector3 pos, float clearance, GameCamera cam) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) clearance = Mathf.Max(0f, clearance); ZoneSystem instance = ZoneSystem.instance; float num = default(float); if ((Object)(object)instance != (Object)null && instance.GetGroundHeight(pos, ref num)) { pos.y = Mathf.Max(pos.y, num + clearance); } float num2 = Floating.GetLiquidLevel(pos, 1f, (LiquidType)10); if ((Object)(object)instance != (Object)null && !Character.InInterior(pos)) { num2 = Mathf.Max(num2, instance.m_waterLevel); } if (num2 > -9000f) { pos.y = Mathf.Max(pos.y, num2 + Mathf.Max(clearance, cam.m_minWaterDistance)); } return pos; } public static bool Overlaps(Vector3 pos, LayerMask mask) { //IL_0001: 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) return Physics.CheckSphere(pos, 0.225f, LayerMask.op_Implicit(mask), (QueryTriggerInteraction)1); } public static Vector3 Collide(Vector3 from, Vector3 to, LayerMask mask) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0033: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) Vector3 val = to - from; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude < 1E-05f) { return to; } Vector3 val2 = val / magnitude; RaycastHit val3 = default(RaycastHit); if (Physics.SphereCast(from, 0.25f, val2, ref val3, magnitude, LayerMask.op_Implicit(mask), (QueryTriggerInteraction)1)) { return from + val2 * Mathf.Max(0f, ((RaycastHit)(ref val3)).distance - 0.02f); } return to; } } internal static class CameraLock { private const string Prefix = "vsm_camera_lock:"; public static string Holder() { GameCamera instance = GameCamera.instance; if ((Object)(object)instance == (Object)null) { return null; } Transform transform = ((Component)instance).transform; for (int i = 0; i < transform.childCount; i++) { string name = ((Object)transform.GetChild(i)).name; if (name.StartsWith("vsm_camera_lock:", StringComparison.Ordinal)) { return name.Substring("vsm_camera_lock:".Length); } } return null; } public static bool TryAcquire(string owner) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown GameCamera instance = GameCamera.instance; if ((Object)(object)instance == (Object)null) { return false; } string text = Holder(); if (text != null) { return text == owner; } GameObject val = new GameObject("vsm_camera_lock:" + owner); val.transform.SetParent(((Component)instance).transform, false); return true; } public static void Release(string owner) { GameCamera instance = GameCamera.instance; if ((Object)(object)instance == (Object)null) { return; } Transform transform = ((Component)instance).transform; for (int num = transform.childCount - 1; num >= 0; num--) { Transform child = transform.GetChild(num); if (((Object)child).name == "vsm_camera_lock:" + owner) { Object.Destroy((Object)(object)((Component)child).gameObject); ((Object)child).name = "vsm_camera_lock_released"; } } } } internal sealed class BodyHider { private readonly List<Renderer> _hidden = new List<Renderer>(); private float _nextScan; public void Update(Player player, bool hide) { if (!hide || (Object)(object)player == (Object)null) { Restore(); } else { if (Time.unscaledTime < _nextScan) { return; } _nextScan = Time.unscaledTime + 0.5f; Renderer[] componentsInChildren = ((Component)player).GetComponentsInChildren<Renderer>(false); foreach (Renderer val in componentsInChildren) { if ((Object)(object)val != (Object)null && val.enabled && (val is SkinnedMeshRenderer || val is MeshRenderer)) { val.enabled = false; _hidden.Add(val); } } } } public void Restore() { foreach (Renderer item in _hidden) { if ((Object)(object)item != (Object)null) { item.enabled = true; } } _hidden.Clear(); _nextScan = 0f; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }
plugins/VSM.Guard/VSM.Guard.dll
Decompiled 3 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.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using System.Threading; using System.Threading.Tasks; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.UI; using VSM.Core.Config; using VSM.Core.Harmony; using VSM.Core.Localization; using VSM.Core.Net; using VSM.Core.Reflection; using VSM.Core.Runtime; using VSM.Guard.Admission; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: <bae7c731-d4a2-4f32-bc22-36bb9df641bb>IgnoresAccessChecksTo("assembly_guiutils")] [assembly: <bae7c731-d4a2-4f32-bc22-36bb9df641bb>IgnoresAccessChecksTo("assembly_utils")] [assembly: <bae7c731-d4a2-4f32-bc22-36bb9df641bb>IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("VSM.Guard")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("0.1.4.0")] [assembly: AssemblyInformationalVersion("0.1.4+ff27bc889ccf218c61c45d3417d48ab708a5ba8f")] [assembly: AssemblyProduct("VSM.Guard")] [assembly: AssemblyTitle("VSM.Guard")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.4.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace VSM.Guard { internal static class GuardPatches { [HarmonyPatch(typeof(ZNet), "OnNewConnection", new Type[] { typeof(ZNetPeer) })] private static class OnNewConnectionPatch { [HarmonyPrefix] [HarmonyPriority(800)] private static void Prefix(ZNet __instance, ZNetPeer peer) { try { AdmissionCore.OnNewConnection(__instance, peer); } catch (Exception ex) { GuardPlugin.Log.LogError((object)("vsm.guard: OnNewConnection: " + ex)); } } } [HarmonyPatch(typeof(ZNet), "RPC_ServerHandshake", new Type[] { typeof(ZRpc), typeof(string) })] private static class ServerHandshakePatch { [HarmonyPrefix] private static void Prefix(ZNet __instance, ZRpc rpc) { if (__instance.IsServer()) { AdmissionCore.OnServerHandshake(__instance, rpc); } } } [HarmonyPatch(typeof(ZNet), "RPC_ClientHandshake", new Type[] { typeof(ZRpc), typeof(bool), typeof(string) })] private static class ClientHandshakePatch { [HarmonyPrefix] private static bool Prefix(ZNet __instance, ZRpc rpc) { try { return AdmissionCore.OnClientHandshake(__instance, rpc); } catch (Exception ex) { GuardPlugin.Log.LogError((object)("vsm.guard: ClientHandshake: " + ex)); return true; } } } [HarmonyPatch(typeof(ZNet), "RPC_PeerInfo", new Type[] { typeof(ZRpc), typeof(ZPackage) })] [HarmonyBefore(new string[] { "_shudnal.ConditionalConfigSync", "shudnal.ConditionalConfigSync", "org.bepinex.helpers.ServerSync" })] private static class PeerInfoPatch { [HarmonyPrefix] [HarmonyPriority(800)] private static bool Prefix(ZNet __instance, ZRpc rpc) { try { return AdmissionCore.GateAllows(__instance, rpc); } catch (Exception ex) { GuardPlugin.Log.LogError((object)("vsm.guard: excepción en la puerta de PeerInfo (se rechaza): " + ex)); return !__instance.IsServer(); } } } [HarmonyPatch(typeof(ZNet), "Disconnect", new Type[] { typeof(ZNetPeer) })] private static class DisconnectPatch { [HarmonyPrefix] private static void Prefix(ZNetPeer peer) { AdmissionCore.OnDisconnect(peer); } } [HarmonyPatch(typeof(FejdStartup), "ShowConnectError", new Type[] { typeof(ConnectionStatus) })] private static class ShowConnectErrorPatch { [HarmonyPostfix] private static void Postfix(FejdStartup __instance, ConnectionStatus statusOverride) { //IL_0002: 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_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 try { ConnectionStatus val = (((int)statusOverride != 0) ? statusOverride : ZNet.GetConnectionStatus()); if ((int)val == 3 && !((Object)(object)__instance.m_connectionFailedPanel == (Object)null) && __instance.m_connectionFailedPanel.activeSelf && !((Object)(object)__instance.m_connectionFailedError == (Object)null) && AdmissionCore.TakePendingReason(out var text)) { __instance.m_connectionFailedError.text = __instance.m_connectionFailedError.text + "\n\n" + text; } } catch (Exception ex) { GuardPlugin.Log.LogWarning((object)("vsm.guard: no se pudo anexar el motivo al panel: " + ex.Message)); } } } [HarmonyPatch(typeof(Terminal), "InitTerminal")] private static class InitTerminalPatch { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Func<Patch, int> <>9__1_2; public static ConsoleEvent <>9__1_0; public static ConsoleEvent <>9__1_1; internal void <Postfix>b__1_0(ConsoleEventArgs args) { foreach (string item in AdmissionCore.DumpLines()) { args.Context.AddString(item); GuardPlugin.Log.LogInfo((object)item); } try { MethodInfo methodInfo = AccessTools.DeclaredMethod(typeof(ZNet), "RPC_PeerInfo", new Type[2] { typeof(ZRpc), typeof(ZPackage) }, (Type[])null); Patches val = ((methodInfo != null) ? Harmony.GetPatchInfo((MethodBase)methodInfo) : null); string text = ((val == null) ? "(sin parches)" : string.Join(", ", val.Owners.ToArray())); args.Context.AddString("Dueños Harmony de RPC_PeerInfo: " + text); if (val == null) { return; } foreach (Patch item2 in val.Prefixes.OrderByDescending((Patch p) => p.priority)) { Terminal context = args.Context; string[] obj = new string[5] { " prefix ", item2.owner, " prioridad ", null, null }; int priority = item2.priority; obj[3] = priority.ToString(); obj[4] = ((item2.before != null && item2.before.Length != 0) ? (" before " + string.Join(",", item2.before)) : string.Empty); context.AddString(string.Concat(obj)); } } catch (Exception ex) { args.Context.AddString("(no se pudo leer la información de Harmony: " + ex.Message + ")"); } } internal int <Postfix>b__1_2(Patch p) { return p.priority; } internal void <Postfix>b__1_1(ConsoleEventArgs args) { PolicyManager.Reload(GuardPlugin.HashMode.Value); args.Context.AddString("vsm.guard: política recargada" + (PolicyManager.SelfCheckFailed ? " (AUTOCOMPROBACIÓN FALLIDA, ver log)" : string.Empty)); } } private static bool s_registered; [HarmonyPostfix] private static void Postfix() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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_0075: Expected O, but got Unknown if (s_registered) { return; } s_registered = true; object obj = <>c.<>9__1_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { foreach (string item in AdmissionCore.DumpLines()) { args.Context.AddString(item); GuardPlugin.Log.LogInfo((object)item); } try { MethodInfo methodInfo = AccessTools.DeclaredMethod(typeof(ZNet), "RPC_PeerInfo", new Type[2] { typeof(ZRpc), typeof(ZPackage) }, (Type[])null); Patches val3 = ((methodInfo != null) ? Harmony.GetPatchInfo((MethodBase)methodInfo) : null); string text = ((val3 == null) ? "(sin parches)" : string.Join(", ", val3.Owners.ToArray())); args.Context.AddString("Dueños Harmony de RPC_PeerInfo: " + text); if (val3 != null) { foreach (Patch item2 in val3.Prefixes.OrderByDescending((Patch p) => p.priority)) { Terminal context = args.Context; string[] obj3 = new string[5] { " prefix ", item2.owner, " prioridad ", null, null }; int priority = item2.priority; obj3[3] = priority.ToString(); obj3[4] = ((item2.before != null && item2.before.Length != 0) ? (" before " + string.Join(",", item2.before)) : string.Empty); context.AddString(string.Concat(obj3)); } return; } } catch (Exception ex) { args.Context.AddString("(no se pudo leer la información de Harmony: " + ex.Message + ")"); } }; <>c.<>9__1_0 = val; obj = (object)val; } new ConsoleCommand("vsm_guard_dump", "Muestra mods cargados (GUID, versión, hash), patchers, errores de dependencias, política y estado de vsm.guard", (ConsoleEvent)obj, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj2 = <>c.<>9__1_1; if (obj2 == null) { ConsoleEvent val2 = delegate(ConsoleEventArgs args) { PolicyManager.Reload(GuardPlugin.HashMode.Value); args.Context.AddString("vsm.guard: política recargada" + (PolicyManager.SelfCheckFailed ? " (AUTOCOMPROBACIÓN FALLIDA, ver log)" : string.Empty)); }; <>c.<>9__1_1 = val2; obj2 = (object)val2; } new ConsoleCommand("vsm_guard_reload", "Recarga vsm.guard.policy.cfg (solo servidor/admin)", (ConsoleEvent)obj2, false, false, true, false, false, false, (ConsoleOptionsFetcher)null, false, false, true); } } internal const string CcsHarmonyId = "_shudnal.ConditionalConfigSync"; internal const string CcsHarmonyIdAlt = "shudnal.ConditionalConfigSync"; internal const string ServerSyncHarmonyId = "org.bepinex.helpers.ServerSync"; } public enum SelfCheckMode { Strict, Warn } [BepInPlugin("vsm.guard", "MEL Guard", "0.1.4")] public sealed class GuardPlugin : BaseUnityPlugin { internal static ManualLogSource Log; public static ConfigEntry<UnknownModsMode> UnknownMods; public static ConfigEntry<HashMode> HashMode; public static ConfigEntry<SelfCheckMode> SelfCheck; public static ConfigEntry<bool> AdminExempt; public static ConfigEntry<bool> EnforcePatchers; public static ConfigEntry<float> DisconnectDelaySeconds; public static ConfigEntry<bool> ClientRequireGuardServer; public static ConfigEntry<bool> Verbose; public static ConfigEntry<bool> DebugThrowInValidator; public static ConfigEntry<bool> DebugDropChunk; private Harmony _harmony; public static GuardPlugin Instance { get; private set; } private void Awake() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Expected O, but got Unknown //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Expected O, but got Unknown //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Expected O, but got Unknown //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Expected O, but got Unknown //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Expected O, but got Unknown //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Expected O, but got Unknown //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Expected O, but got Unknown //IL_02fd: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; UnknownMods = ((BaseUnityPlugin)this).Config.Bind<UnknownModsMode>("1. Servidor", "unknownMods", UnknownModsMode.Reject, new ConfigDescription("Qué hacer con un mod del cliente que no está en ninguna lista de la política: Reject = no entra; Warn = entra y se registra en el log.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 10 } })); HashMode = ((BaseUnityPlugin)this).Config.Bind<HashMode>("1. Servidor", "hashMode", VSM.Guard.Admission.HashMode.Strict, new ConfigDescription("Strict = además de la versión se comprueba el SHA-256 del DLL cuando la política lo indica; Off = interruptor de emergencia que ignora los hashes.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 9 } })); SelfCheck = ((BaseUnityPlugin)this).Config.Bind<SelfCheckMode>("1. Servidor", "selfCheck", SelfCheckMode.Strict, new ConfigDescription("Si el propio servidor no tiene cargado algo que exige: Strict = rechaza a todos hasta corregir la política; Warn = solo lo registra.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 8 } })); AdminExempt = ((BaseUnityPlugin)this).Config.Bind<bool>("1. Servidor", "adminExempt", false, new ConfigDescription("Permite entrar a los admins (adminlist.txt) aunque no cumplan la política. Solo para probar builds nuevas; se registra en el log.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 7 } })); EnforcePatchers = ((BaseUnityPlugin)this).Config.Bind<bool>("1. Servidor", "enforcePatchers", false, new ConfigDescription("Exigir que los DLL de BepInEx/patchers del cliente estén en la lista [patchers] de la política. Por defecto solo se informan.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 6 } })); DisconnectDelaySeconds = ((BaseUnityPlugin)this).Config.Bind<float>("1. Servidor", "disconnectDelaySeconds", 1.5f, new ConfigDescription("Segundos que espera el servidor tras enviar el motivo antes de cerrar la conexión rechazada (da tiempo a que el cliente lo reciba).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 10f), new object[1] { new ConfigurationManagerAttributes { Order = 5 } })); ClientRequireGuardServer = ((BaseUnityPlugin)this).Config.Bind<bool>("2. Cliente", "clientRequireGuardServer", true, new ConfigDescription("Si el servidor al que te conectas no tiene MEL Guard, abortar la conexión (evita entrar a servidores sin el modpack).", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 10 } })); Verbose = ((BaseUnityPlugin)this).Config.Bind<bool>("3. Depuración", "verbose", false, "Registrar Hello/manifiesto y detalles del handshake."); DebugThrowInValidator = ((BaseUnityPlugin)this).Config.Bind<bool>("3. Depuración", "debugThrowInValidator", false, "SOLO PRUEBAS: lanza una excepción en la validación para comprobar que el servidor falla cerrado (rechaza a todos)."); DebugDropChunk = ((BaseUnityPlugin)this).Config.Bind<bool>("3. Depuración", "debugDropChunk", false, new ConfigDescription("SOLO PRUEBAS: el cliente omite el último trozo del manifiesto para comprobar el rechazo por manifiesto incompleto (con true el servidor te rechaza).", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Browsable = false } })); string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); Texts.LoadOverrides(directoryName); AdmissionCore.Init(Log); PolicyManager.Init(Log); ManifestBuilder.StartHashing(Log); Log.LogInfo((object)("vsm.guard 0.1.4 | Valheim " + GameConstants.GameVersionString + " | red " + GameConstants.NetworkVersion + " | headless=" + Headless.IsHeadless)); _harmony = new Harmony("vsm.guard"); PatchUtil.PatchAllSafely(Log, _harmony, Assembly.GetExecutingAssembly()); if (PatchUtil.IsDegraded) { Log.LogError((object)"vsm.guard: hay parches sin aplicar; el servidor rechazará a todos los clientes hasta que se corrija (ver arriba)."); } } private void Start() { if (Headless.IsHeadless) { PolicyManager.EnsureLoaded(HashMode.Value); } } private void Update() { PolicyManager.Tick(HashMode.Value); AdmissionCore.Tick(); } private void OnDestroy() { PolicyManager.Dispose(); if (_harmony != null) { _harmony.UnpatchSelf(); } } } public static class MyPluginInfo { public const string PLUGIN_GUID = "vsm.guard"; public const string PLUGIN_NAME = "MEL Guard"; public const string PLUGIN_VERSION = "0.1.4"; } } namespace VSM.Guard.Admission { public static class AdmissionCore { private sealed class RefEq : IEqualityComparer<ZRpc> { public bool Equals(ZRpc a, ZRpc b) { return a == b; } public int GetHashCode(ZRpc o) { return RuntimeHelpers.GetHashCode(o); } } public const int Protocol = 1; public const string RpcHello = "VSM_Guard_Hello"; public const string RpcManifest = "VSM_Guard_Manifest"; public const string RpcReject = "VSM_Guard_Reject"; private static readonly Dictionary<ZRpc, PeerState> s_states = new Dictionary<ZRpc, PeerState>(new RefEq()); private static ManualLogSource s_log; private static DateTime s_lastSweep = DateTime.UtcNow; private static int s_generation; private static bool s_helloReceived; private static byte[] s_clientNonce; private static long s_serverPolicyVersion; private static string s_serverGuardVersion = string.Empty; private static string s_pendingReason; private static DateTime s_pendingReasonTime; public static int StateCount => s_states.Count; public static bool ClientHelloReceived => s_helloReceived; public static void Init(ManualLogSource log) { s_log = log; } private static ValidatorSettings Settings() { return new ValidatorSettings { UnknownMods = GuardPlugin.UnknownMods.Value, HashMode = GuardPlugin.HashMode.Value, EnforcePatchersOverride = GuardPlugin.EnforcePatchers.Value, OwnGuid = "vsm.guard", OwnVersion = "0.1.4" }; } public static void OnNewConnection(ZNet znet, ZNetPeer peer) { if (peer != null && peer.m_rpc != null) { if (znet.IsServer()) { s_states[peer.m_rpc] = new PeerState(); peer.m_rpc.Register<ZPackage>("VSM_Guard_Manifest", (Action<ZRpc, ZPackage>)OnManifestChunk); PolicyManager.EnsureLoaded(GuardPlugin.HashMode.Value); } else { s_generation++; s_helloReceived = false; s_clientNonce = null; peer.m_rpc.Register<ZPackage>("VSM_Guard_Hello", (Action<ZRpc, ZPackage>)OnHello); peer.m_rpc.Register<ZPackage>("VSM_Guard_Reject", (Action<ZRpc, ZPackage>)OnReject); } } } public static void OnDisconnect(ZNetPeer peer) { if (peer != null && peer.m_rpc != null) { s_states.Remove(peer.m_rpc); } } public static void Tick() { if ((DateTime.UtcNow - s_lastSweep).TotalSeconds < 10.0) { return; } s_lastSweep = DateTime.UtcNow; List<ZRpc> list = null; foreach (KeyValuePair<ZRpc, PeerState> s_state in s_states) { bool flag = false; try { flag = s_state.Key.IsConnected(); } catch (Exception) { flag = false; } if (!flag && s_state.Value.AgeSeconds > 60.0) { (list ?? (list = new List<ZRpc>())).Add(s_state.Key); } } if (list == null) { return; } foreach (ZRpc item in list) { s_states.Remove(item); } } public static void OnServerHandshake(ZNet znet, ZRpc rpc) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown try { if (!s_states.TryGetValue(rpc, out var value)) { value = new PeerState(); s_states[rpc] = value; } ZNetPeer peer = znet.GetPeer(rpc); if (peer != null && peer.m_socket != null) { value.HostName = peer.m_socket.GetHostName() ?? string.Empty; } value.Nonce = ManifestBuilder.RandomBytes(16); Policy current = PolicyManager.Current; ZPackage val = new ZPackage(); val.Write(1); val.Write("0.1.4"); val.Write(value.Nonce); val.Write(current?.Version ?? 0); List<RequiredEntry> list = ((current != null) ? current.Required : new List<RequiredEntry>()); val.Write(list.Count); foreach (RequiredEntry item in list) { val.Write(item.Guid); val.Write(item.Version); val.Write((int)item.Mode); } List<PatternEntry> list2 = ((current != null) ? current.Forbidden : new List<PatternEntry>()); val.Write(list2.Count); foreach (PatternEntry item2 in list2) { val.Write(item2.Pattern); } rpc.Invoke("VSM_Guard_Hello", new object[1] { val }); value.HelloSent = true; } catch (Exception ex) { s_log.LogError((object)("vsm.guard: fallo enviando Hello: " + ex)); } } private static void OnManifestChunk(ZRpc rpc, ZPackage pkg) { //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Expected O, but got Unknown if (!s_states.TryGetValue(rpc, out var value)) { value = new PeerState(); s_states[rpc] = value; } try { if (value.Chunks == null) { value.Chunks = new Chunker.Assembler(); } if (!value.Chunks.TryAdd(pkg, out var complete, out var error)) { if (error != null) { Fail(value, new ReasonItem(ReasonCode.Protocol, "vsm.guard", "0.1.4", error)); } return; } ZPackage val = new ZPackage(complete); ZPackage pkg2 = val.ReadCompressedPackage(); string error2; Manifest manifest = Manifest.Read(pkg2, out error2); if (manifest == null) { Fail(value, new ReasonItem(ReasonCode.Protocol, "vsm.guard", "0.1.4", error2)); return; } value.ManifestReceived = true; value.Manifest = manifest; if (value.Nonce == null || !Manifest.ConstantTimeEquals(manifest.Hmac, manifest.ComputeHmac(value.Nonce))) { Fail(value, new ReasonItem(ReasonCode.Hmac)); return; } PolicyManager.EnsureLoaded(GuardPlugin.HashMode.Value); if (PolicyManager.SelfCheckFailed && GuardPlugin.SelfCheck.Value == SelfCheckMode.Strict) { value.Validated = false; value.Items = new List<ReasonItem>(PolicyManager.SelfCheckItems); return; } if (GuardPlugin.DebugThrowInValidator.Value) { throw new InvalidOperationException("debugThrowInValidator"); } List<ReasonItem> list = Validator.Run(PolicyManager.Current, manifest, Settings()); if (list.Count == 0) { value.Items.Clear(); value.Validated = true; s_log.LogInfo((object)Texts.Get("vsm_guard_admitted_log", value.HostName, "?", manifest.Plugins.Count)); } else if (GuardPlugin.AdminExempt.Value && (Object)(object)ZNet.instance != (Object)null && !string.IsNullOrEmpty(value.HostName) && ZNet.instance.IsAdmin(value.HostName)) { value.Items.Clear(); value.Validated = true; s_log.LogWarning((object)("vsm.guard: ADMIN EXENTO admitido con problemas: " + value.HostName + " — " + Texts.Summary(list))); } else { value.Validated = false; value.Items = list; } } catch (Exception ex) { s_log.LogError((object)("vsm.guard: excepción validando manifiesto (se rechaza): " + ex)); Fail(value, new ReasonItem(ReasonCode.Internal, "", "", "", ex.GetType().Name)); } } private static void Fail(PeerState state, ReasonItem item) { state.Validated = false; state.Items = new List<ReasonItem> { item }; } public static bool GateAllows(ZNet znet, ZRpc rpc) { if (!znet.IsServer()) { return true; } if (!s_states.TryGetValue(rpc, out var value)) { value = new PeerState(); s_states[rpc] = value; } if (PatchUtil.IsDegraded) { Reject(znet, rpc, value, new List<ReasonItem> { new ReasonItem(ReasonCode.ServerMisconfig, "", "", "", "parches Harmony incompletos: " + string.Join(" | ", PatchUtil.FailedTargets.ToArray())) }); return false; } if (value.Validated) { return true; } if (!value.Rejected) { List<ReasonItem> items = ((value.Items != null && value.Items.Count > 0) ? value.Items : new List<ReasonItem> { new ReasonItem(ReasonCode.NoManifest, "", "0.1.4") }); Reject(znet, rpc, value, items); } return false; } private static void Reject(ZNet znet, ZRpc rpc, PeerState state, List<ReasonItem> items) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown state.Rejected = true; long num = ((PolicyManager.Current != null) ? PolicyManager.Current.Version : 0); string text = Texts.Render(items, "0.1.4", num); if (text.Length > 8192) { text = text.Substring(0, 8192); } try { ZPackage val = new ZPackage(); val.Write(1); val.Write(ManifestBuilder.RandomBytes(16)); val.Write(num); val.Write("0.1.4"); int num2 = Math.Min(items.Count, 64); val.Write(num2); for (int i = 0; i < num2; i++) { ReasonItem reasonItem = items[i]; val.Write((int)reasonItem.Code); val.Write(Truncate(reasonItem.Guid, 256)); val.Write(Truncate(reasonItem.Expected, 256)); val.Write(Truncate(reasonItem.Actual, 256)); val.Write(Truncate(Texts.RenderItem(reasonItem, "0.1.4"), 512)); } val.Write(text); rpc.Invoke("VSM_Guard_Reject", new object[1] { val }); rpc.Invoke("Error", new object[1] { 3 }); try { rpc.GetSocket().Flush(); } catch (Exception) { } } catch (Exception ex2) { s_log.LogError((object)("vsm.guard: fallo enviando el rechazo: " + ex2.Message)); } s_log.LogWarning((object)Texts.Get("vsm_guard_rejected_log", state.HostName, items.Count + " problemas", Texts.Summary(items))); if ((Object)(object)GuardPlugin.Instance != (Object)null) { ((MonoBehaviour)GuardPlugin.Instance).StartCoroutine(DisconnectLater(znet, rpc, GuardPlugin.DisconnectDelaySeconds.Value)); } } private static IEnumerator DisconnectLater(ZNet znet, ZRpc rpc, float delay) { yield return (object)new WaitForSecondsRealtime(Mathf.Clamp(delay, 0.1f, 10f)); try { if (!((Object)(object)znet == (Object)null) && !((Object)(object)ZNet.instance != (Object)(object)znet)) { ZNetPeer peer = znet.GetPeer(rpc); if (peer != null && znet.m_peers.Contains(peer)) { znet.Disconnect(peer); } } } catch (Exception ex) { Exception ex2 = ex; s_log.LogWarning((object)("vsm.guard: fallo desconectando al peer rechazado: " + ex2.Message)); } } private static string Truncate(string s, int max) { if (s == null) { return string.Empty; } return (s.Length <= max) ? s : s.Substring(0, max); } private static void OnHello(ZRpc rpc, ZPackage pkg) { try { int num = pkg.ReadInt(); s_serverGuardVersion = pkg.ReadBoundedString(64) ?? string.Empty; s_clientNonce = pkg.ReadByteArray(); s_serverPolicyVersion = pkg.ReadLong(); int num2 = pkg.ReadInt(); List<string> list = new List<string>(); for (int i = 0; i < num2 && i < 512; i++) { string text = pkg.ReadBoundedString(256); string text2 = pkg.ReadBoundedString(128); int num3 = pkg.ReadInt(); if (text == null) { break; } string[] obj = new string[6] { text, " ", text2, " (", null, null }; VersionMode versionMode = (VersionMode)num3; obj[4] = versionMode.ToString(); obj[5] = ")"; list.Add(string.Concat(obj)); } s_helloReceived = true; if (GuardPlugin.Verbose.Value) { s_log.LogInfo((object)("vsm.guard: Hello del servidor (guard " + s_serverGuardVersion + ", protocolo " + num + ", política " + s_serverPolicyVersion + "): " + list.Count + " requeridos")); } if (num != 1) { s_log.LogWarning((object)("vsm.guard: el servidor usa protocolo " + num + " y este cliente " + 1 + "; se envía el manifiesto igualmente.")); } SendManifest(rpc); } catch (Exception ex) { s_log.LogError((object)("vsm.guard: fallo procesando Hello: " + ex)); } } private static void SendManifest(ZRpc rpc) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown Manifest manifest = ManifestBuilder.Build(s_clientNonce, "0.1.4"); ZPackage val = new ZPackage(); manifest.Write(val); ZPackage val2 = new ZPackage(); val2.WriteCompressed(val); byte[] array = val2.GetArray(); List<ZPackage> list = Chunker.Split(array, ManifestBuilder.RandomBytes(16)); for (int i = 0; i < list.Count; i++) { if (GuardPlugin.DebugDropChunk.Value && i == list.Count - 1) { s_log.LogWarning((object)"vsm.guard: debugDropChunk — se omite el último trozo del manifiesto"); continue; } rpc.Invoke("VSM_Guard_Manifest", new object[1] { list[i] }); } if (GuardPlugin.Verbose.Value) { s_log.LogInfo((object)("vsm.guard: manifiesto enviado (" + manifest.Plugins.Count + " plugins, " + array.Length + " bytes, " + list.Count + " trozo(s))")); } } public static bool OnClientHandshake(ZNet znet, ZRpc rpc) { if (znet.IsServer() || s_helloReceived || !GuardPlugin.ClientRequireGuardServer.Value) { return true; } s_log.LogWarning((object)"vsm.guard: el servidor no envió Hello (no tiene vsm.guard); se aborta la conexión por configuración del cliente."); SetPendingReason(Texts.Get("vsm_guard_server_vanilla")); ZNet.SetExternalError((ConnectionStatus)3); try { rpc.Invoke("Disconnect", Array.Empty<object>()); } catch (Exception) { } return false; } private static void OnReject(ZRpc rpc, ZPackage pkg) { try { pkg.ReadInt(); pkg.ReadByteArray(); long num = pkg.ReadLong(); string text = pkg.ReadBoundedString(64); int num2 = pkg.ReadInt(); for (int i = 0; i < num2 && i < 64; i++) { pkg.ReadInt(); pkg.ReadBoundedString(256); pkg.ReadBoundedString(256); pkg.ReadBoundedString(256); pkg.ReadBoundedString(512); } string text2 = pkg.ReadBoundedString(8192) ?? Texts.Get("vsm_guard_internal"); SetPendingReason(text2); ZNet.SetExternalError((ConnectionStatus)3); s_log.LogWarning((object)("vsm.guard: rechazado por el servidor (guard " + text + ", política " + num + "):\n" + text2)); } catch (Exception ex) { SetPendingReason(Texts.Get("vsm_guard_internal")); ZNet.SetExternalError((ConnectionStatus)3); s_log.LogError((object)("vsm.guard: fallo leyendo el rechazo: " + ex.Message)); } } private static void SetPendingReason(string text) { s_pendingReason = text; s_pendingReasonTime = DateTime.UtcNow; } public static bool TakePendingReason(out string text) { text = null; if (string.IsNullOrEmpty(s_pendingReason) || (DateTime.UtcNow - s_pendingReasonTime).TotalSeconds > 120.0) { s_pendingReason = null; return false; } text = s_pendingReason; s_pendingReason = null; return true; } public static IEnumerable<string> DumpLines() { yield return "vsm.guard 0.1.4 | protocolo " + 1 + " | juego " + GameConstants.GameVersionString + " | red " + GameConstants.NetworkVersion; yield return "Plugins cargados:"; foreach (PluginEntry p in ManifestBuilder.LoadedPlugins()) { yield return " " + p.Guid + " = " + p.Version + " | " + (string.IsNullOrEmpty(p.Sha256) ? "(sin hash)" : (p.Sha256.Substring(0, 12) + "…")) + " | " + p.Name; } List<string> depErrors = Chainloader.DependencyErrors; if (depErrors.Count > 0) { yield return "Errores de dependencias:"; foreach (string e in depErrors) { yield return " " + e; } } List<KeyValuePair<string, string>> patchers = ManifestBuilder.ListPatchers(); yield return "Patchers: " + ((patchers.Count == 0) ? "(ninguno)" : string.Join(", ", patchers.Select((KeyValuePair<string, string> keyValuePair) => keyValuePair.Key).ToArray())); if (PolicyManager.Current != null) { Policy p2 = PolicyManager.Current; yield return "Política v" + p2.Version + ": " + p2.Required.Count + " requeridos, " + p2.ClientOptional.Count + " opcionales, " + p2.Forbidden.Count + " prohibidos, " + p2.ServerOnly.Count + " solo servidor" + (PolicyManager.SelfCheckFailed ? " — AUTOCOMPROBACIÓN FALLIDA" : string.Empty); foreach (ReasonItem item in PolicyManager.SelfCheckItems) { yield return " ! " + Texts.RenderItem(item, "0.1.4"); } } yield return "Conexiones en seguimiento: " + s_states.Count + " | Hello recibido (cliente): " + s_helloReceived; if (PatchUtil.IsDegraded) { yield return "PARCHES FALLIDOS: " + string.Join(" | ", PatchUtil.FailedTargets.ToArray()); } } } public static class Chunker { public sealed class Assembler { private byte[] _id; private byte[][] _parts; private int _count; private int _total; private int _received; public bool TryAdd(ZPackage pkg, out byte[] complete, out string error) { complete = null; error = null; if (pkg == null || pkg.Size() > 215040) { Reset(); error = "sobre demasiado grande"; return false; } int num = pkg.ReadInt(); if (num != 1) { Reset(); error = "protocolo de troceado " + num; return false; } byte[] array = pkg.ReadByteArray(); int num2 = pkg.ReadInt(); int num3 = pkg.ReadInt(); int num4 = pkg.ReadInt(); byte[] array2 = pkg.ReadByteArray(); if (array == null || array.Length != 16 || num3 < 1 || num3 > 8 || num2 < 0 || num2 >= num3 || num4 < 0 || num4 > 1048576 || array2 == null || array2.Length > 204800) { Reset(); error = "cabecera de trozo inválida"; return false; } if (_parts == null || !SameId(array) || _count != num3 || _total != num4) { _id = array; _count = num3; _total = num4; _parts = new byte[num3][]; _received = 0; } if (_parts[num2] == null) { _received++; } _parts[num2] = array2; if (_received < _count) { return false; } int num5 = 0; for (int i = 0; i < _count; i++) { num5 += _parts[i].Length; } if (num5 != _total) { Reset(); error = "tamaño total incoherente"; return false; } byte[] array3 = new byte[_total]; int num6 = 0; for (int j = 0; j < _count; j++) { Buffer.BlockCopy(_parts[j], 0, array3, num6, _parts[j].Length); num6 += _parts[j].Length; } Reset(); complete = array3; return true; } private bool SameId(byte[] id) { if (_id == null || _id.Length != id.Length) { return false; } for (int i = 0; i < id.Length; i++) { if (_id[i] != id[i]) { return false; } } return true; } public void Reset() { _id = null; _parts = null; _count = 0; _total = 0; _received = 0; } } public const int Protocol = 1; public const int ChunkSize = 204800; public const int MaxChunks = 8; public const int MaxTotalBytes = 1048576; public const int MaxEnvelopeBytes = 215040; public static List<ZPackage> Split(byte[] payload, byte[] id) { //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected O, but got Unknown if (payload == null) { payload = new byte[0]; } if (payload.Length > 1048576) { throw new InvalidOperationException("carga demasiado grande: " + payload.Length + " bytes"); } int num = Math.Max(1, (payload.Length + 204800 - 1) / 204800); List<ZPackage> list = new List<ZPackage>(num); for (int i = 0; i < num; i++) { int num2 = i * 204800; int num3 = Math.Min(204800, payload.Length - num2); byte[] array = new byte[Math.Max(0, num3)]; if (num3 > 0) { Buffer.BlockCopy(payload, num2, array, 0, num3); } ZPackage val = new ZPackage(); val.Write(1); val.Write(id); val.Write(i); val.Write(num); val.Write(payload.Length); val.Write(array); list.Add(val); } return list; } } public sealed class PluginEntry { public string Guid = string.Empty; public string Name = string.Empty; public string Version = string.Empty; public string Sha256 = string.Empty; } public sealed class PatcherEntry { public string RelPath = string.Empty; public string Sha256 = string.Empty; } public sealed class Manifest { public const int Format = 1; public const int MaxPlugins = 512; public const int MaxPatchers = 128; public const int MaxDependencyErrors = 64; public const int MaxString = 1024; public string GameVersion = string.Empty; public uint NetworkVersion; public string GuardVersion = string.Empty; public List<PluginEntry> Plugins = new List<PluginEntry>(); public List<string> DependencyErrors = new List<string>(); public List<PatcherEntry> Patchers = new List<PatcherEntry>(); public byte[] Hmac = new byte[0]; public string CanonicalText() { List<string> list = new List<string>(); list.Add("G:" + GameVersion + "|" + NetworkVersion + "|" + GuardVersion); foreach (PluginEntry plugin in Plugins) { list.Add("M:" + plugin.Guid + "=" + plugin.Version + "=" + plugin.Sha256); } foreach (PatcherEntry patcher in Patchers) { list.Add("P:" + patcher.RelPath + "=" + patcher.Sha256); } foreach (string dependencyError in DependencyErrors) { list.Add("D:" + dependencyError); } list.Sort(StringComparer.Ordinal); return string.Join("\n", list.ToArray()); } public byte[] ComputeHmac(byte[] nonce) { using HMACSHA256 hMACSHA = new HMACSHA256(nonce ?? new byte[0]); return hMACSHA.ComputeHash(Encoding.UTF8.GetBytes(CanonicalText())); } public static bool ConstantTimeEquals(byte[] a, byte[] b) { if (a == null || b == null || a.Length != b.Length) { return false; } int num = 0; for (int i = 0; i < a.Length; i++) { num |= a[i] ^ b[i]; } return num == 0; } public void Write(ZPackage pkg) { pkg.Write(1); pkg.Write(GameVersion ?? string.Empty); pkg.Write(NetworkVersion); pkg.Write(GuardVersion ?? string.Empty); pkg.Write(Hmac ?? new byte[0]); pkg.Write(Plugins.Count); foreach (PluginEntry plugin in Plugins) { pkg.Write(plugin.Guid ?? string.Empty); pkg.Write(plugin.Name ?? string.Empty); pkg.Write(plugin.Version ?? string.Empty); pkg.Write(plugin.Sha256 ?? string.Empty); } pkg.Write(DependencyErrors.Count); foreach (string dependencyError in DependencyErrors) { pkg.Write(dependencyError ?? string.Empty); } pkg.Write(Patchers.Count); foreach (PatcherEntry patcher in Patchers) { pkg.Write(patcher.RelPath ?? string.Empty); pkg.Write(patcher.Sha256 ?? string.Empty); } } public static Manifest Read(ZPackage pkg, out string error) { error = null; Manifest manifest = new Manifest(); int num = pkg.ReadInt(); if (num != 1) { error = "formato " + num + " (esperado " + 1 + ")"; return null; } manifest.GameVersion = pkg.ReadBoundedString(64); manifest.NetworkVersion = pkg.ReadUInt(); manifest.GuardVersion = pkg.ReadBoundedString(64); manifest.Hmac = pkg.ReadByteArray(); if (manifest.GameVersion == null || manifest.GuardVersion == null || manifest.Hmac == null || manifest.Hmac.Length > 64) { error = "cabecera inválida"; return null; } int num2 = pkg.ReadInt(); if (num2 < 0 || num2 > 512) { error = "número de plugins inválido: " + num2; return null; } for (int i = 0; i < num2; i++) { PluginEntry pluginEntry = new PluginEntry { Guid = pkg.ReadBoundedString(1024), Name = pkg.ReadBoundedString(1024), Version = pkg.ReadBoundedString(128), Sha256 = pkg.ReadBoundedString(128) }; if (pluginEntry.Guid == null || pluginEntry.Name == null || pluginEntry.Version == null || pluginEntry.Sha256 == null) { error = "entrada de plugin inválida"; return null; } manifest.Plugins.Add(pluginEntry); } int num3 = pkg.ReadInt(); if (num3 < 0 || num3 > 64) { error = "número de errores de dependencia inválido"; return null; } for (int j = 0; j < num3; j++) { string text = pkg.ReadBoundedString(2048); if (text == null) { error = "error de dependencia inválido"; return null; } manifest.DependencyErrors.Add(text); } int num4 = pkg.ReadInt(); if (num4 < 0 || num4 > 128) { error = "número de patchers inválido"; return null; } for (int k = 0; k < num4; k++) { PatcherEntry patcherEntry = new PatcherEntry { RelPath = pkg.ReadBoundedString(1024), Sha256 = pkg.ReadBoundedString(128) }; if (patcherEntry.RelPath == null || patcherEntry.Sha256 == null) { error = "entrada de patcher inválida"; return null; } manifest.Patchers.Add(patcherEntry); } return manifest; } } public static class ManifestBuilder { private static readonly object s_lock = new object(); private static readonly Dictionary<string, string> s_hashes = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); private static Task s_hashTask; private static ManualLogSource s_log; public static void StartHashing(ManualLogSource log) { s_log = log; List<string> files = new List<string>(); foreach (PluginInfo value2 in Chainloader.PluginInfos.Values) { if (value2 != null && !string.IsNullOrEmpty(value2.Location)) { files.Add(value2.Location); } } files.AddRange(from p in ListPatchers() select p.Key); s_hashTask = Task.Run(delegate { foreach (string item in files) { string value = Sha256File(item); lock (s_lock) { s_hashes[item] = value; } } }); } public static void WaitForHashes(int milliseconds) { try { s_hashTask?.Wait(milliseconds); } catch (Exception ex) { if (s_log != null) { s_log.LogWarning((object)("vsm.guard: fallo calculando hashes: " + ex.Message)); } } } public static string GetHash(string file) { if (string.IsNullOrEmpty(file)) { return string.Empty; } lock (s_lock) { if (s_hashes.TryGetValue(file, out var value) && !string.IsNullOrEmpty(value)) { return value; } } string text = Sha256File(file); lock (s_lock) { s_hashes[file] = text; } return text; } public static string Sha256File(string path) { try { using SHA256 sHA = SHA256.Create(); using FileStream inputStream = File.OpenRead(path); return BitConverter.ToString(sHA.ComputeHash(inputStream)).Replace("-", string.Empty).ToLowerInvariant(); } catch (Exception) { return string.Empty; } } public static List<PluginEntry> LoadedPlugins() { List<PluginEntry> list = new List<PluginEntry>(); bool flag = ChainloaderLoaded(); foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos) { PluginInfo value = pluginInfo.Value; if (value != null && value.Metadata != null && (!flag || !((Object)(object)value.Instance == (Object)null))) { list.Add(new PluginEntry { Guid = (value.Metadata.GUID ?? pluginInfo.Key), Name = (value.Metadata.Name ?? string.Empty), Version = VersionString(value.Metadata), Sha256 = GetHash(value.Location) }); } } list.Sort((PluginEntry a, PluginEntry b) => string.CompareOrdinal(a.Guid, b.Guid)); return list; } public static string VersionString(BepInPlugin metadata) { if (metadata == null || metadata.Version == null) { return string.Empty; } string text = metadata.Version.ToString(); string versionExtra = metadata.VersionExtra; return string.IsNullOrEmpty(versionExtra) ? text : (text + versionExtra); } private static bool ChainloaderLoaded() { try { FieldInfo field = typeof(Chainloader).GetField("_loaded", BindingFlags.Static | BindingFlags.NonPublic); return field == null || (bool)field.GetValue(null); } catch (Exception) { return true; } } public static List<KeyValuePair<string, string>> ListPatchers() { List<KeyValuePair<string, string>> list = new List<KeyValuePair<string, string>>(); try { string patcherPluginPath = Paths.PatcherPluginPath; if (string.IsNullOrEmpty(patcherPluginPath) || !Directory.Exists(patcherPluginPath)) { return list; } string[] files = Directory.GetFiles(patcherPluginPath, "*.dll", SearchOption.AllDirectories); foreach (string text in files) { string key = text.Substring(patcherPluginPath.Length).TrimStart('\\', '/').Replace('\\', '/') .ToLowerInvariant(); list.Add(new KeyValuePair<string, string>(key, text)); } list.Sort((KeyValuePair<string, string> a, KeyValuePair<string, string> b) => string.CompareOrdinal(a.Key, b.Key)); } catch (Exception) { } return list; } public static Manifest Build(byte[] nonce, string guardVersion) { WaitForHashes(2000); Manifest manifest = new Manifest { GameVersion = GameConstants.GameVersionString, NetworkVersion = GameConstants.NetworkVersion, GuardVersion = (guardVersion ?? string.Empty), Plugins = LoadedPlugins() }; foreach (string dependencyError in Chainloader.DependencyErrors) { if (!string.IsNullOrEmpty(dependencyError)) { manifest.DependencyErrors.Add((dependencyError.Length > 2000) ? dependencyError.Substring(0, 2000) : dependencyError); } } foreach (KeyValuePair<string, string> item in ListPatchers()) { manifest.Patchers.Add(new PatcherEntry { RelPath = item.Key, Sha256 = GetHash(item.Value) }); } manifest.Hmac = manifest.ComputeHmac(nonce); return manifest; } public static byte[] RandomBytes(int count) { byte[] array = new byte[count]; using (RNGCryptoServiceProvider rNGCryptoServiceProvider = new RNGCryptoServiceProvider()) { rNGCryptoServiceProvider.GetBytes(array); } return array; } } public sealed class PeerState { public DateTime Created = DateTime.UtcNow; public byte[] Nonce; public bool HelloSent; public string HostName = string.Empty; public Chunker.Assembler Chunks; public bool ManifestReceived; public Manifest Manifest; public bool Validated; public bool Rejected; public List<ReasonItem> Items = new List<ReasonItem>(); public double AgeSeconds => (DateTime.UtcNow - Created).TotalSeconds; } public enum ReasonCode { Missing = 1, Version, Hash, Forbidden, Unknown, ServerOnly, FailedLoad, NoManifest, Protocol, Hmac, Internal, ServerMisconfig, Patcher } public sealed class ReasonItem { public ReasonCode Code; public string Guid = string.Empty; public string Expected = string.Empty; public string Actual = string.Empty; public string Note = string.Empty; public ReasonItem(ReasonCode code, string guid = "", string expected = "", string actual = "", string note = "") { Code = code; Guid = guid ?? string.Empty; Expected = expected ?? string.Empty; Actual = actual ?? string.Empty; Note = note ?? string.Empty; } } public enum VersionMode { Exact, MinorCompatible, AtLeast, Ignore } public sealed class RequiredEntry { public string Guid = string.Empty; public string Version = string.Empty; public VersionMode Mode = VersionMode.Exact; public HashSet<string> Hashes = new HashSet<string>(StringComparer.OrdinalIgnoreCase); public string Note = string.Empty; } public sealed class PatternEntry { public string Pattern = string.Empty; public string Note = string.Empty; public bool Matches(string guid) { if (string.IsNullOrEmpty(Pattern) || guid == null) { return false; } if (Pattern.EndsWith("*", StringComparison.Ordinal)) { return guid.StartsWith(Pattern.Substring(0, Pattern.Length - 1), StringComparison.OrdinalIgnoreCase); } return string.Equals(Pattern, guid, StringComparison.OrdinalIgnoreCase); } } public sealed class Policy { public long Version = 1L; public List<RequiredEntry> Required = new List<RequiredEntry>(); public List<PatternEntry> ClientOptional = new List<PatternEntry>(); public List<PatternEntry> Forbidden = new List<PatternEntry>(); public List<PatternEntry> ServerOnly = new List<PatternEntry>(); public bool EnforcePatchers; public List<PatternEntry> PatchersAllowed = new List<PatternEntry>(); public static readonly string[] KnownClientOnly = new string[4] { "_shudnal.ConfigurationManager", "com.bepis.bepinex.configurationmanager", "vsm.diag", "vsm.connect" }; public static readonly KeyValuePair<string, string>[] KnownServerOnly = new KeyValuePair<string, string>[3] { new KeyValuePair<string, string>("Azumatt.A2SEnabler", "hosting (ValHost): responde a la lista de servidores (A2S)"), new KeyValuePair<string, string>("Azumatt.MaxPlayerCount", "hosting (ValHost): límite de jugadores del plan"), new KeyValuePair<string, string>("valhost.*", "hosting (ValHost): plugin propio del panel (valhost.plugin)") }; public static readonly KeyValuePair<string, string>[] DefaultForbidden = new KeyValuePair<string, string>[19] { new KeyValuePair<string, string>("valheim.buildcamera", "Stonaar-ValheimBuildCamera: sustituido por vsm.buildcam"), new KeyValuePair<string, string>("lesly.valheim.buildcamera", "BuildCamera antiguo: sustituido por vsm.buildcam"), new KeyValuePair<string, string>("Azumatt.BuildCameraCHE", "BuildCameraCHE: compite con vsm.buildcam"), new KeyValuePair<string, string>("shudnal.ExtraSlots", "ranuras: compite con vsm.slots"), new KeyValuePair<string, string>("Azumatt.AzuExtendedPlayerInventory", "ranuras: compite con vsm.slots"), new KeyValuePair<string, string>("randyknapp.mods.equipmentandquickslots", "ranuras: compite con vsm.slots"), new KeyValuePair<string, string>("aedenthorn.ExtendedPlayerInventory", "ranuras: compite con vsm.slots"), new KeyValuePair<string, string>("com.bruce.valheim.comfyquickslots", "ranuras: compite con vsm.slots"), new KeyValuePair<string, string>("shudnal.ExtraSlotsCustomSlots", "ranuras: compite con vsm.slots"), new KeyValuePair<string, string>("moreslots", "ranuras: compite con vsm.slots"), new KeyValuePair<string, string>("randyknapp.mods.auga", "interfaz Auga: rehace el inventario, choca con vsm.slots"), new KeyValuePair<string, string>("toombe.EquipMultipleUtilityItemsUpdate", "varios cinturones a la vez: rompe las ranuras de vsm.slots"), new KeyValuePair<string, string>("aedenthorn.EquipMultipleUtilityItems", "varios cinturones a la vez: rompe las ranuras de vsm.slots"), new KeyValuePair<string, string>("advize.Armoire", "transfiguración: compite con la de vsm.slots"), new KeyValuePair<string, string>("Transmog", "transfiguración (Alpus): compite con la de vsm.slots"), new KeyValuePair<string, string>("org.bepinex.plugins.valheim_plus", "ValheimPlus: cambia drops, cámara e inventario"), new KeyValuePair<string, string>("CW_Jesse.BetterNetworking", "red: compite con vsm.net"), new KeyValuePair<string, string>("org.bepinex.plugins.network", "red (Smoothbrain Network): compite con vsm.net"), new KeyValuePair<string, string>("Nosferatu.SmoothServer", "red: compite con vsm.net") }; public RequiredEntry FindRequired(string guid) { foreach (RequiredEntry item in Required) { if (string.Equals(item.Guid, guid, StringComparison.OrdinalIgnoreCase)) { return item; } } return null; } public PatternEntry FirstMatch(List<PatternEntry> list, string guid) { foreach (PatternEntry item in list) { if (item.Matches(guid)) { return item; } } return null; } public static Policy Parse(string text, List<string> errors) { Policy policy = new Policy(); if (text == null) { return policy; } string text2 = string.Empty; string[] array = text.Replace("\r\n", "\n").Split(new char[1] { '\n' }); for (int i = 0; i < array.Length; i++) { string text3 = array[i]; string text4 = StripComment(text3).Trim(); if (text4.Length == 0) { continue; } if (text4.StartsWith("[", StringComparison.Ordinal) && text4.EndsWith("]", StringComparison.Ordinal)) { text2 = text4.Substring(1, text4.Length - 2).Trim().ToLowerInvariant(); continue; } int num = text4.IndexOf('='); if (num <= 0) { errors.Add("línea " + (i + 1) + ": falta '=' → " + text3.Trim()); continue; } string key = text4.Substring(0, num).Trim(); string text5 = text4.Substring(num + 1).Trim(); string[] array2 = (from f in text5.Split(new char[1] { '|' }) select f.Trim()).ToArray(); switch (text2) { case "guard": { if (key.Equals("policyVersion", StringComparison.OrdinalIgnoreCase) && long.TryParse(text5, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) { policy.Version = result; } break; } case "required": { RequiredEntry requiredEntry = new RequiredEntry { Guid = key }; requiredEntry.Version = ((array2.Length != 0) ? array2[0] : string.Empty); if (array2.Length > 1 && array2[1].Length > 0 && !TryParseMode(array2[1], out requiredEntry.Mode)) { errors.Add("línea " + (i + 1) + ": modo desconocido '" + array2[1] + "' (Exact|MinorCompatible|AtLeast|Ignore)"); } if (array2.Length > 2 && array2[2].Length > 0) { foreach (string item in from x in array2[2].Split(new char[1] { ',' }) select x.Trim() into x where x.Length > 0 select x) { requiredEntry.Hashes.Add(item.ToLowerInvariant()); } } requiredEntry.Note = ((array2.Length > 3) ? array2[3] : string.Empty); if (policy.FindRequired(key) != null) { errors.Add("línea " + (i + 1) + ": '" + key + "' duplicado en [required] (gana la última)"); policy.Required.RemoveAll((RequiredEntry x) => string.Equals(x.Guid, key, StringComparison.OrdinalIgnoreCase)); } policy.Required.Add(requiredEntry); break; } case "clientoptional": policy.ClientOptional.Add(new PatternEntry { Pattern = key, Note = text5 }); break; case "forbidden": policy.Forbidden.Add(new PatternEntry { Pattern = key, Note = text5 }); break; case "serveronly": policy.ServerOnly.Add(new PatternEntry { Pattern = key, Note = text5 }); break; case "patchers": if (key.Equals("enforce", StringComparison.OrdinalIgnoreCase)) { policy.EnforcePatchers = text5.Equals("true", StringComparison.OrdinalIgnoreCase); break; } policy.PatchersAllowed.Add(new PatternEntry { Pattern = key.Replace('\\', '/').ToLowerInvariant(), Note = text5 }); break; default: errors.Add("línea " + (i + 1) + ": sección desconocida '" + text2 + "'"); break; } } if (policy.Required.Count == 0) { errors.Add("la sección [required] está vacía: se rechazaría a todo el mundo salvo que unknownMods=warn"); } return policy; } private static string StripComment(string line) { int num = line.IndexOf('#'); int num2 = line.IndexOf(';'); int num3 = -1; if (num >= 0) { num3 = num; } if (num2 >= 0 && (num3 < 0 || num2 < num3)) { num3 = num2; } return (num3 >= 0) ? line.Substring(0, num3) : line; } public static bool TryParseMode(string s, out VersionMode mode) { switch ((s ?? string.Empty).Trim().ToLowerInvariant()) { case "exact": mode = VersionMode.Exact; return true; case "minorcompatible": mode = VersionMode.MinorCompatible; return true; case "atleast": mode = VersionMode.AtLeast; return true; case "ignore": mode = VersionMode.Ignore; return true; default: mode = VersionMode.Exact; return false; } } public static Version ParseVersion(string s) { if (string.IsNullOrEmpty(s)) { return null; } string text = s.Trim(); int num = text.IndexOfAny(new char[3] { '-', '+', ' ' }); if (num > 0) { text = text.Substring(0, num); } string[] array = text.Split(new char[1] { '.' }); int[] array2 = new int[4]; if (array.Length == 0 || array.Length > 4) { return null; } for (int i = 0; i < array.Length; i++) { if (!int.TryParse(array[i], NumberStyles.Integer, CultureInfo.InvariantCulture, out array2[i]) || array2[i] < 0) { return null; } } return new Version(array2[0], array2[1], array2[2], array2[3]); } public static bool VersionSatisfies(string actual, string expected, VersionMode mode) { if (mode == VersionMode.Ignore) { return true; } Version version = ParseVersion(actual); Version version2 = ParseVersion(expected); if (version == null || version2 == null) { return string.Equals((actual ?? string.Empty).Trim(), (expected ?? string.Empty).Trim(), StringComparison.OrdinalIgnoreCase); } return mode switch { VersionMode.Exact => version == version2 && SuffixEquals(actual, expected), VersionMode.MinorCompatible => version.Major == version2.Major && version.Minor == version2.Minor && version >= version2, VersionMode.AtLeast => version >= version2, _ => false, }; } private static bool SuffixEquals(string a, string b) { return string.Equals(Suffix(a), Suffix(b), StringComparison.OrdinalIgnoreCase); } private static string Suffix(string s) { if (string.IsNullOrEmpty(s)) { return string.Empty; } int num = s.IndexOfAny(new char[2] { '-', '+' }); return (num >= 0) ? s.Substring(num) : string.Empty; } public string Serialize() { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("# vsm.guard.policy.cfg — política de admisión del servidor (se recarga sola al guardar; solo afecta a conexiones nuevas)."); stringBuilder.AppendLine("# [required] guid = versión | modo (Exact|MinorCompatible|AtLeast|Ignore) | sha256[,sha256...] | nota"); stringBuilder.AppendLine("# [clientOptional] patrón = nota -> el cliente puede llevarlo; el servidor no lo necesita ('prefijo*' permitido)"); stringBuilder.AppendLine("# [forbidden] patrón = nota -> rechazo aunque otra regla lo permitiera"); stringBuilder.AppendLine("# [serverOnly] guid = nota -> solo lo ejecuta el servidor; un cliente que lo lleve es rechazado"); stringBuilder.AppendLine("# Un mod del cliente que no esté en ninguna lista se trata según unknownMods (vsm.guard.cfg)."); stringBuilder.AppendLine(); stringBuilder.AppendLine("[guard]"); stringBuilder.AppendLine("policyVersion = " + Version.ToString(CultureInfo.InvariantCulture)); stringBuilder.AppendLine(); stringBuilder.AppendLine("[required]"); foreach (RequiredEntry item in Required) { stringBuilder.AppendLine(item.Guid + " = " + item.Version + " | " + item.Mode.ToString() + " | " + string.Join(",", item.Hashes.ToArray()) + " | " + item.Note); } stringBuilder.AppendLine(); stringBuilder.AppendLine("[clientOptional]"); foreach (PatternEntry item2 in ClientOptional) { stringBuilder.AppendLine(item2.Pattern + " = " + item2.Note); } stringBuilder.AppendLine(); stringBuilder.AppendLine("[forbidden]"); foreach (PatternEntry item3 in Forbidden) { stringBuilder.AppendLine(item3.Pattern + " = " + item3.Note); } stringBuilder.AppendLine(); stringBuilder.AppendLine("[serverOnly]"); foreach (PatternEntry item4 in ServerOnly) { stringBuilder.AppendLine(item4.Pattern + " = " + item4.Note); } stringBuilder.AppendLine(); stringBuilder.AppendLine("[patchers]"); stringBuilder.AppendLine("enforce = " + (EnforcePatchers ? "true" : "false")); foreach (PatternEntry item5 in PatchersAllowed) { stringBuilder.AppendLine(item5.Pattern + " = " + item5.Note); } return stringBuilder.ToString(); } private static bool MatchesAny(IEnumerable<string> patterns, string guid) { return patterns.Any((string k) => new PatternEntry { Pattern = k }.Matches(guid)); } public static Policy AutoPopulate(List<PluginEntry> serverPlugins) { Policy policy = new Policy { Version = 1L }; foreach (PluginEntry serverPlugin in serverPlugins) { if (!MatchesAny(KnownClientOnly, serverPlugin.Guid) && !MatchesAny(KnownServerOnly.Select((KeyValuePair<string, string> k) => k.Key), serverPlugin.Guid)) { RequiredEntry requiredEntry = new RequiredEntry { Guid = serverPlugin.Guid, Version = serverPlugin.Version, Mode = VersionMode.Exact, Note = serverPlugin.Name }; if (!string.IsNullOrEmpty(serverPlugin.Sha256)) { requiredEntry.Hashes.Add(serverPlugin.Sha256); } policy.Required.Add(requiredEntry); } } string[] knownClientOnly = KnownClientOnly; foreach (string pattern in knownClientOnly) { policy.ClientOptional.Add(new PatternEntry { Pattern = pattern, Note = "solo cliente (opcional)" }); } KeyValuePair<string, string>[] knownServerOnly = KnownServerOnly; for (int num2 = 0; num2 < knownServerOnly.Length; num2++) { KeyValuePair<string, string> keyValuePair = knownServerOnly[num2]; policy.ServerOnly.Add(new PatternEntry { Pattern = keyValuePair.Key, Note = keyValuePair.Value }); } KeyValuePair<string, string>[] defaultForbidden = DefaultForbidden; for (int num3 = 0; num3 < defaultForbidden.Length; num3++) { KeyValuePair<string, string> keyValuePair2 = defaultForbidden[num3]; policy.Forbidden.Add(new PatternEntry { Pattern = keyValuePair2.Key, Note = keyValuePair2.Value }); } return policy; } } public static class PolicyManager { public const string FileName = "vsm.guard.policy.cfg"; private static ManualLogSource s_log; private static FileSystemWatcher s_watcher; private static int s_dirty; private static DateTime s_dirtySince; private static bool s_loadedOnce; public static Policy Current { get; private set; } public static List<ReasonItem> SelfCheckItems { get; private set; } = new List<ReasonItem>(); public static bool SelfCheckFailed => SelfCheckItems.Count > 0; public static string LastError { get; private set; } = string.Empty; public static string PathToFile => Path.Combine(Paths.ConfigPath, "vsm.guard.policy.cfg"); public static void Init(ManualLogSource log) { s_log = log; } public static void EnsureLoaded(HashMode hashMode) { if (!s_loadedOnce) { s_loadedOnce = true; if (!File.Exists(PathToFile)) { AutoCreate(); } Reload(hashMode); StartWatcher(); } } private static void AutoCreate() { try { ManifestBuilder.WaitForHashes(5000); List<PluginEntry> serverPlugins = ManifestBuilder.LoadedPlugins(); Policy policy = Policy.AutoPopulate(serverPlugins); File.WriteAllText(PathToFile, policy.Serialize(), new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)); if (s_log != null) { s_log.LogWarning((object)Texts.Get("vsm_guard_policy_created", PathToFile, policy.Required.Count)); } } catch (Exception ex) { LastError = ex.Message; if (s_log != null) { s_log.LogError((object)("vsm.guard: no se pudo crear la política: " + ex.Message)); } } } public static void Reload(HashMode hashMode) { try { string text = ReadStable(PathToFile); if (text == null) { LastError = "no se pudo leer " + PathToFile; if (s_log != null) { s_log.LogError((object)Texts.Get("vsm_guard_policy_error", LastError)); } return; } List<string> list = new List<string>(); Policy policy = Policy.Parse(text, list); foreach (string item in list) { if (s_log != null) { s_log.LogWarning((object)("vsm.guard: política: " + item)); } } Current = policy; LastError = string.Empty; RunSelfCheck(hashMode); if (s_log != null) { s_log.LogInfo((object)Texts.Get("vsm_guard_policy_reloaded", policy.Version, policy.Required.Count, policy.ClientOptional.Count, policy.Forbidden.Count, policy.ServerOnly.Count)); } } catch (Exception ex) { LastError = ex.Message; if (s_log != null) { s_log.LogError((object)Texts.Get("vsm_guard_policy_error", ex.Message)); } } } private static void RunSelfCheck(HashMode hashMode) { ManifestBuilder.WaitForHashes(5000); SelfCheckItems = Validator.SelfCheck(Current, ManifestBuilder.LoadedPlugins(), hashMode); if (SelfCheckItems.Count <= 0 || s_log == null) { return; } foreach (ReasonItem selfCheckItem in SelfCheckItems) { s_log.LogError((object)("vsm.guard: AUTOCOMPROBACIÓN: " + selfCheckItem.Guid + " esperado " + selfCheckItem.Expected + " actual " + selfCheckItem.Actual + " " + selfCheckItem.Note)); } } private static string ReadStable(string path) { string text = null; for (int i = 0; i < 6; i++) { try { string text2 = File.ReadAllText(path, Encoding.UTF8); if (text2 == text) { return text2; } text = text2; } catch (IOException) { } Thread.Sleep(60); } return text; } private static void StartWatcher() { try { if (s_watcher == null) { s_watcher = new FileSystemWatcher(Paths.ConfigPath, "vsm.guard.policy.cfg") { NotifyFilter = (NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite | NotifyFilters.CreationTime), EnableRaisingEvents = true }; s_watcher.Changed += MarkDirty; s_watcher.Created += MarkDirty; s_watcher.Renamed += delegate(object s, RenamedEventArgs e) { MarkDirty(s, e); }; } } catch (Exception ex) { if (s_log != null) { s_log.LogWarning((object)("vsm.guard: sin vigilancia del archivo de política: " + ex.Message)); } } } private static void MarkDirty(object sender, FileSystemEventArgs e) { s_dirtySince = DateTime.UtcNow; Interlocked.Exchange(ref s_dirty, 1); } public static void Tick(HashMode hashMode) { if (s_dirty != 0 && !((DateTime.UtcNow - s_dirtySince).TotalMilliseconds < 500.0)) { Interlocked.Exchange(ref s_dirty, 0); Reload(hashMode); } } public static void Dispose() { if (s_watcher != null) { s_watcher.EnableRaisingEvents = false; s_watcher.Dispose(); s_watcher = null; } } } public static class Texts { private static readonly Dictionary<string, string> s_words = new Dictionary<string, string>(StringComparer.Ordinal) { { "vsm_guard_header", "El servidor rechazó tu conexión por los mods (MEL Guard {0}, política {1}):" }, { "vsm_guard_missing", "• Falta el mod requerido {0} (versión {1}). {2}" }, { "vsm_guard_version", "• Versión incorrecta de {0}: el servidor exige {1} y tú tienes {2}." }, { "vsm_guard_hash", "• El archivo de {0} ({2}) no coincide con el del servidor. Reinstala el perfil del grupo." }, { "vsm_guard_forbidden", "• El mod {0} ({2}) no está permitido: {3}. Desactívalo." }, { "vsm_guard_unknown", "• El mod {0} ({2}) no está en la lista de permitidos. Pide al admin que lo autorice o desactívalo." }, { "vsm_guard_serveronly", "• El mod {0} es solo de servidor; quítalo de tu cliente." }, { "vsm_guard_failed_load", "• Tienes {0} instalado pero no cargó: {3}" }, { "vsm_guard_no_manifest", "Tu cliente no envió la lista de mods. Instala el perfil del grupo (incluye MEL Guard {0})." }, { "vsm_guard_protocol", "Tu MEL Guard ({2}) no es compatible con el del servidor ({1}). Actualiza el perfil." }, { "vsm_guard_hmac", "La lista de mods no superó la verificación. Reinicia el juego e inténtalo de nuevo." }, { "vsm_guard_internal", "Error interno al validar tus mods; se rechaza por seguridad. Avisa al admin (log del servidor)." }, { "vsm_guard_server_misconfig", "El servidor está mal configurado (MEL Guard): {0}. Avisa al admin." }, { "vsm_guard_patcher", "• El patcher {0} no está permitido en este servidor." }, { "vsm_guard_footer", "Corrige lo anterior y vuelve a entrar. En la consola (F5) escribe vsm_guard_dump para ver tus mods." }, { "vsm_guard_server_vanilla", "Este servidor no tiene MEL Guard; el perfil del grupo solo permite servidores con MEL Guard." }, { "vsm_guard_policy_created", "MEL Guard: no existía política; se generó {0} con los {1} plugins de este servidor como requeridos. Revísala." }, { "vsm_guard_policy_reloaded", "MEL Guard: política v{0} cargada ({1} requeridos, {2} opcionales, {3} prohibidos, {4} solo servidor)." }, { "vsm_guard_policy_error", "MEL Guard: error en la política ({0}); se conserva la anterior." }, { "vsm_guard_rejected_log", "MEL Guard: rechazado {0} ({1}) — {2}" }, { "vsm_guard_admitted_log", "MEL Guard: admitido {0} ({1}) con {2} plugins." } }; public static IDictionary<string, string> All => s_words; public static void LoadOverrides(string pluginDirectory) { try { string path = Path.Combine(Path.Combine(pluginDirectory ?? string.Empty, "Translations"), "Spanish.json"); if (!File.Exists(path)) { return; } foreach (KeyValuePair<string, string> item in VsmLocalization.ParseFlatJson(File.ReadAllText(path, Encoding.UTF8))) { string key = (item.Key.StartsWith("$", StringComparison.Ordinal) ? item.Key.Substring(1) : item.Key); s_words[key] = item.Value; } } catch (Exception) { } } public static string Get(string key, params object[] args) { if (!s_words.TryGetValue(key, out var value)) { value = key; } if (args == null || args.Length == 0) { return value; } try { return string.Format(value, args); } catch (FormatException) { return value; } } public static string Render(List<ReasonItem> items, string guardVersion, long policyVersion) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine(Get("vsm_guard_header", guardVersion, policyVersion)); int num = 0; foreach (ReasonItem item in items) { if (num++ >= 64) { stringBuilder.AppendLine("• …"); break; } stringBuilder.AppendLine(RenderItem(item, guardVersion)); } stringBuilder.Append(Get("vsm_guard_footer")); return stringBuilder.ToString(); } public static string RenderItem(ReasonItem item, string guardVersion) { return item.Code switch { ReasonCode.Missing => Get("vsm_guard_missing", item.Guid, item.Expected, item.Note), ReasonCode.Version => Get("vsm_guard_version", item.Guid, item.Expected, item.Actual), ReasonCode.Hash => Get("vsm_guard_hash", item.Guid, item.Expected, item.Actual), ReasonCode.Forbidden => Get("vsm_guard_forbidden", item.Guid, item.Expected, item.Actual, item.Note), ReasonCode.Unknown => Get("vsm_guard_unknown", item.Guid, item.Expected, item.Actual), ReasonCode.ServerOnly => Get("vsm_guard_serveronly", item.Guid), ReasonCode.FailedLoad => Get("vsm_guard_failed_load", item.Guid, item.Expected, item.Actual, item.Note), ReasonCode.NoManifest => Get("vsm_guard_no_manifest", guardVersion), ReasonCode.Protocol => Get("vsm_guard_protocol", item.Guid, item.Expected, item.Actual), ReasonCode.Hmac => Get("vsm_guard_hmac"), ReasonCode.Internal => Get("vsm_guard_internal"), ReasonCode.ServerMisconfig => Get("vsm_guard_server_misconfig", (item.Guid + " " + item.Expected + " " + item.Actual + " " + item.Note).Trim()), ReasonCode.Patcher => Get("vsm_guard_patcher", item.Guid), _ => "• " + item.Code.ToString() + " " + item.Guid, }; } public static string Summary(List<ReasonItem> items) { StringBuilder stringBuilder = new StringBuilder(); foreach (ReasonItem item in items) { if (stringBuilder.Length > 0) { stringBuilder.Append("; "); } stringBuilder.Append(item.Code.ToString().ToLowerInvariant()).Append(' ').Append(item.Guid); if (!string.IsNullOrEmpty(item.Expected) || !string.IsNullOrEmpty(item.Actual)) { stringBuilder.Append(' ').Append(item.Expected).Append('≠') .Append(item.Actual); } } return stringBuilder.ToString(); } } public enum UnknownModsMode { Reject, Warn } public enum HashMode { Strict, Off } public sealed class ValidatorSettings { public UnknownModsMode UnknownMods = UnknownModsMode.Reject; public HashMode HashMode = HashMode.Strict; public bool EnforcePatchersOverride; public string OwnGuid = "vsm.guard"; public string OwnVersion = string.Empty; } public static class Validator { public static List<ReasonItem> Run(Policy policy, Manifest manifest, ValidatorSettings settings) { List<ReasonItem> list = new List<ReasonItem>(); if (policy == null) { list.Add(new ReasonItem(ReasonCode.ServerMisconfig, "", "", "", "sin política cargada")); return list; } if (manifest == null) { list.Add(new ReasonItem(ReasonCode.NoManifest)); return list; } PluginEntry pluginEntry = manifest.Plugins.FirstOrDefault((PluginEntry p) => string.Equals(p.Guid, settings.OwnGuid, StringComparison.OrdinalIgnoreCase)); if (pluginEntry == null) { list.Add(new ReasonItem(ReasonCode.Protocol, settings.OwnGuid, settings.OwnVersion, "(ausente)")); } else if (!Policy.VersionSatisfies(pluginEntry.Version, settings.OwnVersion, VersionMode.Exact) && policy.FindRequired(settings.OwnGuid) == null) { list.Add(new ReasonItem(ReasonCode.Protocol, settings.OwnGuid, settings.OwnVersion, pluginEntry.Version)); } HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase); foreach (PluginEntry plugin in manifest.Plugins) { if (string.IsNullOrEmpty(plugin.Guid)) { continue; } hashSet.Add(plugin.Guid); PatternEntry patternEntry = policy.FirstMatch(policy.ServerOnly, plugin.Guid); if (patternEntry != null) { list.Add(new ReasonItem(ReasonCode.ServerOnly, plugin.Guid, "", plugin.Version, patternEntry.Note)); continue; } PatternEntry patternEntry2 = policy.FirstMatch(policy.Forbidden, plugin.Guid); if (patternEntry2 != null) { list.Add(new ReasonItem(ReasonCode.Forbidden, plugin.Guid, "", plugin.Version, patternEntry2.Note)); continue; } RequiredEntry requiredEntry = policy.FindRequired(plugin.Guid); if (requiredEntry != null) { if (!Policy.VersionSatisfies(plugin.Version, requiredEntry.Version, requiredEntry.Mode)) { list.Add(new ReasonItem(ReasonCode.Version, plugin.Guid, requiredEntry.Version + " (" + requiredEntry.Mode.ToString() + ")", plugin.Version, requiredEntry.Note)); } else if (settings.HashMode == HashMode.Strict && requiredEntry.Hashes.Count > 0 && (string.IsNullOrEmpty(plugin.Sha256) || !requiredEntry.Hashes.Contains(plugin.Sha256))) { list.Add(new ReasonItem(ReasonCode.Hash, plugin.Guid, requiredEntry.Version, plugin.Version, requiredEntry.Note)); } } else if (policy.FirstMatch(policy.ClientOptional, plugin.Guid) == null && settings.UnknownMods == UnknownModsMode.Reject) { list.Add(new ReasonItem(ReasonCode.Unknown, plugin.Guid, "", plugin.Version)); } } foreach (RequiredEntry required in policy.Required) { if (!hashSet.Contains(required.Guid)) { string text = manifest.DependencyErrors.FirstOrDefault((string d) => d != null && d.IndexOf(required.Guid, StringComparison.OrdinalIgnoreCase) >= 0); if (text != null) { list.Add(new ReasonItem(ReasonCode.FailedLoad, required.Guid, required.Version, "", text)); } else { list.Add(new ReasonItem(ReasonCode.Missing, required.Guid, required.Version, "", required.Note)); } } } if (policy.EnforcePatchers || settings.EnforcePatchersOverride) { foreach (PatcherEntry patcher in manifest.Patchers) { if (policy.FirstMatch(policy.PatchersAllowed, patcher.RelPath) == null) { list.Add(new ReasonItem(ReasonCode.Patcher, patcher.RelPath, "", patcher.Sha256)); } } } return list; } public static List<ReasonItem> SelfCheck(Policy policy, List<PluginEntry> serverPlugins, HashMode hashMode) { List<ReasonItem> list = new List<ReasonItem>(); if (policy == null) { return list; } foreach (RequiredEntry required in policy.Required) { PluginEntry pluginEntry = serverPlugins.FirstOrDefault((PluginEntry p) => string.Equals(p.Guid, required.Guid, StringComparison.OrdinalIgnoreCase)); if (pluginEntry == null) { list.Add(new ReasonItem(ReasonCode.ServerMisconfig, required.Guid, required.Version, "(no cargado en el servidor)", required.Note)); } else if (!Policy.VersionSatisfies(pluginEntry.Version, required.Version, required.Mode)) { list.Add(new ReasonItem(ReasonCode.ServerMisconfig, required.Guid, required.Version, pluginEntry.Version, "versión del servidor distinta")); } else if (hashMode == HashMode.Strict && required.Hashes.Count > 0 && !string.IsNullOrEmpty(pluginEntry.Sha256) && !required.Hashes.Contains(pluginEntry.Sha256)) { list.Add(new ReasonItem(ReasonCode.ServerMisconfig, required.Guid, string.Join(",", required.Hashes.ToArray()), pluginEntry.Sha256, "hash del servidor distinto")); } } return list; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class <bae7c731-d4a2-4f32-bc22-36bb9df641bb>IgnoresAccessChecksToAttribute : Attribute { public <bae7c731-d4a2-4f32-bc22-36bb9df641bb>IgnoresAccessChecksToAttribute(string assemblyName) { } } } namespace VSM.Core.Ui { internal static class VanillaStyle { public static TMP_Text TitleFont => ((Object)(object)InventoryGui.instance != (Object)null) ? InventoryGui.instance.m_playerName : null; public static TMP_Text BodyFont => (!((Object)(object)InventoryGui.instance != (Object)null)) ? null : (((Object)(object)InventoryGui.instance.m_armor != (Object)null) ? InventoryGui.instance.m_armor : InventoryGui.instance.m_playerName); public static Image FindBackground(Transform root, Transform exclude1, Transform exclude2) { //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)root == (Object)null) { return null; } Image result = null; float num = 0f; Image[] componentsInChildren = ((Component)root).GetComponentsInChildren<Image>(true); foreach (Image val in componentsInChildren) { if ((Object)(object)val == (Object)null || (Object)(object)val.sprite == (Object)null) { continue; } Transform transform = ((Component)val).transform; if ((!((Object)(object)exclude1 != (Object)null) || !transform.IsChildOf(exclude1)) && (!((Object)(object)exclude2 != (Object)null) || !transform.IsChildOf(exclude2))) { Rect rect = ((Graphic)val).rectTransform.rect; float num2 = Mathf.Abs(((Rect)(ref rect)).width * ((Rect)(ref rect)).height); if (num2 > num) { num = num2; result = val; } } } return result; } public static bool CopyImage(Image source, Image target) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target == (Object)null) { return false; } if ((Object)(object)source == (Object)null) { ((Graphic)target).color = new Color(0f, 0f, 0f, 0.6f); return false; } target.sprite = source.sprite; target.type = source.type; ((Graphic)target).material = ((Graphic)source).material; ((Graphic)target).color = ((Graphic)source).color; target.fillCenter = source.fillCenter; target.pixelsPerUnitMultiplier = source.pixelsPerUnitMultiplier; target.preserveAspect = false; return true; } public static Image InventoryBackground(Transform exclude) { InventoryGui instance = InventoryGui.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.m_player == (Object)null) { return null; } Transform exclude2 = (Transform)(object)(((Object)(object)instance.m_playerGrid != (Object)null) ? instance.m_playerGrid.m_gridRoot : null); return FindBackground((Transform)(object)instance.m_player, exclude2, exclude); } public static void CopyFont(TMP_Text source, TMP_Text target) { //IL_0037: 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) if (!((Object)(object)source == (Object)null) && !((Object)(object)target == (Object)null)) { target.font = source.font; target.fontSharedMaterial = source.fontSharedMaterial; ((Graphic)target).color = ((Graphic)source).color; target.fontStyle = source.fontStyle; } } public static TextMeshProUGUI NewText(Transform parent, string name, TMP_Text style, float size, TextAlignmentOptions align) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0041: 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(parent, false); TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>(); CopyFont(style, (TMP_Text)(object)val2); ((TMP_Text)val2).fontSize = size; ((TMP_Text)val2).alignment = align; ((Graphic)val2).raycastTarget = false; ((TMP_Text)val2).enableWordWrapping = false; ((TMP_Text)val2).richText = true; return val2; } } } namespace VSM.Core.Runtime { internal static class Headless { private static bool? s_isHeadless; public static bool IsHeadless { get { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 if (!s_isHeadless.HasValue) { s_isHeadless = (int)SystemInfo.graphicsDeviceType == 4 || Application.isBatchMode; } return s_isHeadless.Value; } } public static bool IsServerProcess => (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer(); public static bool IsDedicatedServer => (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && ZNet.instance.IsDedicated(); public static bool IsListenHost => (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && !ZNet.instance.IsDedicated(); public static bool IsRemoteClient => (Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer(); } internal static class Keys { public static bool Pressed(KeyboardShortcut shortcut) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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) KeyCode mainKey = ((KeyboardShortcut)(ref shortcut)).MainKey; return (int)mainKey != 0 && ZInput.GetKeyDown(mainKey, false) && ((KeyboardShortcut)(ref shortcut)).Modifiers.All((KeyCode m) => ZInput.GetKey(m, false)); } } } namespace VSM.Core.Reflection { internal static class GameConstants { private static uint? s_networkVersion; private static long? s_routedEverybody; public static uint NetworkVersion { get { if (!s_networkVersion.HasValue) { s_networkVersion = ReadConstant<uint>(typeof(Version), new string[2] { "c_networkVersion", "m_networkVersion" }); } return s_networkVersion.Value; } } public static long RoutedRpcEverybody { get { if (!s_routedEverybody.HasValue) { s_routedEverybody = ReadConstant<long>(typeof(ZRoutedRpc), new string[1] { "Everybody" }); } return s_routedEverybody.Value; } } public static string GameVersionString { get { //IL_0002: 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) try { return ((object)Version.CurrentVersion/*cast due to .constrained prefix*/).ToString(); } catch (Exception) { return "?"; } } } private static T ReadConstant<T>(Type type, params string[] names) where T : struct { foreach (string name in names) { FieldInfo field = type.GetField(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (!(field == null)) { object obj = (field.IsLiteral ? field.GetRawConstantValue() : field.GetValue(null)); if (obj is T result) { return result; } try { return (T)Convert.ChangeType(obj, typeof(T)); } catch (Exception) { } } } return default(T); } } } namespace VSM.Core.Net { internal static class ZPackageExt { public static bool HasMore(this ZPackage pkg) { return pkg != null && pkg.GetPos() < pkg.Size(); } public static int ReadIntOr(this ZPackage pkg, int fallback) { return pkg.HasMore() ? pkg.ReadInt() : fallback; } public static string ReadStringOr(this ZPackage pkg, string fallback) { return pkg.HasMore() ? pkg.ReadString() : fallback; } public static bool ReadBoolOr(this ZPackage pkg, bool fallback) { return pkg.HasMore() ? pkg.ReadBool() : fallback; } public static string ReadBoundedString(this ZPackage pkg, int maxLength) { string text = pkg.ReadString(); return (text != null && text.Length <= maxLength) ? text : null; } } } namespace VSM.Core.Localization { internal static class VsmLocalization { public static void Register(ManualLogSource log, string pluginDirectory, IDictionary<string, string> embeddedSpanish) { Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.Ordinal); if (embeddedSpanish != null) { foreach (KeyValuePair<string, string> item in embeddedSpanish) { dictionary[item.Key] = item.Value; } } string path = Path.Combine(pluginDirectory ?? string.Empty, "Translations"); MergeFile(log, Path.Combine(path, "Spanish.json"), dictionary); string text = SafeSelectedLanguage(); if (!string.Equals(text, "Spanish", StringComparison.OrdinalIgnoreCase)) { MergeFile(log, Path.Combine(path, text + ".json"), dictionary); } Apply(log, dictionary); } public static string Localize(string token, params object[] args) { string text = token; try { if (Localization.instance != null && !string.IsNullOrEmpty(token)) { bool flag = token[0] != '$' && token.IndexOf(' ') < 0 && token.IndexOf('\n') < 0; string text2 = Localization.instance.Localize(flag ? ("$" + token) : token); text = ((flag && text2.Length > 1 && text2[0] == '[' && text2[text2.Length - 1] == ']') ? token : text2); } } catch (Exception) { text = token; } if (args != null && args.Length != 0) { try { text = string.Format(text, args); } catch (FormatException) { } } return text; } private static string SafeSelectedLanguage() { try { return (Localization.instance != null) ? Localization.instance.GetSelectedLanguage() : "Spanish"; } catch (Exception) { return "Spanish"; } } private static void Apply(ManualLogSource log, Dictionary<string, string> words) { if (Localization.instance == null) { if (log != null) { log.LogWarning((object)"Localization.instance aún no existe; las traducciones no se han aplicado."); } return; } foreach (KeyValuePair<string, string> word in words) { string text = (word.Key.StartsWith("$", StringComparison.Ordinal) ? word.Key.Substring(1) : word.Key); Localization.instance.AddWord(text, word.Value); } } private static void MergeFile(ManualLogSource log, string path, Dictionary<string, string> into) { if (!File.Exists(path)) { return; } try { foreach (KeyValuePair<string, string> item in ParseFlatJson(File.ReadAllText(path, Encoding.UTF8))) { into[item.Key] = item.Value; } } catch (Exception ex) { if (log != null) { log.LogWarning((object)("No se pudo leer " + path + ": " + ex.Message)); } } } public static Dictionary<string, string> ParseFlatJson(string json) { Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.Ordinal); if (string.IsNullOrEmpty(json)) { return dictionary; } int i = 0; SkipWs(json, ref i); if (i >= json.Length || json[i] != '{') { return dictionary; } i++; while (true) { SkipWs(json, ref i); if (i >= json.Length || json[i] == '}') { break; } if (json[i] == ',') { i++; continue; } string text = ReadString(json, ref i); if (text == null) { i++; continue; } SkipWs(json, ref i); if (i < json.Length && json[i] == ':') { i++; } SkipWs(json, ref i); if (i < json.Length && json[i] == '"') { string text2 = ReadString(json, ref i); dictionary[text] = text2 ?? string.Empty; } else { for (; i < json.Length && json[i] != ',' && json[i] != '}'; i++) { } } } return dictionary; } private static void SkipWs(string s, ref int i) { while (i < s.Length && char.IsWhiteSpace(s[i])) { i++; } } private static string ReadString(string s, ref int i) { if (i >= s.Length || s[i] != '"') { return null; } i++; StringBuilder stringBuilder = new StringBuilder(); while (i < s.Length) { char c = s[i++]; switch (c) { case '"': return stringBuilder.ToString(); case '\\': { if (i >= s.Length) { break; } char c2 = s[i++]; switch (c2) { case 'n': stringBuilder.Append('\n'); break; case 't': stringBuilder.Append('\t'); break; case 'r': stringBuilder.Append('\r'); break; case 'b': stringBuilder.Append('\b'); break; case 'f': stringBuilder.Append('\f'); break; case 'u': if (i + 4 <= s.Length) { stringBuilder.Append((char)Convert.ToInt32(s.Substring(i, 4), 16)); i += 4; } break; default: stringBuilder.Append(c2); break; } continue; } } stringBuilder.Append(c); } return stringBuilder.ToString(); } } } namespace VSM.Core.Harmony { internal static class PatchUtil { private static readonly List<string> s_failed = new List<string>(); public static IReadOnlyList<string> FailedTargets => s_failed; public static bool IsDegraded => s_failed.Count > 0; public static MethodInfo DeclaredMethodOrNull(ManualLogSource log, Type type, string name, Type[] parameters, string owner) { if (type == null) { Fail(log, owner, name + " (tipo nulo)"); return null; } MethodInfo methodInfo = AccessTools.DeclaredMethod(type, name, parameters, (Type[])null); if (methodInfo == null) { Fail(log, owner, type.FullName + "." + name + "(" + Describe(parameters) + ")"); } return methodInfo; } public static void PatchAllSafely(ManualLogSource log, Harmony harmony, Assembly assembly) { Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(assembly); foreach (Type type in typesFromAssembly) { if (type.GetCustomAttributes(typeof(HarmonyPatch), inherit: true).Length != 0) { PatchClassSafely(log, harmony, type); } } } public static bool PatchClassSafely(ManualLogSource log, Harmony harmony, Type patchClass) { try { harmony.CreateClassProcessor(patchClass).Patch(); return true; } catch (Exception ex) { Fail(log, harmony.Id, patchClass.FullName + " -> " + ex.GetType().Name + ": " + ex.Message); return false; } } private static void Fail(ManualLogSource log, string owner, string what) { s_failed.Add(what); if (log != null) { log.LogError((object)("[" + owner + "] No se pudo aplicar el parche (¿cambió el juego?): " + what + ". El mod sigue cargado en modo degradado.")); } } private static string Describe(Type[] parameters) { if (parameters == null || parameters.Length == 0) { return string.Empty; } string[] array = new string[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { array[i] = ((parameters[i] == null) ? "?" : parameters[i].Name); } return string.Join(", ", array); } } } namespace VSM.Core.Config { internal sealed class ConfigurationManagerAttributes { public bool? ShowRangeAsPercent; public Action<ConfigEntryBase> CustomDrawer; public bool? Browsable; public string Category; public object DefaultValue; public bool? HideDefaultButton; public bool? HideSettingName; public string Description; public string DispName; public int? Order; public bool? ReadOnly; public bool? IsAdvanced; public bool? IsAdminOnly; public Func<object, string> ObjToStr; public Func<string, object> StrToObj; } } namespace VSM.Core.Camera { internal struct RigSettings { public float Speed; public float FastMultiplier; public bool MoveRelativeToView; } internal sealed class CameraRig { public const float MaxPitch = 89f; public float Yaw; public float Pitch; public Vector3 Position; public Vector3 Velocity; public Vector3 ForwardVector => Forward(Yaw, Pitch); public Quaternion Rotation => Quaternion.Euler(Pitch, Yaw, 0f); public static Vector3 Forward(float yawDeg, float pitchDeg) { //IL_002f: 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) //IL_0037: Unknown result type (might be due to invalid IL or missing references) float num = yawDeg * ((float)Math.PI / 180f); float num2 = pitchDeg * ((float)Math.PI / 180f); float num3 = Mathf.Cos(num2); return new Vector3(Mathf.Sin(num) * num3, 0f - Mathf.Sin(num2), Mathf.Cos(num) * num3); } public static Vector3 FlatForward(float yawDeg) { //IL_001a: 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_0022: Unknown result type (might be due to invalid IL or missing references) float num = yawDeg * ((float)Math.PI / 180f); return new Vector3(Mathf.Sin(num), 0f, Mathf.Cos(num)); } public static Vector3 Right(float yawDeg) { //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_0023: Unknown result type (might be due to invalid IL or missing references) float num = yawDeg * ((float)Math.PI / 180f); return new Vector3(Mathf.Cos(num), 0f, 0f - Mathf.Sin(num)); } public void Reset(Vector3 position, Vector3 forward) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) Position = position; Velocity = Vector3.zero; SetFromDirection(forward); } public void SetFromDirection(Vector3 forward) { //IL_0035: 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_005c: Unknown result type (might be due to invalid IL or missing references) if (((Vector3)(ref forward)).sqrMagnitude < 1E-08f) { Yaw = 0f; Pitch = 0f; } else { ((Vector3)(ref forward)).Normalize(); Yaw = Mathf.Repeat(Mathf.Atan2(forward.x, forward.z) * 57.29578f, 360f); Pitch = Mathf.Clamp((0f - Mathf.Asin(Mathf.Clamp(forward.y, -1f, 1f))) * 57.29578f, -89f, 89f); } } public void ApplyLook(Vector2 delta) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) Yaw = Mathf.Repeat(Yaw + delta.x, 360f); Pitch = Mathf.Clamp(Pitch - delta.y, -89f, 89f); } public Vector3 DesiredVelocity(Vector3 move, float vertical, bool fast, RigSettings settings) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //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_0083: 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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: 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_00df: 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) Vector3 val = (settings.MoveRelativeToView ? Forward(Yaw, Pitch) : FlatForward(Yaw)); Vector3 val2 = Right(Yaw) * Mathf.Clamp(move.x, -1f, 1f) + val * Mathf.Clamp(move.z, -1f, 1f) + Vector3.up * Mathf.Clamp(vertical, -1f, 1f); if (((Vector3)(ref val2)).sqrMagnitude > 1f) { ((Vector3)(ref val2)).Normalize(); } float num = Mathf.Max(0f, settings.Speed) * (fast ? Mathf.Max(1f, settings.FastMultiplier) : 1f); return val2 * num; } public void Integrate(Vector3 desiredVelocity, float dt, float smoothing) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be
plugins/VSM.Locks/VSM.Locks.dll
Decompiled 3 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using ConditionalConfigSync; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.UI; using VSM.Core.Config; using VSM.Core.Reflection; using VSM.Core.Runtime; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: <37a26cfd-4743-4d10-8e70-325e88058f0f>IgnoresAccessChecksTo("assembly_guiutils")] [assembly: <37a26cfd-4743-4d10-8e70-325e88058f0f>IgnoresAccessChecksTo("assembly_utils")] [assembly: <37a26cfd-4743-4d10-8e70-325e88058f0f>IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("VSM.Locks")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("0.1.4.0")] [assembly: AssemblyInformationalVersion("0.1.4+ff27bc889ccf218c61c45d3417d48ab708a5ba8f")] [assembly: AssemblyProduct("VSM.Locks")] [assembly: AssemblyTitle("VSM.Locks")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.4.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace VSM.Locks { public sealed class LockRule { public string Guid; public string Section; public string Key; public string Value; private static readonly char[] InvalidNameChars = new char[6] { '\t', '\\', '"', '\'', '[', ']' }; public override string ToString() { return Guid + " [" + Section + "] " + Key + " = " + Value; } public static List<LockRule> ParseList(string text, List<string> errors) { List<LockRule> list = new List<LockRule>(); if (string.IsNullOrEmpty(text)) { return list; } string[] array = text.Split(new char[3] { ';', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries); foreach (string text2 in array) { string text3 = text2.Trim(); if (text3.Length == 0 || text3.StartsWith("#", StringComparison.Ordinal)) { continue; } int num = text3.IndexOf('='); string[] array2 = ((num > 0) ? text3.Substring(0, num) : text3).Split(new char[1] { '|' }); if (num <= 0 || array2.Length != 3) { errors?.Add("regla mal escrita (se espera GUID|Sección|Clave=Valor): " + text3); continue; } string text4 = array2[1].Trim(); if (text4.Length >= 2 && text4[0] == '[' && text4[text4.Length - 1] == ']') { text4 = text4.Substring(1, text4.Length - 2).Trim(); } LockRule rule = new LockRule { Guid = array2[0].Trim(), Section = text4, Key = array2[2].Trim(), Value = text3.Substring(num + 1).Trim() }; if (rule.Guid.Length == 0 || rule.Section.Length == 0 || rule.Key.Length == 0) { errors?.Add("regla incompleta: " + text3); continue; } if (rule.Section.IndexOfAny(InvalidNameChars) >= 0 || rule.Key.IndexOfAny(InvalidNameChars) >= 0) { errors?.Add("sección o clave con caracteres no válidos (\\ \" ' [ ] tabulador): " + text3); continue; } list.RemoveAll((LockRule r) => r.SameSetting(rule)); list.Add(rule); } return list; } public bool SameSetting(LockRule other) { return other != null && string.Equals(Guid, other.Guid, StringComparison.Ordinal) && string.Equals(Section, other.Section, StringComparison.Ordinal) && string.Equals(Key, other.Key, StringComparison.Ordinal); } } [BepInPlugin("vsm.locks", "MEL Locks", "0.1.4")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class LocksPlugin : BaseUnityPlugin { public const string DefaultRules = "xeio.MassFarming|Pickup|MassInteractRange=5;xeio.MassFarming|Plant|IgnoreDurability=false"; internal static ManualLogSource Log; private static ConfigSync s_sync; public static ConfigEntry<bool> Enabled; public static ConfigEntry<string> Rules; public static ConfigEntry<bool> ServerLock; private static readonly FieldInfo s_descriptionField = typeof(ConfigEntryBase).GetField("<Description>k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic); private readonly Dictionary<ConfigEntryBase, LockRule> _locked = new Dictionary<ConfigEntryBase, LockRule>(); private readonly Dictionary<ConfigEntryBase, ConfigDescription> _originalDescriptions = new Dictionary<ConfigEntryBase, ConfigDescription>(); private readonly HashSet<ConfigFile> _hookedFiles = new HashSet<ConfigFile>(); private readonly HashSet<string> _warned = new HashSet<string>(); private bool _applying; private bool _started; private void Awake() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0044: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Expected O, but got Unknown //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; s_sync = new ConfigSync("vsm.locks") { DisplayName = "MEL Locks", CurrentVersion = "0.1.4", MinimumRequiredVersion = "0.1.4", ModRequired = true }; Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1. General", "Enabled", true, new ConfigDescription("Aplica las reglas: los ajustes de otros mods de la lista quedan fijos con el valor del servidor.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 100 } })); Rules = ((BaseUnityPlugin)this).Config.Bind<string>("1. General", "Rules", "xeio.MassFarming|Pickup|MassInteractRange=5;xeio.MassFarming|Plant|IgnoreDurability=false", new ConfigDescription("Ajustes fijados, separados por ';': GUID|Sección|Clave=Valor (los nombres exactos del .cfg del otro mod).", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 99 } })); ServerLock = ((BaseUnityPlugin)this).Config.Bind<bool>("1. General", "ServerLock", true, new ConfigDescription("Bloquea la configuración sincronizada: solo los administradores del servidor pueden cambiarla.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 98 } })); ((ConditionalConfigSync)s_sync).AddConfigEntry<bool>(Enabled, (ConfigSyncMode)0); ((ConditionalConfigSync)s_sync).AddConfigEntry<string>(Rules, (ConfigSyncMode)0); ((ConditionalConfigSync)s_sync).AddLockingConfigEntry<bool>(ServerLock); Enabled.SettingChanged += delegate { ApplyAll(); }; Rules.SettingChanged += delegate { ApplyAll(); }; Log.LogInfo((object)("vsm.locks 0.1.4 | Valheim " + GameConstants.GameVersionString + " | headless=" + Headless.IsHeadless)); } private void Start() { _started = true; ApplyAll(); } private void ApplyAll() { if (!_started) { return; } List<string> list = new List<string>(); List<LockRule> list2 = (Enabled.Value ? LockRule.ParseList(Rules.Value, list) : new List<LockRule>()); foreach (string item in list) { WarnOnce("vsm.locks: " + item); } Dictionary<ConfigEntryBase, LockRule> dictionary = new Dictionary<ConfigEntryBase, LockRule>(); foreach (LockRule item2 in list2) { try { ConfigEntryBase val = Find(item2); if (val != null) { TomlTypeConverter.ConvertToValue(item2.Value, val.SettingType); dictionary[val] = item2; } } catch (Exception ex) { WarnOnce("vsm.locks: regla no válida " + item2?.ToString() + ": " + ex.Message); } } foreach (ConfigEntryBase item3 in new List<ConfigEntryBase>(_locked.Keys)) { if (!dictionary.ContainsKey(item3)) { SetReadOnly(item3, locked: false); _locked.Remove(item3); } } foreach (KeyValuePair<ConfigEntryBase, LockRule> item4 in dictionary) { _locked[item4.Key] = item4.Value; Hook(item4.Key.ConfigFile); SetReadOnly(item4.Key, locked: true); Enforce(item4.Key, item4.Value); } } private ConfigEntryBase Find(LockRule rule) { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown if (!Chainloader.PluginInfos.TryGetValue(rule.Guid, out var value) || value == null || (Object)(object)value.Instance == (Object)null) { WarnOnce("vsm.locks: no está cargado el mod " + rule.Guid + " (regla " + rule?.ToString() + ")"); return null; } ConfigFile config = value.Instance.Config; ConfigDefinition val = new ConfigDefinition(rule.Section, rule.Key); if (config == null || !config.ContainsKey(val)) { WarnOnce("vsm.locks: " + rule.Guid + " no tiene el ajuste [" + rule.Section + "] " + rule.Key); return null; } return config[val]; } private void Enforce(ConfigEntryBase entry, LockRule rule) { if (_applying) { return; } try { _applying = true; string serializedValue = entry.GetSerializedValue(); entry.SetSerializedValue(rule.Value); string serializedValue2 = entry.GetSerializedValue(); if (serializedValue2 != serializedValue) { Log.LogInfo((object)("vsm.locks: " + rule.Guid + " [" + rule.Section + "] " + rule.Key + " = " + serializedValue2 + " (antes " + serializedValue + ")")); } } catch (Exception ex) { WarnOnce("vsm.locks: no se pudo fijar " + rule?.ToString() + ": " + ex.Message); } finally { _applying = false; } } private void Hook(ConfigFile file) { if (file == null || !_hookedFiles.Add(file)) { return; } file.SettingChanged += delegate(object s, SettingChangedEventArgs e) { if (e != null && e.ChangedSetting != null && _locked.TryGetValue(e.ChangedSetting, out var value)) { Enforce(e.ChangedSetting, value); } }; file.ConfigReloaded += delegate { foreach (KeyValuePair<ConfigEntryBase, LockRule> item in _locked) { if (item.Key.ConfigFile == file) { Enforce(item.Key, item.Value); } } }; } private void SetReadOnly(ConfigEntryBase entry, bool locked) { //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Expected O, but got Unknown if (s_descriptionField == null) { WarnOnce("vsm.locks: esta versión de BepInEx no deja marcar ajustes como de solo lectura (se reponen igual)."); return; } try { if (!_originalDescriptions.TryGetValue(entry, out var value)) { value = entry.Description; _originalDescriptions[entry] = value; } if (!locked) { s_descriptionField.SetValue(entry, value); return; } List<object> list = new List<object>(); if (value != null && value.Tags != null) { list.AddRange(value.Tags); } list.Add(new ConfigurationManagerAttributes { ReadOnly = true }); string text = ((value != null) ? value.Description : string.Empty) + "\n[Fijado por el servidor (MEL Locks)]"; s_descriptionField.SetValue(entry, (object?)new ConfigDescription(text, (value != null) ? value.AcceptableValues : null, list.ToArray())); } catch (Exception ex) { WarnOnce("vsm.locks: no se pudo marcar " + ((object)entry.Definition)?.ToString() + " como de solo lectura: " + ex.Message); } } private void WarnOnce(string message) { if (_warned.Add(message)) { Log.LogWarning((object)message); } } } public static class MyPluginInfo { public const string PLUGIN_GUID = "vsm.locks"; public const string PLUGIN_NAME = "MEL Locks"; public const string PLUGIN_VERSION = "0.1.4"; } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class <37a26cfd-4743-4d10-8e70-325e88058f0f>IgnoresAccessChecksToAttribute : Attribute { public <37a26cfd-4743-4d10-8e70-325e88058f0f>IgnoresAccessChecksToAttribute(string assemblyName) { } } } namespace VSM.Core.Ui { internal static class VanillaStyle { public static TMP_Text TitleFont => ((Object)(object)InventoryGui.instance != (Object)null) ? InventoryGui.instance.m_playerName : null; public static TMP_Text BodyFont => (!((Object)(object)InventoryGui.instance != (Object)null)) ? null : (((Object)(object)InventoryGui.instance.m_armor != (Object)null) ? InventoryGui.instance.m_armor : InventoryGui.instance.m_playerName); public static Image FindBackground(Transform root, Transform exclude1, Transform exclude2) { //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)root == (Object)null) { return null; } Image result = null; float num = 0f; Image[] componentsInChildren = ((Component)root).GetComponentsInChildren<Image>(true); foreach (Image val in componentsInChildren) { if ((Object)(object)val == (Object)null || (Object)(object)val.sprite == (Object)null) { continue; } Transform transform = ((Component)val).transform; if ((!((Object)(object)exclude1 != (Object)null) || !transform.IsChildOf(exclude1)) && (!((Object)(object)exclude2 != (Object)null) || !transform.IsChildOf(exclude2))) { Rect rect = ((Graphic)val).rectTransform.rect; float num2 = Mathf.Abs(((Rect)(ref rect)).width * ((Rect)(ref rect)).height); if (num2 > num) { num = num2; result = val; } } } return result; } public static bool CopyImage(Image source, Image target) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target == (Object)null) { return false; } if ((Object)(object)source == (Object)null) { ((Graphic)target).color = new Color(0f, 0f, 0f, 0.6f); return false; } target.sprite = source.sprite; target.type = source.type; ((Graphic)target).material = ((Graphic)source).material; ((Graphic)target).color = ((Graphic)source).color; target.fillCenter = source.fillCenter; target.pixelsPerUnitMultiplier = source.pixelsPerUnitMultiplier; target.preserveAspect = false; return true; } public static Image InventoryBackground(Transform exclude) { InventoryGui instance = InventoryGui.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.m_player == (Object)null) { return null; } Transform exclude2 = (Transform)(object)(((Object)(object)instance.m_playerGrid != (Object)null) ? instance.m_playerGrid.m_gridRoot : null); return FindBackground((Transform)(object)instance.m_player, exclude2, exclude); } public static void CopyFont(TMP_Text source, TMP_Text target) { //IL_0037: 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) if (!((Object)(object)source == (Object)null) && !((Object)(object)target == (Object)null)) { target.font = source.font; target.fontSharedMaterial = source.fontSharedMaterial; ((Graphic)target).color = ((Graphic)source).color; target.fontStyle = source.fontStyle; } } public static TextMeshProUGUI NewText(Transform parent, string name, TMP_Text style, float size, TextAlignmentOptions align) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0041: 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(parent, false); TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>(); CopyFont(style, (TMP_Text)(object)val2); ((TMP_Text)val2).fontSize = size; ((TMP_Text)val2).alignment = align; ((Graphic)val2).raycastTarget = false; ((TMP_Text)val2).enableWordWrapping = false; ((TMP_Text)val2).richText = true; return val2; } } } namespace VSM.Core.Runtime { internal static class Headless { private static bool? s_isHeadless; public static bool IsHeadless { get { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 if (!s_isHeadless.HasValue) { s_isHeadless = (int)SystemInfo.graphicsDeviceType == 4 || Application.isBatchMode; } return s_isHeadless.Value; } } public static bool IsServerProcess => (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer(); public static bool IsDedicatedServer => (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && ZNet.instance.IsDedicated(); public static bool IsListenHost => (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && !ZNet.instance.IsDedicated(); public static bool IsRemoteClient => (Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer(); } internal static class Keys { public static bool Pressed(KeyboardShortcut shortcut) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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) KeyCode mainKey = ((KeyboardShortcut)(ref shortcut)).MainKey; return (int)mainKey != 0 && ZInput.GetKeyDown(mainKey, false) && ((KeyboardShortcut)(ref shortcut)).Modifiers.All((KeyCode m) => ZInput.GetKey(m, false)); } } } namespace VSM.Core.Reflection { internal static class GameConstants { private static uint? s_networkVersion; private static long? s_routedEverybody; public static uint NetworkVersion { get { if (!s_networkVersion.HasValue) { s_networkVersion = ReadConstant<uint>(typeof(Version), new string[2] { "c_networkVersion", "m_networkVersion" }); } return s_networkVersion.Value; } } public static long RoutedRpcEverybody { get { if (!s_routedEverybody.HasValue) { s_routedEverybody = ReadConstant<long>(typeof(ZRoutedRpc), new string[1] { "Everybody" }); } return s_routedEverybody.Value; } } public static string GameVersionString { get { //IL_0002: 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) try { return ((object)Version.CurrentVersion/*cast due to .constrained prefix*/).ToString(); } catch (Exception) { return "?"; } } } private static T ReadConstant<T>(Type type, params string[] names) where T : struct { foreach (string name in names) { FieldInfo field = type.GetField(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (!(field == null)) { object obj = (field.IsLiteral ? field.GetRawConstantValue() : field.GetValue(null)); if (obj is T result) { return result; } try { return (T)Convert.ChangeType(obj, typeof(T)); } catch (Exception) { } } } return default(T); } } } namespace VSM.Core.Net { internal static class ZPackageExt { public static bool HasMore(this ZPackage pkg) { return pkg != null && pkg.GetPos() < pkg.Size(); } public static int ReadIntOr(this ZPackage pkg, int fallback) { return pkg.HasMore() ? pkg.ReadInt() : fallback; } public static string ReadStringOr(this ZPackage pkg, string fallback) { return pkg.HasMore() ? pkg.ReadString() : fallback; } public static bool ReadBoolOr(this ZPackage pkg, bool fallback) { return pkg.HasMore() ? pkg.ReadBool() : fallback; } public static string ReadBoundedString(this ZPackage pkg, int maxLength) { string text = pkg.ReadString(); return (text != null && text.Length <= maxLength) ? text : null; } } } namespace VSM.Core.Localization { internal static class VsmLocalization { public static void Register(ManualLogSource log, string pluginDirectory, IDictionary<string, string> embeddedSpanish) { Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.Ordinal); if (embeddedSpanish != null) { foreach (KeyValuePair<string, string> item in embeddedSpanish) { dictionary[item.Key] = item.Value; } } string path = Path.Combine(pluginDirectory ?? string.Empty, "Translations"); MergeFile(log, Path.Combine(path, "Spanish.json"), dictionary); string text = SafeSelectedLanguage(); if (!string.Equals(text, "Spanish", StringComparison.OrdinalIgnoreCase)) { MergeFile(log, Path.Combine(path, text + ".json"), dictionary); } Apply(log, dictionary); } public static string Localize(string token, params object[] args) { string text = token; try { if (Localization.instance != null && !string.IsNullOrEmpty(token)) { bool flag = token[0] != '$' && token.IndexOf(' ') < 0 && token.IndexOf('\n') < 0; string text2 = Localization.instance.Localize(flag ? ("$" + token) : token); text = ((flag && text2.Length > 1 && text2[0] == '[' && text2[text2.Length - 1] == ']') ? token : text2); } } catch (Exception) { text = token; } if (args != null && args.Length != 0) { try { text = string.Format(text, args); } catch (FormatException) { } } return text; } private static string SafeSelectedLanguage() { try { return (Localization.instance != null) ? Localization.instance.GetSelectedLanguage() : "Spanish"; } catch (Exception) { return "Spanish"; } } private static void Apply(ManualLogSource log, Dictionary<string, string> words) { if (Localization.instance == null) { if (log != null) { log.LogWarning((object)"Localization.instance aún no existe; las traducciones no se han aplicado."); } return; } foreach (KeyValuePair<string, string> word in words) { string text = (word.Key.StartsWith("$", StringComparison.Ordinal) ? word.Key.Substring(1) : word.Key); Localization.instance.AddWord(text, word.Value); } } private static void MergeFile(ManualLogSource log, string path, Dictionary<string, string> into) { if (!File.Exists(path)) { return; } try { foreach (KeyValuePair<string, string> item in ParseFlatJson(File.ReadAllText(path, Encoding.UTF8))) { into[item.Key] = item.Value; } } catch (Exception ex) { if (log != null) { log.LogWarning((object)("No se pudo leer " + path + ": " + ex.Message)); } } } public static Dictionary<string, string> ParseFlatJson(string json) { Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.Ordinal); if (string.IsNullOrEmpty(json)) { return dictionary; } int i = 0; SkipWs(json, ref i); if (i >= json.Length || json[i] != '{') { return dictionary; } i++; while (true) { SkipWs(json, ref i); if (i >= json.Length || json[i] == '}') { break; } if (json[i] == ',') { i++; continue; } string text = ReadString(json, ref i); if (text == null) { i++; continue; } SkipWs(json, ref i); if (i < json.Length && json[i] == ':') { i++; } SkipWs(json, ref i); if (i < json.Length && json[i] == '"') { string text2 = ReadString(json, ref i); dictionary[text] = text2 ?? string.Empty; } else { for (; i < json.Length && json[i] != ',' && json[i] != '}'; i++) { } } } return dictionary; } private static void SkipWs(string s, ref int i) { while (i < s.Length && char.IsWhiteSpace(s[i])) { i++; } } private static string ReadString(string s, ref int i) { if (i >= s.Length || s[i] != '"') { return null; } i++; StringBuilder stringBuilder = new StringBuilder(); while (i < s.Length) { char c = s[i++]; switch (c) { case '"': return stringBuilder.ToString(); case '\\': { if (i >= s.Length) { break; } char c2 = s[i++]; switch (c2) { case 'n': stringBuilder.Append('\n'); break; case 't': stringBuilder.Append('\t'); break; case 'r': stringBuilder.Append('\r'); break; case 'b': stringBuilder.Append('\b'); break; case 'f': stringBuilder.Append('\f'); break; case 'u': if (i + 4 <= s.Length) { stringBuilder.Append((char)Convert.ToInt32(s.Substring(i, 4), 16)); i += 4; } break; default: stringBuilder.Append(c2); break; } continue; } } stringBuilder.Append(c); } return stringBuilder.ToString(); } } } namespace VSM.Core.Harmony { internal static class PatchUtil { private static readonly List<string> s_failed = new List<string>(); public static IReadOnlyList<string> FailedTargets => s_failed; public static bool IsDegraded => s_failed.Count > 0; public static MethodInfo DeclaredMethodOrNull(ManualLogSource log, Type type, string name, Type[] parameters, string owner) { if (type == null) { Fail(log, owner, name + " (tipo nulo)"); return null; } MethodInfo methodInfo = AccessTools.DeclaredMethod(type, name, parameters, (Type[])null); if (methodInfo == null) { Fail(log, owner, type.FullName + "." + name + "(" + Describe(parameters) + ")"); } return methodInfo; } public static void PatchAllSafely(ManualLogSource log, Harmony harmony, Assembly assembly) { Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(assembly); foreach (Type type in typesFromAssembly) { if (type.GetCustomAttributes(typeof(HarmonyPatch), inherit: true).Length != 0) { PatchClassSafely(log, harmony, type); } } } public static bool PatchClassSafely(ManualLogSource log, Harmony harmony, Type patchClass) { try { harmony.CreateClassProcessor(patchClass).Patch(); return true; } catch (Exception ex) { Fail(log, harmony.Id, patchClass.FullName + " -> " + ex.GetType().Name + ": " + ex.Message); return false; } } private static void Fail(ManualLogSource log, string owner, string what) { s_failed.Add(what); if (log != null) { log.LogError((object)("[" + owner + "] No se pudo aplicar el parche (¿cambió el juego?): " + what + ". El mod sigue cargado en modo degradado.")); } } private static string Describe(Type[] parameters) { if (parameters == null || parameters.Length == 0) { return string.Empty; } string[] array = new string[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { array[i] = ((parameters[i] == null) ? "?" : parameters[i].Name); } return string.Join(", ", array); } } } namespace VSM.Core.Config { internal sealed class ConfigurationManagerAttributes { public bool? ShowRangeAsPercent; public Action<ConfigEntryBase> CustomDrawer; public bool? Browsable; public string Category; public object DefaultValue; public bool? HideDefaultButton; public bool? HideSettingName; public string Description; public string DispName; public int? Order; public bool? ReadOnly; public bool? IsAdvanced; public bool? IsAdminOnly; public Func<object, string> ObjToStr; public Func<string, object> StrToObj; } } namespace VSM.Core.Camera { internal struct RigSettings { public float Speed; public float FastMultiplier; public bool MoveRelativeToView; } internal sealed class CameraRig { public const float MaxPitch = 89f; public float Yaw; public float Pitch; public Vector3 Position; public Vector3 Velocity; public Vector3 ForwardVector => Forward(Yaw, Pitch); public Quaternion Rotation => Quaternion.Euler(Pitch, Yaw, 0f); public static Vector3 Forward(float yawDeg, float pitchDeg) { //IL_002f: 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) //IL_0037: Unknown result type (might be due to invalid IL or missing references) float num = yawDeg * ((float)Math.PI / 180f); float num2 = pitchDeg * ((float)Math.PI / 180f); float num3 = Mathf.Cos(num2); return new Vector3(Mathf.Sin(num) * num3, 0f - Mathf.Sin(num2), Mathf.Cos(num) * num3); } public static Vector3 FlatForward(float yawDeg) { //IL_001a: 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_0022: Unknown result type (might be due to invalid IL or missing references) float num = yawDeg * ((float)Math.PI / 180f); return new Vector3(Mathf.Sin(num), 0f, Mathf.Cos(num)); } public static Vector3 Right(float yawDeg) { //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_0023: Unknown result type (might be due to invalid IL or missing references) float num = yawDeg * ((float)Math.PI / 180f); return new Vector3(Mathf.Cos(num), 0f, 0f - Mathf.Sin(num)); } public void Reset(Vector3 position, Vector3 forward) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) Position = position; Velocity = Vector3.zero; SetFromDirection(forward); } public void SetFromDirection(Vector3 forward) { //IL_0035: 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_005c: Unknown result type (might be due to invalid IL or missing references) if (((Vector3)(ref forward)).sqrMagnitude < 1E-08f) { Yaw = 0f; Pitch = 0f; } else { ((Vector3)(ref forward)).Normalize(); Yaw = Mathf.Repeat(Mathf.Atan2(forward.x, forward.z) * 57.29578f, 360f); Pitch = Mathf.Clamp((0f - Mathf.Asin(Mathf.Clamp(forward.y, -1f, 1f))) * 57.29578f, -89f, 89f); } } public void ApplyLook(Vector2 delta) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) Yaw = Mathf.Repeat(Yaw + delta.x, 360f); Pitch = Mathf.Clamp(Pitch - delta.y, -89f, 89f); } public Vector3 DesiredVelocity(Vector3 move, float vertical, bool fast, RigSettings settings) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //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_0083: 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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: 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_00df: 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) Vector3 val = (settings.MoveRelativeToView ? Forward(Yaw, Pitch) : FlatForward(Yaw)); Vector3 val2 = Right(Yaw) * Mathf.Clamp(move.x, -1f, 1f) + val * Mathf.Clamp(move.z, -1f, 1f) + Vector3.up * Mathf.Clamp(vertical, -1f, 1f); if (((Vector3)(ref val2)).sqrMagnitude > 1f) { ((Vector3)(ref val2)).Normalize(); } float num = Mathf.Max(0f, settings.Speed) * (fast ? Mathf.Max(1f, settings.FastMultiplier) : 1f); return val2 * num; } public void Integrate(Vector3 desiredVelocity, float dt, float smoothing) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0047: 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) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) if (!(dt <= 0f)) { float num = ((smoothing <= 0f) ? 1f : (1f - Mathf.Exp((0f - dt) / smoothing))); Velocity = Vector3.Lerp(Velocity, desiredVelocity, num); Position += Velocity * dt; } } public static Vector3 ClampToSphere(Vector3 pos, Vector3 center, float radius) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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) Vector3 val = pos - center; float num = Mathf.Max(0f, radius); if (((Vector3)(ref val)).sqrMagnitude <= num * num) { return pos; } return center + ((Vector3)(ref val)).normalized * num; } } internal static class CameraWorld { public const float CollisionRadius = 0.25f; public static Vector3 Anchor(Player player) { //IL_0033: 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_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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) Transform eye = ((Character)player).m_eye; return ((Object)(object)eye != (Object)null) ? eye.position : (((Component)player).transform.position + Vector3.up * 1.6f); } public static Vector3 Constrain(Vector3 from, Vector3 to, Vector3 anchor, float maxDistance, float clearance, GameCamera cam) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0038: 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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) Vector3 pos = CameraRig.ClampToSphere(to, anchor, maxDistance); pos = Lift(pos, clearance, cam); pos = CameraRig.ClampToSphere(pos, anchor, maxDistance + 1f); LayerMask blockCameraMask = cam.m_blockCameraMask; Vector3 val = (Overlaps(from, blockCameraMask) ? anchor : from); return Collide(val, pos, blockCameraMask); } public static Vector3 Lift(Vector3 pos, float clearance, GameCamera cam) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) clearance = Mathf.Max(0f, clearance); ZoneSystem instance = ZoneSystem.instance; float num = default(float); if ((Object)(object)instance != (Object)null && instance.GetGroundHeight(pos, ref num)) { pos.y = Mathf.Max(pos.y, num + clearance); } float num2 = Floating.GetLiquidLevel(pos, 1f, (LiquidType)10); if ((Object)(object)instance != (Object)null && !Character.InInterior(pos)) { num2 = Mathf.Max(num2, instance.m_waterLevel); } if (num2 > -9000f) { pos.y = Mathf.Max(pos.y, num2 + Mathf.Max(clearance, cam.m_minWaterDistance)); } return pos; } public static bool Overlaps(Vector3 pos, LayerMask mask) { //IL_0001: 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) return Physics.CheckSphere(pos, 0.225f, LayerMask.op_Implicit(mask), (QueryTriggerInteraction)1); } public static Vector3 Collide(Vector3 from, Vector3 to, LayerMask mask) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0033: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) Vector3 val = to - from; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude < 1E-05f) { return to; } Vector3 val2 = val / magnitude; RaycastHit val3 = default(RaycastHit); if (Physics.SphereCast(from, 0.25f, val2, ref val3, magnitude, LayerMask.op_Implicit(mask), (QueryTriggerInteraction)1)) { return from + val2 * Mathf.Max(0f, ((RaycastHit)(ref val3)).distance - 0.02f); } return to; } } internal static class CameraLock { private const string Prefix = "vsm_camera_lock:"; public static string Holder() { GameCamera instance = GameCamera.instance; if ((Object)(object)instance == (Object)null) { return null; } Transform transform = ((Component)instance).transform; for (int i = 0; i < transform.childCount; i++) { string name = ((Object)transform.GetChild(i)).name; if (name.StartsWith("vsm_camera_lock:", StringComparison.Ordinal)) { return name.Substring("vsm_camera_lock:".Length); } } return null; } public static bool TryAcquire(string owner) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown GameCamera instance = GameCamera.instance; if ((Object)(object)instance == (Object)null) { return false; } string text = Holder(); if (text != null) { return text == owner; } GameObject val = new GameObject("vsm_camera_lock:" + owner); val.transform.SetParent(((Component)instance).transform, false); return true; } public static void Release(string owner) { GameCamera instance = GameCamera.instance; if ((Object)(object)instance == (Object)null) { return; } Transform transform = ((Component)instance).transform; for (int num = transform.childCount - 1; num >= 0; num--) { Transform child = transform.GetChild(num); if (((Object)child).name == "vsm_camera_lock:" + owner) { Object.Destroy((Object)(object)((Component)child).gameObject); ((Object)child).name = "vsm_camera_lock_released"; } } } } internal sealed class BodyHider { private readonly List<Renderer> _hidden = new List<Renderer>(); private float _nextScan; public void Update(Player player, bool hide) { if (!hide || (Object)(object)player == (Object)null) { Restore(); } else { if (Time.unscaledTime < _nextScan) { return; } _nextScan = Time.unscaledTime + 0.5f; Renderer[] componentsInChildren = ((Component)player).GetComponentsInChildren<Renderer>(false); foreach (Renderer val in componentsInChildren) { if ((Object)(object)val != (Object)null && val.enabled && (val is SkinnedMeshRenderer || val is MeshRenderer)) { val.enabled = false; _hidden.Add(val); } } } } public void Restore() { foreach (Renderer item in _hidden) { if ((Object)(object)item != (Object)null) { item.enabled = true; } } _hidden.Clear(); _nextScan = 0f; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }
plugins/VSM.Net/VSM.Net.dll
Decompiled 3 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.UI; using VSM.Core.Harmony; using VSM.Core.Reflection; using VSM.Core.Runtime; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: <a8264826-ed31-4744-a6ee-6dab45ecd123>IgnoresAccessChecksTo("assembly_guiutils")] [assembly: <a8264826-ed31-4744-a6ee-6dab45ecd123>IgnoresAccessChecksTo("assembly_utils")] [assembly: <a8264826-ed31-4744-a6ee-6dab45ecd123>IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("VSM.Net")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("0.1.4.0")] [assembly: AssemblyInformationalVersion("0.1.4+ff27bc889ccf218c61c45d3417d48ab708a5ba8f")] [assembly: AssemblyProduct("VSM.Net")] [assembly: AssemblyTitle("VSM.Net")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.4.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace VSM.Net { internal static class NetPatches { [HarmonyPatch(typeof(ZDOMan), "SendZDOs", new Type[] { typeof(ZDOPeer), typeof(bool) })] private static class SendZdosPatch { [HarmonyPrefix] private static void Prefix(ZDOPeer peer, out int __state) { __state = -1; try { if (Telemetry.Active && peer != null && peer.m_peer != null && peer.m_peer.m_socket != null) { __state = peer.m_peer.m_socket.GetSendQueueSize(); } } catch (Exception) { __state = -1; } } [HarmonyPostfix] private static void Postfix(ZDOPeer peer, bool __result, int __state) { if (__state < 0 || peer == null || peer.m_peer == null) { return; } try { int queueAfter = ((__result && peer.m_peer.m_socket != null) ? peer.m_peer.m_socket.GetSendQueueSize() : __state); Telemetry.For(peer.m_peer)?.RecordCall(__state, queueAfter, __result, Time.timeAsDouble); } catch (Exception) { } } } [HarmonyPatch(typeof(ZNet), "OnDestroy")] private static class ZNetDestroyPatch { [HarmonyPostfix] private static void Postfix() { Telemetry.Reset(); } } [HarmonyPatch(typeof(Terminal), "InitTerminal")] private static class TerminalInitPatch { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__1_0; internal void <Postfix>b__1_0(ConsoleEventArgs args) { if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer()) { args.Context.AddString("vsm_net: solo tiene datos en el servidor (o anfitrión)."); return; } string text = ((args.Length > 1) ? args.Args[1].ToLowerInvariant() : string.Empty); if (text == "owners") { foreach (string item in Telemetry.Owners()) { args.Context.AddString(item); } return; } if (text == "reset") { Telemetry.Reset(); args.Context.AddString("vsm_net: contadores reiniciados."); return; } foreach (string item2 in Telemetry.Snapshot(reset: false)) { args.Context.AddString(item2); } } } private static bool s_registered; [HarmonyPostfix] private static void Postfix() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown if (s_registered) { return; } s_registered = true; object obj = <>c.<>9__1_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer()) { args.Context.AddString("vsm_net: solo tiene datos en el servidor (o anfitrión)."); } else { string text = ((args.Length > 1) ? args.Args[1].ToLowerInvariant() : string.Empty); if (text == "owners") { foreach (string item in Telemetry.Owners()) { args.Context.AddString(item); } return; } if (!(text == "reset")) { foreach (string item2 in Telemetry.Snapshot(reset: false)) { args.Context.AddString(item2); } return; } Telemetry.Reset(); args.Context.AddString("vsm_net: contadores reiniciados."); } }; <>c.<>9__1_0 = val; obj = (object)val; } new ConsoleCommand("vsm_net", "Telemetría de red del servidor: vsm_net [owners|reset]", (ConsoleEvent)obj, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } } } [BepInPlugin("vsm.net", "MEL Net", "0.1.4")] public sealed class NetPlugin : BaseUnityPlugin { internal static ManualLogSource Log; private Harmony _harmony; public static ConfigEntry<bool> Enabled; public static ConfigEntry<float> LogIntervalSeconds; public static ConfigEntry<bool> LogToCsv; private void Awake() { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1. Telemetría (servidor)", "Enabled", true, "Medir el planificador de envío de ZDO por peer (sin cambiar nada)."); LogIntervalSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("1. Telemetría (servidor)", "LogIntervalSeconds", 60f, new ConfigDescription("Cada cuántos segundos volcar un resumen al log (0 = solo con el comando vsm_net).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3600f), Array.Empty<object>())); LogToCsv = ((BaseUnityPlugin)this).Config.Bind<bool>("1. Telemetría (servidor)", "LogToCsv", true, "Además del log, añadir filas a BepInEx/config/vsm.net/telemetria.csv."); Log.LogInfo((object)("vsm.net 0.1.4 (etapa 0: telemetría) | Valheim " + GameConstants.GameVersionString + " | red " + GameConstants.NetworkVersion + " | headless=" + Headless.IsHeadless)); _harmony = new Harmony("vsm.net"); PatchUtil.PatchAllSafely(Log, _harmony, Assembly.GetExecutingAssembly()); if (PatchUtil.IsDegraded) { Log.LogWarning((object)"vsm.net: algún parche de telemetría no se aplicó; las métricas pueden estar incompletas."); } } private void Update() { Telemetry.Tick(); } private void OnDestroy() { if (_harmony != null) { _harmony.UnpatchSelf(); } } } public sealed class PeerStats { public const int Window = 10240; public const int MinBudget = 2048; public string Name = "?"; public long Uid; public int Calls; public int Sent; public int BlockedFull; public int BlockedBudget; public long BytesQueued; public int QueueMax; public double QueueAvg; public double CycleHz; public int Ping = -1; public double LastSendTime = -1.0; public double WindowStart; private bool _haveCycle; public const string CsvHeader = "hora;peer;uid;cicloHz;turnos;envios;bloqueadoPct;colaMedia;colaMax;kbps;ping;zdosEnviadosPorSeg;fpsServidor"; public double BlockedPercent => (Calls == 0) ? 0.0 : (100.0 * (double)(BlockedFull + BlockedBudget) / (double)Calls); public void RecordCall(int queueBefore, int queueAfter, bool sent, double now) { Calls++; if (queueBefore > 10240) { BlockedFull++; } else if (10240 - queueBefore < 2048) { BlockedBudget++; } if (queueBefore > QueueMax) { QueueMax = queueBefore; } QueueAvg = ((Calls == 1) ? ((double)queueBefore) : (QueueAvg + ((double)queueBefore - QueueAvg) * 0.05)); if (sent) { Sent++; int num = queueAfter - queueBefore; if (num > 0) { BytesQueued += num; } if (LastSendTime >= 0.0 && now > LastSendTime) { double num2 = 1.0 / (now - LastSendTime); CycleHz = (_haveCycle ? (CycleHz + (num2 - CycleHz) * 0.2) : num2); _haveCycle = true; } LastSendTime = now; } } public double KilobytesPerSecond(double now) { double num = now - WindowStart; return (num <= 0.0) ? 0.0 : ((double)BytesQueued / 1024.0 / num); } public void ResetWindow(double now) { Calls = 0; Sent = 0; BlockedFull = 0; BlockedBudget = 0; BytesQueued = 0L; QueueMax = 0; WindowStart = now; } public string Line(double now) { CultureInfo invariantCulture = CultureInfo.InvariantCulture; return Name + " (" + Uid + "): ciclo=" + CycleHz.ToString("0.0", invariantCulture) + " Hz | turnos=" + Calls + " envíos=" + Sent + " | bloqueado=" + BlockedPercent.ToString("0", invariantCulture) + "% (ventana " + BlockedFull + ", presupuesto " + BlockedBudget + ") | cola media/máx=" + (QueueAvg / 1024.0).ToString("0.0", invariantCulture) + "/" + ((double)QueueMax / 1024.0).ToString("0.0", invariantCulture) + " KB | salida≈" + KilobytesPerSecond(now).ToString("0.0", invariantCulture) + " KB/s" + ((Ping >= 0) ? (" | ping=" + Ping + " ms") : string.Empty); } public string Csv(string timestamp, double now, int zdosSentPerSec, double serverFps) { CultureInfo invariantCulture = CultureInfo.InvariantCulture; return string.Join(";", timestamp, Name.Replace(';', ','), Uid.ToString(invariantCulture), CycleHz.ToString("0.00", invariantCulture), Calls.ToString(invariantCulture), Sent.ToString(invariantCulture), BlockedPercent.ToString("0.0", invariantCulture), QueueAvg.ToString("0", invariantCulture), QueueMax.ToString(invariantCulture), KilobytesPerSecond(now).ToString("0.00", invariantCulture), Ping.ToString(invariantCulture), zdosSentPerSec.ToString(invariantCulture), serverFps.ToString("0.0", invariantCulture)); } public static double TheoreticalCycleHz(int peers, double serverFps) { if (peers <= 0 || serverFps <= 0.0) { return 0.0; } double num = (double)peers / serverFps + 0.05; return 1.0 / num; } } internal static class Telemetry { private static readonly Dictionary<long, PeerStats> s_peers = new Dictionary<long, PeerStats>(); private static double s_fps; private static float s_nextLog; private static string s_csvPath; public static bool Active => NetPlugin.Enabled.Value && (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && ZDOMan.instance != null; public static PeerStats For(ZNetPeer peer) { if (peer == null) { return null; } if (!s_peers.TryGetValue(peer.m_uid, out var value)) { value = new PeerStats { Uid = peer.m_uid, WindowStart = Time.timeAsDouble }; s_peers[peer.m_uid] = value; } if (!string.IsNullOrEmpty(peer.m_playerName)) { value.Name = peer.m_playerName; } return value; } public static void Tick() { if (Active) { float deltaTime = Time.deltaTime; if (deltaTime > 0f) { double num = 1.0 / (double)deltaTime; s_fps = ((s_fps <= 0.0) ? num : (s_fps + (num - s_fps) * 0.05)); } if (NetPlugin.LogIntervalSeconds.Value > 0f && Time.time >= s_nextLog) { s_nextLog = Time.time + NetPlugin.LogIntervalSeconds.Value; Snapshot(reset: true); } } } public static List<string> Snapshot(bool reset) { List<string> list = new List<string>(); if (ZDOMan.instance == null || (Object)(object)ZNet.instance == (Object)null) { list.Add("vsm.net: sin sesión."); return list; } double timeAsDouble = Time.timeAsDouble; List<ZNetPeer> peers = ZNet.instance.GetPeers(); int sentZDOs = ZDOMan.instance.GetSentZDOs(); list.Add("vsm.net: peers=" + peers.Count + " | ZDO=" + ZDOMan.instance.NrOfObjects() + " | ZDO enviadas/s=" + sentZDOs + " recibidas/s=" + ZDOMan.instance.GetRecvZDOs() + " | fps servidor≈" + s_fps.ToString("0") + " | ciclo teórico por peer≈" + PeerStats.TheoreticalCycleHz(peers.Count, s_fps).ToString("0.0") + " Hz"); HashSet<long> hashSet = new HashSet<long>(); StringBuilder stringBuilder = null; string timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); foreach (ZNetPeer item in peers) { if (item != null) { hashSet.Add(item.m_uid); PeerStats peerStats = For(item); peerStats.Ping = SafePing(item); list.Add(" " + peerStats.Line(timeAsDouble)); if (reset && NetPlugin.LogToCsv.Value) { (stringBuilder ?? (stringBuilder = new StringBuilder())).AppendLine(peerStats.Csv(timestamp, timeAsDouble, sentZDOs, s_fps)); } if (reset) { peerStats.ResetWindow(timeAsDouble); } } } List<long> list2 = new List<long>(); foreach (long key in s_peers.Keys) { if (!hashSet.Contains(key)) { list2.Add(key); } } foreach (long item2 in list2) { s_peers.Remove(item2); } if (reset) { foreach (string item3 in list) { NetPlugin.Log.LogInfo((object)item3); } if (stringBuilder != null) { WriteCsv(stringBuilder.ToString()); } } return list; } private static int SafePing(ZNetPeer peer) { try { if (peer.m_socket == null) { return -1; } float num = default(float); float num2 = default(float); int result = default(int); float num3 = default(float); float num4 = default(float); peer.m_socket.GetConnectionQuality(ref num, ref num2, ref result, ref num3, ref num4); return result; } catch (Exception) { return -1; } } private static void WriteCsv(string rows) { try { if (s_csvPath == null) { string text = Path.Combine(Paths.ConfigPath, "vsm.net"); Directory.CreateDirectory(text); s_csvPath = Path.Combine(text, "telemetria.csv"); if (!File.Exists(s_csvPath)) { File.WriteAllText(s_csvPath, "hora;peer;uid;cicloHz;turnos;envios;bloqueadoPct;colaMedia;colaMax;kbps;ping;zdosEnviadosPorSeg;fpsServidor" + Environment.NewLine, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)); } } File.AppendAllText(s_csvPath, rows, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)); } catch (Exception ex) { NetPlugin.Log.LogWarning((object)("vsm.net: no se pudo escribir el CSV: " + ex.Message)); } } public static List<string> Owners() { List<string> list = new List<string>(); if (ZDOMan.instance == null || (Object)(object)ZNet.instance == (Object)null) { list.Add("vsm.net: sin sesión."); return list; } Dictionary<long, int> dictionary = new Dictionary<long, int>(); int num = 0; foreach (ZDO value2 in ZDOMan.instance.m_objectsByID.Values) { num++; long owner = value2.GetOwner(); dictionary.TryGetValue(owner, out var value); dictionary[owner] = value + 1; } Dictionary<long, string> dictionary2 = new Dictionary<long, string>(); foreach (ZNetPeer peer in ZNet.instance.GetPeers()) { if (peer != null) { dictionary2[peer.m_uid] = peer.m_playerName; } } List<KeyValuePair<long, int>> list2 = new List<KeyValuePair<long, int>>(dictionary); list2.Sort((KeyValuePair<long, int> a, KeyValuePair<long, int> b) => b.Value.CompareTo(a.Value)); list.Add("vsm.net: " + num + " ZDO en memoria; por dueño:"); foreach (KeyValuePair<long, int> item in list2) { string text = ((item.Key == 0L) ? "sin dueño" : ((item.Key == ZDOMan.GetSessionID()) ? "servidor" : (dictionary2.ContainsKey(item.Key) ? dictionary2[item.Key] : ("peer " + item.Key)))); list.Add(" " + text + ": " + item.Value + " (" + (100.0 * (double)item.Value / (double)Math.Max(1, num)).ToString("0.0") + "%)"); } return list; } public static void Reset() { s_peers.Clear(); s_fps = 0.0; } } public static class MyPluginInfo { public const string PLUGIN_GUID = "vsm.net"; public const string PLUGIN_NAME = "MEL Net"; public const string PLUGIN_VERSION = "0.1.4"; } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class <a8264826-ed31-4744-a6ee-6dab45ecd123>IgnoresAccessChecksToAttribute : Attribute { public <a8264826-ed31-4744-a6ee-6dab45ecd123>IgnoresAccessChecksToAttribute(string assemblyName) { } } } namespace VSM.Core.Ui { internal static class VanillaStyle { public static TMP_Text TitleFont => ((Object)(object)InventoryGui.instance != (Object)null) ? InventoryGui.instance.m_playerName : null; public static TMP_Text BodyFont => (!((Object)(object)InventoryGui.instance != (Object)null)) ? null : (((Object)(object)InventoryGui.instance.m_armor != (Object)null) ? InventoryGui.instance.m_armor : InventoryGui.instance.m_playerName); public static Image FindBackground(Transform root, Transform exclude1, Transform exclude2) { //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)root == (Object)null) { return null; } Image result = null; float num = 0f; Image[] componentsInChildren = ((Component)root).GetComponentsInChildren<Image>(true); foreach (Image val in componentsInChildren) { if ((Object)(object)val == (Object)null || (Object)(object)val.sprite == (Object)null) { continue; } Transform transform = ((Component)val).transform; if ((!((Object)(object)exclude1 != (Object)null) || !transform.IsChildOf(exclude1)) && (!((Object)(object)exclude2 != (Object)null) || !transform.IsChildOf(exclude2))) { Rect rect = ((Graphic)val).rectTransform.rect; float num2 = Mathf.Abs(((Rect)(ref rect)).width * ((Rect)(ref rect)).height); if (num2 > num) { num = num2; result = val; } } } return result; } public static bool CopyImage(Image source, Image target) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target == (Object)null) { return false; } if ((Object)(object)source == (Object)null) { ((Graphic)target).color = new Color(0f, 0f, 0f, 0.6f); return false; } target.sprite = source.sprite; target.type = source.type; ((Graphic)target).material = ((Graphic)source).material; ((Graphic)target).color = ((Graphic)source).color; target.fillCenter = source.fillCenter; target.pixelsPerUnitMultiplier = source.pixelsPerUnitMultiplier; target.preserveAspect = false; return true; } public static Image InventoryBackground(Transform exclude) { InventoryGui instance = InventoryGui.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.m_player == (Object)null) { return null; } Transform exclude2 = (Transform)(object)(((Object)(object)instance.m_playerGrid != (Object)null) ? instance.m_playerGrid.m_gridRoot : null); return FindBackground((Transform)(object)instance.m_player, exclude2, exclude); } public static void CopyFont(TMP_Text source, TMP_Text target) { //IL_0037: 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) if (!((Object)(object)source == (Object)null) && !((Object)(object)target == (Object)null)) { target.font = source.font; target.fontSharedMaterial = source.fontSharedMaterial; ((Graphic)target).color = ((Graphic)source).color; target.fontStyle = source.fontStyle; } } public static TextMeshProUGUI NewText(Transform parent, string name, TMP_Text style, float size, TextAlignmentOptions align) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0041: 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(parent, false); TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>(); CopyFont(style, (TMP_Text)(object)val2); ((TMP_Text)val2).fontSize = size; ((TMP_Text)val2).alignment = align; ((Graphic)val2).raycastTarget = false; ((TMP_Text)val2).enableWordWrapping = false; ((TMP_Text)val2).richText = true; return val2; } } } namespace VSM.Core.Runtime { internal static class Headless { private static bool? s_isHeadless; public static bool IsHeadless { get { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 if (!s_isHeadless.HasValue) { s_isHeadless = (int)SystemInfo.graphicsDeviceType == 4 || Application.isBatchMode; } return s_isHeadless.Value; } } public static bool IsServerProcess => (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer(); public static bool IsDedicatedServer => (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && ZNet.instance.IsDedicated(); public static bool IsListenHost => (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && !ZNet.instance.IsDedicated(); public static bool IsRemoteClient => (Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer(); } internal static class Keys { public static bool Pressed(KeyboardShortcut shortcut) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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) KeyCode mainKey = ((KeyboardShortcut)(ref shortcut)).MainKey; return (int)mainKey != 0 && ZInput.GetKeyDown(mainKey, false) && ((KeyboardShortcut)(ref shortcut)).Modifiers.All((KeyCode m) => ZInput.GetKey(m, false)); } } } namespace VSM.Core.Reflection { internal static class GameConstants { private static uint? s_networkVersion; private static long? s_routedEverybody; public static uint NetworkVersion { get { if (!s_networkVersion.HasValue) { s_networkVersion = ReadConstant<uint>(typeof(Version), new string[2] { "c_networkVersion", "m_networkVersion" }); } return s_networkVersion.Value; } } public static long RoutedRpcEverybody { get { if (!s_routedEverybody.HasValue) { s_routedEverybody = ReadConstant<long>(typeof(ZRoutedRpc), new string[1] { "Everybody" }); } return s_routedEverybody.Value; } } public static string GameVersionString { get { //IL_0002: 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) try { return ((object)Version.CurrentVersion/*cast due to .constrained prefix*/).ToString(); } catch (Exception) { return "?"; } } } private static T ReadConstant<T>(Type type, params string[] names) where T : struct { foreach (string name in names) { FieldInfo field = type.GetField(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (!(field == null)) { object obj = (field.IsLiteral ? field.GetRawConstantValue() : field.GetValue(null)); if (obj is T result) { return result; } try { return (T)Convert.ChangeType(obj, typeof(T)); } catch (Exception) { } } } return default(T); } } } namespace VSM.Core.Net { internal static class ZPackageExt { public static bool HasMore(this ZPackage pkg) { return pkg != null && pkg.GetPos() < pkg.Size(); } public static int ReadIntOr(this ZPackage pkg, int fallback) { return pkg.HasMore() ? pkg.ReadInt() : fallback; } public static string ReadStringOr(this ZPackage pkg, string fallback) { return pkg.HasMore() ? pkg.ReadString() : fallback; } public static bool ReadBoolOr(this ZPackage pkg, bool fallback) { return pkg.HasMore() ? pkg.ReadBool() : fallback; } public static string ReadBoundedString(this ZPackage pkg, int maxLength) { string text = pkg.ReadString(); return (text != null && text.Length <= maxLength) ? text : null; } } } namespace VSM.Core.Localization { internal static class VsmLocalization { public static void Register(ManualLogSource log, string pluginDirectory, IDictionary<string, string> embeddedSpanish) { Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.Ordinal); if (embeddedSpanish != null) { foreach (KeyValuePair<string, string> item in embeddedSpanish) { dictionary[item.Key] = item.Value; } } string path = Path.Combine(pluginDirectory ?? string.Empty, "Translations"); MergeFile(log, Path.Combine(path, "Spanish.json"), dictionary); string text = SafeSelectedLanguage(); if (!string.Equals(text, "Spanish", StringComparison.OrdinalIgnoreCase)) { MergeFile(log, Path.Combine(path, text + ".json"), dictionary); } Apply(log, dictionary); } public static string Localize(string token, params object[] args) { string text = token; try { if (Localization.instance != null && !string.IsNullOrEmpty(token)) { bool flag = token[0] != '$' && token.IndexOf(' ') < 0 && token.IndexOf('\n') < 0; string text2 = Localization.instance.Localize(flag ? ("$" + token) : token); text = ((flag && text2.Length > 1 && text2[0] == '[' && text2[text2.Length - 1] == ']') ? token : text2); } } catch (Exception) { text = token; } if (args != null && args.Length != 0) { try { text = string.Format(text, args); } catch (FormatException) { } } return text; } private static string SafeSelectedLanguage() { try { return (Localization.instance != null) ? Localization.instance.GetSelectedLanguage() : "Spanish"; } catch (Exception) { return "Spanish"; } } private static void Apply(ManualLogSource log, Dictionary<string, string> words) { if (Localization.instance == null) { if (log != null) { log.LogWarning((object)"Localization.instance aún no existe; las traducciones no se han aplicado."); } return; } foreach (KeyValuePair<string, string> word in words) { string text = (word.Key.StartsWith("$", StringComparison.Ordinal) ? word.Key.Substring(1) : word.Key); Localization.instance.AddWord(text, word.Value); } } private static void MergeFile(ManualLogSource log, string path, Dictionary<string, string> into) { if (!File.Exists(path)) { return; } try { foreach (KeyValuePair<string, string> item in ParseFlatJson(File.ReadAllText(path, Encoding.UTF8))) { into[item.Key] = item.Value; } } catch (Exception ex) { if (log != null) { log.LogWarning((object)("No se pudo leer " + path + ": " + ex.Message)); } } } public static Dictionary<string, string> ParseFlatJson(string json) { Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.Ordinal); if (string.IsNullOrEmpty(json)) { return dictionary; } int i = 0; SkipWs(json, ref i); if (i >= json.Length || json[i] != '{') { return dictionary; } i++; while (true) { SkipWs(json, ref i); if (i >= json.Length || json[i] == '}') { break; } if (json[i] == ',') { i++; continue; } string text = ReadString(json, ref i); if (text == null) { i++; continue; } SkipWs(json, ref i); if (i < json.Length && json[i] == ':') { i++; } SkipWs(json, ref i); if (i < json.Length && json[i] == '"') { string text2 = ReadString(json, ref i); dictionary[text] = text2 ?? string.Empty; } else { for (; i < json.Length && json[i] != ',' && json[i] != '}'; i++) { } } } return dictionary; } private static void SkipWs(string s, ref int i) { while (i < s.Length && char.IsWhiteSpace(s[i])) { i++; } } private static string ReadString(string s, ref int i) { if (i >= s.Length || s[i] != '"') { return null; } i++; StringBuilder stringBuilder = new StringBuilder(); while (i < s.Length) { char c = s[i++]; switch (c) { case '"': return stringBuilder.ToString(); case '\\': { if (i >= s.Length) { break; } char c2 = s[i++]; switch (c2) { case 'n': stringBuilder.Append('\n'); break; case 't': stringBuilder.Append('\t'); break; case 'r': stringBuilder.Append('\r'); break; case 'b': stringBuilder.Append('\b'); break; case 'f': stringBuilder.Append('\f'); break; case 'u': if (i + 4 <= s.Length) { stringBuilder.Append((char)Convert.ToInt32(s.Substring(i, 4), 16)); i += 4; } break; default: stringBuilder.Append(c2); break; } continue; } } stringBuilder.Append(c); } return stringBuilder.ToString(); } } } namespace VSM.Core.Harmony { internal static class PatchUtil { private static readonly List<string> s_failed = new List<string>(); public static IReadOnlyList<string> FailedTargets => s_failed; public static bool IsDegraded => s_failed.Count > 0; public static MethodInfo DeclaredMethodOrNull(ManualLogSource log, Type type, string name, Type[] parameters, string owner) { if (type == null) { Fail(log, owner, name + " (tipo nulo)"); return null; } MethodInfo methodInfo = AccessTools.DeclaredMethod(type, name, parameters, (Type[])null); if (methodInfo == null) { Fail(log, owner, type.FullName + "." + name + "(" + Describe(parameters) + ")"); } return methodInfo; } public static void PatchAllSafely(ManualLogSource log, Harmony harmony, Assembly assembly) { Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(assembly); foreach (Type type in typesFromAssembly) { if (type.GetCustomAttributes(typeof(HarmonyPatch), inherit: true).Length != 0) { PatchClassSafely(log, harmony, type); } } } public static bool PatchClassSafely(ManualLogSource log, Harmony harmony, Type patchClass) { try { harmony.CreateClassProcessor(patchClass).Patch(); return true; } catch (Exception ex) { Fail(log, harmony.Id, patchClass.FullName + " -> " + ex.GetType().Name + ": " + ex.Message); return false; } } private static void Fail(ManualLogSource log, string owner, string what) { s_failed.Add(what); if (log != null) { log.LogError((object)("[" + owner + "] No se pudo aplicar el parche (¿cambió el juego?): " + what + ". El mod sigue cargado en modo degradado.")); } } private static string Describe(Type[] parameters) { if (parameters == null || parameters.Length == 0) { return string.Empty; } string[] array = new string[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { array[i] = ((parameters[i] == null) ? "?" : parameters[i].Name); } return string.Join(", ", array); } } } namespace VSM.Core.Config { internal sealed class ConfigurationManagerAttributes { public bool? ShowRangeAsPercent; public Action<ConfigEntryBase> CustomDrawer; public bool? Browsable; public string Category; public object DefaultValue; public bool? HideDefaultButton; public bool? HideSettingName; public string Description; public string DispName; public int? Order; public bool? ReadOnly; public bool? IsAdvanced; public bool? IsAdminOnly; public Func<object, string> ObjToStr; public Func<string, object> StrToObj; } } namespace VSM.Core.Camera { internal struct RigSettings { public float Speed; public float FastMultiplier; public bool MoveRelativeToView; } internal sealed class CameraRig { public const float MaxPitch = 89f; public float Yaw; public float Pitch; public Vector3 Position; public Vector3 Velocity; public Vector3 ForwardVector => Forward(Yaw, Pitch); public Quaternion Rotation => Quaternion.Euler(Pitch, Yaw, 0f); public static Vector3 Forward(float yawDeg, float pitchDeg) { //IL_002f: 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) //IL_0037: Unknown result type (might be due to invalid IL or missing references) float num = yawDeg * ((float)Math.PI / 180f); float num2 = pitchDeg * ((float)Math.PI / 180f); float num3 = Mathf.Cos(num2); return new Vector3(Mathf.Sin(num) * num3, 0f - Mathf.Sin(num2), Mathf.Cos(num) * num3); } public static Vector3 FlatForward(float yawDeg) { //IL_001a: 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_0022: Unknown result type (might be due to invalid IL or missing references) float num = yawDeg * ((float)Math.PI / 180f); return new Vector3(Mathf.Sin(num), 0f, Mathf.Cos(num)); } public static Vector3 Right(float yawDeg) { //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_0023: Unknown result type (might be due to invalid IL or missing references) float num = yawDeg * ((float)Math.PI / 180f); return new Vector3(Mathf.Cos(num), 0f, 0f - Mathf.Sin(num)); } public void Reset(Vector3 position, Vector3 forward) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) Position = position; Velocity = Vector3.zero; SetFromDirection(forward); } public void SetFromDirection(Vector3 forward) { //IL_0035: 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_005c: Unknown result type (might be due to invalid IL or missing references) if (((Vector3)(ref forward)).sqrMagnitude < 1E-08f) { Yaw = 0f; Pitch = 0f; } else { ((Vector3)(ref forward)).Normalize(); Yaw = Mathf.Repeat(Mathf.Atan2(forward.x, forward.z) * 57.29578f, 360f); Pitch = Mathf.Clamp((0f - Mathf.Asin(Mathf.Clamp(forward.y, -1f, 1f))) * 57.29578f, -89f, 89f); } } public void ApplyLook(Vector2 delta) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) Yaw = Mathf.Repeat(Yaw + delta.x, 360f); Pitch = Mathf.Clamp(Pitch - delta.y, -89f, 89f); } public Vector3 DesiredVelocity(Vector3 move, float vertical, bool fast, RigSettings settings) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //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_0083: 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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: 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_00df: 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) Vector3 val = (settings.MoveRelativeToView ? Forward(Yaw, Pitch) : FlatForward(Yaw)); Vector3 val2 = Right(Yaw) * Mathf.Clamp(move.x, -1f, 1f) + val * Mathf.Clamp(move.z, -1f, 1f) + Vector3.up * Mathf.Clamp(vertical, -1f, 1f); if (((Vector3)(ref val2)).sqrMagnitude > 1f) { ((Vector3)(ref val2)).Normalize(); } float num = Mathf.Max(0f, settings.Speed) * (fast ? Mathf.Max(1f, settings.FastMultiplier) : 1f); return val2 * num; } public void Integrate(Vector3 desiredVelocity, float dt, float smoothing) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0047: 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) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) if (!(dt <= 0f)) { float num = ((smoothing <= 0f) ? 1f : (1f - Mathf.Exp((0f - dt) / smoothing))); Velocity = Vector3.Lerp(Velocity, desiredVelocity, num); Position += Velocity * dt; } } public static Vector3 ClampToSphere(Vector3 pos, Vector3 center, float radius) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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) Vector3 val = pos - center; float num = Mathf.Max(0f, radius); if (((Vector3)(ref val)).sqrMagnitude <= num * num) { return pos; } return center + ((Vector3)(ref val)).normalized * num; } } internal static class CameraWorld { public const float CollisionRadius = 0.25f; public static Vector3 Anchor(Player player) { //IL_0033: 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_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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) Transform eye = ((Character)player).m_eye; return ((Object)(object)eye != (Object)null) ? eye.position : (((Component)player).transform.position + Vector3.up * 1.6f); } public static Vector3 Constrain(Vector3 from, Vector3 to, Vector3 anchor, float maxDistance, float clearance, GameCamera cam) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0038: 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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) Vector3 pos = CameraRig.ClampToSphere(to, anchor, maxDistance); pos = Lift(pos, clearance, cam); pos = CameraRig.ClampToSphere(pos, anchor, maxDistance + 1f); LayerMask blockCameraMask = cam.m_blockCameraMask; Vector3 val = (Overlaps(from, blockCameraMask) ? anchor : from); return Collide(val, pos, blockCameraMask); } public static Vector3 Lift(Vector3 pos, float clearance, GameCamera cam) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) clearance = Mathf.Max(0f, clearance); ZoneSystem instance = ZoneSystem.instance; float num = default(float); if ((Object)(object)instance != (Object)null && instance.GetGroundHeight(pos, ref num)) { pos.y = Mathf.Max(pos.y, num + clearance); } float num2 = Floating.GetLiquidLevel(pos, 1f, (LiquidType)10); if ((Object)(object)instance != (Object)null && !Character.InInterior(pos)) { num2 = Mathf.Max(num2, instance.m_waterLevel); } if (num2 > -9000f) { pos.y = Mathf.Max(pos.y, num2 + Mathf.Max(clearance, cam.m_minWaterDistance)); } return pos; } public static bool Overlaps(Vector3 pos, LayerMask mask) { //IL_0001: 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) return Physics.CheckSphere(pos, 0.225f, LayerMask.op_Implicit(mask), (QueryTriggerInteraction)1); } public static Vector3 Collide(Vector3 from, Vector3 to, LayerMask mask) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0033: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) Vector3 val = to - from; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude < 1E-05f) { return to; } Vector3 val2 = val / magnitude; RaycastHit val3 = default(RaycastHit); if (Physics.SphereCast(from, 0.25f, val2, ref val3, magnitude, LayerMask.op_Implicit(mask), (QueryTriggerInteraction)1)) { return from + val2 * Mathf.Max(0f, ((RaycastHit)(ref val3)).distance - 0.02f); } return to; } } internal static class CameraLock { private const string Prefix = "vsm_camera_lock:"; public static string Holder() { GameCamera instance = GameCamera.instance; if ((Object)(object)instance == (Object)null) { return null; } Transform transform = ((Component)instance).transform; for (int i = 0; i < transform.childCount; i++) { string name = ((Object)transform.GetChild(i)).name; if (name.StartsWith("vsm_camera_lock:", StringComparison.Ordinal)) { return name.Substring("vsm_camera_lock:".Length); } } return null; } public static bool TryAcquire(string owner) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown GameCamera instance = GameCamera.instance; if ((Object)(object)instance == (Object)null) { return false; } string text = Holder(); if (text != null) { return text == owner; } GameObject val = new GameObject("vsm_camera_lock:" + owner); val.transform.SetParent(((Component)instance).transform, false); return true; } public static void Release(string owner) { GameCamera instance = GameCamera.instance; if ((Object)(object)instance == (Object)null) { return; } Transform transform = ((Component)instance).transform; for (int num = transform.childCount - 1; num >= 0; num--) { Transform child = transform.GetChild(num); if (((Object)child).name == "vsm_camera_lock:" + owner) { Object.Destroy((Object)(object)((Component)child).gameObject); ((Object)child).name = "vsm_camera_lock_released"; } } } } internal sealed class BodyHider { private readonly List<Renderer> _hidden = new List<Renderer>(); private float _nextScan; public void Update(Player player, bool hide) { if (!hide || (Object)(object)player == (Object)null) { Restore(); } else { if (Time.unscaledTime < _nextScan) { return; } _nextScan = Time.unscaledTime + 0.5f; Renderer[] componentsInChildren = ((Component)player).GetComponentsInChildren<Renderer>(false); foreach (Renderer val in componentsInChildren) { if ((Object)(object)val != (Object)null && val.enabled && (val is SkinnedMeshRenderer || val is MeshRenderer)) { val.enabled = false; _hidden.Add(val); } } } } public void Restore() { foreach (Renderer item in _hidden) { if ((Object)(object)item != (Object)null) { item.enabled = true; } } _hidden.Clear(); _nextScan = 0f; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }
plugins/VSM.Photo/VSM.Photo.dll
Decompiled 3 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ConditionalConfigSync; using HarmonyLib; using Microsoft.CodeAnalysis; using Steamworks; using TMPro; using UnityEngine; using UnityEngine.UI; using VSM.Core.Camera; using VSM.Core.Config; using VSM.Core.Harmony; using VSM.Core.Localization; using VSM.Core.Reflection; using VSM.Core.Runtime; using VSM.Core.Ui; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: <7d235df6-9ed0-4a53-9e02-a64911f97fac>IgnoresAccessChecksTo("assembly_guiutils")] [assembly: <7d235df6-9ed0-4a53-9e02-a64911f97fac>IgnoresAccessChecksTo("assembly_utils")] [assembly: <7d235df6-9ed0-4a53-9e02-a64911f97fac>IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("VSM.Photo")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("0.1.4.0")] [assembly: AssemblyInformationalVersion("0.1.4+ff27bc889ccf218c61c45d3417d48ab708a5ba8f")] [assembly: AssemblyProduct("VSM.Photo")] [assembly: AssemblyTitle("VSM.Photo")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.4.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace VSM.Photo { public static class PhotoMath { public const float MinFov = 10f; public const float MaxFov = 100f; public const float MaxRoll = 45f; public const float MaxAperture = 0.9f; public static float Zoom(float fov, float scroll, float stepPercent) { if (Mathf.Abs(scroll) < 1E-05f) { return Mathf.Clamp(fov, 10f, 100f); } float num = 1f - Mathf.Sign(scroll) * Mathf.Clamp(stepPercent, 1f, 50f) / 100f; return Mathf.Clamp(fov * num, 10f, 100f); } public static float LookScale(float fov, float baseFov) { if (baseFov <= 0f) { return 1f; } return Mathf.Clamp(fov / baseFov, 0.1f, 1.5f); } public static float Roll(float roll, float delta) { return Mathf.Clamp(roll + delta, -45f, 45f); } public static float TimeOfDay(float fraction, float delta) { return Mathf.Repeat(fraction + delta, 1f); } public static Vector4 DayWeights(float f, float transitionL, float transitionH) { //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Pow(Mathf.Max(1f - Mathf.Clamp01(f / 0.25f), Mathf.Clamp01((f - 0.75f) / 0.25f)), 0.5f); float num2 = Mathf.Pow(Mathf.Clamp01(1f - Mathf.Abs(f - 0.5f) / 0.25f), 0.5f); float num3 = Mathf.Min(Mathf.Clamp01(1f - (f - 0.26f) / (0f - transitionL)), Mathf.Clamp01(1f - (f - 0.26f) / transitionH)); float num4 = Mathf.Min(Mathf.Clamp01(1f - (f - 0.74f) / (0f - transitionH)), Mathf.Clamp01(1f - (f - 0.74f) / transitionL)); float num5 = num + num2 + num3 + num4; if (num5 <= 1E-06f) { return new Vector4(0f, 1f, 0f, 0f); } return new Vector4(num / num5, num2 / num5, num3 / num5, num4 / num5); } public static string Clock(float fraction) { int num = Mathf.FloorToInt(Mathf.Repeat(fraction, 1f) * 24f * 60f); return (num / 60).ToString("00") + ":" + (num % 60).ToString("00"); } public static float Speed(float baseSpeed, bool fast, bool slow, float fastMul, float slowMul) { float num = Mathf.Max(0f, baseSpeed); if (fast) { num *= Mathf.Max(1f, fastMul); } if (slow) { num *= Mathf.Clamp(slowMul, 0.05f, 1f); } return num; } } internal static class PhotoOverlay { private static Canvas s_canvas; private static GameObject s_grid; private static GameObject s_help; private static TextMeshProUGUI s_helpText; private static TextMeshProUGUI s_toast; private static float s_toastUntil; private static bool s_suppressed; public static bool GridVisible; public static bool HelpVisible; public static Canvas Canvas => s_canvas; public static void Ensure() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Expected O, but got Unknown //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Expected O, but got Unknown //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)s_canvas != (Object)null)) { GameObject val = new GameObject("vsm_photo_overlay", new Type[1] { typeof(RectTransform) }); Object.DontDestroyOnLoad((Object)(object)val); s_canvas = val.AddComponent<Canvas>(); s_canvas.renderMode = (RenderMode)0; s_canvas.sortingOrder = 32000; CanvasScaler val2 = val.AddComponent<CanvasScaler>(); val2.uiScaleMode = (ScaleMode)1; val2.referenceResolution = new Vector2(1920f, 1080f); val2.matchWidthOrHeight = 0.5f; s_grid = new GameObject("grid", new Type[1] { typeof(RectTransform) }); s_grid.transform.SetParent(val.transform, false); Stretch(s_grid.GetComponent<RectTransform>()); for (int i = 1; i <= 2; i++) { Line(s_grid.transform, vertical: true, (float)i / 3f); Line(s_grid.transform, vertical: false, (float)i / 3f); } s_help = new GameObject("help", new Type[1] { typeof(RectTransform) }); s_help.transform.SetParent(val.transform, false); RectTransform component = s_help.GetComponent<RectTransform>(); Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0f, 0f); component.anchorMax = val3; component.anchorMin = val3; component.pivot = new Vector2(0f, 0f); component.anchoredPosition = new Vector2(24f, 24f); component.sizeDelta = new Vector2(430f, 420f); Image val4 = s_help.AddComponent<Image>(); ((Graphic)val4).raycastTarget = false; VanillaStyle.CopyImage(VanillaStyle.InventoryBackground(null), val4); s_helpText = VanillaStyle.NewText(s_help.transform, "text", VanillaStyle.BodyFont, 16f, (TextAlignmentOptions)257); RectTransform rectTransform = ((TMP_Text)s_helpText).rectTransform; rectTransform.anchorMin = Vector2.zero; rectTransform.anchorMax = Vector2.one; rectTransform.offsetMin = new Vector2(22f, 18f); rectTransform.offsetMax = new Vector2(-22f, -18f); ((TMP_Text)s_helpText).enableWordWrapping = true; s_toast = VanillaStyle.NewText(val.transform, "toast", VanillaStyle.TitleFont, 24f, (TextAlignmentOptions)514); RectTransform rectTransform2 = ((TMP_Text)s_toast).rectTransform; ((Vector2)(ref val3))..ctor(0.5f, 1f); rectTransform2.anchorMax = val3; rectTransform2.anchorMin = val3; rectTransform2.pivot = new Vector2(0.5f, 1f); rectTransform2.anchoredPosition = new Vector2(0f, -60f); rectTransform2.sizeDelta = new Vector2(1200f, 40f); val.SetActive(false); } } private static void Stretch(RectTransform rt) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) rt.anchorMin = Vector2.zero; rt.anchorMax = Vector2.one; Vector2 offsetMin = (rt.offsetMax = Vector2.zero); rt.offsetMin = offsetMin; } private static void Line(Transform parent, bool vertical, float at) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(vertical ? "v" : "h", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); RectTransform component = val.GetComponent<RectTransform>(); component.anchorMin = (vertical ? new Vector2(at, 0f) : new Vector2(0f, at)); component.anchorMax = (vertical ? new Vector2(at, 1f) : new Vector2(1f, at)); component.sizeDelta = (vertical ? new Vector2(2f, 0f) : new Vector2(0f, 2f)); component.anchoredPosition = Vector2.zero; Image val2 = val.AddComponent<Image>(); ((Graphic)val2).raycastTarget = false; ((Graphic)val2).color = new Color(1f, 1f, 1f, 0.35f); } public static void SetActive(bool active) { Ensure(); ((Component)s_canvas).gameObject.SetActive(active); if (!active) { s_toastUntil = 0f; } } public static void Suppress(bool suppress) { s_suppressed = suppress; Refresh(); } public static void Toast(string text, float seconds = 2.5f) { Ensure(); ((TMP_Text)s_toast).text = text; s_toastUntil = Time.unscaledTime + seconds; Refresh(); } public static void SetHelp(string text) { Ensure(); ((TMP_Text)s_helpText).text = text; } public static void Refresh() { if (!((Object)(object)s_canvas == (Object)null)) { s_grid.SetActive(GridVisible && !s_suppressed); s_help.SetActive(HelpVisible && !s_suppressed); ((Component)s_toast).gameObject.SetActive(!s_suppressed && Time.unscaledTime < s_toastUntil); } } public static void Destroy() { if ((Object)(object)s_canvas != (Object)null) { Object.Destroy((Object)(object)((Component)s_canvas).gameObject); } s_canvas = null; } } internal static class PhotoPatches { [HarmonyPatch(typeof(GameCamera), "UpdateCamera", new Type[] { typeof(float) })] private static class UpdateCameraPatch { [HarmonyPrefix] [HarmonyPriority(600)] private static bool Prefix(GameCamera __instance, float dt) { return PhotoSession.UpdateCamera(__instance, dt); } } [HarmonyPatch(typeof(Player), "SetMouseLook", new Type[] { typeof(Vector2) })] private static class SetMouseLookPatch { [HarmonyPrefix] private static bool Prefix(Player __instance, Vector2 mouseLook) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (!PhotoSession.Owns(__instance)) { return true; } PhotoSession.OnLook(mouseLook); return false; } } [HarmonyPatch(typeof(Player), "SetControls", new Type[] { typeof(Vector3), typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(bool) })] private static class SetControlsPatch { [HarmonyPrefix] private static void Prefix(Player __instance, ref Vector3 movedir, ref bool attack, ref bool attackHold, ref bool secondaryAttack, ref bool secondaryAttackHold, ref bool block, ref bool blockHold, ref bool jump, ref bool crouch, ref bool run, ref bool autoRun, ref bool dodge) { //IL_0012: 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_0033: Unknown result type (might be due to invalid IL or missing references) if (PhotoSession.Owns(__instance)) { PhotoSession.OnControls(movedir, jump, crouch, run); __instance.m_autoRun = false; movedir = Vector3.zero; attack = (attackHold = (secondaryAttack = (secondaryAttackHold = false))); block = (blockHold = (jump = (crouch = (run = (autoRun = (dodge = false)))))); } } } [HarmonyPatch(typeof(Player), "TakeInput")] private static class TakeInputPatch { [HarmonyPostfix] private static void Postfix(Player __instance, ref bool __result) { if (PhotoSession.Owns(__instance)) { __result = false; } } } [HarmonyPatch(typeof(EnvMan), "FixedUpdate")] private static class EnvFixedUpdatePatch { [HarmonyPrefix] private static void Prefix(out bool __state) { __state = Time.frameCount != EnvMan.s_lastFrame; } [HarmonyPostfix] private static void Postfix(EnvMan __instance, bool __state) { if (__state) { PhotoSession.RenderFakeTime(__instance); } } } [HarmonyPatch(typeof(Player), "UpdatePlacementGhost", new Type[] { typeof(bool) })] private static class PlacementGhostPatch { [HarmonyPrefix] private static bool Prefix(Player __instance) { if (!PhotoSession.HidesBuildGhost(__instance)) { return true; } if ((Object)(object)__instance.m_placementGhost != (Object)null) { __instance.m_placementGhost.SetActive(false); } if ((Object)(object)__instance.m_placementMarkerInstance != (Object)null) { __instance.m_placementMarkerInstance.SetActive(false); } return false; } } [HarmonyPatch(typeof(Player), "UpdateWearNTearHover")] private static class WearNTearHoverPatch { [HarmonyPrefix] private static bool Prefix(Player __instance) { if (!PhotoSession.HidesBuildGhost(__instance)) { return true; } __instance.m_hoveringPiece = null; return false; } } [HarmonyPatch(typeof(Player), "SetLocalPlayer")] private static class SetLocalPlayerPatch { [HarmonyPostfix] private static void Postfix() { PhotoSession.Reset(); } } [HarmonyPatch(typeof(Player), "OnDestroy")] private static class PlayerDestroyPatch { [HarmonyPrefix] private static void Prefix(Player __instance) { if (PhotoSession.Owns(__instance)) { PhotoSession.Reset(); } } } [HarmonyPatch(typeof(GameCamera), "OnDestroy")] private static class CameraDestroyPatch { [HarmonyPrefix] private static void Prefix() { PhotoSession.Reset(); } } [HarmonyPatch(typeof(Terminal), "InitTerminal")] private static class TerminalInitPatch { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__1_0; internal void <Postfix>b__1_0(ConsoleEventArgs args) { args.Context.AddString(PhotoSession.Status()); } } private static bool s_registered; [HarmonyPostfix] private static void Postfix() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown if (s_registered) { return; } s_registered = true; object obj = <>c.<>9__1_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { args.Context.AddString(PhotoSession.Status()); }; <>c.<>9__1_0 = val; obj = (object)val; } new ConsoleCommand("vsm_photo", "Estado y límites del modo foto (vsm.photo)", (ConsoleEvent)obj, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } } internal static readonly Type[] SetControlsSignature = new Type[12] { typeof(Vector3), typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(bool) }; } [BepInPlugin("vsm.photo", "MEL Photo", "0.1.4")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class PhotoPlugin : BaseUnityPlugin { internal static ManualLogSource Log; private static ConfigSync s_sync; private Harmony _harmony; internal static bool PatchesOk; public static ConfigEntry<bool> Enabled; public static ConfigEntry<float> MaxCameraDistance; public static ConfigEntry<float> MinTerrainClearance; public static ConfigEntry<float> CombatCooldownSeconds; public static ConfigEntry<bool> ExitOnDamage; public static ConfigEntry<bool> ExitWhenSensed; public static ConfigEntry<bool> AllowTimeOfDay; public static ConfigEntry<bool> AllowDepthOfField; public static ConfigEntry<bool> ServerLock; public static ConfigEntry<KeyboardShortcut> ToggleKey; public static ConfigEntry<KeyCode> CaptureKey; public static ConfigEntry<KeyCode> RollLeftKey; public static ConfigEntry<KeyCode> RollRightKey; public static ConfigEntry<KeyCode> ResetKey; public static ConfigEntry<KeyCode> TimeEarlierKey; public static ConfigEntry<KeyCode> TimeLaterKey; public static ConfigEntry<KeyCode> TimeResetKey; public static ConfigEntry<KeyCode> DofKey; public static ConfigEntry<KeyCode> HideBodyKey; public static ConfigEntry<KeyCode> GridKey; public static ConfigEntry<KeyCode> GameUiKey; public static ConfigEntry<KeyCode> HelpKey; public static ConfigEntry<float> MoveSpeed; public static ConfigEntry<float> FastMultiplier; public static ConfigEntry<float> SlowMultiplier; public static ConfigEntry<float> MoveSmoothing; public static ConfigEntry<float> ZoomStepPercent; public static ConfigEntry<float> RollSpeed; public static ConfigEntry<float> TimeSpeed; public static ConfigEntry<float> Aperture; public static ConfigEntry<bool> HideGameUiOnEnter; public static ConfigEntry<bool> ShowHelpOnEnter; public static ConfigEntry<bool> GridOnEnter; private static readonly Dictionary<string, string> s_spanish = new Dictionary<string, string> { { "vsm_photo_on", "Modo foto · {0} para salir" }, { "vsm_photo_captured", "Captura de Steam hecha" }, { "vsm_photo_no_steam", "Steam no está disponible: usa F12" }, { "vsm_photo_deny_combat", "Hay enemigos cerca: modo foto bloqueado {0} s" }, { "vsm_photo_deny_camerabusy", "La cámara de construcción está activa: ciérrala primero" }, { "vsm_photo_deny_confignotready", "Esperando la configuración del servidor…" }, { "vsm_photo_exit_damaged", "Modo foto cerrado: has recibido daño" } }; public static bool IsConfigReady => s_sync != null && (((ConditionalConfigSync)s_sync).IsSourceOfTruth || ((ConditionalConfigSync)s_sync).InitialSyncDone); private void Awake() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0044: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Expected O, but got Unknown //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Expected O, but got Unknown //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Expected O, but got Unknown //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Expected O, but got Unknown //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Expected O, but got Unknown //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Expected O, but got Unknown //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Expected O, but got Unknown //IL_02f4: Unknown result type (might be due to invalid IL or missing references) //IL_04c5: Unknown result type (might be due to invalid IL or missing references) //IL_04cf: Expected O, but got Unknown //IL_0502: Unknown result type (might be due to invalid IL or missing references) //IL_050c: Expected O, but got Unknown //IL_053f: Unknown result type (might be due to invalid IL or missing references) //IL_0549: Expected O, but got Unknown //IL_057c: Unknown result type (might be due to invalid IL or missing references) //IL_0586: Expected O, but got Unknown //IL_05b9: Unknown result type (might be due to invalid IL or missing references) //IL_05c3: Expected O, but got Unknown //IL_05f6: Unknown result type (might be due to invalid IL or missing references) //IL_0600: Expected O, but got Unknown //IL_0633: Unknown result type (might be due to invalid IL or missing references) //IL_063d: Expected O, but got Unknown //IL_0670: Unknown result type (might be due to invalid IL or missing references) //IL_067a: Expected O, but got Unknown //IL_0750: Unknown result type (might be due to invalid IL or missing references) //IL_075a: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; s_sync = new ConfigSync("vsm.photo") { DisplayName = "MEL Photo", CurrentVersion = "0.1.4", MinimumRequiredVersion = "0.1.4", ModRequired = true }; Enabled = Synced<bool>(((BaseUnityPlugin)this).Config.Bind<bool>("1. Límites (servidor)", "Enabled", true, new ConfigDescription("Permite usar el modo foto. Con false nadie puede entrar y los que estén dentro salen.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 100 } }))); MaxCameraDistance = Synced<float>(((BaseUnityPlugin)this).Config.Bind<float>("1. Límites (servidor)", "MaxCameraDistance", 30f, new ConfigDescription("Distancia máxima (m) de la cámara al jugador. En un servidor sin mapa evita usarlo para explorar (tope 60).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(3f, 60f), new object[1] { new ConfigurationManagerAttributes { Order = 99 } }))); MinTerrainClearance = Synced<float>(((BaseUnityPlugin)this).Config.Bind<float>("1. Límites (servidor)", "MinTerrainClearance", 0.3f, new ConfigDescription("Altura mínima (m) de la cámara sobre el terreno y el agua.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), new object[1] { new ConfigurationManagerAttributes { Order = 98 } }))); CombatCooldownSeconds = Synced<float>(((BaseUnityPlugin)this).Config.Bind<float>("1. Límites (servidor)", "CombatCooldownSeconds", 5f, new ConfigDescription("Segundos desde que un enemigo detectó al jugador hasta poder entrar en modo foto.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 120f), new object[1] { new ConfigurationManagerAttributes { Order = 97 } }))); ExitOnDamage = Synced<bool>(((BaseUnityPlugin)this).Config.Bind<bool>("1. Límites (servidor)", "ExitOnDamage", true, new ConfigDescription("Salir del modo foto al recibir daño (el cuerpo queda quieto y vulnerable).", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 96 } }))); ExitWhenSensed = Synced<bool>(((BaseUnityPlugin)this).Config.Bind<bool>("1. Límites (servidor)", "ExitWhenSensed", false, new ConfigDescription("Salir del modo foto en cuanto un enemigo te detecte (con false se pueden sacar fotos de combate).", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 95 } }))); AllowTimeOfDay = Synced<bool>(((BaseUnityPlugin)this).Config.Bind<bool>("1. Límites (servidor)", "AllowTimeOfDay", true, new ConfigDescription("Permitir cambiar la hora del día (solo visual y solo para quien hace la foto; no cambia la noche real ni los spawns).", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 94 } }))); AllowDepthOfField = Synced<bool>(((BaseUnityPlugin)this).Config.Bind<bool>("1. Límites (servidor)", "AllowDepthOfField", true, new ConfigDescription("Permitir la profundidad de campo (fondo desenfocado).", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 93 } }))); ServerLock = ((BaseUnityPlugin)this).Config.Bind<bool>("1. Límites (servidor)", "ServerLock", true, "Bloquea la configuración sincronizada: solo los administradores del servidor pueden cambiarla."); ((ConditionalConfigSync)s_sync).AddLockingConfigEntry<bool>(ServerLock); ToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("2. Teclas", "ToggleKey", new KeyboardShortcut((KeyCode)289, Array.Empty<KeyCode>()), "Entrar/salir del modo foto (también se sale con Esc)."); CaptureKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("2. Teclas", "CaptureKey", (KeyCode)323, "Hacer la captura de Steam (igual que F12, sin la cuadrícula ni la ayuda)."); RollLeftKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("2. Teclas", "RollLeftKey", (KeyCode)113, "Inclinar la cámara a la izquierda (mantener)."); RollRightKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("2. Teclas", "RollRightKey", (KeyCode)101, "Inclinar la cámara a la derecha (mantener)."); ResetKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("2. Teclas", "ResetKey", (KeyCode)114, "Quitar inclinación y zoom."); TimeEarlierKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("2. Teclas", "TimeEarlierKey", (KeyCode)122, "Retrasar la hora del día (mantener; solo visual)."); TimeLaterKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("2. Teclas", "TimeLaterKey", (KeyCode)120, "Adelantar la hora del día (mantener; solo visual)."); TimeResetKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("2. Teclas", "TimeResetKey", (KeyCode)99, "Volver a la hora real."); DofKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("2. Teclas", "DepthOfFieldKey", (KeyCode)102, "Activar/desactivar la profundidad de campo (enfoca lo que está en el centro; Alt + rueda = apertura)."); HideBodyKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("2. Teclas", "HideBodyKey", (KeyCode)118, "Ocultar/mostrar tu personaje."); GridKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("2. Teclas", "GridKey", (KeyCode)103, "Mostrar/ocultar la cuadrícula de tercios."); GameUiKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("2. Teclas", "GameUiKey", (KeyCode)117, "Mostrar/ocultar la interfaz del juego."); HelpKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("2. Teclas", "HelpKey", (KeyCode)104, "Mostrar/ocultar la ayuda de controles."); MoveSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("3. Cámara", "MoveSpeed", 5f, new ConfigDescription("Velocidad de la cámara (m/s).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 30f), Array.Empty<object>())); FastMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("3. Cámara", "FastMultiplier", 3f, new ConfigDescription("Multiplicador al mantener correr.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 6f), Array.Empty<object>())); SlowMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("3. Cámara", "SlowMultiplier", 0.25f, new ConfigDescription("Multiplicador al mantener Alt (movimiento fino).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 1f), Array.Empty<object>())); MoveSmoothing = ((BaseUnityPlugin)this).Config.Bind<float>("3. Cámara", "MoveSmoothing", 0.3f, new ConfigDescription("Suavizado del movimiento (s). Más alto = más cinematográfico.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1.5f), Array.Empty<object>())); ZoomStepPercent = ((BaseUnityPlugin)this).Config.Bind<float>("3. Cámara", "ZoomStepPercent", 8f, new ConfigDescription("Cuánto cambia el zoom por paso de rueda (%).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 50f), Array.Empty<object>())); RollSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("3. Cámara", "RollSpeed", 30f, new ConfigDescription("Velocidad de inclinación (grados/s).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 120f), Array.Empty<object>())); TimeSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("3. Cámara", "TimeSpeed", 0.05f, new ConfigDescription("Velocidad al cambiar la hora (fracción del día por segundo; 0,05 ≈ 1 h cada 0,8 s).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.005f, 0.5f), Array.Empty<object>())); Aperture = ((BaseUnityPlugin)this).Config.Bind<float>("3. Cámara", "Aperture", 0.6f, new ConfigDescription("Apertura de la profundidad de campo (más alto = fondo más borroso; máximo 0,9).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 0.9f), Array.Empty<object>())); HideGameUiOnEnter = ((BaseUnityPlugin)this).Config.Bind<bool>("3. Cámara", "HideGameUiOnEnter", true, "Ocultar la interfaz del juego al entrar en modo foto."); ShowHelpOnEnter = ((BaseUnityPlugin)this).Config.Bind<bool>("3. Cámara", "ShowHelpOnEnter", true, "Mostrar la ayuda de controles al entrar."); GridOnEnter = ((BaseUnityPlugin)this).Config.Bind<bool>("3. Cámara", "GridOnEnter", false, "Mostrar la cuadrícula de tercios al entrar."); Log.LogInfo((object)("vsm.photo 0.1.4 | Valheim " + GameConstants.GameVersionString + " | headless=" + Headless.IsHeadless)); if (Headless.IsHeadless) { Log.LogInfo((object)"vsm.photo: servidor dedicado: solo configuración, sin parches."); return; } VsmLocalization.Register(Log, Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), s_spanish); _harmony = new Harmony("vsm.photo"); PatchUtil.PatchAllSafely(Log, _harmony, Assembly.GetExecutingAssembly()); PatchesOk = Owns(AccessTools.DeclaredMethod(typeof(GameCamera), "UpdateCamera", new Type[1] { typeof(float) }, (Type[])null)) && Owns(AccessTools.DeclaredMethod(typeof(Player), "SetMouseLook", new Type[1] { typeof(Vector2) }, (Type[])null)) && Owns(AccessTools.DeclaredMethod(typeof(Player), "SetControls", PhotoPatches.SetControlsSignature, (Type[])null)) && Owns(AccessTools.DeclaredMethod(typeof(Player), "TakeInput", (Type[])null, (Type[])null)); if (!PatchesOk) { Log.LogError((object)"vsm.photo: faltan parches críticos; el modo foto queda desactivado."); _harmony.UnpatchSelf(); _harmony = null; } } private static ConfigEntry<T> Synced<T>(ConfigEntry<T> entry) { ((ConditionalConfigSync)s_sync).AddConfigEntry<T>(entry, (ConfigSyncMode)0); return entry; } private static bool Owns(MethodBase m) { if (m == null) { return false; } Patches patchInfo = Harmony.GetPatchInfo(m); return patchInfo != null && patchInfo.Owners.Contains("vsm.photo"); } private void Update() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) if (_harmony == null) { return; } Player localPlayer = Player.m_localPlayer; if (Keys.Pressed(ToggleKey.Value) && (Object)(object)localPlayer != (Object)null && !Console.IsVisible() && (!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus()) && !TextInput.IsVisible()) { PhotoDenial denial; if (PhotoSession.Active) { PhotoSession.Exit(PhotoDenial.User); } else if (!PhotoSession.TryEnter(localPlayer, out denial)) { Notify(localPlayer, denial); } } else { PhotoSession.HandleKeys((MonoBehaviour)(object)this); } } private static void Notify(Player player, PhotoDenial denial) { string token = "vsm_photo_deny_" + denial.ToString().ToLowerInvariant(); string text = ((denial == PhotoDenial.Combat) ? VsmLocalization.Localize(token, Mathf.CeilToInt(PhotoSession.CombatRemaining(player))) : VsmLocalization.Localize(token)); ((Character)player).Message((MessageType)1, text, 0, (Sprite)null, false); } private void OnDestroy() { PhotoSession.Reset(); PhotoOverlay.Destroy(); if (_harmony != null) { _harmony.UnpatchSelf(); } } } internal enum PhotoDenial { None, User, PatchesMissing, Disabled, ConfigNotReady, NoPlayer, CameraBusy, FreeFly, UiOpen, Dead, Cutscene, Teleporting, Swimming, Combat, Damaged, Sensed, Menu, Error } internal static class PhotoSession { public static PhotoDenial LastExit = PhotoDenial.None; private static readonly CameraRig s_rig = new CameraRig(); private static readonly BodyHider s_body = new BodyHider(); private static readonly Action<float, Character> s_damageHandler = delegate(float d, Character a) { if (d > 0f) { s_damaged = true; } }; private static Player s_player; private static Vector3 s_move; private static float s_vertical; private static bool s_fast; private static Vector3 s_lastPos; private static bool s_damaged; private static float s_fov; private static float s_baseFov; private static float s_roll; private static bool s_hideBody; private static bool s_capturing; private static bool s_uiShownForMenu; private static float s_savedCamFov; private static float s_savedNear; private static bool s_timeOverride; private static float s_time; private static int s_session; private static float s_scrollAcc; private static bool s_dofOn; private static bool s_dofSaved; private static bool s_savedDofEnabled; private static bool s_savedDofAuto; private static float s_savedFocal; private static float s_savedAperture; private static float s_focus = 10f; private static readonly FieldInfo s_dofField = AccessTools.Field(typeof(CameraEffects), "m_dof"); public static bool Active { get; private set; } public static bool TimeOverrideActive => Active && s_timeOverride; public static bool WantsBodyVisible => Active && !s_hideBody; public static bool Owns(Player player) { return Active && (Object)(object)player != (Object)null && (Object)(object)player == (Object)(object)s_player; } public static bool HidesBuildGhost(Player player) { return Owns(player); } public static PhotoDenial CanEnter(Player player) { if (!PhotoPlugin.PatchesOk) { return PhotoDenial.PatchesMissing; } if (!PhotoPlugin.Enabled.Value) { return PhotoDenial.Disabled; } if (!PhotoPlugin.IsConfigReady) { return PhotoDenial.ConfigNotReady; } if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer || (Object)(object)GameCamera.instance == (Object)null) { return PhotoDenial.NoPlayer; } if (GameCamera.InFreeFly()) { return PhotoDenial.FreeFly; } string text = CameraLock.Holder(); if (text != null && text != "vsm.photo") { return PhotoDenial.CameraBusy; } if (UiOpen()) { return PhotoDenial.UiOpen; } PhotoDenial photoDenial = BodyState(player); if (photoDenial != PhotoDenial.None) { return photoDenial; } if (CombatRemaining(player) > 0f) { return PhotoDenial.Combat; } return PhotoDenial.None; } private static PhotoDenial BodyState(Player player) { if (((Character)player).IsDead()) { return PhotoDenial.Dead; } if (((Character)player).InCutscene() || ((Character)player).InIntro()) { return PhotoDenial.Cutscene; } if (((Character)player).IsTeleporting()) { return PhotoDenial.Teleporting; } if (((Character)player).IsSwimming()) { return PhotoDenial.Swimming; } return PhotoDenial.None; } public static float CombatRemaining(Player player) { return Mathf.Max(0f, PhotoPlugin.CombatCooldownSeconds.Value - player.m_timeSinceSensed); } private static bool UiOpen() { return ((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus()) || Console.IsVisible() || TextInput.IsVisible() || StoreGui.IsVisible() || InventoryGui.IsVisible() || Menu.IsVisible() || Minimap.IsOpen() || Hud.IsPieceSelectionVisible() || Hud.InRadial() || UnifiedPopup.IsVisible() || PlayerCustomizaton.IsBarberGuiVisible() || ((Object)(object)TextViewer.instance != (Object)null && TextViewer.instance.IsVisible()); } public static bool TryEnter(Player player, out PhotoDenial denial) { //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //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_0107: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) denial = CanEnter(player); if (denial != PhotoDenial.None) { return false; } GameCamera instance = GameCamera.instance; if (!CameraLock.TryAcquire("vsm.photo")) { denial = PhotoDenial.CameraBusy; return false; } try { s_player = player; s_savedCamFov = (((Object)(object)instance.m_camera != (Object)null) ? instance.m_camera.fieldOfView : instance.m_fov); s_savedNear = (((Object)(object)instance.m_camera != (Object)null) ? instance.m_camera.nearClipPlane : instance.m_nearClipPlaneMin); s_baseFov = ((instance.m_fov > 1f) ? instance.m_fov : 65f); s_fov = Mathf.Clamp(s_savedCamFov, 10f, 100f); s_roll = 0f; s_rig.Reset(((Component)instance).transform.position, ((Component)instance).transform.forward); s_lastPos = s_rig.Position; s_move = Vector3.zero; s_vertical = 0f; s_fast = false; s_damaged = false; s_hideBody = false; s_timeOverride = false; s_time = (((Object)(object)EnvMan.instance != (Object)null) ? EnvMan.instance.GetDayFraction() : 0.5f); s_scrollAcc = 0f; s_session++; player.m_autoRun = false; s_dofOn = false; s_dofSaved = false; ((Character)player).m_onDamaged = (Action<float, Character>)Delegate.Combine(((Character)player).m_onDamaged, s_damageHandler); Active = true; LastExit = PhotoDenial.None; PhotoOverlay.Ensure(); PhotoOverlay.SetActive(active: true); PhotoOverlay.GridVisible = PhotoPlugin.GridOnEnter.Value; PhotoOverlay.HelpVisible = PhotoPlugin.ShowHelpOnEnter.Value; PhotoOverlay.SetHelp(HelpText()); PhotoOverlay.Suppress(suppress: false); if (PhotoPlugin.HideGameUiOnEnter.Value) { UiHider.Hide(PhotoOverlay.Canvas); } PhotoOverlay.Toast(L("vsm_photo_on", ((object)PhotoPlugin.ToggleKey.Value/*cast due to .constrained prefix*/).ToString())); return true; } catch (Exception ex) { PhotoPlugin.Log.LogError((object)("vsm.photo: error al entrar en modo foto: " + ex)); Restore(null); denial = PhotoDenial.Error; return false; } } public static void Exit(PhotoDenial reason) { if (Active) { LastExit = reason; Player val = s_player; Restore(val); if ((Object)(object)val != (Object)null && reason != PhotoDenial.User) { ((Character)val).Message((MessageType)1, L("vsm_photo_exit_" + reason.ToString().ToLowerInvariant()), 0, (Sprite)null, false); } } } private static void Restore(Player player) { Active = false; s_player = null; s_capturing = false; s_uiShownForMenu = false; try { GameCamera instance = GameCamera.instance; if ((Object)(object)instance != (Object)null) { if ((Object)(object)instance.m_camera != (Object)null) { instance.m_camera.fieldOfView = ((s_savedCamFov > 1f) ? s_savedCamFov : instance.m_fov); instance.m_camera.nearClipPlane = s_savedNear; } if ((Object)(object)instance.m_skyCamera != (Object)null) { instance.m_skyCamera.fieldOfView = ((s_savedCamFov > 1f) ? s_savedCamFov : instance.m_fov); } } s_timeOverride = false; s_session++; RestoreDof(); s_body.Restore(); UiHider.Show(); PhotoOverlay.Suppress(suppress: false); PhotoOverlay.SetActive(active: false); if ((Object)(object)player != (Object)null) { ((Character)player).m_onDamaged = (Action<float, Character>)Delegate.Remove(((Character)player).m_onDamaged, s_damageHandler); } } catch (Exception ex) { PhotoPlugin.Log.LogWarning((object)("vsm.photo: error al restaurar: " + ex.Message)); } finally { CameraLock.Release("vsm.photo"); } } public static void Reset() { if (Active) { LastExit = PhotoDenial.NoPlayer; Player player = s_player; try { Restore(player); } catch (Exception) { } } } public static void OnLook(Vector2 delta) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) if (!Paused() && !(delta == Vector2.zero)) { s_rig.ApplyLook(delta * PhotoMath.LookScale(s_fov, s_baseFov)); } } public static void OnControls(Vector3 movedir, bool jump, bool crouch, bool run) { //IL_0001: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) s_move = new Vector3(Mathf.Clamp(movedir.x, -1f, 1f), 0f, Mathf.Clamp(movedir.z, -1f, 1f)); s_fast = run; } internal static float HeldVertical() { bool flag = ZInput.GetButton("Jump") || ZInput.GetButton("JoyJump"); bool flag2 = ZInput.GetButton("Crouch") || ZInput.GetButton("JoyCrouch"); return (flag ? 1f : 0f) - (flag2 ? 1f : 0f); } private static bool Paused() { return UiOpen() || s_capturing; } private static bool Key(KeyCode k) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) return (int)k != 0 && ZInput.GetKey(k, false); } private static bool KeyDown(KeyCode k) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) return (int)k != 0 && ZInput.GetKeyDown(k, false); } public static void HandleKeys(MonoBehaviour host) { //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_020e: 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_0272: Unknown result type (might be due to invalid IL or missing references) //IL_0324: Unknown result type (might be due to invalid IL or missing references) //IL_0372: Unknown result type (might be due to invalid IL or missing references) //IL_040a: Unknown result type (might be due to invalid IL or missing references) //IL_0456: Unknown result type (might be due to invalid IL or missing references) //IL_0480: Unknown result type (might be due to invalid IL or missing references) //IL_04aa: Unknown result type (might be due to invalid IL or missing references) //IL_04e9: Unknown result type (might be due to invalid IL or missing references) if (!Active) { return; } bool flag = UiOpen(); if (flag && UiHider.Hidden) { UiHider.Show(); s_uiShownForMenu = true; } else if (!flag && s_uiShownForMenu) { s_uiShownForMenu = false; UiHider.Hide(PhotoOverlay.Canvas); } if (Paused()) { s_scrollAcc = 0f; return; } float unscaledDeltaTime = Time.unscaledDeltaTime; s_scrollAcc += ZInput.GetMouseScrollWheel(); float num = 0f; if (s_scrollAcc > 0.1f) { num = 1f; s_scrollAcc = 0f; } else if (s_scrollAcc < -0.1f) { num = -1f; s_scrollAcc = 0f; } if (num != 0f) { if (s_dofOn && Key((KeyCode)308)) { PhotoPlugin.Aperture.Value = Mathf.Clamp(Mathf.Round((PhotoPlugin.Aperture.Value + num * 0.05f) * 20f) / 20f, 0.05f, 0.9f); PhotoOverlay.Toast(L("vsm_photo_aperture", PhotoPlugin.Aperture.Value.ToString("0.00")), 1f); } else { s_fov = PhotoMath.Zoom(s_fov, num, PhotoPlugin.ZoomStepPercent.Value); } } if (Key(PhotoPlugin.RollLeftKey.Value)) { s_roll = PhotoMath.Roll(s_roll, PhotoPlugin.RollSpeed.Value * unscaledDeltaTime); } if (Key(PhotoPlugin.RollRightKey.Value)) { s_roll = PhotoMath.Roll(s_roll, (0f - PhotoPlugin.RollSpeed.Value) * unscaledDeltaTime); } if (KeyDown(PhotoPlugin.ResetKey.Value)) { s_roll = 0f; s_fov = Mathf.Clamp(s_baseFov, 10f, 100f); PhotoOverlay.Toast(L("vsm_photo_reset"), 1.2f); } bool flag2 = Key(PhotoPlugin.TimeEarlierKey.Value); bool flag3 = Key(PhotoPlugin.TimeLaterKey.Value); if ((flag2 || flag3) && PhotoPlugin.AllowTimeOfDay.Value && (Object)(object)EnvMan.instance != (Object)null) { if (!s_timeOverride) { s_timeOverride = true; s_time = EnvMan.instance.GetDayFraction(); } s_time = PhotoMath.TimeOfDay(s_time, (flag3 ? 1f : (-1f)) * PhotoPlugin.TimeSpeed.Value * unscaledDeltaTime); PhotoOverlay.Toast(L("vsm_photo_time", PhotoMath.Clock(s_time)), 1f); } if (KeyDown(PhotoPlugin.TimeResetKey.Value) && s_timeOverride && (Object)(object)EnvMan.instance != (Object)null) { s_timeOverride = false; PhotoOverlay.Toast(L("vsm_photo_time_real"), 1.2f); } if (KeyDown(PhotoPlugin.DofKey.Value)) { if (!PhotoPlugin.AllowDepthOfField.Value) { PhotoOverlay.Toast(L("vsm_photo_dof_disabled"), 1.5f); } else { s_dofOn = !s_dofOn; if (!s_dofOn) { RestoreDof(); } PhotoOverlay.Toast(L(s_dofOn ? "vsm_photo_dof_on" : "vsm_photo_dof_off"), 1.2f); } } if (KeyDown(PhotoPlugin.HideBodyKey.Value)) { s_hideBody = !s_hideBody; PhotoOverlay.Toast(L(s_hideBody ? "vsm_photo_body_hidden" : "vsm_photo_body_shown"), 1.2f); } if (KeyDown(PhotoPlugin.GridKey.Value)) { PhotoOverlay.GridVisible = !PhotoOverlay.GridVisible; PhotoOverlay.Refresh(); } if (KeyDown(PhotoPlugin.HelpKey.Value)) { PhotoOverlay.HelpVisible = !PhotoOverlay.HelpVisible; PhotoOverlay.Refresh(); } if (KeyDown(PhotoPlugin.GameUiKey.Value)) { s_uiShownForMenu = false; if (UiHider.Hidden) { UiHider.Show(); } else { UiHider.Hide(PhotoOverlay.Canvas); } } if (KeyDown(PhotoPlugin.CaptureKey.Value)) { host.StartCoroutine(Capture()); } PhotoOverlay.Refresh(); UiHider.Tick(PhotoOverlay.Canvas); } private static IEnumerator Capture() { if (s_capturing) { yield break; } int session = s_session; s_capturing = true; PhotoOverlay.Suppress(suppress: true); UiHider.Rescan(PhotoOverlay.Canvas); yield return null; yield return (object)new WaitForEndOfFrame(); if (!Active || session != s_session) { s_capturing = false; yield break; } UiHider.Rescan(PhotoOverlay.Canvas); bool ok = false; try { if (SteamManager.Initialized) { SteamScreenshots.TriggerScreenshot(); ok = true; } } catch (Exception ex) { Exception ex2 = ex; PhotoPlugin.Log.LogWarning((object)("vsm.photo: la captura de Steam falló: " + ex2.Message)); } yield return (object)new WaitForSecondsRealtime(0.3f); s_capturing = false; if (Active && session == s_session) { PhotoOverlay.Suppress(suppress: false); PhotoOverlay.Toast(L(ok ? "vsm_photo_captured" : "vsm_photo_no_steam"), ok ? 1.2f : 3f); } } public static bool UpdateCamera(GameCamera cam, float dt) { //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: 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_00e2: 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_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_015f: 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_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0181: 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_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) if (!Active) { return true; } try { Player val = s_player; PhotoDenial photoDenial = MustExit(val); if (photoDenial != PhotoDenial.None) { Exit(photoDenial); return true; } bool flag = Paused(); RigSettings settings = new RigSettings { Speed = PhotoMath.Speed(PhotoPlugin.MoveSpeed.Value, fast: false, !flag && Key((KeyCode)308), 1f, PhotoPlugin.SlowMultiplier.Value), FastMultiplier = PhotoPlugin.FastMultiplier.Value, MoveRelativeToView = true }; s_vertical = (flag ? 0f : HeldVertical()); Vector3 desiredVelocity = (flag ? Vector3.zero : s_rig.DesiredVelocity(s_move, s_vertical, s_fast, settings)); s_rig.Integrate(desiredVelocity, dt, PhotoPlugin.MoveSmoothing.Value); float maxDistance = Mathf.Clamp(PhotoPlugin.MaxCameraDistance.Value, 3f, 60f); Vector3 val2 = CameraWorld.Constrain(s_lastPos, s_rig.Position, CameraWorld.Anchor(val), maxDistance, PhotoPlugin.MinTerrainClearance.Value, cam); s_rig.Velocity = ((dt > 0f) ? ((val2 - s_lastPos) / dt) : Vector3.zero); s_rig.Position = val2; s_lastPos = val2; Transform transform = ((Component)cam).transform; transform.position = val2; transform.rotation = s_rig.Rotation * Quaternion.Euler(0f, 0f, s_roll); if ((Object)(object)cam.m_camera != (Object)null) { cam.m_camera.fieldOfView = s_fov; cam.m_camera.nearClipPlane = cam.m_nearClipPlaneMin; } if ((Object)(object)cam.m_skyCamera != (Object)null) { cam.m_skyCamera.fieldOfView = s_fov; } s_body.Update(val, s_hideBody); if (!s_hideBody) { ((Character)val).SetVisible(true); } if (s_dofOn) { UpdateDof(transform); } return false; } catch (Exception ex) { PhotoPlugin.Log.LogError((object)("vsm.photo: error en la cámara, se vuelve a la vanilla: " + ex)); Exit(PhotoDenial.Error); return true; } } private static PhotoDenial MustExit(Player player) { if (!PhotoPlugin.Enabled.Value) { return PhotoDenial.Disabled; } if (!PhotoPlugin.IsConfigReady) { return PhotoDenial.ConfigNotReady; } if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer) { return PhotoDenial.NoPlayer; } if (Menu.IsVisible()) { return PhotoDenial.Menu; } if (GameCamera.InFreeFly()) { return PhotoDenial.FreeFly; } PhotoDenial photoDenial = BodyState(player); if (photoDenial != PhotoDenial.None) { return photoDenial; } if (s_damaged && PhotoPlugin.ExitOnDamage.Value) { return PhotoDenial.Damaged; } if (PhotoPlugin.ExitWhenSensed.Value && player.IsSensed()) { return PhotoDenial.Sensed; } return PhotoDenial.None; } public static void RenderFakeTime(EnvMan env) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) if (!TimeOverrideActive || (Object)(object)env == (Object)null) { return; } float smoothDayFraction = env.m_smoothDayFraction; try { EnvSetup val = ((!string.IsNullOrEmpty(env.m_forceEnv)) ? env.GetEnv(env.m_forceEnv) : env.m_currentEnv); if (val != null) { env.m_smoothDayFraction = s_time; Vector4 val2 = PhotoMath.DayWeights(s_time, env.m_sunHorizonTransitionL, env.m_sunHorizonTransitionH); env.SetEnv(val, val2.y, val2.x, val2.z, val2.w, 0f); } } catch (Exception ex) { PhotoPlugin.Log.LogWarning((object)("vsm.photo: no se pudo pintar la hora elegida, se vuelve a la real: " + ex.Message)); s_timeOverride = false; } finally { env.m_smoothDayFraction = smoothDayFraction; } } private static Behaviour Dof(CameraEffects fx) { return (Behaviour)(((Object)(object)fx != (Object)null && s_dofField != null) ? /*isinst with value type is only supported in some contexts*/: null); } private static void SetDofField(Behaviour dof, string name, float value) { FieldInfo fieldInfo = AccessTools.Field(((object)dof).GetType(), name); if (fieldInfo != null && fieldInfo.FieldType == typeof(float)) { fieldInfo.SetValue(dof, value); } } private static float GetDofField(Behaviour dof, string name, float fallback) { FieldInfo fieldInfo = AccessTools.Field(((object)dof).GetType(), name); return (fieldInfo != null && fieldInfo.FieldType == typeof(float)) ? ((float)fieldInfo.GetValue(dof)) : fallback; } private static void UpdateDof(Transform camT) { //IL_0097: 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_00aa: Unknown result type (might be due to invalid IL or missing references) CameraEffects instance = CameraEffects.instance; Behaviour val = Dof(instance); if (!((Object)(object)val == (Object)null)) { if (!s_dofSaved) { s_dofSaved = true; s_savedDofEnabled = val.enabled; s_savedDofAuto = instance.m_dofAutoFocus; s_savedFocal = GetDofField(val, "focalLength", 10f); s_savedAperture = GetDofField(val, "aperture", 0.5f); s_focus = s_savedFocal; } instance.m_dofAutoFocus = false; val.enabled = true; float num = 200f; RaycastHit val2 = default(RaycastHit); if (Physics.Raycast(camT.position, camT.forward, ref val2, 500f, LayerMask.op_Implicit(instance.m_dofRayMask))) { num = Mathf.Max(0.3f, ((RaycastHit)(ref val2)).distance); } s_focus = Mathf.Lerp(s_focus, num, 0.25f); SetDofField(val, "focalLength", s_focus); SetDofField(val, "aperture", Mathf.Clamp(PhotoPlugin.Aperture.Value, 0.05f, 0.9f)); } } private static void RestoreDof() { if (s_dofSaved) { s_dofSaved = false; CameraEffects instance = CameraEffects.instance; Behaviour val = Dof(instance); if (!((Object)(object)val == (Object)null)) { instance.m_dofAutoFocus = s_savedDofAuto; val.enabled = s_savedDofEnabled; SetDofField(val, "focalLength", s_savedFocal); SetDofField(val, "aperture", s_savedAperture); } } } private static string L(string token, params object[] args) { return VsmLocalization.Localize(token, args); } private static string HelpText() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0026: 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_004a: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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_0080: 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_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) return L("vsm_photo_help", PhotoPlugin.CaptureKey.Value, PhotoPlugin.RollLeftKey.Value, PhotoPlugin.RollRightKey.Value, PhotoPlugin.ResetKey.Value, PhotoPlugin.TimeEarlierKey.Value, PhotoPlugin.TimeLaterKey.Value, PhotoPlugin.TimeResetKey.Value, PhotoPlugin.DofKey.Value, PhotoPlugin.HideBodyKey.Value, PhotoPlugin.GridKey.Value, PhotoPlugin.GameUiKey.Value, PhotoPlugin.HelpKey.Value, PhotoPlugin.ToggleKey.Value); } public static string Status() { return "vsm.photo 0.1.4 | parches=" + (PhotoPlugin.PatchesOk ? "ok" : "FALTAN") + " | config lista=" + PhotoPlugin.IsConfigReady + " | activo=" + Active + " | última salida=" + LastExit.ToString() + " | cámara de=" + (CameraLock.Holder() ?? "nadie") + " | límites: enabled=" + PhotoPlugin.Enabled.Value + " distancia=" + PhotoPlugin.MaxCameraDistance.Value + " combate=" + PhotoPlugin.CombatCooldownSeconds.Value + "s salirConDaño=" + PhotoPlugin.ExitOnDamage.Value + " salirSiTeDetectan=" + PhotoPlugin.ExitWhenSensed.Value + " hora=" + PhotoPlugin.AllowTimeOfDay.Value + " profundidad=" + PhotoPlugin.AllowDepthOfField.Value + " | Steam=" + SteamManager.Initialized; } } internal static class UiHider { private static readonly List<Canvas> s_hidden = new List<Canvas>(); private static float s_nextScan; public static bool Hidden { get; private set; } public static void Hide(Canvas keep) { Hidden = true; s_nextScan = 0f; Tick(keep); } public static void Tick(Canvas keep) { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Invalid comparison between Unknown and I4 if (!Hidden || Time.unscaledTime < s_nextScan) { return; } s_nextScan = Time.unscaledTime + 0.5f; Transform val = (((Object)(object)keep != (Object)null) ? ((Component)keep).transform : null); Canvas[] array = Object.FindObjectsByType<Canvas>((FindObjectsSortMode)0); foreach (Canvas val2 in array) { if (!((Object)(object)val2 == (Object)null) && ((Behaviour)val2).enabled && !((Object)(object)val2 == (Object)(object)keep) && (!((Object)(object)val != (Object)null) || !((Component)val2).transform.IsChildOf(val))) { Canvas rootCanvas = val2.rootCanvas; if ((int)(((Object)(object)rootCanvas != (Object)null) ? rootCanvas.renderMode : val2.renderMode) != 2) { ((Behaviour)val2).enabled = false; s_hidden.Add(val2); } } } } public static void Rescan(Canvas keep) { if (Hidden) { s_nextScan = 0f; Tick(keep); } } public static void Show() { Hidden = false; foreach (Canvas item in s_hidden) { if ((Object)(object)item != (Object)null) { ((Behaviour)item).enabled = true; } } s_hidden.Clear(); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "vsm.photo"; public const string PLUGIN_NAME = "MEL Photo"; public const string PLUGIN_VERSION = "0.1.4"; } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class <7d235df6-9ed0-4a53-9e02-a64911f97fac>IgnoresAccessChecksToAttribute : Attribute { public <7d235df6-9ed0-4a53-9e02-a64911f97fac>IgnoresAccessChecksToAttribute(string assemblyName) { } } } namespace VSM.Core.Ui { internal static class VanillaStyle { public static TMP_Text TitleFont => ((Object)(object)InventoryGui.instance != (Object)null) ? InventoryGui.instance.m_playerName : null; public static TMP_Text BodyFont => (!((Object)(object)InventoryGui.instance != (Object)null)) ? null : (((Object)(object)InventoryGui.instance.m_armor != (Object)null) ? InventoryGui.instance.m_armor : InventoryGui.instance.m_playerName); public static Image FindBackground(Transform root, Transform exclude1, Transform exclude2) { //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)root == (Object)null) { return null; } Image result = null; float num = 0f; Image[] componentsInChildren = ((Component)root).GetComponentsInChildren<Image>(true); foreach (Image val in componentsInChildren) { if ((Object)(object)val == (Object)null || (Object)(object)val.sprite == (Object)null) { continue; } Transform transform = ((Component)val).transform; if ((!((Object)(object)exclude1 != (Object)null) || !transform.IsChildOf(exclude1)) && (!((Object)(object)exclude2 != (Object)null) || !transform.IsChildOf(exclude2))) { Rect rect = ((Graphic)val).rectTransform.rect; float num2 = Mathf.Abs(((Rect)(ref rect)).width * ((Rect)(ref rect)).height); if (num2 > num) { num = num2; result = val; } } } return result; } public static bool CopyImage(Image source, Image target) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target == (Object)null) { return false; } if ((Object)(object)source == (Object)null) { ((Graphic)target).color = new Color(0f, 0f, 0f, 0.6f); return false; } target.sprite = source.sprite; target.type = source.type; ((Graphic)target).material = ((Graphic)source).material; ((Graphic)target).color = ((Graphic)source).color; target.fillCenter = source.fillCenter; target.pixelsPerUnitMultiplier = source.pixelsPerUnitMultiplier; target.preserveAspect = false; return true; } public static Image InventoryBackground(Transform exclude) { InventoryGui instance = InventoryGui.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.m_player == (Object)null) { return null; } Transform exclude2 = (Transform)(object)(((Object)(object)instance.m_playerGrid != (Object)null) ? instance.m_playerGrid.m_gridRoot : null); return FindBackground((Transform)(object)instance.m_player, exclude2, exclude); } public static void CopyFont(TMP_Text source, TMP_Text target) { //IL_0037: 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) if (!((Object)(object)source == (Object)null) && !((Object)(object)target == (Object)null)) { target.font = source.font; target.fontSharedMaterial = source.fontSharedMaterial; ((Graphic)target).color = ((Graphic)source).color; target.fontStyle = source.fontStyle; } } public static TextMeshProUGUI NewText(Transform parent, string name, TMP_Text style, float size, TextAlignmentOptions align) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0041: 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(parent, false); TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>(); CopyFont(style, (TMP_Text)(object)val2); ((TMP_Text)val2).fontSize = size; ((TMP_Text)val2).alignment = align; ((Graphic)val2).raycastTarget = false; ((TMP_Text)val2).enableWordWrapping = false; ((TMP_Text)val2).richText = true; return val2; } } } namespace VSM.Core.Runtime { internal static class Headless { private static bool? s_isHeadless; public static bool IsHeadless { get { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 if (!s_isHeadless.HasValue) { s_isHeadless = (int)SystemInfo.graphicsDeviceType == 4 || Application.isBatchMode; } return s_isHeadless.Value; } } public static bool IsServerProcess => (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer(); public static bool IsDedicatedServer => (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && ZNet.instance.IsDedicated(); public static bool IsListenHost => (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && !ZNet.instance.IsDedicated(); public static bool IsRemoteClient => (Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer(); } internal static class Keys { public static bool Pressed(KeyboardShortcut shortcut) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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) KeyCode mainKey = ((KeyboardShortcut)(ref shortcut)).MainKey; return (int)mainKey != 0 && ZInput.GetKeyDown(mainKey, false) && ((KeyboardShortcut)(ref shortcut)).Modifiers.All((KeyCode m) => ZInput.GetKey(m, false)); } } } namespace VSM.Core.Reflection { internal static class GameConstants { private static uint? s_networkVersion; private static long? s_routedEverybody; public static uint NetworkVersion { get { if (!s_networkVersion.HasValue) { s_networkVersion = ReadConstant<uint>(typeof(Version), new string[2] { "c_networkVersion", "m_networkVersion" }); } return s_networkVersion.Value; } } public static long RoutedRpcEverybody { get { if (!s_routedEverybody.HasValue) { s_routedEverybody = ReadConstant<long>(typeof(ZRoutedRpc), new string[1] { "Everybody" }); } return s_routedEverybody.Value; } } public static string GameVersionString { get { //IL_0002: 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) try { return ((object)Version.CurrentVersion/*cast due to .constrained prefix*/).ToString(); } catch (Exception) { return "?"; } } } private static T ReadConstant<T>(Type type, params string[] names) where T : struct { foreach (string name in names) { FieldInfo field = type.GetField(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (!(field == null)) { object obj = (field.IsLiteral ? field.GetRawConstantValue() : field.GetValue(null)); if (obj is T result) { return result; } try { return (T)Convert.ChangeType(obj, typeof(T)); } catch (Exception) { } } } return default(T); } } } namespace VSM.Core.Net { internal static class ZPackageExt { public static bool HasMore(this ZPackage pkg) { return pkg != null && pkg.GetPos() < pkg.Size(); } public static int ReadIntOr(this ZPackage pkg, int fallback) { return pkg.HasMore() ? pkg.ReadInt() : fallback; } public static string ReadStringOr(this ZPackage pkg, string fallback) { return pkg.HasMore() ? pkg.ReadString() : fallback; } public static bool ReadBoolOr(this ZPackage pkg, bool fallback) { return pkg.HasMore() ? pkg.ReadBool() : fallback; } public static string ReadBoundedString(this ZPackage pkg, int maxLength) { string text = pkg.ReadString(); return (text != null && text.Length <= maxLength) ? text : null; } } } namespace VSM.Core.Localization { internal static class VsmLocalization { public static void Register(ManualLogSource log, string pluginDirectory, IDictionary<string, string> embeddedSpanish) { Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.Ordinal); if (embeddedSpanish != null) { foreach (KeyValuePair<string, string> item in embeddedSpanish) { dictionary[item.Key] = item.Value; } } string path = Path.Combine(pluginDirectory ?? string.Empty, "Translations"); MergeFile(log, Path.Combine(path, "Spanish.json"), dictionary); string text = SafeSelectedLanguage(); if (!string.Equals(text, "Spanish", StringComparison.OrdinalIgnoreCase)) { MergeFile(log, Path.Combine(path, text + ".json"), dictionary); } Apply(log, dictionary); } public static string Localize(string token, params object[] args) { string text = token; try { if (Localization.instance != null && !string.IsNullOrEmpty(token)) { bool flag = token[0] != '$' && token.IndexOf(' ') < 0 && token.IndexOf('\n') < 0; string text2 = Localization.instance.Localize(flag ? ("$" + token) : token); text = ((flag && text2.Length > 1 && text2[0] == '[' && text2[text2.Length - 1] == ']') ? token : text2); } } catch (Exception) { text = token; } if (args != null && args.Length != 0) { try { text = string.Format(text, args); } catch (FormatException) { } } return text; } private static string SafeSelectedLanguage() { try { return (Localization.instance != null) ? Localization.instance.GetSelectedLanguage() : "Spanish"; } catch (Exception) { return "Spanish"; } } private static void Apply(ManualLogSource log, Dictionary<string, string> words) { if (Localization.instance == null) { if (log != null) { log.LogWarning((object)"Localization.instance aún no existe; las traducciones no se han aplicado."); } return; } foreach (KeyValuePair<string, string> word in words) { string text = (word.Key.StartsWith("$", StringComparison.Ordinal) ? word.Key.Substring(1) : word.Key); Localization.instance.AddWord(text, word.Value); } } private static void MergeFile(ManualLogSource log, string path, Dictionary<string, string> into) { if (!File.Exists(path)) { return; } try { foreach (KeyValuePair<string, string> item in ParseFlatJson(File.ReadAllText(path, Encoding.UTF8))) { into[item.Key] = item.Value; } } catch (Exception ex) { if (log != null) { log.LogWarning((object)("No se pudo leer " + path + ": " + ex.Message)); } } } public static Dictionary<string, string> ParseFlatJson(string json) { Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.Ordinal); if (string.IsNullOrEmpty(json)) { return dictionary; } int i = 0; SkipWs(json, ref i); if (i >= json.Length || json[i] != '{') { return dictionary; } i++; while (true) { SkipWs(json, ref i); if (i >= json.Length || json[i] == '}') { break; } if (json[i] == ',') { i++; continue; } string text = ReadString(json, ref i); if (text == null) { i++; continue; } SkipWs(json, ref i); if (i < json.Length && json[i] == ':') { i++; } SkipWs(json, ref i); if (i < json.Length && json[i] == '"') { string text2 = ReadString(json, ref i); dictionary[text] = text2 ?? string.Empty; } else { for (; i < json.Length && json[i] != ',' && json[i] != '}'; i++) { } } } return dictionary; } private static void SkipWs(string s, ref int i) { while (i < s.Length && char.IsWhiteSpace(s[i])) { i++; } } private static string ReadString(string s, ref int i) { if (i >= s.Length || s[i] != '"') { return null; } i++; StringBuilder stringBuilder = new StringBuilder(); while (i < s.Length) { char c = s[i++]; switch (c) { case '"': return stringBuilder.ToString(); case '\\': { if (i >= s.Length) { break; } char c2 = s[i++]; switch (c2) { case 'n': stringBuilder.Append('\n'); break; case 't': stringBuilder.Append('\t'); break; case 'r': stringBuilder.Append('\r'); break; case 'b': stringBuilder.Append('\b'); break; case 'f': stringBuilder.Append('\f'); break; case 'u': if (i + 4 <= s.Length) { stringBuilder.Append((char)Convert.ToInt32(s.Substring(i, 4), 16)); i += 4; } break; default: stringBuilder.Append(c2); break; } continue; } } stringBuilder.Append(c); } return stringBuilder.ToString(); } } } namespace VSM.Core.Harmony { internal static class PatchUtil { private static readonly List<string> s_failed = new List<string>(); public static IReadOnlyList<string> FailedTargets => s_failed; public static bool IsDegraded => s_failed.Count > 0; public static MethodInfo DeclaredMethodOrNull(ManualLogSource log, Type type, string name, Type[] parameters, string owner) { if (type == null) { Fail(log, owner, name + " (tipo nulo)"); return null; } MethodInfo methodInfo = AccessTools.DeclaredMethod(type, name, parameters, (Type[])null); if (methodInfo == null) { Fail(log, owner, type.FullName + "." + name + "(" + Describe(parameters) + ")"); } return methodInfo; } public static void PatchAllSafely(ManualLogSource log, Harmony harmony, Assembly assembly) { Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(assembly); foreach (Type type in typesFromAssembly) { if (type.GetCustomAttributes(typeof(HarmonyPatch), inherit: true).Length != 0) { PatchClassSafely(log, harmony, type); } } } public static bool PatchClassSafely(ManualLogSource log, Harmony harmony, Type patchClass) { try { harmony.CreateClassProcessor(patchClass).Patch(); return true; } catch (Exception ex) { Fail(log, harmony.Id, patchClass.FullName + " -> " + ex.GetType().Name + ": " + ex.Message); return false; } } private static void Fail(ManualLogSource log, string owner, string what) { s_failed.Add(what); if (log != null) { log.LogError((object)("[" + owner + "] No se pudo aplicar el parche (¿cambió el juego?): " + what + ". El mod sigue cargado en modo degradado.")); } } private static string Describe(Type[] parameters) { if (parameters == null || parameters.Length == 0) { return string.Empty; } string[] array = new string[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { array[i] = ((parameters[i] == null) ? "?" : parameters[i].Name); } return string.Join(", ", array); } } } namespace VSM.Core.Config { internal sealed class ConfigurationManagerAttributes { public bool? ShowRangeAsPercent; public Action<ConfigEntryBase> CustomDrawer; public bool? Browsable; public string Category; public object DefaultValue; public bool? HideDefaultButton; public bool? HideSettingName; public string Description; public string DispName; public int? Order; public bool? ReadOnly; public bool? IsAdvanced; public bool? IsAdminOnly; public Func<object, string> ObjToStr; public Func<string, object> StrToObj; } } namespace VSM.Core.Camera { internal struct RigSettings { public float Speed; public float FastMultiplier; public bool MoveRelativeToView; } internal sealed class CameraRig { public const float MaxPitch = 89f; public float Yaw; public float Pitch; public Vector3 Position; public Vector3 Velocity; public Vector3 ForwardVector => Forward(Yaw, Pitch); public Quaternion Rotation => Quaternion.Euler(Pitch, Yaw, 0f); public static Vector3 Forward(float yawDeg, float pitchDeg) { //IL_002f: 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) //IL_0037: Unknown result type (might be due to invalid IL or missing references) float num = yawDeg * ((float)Math.PI / 180f); float num2 = pitchDeg * ((float)Math.PI / 180f); float num3 = Mathf.Cos(num2); return new Vector3(Mathf.Sin(num) * num3, 0f - Mathf.Sin(num2), Mathf.Cos(num) * num3); } public static Vector3 FlatForward(float yawDeg) { //IL_001a: 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_0022: Unknown result type (might be due to invalid IL or missing references) float num = yawDeg * ((float)Math.PI / 180f); return new Vector3(Mathf.Sin(num), 0f, Mathf.Cos(num)); } public static Vector3 Right(float yawDeg) { //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_0023: Unknown result type (might be due to invalid IL or missing references) float num = yawDeg * ((float)Math.PI / 180f); return new Vector3(Mathf.Cos(num), 0f, 0f - Mathf.Sin(num)); } public void Reset(Vector3 position, Vector3 forward) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) Position = position; Velocity = Vector3.zero; SetFromDirection(forward); } public void SetFromDirection(Vector3 forward) { //IL_0035: 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_005c: Unknown result type (might be due to invalid IL or missing references) if (((Vector3)(ref forward)).sqrMagnitude < 1E-08f) { Yaw = 0f; Pitch = 0f; } else { ((Vector3)(ref forward)).Normalize(); Yaw = Mathf.Repeat(Mathf.Atan2(forward.x, forward.z) * 57.29578f, 360f); Pitch = Mathf.Clamp((0f - Mathf.Asin(Mathf.Clamp(forward.y, -1f, 1f))) * 57.29578f, -89f, 89f); } } public void ApplyLook(Vector2 delta) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) Yaw = Mathf.Repeat(Yaw + delta.x, 360f); Pitch = Mathf.Clamp(Pitch - delta.y, -89f, 89f); } public Vector3 DesiredVelocity(Vector3 move, float vertical, bool fast, RigSettings settings) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //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_0083: 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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: 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_00df: 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) Vector3 val = (settings.MoveRelativeToView ? Forward(Yaw, Pitch) : FlatForward(Yaw)); Vector3 val2 = Right(Yaw) * Mathf.Clamp(move.x, -1f, 1f) + val * Mathf.Clamp(move.z, -1f, 1f) + Vector3.up * Mathf.Clamp(vertical, -1f, 1f); if (((Vector3)(ref val2)).sqrMagnitude > 1f) { ((Vector3)(ref val2)).Normalize(); } float num = Mathf.Max(0f, settings.Speed) * (fast ? Mathf.Max(1f, settings.FastMultiplier) : 1f); return val2 * num; } public void Integrate(Vector3 desiredVelocity, float dt, float smoothing) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0047: 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) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) if (!(dt <= 0f)) { float num = ((smoothing <= 0f) ? 1f : (1f - Mathf.Exp((0f - dt) / smoothing))); Velocity = Vector3.Lerp(Velocity, desiredVelocity, num); Position += Velocity * dt; } } public static Vector3 ClampToSphere(Vector3 pos, Vector3 center, float radius) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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) Vector3 val = pos - center; float num = Mathf.Max(0f, radius); if (((Vector3)(ref val)).sqrMagnitude <= num * num) { return pos; } return center + ((Vector3)(ref val)).normalized * num; } } internal static class CameraWorld { public const float CollisionRadius = 0.25f; public static Vector3 Anchor(Player player) { //IL_0033: 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_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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) Transform eye = ((Character)player).m_eye; return ((Object)(object)eye != (Object)null) ? eye.position : (((Component)player).transform.position + Vector3.up * 1.6f); } public static Vector3 Constrain(Vector3 from, Vector3 to, Vector3 anchor, float maxDistance, float clearance, GameCamera cam) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0038: 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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) Vector3 pos = CameraRig.ClampToSphere(to, anchor, maxDistance); pos = Lift(pos, clearance, cam); pos = CameraRig.ClampToSphere(pos, anchor, maxDistance + 1f); LayerMask blockCameraMask = cam.m_blockCameraMask; Vector3 val = (Overlaps(from, blockCameraMask) ? anchor : from); return Collide(val, pos, blockCameraMask); } public static Vector3 Lift(Vector3 pos, float clearance, GameCamera cam) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) clearance = Mathf.Max(0f, clearance); ZoneSystem instance = ZoneSystem.instance; float num = default(float); if ((Object)(object)instance != (Object)null && instance.GetGroundHeight(pos, ref num)) { pos.y = Mathf.Max(pos.y, num + clearance); } float num2 = Floating.GetLiquidLevel(pos, 1f, (LiquidType)10); if ((Object)(object)instance != (Object)null && !Character.InInterior(pos)) { num2 = Mathf.Max(num2, instance.m_waterLevel); } if (num2 > -9000f) { pos.y = Mathf.Max(pos.y, num2 + Mathf.Max(clearance, cam.m_minWaterDistance)); } return pos; } public static bool Overlaps(Vector3 pos, LayerMask mask) { //IL_0001: 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) return Physics.CheckSphere(pos, 0.225f, LayerMask.op_Implicit(mask), (QueryTriggerInteraction)1); } public static Vector3 Collide(Vector3 from, Vector3 to, LayerMask mask) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0033: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) Vector3 val = to - from; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude < 1E-05f) { return to; } Vector3 val2 = val / magnitude; RaycastHit val3 = default(RaycastHit); if (Physics.SphereCast(from, 0.25f, val2, ref val3, magnitude, LayerMask.op_Implicit(mask), (QueryTriggerInteraction)1)) { return from + val2 * Mathf.Max(0f, ((RaycastHit)(ref val3)).distance - 0.02f); } return to; } } internal static class CameraLock { private const string Prefix = "vsm_camera_lock:"; public static string Holder() { GameCamera instance = GameCamera.instance; if ((Object)(object)instance == (Object)null) { return null; } Transform transform = ((Component)instance).transform; for (int i = 0; i < transform.childCount; i++) { string name = ((Object)transform.GetChild(i)).name; if (name.StartsWith("vsm_camera_lock:", StringComparison.Ordinal)) { return name.Substring("vsm_camera_lock:".Length); } } return null; } public static bool TryAcquire(string owner) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown GameCamera instance = GameCamera.instance; if ((Object)(object)instance == (Object)null) { return false; } string text = Holder(); if (text != null) { return text == owner; } GameObject val = new GameObject("vsm_camera_lock:" + owner); val.transform.SetParent(((Component)instance).transform, false); return true; } public static void Release(string owner) { GameCamera instance = GameCamera.instance; if ((Object)(object)instance == (Object)null) { return; } Transform transform = ((Component)instance).transform; for (int num = transform.childCount - 1; num >= 0; num--) { Transform child = transform.GetChild(num); if (((Object)child).name == "vsm_camera_lock:" + owner) { Object.Destroy((Object)(object)((Component)child).gameObject); ((Object)child).name = "vsm_camera_lock_released"; } } } } internal sealed class BodyHider { private readonly List<Renderer> _hidden = new List<Renderer>(); private float _nextScan; public void Update(Player player, bool hide) { if (!hide || (Object)(object)player == (Object)null) { Restore(); } else { if (Time.unscaledTime < _nextScan) { return; } _nextScan = Time.unscaledTime + 0.5f; Renderer[] componentsInChildren = ((Component)player).GetComponentsInChildren<Renderer>(false); foreach (Renderer val in componentsInChildren) { if ((Object)(object)val != (Object)null && val.enabled && (val is SkinnedMeshRenderer || val is MeshRenderer)) { val.enabled = false; _hidden.Add(val); } } } } public void Restore() { foreach (Renderer item in _hidden) { if ((Object)(object)item != (Object)null) { item.enabled = true; } } _hidden.Clear(); _nextScan = 0f; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }
plugins/VSM.Slots/VSM.Slots.dll
Decompiled 3 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ConditionalConfigSync; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; using VSM.Core.Config; using VSM.Core.Harmony; using VSM.Core.Localization; using VSM.Core.Reflection; using VSM.Core.Runtime; using VSM.Core.Ui; using VSM.Slots.Core; using VSM.Slots.Runtime; using VSM.Slots.Transmog; using VSM.Slots.Ui; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: <f38ba538-35fd-47fd-b707-af2183e34bfc>IgnoresAccessChecksTo("assembly_guiutils")] [assembly: <f38ba538-35fd-47fd-b707-af2183e34bfc>IgnoresAccessChecksTo("assembly_utils")] [assembly: <f38ba538-35fd-47fd-b707-af2183e34bfc>IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("VSM.Slots")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("0.1.4.0")] [assembly: AssemblyInformationalVersion("0.1.4+ff27bc889ccf218c61c45d3417d48ab708a5ba8f")] [assembly: AssemblyProduct("VSM.Slots")] [assembly: AssemblyTitle("VSM.Slots")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.4.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace VSM.Slots { [BepInPlugin("vsm.slots", "MEL Slots", "0.1.4")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class SlotsPlugin : BaseUnityPlugin { [HarmonyPatch(typeof(Game), "Start")] internal static class NetPatch { private static ZRoutedRpc s_registeredFor; [HarmonyPostfix] private static void Postfix() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null && instance != s_registeredFor) { instance.Register<string, int, int>("VSM_Slots_RowsTrimmed", (Action<long, string, int, int>)RowCap.RPC_RowsTrimmed); s_registeredFor = instance; SlotState.Reset(); Reconciler.Forget(); } } } [HarmonyPatch(typeof(Terminal), "InitTerminal")] internal static class CommandsPatch { [HarmonyPostfix] private static void Postfix() { RegisterCommands(); } } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static EventHandler <>9__23_0; public static EventHandler <>9__23_1; public static EventHandler <>9__23_2; public static EventHandler <>9__23_3; public static EventHandler <>9__23_4; public static EventHandler <>9__23_5; public static EventHandler <>9__23_6; public static EventHandler <>9__23_7; public static ConsoleEvent <>9__35_0; public static ConsoleEvent <>9__35_1; internal void <BindConfig>b__23_0(object s, EventArgs e) { SlotLayout.SetEnabled(EnabledSlots.Value); RefreshLooks(); } internal void <BindConfig>b__23_1(object s, EventArgs e) { EnforceRows("config"); } internal void <BindConfig>b__23_2(object s, EventArgs e) { EnforceRows("config"); } internal void <BindConfig>b__23_3(object s, EventArgs e) { EnforceRows("config"); } internal void <BindConfig>b__23_4(object s, EventArgs e) { EnforceRows("config"); } internal void <BindConfig>b__23_5(object s, EventArgs e) { RefreshLooks(); } internal void <BindConfig>b__23_6(object s, EventArgs e) { RefreshLooks(); } internal void <BindConfig>b__23_7(object s, EventArgs e) { RefreshLooks(); } internal void <RegisterCommands>b__35_0(ConsoleEventArgs args) { //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { args.Context.AddString("Sin jugador local."); return; } Inventory inventory = ((Humanoid)localPlayer).m_inventory; int num = SlotState.VisibleRows(localPlayer); args.Context.AddString("vsm.slots 0.1.4 | filas visibles=" + num + " (tope " + RowCap.MaxRows(localPlayer) + ", " + RowsCap.Value.ToString() + ") | altura=" + inventory.m_height + " | config lista=" + IsConfigReady + " | seguridad=" + s_safetyOk + " | funciones=" + s_featuresOk); SlotDefinition[] all = SlotLayout.All; foreach (SlotDefinition slotDefinition in all) { Vector2i val = SlotLayout.CellOf(slotDefinition, num); ItemData itemAt = inventory.GetItemAt(val.x, val.y); ItemData val2 = slotDefinition.Equipped((Humanoid)(object)localPlayer); Appearance look; string text = (TransmogRuntime.Get(localPlayer).TryGet(slotDefinition.Id, out look) ? (look.Hidden ? "oculto" : (look.Prefab + ((look.Variant > 0) ? (":" + look.Variant) : string.Empty))) : "-"); args.Context.AddString(" " + slotDefinition.Id + (SlotLayout.IsEnabled(slotDefinition) ? string.Empty : " (desactivada)") + " @" + val.x + "," + val.y + ": " + ((itemAt != null) ? itemAt.m_shared.m_name : "-") + " | puesto: " + ((val2 != null) ? val2.m_shared.m_name : "-") + " | apariencia: " + text + ((itemAt != null && itemAt != val2) ? " <-- en espera / incoherente" : string.Empty)); } int num2 = 0; foreach (ItemData allItem in inventory.GetAllItems()) { if (allItem.m_gridPos.y == num && SlotLayout.SlotAt(allItem.m_gridPos, num) == null) { num2++; } } args.Context.AddString("Objetos atascados en celdas reservadas: " + num2); } internal void <RegisterCommands>b__35_1(ConsoleEventArgs args) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { TransmogRuntime.ClearAll(localPlayer); args.Context.AddString("Apariencias quitadas."); } } } internal static ManualLogSource Log; private static ConfigSync s_sync; private Harmony _harmony; private static bool s_safetyOk; private static bool s_featuresOk; private static float s_lastMessage; private static readonly HashSet<string> s_loggedOnce = new HashSet<string>(); public static ConfigEntry<string> EnabledSlots; public static ConfigEntry<RowsCapMode> RowsCap; public static ConfigEntry<int> RowsBase; public static ConfigEntry<string> RowsLegalKeys; public static ConfigEntry<int> RowsFixedMax; public static ConfigEntry<bool> TransmogEnabled; public static ConfigEntry<bool> TransmogRequireKnown; public static ConfigEntry<bool> TransmogAllowHide; public static ConfigEntry<bool> ServerLock; public static ConfigEntry<bool> ShowSlotLabels; public static ConfigEntry<float> PanelGapX; public static ConfigEntry<float> PanelOffsetY; public static ConfigEntry<float> PanelScale; public static ConfigEntry<bool> ShowMessages; private static readonly Dictionary<string, string> s_spanish = new Dictionary<string, string> { { "vsm_slots_title", "Equipo" }, { "vsm_slots_helmet", "Casco" }, { "vsm_slots_chest", "Pecho" }, { "vsm_slots_legs", "Piernas" }, { "vsm_slots_shoulder", "Capa" }, { "vsm_slots_utility", "Cinturón" }, { "vsm_slots_trinket", "Trinket" }, { "vsm_slots_close", "Cerrar" }, { "vsm_slots_wrong_type", "Eso no va en la ranura de {0}" }, { "vsm_slots_swap_blocked", "No se puede cambiar: {0} no va en la ranura de {1}" }, { "vsm_slots_inventory_full", "Inventario lleno: no hay sitio para quitártelo" }, { "vsm_slots_stuck", "{0} está esperando sitio en tu inventario para salir de la fila de equipo" }, { "vsm_slots_rows_dropped", "No cabía todo: {0} objetos quedaron en el suelo junto a ti" }, { "vsm_slots_rows_trimmed", "El servidor permite {1} filas de inventario (tenías {0}). Lo que no cupo quedó en el suelo junto a ti." }, { "vsm_slots_transmog_button", "Transfigurar" }, { "vsm_slots_transmog_title", "Transfiguración" }, { "vsm_slots_transmog_wearing", "{0}: llevas {1}. Elige cómo se ve (las estadísticas no cambian)." }, { "vsm_slots_transmog_nothing", "{0}: no llevas nada. La apariencia elegida se verá cuando te pongas una pieza." }, { "vsm_slots_transmog_none_known", "Todavía no has tenido ninguna pieza de {0}. Cuando consigas una, aparecerá aquí." }, { "vsm_slots_transmog_original", "Original" }, { "vsm_slots_transmog_original_tip", "Se ve la pieza que llevas puesta" }, { "vsm_slots_transmog_hide", "Ocultar" }, { "vsm_slots_transmog_hide_tip", "No se ve nada en esta ranura (la pieza sigue protegiendo)" }, { "vsm_slots_transmog_reset_all", "Quitar todas" }, { "vsm_slots_transmog_saved_empty", "Guardado: se verá cuando lleves algo en la ranura de {0}" } }; public static bool IsConfigReady => s_sync != null && (((ConditionalConfigSync)s_sync).IsSourceOfTruth || ((ConditionalConfigSync)s_sync).InitialSyncDone); private void Awake() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0044: Expected O, but got Unknown //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; s_sync = new ConfigSync("vsm.slots") { DisplayName = "MEL Slots", CurrentVersion = "0.1.4", MinimumRequiredVersion = "0.1.4", ModRequired = true }; BindConfig(); SlotLayout.SetEnabled(EnabledSlots.Value); ((ConditionalConfigSync)s_sync).InitialSyncCompleted += OnServerConfig; Log.LogInfo((object)("vsm.slots 0.1.4 | Valheim " + GameConstants.GameVersionString + " | headless=" + Headless.IsHeadless)); _harmony = new Harmony("vsm.slots"); PatchUtil.PatchClassSafely(Log, _harmony, typeof(NetPatch)); if (Headless.IsHeadless) { Log.LogInfo((object)"vsm.slots: servidor dedicado: configuración y registro de recortes, sin parches de inventario."); return; } VsmLocalization.Register(Log, Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), s_spanish); s_safetyOk = true; Type[] classes = SafetyPatches.Classes; foreach (Type patchClass in classes) { s_safetyOk &= PatchUtil.PatchClassSafely(Log, _harmony, patchClass); } if (!s_safetyOk) { Log.LogError((object)"vsm.slots: faltan parches de seguridad (¿cambió el juego?). Las ranuras quedan en modo protegido: sin panel ni arrastres."); return; } bool flag = PatchUtil.PatchClassSafely(Log, _harmony, typeof(DragResolver)); PatchUtil.PatchClassSafely(Log, _harmony, typeof(TransmogRuntime.ApplyPatch)); PatchUtil.PatchClassSafely(Log, _harmony, typeof(GraveEasyFit)); PatchUtil.PatchClassSafely(Log, _harmony, typeof(CommandsPatch)); if (flag) { Type[] classes2 = UiPatches.Classes; foreach (Type patchClass2 in classes2) { PatchUtil.PatchClassSafely(Log, _harmony, patchClass2); } } else { Log.LogError((object)"vsm.slots: no se pudo enganchar el arrastre; el panel de equipo no se muestra (las ranuras siguen funcionando con clic derecho)."); } s_featuresOk = true; } private void BindConfig() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Expected O, but got Unknown //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Expected O, but got Unknown //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Expected O, but got Unknown //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Expected O, but got Unknown //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Expected O, but got Unknown //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Expected O, but got Unknown //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Expected O, but got Unknown //IL_036d: Unknown result type (might be due to invalid IL or missing references) //IL_0377: Expected O, but got Unknown EnabledSlots = ((BaseUnityPlugin)this).Config.Bind<string>("1. Ranuras", "EnabledSlots", "helmet,chest,legs,shoulder,utility,trinket", new ConfigDescription("Ranuras activas (ids separados por coma: helmet, chest, legs, shoulder, utility, trinket). Lo que haya en una ranura desactivada vuelve al inventario.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 100 } })); ((ConditionalConfigSync)s_sync).AddConfigEntry<string>(EnabledSlots, (ConfigSyncMode)0); ServerLock = ((BaseUnityPlugin)this).Config.Bind<bool>("1. Ranuras", "ServerLock", true, "Bloquea la configuración sincronizada: solo los administradores del servidor pueden cambiarla."); ((ConditionalConfigSync)s_sync).AddLockingConfigEntry<bool>(ServerLock); RowsCap = ((BaseUnityPlugin)this).Config.Bind<RowsCapMode>("2. Filas del inventario", "RowsCap", RowsCapMode.Legal, new ConfigDescription("Tope de filas del inventario. Legal = base + una por cada bolsillo comprado a Haldor (lo que se puede conseguir jugando; quien traiga más filas de un mundo con trucos se recorta al entrar). Fijo = el máximo de RowsFixedMax para todos. Libre = sin tope (hasta 9).", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 90 } })); RowsBase = ((BaseUnityPlugin)this).Config.Bind<int>("2. Filas del inventario", "RowsBase", 4, new ConfigDescription("Filas con las que empieza todo personaje (vanilla: 4). Solo en modo Legal.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 9), new object[1] { new ConfigurationManagerAttributes { Order = 89 } })); RowsLegalKeys = ((BaseUnityPlugin)this).Config.Bind<string>("2. Filas del inventario", "RowsLegalKeys", "invslot1,invslot2", new ConfigDescription("Claves de compra que dan una fila cada una (vanilla: invslot1 = Bolsillos más amplios, invslot2 = Bolsillos más profundos). Solo en modo Legal.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 88 } })); RowsFixedMax = ((BaseUnityPlugin)this).Config.Bind<int>("2. Filas del inventario", "RowsFixedMax", 6, new ConfigDescription("Máximo de filas en modo Fijo.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 9), new object[1] { new ConfigurationManagerAttributes { Order = 87 } })); ((ConditionalConfigSync)s_sync).AddConfigEntry<RowsCapMode>(RowsCap, (ConfigSyncMode)0); ((ConditionalConfigSync)s_sync).AddConfigEntry<int>(RowsBase, (ConfigSyncMode)0); ((ConditionalConfigSync)s_sync).AddConfigEntry<string>(RowsLegalKeys, (ConfigSyncMode)0); ((ConditionalConfigSync)s_sync).AddConfigEntry<int>(RowsFixedMax, (ConfigSyncMode)0); TransmogEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("3. Transfiguración", "Enabled", true, new ConfigDescription("Permite cambiar la apariencia del equipo (las estadísticas siguen siendo las de la pieza real). Apagarlo desde el servidor quita todas las apariencias.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 80 } })); TransmogRequireKnown = ((BaseUnityPlugin)this).Config.Bind<bool>("3. Transfiguración", "RequireKnown", true, new ConfigDescription("Solo se pueden elegir apariencias de piezas que el jugador ya haya tenido alguna vez en el inventario.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 79 } })); TransmogAllowHide = ((BaseUnityPlugin)this).Config.Bind<bool>("3. Transfiguración", "AllowHide", true, new ConfigDescription("Permite ocultar una pieza (se ve el cuerpo o el pelo, pero la pieza sigue protegiendo).", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 78 } })); ((ConditionalConfigSync)s_sync).AddConfigEntry<bool>(TransmogEnabled, (ConfigSyncMode)0); ((ConditionalConfigSync)s_sync).AddConfigEntry<bool>(TransmogRequireKnown, (ConfigSyncMode)0); ((ConditionalConfigSync)s_sync).AddConfigEntry<bool>(TransmogAllowHide, (ConfigSyncMode)0); ShowSlotLabels = ((BaseUnityPlugin)this).Config.Bind<bool>("4. Interfaz", "ShowSlotLabels", true, "Nombre de cada ranura debajo de la celda."); PanelGapX = ((BaseUnityPlugin)this).Config.Bind<float>("4. Interfaz", "PanelGapX", 8f, "Separación horizontal (píxeles) entre las pestañas de armadura/peso y el panel de equipo."); PanelOffsetY = ((BaseUnityPlugin)this).Config.Bind<float>("4. Interfaz", "PanelOffsetY", 0f, "Desplazamiento vertical del panel de equipo (píxeles)."); PanelScale = ((BaseUnityPlugin)this).Config.Bind<float>("4. Interfaz", "PanelScale", 1f, new ConfigDescription("Escala del panel de equipo (se encoge solo si no cabe).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 2f), Array.Empty<object>())); ShowMessages = ((BaseUnityPlugin)this).Config.Bind<bool>("4. Interfaz", "ShowMessages", true, "Avisos en pantalla (objeto que no va en la ranura, inventario lleno, recortes)."); EnabledSlots.SettingChanged += delegate { SlotLayout.SetEnabled(EnabledSlots.Value); RefreshLooks(); }; RowsCap.SettingChanged += delegate { EnforceRows("config"); }; RowsBase.SettingChanged += delegate { EnforceRows("config"); }; RowsLegalKeys.SettingChanged += delegate { EnforceRows("config"); }; RowsFixedMax.SettingChanged += delegate { EnforceRows("config"); }; TransmogEnabled.SettingChanged += delegate { RefreshLooks(); }; TransmogRequireKnown.SettingChanged += delegate { RefreshLooks(); }; TransmogAllowHide.SettingChanged += delegate { RefreshLooks(); }; } private static void OnServerConfig() { SlotLayout.SetEnabled(EnabledSlots.Value); EnforceRows("config del servidor"); RefreshLooks(); } private static void EnforceRows(string when) { if (!s_safetyOk || (Object)(object)Player.m_localPlayer == (Object)null) { return; } try { RowCap.Enforce(Player.m_localPlayer, when); } catch (Exception ex) { Log.LogError((object)("vsm.slots: tope de filas: " + ex)); } } private static void RefreshLooks() { if (s_featuresOk && (Object)(object)Player.m_localPlayer != (Object)null) { TransmogRuntime.Refresh(Player.m_localPlayer); } } private void LateUpdate() { if (!s_featuresOk) { return; } try { Reconciler.Tick(); } catch (Exception ex) { LogOnce("reconcile", "vsm.slots: reconciliación: " + ex); } try { EquipmentPanel.Tick(); } catch (Exception ex2) { LogOnce("panel", "vsm.slots: panel: " + ex2); } } private void OnDestroy() { TransmogPanel.Destroy(); EquipmentPanel.Destroy(); if (_harmony != null) { _harmony.UnpatchSelf(); } } internal static void Message(Player p, string token, params object[] args) { if ((Object)(object)p == (Object)null || !ShowMessages.Value || Time.unscaledTime - s_lastMessage < 1f) { return; } s_lastMessage = Time.unscaledTime; if (args != null) { for (int i = 0; i < args.Length; i++) { if (args[i] is string { Length: >1 } text && text[0] == '$') { args[i] = VsmLocalization.Localize(text); } } } ((Character)p).Message((MessageType)2, VsmLocalization.Localize(token, args), 0, (Sprite)null, false); } internal static void LogOnce(string key, string message) { if (s_loggedOnce.Add(key)) { Log.LogError((object)message); } } private static void RegisterCommands() { //IL_0034: 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_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown object obj = <>c.<>9__35_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { args.Context.AddString("Sin jugador local."); } else { Inventory inventory = ((Humanoid)localPlayer).m_inventory; int num = SlotState.VisibleRows(localPlayer); args.Context.AddString("vsm.slots 0.1.4 | filas visibles=" + num + " (tope " + RowCap.MaxRows(localPlayer) + ", " + RowsCap.Value.ToString() + ") | altura=" + inventory.m_height + " | config lista=" + IsConfigReady + " | seguridad=" + s_safetyOk + " | funciones=" + s_featuresOk); SlotDefinition[] all = SlotLayout.All; foreach (SlotDefinition slotDefinition in all) { Vector2i val3 = SlotLayout.CellOf(slotDefinition, num); ItemData itemAt = inventory.GetItemAt(val3.x, val3.y); ItemData val4 = slotDefinition.Equipped((Humanoid)(object)localPlayer); Appearance look; string text = (TransmogRuntime.Get(localPlayer).TryGet(slotDefinition.Id, out look) ? (look.Hidden ? "oculto" : (look.Prefab + ((look.Variant > 0) ? (":" + look.Variant) : string.Empty))) : "-"); args.Context.AddString(" " + slotDefinition.Id + (SlotLayout.IsEnabled(slotDefinition) ? string.Empty : " (desactivada)") + " @" + val3.x + "," + val3.y + ": " + ((itemAt != null) ? itemAt.m_shared.m_name : "-") + " | puesto: " + ((val4 != null) ? val4.m_shared.m_name : "-") + " | apariencia: " + text + ((itemAt != null && itemAt != val4) ? " <-- en espera / incoherente" : string.Empty)); } int num2 = 0; foreach (ItemData allItem in inventory.GetAllItems()) { if (allItem.m_gridPos.y == num && SlotLayout.SlotAt(allItem.m_gridPos, num) == null) { num2++; } } args.Context.AddString("Objetos atascados en celdas reservadas: " + num2); } }; <>c.<>9__35_0 = val; obj = (object)val; } new ConsoleCommand("vsm_slots_dump", "Estado de las ranuras de equipo (filas, altura, contenido, apariencias)", (ConsoleEvent)obj, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj2 = <>c.<>9__35_1; if (obj2 == null) { ConsoleEvent val2 = delegate(ConsoleEventArgs args) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { TransmogRuntime.ClearAll(localPlayer); args.Context.AddString("Apariencias quitadas."); } }; <>c.<>9__35_1 = val2; obj2 = (object)val2; } new ConsoleCommand("vsm_slots_transmog_reset", "Quita todas tus apariencias de transfiguración", (ConsoleEvent)obj2, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "vsm.slots"; public const string PLUGIN_NAME = "MEL Slots"; public const string PLUGIN_VERSION = "0.1.4"; } } namespace VSM.Slots.Ui { internal static class EquipmentPanel { private const string PanelName = "vsm_slots_panel"; private const float Pad = 12f; private const float TitleHeight = 28f; private const float LabelHeight = 14f; private const float ColumnGap = 10f; private const float ButtonHeight = 32f; private static RectTransform s_panel; private static Button s_transmogButton; private static TMP_Text s_title; private static readonly Dictionary<string, TMP_Text> s_labels = new Dictionary<string, TMP_Text>(); private static readonly Color LabelColor = new Color(0.85f, 0.8f, 0.7f, 1f); private static readonly Color LabelTransmogColor = new Color(1f, 0.68f, 0.2f, 1f); private static readonly Vector3[] s_corners = (Vector3[])(object)new Vector3[4]; public static bool Built => (Object)(object)s_panel != (Object)null; public static void Destroy() { if ((Object)(object)s_panel != (Object)null) { Object.Destroy((Object)(object)((Component)s_panel).gameObject); } s_panel = null; s_transmogButton = null; s_title = null; s_labels.Clear(); } private static float Space(InventoryGrid grid) { return ((Object)(object)grid != (Object)null && grid.m_elementSpace > 1f) ? grid.m_elementSpace : 70f; } private static RectTransform Ensure(InventoryGui gui) { //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_013f: 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_017d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)s_panel != (Object)null) { return s_panel; } if ((Object)(object)gui == (Object)null || (Object)(object)gui.m_player == (Object)null) { return null; } Transform val = ((Transform)gui.m_player).Find("vsm_slots_panel"); if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)((Component)val).gameObject); } RectTransform val2 = UiKit.NewRect((Transform)(object)gui.m_player, "vsm_slots_panel"); UiKit.VanillaBackground((Transform)(object)gui.m_player, val2); s_title = (TMP_Text)(object)UiKit.Text((Transform)(object)val2, "vsm_slots_title", VanillaStyle.TitleFont, 22f, (TextAlignmentOptions)514); s_title.text = VsmLocalization.Localize("$vsm_slots_title"); s_title.rectTransform.anchorMin = new Vector2(0f, 1f); s_title.rectTransform.anchorMax = new Vector2(1f, 1f); s_title.rectTransform.pivot = new Vector2(0.5f, 1f); s_title.rectTransform.anchoredPosition = new Vector2(0f, -6f); s_title.rectTransform.sizeDelta = new Vector2(-24f, 28f); s_transmogButton = UiKit.MakeButton((Transform)(object)val2, VsmLocalization.Localize("$vsm_slots_transmog_button"), delegate { TransmogPanel.Toggle(gui); }); s_panel = val2; return val2; } public static void Layout(InventoryGui gui, InventoryGrid grid) { //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)gui == (Object)null || (Object)(object)grid == (Object)null || (Object)(object)grid != (Object)(object)gui.m_playerGrid || (Object)(object)localPlayer == (Object)null || !SlotState.HiddenRowActive(((Humanoid)localPlayer).m_inventory, out var visibleRows)) { return; } RectTransform val = Ensure(gui); if ((Object)(object)val == (Object)null) { return; } float num = Space(grid); float num2 = num + 14f; float num3 = 40f; float num4 = 3f * num2; float num5 = 24f + num * 2f + 10f; bool active = TransmogRuntime.Active; float num6 = num3 + num4 + (active ? 38f : 0f) + 12f; val.sizeDelta = new Vector2(num5, num6); Place(gui, val, num5); float num7 = 12f; float num8 = 12f + num + 10f; if ((Object)(object)s_transmogButton != (Object)null) { ((Component)s_transmogButton).gameObject.SetActive(active); UiKit.TopLeft(((Component)s_transmogButton).GetComponent<RectTransform>(), 12f, 0f - (num3 + num4 + 2f), num5 - 24f, 32f); } TransmogData transmogData = (active ? TransmogRuntime.Get(localPlayer) : null); Vector2 val2 = default(Vector2); for (int i = 0; i < 8; i++) { InventoryElement element = grid.GetElement(i, visibleRows, 8); if ((Object)(object)element == (Object)null) { continue; } SlotDefinition slotDefinition = SlotLayout.SlotAt(new Vector2i(i, visibleRows), visibleRows); RectTransform elementRectTransform = element.GetElementRectTransform(); if (slotDefinition == null) { ((Component)element).gameObject.SetActive(false); HideLabel(i); continue; } ((Component)element).gameObject.SetActive(true); if ((Object)(object)((Transform)elementRectTransform).parent != (Object)(object)val) { ((Transform)elementRectTransform).SetParent((Transform)(object)val, false); } float num9 = ((slotDefinition.Column == 0) ? num7 : num8) + (num - elementRectTransform.sizeDelta.x) * 0.5f; float num10 = 0f - (num3 + (float)slotDefinition.Row * num2); ((Vector2)(ref val2))..ctor(0f, 1f); elementRectTransform.anchorMax = val2; elementRectTransform.anchorMin = val2; elementRectTransform.pivot = new Vector2(0f, 1f); elementRectTransform.anchoredPosition = new Vector2(num9, num10); Appearance look; bool transmog = transmogData?.TryGet(slotDefinition.Id, out look) ?? false; PlaceLabel(element, slotDefinition, val, (slotDefinition.Column == 0) ? num7 : num8, num10 - elementRectTransform.sizeDelta.y - 1f, num, transmog); } grid.m_gridRoot.SetSizeWithCurrentAnchors((Axis)1, (float)visibleRows * num); } public static void Tick() { bool inventoryVisible = (Object)(object)s_panel != (Object)null && InventoryGui.IsVisible() && ((Component)s_panel).gameObject.activeInHierarchy; TransmogPanel.Tick(inventoryVisible); } private static void Place(InventoryGui gui, RectTransform panel, float width) { //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: 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_0057: Unknown result type (might be due to invalid IL or missing references) RectTransform player = gui.m_player; float num = Mathf.Abs(SlotsPlugin.PanelGapX.Value) + OverhangRight(gui); float num2 = Mathf.Clamp(SlotsPlugin.PanelScale.Value, 0.5f, 2f); float num3 = RightPanelsLeftEdge(gui); if (!float.IsInfinity(num3)) { Rect rect = player.rect; float num4 = num3 - (((Rect)(ref rect)).xMax + num) - 8f; if (num4 > 0f && width * num2 > num4) { num2 = Mathf.Max(0.6f, num4 / width); } } Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(1f, 1f); panel.anchorMax = val; panel.anchorMin = val; panel.pivot = new Vector2(0f, 1f); ((Transform)panel).localScale = new Vector3(num2, num2, 1f); panel.anchoredPosition = new Vector2(num, SlotsPlugin.PanelOffsetY.Value); } private static float RightPanelsLeftEdge(InventoryGui gui) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) float num = float.PositiveInfinity; RectTransform[] array = (RectTransform[])(object)new RectTransform[2] { gui.m_info, gui.m_crafting }; foreach (RectTransform val in array) { if (!((Object)(object)val == (Object)null) && ((Component)val).gameObject.activeInHierarchy) { val.GetWorldCorners(s_corners); for (int j = 0; j < 4; j++) { num = Mathf.Min(num, ((Transform)gui.m_player).InverseTransformPoint(s_corners[j]).x); } } } return num; } private static float OverhangRight(InventoryGui gui) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) RectTransform player = gui.m_player; Rect rect = player.rect; float xMax = ((Rect)(ref rect)).xMax; float num = 0f; TMP_Text[] array = (TMP_Text[])(object)new TMP_Text[2] { gui.m_armor, gui.m_weight }; foreach (TMP_Text val in array) { if ((Object)(object)val == (Object)null) { continue; } Transform val2 = val.transform; int num2 = 0; while (num2 < 3 && (Object)(object)val2 != (Object)null && (Object)(object)val2 != (Object)(object)player) { RectTransform val3 = (RectTransform)(object)((val2 is RectTransform) ? val2 : null); if (!((Object)(object)val3 == (Object)null)) { val3.GetWorldCorners(s_corners); for (int j = 0; j < 4; j++) { num = Mathf.Max(num, ((Transform)player).InverseTransformPoint(s_corners[j]).x - xMax); } } num2++; val2 = val2.parent; } } return Mathf.Clamp(num, 0f, 400f); } private static void PlaceLabel(InventoryElement element, SlotDefinition slot, RectTransform panel, float x, float y, float width, bool transmog) { //IL_00b9: 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) if (!s_labels.TryGetValue(slot.Id, out var value) || (Object)(object)value == (Object)null) { value = (TMP_Text)(object)UiKit.Text((Transform)(object)panel, "vsm_slots_label_" + slot.Id, VanillaStyle.BodyFont, 12f, (TextAlignmentOptions)514); s_labels[slot.Id] = value; } bool value2 = SlotsPlugin.ShowSlotLabels.Value; ((Component)value).gameObject.SetActive(value2); if (value2) { UiKit.TopLeft(value.rectTransform, x, y, width, 14f); value.text = VsmLocalization.Localize(slot.NameToken); ((Graphic)value).color = (transmog ? LabelTransmogColor : LabelColor); } } private static void HideLabel(int order) { SlotDefinition[] all = SlotLayout.All; foreach (SlotDefinition slotDefinition in all) { if (slotDefinition.Order == order && s_labels.TryGetValue(slotDefinition.Id, out var value) && (Object)(object)value != (Object)null) { ((Component)value).gameObject.SetActive(false); } } } } internal static class TransmogPanel { private enum CellKind { Original, Hide, Look } private sealed class CellView { public InventoryElement Element; public CellKind Kind; public LookOption Option; } private const string PanelName = "vsm_slots_transmog"; private const float Pad = 14f; private const float Cell = 64f; private const float CellGap = 6f; private static RectTransform s_panel; private static RectTransform s_content; private static TMP_Text s_info; private static TMP_Text s_empty; private static readonly Dictionary<string, Button> s_tabs = new Dictionary<string, Button>(); private static readonly List<CellView> s_cells = new List<CellView>(); private static SlotDefinition s_slot; private static string s_signature; public static bool IsOpen => (Object)(object)s_panel != (Object)null && ((Component)s_panel).gameObject.activeSelf; public static void Toggle(InventoryGui gui) { if (IsOpen) { Close(); } else { Open(gui); } } public static void Close() { if ((Object)(object)s_panel != (Object)null) { ((Component)s_panel).gameObject.SetActive(false); } } public static void Destroy() { if ((Object)(object)s_panel != (Object)null) { Object.Destroy((Object)(object)((Component)s_panel).gameObject); } s_panel = null; s_content = null; s_info = null; s_empty = null; s_tabs.Clear(); s_cells.Clear(); s_signature = null; } private static void Open(InventoryGui gui) { if (TransmogRuntime.Active && !((Object)(object)Player.m_localPlayer == (Object)null) && Ensure(gui)) { if (s_slot == null || !SlotLayout.IsEnabled(s_slot)) { s_slot = FirstEnabled(); } ((Component)s_panel).gameObject.SetActive(true); ((Transform)s_panel).SetAsLastSibling(); s_signature = null; } } public static void Tick(bool inventoryVisible) { if (!IsOpen) { return; } Player localPlayer = Player.m_localPlayer; if (!inventoryVisible || (Object)(object)localPlayer == (Object)null || !TransmogRuntime.Active) { Close(); return; } if (s_slot == null || !SlotLayout.IsEnabled(s_slot)) { s_slot = FirstEnabled(); if (s_slot == null) { Close(); return; } } ItemData val = s_slot.Equipped((Humanoid)(object)localPlayer); localPlayer.m_customData.TryGetValue("vsm.slots.transmog", out var value); string text = s_slot.Id + "|" + ((val != null && (Object)(object)val.m_dropPrefab != (Object)null) ? ((Object)val.m_dropPrefab).name : ((val != null) ? val.m_shared.m_name : "-")) + "|" + localPlayer.m_knownMaterial.Count + "|" + value + "|" + SlotsPlugin.TransmogAllowHide.Value + "|" + SlotsPlugin.TransmogRequireKnown.Value; if (text != s_signature) { s_signature = text; Rebuild(localPlayer, val); } } private static SlotDefinition FirstEnabled() { SlotDefinition[] all = SlotLayout.All; foreach (SlotDefinition slotDefinition in all) { if (SlotLayout.IsEnabled(slotDefinition)) { return slotDefinition; } } return null; } private static bool Ensure(InventoryGui gui) { //IL_0099: 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_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_02d1: Unknown result type (might be due to invalid IL or missing references) //IL_02eb: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Unknown result type (might be due to invalid IL or missing references) //IL_0354: Unknown result type (might be due to invalid IL or missing references) //IL_0365: Unknown result type (might be due to invalid IL or missing references) //IL_036f: Expected O, but got Unknown //IL_0465: Unknown result type (might be due to invalid IL or missing references) //IL_0484: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)s_panel != (Object)null) { return true; } if ((Object)(object)gui == (Object)null || (Object)(object)gui.m_crafting == (Object)null) { return false; } Transform val = ((Transform)gui.m_crafting).Find("vsm_slots_transmog"); if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)((Component)val).gameObject); } RectTransform val2 = UiKit.NewRect((Transform)(object)gui.m_crafting, "vsm_slots_transmog"); UiKit.Stretch(val2); UiKit.VanillaBackground((Transform)(object)gui.m_crafting, val2); Rect rect = gui.m_crafting.rect; float width = ((Rect)(ref rect)).width; rect = gui.m_crafting.rect; float height = ((Rect)(ref rect)).height; TMP_Text val3 = (TMP_Text)(object)UiKit.Text((Transform)(object)val2, "title", VanillaStyle.TitleFont, 26f, (TextAlignmentOptions)514); val3.text = VsmLocalization.Localize("$vsm_slots_transmog_title"); UiKit.TopLeft(val3.rectTransform, 14f, -14f, width - 28f, 34f); float num = (width - 28f - 20f) / 6f; float num2 = 14f; SlotDefinition[] all = SlotLayout.All; foreach (SlotDefinition slotDefinition in all) { SlotDefinition captured = slotDefinition; Button val4 = UiKit.MakeButton((Transform)(object)val2, VsmLocalization.Localize(slotDefinition.NameToken), delegate { s_slot = captured; s_signature = null; }); UiKit.TopLeft(((Component)val4).GetComponent<RectTransform>(), num2, -54f, num, 34f); s_tabs[slotDefinition.Id] = val4; num2 += num + 4f; } s_info = (TMP_Text)(object)UiKit.Text((Transform)(object)val2, "info", VanillaStyle.BodyFont, 16f, (TextAlignmentOptions)514); s_info.enableWordWrapping = true; UiKit.TopLeft(s_info.rectTransform, 14f, -94f, width - 28f, 44f); float num3 = 144f; float num4 = 50f; RectTransform val5 = UiKit.NewRect((Transform)(object)val2, "viewport"); UiKit.TopLeft(val5, 14f, 0f - num3, width - 28f, height - num3 - num4 - 14f); ((Component)val5).gameObject.AddComponent<RectMask2D>(); Image val6 = ((Component)val5).gameObject.AddComponent<Image>(); ((Graphic)val6).color = new Color(0f, 0f, 0f, 0.25f); s_content = UiKit.NewRect((Transform)(object)val5, "content"); s_content.anchorMin = new Vector2(0f, 1f); s_content.anchorMax = new Vector2(1f, 1f); s_content.pivot = new Vector2(0.5f, 1f); s_content.anchoredPosition = Vector2.zero; s_content.sizeDelta = new Vector2(0f, 0f); GridLayoutGroup val7 = ((Component)s_content).gameObject.AddComponent<GridLayoutGroup>(); val7.cellSize = new Vector2(64f, 64f); val7.spacing = new Vector2(6f, 6f); ((LayoutGroup)val7).padding = new RectOffset(8, 8, 8, 8); ((LayoutGroup)val7).childAlignment = (TextAnchor)1; val7.constraint = (Constraint)1; val7.constraintCount = Mathf.Max(1, Mathf.FloorToInt((width - 28f - 16f + 6f) / 70f)); ContentSizeFitter val8 = ((Component)s_content).gameObject.AddComponent<ContentSizeFitter>(); val8.verticalFit = (FitMode)2; ScrollRect val9 = ((Component)val5).gameObject.AddComponent<ScrollRect>(); val9.content = s_content; val9.viewport = val5; val9.horizontal = false; val9.vertical = true; val9.movementType = (MovementType)2; val9.scrollSensitivity = 40f; s_empty = (TMP_Text)(object)UiKit.Text((Transform)(object)val5, "empty", VanillaStyle.BodyFont, 16f, (TextAlignmentOptions)514); s_empty.enableWordWrapping = true; UiKit.Stretch(s_empty.rectTransform); s_empty.rectTransform.offsetMin = new Vector2(20f, 20f); s_empty.rectTransform.offsetMax = new Vector2(-20f, -20f); float num5 = (width - 28f - 8f) / 2f; Button val10 = UiKit.MakeButton((Transform)(object)val2, VsmLocalization.Localize("$vsm_slots_transmog_reset_all"), delegate { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { TransmogRuntime.ClearAll(localPlayer); } }); UiKit.TopLeft(((Component)val10).GetComponent<RectTransform>(), 14f, 0f - (height - num4), num5, 38f); Button val11 = UiKit.MakeButton((Transform)(object)val2, VsmLocalization.Localize("$vsm_slots_close"), Close); UiKit.TopLeft(((Component)val11).GetComponent<RectTransform>(), 14f + num5 + 8f, 0f - (height - num4), num5, 38f); s_panel = val2; ((Component)val2).gameObject.SetActive(false); return true; } private static void Rebuild(Player p, ItemData real) { //IL_0166: Unknown result type (might be due to invalid IL or missing references) foreach (KeyValuePair<string, Button> s_tab in s_tabs) { SlotDefinition slotDefinition = SlotLayout.ById(s_tab.Key); ((Component)s_tab.Value).gameObject.SetActive(slotDefinition != null && SlotLayout.IsEnabled(slotDefinition)); ((Selectable)s_tab.Value).interactable = slotDefinition != s_slot; } foreach (CellView s_cell in s_cells) { if ((Object)(object)s_cell.Element != (Object)null) { Object.Destroy((Object)(object)((Component)s_cell.Element).gameObject); } } s_cells.Clear(); string text = VsmLocalization.Localize(s_slot.NameToken); s_info.text = ((real != null) ? VsmLocalization.Localize("$vsm_slots_transmog_wearing", text, VsmLocalization.Localize(real.m_shared.m_name)) : VsmLocalization.Localize("$vsm_slots_transmog_nothing", text)); TransmogData transmogData = TransmogRuntime.Get(p); Appearance look; bool flag = transmogData.TryGet(s_slot.Id, out look); List<LookOption> list = TransmogCatalog.For(s_slot.Type, SlotsPlugin.TransmogRequireKnown.Value ? p : null); ((Component)s_empty).gameObject.SetActive(list.Count == 0); s_empty.text = VsmLocalization.Localize("$vsm_slots_transmog_none_known", text); if (list.Count == 0 && !flag) { return; } AddCell(CellKind.Original, null, (real != null) ? real.GetIcon() : null, !flag, VsmLocalization.Localize("$vsm_slots_transmog_original"), VsmLocalization.Localize("$vsm_slots_transmog_original_tip")); if (SlotsPlugin.TransmogAllowHide.Value) { AddCell(CellKind.Hide, null, null, flag && look.Hidden, VsmLocalization.Localize("$vsm_slots_transmog_hide"), VsmLocalization.Localize("$vsm_slots_transmog_hide_tip")); } foreach (LookOption item in list) { bool selected = flag && !look.Hidden && look.Prefab == item.Prefab && look.Variant == item.Variant; string text2 = VsmLocalization.Localize(item.Shared.m_name); if (item.Shared.m_variants > 1) { text2 = text2 + " (" + (item.Variant + 1) + ")"; } AddCell(CellKind.Look, item, item.Icon, selected, null, text2); } } private static void AddCell(CellKind kind, LookOption option, Sprite icon, bool selected, string caption, string tooltip) { //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Expected O, but got Unknown //IL_0258: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Expected O, but got Unknown //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) InventoryGui instance = InventoryGui.instance; GameObject val = (((Object)(object)instance != (Object)null && (Object)(object)instance.m_playerGrid != (Object)null) ? instance.m_playerGrid.m_elementPrefab : null); if ((Object)(object)val == (Object)null) { return; } GameObject val2 = Object.Instantiate<GameObject>(val, (Transform)(object)s_content, false); ((Object)val2).name = "vsm_look"; InventoryElement component = val2.GetComponent<InventoryElement>(); if ((Object)(object)component == (Object)null) { Object.Destroy((Object)(object)val2); return; } component.Initialize(-1, -1); ((Behaviour)component.m_icon).enabled = (Object)(object)icon != (Object)null; component.m_icon.sprite = icon; ((Graphic)component.m_icon).color = (Color)((kind == CellKind.Original) ? new Color(1f, 1f, 1f, 0.55f) : Color.white); ((Behaviour)component.m_amount).enabled = false; ((Behaviour)component.m_quality).enabled = false; ((Behaviour)component.m_queued).enabled = false; ((Behaviour)component.m_noteleport).enabled = false; ((Behaviour)component.m_food).enabled = false; ((Component)component.m_durability).gameObject.SetActive(false); component.m_selected.SetActive(false); ((Behaviour)component.m_equiped).enabled = selected; Transform val3 = val2.transform.Find("binding"); if ((Object)(object)val3 != (Object)null) { ((Component)val3).gameObject.SetActive(false); } if (!string.IsNullOrEmpty(caption)) { TMP_Text val4 = (TMP_Text)(object)UiKit.Text(val2.transform, "caption", VanillaStyle.BodyFont, 13f, (TextAlignmentOptions)514); UiKit.Stretch(val4.rectTransform); val4.enableWordWrapping = true; val4.text = caption; } if ((Object)(object)component.m_tooltip != (Object)null) { component.m_tooltip.Set(tooltip ?? string.Empty, string.Empty, (RectTransform)null, default(Vector2)); } Button component2 = val2.GetComponent<Button>(); if ((Object)(object)component2 != (Object)null) { component2.onClick = new ButtonClickedEvent(); ((UnityEvent)component2.onClick).AddListener((UnityAction)delegate { OnCellClicked(kind, option); }); } s_cells.Add(new CellView { Element = component, Kind = kind, Option = option }); } private static void OnCellClicked(CellKind kind, LookOption option) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || s_slot == null) { return; } switch (kind) { case CellKind.Original: TransmogRuntime.Clear(localPlayer, s_slot); break; case CellKind.Hide: TransmogRuntime.Set(localPlayer, s_slot, Appearance.HiddenLook); break; default: if (option != null) { TransmogRuntime.Set(localPlayer, s_slot, new Appearance { Prefab = option.Prefab, Variant = option.Variant }); } break; } if (s_slot.Equipped((Humanoid)(object)localPlayer) == null) { SlotsPlugin.Message(localPlayer, "$vsm_slots_transmog_saved_empty", s_slot.NameToken); } s_signature = null; } } internal static class UiKit { public static RectTransform CloneChild(Transform vanillaPanel, string childName, RectTransform parent) { Transform val = (((Object)(object)vanillaPanel != (Object)null) ? vanillaPanel.Find(childName) : null); if ((Object)(object)val == (Object)null) { return null; } GameObject val2 = Object.Instantiate<GameObject>(((Component)val).gameObject, (Transform)(object)parent, false); ((Object)val2).name = "vsm_" + childName; for (int num = val2.transform.childCount - 1; num >= 0; num--) { Object.Destroy((Object)(object)((Component)val2.transform.GetChild(num)).gameObject); } MonoBehaviour[] components = val2.GetComponents<MonoBehaviour>(); foreach (MonoBehaviour val3 in components) { if (!(val3 is Graphic)) { Object.Destroy((Object)(object)val3); } } val2.SetActive(true); Transform transform = val2.transform; return (RectTransform)(object)((transform is RectTransform) ? transform : null); } public static void VanillaBackground(Transform vanillaPanel, RectTransform panel) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) RectTransform val = CloneChild(vanillaPanel, "Darken", panel); RectTransform val2 = CloneChild(vanillaPanel, "Bkg", panel); if ((Object)(object)val2 != (Object)null) { ((Transform)val2).SetAsFirstSibling(); Image component = ((Component)val2).GetComponent<Image>(); if ((Object)(object)component != (Object)null) { ((Graphic)component).raycastTarget = true; } } else { Image val3 = ((Component)panel).gameObject.AddComponent<Image>(); ((Graphic)val3).color = new Color(0.1f, 0.08f, 0.06f, 0.92f); } if ((Object)(object)val != (Object)null) { ((Transform)val).SetAsFirstSibling(); Image component2 = ((Component)val).GetComponent<Image>(); if ((Object)(object)component2 != (Object)null) { ((Graphic)component2).raycastTarget = false; } } } public static Button MakeButton(Transform parent, string label, Action onClick) { //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Expected O, but got Unknown //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Expected O, but got Unknown //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Expected O, but got Unknown Button val = (((Object)(object)InventoryGui.instance != (Object)null) ? InventoryGui.instance.m_craftButton : null); GameObject val2; if ((Object)(object)val != (Object)null) { val2 = Object.Instantiate<GameObject>(((Component)val).gameObject, parent, false); UIGamePad[] componentsInChildren = val2.GetComponentsInChildren<UIGamePad>(true); foreach (UIGamePad val3 in componentsInChildren) { if ((Object)(object)val3.m_hint != (Object)null) { Object.Destroy((Object)(object)val3.m_hint); } Object.Destroy((Object)(object)val3); } } else { val2 = new GameObject("button", new Type[1] { typeof(RectTransform) }); val2.transform.SetParent(parent, false); ((Graphic)val2.AddComponent<Image>()).color = new Color(0.2f, 0.15f, 0.1f, 0.9f); val2.AddComponent<Button>(); } ((Object)val2).name = "vsm_slots_btn"; val2.SetActive(true); Button component = val2.GetComponent<Button>(); component.onClick = new ButtonClickedEvent(); ((UnityEvent)component.onClick).AddListener((UnityAction)delegate { onClick(); }); ((Selectable)component).interactable = true; TMP_Text val4 = val2.GetComponentInChildren<TMP_Text>(true); if ((Object)(object)val4 == (Object)null) { val4 = (TMP_Text)(object)VanillaStyle.NewText(val2.transform, "label", VanillaStyle.BodyFont, 16f, (TextAlignmentOptions)514); Stretch(val4.rectTransform); } val4.text = label; val4.enableAutoSizing = true; val4.fontSizeMin = 10f; val4.fontSizeMax = 18f; ((Component)val4).gameObject.SetActive(true); return component; } public static void SetLabel(Button b, string label) { TMP_Text val = (((Object)(object)b != (Object)null) ? ((Component)b).GetComponentInChildren<TMP_Text>(true) : null); if ((Object)(object)val != (Object)null) { val.text = label; } } public static TextMeshProUGUI Text(Transform parent, string name, TMP_Text style, float size, TextAlignmentOptions align) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) TextMeshProUGUI val = VanillaStyle.NewText(parent, name, style, size, align); ((TMP_Text)val).enableAutoSizing = true; ((TMP_Text)val).fontSizeMin = Mathf.Max(8f, size - 6f); ((TMP_Text)val).fontSizeMax = size; ((TMP_Text)val).overflowMode = (TextOverflowModes)1; return val; } public static RectTransform NewRect(Transform parent, string name) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); return val.GetComponent<RectTransform>(); } public static void TopLeft(RectTransform rt, float x, float y, float w, float h) { //IL_0014: 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_002d: 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_004a: Unknown result type (might be due to invalid IL or missing references) Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0f, 1f); rt.anchorMax = val; rt.anchorMin = val; rt.pivot = new Vector2(0f, 1f); rt.anchoredPosition = new Vector2(x, y); rt.sizeDelta = new Vector2(w, h); } public static void Stretch(RectTransform rt) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) rt.anchorMin = Vector2.zero; rt.anchorMax = Vector2.one; Vector2 offsetMin = (rt.offsetMax = Vector2.zero); rt.offsetMin = offsetMin; } } internal static class UiPatches { [HarmonyPatch(typeof(InventoryGrid), "UpdateGui")] internal static class GridLayoutPatch { [HarmonyPostfix] private static void Postfix(InventoryGrid __instance) { InventoryGui instance = InventoryGui.instance; if ((Object)(object)instance == (Object)null || (Object)(object)__instance != (Object)(object)instance.m_playerGrid) { return; } try { EquipmentPanel.Layout(instance, __instance); } catch (Exception ex) { SlotsPlugin.LogOnce("layout", "vsm.slots: panel de equipo: " + ex); } } } [HarmonyPatch(typeof(InventoryGui), "Hide")] internal static class HidePatch { [HarmonyPostfix] private static void Postfix() { TransmogPanel.Close(); } } [HarmonyPatch(typeof(InventoryGui), "OnDestroy")] internal static class DestroyPatch { [HarmonyPrefix] private static void Prefix() { TransmogPanel.Destroy(); EquipmentPanel.Destroy(); } } public static readonly Type[] Classes = new Type[3] { typeof(GridLayoutPatch), typeof(HidePatch), typeof(DestroyPatch) }; } } namespace VSM.Slots.Transmog { internal sealed class LookOption { public string Prefab; public int Variant; public SharedData Shared; public Sprite Icon { get { Sprite[] icons = Shared.m_icons; if (icons == null || icons.Length == 0) { return null; } return icons[Mathf.Clamp(Variant, 0, icons.Length - 1)]; } } } internal static class TransmogCatalog { private static ObjectDB s_builtFor; private static int s_builtCount = -1; private static readonly Dictionary<ItemType, List<LookOption>> s_byType = new Dictionary<ItemType, List<LookOption>>(); private static readonly Dictionary<string, ItemDrop> s_byPrefab = new Dictionary<string, ItemDrop>(StringComparer.Ordinal); private static readonly string[] ExcludedPrefixes = new string[3] { "FW_", "SP_", "CapeTest" }; public static List<LookOption> For(ItemType type, Player knownBy) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) Ensure(); List<LookOption> list = new List<LookOption>(); if (!s_byType.TryGetValue(type, out var value)) { return list; } foreach (LookOption item in value) { if ((Object)(object)knownBy == (Object)null || knownBy.IsMaterialKnown(item.Shared.m_name)) { list.Add(item); } } return list; } public static ItemDrop Lookup(string prefab, ItemType type) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) Ensure(); if (string.IsNullOrEmpty(prefab) || !s_byPrefab.TryGetValue(prefab, out var value) || (Object)(object)value == (Object)null) { return null; } return (value.m_itemData.m_shared.m_itemType == type) ? value : null; } public static void Invalidate() { s_builtFor = null; s_builtCount = -1; } private static void Ensure() { //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Invalid comparison between Unknown and I4 //IL_020d: Unknown result type (might be due to invalid IL or missing references) ObjectDB instance = ObjectDB.instance; if ((Object)(object)instance == (Object)null) { s_byType.Clear(); s_byPrefab.Clear(); } else { if ((Object)(object)instance == (Object)(object)s_builtFor && instance.m_items.Count == s_builtCount) { return; } s_byType.Clear(); s_byPrefab.Clear(); HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal); foreach (GameObject item in instance.m_items) { if ((Object)(object)item == (Object)null) { continue; } ItemDrop component = item.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null || component.m_itemData == null || component.m_itemData.m_shared == null) { continue; } SharedData shared = component.m_itemData.m_shared; if (SlotLayout.ForType(shared.m_itemType) != null && !IsExcluded(((Object)item).name) && shared.m_icons != null && shared.m_icons.Length != 0 && HasBodyVisual(item.transform, shared.m_itemType) && (string.IsNullOrEmpty(shared.m_dlc) || (!((Object)(object)DLCMan.instance == (Object)null) && DLCMan.instance.IsDLCInstalled(shared.m_dlc))) && hashSet.Add(((object)Unsafe.As<ItemType, ItemType>(ref shared.m_itemType)/*cast due to .constrained prefix*/).ToString() + "|" + shared.m_name)) { s_byPrefab[((Object)item).name] = component; if (!s_byType.TryGetValue(shared.m_itemType, out var value)) { value = new List<LookOption>(); s_byType[shared.m_itemType] = value; } int num = (((int)shared.m_itemType != 17) ? 1 : Mathf.Max(1, Mathf.Min(shared.m_variants, shared.m_icons.Length))); for (int i = 0; i < num; i++) { value.Add(new LookOption { Prefab = ((Object)item).name, Variant = i, Shared = shared }); } } } foreach (List<LookOption> value2 in s_byType.Values) { value2.Sort(Compare); } s_builtFor = instance; s_builtCount = instance.m_items.Count; } } private static int Compare(LookOption a, LookOption b) { int num = string.Compare(Localized(a.Shared.m_name), Localized(b.Shared.m_name), StringComparison.CurrentCultureIgnoreCase); return (num != 0) ? num : a.Variant.CompareTo(b.Variant); } private static string Localized(string token) { return (Localization.instance != null) ? Localization.instance.Localize(token) : token; } private static bool IsExcluded(string prefab) { string[] excludedPrefixes = ExcludedPrefixes; foreach (string value in excludedPrefixes) { if (prefab.StartsWith(value, StringComparison.Ordinal)) { return true; } } return false; } private static bool HasBodyVisual(Transform root, ItemType type) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Invalid comparison between Unknown and I4 for (int i = 0; i < root.childCount; i++) { string name = ((Object)root.GetChild(i)).name; if (name.StartsWith("attach_", StringComparison.Ordinal) || ((int)type == 6 && name == "attach")) { return true; } } return false; } } public struct Appearance { public string Prefab; public int Variant; public bool Hidden; public static Appearance HiddenLook => new Appearance { Hidden = true }; public bool IsSet => Hidden || !string.IsNullOrEmpty(Prefab); } public sealed class TransmogData { public const string Key = "vsm.slots.transmog"; private const int MaxNameLength = 80; private readonly Dictionary<string, Appearance> _slots = new Dictionary<string, Appearance>(StringComparer.OrdinalIgnoreCase); public int Count => _slots.Count; public bool TryGet(string slotId, out Appearance look) { return _slots.TryGetValue(slotId ?? string.Empty, out look); } public void Set(string slotId, Appearance look) { if (!string.IsNullOrEmpty(slotId)) { if (!look.IsSet) { _slots.Remove(slotId); } else if (look.Hidden || IsSafeName(look.Prefab)) { look.Variant = Math.Max(0, Math.Min(31, look.Variant)); _slots[slotId] = look; } } } public void Clear(string slotId) { _slots.Remove(slotId ?? string.Empty); } public void ClearAll() { _slots.Clear(); } public static bool IsSafeName(string name) { if (string.IsNullOrEmpty(name) || name.Length > 80) { return false; } foreach (char c in name) { if (!char.IsLetterOrDigit(c) && c != '_' && c != '-' && c != '(' && c != ')' && c != '.') { return false; } } return name != "-"; } public string Serialize() { StringBuilder stringBuilder = new StringBuilder(); List<string> list = new List<string>(_slots.Keys); list.Sort(StringComparer.OrdinalIgnoreCase); foreach (string item in list) { Appearance appearance = _slots[item]; if (stringBuilder.Length > 0) { stringBuilder.Append(';'); } stringBuilder.Append(item.ToLowerInvariant()).Append('='); if (appearance.Hidden) { stringBuilder.Append('-'); continue; } stringBuilder.Append(appearance.Prefab); if (appearance.Variant > 0) { stringBuilder.Append(':').Append(appearance.Variant); } } return stringBuilder.ToString(); } public static TransmogData Parse(string text, ICollection<string> knownSlots) { TransmogData transmogData = new TransmogData(); if (string.IsNullOrEmpty(text)) { return transmogData; } string[] array = text.Split(new char[1] { ';' }); foreach (string text2 in array) { int num = text2.IndexOf('='); if (num <= 0) { continue; } string text3 = text2.Substring(0, num).Trim(); string text4 = text2.Substring(num + 1).Trim(); if (knownSlots != null && !Contains(knownSlots, text3)) { continue; } if (text4 == "-") { transmogData.Set(text3, Appearance.HiddenLook); continue; } int result = 0; int num2 = text4.LastIndexOf(':'); if (num2 > 0) { int.TryParse(text4.Substring(num2 + 1), out result); text4 = text4.Substring(0, num2); } transmogData.Set(text3, new Appearance { Prefab = text4, Variant = result }); } return transmogData; } private static bool Contains(ICollection<string> set, string key) { foreach (string item in set) { if (string.Equals(item, key, StringComparison.OrdinalIgnoreCase)) { return true; } } return false; } } internal static class TransmogRuntime { [HarmonyPatch(typeof(Humanoid), "SetupVisEquipment", new Type[] { typeof(VisEquipment), typeof(bool) })] internal static class ApplyPatch { [HarmonyPostfix] private static void Postfix(Humanoid __instance, VisEquipment visEq, bool isRagdoll) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if ((Object)(object)val == (Object)null || (Object)(object)val != (Object)(object)Player.m_localPlayer || (Object)(object)visEq == (Object)null || val.m_isLoading || !Active) { return; } try { Apply(val, visEq); } catch (Exception ex) { SlotsPlugin.Log.LogError((object)("vsm.slots: transfiguración: " + ex.Message)); } } } private static Player s_cachedFor; private static string s_cachedRaw; private static TransmogData s_cached; private static readonly List<string> s_slotIds = new List<string>(); public static bool Active => SlotsPlugin.TransmogEnabled != null && SlotsPlugin.TransmogEnabled.Value && SlotsPlugin.IsConfigReady; private static ICollection<string> SlotIds { get { if (s_slotIds.Count == 0) { SlotDefinition[] all = SlotLayout.All; foreach (SlotDefinition slotDefinition in all) { s_slotIds.Add(slotDefinition.Id); } } return s_slotIds; } } public static TransmogData Get(Player p) { p.m_customData.TryGetValue("vsm.slots.transmog", out var value); if ((Object)(object)p != (Object)(object)s_cachedFor || !string.Equals(value, s_cachedRaw, StringComparison.Ordinal) || s_cached == null) { s_cached = TransmogData.Parse(value, SlotIds); s_cachedRaw = value; s_cachedFor = p; } return s_cached; } public static void Set(Player p, SlotDefinition slot, Appearance look) { TransmogData transmogData = Get(p); transmogData.Set(slot.Id, look); Store(p, transmogData); } public static void Clear(Player p, SlotDefinition slot) { TransmogData transmogData = Get(p); transmogData.Clear(slot.Id); Store(p, transmogData); } public static void ClearAll(Player p) { TransmogData transmogData = Get(p); transmogData.ClearAll(); Store(p, transmogData); } private static void Store(Player p, TransmogData data) { string text = data.Serialize(); if (text.Length == 0) { p.m_customData.Remove("vsm.slots.transmog"); } else { p.m_customData["vsm.slots.transmog"] = text; } s_cachedFor = null; Refresh(p); } public static void Refresh(Player p) { if ((Object)(object)p != (Object)null && (Object)(object)((Humanoid)p).m_visEquipment != (Object)null && !p.m_isLoading) { ((Humanoid)p).SetupVisEquipment(((Humanoid)p).m_visEquipment, false); } } public static bool TryResolve(Player p, SlotDefinition slot, out Appearance look, out ItemDrop drop) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) look = default(Appearance); drop = null; if (!Active || !SlotLayout.IsEnabled(slot) || slot.Equipped((Humanoid)(object)p) == null || !Get(p).TryGet(slot.Id, out look)) { return false; } if (look.Hidden) { return SlotsPlugin.TransmogAllowHide.Value; } drop = TransmogCatalog.Lookup(look.Prefab, slot.Type); if ((Object)(object)drop == (Object)null) { return false; } if (SlotsPlugin.TransmogRequireKnown.Value && !p.IsMaterialKnown(drop.m_itemData.m_shared.m_name)) { return false; } return true; } private static void Apply(Player p, VisEquipment visEq) { //IL_004d: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Invalid comparison between Unknown and I4 //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Invalid comparison between Unknown and I4 //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Invalid comparison between Unknown and I4 //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Invalid comparison between Unknown and I4 //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Invalid comparison between Unknown and I4 //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Invalid comparison between Unknown and I4 //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Invalid comparison between Unknown and I4 SlotDefinition[] all = SlotLayout.All; foreach (SlotDefinition slotDefinition in all) { if (!TryResolve(p, slotDefinition, out var look, out var drop)) { continue; } int num = ((!look.Hidden) ? StringExtensionMethods.GetStableHashCode(((Object)((Component)drop).gameObject).name) : 0); ItemType type = slotDefinition.Type; ItemType val = type; if ((int)val <= 11) { if ((int)val != 6) { if ((int)val != 7) { if ((int)val == 11) { visEq.SetLegItem(num); } } else { visEq.SetChestItem(num); } } else { visEq.SetHelmetItem(num); } } else if ((int)val != 17) { if ((int)val != 18) { if ((int)val == 24) { visEq.SetTrinketItem(look.Hidden ? string.Empty : ((Object)((Component)drop).gameObject).name); } } else { visEq.SetUtilityItem(num); } } else { int num2 = (look.Hidden ? 1 : Math.Max(1, drop.m_itemData.m_shared.m_variants)); int num3 = ((!look.Hidden) ? Math.Max(0, Math.Min(num2 - 1, look.Variant)) : 0); visEq.SetShoulderItem(num, num3, (((Humanoid)p).m_shoulderItem != null) ? ((Humanoid)p).m_shoulderItem.m_quality : 0); } } } } } namespace VSM.Slots.Runtime { [HarmonyPatch(typeof(InventoryGui), "OnSelectedItem")] internal static class DragResolver { [HarmonyPrefix] [HarmonyPriority(600)] private static bool Prefix(InventoryGui __instance, InventoryGrid grid, Vector2i pos) { //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance.m_dragGo == (Object)null || (Object)(object)grid == (Object)null) { return true; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsTeleporting()) { return true; } Inventory inventory = ((Humanoid)localPlayer).m_inventory; if (!SlotState.HiddenRowActive(inventory, out var visibleRows)) { return true; } ItemData dragItem = __instance.m_dragItem; Inventory dragInventory = __instance.m_dragInventory; if (dragItem == null || dragInventory == null) { return true; } Inventory inventory2 = grid.GetInventory(); bool flag = inventory2 == inventory && pos.y == visibleRows; bool flag2 = dragInventory == inventory && dragItem.m_gridPos.y == visibleRows; if (!flag && !flag2) { return true; } if (!dragInventory.ContainsItem(dragItem)) { __instance.SetupDragItem((ItemData)null, (Inventory)null, 1); return false; } bool flag3; try { flag3 = (flag ? IntoSlot(localPlayer, inventory, visibleRows, dragInventory, dragItem, pos) : OutOfSlot(localPlayer, inventory, visibleRows, inventory2, dragItem, pos)); } catch (Exception ex) { SlotsPlugin.Log.LogError((object)("vsm.slots: error al mover " + dragItem.m_shared.m_name + ": " + ex)); flag3 = false; } finally { SlotState.Internal = false; } if (flag3) { __instance.m_moveItemEffects.Create(((Component)__instance).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID)); __instance.SetupDragItem((ItemData)null, (Inventory)null, 1); __instance.UpdateCraftingPanel(false); } return false; } private static bool IntoSlot(Player p, Inventory pinv, int v, Inventory from, ItemData drag, Vector2i pos) { //IL_0001: 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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0170: 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_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) SlotDefinition slotDefinition = SlotLayout.SlotAt(pos, v); if (from == pinv && drag.m_gridPos.x == pos.x && drag.m_gridPos.y == pos.y) { return true; } if (slotDefinition == null) { return false; } if (!slotDefinition.Accepts(drag)) { SlotsPlugin.Message(p, "$vsm_slots_wrong_type", slotDefinition.NameToken); return false; } ItemData itemAt = pinv.GetItemAt(pos.x, pos.y); if (from == pinv) { if (drag.m_gridPos.y == v) { return false; } if (itemAt == null) { Placement.Move(pinv, drag, pos); } else { ((Humanoid)p).RemoveEquipAction(itemAt); Placement.Swap(pinv, drag, itemAt); } Equip(p, drag); return true; } if (itemAt == null) { SlotState.Internal = true; bool flag = pinv.MoveItemToThis(from, drag, drag.m_stack, pos.x, pos.y); SlotState.Internal = false; if (!flag) { return false; } Equip(p, pinv.GetItemAt(pos.x, pos.y)); return true; } return CrossSwap(p, pinv, from, itemAt, drag, pos, drag.m_gridPos); } private static bool OutOfSlot(Player p, Inventory pinv, int v, Inventory to, ItemData drag, Vector2i pos) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0010: 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_0087: 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_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) SlotDefinition slotDefinition = SlotLayout.SlotAt(drag.m_gridPos, v); ItemData itemAt = to.GetItemAt(pos.x, pos.y); if (itemAt != null && (slotDefinition == null || !slotDefinition.Accepts(itemAt))) { SlotsPlugin.Message(p, "$vsm_slots_swap_blocked", itemAt.m_shared.m_name, (slotDefinition != null) ? slotDefinition.NameToken : "?"); return false; } if (to == pinv) { if (pos.y >= v || pos.x < 0 || pos.x >= pinv.m_width) { return false; } if (itemAt == null) { ((Humanoid)p).RemoveEquipAction(drag); ((Humanoid)p).UnequipItem(drag, false); Placement.Move(pinv, drag, pos); } else { ((Humanoid)p).RemoveEquipAction(drag); ((Humanoid)p).RemoveEquipAction(itemAt); Placement.Swap(pinv, drag, itemAt); Equip(p, itemAt); } return true; } if (itemAt == null) { bool equipped = drag.m_equipped; ((Humanoid)p).RemoveEquipAction(drag); ((Humanoid)p).UnequipItem(drag, false); if (to.MoveItemToThis(pinv, drag, drag.m_stack, pos.x, pos.y)) { return true; } if (equipped) { ((Humanoid)p).EquipItem(drag, false); } return false; } return CrossSwap(p, pinv, to, drag, itemAt, drag.m_gridPos, pos); } private static bool CrossSwap(Player p, Inventory pinv, Inventory chest, ItemData leaving, ItemData entering, Vector2i slotPos, Vector2i chestPos) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) bool equipped = leaving.m_equipped; ((Humanoid)p).RemoveEquipAction(leaving); ((Humanoid)p).UnequipItem(leaving, false); if (!chest.RemoveItem(entering)) { Restore(p, leaving, equipped); return false; } if (!chest.MoveItemToThis(pinv, leaving, leaving.m_stack, chestPos.x, chestPos.y)) { PutBack(p, chest, entering, chestPos); Restore(p, leaving, equipped); return false; } SlotState.Internal = true; bool flag = pinv.AddItem(entering, entering.m_stack, slotPos.x, slotPos.y, false); SlotState.Internal = false; if (!flag) { SlotsPlugin.Log.LogWarning((object)("vsm.slots: no se pudo poner " + entering.m_shared.m_name + " en la ranura; se devuelve.")); PutBack(p, chest, entering, new Vector2i(-1, -1)); return true; } Equip(p, pinv.GetItemAt(slotPos.x, slotPos.y)); return true; } private static void Restore(Player p, ItemData item, bool wasEquipped) { if (wasEquipped && ((Humanoid)p).m_inventory.ContainsItem(item)) { ((Humanoid)p).EquipItem(item, false); } } private static void PutBack(Player p, Inventory chest, ItemData item, Vector2i cell) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //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) //IL_00ad: 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_00bd: Unknown result type (might be due to invalid IL or missing references) if (item.m_stack > 0 && (cell.x < 0 || !chest.AddItem(item, item.m_stack, cell.x, cell.y, false)) && !chest.AddItem(item) && !((Humanoid)p).m_inventory.AddItem(item)) { SlotsPlugin.Log.LogWarning((object)("vsm.slots: " + item.m_shared.m_name + " no cabía en ningún sitio; se deja en el suelo.")); ItemDrop.DropItem(item, item.m_stack, ((Component)p).transform.position + ((Component)p).transform.forward + Vector3.up, ((Component)p).transform.rotation); } } internal static void Equip(Player p, ItemData item) { if (item != null && !((Humanoid)p).IsItemEquiped(item)) { if (item.m_shared.m_equipDuration <= 0f) { ((Humanoid)p).EquipItem(item, true); } else if (!p.IsEquipActionQueued(item)) { p.QueueEquipAction(item); } } } } [HarmonyPatch(typeof(TombStone), "EasyFitInInventory")] internal static class GraveEasyFit { [HarmonyPostfix] private static void Postfix(TombStone __instance, Player player, ref bool __result) { //IL_008e: Unknown result type (might be due to invalid IL or missing references) if (__result || (Object)(object)player == (Object)null || !SlotState.IsLocal((Humanoid)(object)player) || (Object)(object)__instance.m_container == (Object)null || !SlotState.HiddenRowActive(((Humanoid)player).m_inventory, out var visibleRows)) { return; } Inventory inventory = ((Humanoid)player).m_inventory; Inventory inventory2 = __instance.m_container.GetInventory(); string text = player.GetPlayerID().ToString(); int num = 0; int num2 = 0; int num3 = 0; foreach (ItemData allItem in inventory2.GetAllItems()) { SlotDefinition slotDefinition = SlotLayout.SlotAt(allItem.m_gridPos, visibleRows); if (slotDefinition != null && slotDefinition.Accepts(allItem) && inventory.GetItemAt(allItem.m_gridPos.x, allItem.m_gridPos.y) == null && allItem.m_customData != null && allItem.m_customData.TryGetValue("vsm.slots.grave", out var value) && value == text) { num++; continue; } num2++; if (inventory.FindFreeStackSpace(allItem.m_shared.m_name, (float)allItem.m_worldLevel) >= allItem.m_stack) { num3++; } } if (num != 0) { int num4 = inventory.GetEmptySlots() - num2; if (num4 >= 0 || num4 + num3 >= 0) { __result = inventory.GetTotalWeight() + inventory2.GetTotalWeight() <= player.GetMaxCarryWeight(); } } } } internal static class Placement { public static void EnsureFullHeight(Player p) { if (!((Object)(object)p == (Object)null) && ((Humanoid)p).m_inventory != null) { int num = SlotLayout.FullHeight(SlotState.VisibleRows(p)); if (((Humanoid)p).m_inventory.m_height != num) { ((Humanoid)p).m_inventory.m_height = num; ((Humanoid)p).m_inventory.Changed(false, false); } } } public static int Rebase(Player p, int oldRows, int newRows) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) Inventory inventory = ((Humanoid)p).m_inventory; List<ItemData> inventory2 = inventory.m_inventory; List<RebaseEntry> list = new List<RebaseEntry>(inventory2.Count); for (int i = 0; i < 2; i++) { for (int j = 0; j < inventory2.Count; j++) { ItemData val = inventory2[j]; if (val.m_equipped == (i == 0)) { Vector2i gridPos = val.m_gridPos; SlotDefinition slotDefinition = SlotLayout.ForType(val.m_shared.m_itemType); bool flag = slotDefinition != null && SlotLayout.IsEnabled(slotDefinition) && slotDefinition.Accepts(val) && (val.m_equipped || (gridPos.y == oldRows && gridPos.x == slotDefinition.Order)); list.Add(new RebaseEntry { Id = j, X = gridPos.x, Y = gridPos.y, SlotOrder = (flag ? slotDefinition.Order : (-1)), WasHidden = (gridPos.y == oldRows) }); } } } List<RebaseMove> list2 = RebasePlanner.Plan(list, inventory.m_width, newRows); if (list2.Count == 0) { return 0; } int num = 0; foreach (RebaseMove item in list2) { ItemData val2 = inventory2[item.Id]; if (item.Drop) { val2.m_gridPos = new Vector2i(val2.m_gridPos.x, SlotLayout.FullHeight(newRows) + 1); num++; SlotsPlugin.Log.LogWarning((object)("vsm.slots: sin sitio para " + val2.m_shared.m_name + " x" + val2.m_stack + " al pasar de " + oldRows + " a " + newRows + " filas; cae al suelo.")); } else { val2.m_gridPos = new Vector2i(item.X, item.Y); } } inventory.Changed(false, false); return num; } public static Vector2i FreeVisibleCell(Inventory inv, int visibleRows, ItemData forItem) { //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) if (forItem != null && inv.TopFirst(forItem)) { for (int i = 0; i < visibleRows; i++) { for (int j = 0; j < inv.m_width; j++) { if (inv.GetItemAt(j, i) == null) { return new Vector2i(j, i); } } } } else { for (int num = visibleRows - 1; num >= 0; num--) { for (int k = 0; k < inv.m_width; k++) { if (inv.GetItemAt(k, num) == null) { return new Vector2i(k, num); } } } } return new Vector2i(-1, -1); } public static void Move(Inventory inv, ItemData item, Vector2i to) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) item.m_gridPos = to; inv.Changed(false, false); } public static void Swap(Inventory inv, ItemData a, ItemData b) { //IL_0002: 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: 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) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) Vector2i gridPos = a.m_gridPos; a.m_gridPos = b.m_gridPos; b.m_gridPos = gridPos; inv.Changed(false, false); } } internal static class Reconciler { private static readonly Dictionary<ItemData, float> s_cooldown = new Dictionary<ItemData, float>(); private static float s_nextStuckWarning; public static void Tick() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || SlotState.Suspended || ((Character)localPlayer).IsDead() || localPlayer.m_isLoading || !SlotsPlugin.IsConfigReady) { return; } Inventory inventory = ((Humanoid)localPlayer).m_inventory; if (!SlotState.HiddenRowActive(inventory, out var visibleRows)) { Placement.EnsureFullHeight(localPlayer); if (!SlotState.HiddenRowActive(inventory, out visibleRows)) { return; } } for (int i = 0; i < 3; i++) { if (!Pass(localPlayer, inventory, visibleRows)) { break; } } } public static void Forget() { s_cooldown.Clear(); } private static bool Pass(Player p, Inventory inv, int v) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: 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) bool flag = false; SlotDefinition[] all = SlotLayout.All; foreach (SlotDefinition slotDefinition in all) { Vector2i val = SlotLayout.CellOf(slotDefinition, v); ItemData itemAt = inv.GetItemAt(val.x, val.y); if (!SlotLayout.IsEnabled(slotDefinition)) { flag |= itemAt != null && Evict(p, inv, v, itemAt, reequipIfFull: false); continue; } ItemData val2 = slotDefinition.Equipped((Humanoid)(object)p); if (itemAt != null && val2 == itemAt) { ClearSeal(itemAt); } else { if (itemAt != null && p.IsEquipActionQueued(itemAt)) { continue; } if (val2 != null && inv.ContainsItem(val2) && val2.m_gridPos.y < v) { if (itemAt == null) { Placement.Move(inv, val2, val); } else { Placement.Swap(inv, val2, itemAt); } flag = true; } else { if (itemAt == null || OnCooldown(itemAt)) { continue; } if (!slotDefinition.Accepts(itemAt)) { flag |= Evict(p, inv, v, itemAt, reequipIfFull: false); } else if (IsOwnGraveSeal(p, itemAt)) { if (((Humanoid)p).EquipItem(itemAt, false)) { ClearSeal(itemAt); flag = true; } else if (NeverEquipable(itemAt)) { ClearSeal(itemAt); flag = true; } else { Cooldown(itemAt); } } else { flag |= Evict(p, inv, v, itemAt, reequipIfFull: true); } } } } for (int j = 0; j < inv.m_width; j++) { if (SlotLayout.IsReservedCell(new Vector2i(j, v), v)) { ItemData itemAt2 = inv.GetItemAt(j, v); if (itemAt2 != null && !OnCooldown(itemAt2)) { flag |= Evict(p, inv, v, itemAt2, reequipIfFull: false); } } } return flag; } private static bool Evict(Player p, Inventory inv, int v, ItemData item, bool reequipIfFull) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) Vector2i val = Placement.FreeVisibleCell(inv, v, item); if (val.x >= 0) { Placement.Move(inv, item, val); return true; } Cooldown(item); if (reequipIfFull && !item.m_equipped && ((Humanoid)p).EquipItem(item, false)) { SlotsPlugin.Message(p, "$vsm_slots_inventory_full"); return true; } if (Time.unscaledTime >= s_nextStuckWarning) { s_nextStuckWarning = Time.unscaledTime + 30f; SlotsPlugin.Message(p, "$vsm_slots_stuck", item.m_shared.m_name); } return false; } private static bool NeverEquipable(ItemData item) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Invalid comparison between Unknown and I4 //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Invalid comparison between Unknown and I4 SharedData shared = item.m_shared; if (shared.m_useDurability && item.m_durability <= 0f) { return true; } if (!string.IsNullOrEmpty(shared.m_dlc) && ((Object)(object)DLCMan.instance == (Object)null || !DLCMan.instance.IsDLCInstalled(shared.m_dlc))) { return true; } return Game.m_worldLevel > 0 && item.m_worldLevel < Game.m_worldLevel && ((int)shared.m_itemType == 18 || (int)shared.m_itemType == 24); } private static bool IsOwnGraveSeal(Player p, ItemData item) { string value; return item.m_customData != null && item.m_customData.TryGetValue("vsm.slots.grave", out value) && value == p.GetPlayerID().ToString(); } private static void ClearSeal(ItemData item) { if (item.m_customData != null) { item.m_customData.Remove("vsm.slots.grave"); } } private static bool OnCooldown(ItemData item) { if (!s_cooldown.TryGetValue(item, out var value)) { return false; } if (Time.unscaledTime < value) { return true; } s_cooldown.Remove(item); return false; } private static void Cooldown(ItemData item) { if (s_cooldown.Count > 64) { s_cooldown.Clear(); } s_cooldown[item] = Time.unscaledTime + 3f; } } public enum RowsCapMode { Legal, Fijo, Libre } internal static class RowCap { public const string TrimmedRpc = "VSM_Slots_RowsTrimmed"; public static int MaxRows(Player p) { if (!SlotsPlugin.IsConfigReady || (Object)(object)p == (Object)null) { return 9; } switch (SlotsPlugin.RowsCap.Value) { case RowsCapMode.Legal: { int num = 0; string[] array = (SlotsPlugin.RowsLegalKeys.Value ?? string.Empty).Split(new char[1] { ',' }); foreach (string text in array) { string text2 = text.Trim(); if (text2.Length > 0 && ((Humanoid)p).HaveUniqueKey(text2)) { num++; } } return SlotMath.LegalRows(SlotsPlugin.RowsBase.Value, num); } case RowsCapMode.Fijo: return SlotLayout.ClampRows(SlotsPlugin.RowsFixedMax.Value); default: return 9; } } public static void Enforce(Player p, string when) { if (!((Object)(object)p == (Object)null) && SlotState.IsLocal((Humanoid)(object)p) && SlotsPlugin.IsConfigReady) { int num = MaxRows(p); int num2 = SlotState.VisibleRows(p); if (num2 > num) { SlotsPlugin.Log.LogInfo((object)("vsm.slots: aplicando el tope de filas (" + when + ").")); OnTrimmed(p, num2, num); p.SetInventorySize(num); } } } public static void OnTrimmed(Player p, int requested, int cap) { SlotsPlugin.Log.LogWarning((object)("vsm.slots: " + p.GetPlayerName() + " pidió " + requested + " filas y el servidor permite " + cap + ": se recorta.")); try { if (ZRoutedRpc.instance != null && (Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer()) { ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), "VSM_Slots_RowsTrimmed", new object[3] { p.GetPlayerName(), requested, cap }); } } catch (Exception ex) { SlotsPlugin.Log.LogWarning((object)("vsm.slots: no se pudo avisar al servidor del recorte: " + ex.Message)); } SlotsPlugin.Message(p, "$vsm_slots_rows_trimmed", requested, cap); } public static void RPC_RowsTrimmed(long sender, string playerName, int from, int to) { if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer()) { ZNetPeer peer = ZNet.instance.GetPeer(sender); string text = ((peer != null && peer.m_socket != null) ? peer.m_socket.GetHostName() : "?"); SlotsPlugin.Log.LogWarning((object)("vsm.slots: [inventario] " + playerName + " (" + text + ") tenía o pidió " + from + " filas; recortado a " + to + ".")); } } } internal static class SafetyPatches { [HarmonyPatch(typeof(Player), "SetInventorySize", new Type[] { typeof(int) })] internal static class SetInventorySizePatch { [HarmonyPrefix] [HarmonyPriority(800)] private static void Prefix(Player __instance, ref int rows) { if (SlotState.IsLocal((Humanoid)(object)__instance)) { int num = RowCap.MaxRows(__instance); if (rows > num) { RowCap.OnTrimmed(__instance, rows, num); rows = num; } SlotState.PendingOldRows = SlotState.VisibleRows(__instance); SlotState.PendingNewRows = SlotLayout.ClampRows(rows); } } [HarmonyFinalizer] private static void Finalizer(Player __instance) { if (SlotState.IsLocal((Humanoid)(object)__instance)) { SlotState.PendingOldRows = (SlotState.PendingNewRows = -1); SlotState.InvalidateRows(); Placement.EnsureFullHeight(__instance);
plugins/VSM.Stats/VSM.Stats.dll
Decompiled 3 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ConditionalConfigSync; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; using VSM.Core.Config; using VSM.Core.Harmony; using VSM.Core.Localization; using VSM.Core.Reflection; using VSM.Core.Runtime; using VSM.Core.Ui; using VSM.Stats.Deaths; using VSM.Stats.Obituaries; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: <4b063d6b-fe3c-473f-bfb8-23fcb4e3d6f4>IgnoresAccessChecksTo("assembly_guiutils")] [assembly: <4b063d6b-fe3c-473f-bfb8-23fcb4e3d6f4>IgnoresAccessChecksTo("assembly_utils")] [assembly: <4b063d6b-fe3c-473f-bfb8-23fcb4e3d6f4>IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("VSM.Stats")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("0.1.4.0")] [assembly: AssemblyInformationalVersion("0.1.4+ff27bc889ccf218c61c45d3417d48ab708a5ba8f")] [assembly: AssemblyProduct("VSM.Stats")] [assembly: AssemblyTitle("VSM.Stats")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.4.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace VSM.Stats { internal static class AliveTracker { public const string KeyAlive = "vsm.stats.alive"; public const string KeyBest = "vsm.stats.alivebest"; public const string KeySince = "vsm.stats.since"; public const string KeyNemesisSince = "vsm.stats.nemesis.since"; public static double Alive; public static double Best; public static bool Loaded; public static bool TrackedSinceCreation; public static void Load(Player player) { Alive = Read(player, "vsm.stats.alive"); Best = Read(player, "vsm.stats.alivebest"); TrackedSinceCreation = player.m_customData.ContainsKey("vsm.stats.since"); string value = DateTime.UtcNow.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture); if (!TrackedSinceCreation) { player.m_customData["vsm.stats.since"] = value; } if (!player.m_customData.ContainsKey("vsm.stats.nemesis.since")) { player.m_customData["vsm.stats.nemesis.since"] = value; } Loaded = true; } public static void Tick(Player player, float dt) { if (Loaded && !((Object)(object)player == (Object)null) && !(dt <= 0f) && !((Character)player).IsDead()) { Alive += dt; if (Alive > Best) { Best = Alive; } } } public static void OnDeath(Player player) { if (Alive > Best) { Best = Alive; } Alive = 0.0; Save(player); } public static void Save(Player player) { if (Loaded && !((Object)(object)player == (Object)null)) { player.m_customData["vsm.stats.alive"] = Alive.ToString("0", CultureInfo.InvariantCulture); player.m_customData["vsm.stats.alivebest"] = Best.ToString("0", CultureInfo.InvariantCulture); } } public static string SinceText(Player player) { string value; return ((Object)(object)player != (Object)null && player.m_customData.TryGetValue("vsm.stats.since", out value)) ? value : "?"; } public static string NemesisSinceText(Player player) { string value; return ((Object)(object)player != (Object)null && player.m_customData.TryGetValue("vsm.stats.nemesis.since", out value)) ? value : "?"; } public static void Reset() { Alive = 0.0; Best = 0.0; Loaded = false; } private static double Read(Player player, string key) { string value; double result; return (player.m_customData.TryGetValue(key, out value) && double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out result) && result >= 0.0) ? result : 0.0; } } public sealed class BestiaryRow { public string Key; public string Name; public float Kills; public int Deaths; } public static class Bestiary { public static List<BestiaryRow> Build(IDictionary<string, float> kills, IDictionary<string, int> deaths, Func<string, string> localize) { Dictionary<string, BestiaryRow> dictionary = new Dictionary<string, BestiaryRow>(StringComparer.Ordinal); if (kills != null) { foreach (KeyValuePair<string, float> kill in kills) { if (!string.IsNullOrEmpty(kill.Key) && kill.Value >= 0.5f) { Row(dictionary, kill.Key).Kills += kill.Value; } } } if (deaths != null) { foreach (KeyValuePair<string, int> death in deaths) { if (!string.IsNullOrEmpty(death.Key) && death.Value > 0) { Row(dictionary, death.Key).Deaths += death.Value; } } } foreach (BestiaryRow value in dictionary.Values) { value.Name = StatsReport.MobName(value.Key, localize); } return Sort(dictionary.Values).ToList(); } public static IEnumerable<BestiaryRow> Sort(IEnumerable<BestiaryRow> rows) { return (from r in rows orderby Math.Round(r.Kills) descending, r.Deaths descending select r).ThenBy<BestiaryRow, string>((BestiaryRow r) => r.Name ?? string.Empty, StringComparer.OrdinalIgnoreCase).ThenBy<BestiaryRow, string>((BestiaryRow r) => r.Key ?? string.Empty, StringComparer.Ordinal); } private static BestiaryRow Row(Dictionary<string, BestiaryRow> rows, string key) { if (!rows.TryGetValue(key, out var value)) { value = (rows[key] = new BestiaryRow { Key = key }); } return value; } } internal static class StatsCommands { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__0_0; public static ConsoleEvent <>9__0_1; public static ConsoleEvent <>9__0_2; public static ConsoleOptionsFetcher <>9__0_3; internal void <Register>b__0_0(ConsoleEventArgs args) { args.Context.AddString("vsm.stats 0.1.4 | esquelas=" + StatsPlugin.ObituariesEnabled.Value + " | canal=" + StatsPlugin.ObituaryChannel.Value.ToString() + " | ventana DoT=" + StatsPlugin.DotWindowSeconds.Value + " s | config lista=" + StatsPlugin.IsConfigReady); if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer()) { args.Context.AddString("servidor: " + ObituaryServer.TemplateCount + " plantillas en " + ObituaryServer.PathInUse); } } internal void <Register>b__0_1(ConsoleEventArgs args) { string text = ObituaryServer.Reload(); StatsPlugin.Log.LogInfo((object)text); args.Context.AddString(text); } internal void <Register>b__0_2(ConsoleEventArgs args) { string text = ((args.Length > 1) ? args[1].Trim().ToLowerInvariant() : CauseMap.KnownCauses[new Random().Next(CauseMap.KnownCauses.Length)]); if (!CauseMap.IsKnown(text)) { args.Context.AddString("Causa desconocida. Causas: " + string.Join(", ", CauseMap.KnownCauses)); return; } string text2 = ObituaryServer.Preview(text, "Vikingo de prueba"); StatsPlugin.Log.LogInfo((object)("vsm.stats: esquela de prueba [" + text + "] " + text2)); ObituaryServer.BroadcastPreview("[prueba] " + text2); args.Context.AddString("[" + text + "] " + text2); } internal List<string> <Register>b__0_3() { return CauseMap.KnownCauses.ToList(); } } public static void Register() { //IL_0034: 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_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Expected O, but got Unknown object obj = <>c.<>9__0_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { args.Context.AddString("vsm.stats 0.1.4 | esquelas=" + StatsPlugin.ObituariesEnabled.Value + " | canal=" + StatsPlugin.ObituaryChannel.Value.ToString() + " | ventana DoT=" + StatsPlugin.DotWindowSeconds.Value + " s | config lista=" + StatsPlugin.IsConfigReady); if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer()) { args.Context.AddString("servidor: " + ObituaryServer.TemplateCount + " plantillas en " + ObituaryServer.PathInUse); } }; <>c.<>9__0_0 = val; obj = (object)val; } new ConsoleCommand("vsm_stats", "Estado de vsm.stats (esquelas y ventana de estadísticas)", (ConsoleEvent)obj, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj2 = <>c.<>9__0_1; if (obj2 == null) { ConsoleEvent val2 = delegate(ConsoleEventArgs args) { string text = ObituaryServer.Reload(); StatsPlugin.Log.LogInfo((object)text); args.Context.AddString(text); }; <>c.<>9__0_1 = val2; obj2 = (object)val2; } new ConsoleCommand("vsm_stats_reload", "Recarga el archivo de esquelas del servidor (admin)", (ConsoleEvent)obj2, false, false, true, false, false, false, (ConsoleOptionsFetcher)null, false, true, false); object obj3 = <>c.<>9__0_2; if (obj3 == null) { ConsoleEvent val3 = delegate(ConsoleEventArgs args) { string text = ((args.Length > 1) ? args[1].Trim().ToLowerInvariant() : CauseMap.KnownCauses[new Random().Next(CauseMap.KnownCauses.Length)]); if (!CauseMap.IsKnown(text)) { args.Context.AddString("Causa desconocida. Causas: " + string.Join(", ", CauseMap.KnownCauses)); } else { string text2 = ObituaryServer.Preview(text, "Vikingo de prueba"); StatsPlugin.Log.LogInfo((object)("vsm.stats: esquela de prueba [" + text + "] " + text2)); ObituaryServer.BroadcastPreview("[prueba] " + text2); args.Context.AddString("[" + text + "] " + text2); } }; <>c.<>9__0_2 = val3; obj3 = (object)val3; } object obj4 = <>c.<>9__0_3; if (obj4 == null) { ConsoleOptionsFetcher val4 = () => CauseMap.KnownCauses.ToList(); <>c.<>9__0_3 = val4; obj4 = (object)val4; } new ConsoleCommand("vsm_stats_obituary", "Anuncia a todos una esquela de PRUEBA: vsm_stats_obituary [causa] (admin)", (ConsoleEvent)obj3, false, false, true, false, false, false, (ConsoleOptionsFetcher)obj4, false, true, false); } } internal static class StatsNet { public const string Died = "VSM_Stats_Died"; public const string Obituary = "VSM_Stats_Obituary"; private static ZRoutedRpc s_registeredFor; public static long ServerId => (ZRoutedRpc.instance != null) ? ZRoutedRpc.instance.GetServerPeerID() : 0; public static void Register() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null && instance != s_registeredFor) { instance.Register<ZPackage>("VSM_Stats_Died", (Action<long, ZPackage>)ObituaryServer.RPC_Died); instance.Register<string>("VSM_Stats_Obituary", (Action<long, string>)ObituaryClient.RPC_Obituary); s_registeredFor = instance; } } public static void SendDeath(DeathReport report) { ZRoutedRpc instance = ZRoutedRpc.instance; long serverId = ServerId; if (instance != null && serverId != 0L && report != null) { instance.InvokeRoutedRPC(serverId, "VSM_Stats_Died", new object[1] { Write(report) }); } } public static void Broadcast(string text) { if (ZRoutedRpc.instance != null && !string.IsNullOrEmpty(text)) { ZRoutedRpc.instance.InvokeRoutedRPC(GameConstants.RoutedRpcEverybody, "VSM_Stats_Obituary", new object[1] { text }); } } public static ZPackage Write(DeathReport report) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(1); val.Write(report.HitType ?? string.Empty); val.Write(report.Attacker ?? string.Empty); val.Write(report.Level); val.Write((int)report.Flags); val.Write(report.KillerName ?? string.Empty); val.Write(report.TreeVariant ?? string.Empty); return val; } public static DeathReport Read(ZPackage pkg) { if (pkg == null) { return null; } try { int num = pkg.ReadInt(); if (num < 1) { return null; } return new DeathReport { HitType = pkg.ReadString(), Attacker = pkg.ReadString(), Level = pkg.ReadInt(), Flags = (DeathFlags)pkg.ReadInt(), KillerName = pkg.ReadString(), TreeVariant = pkg.ReadString() }; } catch (Exception) { return null; } } } internal static class StatsPatches { [HarmonyPatch(typeof(Game), "Start")] private static class GameStartPatch { [HarmonyPostfix] private static void Postfix() { StatsNet.Register(); if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer()) { ObituaryServer.EnsureLoaded(); } } } [HarmonyPatch(typeof(Game), "OnDestroy")] private static class GameDestroyPatch { [HarmonyPrefix] private static void Prefix() { StatsWindow.Destroy(); AliveTracker.Reset(); DeathCapture.Reset(); } } [HarmonyPatch(typeof(ZNet), "OnDestroy")] private static class ZNetDestroyPatch { [HarmonyPrefix] private static void Prefix() { ObituaryServer.ResetSession(); } } [HarmonyPatch(typeof(Player), "OnSpawned", new Type[] { typeof(bool) })] private static class OnSpawnedPatch { [HarmonyPostfix] private static void Postfix(Player __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer) { AliveTracker.Load(__instance); DeathCapture.OnSpawned(); } } } [HarmonyPatch(typeof(Player), "OnDeath")] private static class OnDeathPatch { [HarmonyPrefix] private static void Prefix(Player __instance) { try { DeathCapture.OnDeathPrefix(__instance); } catch (Exception ex) { StatsPlugin.Log.LogError((object)("vsm.stats: error al registrar la muerte: " + ex)); } } [HarmonyPostfix] private static void Postfix(Player __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer) { AliveTracker.OnDeath(__instance); } } } [HarmonyPatch(typeof(Player), "Save", new Type[] { typeof(ZPackage) })] private static class SavePatch { [HarmonyPrefix] private static void Prefix(Player __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer) { AliveTracker.Save(__instance); } } } [HarmonyPatch(typeof(Character), "RPC_Damage", new Type[] { typeof(long), typeof(HitData) })] private static class RpcDamagePatch { [HarmonyPrefix] private static void Prefix(Character __instance, HitData hit, out DotTracker.Pending __state) { __state = null; try { DotTracker.Prefix(__instance, hit, out __state); } catch (Exception) { __state = null; } } [HarmonyPostfix] private static void Postfix(Character __instance, HitData hit, DotTracker.Pending __state) { if (__state == null) { return; } try { DotTracker.Postfix(__instance, hit, __state); } catch (Exception) { } } } [HarmonyPatch(typeof(Terminal), "InitTerminal")] private static class TerminalInitPatch { private static bool s_registered; [HarmonyPostfix] private static void Postfix() { if (!s_registered) { s_registered = true; StatsCommands.Register(); } } } [HarmonyPatch(typeof(GameCamera), "UpdateMouseCapture")] private static class MouseCapturePatch { [HarmonyPostfix] private static void Postfix() { if (StatsWindow.Visible) { ZCursor.LockState = (CursorLockMode)0; ZCursor.Show(); } } } [HarmonyPatch(typeof(GameCamera), "UpdateCamera", new Type[] { typeof(float) })] private static class CameraZoomPatch { [HarmonyPrefix] private static void Prefix(GameCamera __instance, out float __state) { __state = -1f; if (StatsWindow.Visible && (Object)(object)__instance != (Object)null) { __state = __instance.m_zoomSens; __instance.m_zoomSens = 0f; } } [HarmonyFinalizer] private static void Finalizer(GameCamera __instance, float __state) { if (__state >= 0f && (Object)(object)__instance != (Object)null) { __instance.m_zoomSens = __state; } } } [HarmonyPatch(typeof(Player), "TakeInput")] private static class TakeInputPatch { [HarmonyPostfix] private static void Postfix(Player __instance, ref bool __result) { if (StatsWindow.Visible && (Object)(object)__instance == (Object)(object)Player.m_localPlayer) { __result = false; } } } [HarmonyPatch(typeof(Player), "SetMouseLook", new Type[] { typeof(Vector2) })] private static class MouseLookPatch { [HarmonyPrefix] private static bool Prefix(Player __instance) { return !StatsWindow.Visible || !((Object)(object)__instance == (Object)(object)Player.m_localPlayer); } } [HarmonyPatch(typeof(Menu), "Update")] private static class MenuUpdatePatch { [HarmonyPrefix] private static bool Prefix() { return !StatsWindow.BlocksMenu; } } } [BepInPlugin("vsm.stats", "MEL Stats", "0.1.4")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class StatsPlugin : BaseUnityPlugin { internal static ManualLogSource Log; private static ConfigSync s_sync; private Harmony _harmony; public static ConfigEntry<KeyboardShortcut> ToggleKey; public static ConfigEntry<int> TopMobs; public static ConfigEntry<float> WindowScale; public static ConfigEntry<bool> ObituariesEnabled; public static ConfigEntry<ObituaryChannelMode> ObituaryChannel; public static ConfigEntry<float> DotWindowSeconds; public static ConfigEntry<bool> ServerLock; public static ConfigEntry<string> TemplatesFile; public static ConfigEntry<float> ReportCooldownSeconds; internal static readonly Color AccentColor = new Color(1f, 0.79f, 0.36f); private static readonly Dictionary<string, string> s_spanish = new Dictionary<string, string> { { "vsm_stats_title", "Estadísticas de {0}" }, { "vsm_stats_tab_summary", "Resumen" }, { "vsm_stats_tab_bestiary", "Bestiario" }, { "vsm_stats_tab_deaths", "Muertes" }, { "vsm_stats_obituary_sender", "Valhalla" } }; public static bool IsConfigReady => s_sync != null && (((ConditionalConfigSync)s_sync).IsSourceOfTruth || ((ConditionalConfigSync)s_sync).InitialSyncDone); private void Awake() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0044: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Expected O, but got Unknown //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Expected O, but got Unknown //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Expected O, but got Unknown //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Expected O, but got Unknown //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Expected O, but got Unknown //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Expected O, but got Unknown //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; s_sync = new ConfigSync("vsm.stats") { DisplayName = "MEL Stats", CurrentVersion = "0.1.4", MinimumRequiredVersion = "0.1.4", ModRequired = true }; ToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("1. Ventana", "ToggleKey", new KeyboardShortcut((KeyCode)288, Array.Empty<KeyCode>()), "Tecla para abrir/cerrar la ventana de estadísticas."); TopMobs = ((BaseUnityPlugin)this).Config.Bind<int>("1. Ventana", "TopMobs", 10, new ConfigDescription("Cuántos enemigos mostrar en 'Más matados' (máximo 14: los que caben en la ventana).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 14), Array.Empty<object>())); WindowScale = ((BaseUnityPlugin)this).Config.Bind<float>("1. Ventana", "WindowScale", 1f, new ConfigDescription("Escala de la ventana.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 2f), Array.Empty<object>())); ObituariesEnabled = Synced<bool>(((BaseUnityPlugin)this).Config.Bind<bool>("2. Esquelas (servidor)", "ObituariesEnabled", true, new ConfigDescription("Anunciar a todos, con un mensaje gracioso, cómo murió cada jugador.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 100 } }))); ObituaryChannel = Synced<ObituaryChannelMode>(((BaseUnityPlugin)this).Config.Bind<ObituaryChannelMode>("2. Esquelas (servidor)", "ObituaryChannel", ObituaryChannelMode.Chat, new ConfigDescription("Dónde se ven las esquelas: Chat (con remitente 'Valhalla'), TopLeft (arriba a la izquierda, queda en el registro de mensajes) o Both. Nunca en el centro: pisaría el '¡HAS MUERTO!'.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 99 } }))); DotWindowSeconds = Synced<float>(((BaseUnityPlugin)this).Config.Bind<float>("2. Esquelas (servidor)", "DotWindowSeconds", 30f, new ConfigDescription("Si mueres quemado o envenenado, se culpa a la criatura que te prendió fuego o te envenenó en los últimos N segundos; si no, cuenta como el entorno (lava, fogata...).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 120f), new object[1] { new ConfigurationManagerAttributes { Order = 98 } }))); ServerLock = ((BaseUnityPlugin)this).Config.Bind<bool>("2. Esquelas (servidor)", "ServerLock", true, "Bloquea la configuración sincronizada: solo los administradores del servidor pueden cambiarla."); ((ConditionalConfigSync)s_sync).AddLockingConfigEntry<bool>(ServerLock); TemplatesFile = ((BaseUnityPlugin)this).Config.Bind<string>("3. Servidor (no se sincroniza)", "TemplatesFile", "vsm.stats.obituaries.txt", "Archivo de plantillas de las esquelas (relativo a BepInEx/config o ruta absoluta). Si no existe se crea con los textos por defecto; se recarga solo al guardarlo o con 'vsm_stats_reload'."); ReportCooldownSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("3. Servidor (no se sincroniza)", "ReportCooldownSeconds", 10f, new ConfigDescription("Mínimo de segundos entre dos esquelas del mismo jugador (anti-spam; el respawn tarda 10 s).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 120f), Array.Empty<object>())); Log.LogInfo((object)("vsm.stats 0.1.4 | Valheim " + GameConstants.GameVersionString + " | headless=" + Headless.IsHeadless)); if (!Headless.IsHeadless) { VsmLocalization.Register(Log, Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), s_spanish); } _harmony = new Harmony("vsm.stats"); PatchUtil.PatchAllSafely(Log, _harmony, Assembly.GetExecutingAssembly()); if (PatchUtil.IsDegraded) { Log.LogError((object)"vsm.stats: hay parches sin aplicar (ver arriba)."); } if (Headless.IsHeadless) { ObituaryServer.EnsureLoaded(); } } private static ConfigEntry<T> Synced<T>(ConfigEntry<T> entry) { ((ConditionalConfigSync)s_sync).AddConfigEntry<T>(entry, (ConfigSyncMode)0); return entry; } private void Update() { //IL_0049: Unknown result type (might be due to invalid IL or missing references) ObituaryServer.Tick(); if (_harmony != null && !Headless.IsHeadless) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { AliveTracker.Tick(localPlayer, Time.deltaTime); DotTracker.PruneExpired((Character)(object)localPlayer); } if (Keys.Pressed(ToggleKey.Value) && (Object)(object)localPlayer != (Object)null && !Console.IsVisible() && (!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus()) && !TextInput.IsVisible()) { StatsWindow.Toggle(); } StatsWindow.Tick(); } } private void OnDestroy() { StatsWindow.Destroy(); ObituaryServer.Shutdown(); if (_harmony != null) { _harmony.UnpatchSelf(); } } internal static StatsSnapshot TakeSnapshot() { //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; PlayerProfile val = (((Object)(object)Game.instance != (Object)null) ? Game.instance.GetPlayerProfile() : null); if ((Object)(object)localPlayer == (Object)null || val == null || val.m_playerStats == null || val.m_playerStats[0] == null) { return null; } PlayerStats val2 = val.m_playerStats[0]; Dictionary<string, float> byName = new Dictionary<string, float>(StringComparer.Ordinal); foreach (KeyValuePair<PlayerStatType, float> stat2 in val2.m_stats) { byName[((object)stat2.Key/*cast due to .constrained prefix*/).ToString()] = stat2.Value; } double num = Math.Max(0.0, (DateTime.Now - val.m_lastSaveLoad).TotalSeconds); string text = (((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetWorldName() : "?"); double num2 = 0.0; double num3 = 0.0; foreach (KeyValuePair<string, float> knownWorld in val2.m_knownWorlds) { num3 += (double)knownWorld.Value; if (string.Equals(knownWorld.Key, text, StringComparison.Ordinal)) { num2 = knownWorld.Value; } } float value; Func<string, float> stat = (string name) => byName.TryGetValue(name, out value) ? value : 0f; StatsSnapshot statsSnapshot = new StatsSnapshot { Character = val.GetName(), World = text, Stat = DeathReclass.Apply(stat, DeathCapture.ReadMoves(localPlayer)), EnemyKills = val2.m_enemyStats[0], KillsUnarmed = Sum(val2.m_enemyStats[1]), KillsMagic = Sum(val2.m_enemyStats[2]), KillsRanged = Sum(val2.m_enemyStats[3]), KillsMelee = Sum(val2.m_enemyStats[4]), SecondsWorld = num2 + num, SecondsTotal = num3 + num, AliveSeconds = AliveTracker.Alive, BestAliveSeconds = AliveTracker.Best, Nemesis = DeathCapture.Read(localPlayer, players: false), PvpNemesis = DeathCapture.Read(localPlayer, players: true), Localize = (string token) => (Localization.instance != null) ? Localization.instance.Localize(token) : token }; if (statsSnapshot.EnemyKills == null) { statsSnapshot.EnemyKills = new Dictionary<string, float>(); } return statsSnapshot; } private static float Sum(Dictionary<string, float> d) { float num = 0f; if (d != null) { foreach (float value in d.Values) { num += value; } } return num; } } public sealed class StatsSnapshot { public string Character = "?"; public string World = "?"; public Func<string, float> Stat = (string _) => 0f; public IDictionary<string, float> EnemyKills = new Dictionary<string, float>(); public float KillsUnarmed; public float KillsMagic; public float KillsRanged; public float KillsMelee; public double SecondsWorld; public double SecondsTotal; public double AliveSeconds; public double BestAliveSeconds; public bool AliveTrackedSinceInstall = true; public IDictionary<string, int> Nemesis = new Dictionary<string, int>(); public IDictionary<string, int> PvpNemesis = new Dictionary<string, int>(); public Func<string, string> Localize = (string s) => s; } public sealed class Section { public string Title; public int Column; public readonly List<KeyValuePair<string, string>> Rows = new List<KeyValuePair<string, string>>(); public Section Add(string label, string value) { Rows.Add(new KeyValuePair<string, string>(label, value)); return this; } } public static class StatsReport { private static readonly CultureInfo Es = CultureInfo.GetCultureInfo("es-ES"); public static readonly KeyValuePair<string, string>[] DeathCauses = new KeyValuePair<string, string>[25] { Pair("DeathByEnemyHit", "Enemigos"), Pair("DeathByPlayerHit", "Otros jugadores"), Pair("DeathByFall", "Caídas"), Pair("DeathByDrowning", "Ahogado"), Pair("DeathByBurning", "Quemado"), Pair("DeathByFreezing", "Congelado"), Pair("DeathByPoisoned", "Envenenado"), Pair("DeathBySmoke", "Humo"), Pair("DeathByWater", "Agua"), Pair("DeathByEdgeOfWorld", "Fin del mundo"), Pair("DeathByImpact", "Impacto"), Pair("DeathByCart", "Carro"), Pair("DeathByTree", "Árbol"), Pair("DeathBySelf", "Uno mismo"), Pair("DeathByStructural", "Estructuras"), Pair("DeathByTurret", "Torreta"), Pair("DeathByBoat", "Barco"), Pair("DeathByStalagtite", "Estalactita"), Pair("DeathByCatapult", "Catapulta"), Pair("DeathByCinderFire", "Fuego de brasas"), Pair("DeathByAshlandsOcean", "Mar de las Cenizas"), Pair("DeathByAshlandsLava", "Lava"), Pair("DeathByIncinerator", "Incinerador"), Pair("DeathByDrawBridge", "Puente levadizo"), Pair("DeathByUndefined", "Otras causas") }; private static readonly HashSet<string> s_notEnvironment = new HashSet<string>(StringComparer.Ordinal) { "DeathByEnemyHit", "DeathByPlayerHit", "DeathBySelf", "DeathByUndefined" }; public const int MaxDeathCauses = 6; public const int MaxDeathCausesTab = 18; public const string KillsLabel = "Matados (participaste)"; public const int TopNemesis = 10; public const int TopPvp = 6; private static KeyValuePair<string, string> Pair(string a, string b) { return new KeyValuePair<string, string>(a, b); } public static List<Section> Build(StatsSnapshot s, int topMobs) { List<Section> list = new List<Section>(); Func<string, float> stat = s.Stat; Section section = new Section { Title = "General", Column = 0 }; section.Add("Tiempo jugado en este mundo", Duration(s.SecondsWorld)); section.Add("Tiempo jugado en total", Duration(s.SecondsTotal)); section.Add("Tiempo vivo ahora", Duration(s.AliveSeconds)); section.Add("Racha más larga con vida", Duration(Math.Max(s.BestAliveSeconds, s.AliveSeconds))); AddDaysSurvived(section, stat); section.Add("Muertes", Count(stat("Deaths"))); section.Add("Jefes derrotados", Count(stat("BossKills"))); section.Add("Veces que dormiste", Count(stat("Sleep"))); list.Add(section); Section section2 = new Section { Title = "Viajes", Column = 0 }; section2.Add("Distancia total", Km(stat("DistanceTraveled"))); section2.Add("Caminando", Km(stat("DistanceWalk"))); section2.Add("Corriendo", Km(stat("DistanceRun"))); section2.Add("Navegando", Km(stat("DistanceSail"))); section2.Add("En el aire", Km(stat("DistanceAir"))); section2.Add("Portales usados", Count(stat("PortalsUsed"))); section2.Add("Saltos", Count(stat("Jumps"))); list.Add(section2); Section section3 = new Section { Title = "Combate", Column = 1 }; float val = s.EnemyKills.Values.Sum(); section3.Add("Matados (participaste)", Count(Math.Max(val, stat("EnemyKills")))); section3.Add("Golpe final", Count(stat("EnemyKillsLastHits"))); section3.Add("Cuerpo a cuerpo / distancia", Count(s.KillsMelee) + " / " + Count(s.KillsRanged)); section3.Add("Magia / sin armas", Count(s.KillsMagic) + " / " + Count(s.KillsUnarmed)); section3.Add("Golpes dados", Count(stat("EnemyHits"))); section3.Add("Golpes recibidos", Count(stat("HitsTakenEnemies"))); section3.Add("Flechas disparadas", Count(stat("ArrowsShot"))); section3.Add("Criaturas domadas", Count(stat("CreatureTamed"))); list.Add(section3); Section section4 = new Section { Title = "Más matados", Column = 1 }; foreach (KeyValuePair<string, float> item in TopMobs(s.EnemyKills, topMobs)) { section4.Add(MobName(item.Key, s.Localize), Count(item.Value)); } if (section4.Rows.Count == 0) { section4.Add("Aún ninguno", "-"); } list.Add(section4); list.Add(DeathsByCause(s, 2, 6)); Section section5 = new Section { Title = "Recursos", Column = 2 }; section5.Add("Árboles talados", Count(stat("Tree"))); section5.Add("Troncos cortados", Count(stat("Logs"))); section5.Add("Vetas agotadas", Count(stat("Mines"))); section5.Add("Objetos recogidos", Count(stat("ItemsPickedUp"))); section5.Add("Cosechas", Count(stat("HarvestCrop") + stat("HarvestBerry") + stat("HarvestMushroom") + stat("HarvestVine"))); section5.Add("Miel y savia", Count(stat("BeesHarvested") + stat("SapHarvested"))); list.Add(section5); Section section6 = new Section { Title = "Construcción y crafteo", Column = 2 }; section6.Add("Piezas construidas", Count(stat("Builds"))); section6.Add("Objetos crafteados", Count(stat("Crafts"))); section6.Add("Mejoras", Count(stat("Upgrades"))); section6.Add("Comidas consumidas", Count(stat("FoodEaten"))); list.Add(section6); return list; } public static List<Section> BuildDeaths(StatsSnapshot s) { List<Section> list = new List<Section>(); Func<string, float> st = s.Stat; list.Add(DeathsByCause(s, 0, 18)); Section section = new Section { Title = "Némesis (te mataron)", Column = 1 }; foreach (KeyValuePair<string, int> item in Top(s.Nemesis, 10)) { section.Add(MobName(item.Key, s.Localize), Count(item.Value)); } if (section.Rows.Count == 0) { section.Add("Ninguna criatura todavía", "-"); } list.Add(section); Section section2 = new Section { Title = "Otros jugadores", Column = 1 }; foreach (KeyValuePair<string, int> item2 in Top(s.PvpNemesis, 6)) { section2.Add(item2.Key, Count(item2.Value)); } if (section2.Rows.Count == 0) { section2.Add("Nadie (por ahora)", "-"); } list.Add(section2); float value = DeathCauses.Where((KeyValuePair<string, string> c) => !s_notEnvironment.Contains(c.Key)).Sum((KeyValuePair<string, string> c) => st(c.Key)); Section section3 = new Section { Title = "Resumen", Column = 2 }; section3.Add("Muertes", Count(st("Deaths"))); section3.Add("Por criaturas", Count(st("DeathByEnemyHit"))); section3.Add("Por otros jugadores", Count(st("DeathByPlayerHit"))); section3.Add("Por el entorno", Count(value)); section3.Add("Por uno mismo", Count(st("DeathBySelf"))); list.Add(section3); KeyValuePair<string, int> keyValuePair = Top(s.Nemesis, 1).FirstOrDefault(); Section section4 = new Section { Title = "Peor némesis", Column = 2 }; if (keyValuePair.Key == null) { section4.Add("Ninguna criatura todavía", "-"); } else { section4.Add(MobName(keyValuePair.Key, s.Localize), Count(keyValuePair.Value)); } list.Add(section4); Section section5 = new Section { Title = "Vida", Column = 2 }; section5.Add("Vida más larga", Duration(Math.Max(s.BestAliveSeconds, s.AliveSeconds))); section5.Add("Vida actual", Duration(s.AliveSeconds)); AddDaysSurvived(section5, st); list.Add(section5); return list; } private static void AddDaysSurvived(Section section, Func<string, float> st) { section.Add("Días seguidos sobrevividos", Count(st("ConsecutiveDaysSurvived"))); section.Add("Récord de días seguidos", Count(st("ConsecutiveDaysSurvivedMax"))); } public static Section DeathsByCause(StatsSnapshot s, int column, int max) { Func<string, float> st = s.Stat; Section section = new Section { Title = "Muertes por causa", Column = column }; List<KeyValuePair<string, float>> list = (from c in DeathCauses select new KeyValuePair<string, float>(c.Value, st(c.Key)) into kv where kv.Value >= 0.5f orderby kv.Value descending select kv).ToList(); foreach (KeyValuePair<string, float> item in list.Take(max)) { section.Add(item.Key, Count(item.Value)); } if (list.Count > max) { section.Add("Resto (" + (list.Count - max) + " causas)", Count(list.Skip(max).Sum((KeyValuePair<string, float> kv) => kv.Value))); } if (section.Rows.Count == 0) { section.Add("Ninguna", "-"); } return section; } public static IEnumerable<KeyValuePair<string, float>> TopMobs(IDictionary<string, float> kills, int n) { if (kills == null || n <= 0) { return Enumerable.Empty<KeyValuePair<string, float>>(); } return (from kv in kills where kv.Value > 0f && !string.IsNullOrEmpty(kv.Key) orderby kv.Value descending select kv).ThenBy<KeyValuePair<string, float>, string>((KeyValuePair<string, float> kv) => kv.Key, StringComparer.Ordinal).Take(n); } private static IEnumerable<KeyValuePair<string, int>> Top(IDictionary<string, int> book, int n) { if (book == null || n <= 0) { return Enumerable.Empty<KeyValuePair<string, int>>(); } return (from kv in book where kv.Value > 0 && !string.IsNullOrEmpty(kv.Key) orderby kv.Value descending select kv).ThenBy<KeyValuePair<string, int>, string>((KeyValuePair<string, int> kv) => kv.Key, StringComparer.Ordinal).Take(n); } public static string MobName(string key, Func<string, string> localize) { if (string.IsNullOrEmpty(key)) { return "?"; } if (key[0] != '$' || localize == null) { return key; } string text = localize(key); return (string.IsNullOrEmpty(text) || text[0] == '[') ? key.TrimStart(new char[1] { '$' }) : text.Trim(); } public static string Duration(double seconds) { if (double.IsNaN(seconds) || seconds < 0.0) { seconds = 0.0; } long num = (long)Math.Floor(seconds); long num2 = num / 86400; long num3 = num % 86400 / 3600; long num4 = num % 3600 / 60; long num5 = num % 60; if (num2 > 0) { return num2 + " d " + num3 + " h"; } if (num3 > 0) { return num3 + " h " + num4.ToString("00") + " min"; } if (num4 > 0) { return num4 + " min " + num5.ToString("00") + " s"; } return num5 + " s"; } public static string Km(float meters) { if (meters < 1000f) { return Math.Round(meters).ToString("0", Es) + " m"; } return (meters / 1000f).ToString("0.0", Es) + " km"; } public static string Count(float value) { return Math.Round(value).ToString("#,0", Es); } } internal static class StatsWindow { private enum Tab { Summary, Bestiary, Deaths } private const float Width = 1100f; private const float Height = 760f; private const float RowHeight = 23f; private const float SectionGap = 12f; private const float TitleRowHeight = 30f; private const float FontSize = 16f; private const float ValueWidthFraction = 0.34f; private const float Pad = 26f; private const float TitleHeight = 40f; private const float TabsTop = 68f; private const float TabHeight = 38f; private const float TabWidth = 180f; private const float ContentTop = 120f; private const float FooterHeight = 20f; private const float ContentHeight = 586f; private const float TableHeaderHeight = 30f; private const float TableRowsTop = 38f; private const float TableFooterHeight = 26f; private const int Columns = 3; private const int ScrollStep = 3; private static GameObject s_canvas; private static RectTransform s_window; private static TextMeshProUGUI s_title; private static TextMeshProUGUI s_footer; private static readonly Button[] s_tabButtons = (Button[])(object)new Button[3]; private static TMP_Text s_bodyStyle; private static RectTransform s_columnsRoot; private static readonly RectTransform[] s_columns = (RectTransform[])(object)new RectTransform[3]; private static readonly List<TextMeshProUGUI>[] s_labels = new List<TextMeshProUGUI>[3]; private static readonly List<TextMeshProUGUI>[] s_values = new List<TextMeshProUGUI>[3]; private static RectTransform s_tableRoot; private static readonly List<TextMeshProUGUI> s_rowNames = new List<TextMeshProUGUI>(); private static readonly List<TextMeshProUGUI> s_rowKills = new List<TextMeshProUGUI>(); private static readonly List<TextMeshProUGUI> s_rowDeaths = new List<TextMeshProUGUI>(); private static readonly List<Image> s_rowShades = new List<Image>(); private static TextMeshProUGUI s_tableRange; private static TextMeshProUGUI s_tableEmpty; private static List<BestiaryRow> s_rows = new List<BestiaryRow>(); private static int s_scroll; private static Tab s_tab = Tab.Summary; private static float s_nextRefresh; private static int s_closedFrame = -1; private static int s_shownFrame; public static bool Visible => (Object)(object)s_canvas != (Object)null && s_canvas.activeSelf; public static bool BlocksMenu => Visible || Time.frameCount == s_closedFrame; private static int VisibleRows => Mathf.Max(1, Mathf.FloorToInt(22.695652f)); public static void Toggle() { if (Visible) { Hide(); } else { Show(); } } public static void Show() { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) if (Ensure()) { if ((Object)(object)InventoryGui.instance != (Object)null && InventoryGui.IsVisible()) { InventoryGui.instance.Hide(); } ((Transform)s_window).localScale = Vector3.one * Mathf.Clamp(StatsPlugin.WindowScale.Value, 0.5f, 2f); s_canvas.SetActive(true); s_shownFrame = Time.frameCount; s_nextRefresh = 0f; Refresh(); } } public static void Hide() { if ((Object)(object)s_canvas != (Object)null) { s_canvas.SetActive(false); } } public static void Destroy() { if ((Object)(object)s_canvas != (Object)null) { Object.Destroy((Object)(object)s_canvas); } s_canvas = null; s_window = null; for (int i = 0; i < 3; i++) { s_columns[i] = null; s_labels[i] = null; s_values[i] = null; } s_rowNames.Clear(); s_rowKills.Clear(); s_rowDeaths.Clear(); s_rowShades.Clear(); s_rows = new List<BestiaryRow>(); } public static void Tick() { if (!Visible) { return; } bool flag = InventoryGui.IsVisible() && Time.frameCount - s_shownFrame > 3; if ((Object)(object)Player.m_localPlayer == (Object)null || Menu.IsVisible() || flag || Minimap.IsOpen()) { Hide(); return; } bool flag2 = Console.IsVisible() || TextInput.IsVisible() || ((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus()); if (!flag2 && ZInput.GetKeyDown((KeyCode)27, false)) { s_closedFrame = Time.frameCount; Hide(); return; } if (s_tab == Tab.Bestiary && !flag2) { HandleScroll(); } if (Time.unscaledTime >= s_nextRefresh) { Refresh(); } } private static bool Ensure() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Expected O, but got Unknown //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_02fd: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)s_canvas != (Object)null) { return true; } if ((Object)(object)InventoryGui.instance == (Object)null) { return false; } s_canvas = new GameObject("vsm_stats_window", new Type[1] { typeof(RectTransform) }); Object.DontDestroyOnLoad((Object)(object)s_canvas); Canvas val = s_canvas.AddComponent<Canvas>(); val.renderMode = (RenderMode)0; val.sortingOrder = 30900; CanvasScaler val2 = s_canvas.AddComponent<CanvasScaler>(); val2.uiScaleMode = (ScaleMode)1; val2.referenceResolution = new Vector2(1920f, 1080f); val2.matchWidthOrHeight = 0.5f; s_canvas.AddComponent<GraphicRaycaster>(); GameObject val3 = new GameObject("window", new Type[1] { typeof(RectTransform) }); s_window = val3.GetComponent<RectTransform>(); ((Transform)s_window).SetParent(s_canvas.transform, false); RectTransform obj = s_window; RectTransform obj2 = s_window; Vector2 val4 = default(Vector2); ((Vector2)(ref val4))..ctor(0.5f, 0.5f); obj2.anchorMax = val4; obj.anchorMin = val4; s_window.pivot = new Vector2(0.5f, 0.5f); s_window.sizeDelta = new Vector2(1100f, 760f); s_window.anchoredPosition = Vector2.zero; Image target = val3.AddComponent<Image>(); if (!VanillaStyle.CopyImage(VanillaStyle.InventoryBackground(null), target)) { StatsPlugin.Log.LogWarning((object)"vsm.stats: no se encontró el fondo del inventario vanilla; se usa uno liso."); } s_bodyStyle = VanillaStyle.BodyFont; s_title = VanillaStyle.NewText((Transform)(object)s_window, "title", VanillaStyle.TitleFont, 28f, (TextAlignmentOptions)514); Place(((TMP_Text)s_title).rectTransform, 26f, 20f, 1048f, 40f); string[] array = new string[3] { "vsm_stats_tab_summary", "vsm_stats_tab_bestiary", "vsm_stats_tab_deaths" }; float num = 270f; for (int i = 0; i < 3; i++) { Tab tab = (Tab)i; Button val5 = MakeButton((Transform)(object)s_window, L(array[i]), delegate { SelectTab(tab); }); Place(((Component)val5).GetComponent<RectTransform>(), num + (float)i * 190f, 68f, 180f, 38f); s_tabButtons[i] = val5; } BuildColumns(); BuildTable(); s_footer = VanillaStyle.NewText((Transform)(object)s_window, "footer", s_bodyStyle, 13f, (TextAlignmentOptions)514); ((Graphic)s_footer).color = new Color(((Graphic)s_footer).color.r, ((Graphic)s_footer).color.g, ((Graphic)s_footer).color.b, 0.6f); Place(((TMP_Text)s_footer).rectTransform, 26f, 716f, 1048f, 20f); s_canvas.SetActive(false); return true; } private static void BuildColumns() { s_columnsRoot = NewRect("columns", (Transform)(object)s_window); Place(s_columnsRoot, 26f, 120f, 1048f, 586f); float num = 349.33334f; for (int i = 0; i < 3; i++) { RectTransform val = NewRect("column" + i, (Transform)(object)s_columnsRoot); Place(val, (float)i * num + 10f, 0f, num - 30f, 586f); s_columns[i] = val; s_labels[i] = new List<TextMeshProUGUI>(); s_values[i] = new List<TextMeshProUGUI>(); } } private static void BuildTable() { //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Expected O, but got Unknown //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Expected O, but got Unknown //IL_02c5: Unknown result type (might be due to invalid IL or missing references) //IL_04c7: Unknown result type (might be due to invalid IL or missing references) //IL_04d6: Unknown result type (might be due to invalid IL or missing references) //IL_04e5: Unknown result type (might be due to invalid IL or missing references) //IL_04f4: Unknown result type (might be due to invalid IL or missing references) float num = 928f; s_tableRoot = NewRect("bestiary", (Transform)(object)s_window); Place(s_tableRoot, 86f, 120f, num, 586f); string text = Accent(); TextMeshProUGUI val = VanillaStyle.NewText((Transform)(object)s_tableRoot, "head_name", s_bodyStyle, 19f, (TextAlignmentOptions)4097); ((TMP_Text)val).text = "<color=" + text + ">" + L("vsm_stats_col_creature") + "</color>"; Place(((TMP_Text)val).rectTransform, 10f, 0f, num * 0.5f, 30f); TextMeshProUGUI val2 = VanillaStyle.NewText((Transform)(object)s_tableRoot, "head_kills", s_bodyStyle, 19f, (TextAlignmentOptions)4100); ((TMP_Text)val2).text = "<color=" + text + ">" + L("vsm_stats_col_kills") + "</color>"; Place(((TMP_Text)val2).rectTransform, num * 0.5f, 0f, num * 0.3f, 30f); TextMeshProUGUI val3 = VanillaStyle.NewText((Transform)(object)s_tableRoot, "head_deaths", s_bodyStyle, 19f, (TextAlignmentOptions)4100); ((TMP_Text)val3).text = "<color=" + text + ">" + L("vsm_stats_col_killedyou") + "</color>"; Place(((TMP_Text)val3).rectTransform, num * 0.8f, 0f, num * 0.2f - 10f, 30f); GameObject val4 = new GameObject("separator", new Type[1] { typeof(RectTransform) }); val4.transform.SetParent((Transform)(object)s_tableRoot, false); Image val5 = val4.AddComponent<Image>(); ((Graphic)val5).color = new Color(1f, 0.79f, 0.36f, 0.35f); ((Graphic)val5).raycastTarget = false; Place(val4.GetComponent<RectTransform>(), 0f, 32f, num, 2f); for (int i = 0; i < VisibleRows; i++) { float y = 38f + (float)i * 23f; GameObject val6 = new GameObject("shade" + i, new Type[1] { typeof(RectTransform) }); val6.transform.SetParent((Transform)(object)s_tableRoot, false); Image val7 = val6.AddComponent<Image>(); ((Graphic)val7).color = new Color(1f, 1f, 1f, 0.045f); ((Graphic)val7).raycastTarget = false; Place(val6.GetComponent<RectTransform>(), 0f, y, num, 23f); s_rowShades.Add(val7); TextMeshProUGUI val8 = VanillaStyle.NewText((Transform)(object)s_tableRoot, "name" + i, s_bodyStyle, 16f, (TextAlignmentOptions)4097); ((TMP_Text)val8).overflowMode = (TextOverflowModes)1; Place(((TMP_Text)val8).rectTransform, 10f, y, num * 0.5f - 20f, 23f); TextMeshProUGUI val9 = VanillaStyle.NewText((Transform)(object)s_tableRoot, "kills" + i, s_bodyStyle, 16f, (TextAlignmentOptions)4100); Place(((TMP_Text)val9).rectTransform, num * 0.5f, y, num * 0.3f, 23f); TextMeshProUGUI val10 = VanillaStyle.NewText((Transform)(object)s_tableRoot, "deaths" + i, s_bodyStyle, 16f, (TextAlignmentOptions)4100); Place(((TMP_Text)val10).rectTransform, num * 0.8f, y, num * 0.2f - 10f, 23f); s_rowNames.Add(val8); s_rowKills.Add(val9); s_rowDeaths.Add(val10); } s_tableEmpty = VanillaStyle.NewText((Transform)(object)s_tableRoot, "empty", s_bodyStyle, 16f, (TextAlignmentOptions)514); Place(((TMP_Text)s_tableEmpty).rectTransform, 0f, 61f, num, 46f); ((TMP_Text)s_tableEmpty).text = L("vsm_stats_bestiary_empty"); s_tableRange = VanillaStyle.NewText((Transform)(object)s_tableRoot, "range", s_bodyStyle, 13f, (TextAlignmentOptions)514); ((Graphic)s_tableRange).color = new Color(((Graphic)s_tableRange).color.r, ((Graphic)s_tableRange).color.g, ((Graphic)s_tableRange).color.b, 0.7f); Place(((TMP_Text)s_tableRange).rectTransform, 0f, 564f, num, 22f); ((Component)s_tableRoot).gameObject.SetActive(false); } private static Button MakeButton(Transform parent, string label, Action onClick) { //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Expected O, but got Unknown //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Expected O, but got Unknown //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Expected O, but got Unknown //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: 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) Button val = (((Object)(object)InventoryGui.instance != (Object)null) ? InventoryGui.instance.m_craftButton : null); GameObject val2; if ((Object)(object)val != (Object)null) { val2 = Object.Instantiate<GameObject>(((Component)val).gameObject, parent, false); UIGamePad[] componentsInChildren = val2.GetComponentsInChildren<UIGamePad>(true); foreach (UIGamePad val3 in componentsInChildren) { Object.Destroy((Object)(object)val3); } UITooltip[] componentsInChildren2 = val2.GetComponentsInChildren<UITooltip>(true); foreach (UITooltip val4 in componentsInChildren2) { Object.Destroy((Object)(object)val4); } } else { val2 = new GameObject("button", new Type[1] { typeof(RectTransform) }); val2.transform.SetParent(parent, false); ((Graphic)val2.AddComponent<Image>()).color = new Color(0.2f, 0.15f, 0.1f, 0.9f); val2.AddComponent<Button>(); } ((Object)val2).name = "vsm_stats_tab"; val2.SetActive(true); Button component = val2.GetComponent<Button>(); component.onClick = new ButtonClickedEvent(); ((UnityEvent)component.onClick).AddListener((UnityAction)delegate { onClick(); }); ((Selectable)component).interactable = true; TMP_Text val5 = val2.GetComponentInChildren<TMP_Text>(true); if ((Object)(object)val5 == (Object)null) { val5 = (TMP_Text)(object)VanillaStyle.NewText(val2.transform, "label", s_bodyStyle, 18f, (TextAlignmentOptions)514); RectTransform rectTransform = val5.rectTransform; rectTransform.anchorMin = Vector2.zero; rectTransform.anchorMax = Vector2.one; Vector2 offsetMin = (rectTransform.offsetMax = Vector2.zero); rectTransform.offsetMin = offsetMin; } val5.text = label; val5.enableAutoSizing = true; val5.fontSizeMin = 12f; val5.fontSizeMax = 20f; return component; } private static RectTransform NewRect(string name, Transform parent) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); return val.GetComponent<RectTransform>(); } private static void Place(RectTransform rt, float x, float y, float w, float h) { //IL_0014: 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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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) Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0f, 1f); rt.anchorMax = val; rt.anchorMin = val; rt.pivot = new Vector2(0f, 1f); rt.sizeDelta = new Vector2(w, h); rt.anchoredPosition = new Vector2(x, 0f - y); } private static void SelectTab(Tab tab) { s_tab = tab; s_nextRefresh = 0f; Refresh(); } private static void UpdateTabs() { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < s_tabButtons.Length; i++) { Button val = s_tabButtons[i]; if ((Object)(object)val != (Object)null && (Object)(object)((Selectable)val).targetGraphic != (Object)null) { ((Selectable)val).targetGraphic.color = (Color)((s_tab == (Tab)i) ? new Color(1f, 0.8f, 0.45f, 1f) : Color.white); } } ((Component)s_columnsRoot).gameObject.SetActive(s_tab != Tab.Bestiary); ((Component)s_tableRoot).gameObject.SetActive(s_tab == Tab.Bestiary); } private static void Refresh() { //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) s_nextRefresh = Time.unscaledTime + 1f; try { StatsSnapshot statsSnapshot = StatsPlugin.TakeSnapshot(); if (statsSnapshot != null) { ((TMP_Text)s_title).text = L("vsm_stats_title", statsSnapshot.Character); UpdateTabs(); switch (s_tab) { case Tab.Bestiary: s_rows = Bestiary.Build(statsSnapshot.EnemyKills, statsSnapshot.Nemesis, statsSnapshot.Localize); RenderTable(); break; case Tab.Deaths: RenderSections(StatsReport.BuildDeaths(statsSnapshot)); break; default: RenderSections(StatsReport.Build(statsSnapshot, StatsPlugin.TopMobs.Value)); break; } string text = AliveTracker.SinceText(Player.m_localPlayer); string text2 = AliveTracker.NemesisSinceText(Player.m_localPlayer); string text3 = ((object)StatsPlugin.ToggleKey.Value/*cast due to .constrained prefix*/).ToString(); ((TMP_Text)s_footer).text = (string.Equals(text, text2, StringComparison.Ordinal) ? L("vsm_stats_footer", statsSnapshot.World, text, text3) : L("vsm_stats_footer_split", statsSnapshot.World, text, text3, text2)); } } catch (Exception ex) { StatsPlugin.Log.LogError((object)("vsm.stats: error al actualizar la ventana: " + ex)); s_nextRefresh = Time.unscaledTime + 10f; } } private static void RenderSections(List<Section> sections) { string text = Accent(); int[] array = new int[3]; float[] array2 = new float[3]; foreach (Section section in sections) { int num = Mathf.Clamp(section.Column, 0, 2); if (array2[num] > 0f) { array2[num] += 12f; } if (array2[num] + 30f + 23f > 586f) { continue; } SetRow(num, array[num]++, array2[num], 30f, "<color=" + text + ">" + section.Title + "</color>", string.Empty, 19f); array2[num] += 30f; foreach (KeyValuePair<string, string> row in section.Rows) { if (array2[num] + 23f > 586f) { break; } SetRow(num, array[num]++, array2[num], 23f, row.Key, row.Value, 16f); array2[num] += 23f; } } for (int i = 0; i < 3; i++) { for (int j = array[i]; j < s_labels[i].Count; j++) { ((Component)s_labels[i][j]).gameObject.SetActive(false); ((Component)s_values[i][j]).gameObject.SetActive(false); } } } private static void SetRow(int column, int index, float y, float height, string label, string value, float size) { //IL_000a: 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) RectTransform val = s_columns[column]; Rect rect = val.rect; float width = ((Rect)(ref rect)).width; float num = width * 0.34f; while (s_labels[column].Count <= index) { TextMeshProUGUI val2 = VanillaStyle.NewText((Transform)(object)val, "label", s_bodyStyle, 16f, (TextAlignmentOptions)4097); ((TMP_Text)val2).overflowMode = (TextOverflowModes)1; TextMeshProUGUI val3 = VanillaStyle.NewText((Transform)(object)val, "value", s_bodyStyle, 16f, (TextAlignmentOptions)4100); ((TMP_Text)val3).overflowMode = (TextOverflowModes)1; s_labels[column].Add(val2); s_values[column].Add(val3); } TextMeshProUGUI val4 = s_labels[column][index]; TextMeshProUGUI val5 = s_values[column][index]; bool flag = string.IsNullOrEmpty(value); Place(((TMP_Text)val4).rectTransform, 0f, y, flag ? width : (width - num - 8f), height); Place(((TMP_Text)val5).rectTransform, width - num, y, num, height); ((TMP_Text)val4).fontSize = size; ((TMP_Text)val5).fontSize = size; ((TMP_Text)val4).text = label; ((TMP_Text)val5).text = value; ((Component)val4).gameObject.SetActive(true); ((Component)val5).gameObject.SetActive(!flag); } private static void RenderTable() { int count = s_rowNames.Count; int count2 = s_rows.Count; s_scroll = Mathf.Clamp(s_scroll, 0, Mathf.Max(0, count2 - count)); for (int i = 0; i < count; i++) { int num = s_scroll + i; bool flag = num < count2; ((Component)s_rowNames[i]).gameObject.SetActive(flag); ((Component)s_rowKills[i]).gameObject.SetActive(flag); ((Component)s_rowDeaths[i]).gameObject.SetActive(flag); ((Behaviour)s_rowShades[i]).enabled = flag && num % 2 == 0; if (flag) { BestiaryRow bestiaryRow = s_rows[num]; ((TMP_Text)s_rowNames[i]).text = bestiaryRow.Name; ((TMP_Text)s_rowKills[i]).text = ((bestiaryRow.Kills >= 0.5f) ? StatsReport.Count(bestiaryRow.Kills) : "-"); ((TMP_Text)s_rowDeaths[i]).text = ((bestiaryRow.Deaths > 0) ? StatsReport.Count(bestiaryRow.Deaths) : "-"); } } ((Component)s_tableEmpty).gameObject.SetActive(count2 == 0); ((Component)s_tableRange).gameObject.SetActive(count2 > 0); if (count2 > 0) { ((TMP_Text)s_tableRange).text = L("vsm_stats_bestiary_range", s_scroll + 1, Mathf.Min(count2, s_scroll + count), count2); } } private static void HandleScroll() { int num = 0; float mouseScrollWheel = ZInput.GetMouseScrollWheel(); if (mouseScrollWheel > 0.0001f) { num -= 3; } else if (mouseScrollWheel < -0.0001f) { num += 3; } if (ZInput.GetKeyDown((KeyCode)281, false)) { num += s_rowNames.Count; } if (ZInput.GetKeyDown((KeyCode)280, false)) { num -= s_rowNames.Count; } if (num != 0) { int num2 = Mathf.Max(0, s_rows.Count - s_rowNames.Count); int num3 = Mathf.Clamp(s_scroll + num, 0, num2); if (num3 != s_scroll) { s_scroll = num3; RenderTable(); } } } private static string Accent() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return "#" + ColorUtility.ToHtmlStringRGB(StatsPlugin.AccentColor); } private static string L(string token, params object[] args) { return VsmLocalization.Localize(token, args); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "vsm.stats"; public const string PLUGIN_NAME = "MEL Stats"; public const string PLUGIN_VERSION = "0.1.4"; } } namespace VSM.Stats.Obituaries { public static class CauseMap { public const string Unknown = "desconocido"; public static readonly string[] KnownCauses = new string[33] { "enemigo", "estrellas", "jefe", "mascota", "misterio", "jugador", "uno_mismo", "flechas", "caida", "caida_empujado", "ahogado", "quemado", "quemado_por", "lava", "brasas", "congelado", "veneno", "veneno_por", "humo", "agua", "fin_del_mundo", "impacto", "carro", "arbol", "estructura", "torreta", "barco", "estalactita", "catapulta", "mar_cenizas", "incinerador", "puente_levadizo", "desconocido" }; private static readonly Dictionary<string, string[]> s_simple = new Dictionary<string, string[]>(StringComparer.Ordinal) { { "Undefined", new string[0] }, { "Drowning", new string[1] { "ahogado" } }, { "Freezing", new string[1] { "congelado" } }, { "Water", new string[1] { "agua" } }, { "Smoke", new string[1] { "humo" } }, { "EdgeOfWorld", new string[1] { "fin_del_mundo" } }, { "Impact", new string[1] { "impacto" } }, { "Cart", new string[2] { "carro", "impacto" } }, { "Tree", new string[2] { "arbol", "impacto" } }, { "Self", new string[1] { "uno_mismo" } }, { "Structural", new string[2] { "estructura", "impacto" } }, { "Turret", new string[1] { "torreta" } }, { "Boat", new string[2] { "barco", "impacto" } }, { "Stalagtite", new string[2] { "estalactita", "impacto" } }, { "Catapult", new string[2] { "catapulta", "impacto" } }, { "CinderFire", new string[2] { "brasas", "quemado" } }, { "AshlandsOcean", new string[2] { "mar_cenizas", "quemado" } }, { "AshlandsLava", new string[2] { "lava", "quemado" } }, { "Incinerator", new string[2] { "incinerador", "quemado" } }, { "DrawBridge", new string[2] { "puente_levadizo", "impacto" } } }; private static readonly string[] s_special = new string[5] { "EnemyHit", "PlayerHit", "Fall", "Burning", "Poisoned" }; private static readonly HashSet<string> s_known = new HashSet<string>(KnownCauses, StringComparer.Ordinal); public static bool IsKnown(string cause) { return !string.IsNullOrEmpty(cause) && s_known.Contains(cause); } public static bool HandlesHitType(string hitType) { return !string.IsNullOrEmpty(hitType) && (s_simple.ContainsKey(hitType) || s_special.Contains(hitType)); } public static List<string> Chain(DeathReport report) { List<string> list = new List<string>(); if (report == null) { list.Add("desconocido"); return list; } bool flag = !string.IsNullOrEmpty(report.Attacker); bool flag2 = report.Has(DeathFlags.Player) && !string.IsNullOrEmpty(report.KillerName); switch (report.HitType) { case "EnemyHit": case "PlayerHit": if (report.Has(DeathFlags.Self)) { list.Add("uno_mismo"); break; } if (report.Has(DeathFlags.Ranged) && (flag2 || flag)) { list.Add("flechas"); } if (flag2) { list.Add("jugador"); } else if (flag) { AddMob(report, list); } else { list.Add("misterio"); } break; case "Fall": if (report.Has(DeathFlags.Pushed) && (flag || flag2)) { list.Add("caida_empujado"); } list.Add("caida"); break; case "Burning": if (report.Has(DeathFlags.Dot) && (flag || flag2)) { list.Add("quemado_por"); } list.Add("quemado"); break; case "Poisoned": if (report.Has(DeathFlags.Dot) && (flag || flag2)) { list.Add("veneno_por"); } list.Add("veneno"); break; default: { if (report.HitType != null && s_simple.TryGetValue(report.HitType, out var value)) { list.AddRange(value); } break; } } list.Add("desconocido"); return list; } private static void AddMob(DeathReport report, List<string> chain) { if (report.Has(DeathFlags.Tamed)) { chain.Add("mascota"); } else if (report.Has(DeathFlags.Boss)) { chain.Add("jefe"); } else if (report.Level > 1) { chain.Add("estrellas"); } chain.Add("enemigo"); } } public enum ObituaryChannelMode { Chat, TopLeft, Both } internal static class ObituaryClient { public const int MaxTextLength = 600; public static void RPC_Obituary(long sender, string text) { try { if (!Headless.IsHeadless) { if (ZRoutedRpc.instance == null || sender != ZRoutedRpc.instance.GetServerPeerID()) { StatsPlugin.Log.LogWarning((object)("vsm.stats: esquela recibida de alguien que no es el servidor (" + sender + "): ignorada.")); } else if (!string.IsNullOrEmpty(text) && text.Length <= 600) { Show(text); } } } catch (Exception ex) { StatsPlugin.Log.LogWarning((object)("vsm.stats: no se pudo mostrar una esquela: " + ex.Message)); } } public static void Show(string text) { //IL_0075: Unknown result type (might be due to invalid IL or missing references) string text2 = ((Localization.instance != null) ? Localization.instance.Localize(text) : text); ObituaryChannelMode obituaryChannelMode = ((StatsPlugin.ObituaryChannel != null) ? StatsPlugin.ObituaryChannel.Value : ObituaryChannelMode.Chat); if ((obituaryChannelMode == ObituaryChannelMode.Chat || obituaryChannelMode == ObituaryChannelMode.Both) && (Object)(object)Chat.instance != (Object)null) { ((Terminal)Chat.instance).AddString("<color=orange>" + VsmLocalization.Localize("vsm_stats_obituary_sender") + "</color>: <color=#" + ColorUtility.ToHtmlStringRGBA(Color.white) + ">" + text2 + "</color>"); Chat.instance.m_hideTimer = 0f; } if ((obituaryChannelMode == ObituaryChannelMode.TopLeft || obituaryChannelMode == ObituaryChannelMode.Both) && (Object)(object)MessageHud.instance != (Object)null) { MessageHud.instance.ShowMessage((MessageType)1, text2, 0, (Sprite)null, false, true); } } } public static class ObituaryComposer { public static string Compose(TemplateBook book, DeathReport report, string victim, Random rng) { DeathReport report2 = (report ?? new DeathReport()).Sanitized(); string template = (book ?? new TemplateBook()).Pick(CauseMap.Chain(report2), rng); return ObituaryFormatter.Fill(template, ObituaryFormatter.Values(report2, victim)); } } public static class ObituaryFormatter { public const int MaxLength = 400; public const string UnknownVictim = "Vikingo anónimo"; public const string UnknownKiller = "alguien"; public static readonly string[] Placeholders = new string[5] { "jugador", "mob", "estrellas", "arbol", "asesino" }; private const string EndChars = " (){}[]+-!?/\\&%,.:=<>\n"; private static readonly string[] s_articles = new string[10] { "el", "la", "los", "las", "un", "una", "unos", "unas", "al", "del" }; public static bool IsLocalizerEndChar(char c) { return " (){}[]+-!?/\\&%,.:=<>\n".IndexOf(c) >= 0; } public static string Stars(int level) { int num = level - 1; if (num <= 0) { return string.Empty; } return (num == 1) ? "1 estrella" : (num.ToString(CultureInfo.InvariantCulture) + " estrellas"); } public static string TreeName(string variant) { return variant switch { "TreeFir" => "un abeto", "TreeOak" => "un roble", "TreePine" => "un pino", "TreeAshlands" => "un arbol de las Cenizas", "TreeYggdrasilShoot" => "un brote de Yggdrasil", "TreeSwamp" => "un arbol ancestral", "TreeBeech" => "una haya", "TreeBirch" => "un abedul", "TreeSnowFir" => "un abeto nevado", "TreeSnowPine" => "un pino nevado", _ => "un arbol", }; } public static Dictionary<string, string> Values(DeathReport report, string victim) { DeathReport deathReport = report ?? new DeathReport(); string text = TextSanitizer.FreeText(deathReport.KillerName, 32); string text2 = TextSanitizer.MobName(deathReport.Attacker); string text3 = ((text.Length <= 0 || (!deathReport.Has(DeathFlags.Tamed) && (!deathReport.Has(DeathFlags.Player) || text2.Length != 0))) ? text2 : text); if (text3.Length == 0) { text3 = "alguien"; } string text4 = TextSanitizer.FreeText(victim, 32); return new Dictionary<string, string>(StringComparer.Ordinal) { { "jugador", (text4.Length > 0) ? text4 : "Vikingo anónimo" }, { "mob", text3 }, { "asesino", (deathReport.Has(DeathFlags.Player) && text.Length > 0) ? text : text3 }, { "estrellas", Stars(deathReport.Level) }, { "arbol", TreeName(deathReport.TreeVariant) } }; } public static string Fill(string template, IDictionary<string, string> values) { if (string.IsNullOrEmpty(template)) { return string.Empty; } StringBuilder stringBuilder = new StringBuilder(template.Length + 64); for (int i = 0; i < template.Length; i++) { char c = template[i]; if (c == '{' && values != null) { int num = template.IndexOf('}', i + 1); if (num > i && values.TryGetValue(template.Substring(i + 1, num - i - 1), out var value)) { stringBuilder.Append(value ?? string.Empty); i = num; continue; } } stringBuilder.Append(c); } return Bound(FixTokens(stringBuilder.ToString())).Trim(); } public static string FixTokens(string text) { if (string.IsNullOrEmpty(text) || text.IndexOf('$') < 0) { return text ?? string.Empty; } StringBuilder stringBuilder = new StringBuilder(text.Length + 8); int num = 0; while (num < text.Length) { char c = text[num]; if (c != '$') { stringBuilder.Append(c); num++; continue; } if (num + 1 >= text.Length || !TextSanitizer.IsWordChar(text[num + 1])) { num++; continue; } int i; for (i = num + 1; i < text.Length && TextSanitizer.IsWordChar(text[i]); i++) { } stringBuilder.Append(text, num, i - num); if (i < text.Length && !IsLocalizerEndChar(text[i])) { stringBuilder.Append(' '); } num = i; } return stringBuilder.ToString(); } public static List<string> Validate(string template, string cause) { List<string> list = Validate(template); if (!string.IsNullOrEmpty(template) && cause != null && cause != "estrellas" && template.IndexOf("{estrellas}", StringComparison.Ordinal) >= 0) { list.Add("{estrellas} solo tiene valor en 'estrellas' (en '" + cause + "' suele quedar vacío)"); } return list; } public static List<string> Validate(string template) { List<string> list = new List<string>(); if (string.IsNullOrEmpty(template)) { list.Add("plantilla vacía"); return list; } for (int i = 0; i < template.Length; i++) { switch (template[i]) { case '{': { int num = template.IndexOf('}', i + 1); if (num < 0) { break; } string text = template.Substring(i + 1, num - i - 1); if (Array.IndexOf(Placeholders, text) < 0) { list.Add("marcador desconocido {" + text + "}"); } else if (text == "mob" || text == "asesino") { if (num + 1 < template.Length && !IsLocalizerEndChar(template[num + 1])) { list.Add("detrás de {" + text + "} va un espacio o . , ! ? : ) - (no '" + template[num + 1] + "')"); } string text2 = WordBefore(template, i); if (Array.IndexOf(s_articles, text2.ToLowerInvariant()) >= 0) { list.Add("no pongas '" + text2 + "' delante de {" + text + "} (algunos nombres ya traen artículo: 'La Reina')"); } } i = num; continue; } case '$': { if (i + 1 >= template.Length || !TextSanitizer.IsWordChar(template[i + 1])) { list.Add("'$' suelto (se quita)"); continue; } int j; for (j = i + 1; j < template.Length && TextSanitizer.IsWordChar(template[j]); j++) { } if (j < template.Length && !IsLocalizerEndChar(template[j])) { list.Add("detrás de " + template.Substring(i, j - i) + " va un espacio o . , ! ? : ) -"); } i = j - 1; continue; } default: continue; } list.Add("'{' sin cerrar"); break; } return list; } private static string WordBefore(string text, int index) { int num = index; while (num > 0 && text[num - 1] == ' ') { num--; } int num2 = num; while (num2 > 0 && char.IsLetter(text[num2 - 1])) { num2--; } return (num > num2) ? text.Substring(num2, num - num2) : string.Empty; } private static string Bound(string text) { if (text.Length <= 400) { return text; } int num = text.LastIndexOf(' ', 399); return ((num > 200) ? text.Substring(0, num) : text.Substring(0, 400)) + "..."; } } internal static class ObituaryServer { public const string DefaultFileName = "vsm.stats.obituaries.txt"; private const int MaxLoggedWarnings = 40; private static TemplateBook s_book; private static string s_path; private static string s_watchedPath; private static FileSystemWatcher s_watcher; private static int s_dirty; private static DateTime s_dirtySince; private static readonly RateLimiter s_limiter = new RateLimiter(10.0); private static readonly Random s_rng = new Random(); public static bool Loaded => s_book != null; public static int TemplateCount => (s_book != null) ? s_book.Count : 0; public static string PathInUse => s_path ?? ResolvePath(); public static string ResolvePath() { string text = ((StatsPlugin.TemplatesFile != null) ? StatsPlugin.TemplatesFile.Value : null); if (string.IsNullOrWhiteSpace(text)) { text = "vsm.stats.obituaries.txt"; } try { string path = (Path.IsPathRooted(text) ? text : Path.Combine(Paths.ConfigPath, text)); return Path.GetFullPath(path); } catch (Exception) { return Path.Combine(Paths.ConfigPath, "vsm.stats.obituaries.txt"); } } public static void EnsureLoaded() { if (s_book == null) { Load(); } StartWatcher(); } public static string Reload() { Load(); StartWatcher(); return "vsm.stats: " + TemplateCount + " plantillas (" + ((s_book != null) ? s_book.CauseCount : 0) + " causas) desde " + s_path + ((s_book != null && s_book.Warnings.Count > 0) ? (" · " + s_book.Warnings.Count + " avisos (ver LogOutput.log)") : string.Empty); } public static void Tick() { if (Volatile.Read(in s_dirty) != 0 && !((DateTime.UtcNow - s_dirtySince).TotalMilliseconds < 500.0)) { Interlocked.Exchange(ref s_dirty, 0); StatsPlugin.Log.LogInfo((object)"vsm.stats: el archivo de esquelas cambió; recargando."); Load(); } } public static void ResetSession() { s_limiter.Clear(); } public static void Shutdown() { if (s_watcher != null) { try { s_watcher.EnableRaisingEvents = false; s_watcher.Dispose(); } catch (Exception) { } s_watcher = null; s_watchedPath = null; } } private static void Load() { string text = ResolvePath(); try { if (!File.Exists(text)) { string directoryName = Path.GetDirectoryName(text); if (!string.IsNullOrEmpty(directoryName)) { Directory.CreateDirectory(directoryName); } File.WriteAllText(text, TemplateBook.DefaultText, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)); StatsPlugin.Log.LogInfo((object)("vsm.stats: creado " + text + " con las esquelas por defecto.")); } TemplateBook templateBook = TemplateBook.Parse(File.ReadAllText(text, Encoding.UTF8)); for (int i = 0; i < templateBook.Warnings.Count && i < 40; i++) { StatsPlugin.Log.LogWarning((object)("vsm.stats: " + Path.GetFileName(text) + ", " + templateBook.Warnings[i])); } if (templateBook.Count == 0) { StatsPlugin.Log.LogWarning((object)("vsm.stats: " + text + " no tiene ninguna plantilla válida: se usan las de por defecto.")); templateBook = TemplateBook.Defaults(); } s_book = templateBook; s_path = text; StatsPlugin.Log.LogInfo((object)("vsm.stats: esquelas cargadas: " + templateBook.Count + " plantillas, " + templateBook.CauseCount + " causas (" + text + ").")); } catch (Exception ex) { StatsPlugin.Log.LogError((object)("vsm.stats: no se pudo leer " + text + ": " + ex.Message + ((s_book != null) ? " (se conservan las anteriores)" : " (se usan las de por defecto)"))); if (s_book == null) { s_book = TemplateBook.Defaults(); s_path = text; } } } private static void StartWatcher() { string text = s_path; if (string.IsNullOrEmpty(text) || string.Equals(text, s_watchedPath, StringComparison.OrdinalIgnoreCase)) { return; } Shutdown(); try { string directoryName = Path.GetDirectoryName(text); if (!string.IsNullOrEmpty(directoryName) && Directory.Exists(directoryName)) { s_watcher = new FileSystemWatcher(directoryName, Path.GetFileName(text)) { NotifyFilter = (NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite | NotifyFilters.CreationTime), EnableRaisingEvents = true }; s_watcher.Changed += MarkDirty; s_watcher.Created += MarkDirty; s_watcher.Deleted += MarkDirty; s_watcher.Renamed += delegate(object s, RenamedEventArgs e) { MarkDirty(s, e); }; s_watchedPath = text; } } catch (Exception ex) { StatsPlugin.Log.LogWarning((object)("vsm.stats: sin recarga automática de las esquelas (usa vsm_stats_reload): " + ex.Message)); } } private static void MarkDirty(object sender, FileSystemEventArgs e) { s_dirtySince = DateTime.UtcNow; Interlocked.Exchange(ref s_dirty, 1); } public static void RPC_Died(long sender, ZPackage pkg) { try { if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer() || !StatsPlugin.ObituariesEnabled.Value) { return; } DeathReport deathReport = StatsNet.Read(pkg); if (deathReport == null) { StatsPlugin.Log.LogWarning((object)("vsm.stats: informe de muerte mal formado de " + sender + " (ignorado).")); return; } string text = VictimName(sender); if (text == null) { StatsPlugin.Log.LogWarning((object)("vsm.stats: informe de muerte de un peer desconocido (" + sender + "): ignorado.")); return; } s_limiter.MinIntervalSeconds = ((StatsPlugin.ReportCooldownSeconds != null) ? StatsPlugin.ReportCooldownSeconds.Value : 10f); if (!s_limiter.TryAcquire(sender, Time.realtimeSinceStartup)) { StatsPlugin.Log.LogInfo((object)("vsm.stats: informe de muerte repetido de " + text + " (ignorado por límite de frecuencia).")); return; } EnsureLoaded(); string text2 = ObituaryComposer.Compose(s_book, deathReport, text, s_rng); StatsPlugin.Log.LogInfo((object)("vsm.stats: esquela [" + deathReport.Sanitized().HitType + "] " + text2)); StatsNet.Broadcast(text2); } catch (Exception ex) { StatsPlugin.Log.LogError((object)("vsm.stats: error al procesar una muerte: " + ex)); } } private static string VictimName(long sender) { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) string text = null; if (sender == ZDOMan.GetSessionID()) { if (ZNet.instance.IsDedicated()) { return null; } PlayerProfile val = (((Object)(object)Game.instance != (Object)null) ? Game.instance.GetPlayerProfile() : null); text = ((val != null) ? val.GetName() : null); } else { ZNetPeer peer = ZNet.instance.GetPeer(sender); if (peer == null || !peer.IsReady()) { return null; } text = peer.m_playerName; if (string.IsNullOrEmpty(text) && !((ZDOID)(ref peer.m_characterID)).IsNone() && ZDOMan.instance != null) { ZDO zDO = ZDOMan.instance.GetZDO(peer.m_characterID); text = ((zDO != null) ? zDO.GetString(ZDOVars.s_playerName, "") : null); } } string text2 = TextSanitizer.FreeText(text, 32); return (text2.Length > 0) ? text2 : "Vikingo anónimo"; } public static string Preview(string cause, string victim) { EnsureLoaded(); DeathReport report = SampleFor(cause); return ObituaryComposer.Compose(s_book, report, victim, s_rng); } private static DeathReport SampleFor(string cause) { return cause switch { "enemigo" => new DeathReport { HitType = "EnemyHit", Attacker = "$enemy_greydwarf", Level = 1 }, "estrellas" => new DeathReport { HitType = "EnemyHit", Attacker = "$enemy_troll", Level = 3 }, "jefe" => new DeathReport { HitType = "EnemyHit", Attacker = "$enemy_gdking", Level = 1, Flags = DeathFlags.Boss }, "mascota" => new DeathReport { HitType = "EnemyHit", Attacker = "$enemy_wolf", Level = 1, Flags = DeathFlags.Tamed, KillerName = "Firulais" }, "misterio" => new DeathReport { HitType = "EnemyHit" }, "jugador" => new DeathReport { HitType = "PlayerHit", Flags = DeathFlags.Player, KillerName = "Bjorn" }, "uno_mismo" => new DeathReport { HitType = "Self" }, "flechas" => new DeathReport { HitType = "EnemyHit", Attacker = "$enemy_skeleton", Level = 1, Flags = DeathFlags.Ranged }, "caida" => new DeathReport { HitType = "Fall", Flags = DeathFlags.Environment }, "caida_empujado" => new DeathReport { HitType = "Fall", Attacker = "$enemy_troll", Level = 1, Flags = DeathFlags.Pushed }, "ahogado" => new DeathReport { HitType = "Drowning" }, "quemado" => new DeathReport { HitType = "Burning", Flags = DeathFlags.Environment }, "quemado_por" => new DeathReport { HitType = "Burning", Attacker = "$enemy_surtling", Level = 1, Flags = DeathFlags.Dot }, "lava" => new DeathReport { HitType = "AshlandsLava" }, "brasas" => new DeathReport { HitType = "CinderFire" }, "congelado" => new DeathReport { HitType = "Freezing" }, "veneno" => new DeathReport { HitType = "Poisoned", Flags = DeathFlags.Environment }, "veneno_por" => new DeathReport { HitType = "Poisoned", Attacker = "$enemy_blob", Level = 1, Flags = DeathFlags.Dot }, "humo" => new DeathReport { HitType = "Smoke" }, "agua" => new DeathReport { HitType = "Water" }, "fin_del_mundo" => new DeathReport { HitType = "EdgeOfWorld" }, "impacto" => new DeathReport { HitType = "Impact" }, "carro" => new DeathReport { HitType = "Cart" }, "arbol" => new DeathReport { HitType = "Tree", TreeVariant = "TreeBirch" }, "estructura" => new DeathReport { HitType = "Structural" }, "torreta" => new DeathReport { HitType = "Turret" }, "barco" => new DeathReport { HitType = "Boat" }, "estalactita" => new DeathReport { HitType = "Stalagtite" }, "catapulta" => new DeathReport { HitType = "Catapult" }, "mar_cenizas" => new DeathReport { HitType = "AshlandsOcean" }, "incinerador" => new DeathReport { HitType = "Incinerator" }, "puente_levadizo" => new DeathReport { HitType = "DrawBridge" }, _ => new DeathReport { HitType = "Undefined" }, }; } public static void BroadcastPreview(string text) { StatsNet.Broadcast(text); } } public sealed class RateLimiter { private readonly Dictionary<long, double> _last = new Dictionary<long, double>(); public double MinIntervalSeconds { get; set; } public int MaxKeys { get; } public int Count => _last.Count; public RateLimiter(double minIntervalSeconds, int maxKeys = 512) { MinIntervalSeconds = minIntervalSeconds; MaxKeys = ((maxKeys < 1) ? 1 : maxKeys); } public bool TryAcquire(long key, double now) { if (_last.TryGetValue(key, out var value) && now >= value && now - value < MinIntervalSeconds) { return false; } _last[key] = now; if (_last.Count > MaxKeys) { Prune(now); } return true; } public void Clear() { _last.Clear(); } private void Prune(double now) { foreach (long item in (from kv in _last where now - kv.Value >= MinIntervalSeconds || now < kv.Value select kv.Key).ToList()) { _last.Remove(item); } while (_last.Count > MaxKeys) { long key = _last.OrderBy((KeyValuePair<long, double> kv) => kv.Value).First().Key; _last.Remove(key); } } } public sealed class TemplateBook { public const int MaxTemplateLength = 300; public const int MaxTemplatesPerCause = 200; public const string FallbackTemplate = "{jugador} se fue a Valhalla."; private const string DefaultResource = "VSM.Stats.obituaries.default.txt"; private readonly Dictionary<string, List<string>> _templates = new Dictionary<string, List<string>>(StringComparer.Ordinal); private static string s_defaultText; public List<string> Warnings { get; } = new List<string>(); public int Count => _templates.Values.Sum((List<string> l) => l.Count); public int CauseCount => _templates.Count; public static string DefaultText { get { if (s_defaultText == null) { s_defaultText = ReadResource() ?? "# vsm.stats: no se encontró el recurso de plantillas por defecto\ndesconocido: {jugador} se fue a Valhalla.\n"; } return s_defaultText; } } public IReadOnlyList<string> For(string cause) { IReadOnlyList<string> result; if (cause == null || !_templates.TryGetValue(cause, out var value)) { IReadOnlyList<string> readOnlyList = new string[0]; result = readOnlyList; } else { IReadOnlyList<string> readOnlyList = value; result = readOnlyList; } return result; } public static TemplateBook Parse(string text) { TemplateBook templateBook = new TemplateBook(); if (string.IsNullOrEmpty(text)) { return templateBook; } string[] array = text.Replace("\r\n", "\n").Replace('\r', '\n').Split(new char[1] { '\n' }); for (int i = 0; i < array.Length; i++) { string text2 = array[i].Trim().TrimStart(new char[1] { '\ufeff' }).Trim(); if (text2.Length == 0 || text2[0] == '#' || text2.StartsWith("//", StringComparison.Ordinal)) { continue; } string text3 = "línea " + (i + 1) + ": "; int num = text2.IndexOf(':'); if (num <= 0) { templateBook.Warnings.Add(text3 + "falta 'causa:' al principio (se ignora)"); continue; } string text4 = text2.Substring(0, num).Trim().ToLowerInvariant(); string text5 = text2.Substring(num + 1).Trim(); if (!CauseMap.IsKnown(text4)) { templateBook.Warnings.Add(text3 + "causa desconocida '" + text4 + "' (se ignora)"); continue; } if (text5.Length == 0) { templateBook.Warnings.Add(text3 + "plantilla vacía (se ignora)"); continue; } if (text5.Length > 300) { templateBook.Warnings.Add(text3 + "más de " + 300 + " caracteres (se ignora)"); continue; } foreach (string item in ObituaryFormatter.Validate(text5, text4)) { templateBook.Warnings.Add(text3 + item); } if (!templateBook._templates.TryGetValue(text4, out var value)) { value = new List<string>(); templateBook._templates[text4] = value; } if (value.Count < 200) { value.Add(text5); } } return templateBook; } public string Pick(IList<string> chain, Random rng) { if (chain != null) { foreach (string item in chain) { if (item != null && _templates.TryGetValue(item, out var value) && value.Count > 0) { return value[rng?.Next(value.Count) ?? 0]; } } } return "{jugador} se fue a Valhalla."; } public static TemplateBook Defaults() { return Parse(DefaultText); } private static string ReadResource() { try { using Stream stream = typeof(TemplateBook).Assembly.GetManifestResourceStream("VSM.Stats.obituaries.default.txt"); if (stream == null) { return null; } using StreamReader streamReader = new StreamReader(stream, Encoding.UTF8, detectEncodingFromByteOrderMarks: true); return streamReader.ReadToEnd(); } catch (Exception) { return null; } } } } namespace VSM.Stats.Deaths { internal sealed class AttackerInfo { public string Attacker = string.Empty; public int Level; public DeathFlags Flags; public string KillerName = string.Empty; public float Time; public void CopyTo(DeathReport report) { report.Attacker = Attacker; report.Level = Level; report.Flags |= Flags; report.KillerName = KillerName; } public static AttackerInfo From(Character attacker, Player victim) { if ((Object)(object)attacker == (Object)null) { return null; } AttackerInfo attackerInfo = new AttackerInfo { Time = Time.time }; if ((Object)(object)victim != (Object)null && (Object)(object)attacker == (Object)(object)victim) { attackerInfo.Flags = DeathFlags.Self; return attackerInfo; } Player val = (Player)(object)((attacker is Player) ? attacker : null); if ((Object)(object)val != (Object)null) { attackerInfo.Flags = DeathFlags.Player; attackerInfo.KillerName = val.GetPlayerName(); return attackerInfo; } attackerInfo.Attacker = attacker.m_name ?? string.Empty; attackerInfo.Level = attacker.GetLevel(); if (attacker.IsBoss()) { attackerInfo.Flags |= DeathFlags.Boss; } try { if (attacker.IsTamed()) { attackerInfo.Flags |= DeathFlags.Tamed; ZNetView nview = attacker.m_nview; if ((Object)(object)nview != (Object)null && nview.IsValid()) { attackerInfo.KillerName = nview.GetZDO().GetString(ZDOVars.s_tamedName, ""); } } } catch (Exception) { } return attackerInfo; } public static AttackerInfo FromZdo(ZDOID id, Player victim) { //IL_0048: 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_0072: Unknown result type (might be due to invalid IL or missing references) if (((ZDOID)(ref id)).IsNone() || ZDOMan.instance == null || (Object)(object)ZNetScene.instance == (Object)null) { return null; } AttackerInfo attackerInfo = new AttackerInfo { Time = Time.time }; if ((Object)(object)victim != (Object)null && id == ((Character)victim).GetZDOID()) { attackerInfo.Flags = DeathFlags.Self; return attackerInfo; } ZDO zDO = ZDOMan.instance.GetZDO(id); if (zDO == null) { return null; } GameObject prefab = ZNetScene.instance.GetPrefab(zDO.GetPrefab()); Character val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<Character>() : null); if ((Object)(object)val == (Object)null) { return null; } if (val is Player) { attackerInfo.Flags = DeathFlags.Player; attackerInfo.KillerName = zDO.GetString(ZDOVars.s_playerName, ""); return attackerInfo; } attackerInfo.Attacker = val.m_name ?? string.Empty; attackerInfo.Level = zDO.GetInt(ZDOVars.s_level, 1); if (val.m_boss) { attackerInfo.Flags |= DeathFlags.Boss; } if (zDO.GetBool(ZDOVars.s_tamed, false)) { attackerInfo.Flags |= DeathFlags.Tamed; attackerInfo.KillerName = zDO.GetString(ZDOVars.s_tamedName, ""); } return attackerInfo; } } internal static class DeathCapture { public const float PushWindowSeconds = 5f; private static bool s_reportedThisLife; public static void OnSpawned() { s_reportedThisLife = false; DotTracker.Clear(); } public static void Reset() { s_reportedThisLife = false; DotTracker.Clear(); } public static void OnDeathPrefix(Player player) { if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer) { return; } ZNetView nview = ((Character)player).m_nview; if ((Object)(object)nview == (Object)null || !nview.IsValid() || !nview.IsOwner() || s_reportedThisLife) { return; } s_reportedThisLife = true; DeathReport report; try { report = Capture(player); } catch (Exception ex) { StatsPlugin.Log.LogWarning((object)("vsm.stats: no se pudo leer la causa de la muerte: " + ex.Message)); report = new DeathReport(); } try { RecordNemesis(player, report); } catch (Exception ex2) { StatsPlugin.Log.LogWarning((object)("vsm.stats: no se pudo guardar la némesis: " + ex2.Message)); } try { RecordMove(player, report); } catch (Exception ex3) { StatsPlugin.Log.LogWarning((object)("vsm.stats: no se pudo reclasificar la muerte: " + ex3.Message)); } try { StatsNet.SendDeath(report); } catch (Exception ex4) { StatsPlugin.Log.LogWarning((object)("vsm.stats: no se pudo avisar al servidor de la muerte: " + ex4.Message)); } } internal unsafe static DeathReport Capture(Player player) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009b: 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_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Expected I4, but got Unknown //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Invalid comparison between Unknown and I4 //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Invalid comparison between Unknown and I4 DeathReport deathReport = new DeathReport(); HitData lastHit = ((Character)player).m_lastHit; if (lastHit == null) { return deathReport; } deathReport.HitType = ((object)Unsafe.As<HitType, HitType>(ref lastHit.m_hitType)/*cast due to .constrained prefix*/).ToString(); float window = ((StatsPlugin.DotWindowSeconds != null) ? StatsPlugin.DotWindowSeconds.Value : 30f); AttackerInfo attackerInfo = AttackerInfo.From(lastHit.GetAttacker(), player); if (attackerInfo == null && lastHit.HaveAttacker()) { attackerInfo = AttackerInfo.FromZdo(lastHit.m_attacker, player); } attackerInfo?.CopyTo(deathReport); HitType hitType = lastHit.m_hitType; HitType val = hitType; switch ((int)val) { case 1: case 2: if (!HasCulprit(deathReport)) { AttackerInfo attackerInfo3 = DotTracker.RecentDirect(5f); if (attackerInfo3 != null && (attackerInfo3.Flags & DeathFlags.Self) == 0) { attackerInfo3.CopyTo(deathReport); } } if (IsArrow(lastHit)) { deathReport.Flags |= DeathFlags.Ranged; } break; case 5: Attribute(deathReport, DotTracker.RecentBurn(window)); break; case 7: Attribute(deathReport, DotTracker.RecentPoison(window)); break; case 3: { AttackerInfo attackerInfo2 = DotTracker.RecentDirect(5f); if (attackerInfo2 != null && (attackerInfo2.Flags & DeathFlags.Self) == 0) { attackerInfo2.CopyTo(deathReport); deathReport.Flags |= DeathFlags.Pushed; } else { deathReport.Flags |= DeathFlags.Environment; } break; } case 13: { PlayerStatType val2 = (PlayerStatType)lastHit.m_variant; if ((int)val2 >= 193 && (int)val2 <= 202) { deathReport.TreeVariant = ((object)(*(PlayerStatType*)(&val2))/*cast due to .constrained prefix*/).ToString(); } deathReport.Flags |= DeathFlags.Environment; break; } default: if (!HasCulprit(deathReport)) { deathReport.Flags |= DeathFlags.Environment; } break; case 0: case 14: break; } return deathReport; } private static bool IsArrow(HitData hit) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 return hit.m_ranged && ((int)hit.m_skill == 8 || (int)hit.m_skill == 14 || hit.m_damage.m_pierce > 0f); } private static void Attribute(DeathReport report, AttackerInfo source) { if (!HasCulprit(report)) { if (source != null && (source.Flags & DeathFlags.Self) == 0) { source.CopyTo(report); report.Flags |= DeathFlags.Dot; } else { report.Flags |= DeathFlags.Environment; } } } private static bool HasCulprit(DeathReport report)