using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using JetBrains.Annotations;
using LocalizationManager;
using Microsoft.CodeAnalysis;
using ServerSync;
using TMPro;
using UnityEngine;
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using YamlDotNet.Core.Tokens;
using YamlDotNet.Helpers;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.Converters;
using YamlDotNet.Serialization.EventEmitters;
using YamlDotNet.Serialization.NamingConventions;
using YamlDotNet.Serialization.NodeDeserializers;
using YamlDotNet.Serialization.NodeTypeResolvers;
using YamlDotNet.Serialization.ObjectFactories;
using YamlDotNet.Serialization.ObjectGraphTraversalStrategies;
using YamlDotNet.Serialization.ObjectGraphVisitors;
using YamlDotNet.Serialization.Schemas;
using YamlDotNet.Serialization.TypeInspectors;
using YamlDotNet.Serialization.TypeResolvers;
using YamlDotNet.Serialization.Utilities;
using YamlDotNet.Serialization.ValueDeserializers;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("TeleportEverything")]
[assembly: AssemblyDescription("https://thunderstore.io/c/valheim/p/OdinPlus/TeleportEverything/")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("kpro")]
[assembly: AssemblyProduct("TeleportEverything")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("2.9.1")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.9.1.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
}
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 Func<object, string> ObjToStr;
public Func<string, object> StrToObj;
}
namespace TeleportEverything
{
[BepInPlugin("com.kpro.TeleportEverything", "TeleportEverything", "2.9.1")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
internal class Plugin : BaseUnityPlugin
{
[HarmonyPatch(typeof(Game), "_RequestRespawn")]
public class _RequestRespawn_Patch
{
private static void Prefix()
{
if (IsModEnabled())
{
Player localPlayer = Player.m_localPlayer;
if (localPlayer != null && !((Character)localPlayer).IsDead())
{
ApplyTax(localPlayer);
}
}
}
private static void Postfix()
{
if (IsModEnabled() && totalContrabandCount > 0)
{
DisplayLongMessage(Localization.instance.Localize("$te_deducted_items_message", new string[2]
{
deductedContraband.ToString(),
totalContrabandCount.ToString()
}));
deductedContraband = 0;
totalContrabandCount = 0;
}
}
}
[HarmonyPatch(typeof(Inventory), "IsTeleportable")]
public static class InventoryIsTeleportablePatch
{
private static bool Prefix(ref bool __result, ref Inventory __instance)
{
if (!IsModEnabled())
{
return true;
}
if (DragonEggsEnabled() && OresEnabled())
{
__result = true;
return false;
}
if (__instance.GetAllItems().Any((ItemData item) => !ItemPermitted(item)))
{
return true;
}
__result = true;
return false;
}
}
[HarmonyPatch(typeof(Teleport), "Interact")]
public static class TeleportInteractPatch
{
private static void Prefix(Humanoid character, bool hold, Teleport __instance)
{
if (IsModEnabled() && !hold && !((Object)(object)__instance.m_targetPoint == (Object)null))
{
IsDungeonTeleport = true;
}
}
private static void Postfix()
{
if (IsModEnabled())
{
IsDungeonTeleport = false;
}
}
}
[HarmonyPatch(typeof(Teleport), "GetHoverText")]
public static class TeleportGetHoverTextPatch
{
private static void Postfix()
{
if (IsModEnabled())
{
SetIncludeMode();
GetCreatures();
DisplayAlliesMessage();
DisplayEnemiesMessage();
}
}
}
[HarmonyPatch(typeof(Humanoid), "IsTeleportable")]
public class IsTeleportablePatch
{
private static bool Postfix(bool __result, Humanoid __instance)
{
if (!IsModEnabled())
{
return __result;
}
if (Game.instance.m_firstSpawn)
{
return __result;
}
if (ShowVikingsDontRun)
{
ShowVikingsDontRun = false;
}
if (!__result)
{
return __result;
}
if (SkyheimAvoidCreatures)
{
return __result;
}
SetIncludeMode();
GetCreatures();
DisplayAlliesMessage();
List<Character>? enemies = Enemies;
if (enemies != null && enemies.Count > 0)
{
if (TeleportMode != null && TeleportMode.Value.Contains("Run"))
{
ShowVikingsDontRun = true;
return false;
}
DisplayEnemiesMessage();
}
if (!IsTransportCartsDisabled() && !IsTeleportingCart())
{
Vagon attachedCart = GetAttachedCart();
if ((Object)(object)attachedCart != (Object)null && !CartIsTeleportable(attachedCart))
{
return false;
}
}
return __result;
}
}
[HarmonyPatch(typeof(TeleportWorld), "Teleport")]
public class TeleportWorldTeleport_Patch
{
private static void Postfix()
{
if (IsModEnabled() && ShowVikingsDontRun)
{
DisplayMessage(Localization.instance.Localize("$te_vikings_dont_run", new string[2]
{
Enemies?.Count.ToString(),
SearchRadius?.Value.ToString()
}));
}
}
}
[HarmonyPatch(typeof(Player), "TeleportTo")]
public class TeleportToPatch
{
private static bool Postfix(bool __result, Player __instance, Vector3 pos, Quaternion rot, bool distantTeleport)
{
//IL_0056: 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_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_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_0074: Unknown result type (might be due to invalid IL or missing references)
if (!IsModEnabled())
{
return __result;
}
if (!((Character)__instance).IsTeleporting())
{
return __result;
}
if (SkyheimAvoidCreatures)
{
return __result;
}
SetIncludeMode();
GetCreatures();
TeleportTriggered = true;
if (!IsDungeonTeleport)
{
ApplyTax(__instance);
}
Vagon attachedCart = GetAttachedCart();
if ((Object)(object)attachedCart != (Object)null && CanTransportCarts())
{
attachedCart.Detach();
TransportCart(attachedCart, pos, rot);
__instance.m_teleportTargetPos += SetForwardOffset(rot, 3.3f);
}
if (TeleportMode != null)
{
List<Character>? enemies = Enemies;
if (enemies != null && enemies.Count > 0 && TeleportMode.Value.Contains("Take"))
{
TeleportCreatures(__instance, Enemies, areEnemies: true);
}
}
TeleportEverythingLogger.LogInfo((object)Localization.instance.Localize("$te_transported_allies_message", new string[2]
{
Allies?.Count.ToString(),
TransportAllies.ToString()
}));
List<Character>? allies = Allies;
if (allies != null && allies.Count > 0 && TransportAllies)
{
TeleportCreatures(__instance, Allies);
}
return __result;
}
}
[HarmonyPatch(typeof(Tameable), "RPC_Command")]
public class TameableRPCCommandPatch
{
private static void Postfix(Tameable __instance)
{
if (IsModEnabled())
{
__instance.m_character.m_nview.ClaimOwnership();
}
}
}
[HarmonyPatch(typeof(Player), "UpdateTeleport")]
public class UpdateTeleportPatch
{
private static void Prefix(ref bool ___m_distantTeleport)
{
int num;
if (IsModEnabled())
{
ConfigEntry<bool>? showTransportAnimationScreen = ShowTransportAnimationScreen;
num = ((showTransportAnimationScreen != null && !showTransportAnimationScreen.Value) ? 1 : 0);
}
else
{
num = 0;
}
if (((uint)num & (___m_distantTeleport ? 1u : 0u)) != 0)
{
___m_distantTeleport = false;
}
}
private static void Postfix(Player __instance, ref bool ___m_teleporting)
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
if (!IsModEnabled() || ___m_teleporting || !TeleportTriggered || !ZNetScene.instance.IsAreaReady(__instance.m_teleportTargetPos))
{
return;
}
TeleportTriggered = false;
if (CanTransportCarts() && attachedTeleportingCartId.HasValue)
{
Vagon val = GetNearbyCarts(((Component)__instance).transform.position, SearchRadius.Value).Where(delegate(Vagon cart)
{
//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_0022: 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)
ZDOID uid = cart.m_nview.GetZDO().m_uid;
ZDOID? attachedTeleportingCartId = Plugin.attachedTeleportingCartId;
return attachedTeleportingCartId.HasValue && uid == attachedTeleportingCartId.GetValueOrDefault();
}).FirstOrDefault();
if (val != null && val.CanAttach(((Component)__instance).gameObject))
{
val.AttachTo(((Component)__instance).gameObject);
}
attachedTeleportingCartId = null;
}
if (totalContrabandCount > 0)
{
DisplayLongMessage(Localization.instance.Localize("$te_deducted_items_message", new string[2]
{
deductedContraband.ToString(),
totalContrabandCount.ToString()
}));
deductedContraband = 0;
totalContrabandCount = 0;
}
}
}
[HarmonyPatch]
public class TeleportWorldPatch
{
[HarmonyPostfix]
[HarmonyPatch(typeof(TeleportWorld), "Awake")]
private static void Postfix(TeleportWorld __instance)
{
if (IsModEnabled())
{
ChangePortalVolume(__instance);
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(TeleportWorld), "UpdatePortal")]
private static void Prefix(TeleportWorld __instance, ref float ___m_activationRange)
{
if (IsModEnabled() && PortalActivationRange != null && !IsFloatEqual(___m_activationRange, PortalActivationRange.Value))
{
___m_activationRange = PortalActivationRange.Value;
}
}
private static void ChangePortalVolume(TeleportWorld portal)
{
AudioSource componentInChildren = ((Component)portal).GetComponentInChildren<AudioSource>();
if ((Object)(object)componentInChildren != (Object)null && PortalSoundVolume != null && !IsFloatEqual(componentInChildren.volume, PortalSoundVolume.Value))
{
componentInChildren.volume = PortalSoundVolume.Value;
}
}
}
[HarmonyPatch(typeof(InventoryGrid), "UpdateGui")]
public class UpdateGui_Patch
{
private static void Postfix(InventoryGrid __instance)
{
if (!IsModEnabled() || (!OresEnabled() && !DragonEggsEnabled()))
{
return;
}
int width = __instance.GetInventory().GetWidth();
foreach (ItemData allItem in __instance.GetInventory().GetAllItems())
{
if (allItem?.m_shared != null && !allItem.m_shared.m_teleportable)
{
Element element = __instance.GetElement(allItem.m_gridPos.x, allItem.m_gridPos.y, width);
if (IsDragonEgg(allItem))
{
((Behaviour)element.m_noteleport).enabled = !DragonEggsEnabled();
}
else
{
((Behaviour)element.m_noteleport).enabled = !OresEnabled();
}
}
}
}
}
[HarmonyPatch(typeof(ItemData), "GetTooltip", new Type[]
{
typeof(ItemData),
typeof(int),
typeof(bool),
typeof(float),
typeof(int)
})]
public class GetTooltip_Patch
{
private static void Postfix(ItemData item, ref string __result)
{
if (!IsModEnabled() || (!OresEnabled() && !DragonEggsEnabled()))
{
return;
}
if ((Object)(object)item?.m_dropPrefab == (Object)null)
{
if (OresEnabled())
{
__result = __result.Replace("\n<color=orange>$item_noteleport</color>", "");
}
}
else if (item?.m_shared != null && !item.m_shared.m_teleportable && ItemPermitted(item))
{
__result = __result.Replace("\n<color=orange>$item_noteleport</color>", "\n" + Localization.instance.Localize("$te_item_transport_fee", new string[1] { HasFeeRemoved(item) ? "0" : TransportFee?.Value.ToString() }));
}
}
}
internal const string SkyheimGuid = "skyheim";
internal static bool SkyheimAvoidCreatures;
private static int placedEnemies;
private static int deductedContraband;
private static int totalContrabandCount;
internal const string ModName = "TeleportEverything";
internal const string ModVersion = "2.9.1";
internal const string Author = "kpro";
internal const string ModURL = "https://thunderstore.io/c/valheim/p/OdinPlus/TeleportEverything/";
private const string ModGUID = "com.kpro.TeleportEverything";
private const string ConfigFileName = "com.kpro.TeleportEverything.cfg";
private static readonly string ConfigFileFullPath;
private readonly Harmony _harmony = new Harmony("com.kpro.TeleportEverything");
public static readonly ManualLogSource TeleportEverythingLogger;
private static readonly ConfigSync ConfigSync;
private static ConfigEntry<bool>? _serverConfigLocked;
public static ConfigEntry<bool>? EnableMod;
public static ConfigEntry<string>? TeleportMode;
public static ConfigEntry<bool>? ServerEnableMask;
public static ConfigEntry<string>? ServerTransportMask;
public static ConfigEntry<float>? TransportRadius;
public static ConfigEntry<float>? TransportVerticalTolerance;
public static ConfigEntry<float>? SpawnForwardOffset;
public static ConfigEntry<bool>? TransportWolves;
public static ConfigEntry<bool>? TransportBoar;
public static ConfigEntry<bool>? TransportLox;
public static ConfigEntry<int>? SpawnEnemiesForwardOffset;
public static ConfigEntry<int>? EnemySpawnRadius;
private const float UP_OFFSET = 0.2f;
public static ConfigEntry<string>? EnemiesMaskMode;
public static ConfigEntry<string>? EnemiesTransportMask;
public static ConfigEntry<float>? PortalActivationRange;
public static ConfigEntry<float>? PortalSoundVolume;
public static ConfigEntry<bool>? ShowTransportAnimationScreen;
public static ConfigEntry<float>? SearchRadius;
public static List<Character>? Enemies;
public static List<Character>? Allies;
public static ConfigEntry<bool>? TransportDragonEggs;
public static ConfigEntry<bool>? TransportOres;
public static ConfigEntry<int>? TransportFee;
public static ConfigEntry<string>? RemoveTransportFeeFrom;
public static ConfigEntry<string>? IncludeMode;
public static ConfigEntry<string>? MessageMode;
public static ConfigEntry<bool>? PlayerEnableMask;
public static ConfigEntry<string>? PlayerTransportMask;
public static ConfigEntry<string>? TransportCartsMode;
public static ConfigEntry<bool>? ShouldTaxCarts;
public static ZDOID? attachedTeleportingCartId;
internal static bool currrentCartBeingTaxed;
private const float CART_SIZE = 2.5f;
private const float CART_FORWARD_OFFSET = 0.8f;
private const float CART_Y_OFFSET = 0.3f;
public static bool TransportAllies;
public static bool IncludeTamed;
public static bool IncludeNamed;
public static bool IncludeFollow;
public static bool ExcludeNamed;
public static bool TeleportTriggered;
public static bool IsDungeonTeleport;
public static bool ShowVikingsDontRun;
private const string LOX = "lox";
private const string BOAR = "boar";
private const string WOLF = "wolf";
private const string DRAGON_EGG = "DragonEgg";
public static bool IsValidAlly(Character c)
{
if (!c.IsTamed())
{
return false;
}
if (IsAllowedAlly(c) && IsTransportable(c) && HorizontalDistance(c) <= TransportRadius?.Value && VerticalDistance(c) <= TransportVerticalTolerance?.Value)
{
return true;
}
return false;
}
public static bool IsAllowedAlly(Character c)
{
if (GetPrefabName(c).Equals("wolf", StringComparison.OrdinalIgnoreCase))
{
ConfigEntry<bool>? transportWolves = TransportWolves;
if (transportWolves != null && !transportWolves.Value)
{
return false;
}
}
if (GetPrefabName(c).Equals("boar", StringComparison.OrdinalIgnoreCase))
{
ConfigEntry<bool>? transportBoar = TransportBoar;
if (transportBoar != null && !transportBoar.Value)
{
return false;
}
}
if (GetPrefabName(c).Equals("lox", StringComparison.OrdinalIgnoreCase))
{
ConfigEntry<bool>? transportLox = TransportLox;
if (transportLox != null && !transportLox.Value)
{
return false;
}
}
if (ServerEnableMask != null && PlayerTransportMask != null && PlayerEnableMask != null && ServerTransportMask != null && IsAllowedInMask(c, ServerEnableMask.Value, ServerTransportMask.Value) && IsAllowedInMask(c, PlayerEnableMask.Value, PlayerTransportMask.Value))
{
return true;
}
return false;
}
private static bool IsAllowedInMask(Character c, bool enableMask, string transportMask)
{
if (!enableMask)
{
return true;
}
return IsInMask(GetPrefabName(c), transportMask);
}
public static bool IsTransportable(Character ally)
{
if (IsNamed(ally) && ExcludeNamed)
{
return false;
}
if (IsFollowing(ally) && IncludeFollow)
{
return true;
}
if (IsNamed(ally) && IncludeNamed)
{
return true;
}
if (ally.IsTamed() && IncludeTamed)
{
return true;
}
return false;
}
public static bool IsNamed(Character t)
{
Tameable component = ((Component)t).GetComponent<Tameable>();
return !string.IsNullOrEmpty((component != null) ? component.GetText() : null);
}
public static bool IsFollowing(Character f)
{
MonsterAI component = ((Component)f).GetComponent<MonsterAI>();
if ((Object)(object)component != (Object)null && (Object)(object)component.GetFollowTarget() != (Object)null)
{
return ((object)component.GetFollowTarget()).Equals((object?)((Component)Player.m_localPlayer).gameObject);
}
return false;
}
public static List<Character> GetAllies(List<Character> creatures)
{
List<Character> list = new List<Character>();
foreach (Character creature in creatures)
{
if (IsValidAlly(creature))
{
list.Add(creature);
}
}
return list;
}
internal static Vagon? GetAttachedCart()
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
if (SearchRadius == null)
{
return null;
}
foreach (Vagon nearbyCart in GetNearbyCarts(((Component)Player.m_localPlayer).transform.position, SearchRadius.Value))
{
if (nearbyCart.IsAttached(((Component)Player.m_localPlayer).gameObject.GetComponent<Character>()))
{
return nearbyCart;
}
}
return null;
}
internal static List<Vagon> GetNearbyCarts(Vector3 position, float searchRadius)
{
//IL_0007: 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)
return GetAllCarts().FindAll((Vagon cart) => Vector3.Distance(((Component)cart).transform.position, position) < searchRadius);
}
internal static List<Vagon> GetAllCarts()
{
return Vagon.m_instances;
}
internal static void TransportCart(Vagon cart, Vector3 pos, Quaternion rot)
{
//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_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: 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_004f: 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_0060: 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_0033: Unknown result type (might be due to invalid IL or missing references)
cart.m_nview.ClaimOwnership();
Vector3 val = pos + SetForwardOffset(rot, 0.8f);
float num = default(float);
if (!ZoneSystem.instance.FindFloor(val, ref num))
{
val.y = ZoneSystem.instance.GetSolidHeight(val) + 0.5f;
}
attachedTeleportingCartId = cart.m_nview.GetZDO().m_uid;
SetPosition((Component)(object)cart, val, rot);
cart.m_body.velocity = Vector3.zero;
}
internal static bool IsTeleportingCart()
{
return attachedTeleportingCartId.HasValue;
}
internal static Inventory? GetCartInventory(Vagon cart)
{
return ((Component)cart).gameObject.GetComponentInChildren<Container>()?.m_inventory;
}
internal static bool CartIsTeleportable(Vagon cart)
{
Inventory? cartInventory = GetCartInventory(cart);
if (cartInventory == null)
{
return false;
}
return cartInventory.IsTeleportable();
}
internal static bool CanTransportCarts()
{
if (IsTransportCartsDisabled())
{
return false;
}
if (TransportCartsMode.Value.Equals("Enabled", StringComparison.OrdinalIgnoreCase))
{
return true;
}
if (TransportCartsMode.Value.Equals("Only Dungeons", StringComparison.OrdinalIgnoreCase) && IsDungeonTeleport)
{
return true;
}
return false;
}
internal static bool IsTransportCartsDisabled()
{
if (TransportCartsMode == null || string.IsNullOrEmpty(TransportCartsMode?.Value) || TransportCartsMode.Value.Equals("Disabled", StringComparison.OrdinalIgnoreCase))
{
return true;
}
return false;
}
private void CheckAndPatchSkyheim()
{
//IL_0054: 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_007c: Expected O, but got Unknown
//IL_007c: Expected O, but got Unknown
//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
//IL_010a: Unknown result type (might be due to invalid IL or missing references)
//IL_0117: Expected O, but got Unknown
//IL_0117: Expected O, but got Unknown
if (!Chainloader.PluginInfos.ContainsKey("skyheim"))
{
return;
}
Type type = Type.GetType("SkyheimAttackBlink, skyheim");
if (type != null)
{
try
{
MethodInfo methodInfo = AccessTools.Method(type, "OnAttackTrigger", (Type[])null, (Type[])null);
_harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(AccessTools.Method(typeof(Plugin), "SkyheimMethodPrefix", (Type[])null, (Type[])null)), new HarmonyMethod(AccessTools.Method(typeof(Plugin), "SkyheimMethodPostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
TeleportEverythingLogger.LogInfo((object)"Skyheim blink settings applied");
}
catch (Exception ex)
{
TeleportEverythingLogger.LogInfo((object)("Failed to apply blink settings to skyheim: " + ex.Message));
}
}
Type type2 = Type.GetType("SkyheimAttackRecall, skyheim");
if (!(type2 != null))
{
return;
}
try
{
MethodInfo methodInfo2 = AccessTools.Method(type2, "OnAttackStart", (Type[])null, (Type[])null);
_harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(AccessTools.Method(typeof(Plugin), "SkyheimMethodPrefix", (Type[])null, (Type[])null)), new HarmonyMethod(AccessTools.Method(typeof(Plugin), "SkyheimMethodPostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
TeleportEverythingLogger.LogInfo((object)"Skyheim recall settings applied");
}
catch (Exception ex2)
{
TeleportEverythingLogger.LogInfo((object)("Failed to apply recall settings to skyheim: " + ex2.Message));
}
}
private static void SkyheimMethodPrefix()
{
SkyheimAvoidCreatures = true;
}
private static void SkyheimMethodPostfix()
{
SkyheimAvoidCreatures = false;
}
public static string GetPrefabName(Character c)
{
return ((Object)c).name.Replace("(Clone)", "");
}
public static List<Regex> CommaSeparatedStringToList(string mask)
{
return (from p in mask.Split(new char[1] { ',' })
select new Regex("\\b" + p.Trim().ToLower() + "\\b", RegexOptions.IgnoreCase)).ToList();
}
private static bool IsInMask(string prefabName, string mask)
{
string prefabName2 = prefabName;
if (string.IsNullOrWhiteSpace(mask))
{
return false;
}
return CommaSeparatedStringToList(mask).FirstOrDefault((Regex name) => name.IsMatch(prefabName2.ToLower())) != null;
}
public static void GetCreatures()
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
List<Character> list = new List<Character>();
if (SearchRadius != null)
{
Character.GetCharactersInRange(((Component)Player.m_localPlayer).transform.position, SearchRadius.Value, list);
}
Allies = GetAllies(list);
Enemies = GetEnemies(list);
}
public static bool IsValidEnemy(Character c)
{
MonsterAI component = ((Component)c).GetComponent<MonsterAI>();
if (component != null && !((BaseAI)component).IsAlerted())
{
return false;
}
if (BaseAI.IsEnemy((Character)(object)Player.m_localPlayer, c))
{
return !c.IsTamed();
}
return false;
}
public static List<Character> GetEnemies(List<Character> creatures)
{
List<Character> list = new List<Character>();
foreach (Character creature in creatures)
{
if ((Object)(object)creature.GetBaseAI() != (Object)null && IsValidEnemy(creature) && IsEnemyAllowedInMask(creature))
{
list.Add(creature);
}
}
return list;
}
public static bool IsEnemyAllowedInMask(Character c)
{
if (EnemiesMaskMode == null || string.IsNullOrEmpty(EnemiesMaskMode.Value))
{
return true;
}
if (EnemiesTransportMask == null || string.IsNullOrEmpty(EnemiesTransportMask.Value))
{
return true;
}
string text = EnemiesMaskMode.Value.ToLower();
if (!(text == "block"))
{
if (text == "allow only" && !IsInMask(GetPrefabName(c), EnemiesTransportMask.Value))
{
return false;
}
}
else if (IsInMask(GetPrefabName(c), EnemiesTransportMask.Value))
{
return false;
}
return true;
}
public static float CalcDistToEntity(Character e)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
Vector3 val = VectorToEntity(e);
return ((Vector3)(ref val)).magnitude;
}
public static Vector3 VectorToEntity(Character e)
{
//IL_0006: 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_001a: Unknown result type (might be due to invalid IL or missing references)
return ((Component)e).transform.position - ((Component)Player.m_localPlayer).transform.position;
}
public static float HorizontalDistance(Character e)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: 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_000f: Unknown result type (might be due to invalid IL or missing references)
Vector3 val = VectorToEntity(e);
Vector2 val2 = default(Vector2);
((Vector2)(ref val2))..ctor(val.x, val.z);
return ((Vector2)(ref val2)).magnitude;
}
public static float VerticalDistance(Character e)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
return Mathf.Abs(VectorToEntity(e).y);
}
public static void DisplayAlliesMessage()
{
if (TransportAllies)
{
List<Character>? allies = Allies;
if (allies != null && allies.Count > 0)
{
DisplayMessage(Localization.instance.Localize("$te_transporting_allies_message", new string[1] { Allies.Count.ToString() }));
}
}
}
public static void DisplayEnemiesMessage()
{
if (TeleportMode != null)
{
List<Character>? enemies = Enemies;
if (enemies != null && enemies.Count > 0 && TeleportMode.Value.Contains("Take"))
{
DisplayMessage(Localization.instance.Localize("$te_transporting_enemies_message", new string[1] { Enemies.Count.ToString() }));
}
}
}
public static void TeleportCreatures(Player player, List<Character> creatures, bool areEnemies = false)
{
//IL_003c: 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)
placedEnemies = 0;
Tameable val = default(Tameable);
foreach (Character creature in creatures)
{
creature.m_nview.ClaimOwnership();
if (!areEnemies && ((Component)creature).TryGetComponent<Tameable>(ref val))
{
val.m_unsummonDistance = 0f;
}
SetPositionAttempt(creature, player.m_teleportTargetPos, player.m_teleportTargetRot, areEnemies);
}
if (placedEnemies > 0)
{
string text = Localization.instance.Localize("$te_transported_enemies_message", new string[1] { placedEnemies.ToString() });
TeleportEverythingLogger.LogInfo((object)text);
DisplayLongMessage(text);
}
}
public static bool IsModEnabled()
{
return EnableMod?.Value ?? false;
}
private static void SetPositionAttempt(Character c, Vector3 destination, Quaternion playerRotation, bool isEnemy)
{
//IL_0015: 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_001d: 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_0024: 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_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_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_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_005c: 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_0069: 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_0090: Unknown result type (might be due to invalid IL or missing references)
int radius = EnemySpawnRadius?.Value ?? 3;
int i = 1;
Vector3 spawnOffset = GetSpawnOffset(c, playerRotation, radius, isEnemy);
for (; i <= 5; i++)
{
Vector3 val = destination;
val += spawnOffset;
val += GetRandomLocation(radius, isEnemy);
if (CharacterFits(val, c, out var placeAt))
{
val.y = placeAt + 0.2f;
SetPosition((Component)(object)c, val, playerRotation);
c.m_body.velocity = Vector3.zero;
c.m_maxAirAltitude = ((Component)c).transform.position.y;
c.SetLookDir(((Component)c).transform.position, 0f);
if (isEnemy)
{
placedEnemies++;
}
break;
}
}
}
private static Vector3 GetRandomLocation(int radius, bool isEnemy)
{
//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_0003: 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_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_002c: 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)
Vector2 val = (isEnemy ? (Random.insideUnitCircle * (float)radius) : (Random.insideUnitCircle * 0.5f));
return new Vector3(val.x, 0f, val.y);
}
internal static Vector3 SetForwardOffset(Quaternion rot, float offsetValue)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: 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)
return rot * Vector3.forward * offsetValue;
}
private static Vector3 GetSpawnOffset(Character c, Quaternion playerRotation, int radius, bool isEnemy)
{
//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_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: 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)
if (SpawnForwardOffset == null)
{
return SetForwardOffset(playerRotation, 0f);
}
float num = SpawnForwardOffset.Value;
if (!isEnemy && GetPrefabName(c).Equals("lox", StringComparison.OrdinalIgnoreCase))
{
num = ((num < 4f) ? 4f : num);
}
if (SpawnEnemiesForwardOffset == null)
{
return SetForwardOffset(playerRotation, 0f);
}
float offsetValue = (isEnemy ? ((float)(SpawnEnemiesForwardOffset.Value + radius / 2)) : num);
return SetForwardOffset(playerRotation, offsetValue);
}
private static void SetPosition(Component c, Vector3 position, Quaternion rotation)
{
//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)
Transform transform = c.transform;
transform.position = position;
transform.rotation = rotation;
}
private static bool FoundFloor(Vector3 position, out float floorHeight)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
float num = default(float);
if (ZoneSystem.instance.FindFloor(position, ref num))
{
floorHeight = num;
return true;
}
floorHeight = 0f;
return false;
}
private static bool FoundRoof(Vector3 p, out float height)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0001: 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)
RaycastHit val = default(RaycastHit);
if (Physics.Raycast(p, Vector3.up, ref val, 1000f, ZoneSystem.instance.m_blockRayMask))
{
height = ((RaycastHit)(ref val)).point.y;
return true;
}
height = 0f;
return false;
}
private static bool CharacterFits(Vector3 position, Character c, out float placeAt)
{
//IL_0007: 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_0016: 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_0022: 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_005c: 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_0069: 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)
placeAt = 0f;
if (!FoundFloor(position, out var floorHeight) && !ZoneSystem.instance.GetGroundHeight(new Vector3(position.x, position.y, position.z), ref floorHeight))
{
floorHeight = ZoneSystem.instance.GetSolidHeight(position) + 0.5f;
}
if (floorHeight - position.y > 20f)
{
return false;
}
placeAt = floorHeight;
if (!FoundRoof(new Vector3(position.x, floorHeight, position.z), out var height))
{
return true;
}
float num = height - floorHeight;
return GetCharacterHeight(c) < num;
}
private static Vector3 FindBlocker(Vector3 p, Vector3 direction, Quaternion rotation, float maxDistance)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//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_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_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_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_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: 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)
Vector3 result = p + rotation * Vector3.forward * maxDistance;
RaycastHit val = default(RaycastHit);
if (!Physics.Raycast(p, direction, ref val, maxDistance, ZoneSystem.instance.m_blockRayMask))
{
return result;
}
return ((RaycastHit)(ref val)).point;
}
private static float GetCharacterHeight(Character c)
{
//IL_0006: 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_000e: Unknown result type (might be due to invalid IL or missing references)
Bounds bounds = ((Collider)c.GetCollider()).bounds;
return ((Bounds)(ref bounds)).size.y;
}
private static bool IsFloatEqual(float first, float second)
{
return Math.Abs(first - second) < 0.01f;
}
public static void DisplayMessage(string msg)
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
if (MessagesEnabled())
{
MessageType messageType = GetMessageType(MessageMode.Value);
MessageHud.instance.ShowMessage(messageType, msg, 0, (Sprite)null, false);
}
}
public static void DisplayLongMessage(string msg)
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Invalid comparison between Unknown and I4
if (MessagesEnabled())
{
if ((int)GetMessageType(MessageMode.Value) == 2)
{
MessageHud.instance.ShowMessage((MessageType)1, msg, 0, (Sprite)null, false);
}
else
{
MessageHud.instance.ShowMessage((MessageType)2, msg, 0, (Sprite)null, false);
}
}
}
public static bool MessagesEnabled()
{
if (!string.IsNullOrWhiteSpace(MessageMode?.Value))
{
return !MessageMode.Value.Equals("No messages", StringComparison.OrdinalIgnoreCase);
}
return false;
}
private static MessageType GetMessageType(string messageMode)
{
if (!messageMode.Equals("centered", StringComparison.OrdinalIgnoreCase))
{
return (MessageType)1;
}
return (MessageType)2;
}
private static bool ItemPermitted(ItemData item)
{
if (item.m_shared.m_teleportable)
{
return true;
}
bool flag = IsDragonEgg(item);
if (flag && !DragonEggsEnabled())
{
return false;
}
if (!flag && !OresEnabled())
{
return false;
}
return true;
}
public static void ApplyTax(Player player)
{
if (((Humanoid)player).IsTeleportable() && !ZoneSystem.instance.GetGlobalKey("noportals") && (TransportFee == null || TransportFee.Value != 0))
{
ReduceStacks(player);
}
}
internal static string GetItemPrefabName(ItemData item)
{
return ((Object)item.m_dropPrefab).name;
}
internal static string GetItemTranslatedName(ItemData item)
{
return Localization.instance.Localize(item.m_shared.m_name);
}
internal static bool IsDragonEgg(ItemData item)
{
if ((Object)(object)item.m_dropPrefab == (Object)null)
{
return false;
}
return GetItemPrefabName(item).Equals("DragonEgg", StringComparison.OrdinalIgnoreCase);
}
internal static bool HasFeeRemoved(ItemData item)
{
if ((Object)(object)item?.m_dropPrefab == (Object)null)
{
return false;
}
if (RemoveTransportFeeFrom?.Value != null)
{
return IsInMask(((Object)item.m_dropPrefab).name, RemoveTransportFeeFrom.Value);
}
return false;
}
private static int CalculateDeductionValue(int oreQuantity)
{
decimal num = (decimal)TransportFee.Value / 100m;
return Math.Max((int)Math.Ceiling((decimal)oreQuantity * num), 1);
}
internal static void ReduceStacks(Player player)
{
Dictionary<string, int> dictionary = RegisterOreQuantities(((Humanoid)player).GetInventory());
Vagon attachedCart = GetAttachedCart();
if (CanTransportCarts())
{
ConfigEntry<bool>? shouldTaxCarts = ShouldTaxCarts;
if (shouldTaxCarts != null && shouldTaxCarts.Value && (Object)(object)attachedCart != (Object)null)
{
dictionary = RegisterOreQuantities(GetCartInventory(attachedCart), isFromCart: true, dictionary);
}
}
foreach (KeyValuePair<string, int> item in dictionary)
{
if (TransportFee == null)
{
continue;
}
int valueToDeduct = CalculateDeductionValue(item.Value);
int deducted = 0;
ConfigEntry<bool>? shouldTaxCarts2 = ShouldTaxCarts;
if (shouldTaxCarts2 != null && shouldTaxCarts2.Value && currrentCartBeingTaxed && (Object)(object)attachedCart != (Object)null && valueToDeduct > 0)
{
Container componentInChildren = ((Component)attachedCart).gameObject.GetComponentInChildren<Container>();
if ((Object)(object)componentInChildren != (Object)null)
{
ReduceFromInventory(componentInChildren.GetInventory(), item.Key, ref valueToDeduct, ref deducted);
}
}
if (valueToDeduct > 0)
{
ReduceFromInventory(((Humanoid)player).GetInventory(), item.Key, ref valueToDeduct, ref deducted);
}
deductedContraband += deducted;
LogDeductionInfo(deducted, item.Value, item.Key);
}
currrentCartBeingTaxed = false;
}
private static void LogDeductionInfo(int deducted, int oreQuantity, string oreKey)
{
string text = Localization.instance.Localize("$te_deducted_items_detailed_message", new string[3]
{
deducted.ToString(),
oreQuantity.ToString(),
oreKey
});
TeleportEverythingLogger.LogInfo((object)text);
}
internal static Dictionary<string, int> RegisterOreQuantities(Inventory? inventory, bool isFromCart = false, Dictionary<string, int> ores = null)
{
if (ores == null)
{
ores = new Dictionary<string, int>();
}
if (inventory == null)
{
return ores;
}
foreach (ItemData item in from item in inventory.GetAllItems()
where !item.m_shared.m_teleportable && !HasFeeRemoved(item)
select item)
{
if (isFromCart)
{
currrentCartBeingTaxed = true;
}
AddOrCreateKey(ores, GetItemTranslatedName(item), item.m_stack);
totalContrabandCount += item.m_stack;
}
return ores;
}
internal static void ReduceFromInventory(Inventory? inventory, string oreKey, ref int valueToDeduct, ref int deducted)
{
string oreKey2 = oreKey;
if (inventory == null)
{
return;
}
foreach (ItemData item in (from item in inventory.GetAllItems()
where !item.m_shared.m_teleportable && GetItemTranslatedName(item).Equals(oreKey2) && item.m_stack > 0
select item).ToList())
{
DeductItemFromInventory(item, ref valueToDeduct, ref deducted);
if (item.m_stack == 0)
{
inventory.RemoveItem(item);
}
}
inventory.Changed();
}
private static void DeductItemFromInventory(ItemData item, ref int valueToDeduct, ref int deducted)
{
if (item.m_stack > valueToDeduct)
{
deducted += valueToDeduct;
item.m_stack -= valueToDeduct;
valueToDeduct = 0;
}
else
{
deducted += item.m_stack;
valueToDeduct -= item.m_stack;
item.m_stack = 0;
}
}
internal static void AddOrCreateKey(Dictionary<string, int> dict, string key, int value)
{
if (dict.ContainsKey(key))
{
dict[key] += value;
}
else
{
dict.Add(key, value);
}
}
public static bool DragonEggsEnabled()
{
return TransportDragonEggs?.Value ?? false;
}
public static bool OresEnabled()
{
return TransportOres?.Value ?? false;
}
private void Awake()
{
Localizer.Load();
CreateConfigValues();
CheckAndPatchSkyheim();
_harmony.PatchAll();
SetupWatcher();
Enemies = new List<Character>();
Allies = new List<Character>();
ClearIncludeVars();
Debug.Log((object)"TeleportEverything Loaded...");
}
private void OnDestroy()
{
_harmony.UnpatchSelf();
}
private void CreateConfigValues()
{
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: Expected O, but got Unknown
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_00ea: Expected O, but got Unknown
//IL_0139: Unknown result type (might be due to invalid IL or missing references)
//IL_0144: Expected O, but got Unknown
//IL_0181: Unknown result type (might be due to invalid IL or missing references)
//IL_018c: Expected O, but got Unknown
//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
//IL_01fa: Expected O, but got Unknown
//IL_023b: Unknown result type (might be due to invalid IL or missing references)
//IL_0246: Expected O, but got Unknown
//IL_0277: Unknown result type (might be due to invalid IL or missing references)
//IL_0282: Expected O, but got Unknown
//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
//IL_02c2: Expected O, but got Unknown
//IL_0335: Unknown result type (might be due to invalid IL or missing references)
//IL_0340: Expected O, but got Unknown
//IL_0381: Unknown result type (might be due to invalid IL or missing references)
//IL_038c: Expected O, but got Unknown
//IL_03cd: Unknown result type (might be due to invalid IL or missing references)
//IL_03d8: Expected O, but got Unknown
//IL_0427: Unknown result type (might be due to invalid IL or missing references)
//IL_0432: Expected O, but got Unknown
//IL_046f: Unknown result type (might be due to invalid IL or missing references)
//IL_047a: Expected O, but got Unknown
//IL_04bb: Unknown result type (might be due to invalid IL or missing references)
//IL_04c6: Expected O, but got Unknown
//IL_0571: Unknown result type (might be due to invalid IL or missing references)
//IL_057c: Expected O, but got Unknown
//IL_05b9: Unknown result type (might be due to invalid IL or missing references)
//IL_05c4: Expected O, but got Unknown
//IL_0608: Unknown result type (might be due to invalid IL or missing references)
//IL_0613: Expected O, but got Unknown
//IL_0657: Unknown result type (might be due to invalid IL or missing references)
//IL_0662: Expected O, but got Unknown
//IL_06c5: Unknown result type (might be due to invalid IL or missing references)
//IL_06d0: Expected O, but got Unknown
//IL_0711: Unknown result type (might be due to invalid IL or missing references)
//IL_071c: Expected O, but got Unknown
//IL_0738: Unknown result type (might be due to invalid IL or missing references)
//IL_0743: Expected O, but got Unknown
//IL_075f: Unknown result type (might be due to invalid IL or missing references)
//IL_076a: Expected O, but got Unknown
//IL_07a2: Unknown result type (might be due to invalid IL or missing references)
//IL_07ad: Expected O, but got Unknown
//IL_07ee: Unknown result type (might be due to invalid IL or missing references)
//IL_07f9: Expected O, but got Unknown
EnableMod = config("--- Mod ---", "Enable Mod", value: true, "Enable/Disable mod");
_serverConfigLocked = config("--- Mod ---", "Force Server Config", value: true, "Force Server Config");
ConfigSync.AddLockingConfigEntry<bool>(_serverConfigLocked);
MessageMode = config("--- Mod ---", "Message Mode", "centered", new ConfigDescription("Message Mode", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[3] { "No messages", "top left", "centered" }), Array.Empty<object>()), synchronizedSetting: false);
PortalActivationRange = config("--- Portal ---", "Portal Activation Range", 5f, new ConfigDescription("Portal activation range in meters.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), new object[1]
{
new ConfigurationManagerAttributes
{
IsAdvanced = true,
Order = 4
}
}), synchronizedSetting: false);
PortalSoundVolume = config("--- Portal ---", "Portal Sound Volume", 0.8f, new ConfigDescription("Portal sound effect volume (rejoin the session or teleport to a farther portal for the new value to take effect).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[1]
{
new ConfigurationManagerAttributes
{
IsAdvanced = true,
Order = 3
}
}), synchronizedSetting: false);
ShowTransportAnimationScreen = config("--- Portal ---", "Show Transport Animation", value: true, new ConfigDescription("Toggle transport animation screen on/off.", (AcceptableValueBase)null, new object[1]
{
new ConfigurationManagerAttributes
{
IsAdvanced = true,
Order = 2
}
}), synchronizedSetting: false);
TeleportMode = config("--- Portal Behavior ---", "Teleport Mode", "Standard", new ConfigDescription("Teleport Mode", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[3] { "Standard", "Vikings Don't Run", "Take Them With You" }), new object[1]
{
new ConfigurationManagerAttributes
{
IsAdvanced = false,
Order = 2
}
}));
SearchRadius = config("--- Portal Behavior ---", "Search Radius", 10f, new ConfigDescription("Radius to search creatures in meters.", (AcceptableValueBase)null, new object[1]
{
new ConfigurationManagerAttributes
{
IsAdvanced = true,
Order = 1
}
}));
ServerEnableMask = config("--- Server ---", "Server Filter By Mask", value: false, new ConfigDescription("Enable to filter and restrict which tameable creatures can teleport on server.", (AcceptableValueBase)null, new object[1]
{
new ConfigurationManagerAttributes
{
IsAdvanced = true
}
}));
ServerTransportMask = config("--- Server ---", "Server Transport Mask", "", new ConfigDescription("Add the prefab names to filter and restrict which creatures can be teleportable on the server", (AcceptableValueBase)null, new object[1]
{
new ConfigurationManagerAttributes
{
IsAdvanced = true
}
}));
IncludeMode = config("--- Transport ---", "Ally Mode", "Only Follow", new ConfigDescription("Ally Mode", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[5] { "No Allies", "All tamed", "Only Follow", "All tamed except Named", "Only Named" }), new object[1]
{
new ConfigurationManagerAttributes
{
IsAdvanced = false,
Order = 7
}
}), synchronizedSetting: false);
TransportRadius = config("--- Transport ---", "Transport Radius", 10f, new ConfigDescription("", (AcceptableValueBase)null, new object[1]
{
new ConfigurationManagerAttributes
{
IsAdvanced = true,
Order = 6
}
}));
TransportVerticalTolerance = config("--- Transport ---", "Vertical Tolerance", 2f, new ConfigDescription("", (AcceptableValueBase)null, new object[1]
{
new ConfigurationManagerAttributes
{
IsAdvanced = true,
Order = 5
}
}));
SpawnForwardOffset = config("--- Transport ---", "Spawn Forward Tolerance", 1.5f, new ConfigDescription("Allies spawn forward offset", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 12f), new object[1]
{
new ConfigurationManagerAttributes
{
IsAdvanced = true,
Order = 4
}
}));
PlayerEnableMask = config("--- Transport ---", "Player Filter By Mask", value: false, new ConfigDescription("Enable to filter and restrict which tameable creatures can teleport.", (AcceptableValueBase)null, new object[1]
{
new ConfigurationManagerAttributes
{
IsAdvanced = true,
Order = 2
}
}), synchronizedSetting: false);
PlayerTransportMask = config("--- Transport ---", "Player Transport Mask", "", new ConfigDescription("Add the prefab names to filter and restrict which creatures can be teleportable.", (AcceptableValueBase)null, new object[1]
{
new ConfigurationManagerAttributes
{
IsAdvanced = true,
Order = 1
}
}), synchronizedSetting: false);
TransportBoar = config("--- Transport ---", "Transport Boars", value: true, "", synchronizedSetting: false);
TransportLox = config("--- Transport ---", "Transport Loxes", value: true, "", synchronizedSetting: false);
TransportWolves = config("--- Transport ---", "Transport Wolves", value: true, "", synchronizedSetting: false);
TransportCartsMode = config("--- Transport Carts ---", "Transport Carts Mode", "Enabled", new ConfigDescription("Allows transporting carts. (beta)", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[3] { "Disabled", "Enabled", "Only Dungeons" }), new object[1]
{
new ConfigurationManagerAttributes
{
Order = 2
}
}));
ShouldTaxCarts = config("--- Transport Carts ---", "Transport Carts Tax Items", value: true, new ConfigDescription("Take fee from cart prohibited items.", (AcceptableValueBase)null, new object[1]
{
new ConfigurationManagerAttributes
{
IsAdvanced = true,
Order = 1
}
}));
SpawnEnemiesForwardOffset = config("--- Transport Enemies ---", "Spawn Enemies Forward Tolerance", 6, new ConfigDescription("Min Spawn forward in meters if Take Enemies With you is enabled.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 12), new object[1]
{
new ConfigurationManagerAttributes
{
IsAdvanced = true,
Order = 4
}
}));
EnemySpawnRadius = config("--- Transport Enemies ---", "Max Enemy Spawn Radius", 3, new ConfigDescription("Max Enemy Spawn Radius if Take Enemies With you is enabled.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 15), new object[1]
{
new ConfigurationManagerAttributes
{
IsAdvanced = true,
Order = 3
}
}));
EnemiesMaskMode = config("--- Transport Enemies ---", "Enemies Mask Mode", "Disabled", new ConfigDescription("This option changes the behavior of the Enemies Mask field.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[3] { "Disabled", "Block", "Allow Only" }), new object[1]
{
new ConfigurationManagerAttributes
{
IsAdvanced = true,
Order = 2
}
}));
EnemiesTransportMask = config("--- Transport Enemies ---", "Enemies Mask", "", new ConfigDescription("This mask is to block or allow only specific enemies to follow the player. If Take Enemies With you is enabled.", (AcceptableValueBase)null, new object[1]
{
new ConfigurationManagerAttributes
{
IsAdvanced = true,
Order = 1
}
}));
TransportDragonEggs = config("--- Transport Items ---", "Transport Dragon Eggs", value: true, new ConfigDescription("Allows transporting dragon eggs.", (AcceptableValueBase)null, Array.Empty<object>()));
TransportOres = config("--- Transport Items ---", "Transport Ores", value: true, new ConfigDescription("Allows transporting ores, ingots and other restricted items.", (AcceptableValueBase)null, Array.Empty<object>()));
TransportFee = config("--- Transport Items ---", "Transport fee", 0, new ConfigDescription("Transport Fee in (%) ore", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), new object[1]
{
new ConfigurationManagerAttributes
{
Order = 2
}
}));
RemoveTransportFeeFrom = config("--- Transport Items ---", "Remove Transport fee from", "DragonEgg", new ConfigDescription("Add the prefab names to remove fee from items on the server", (AcceptableValueBase)null, new object[1]
{
new ConfigurationManagerAttributes
{
IsAdvanced = true,
Order = 1
}
}));
}
private static void ClearIncludeVars()
{
TransportAllies = false;
IncludeTamed = false;
IncludeNamed = false;
IncludeFollow = false;
ExcludeNamed = false;
}
public static void SetIncludeMode()
{
ClearIncludeVars();
if (IncludeMode != null)
{
if (!IncludeMode.Value.Contains("No Allies"))
{
TransportAllies = true;
}
if (IncludeMode.Value.Equals("All tamed"))
{
IncludeTamed = true;
IncludeNamed = true;
IncludeFollow = true;
}
if (IncludeMode.Value.Contains("Only Follow"))
{
IncludeFollow = true;
}
if (IncludeMode.Value.Contains("All tamed except Named"))
{
IncludeTamed = true;
ExcludeNamed = true;
IncludeFollow = true;
}
if (IncludeMode.Value.Contains("Only Named"))
{
IncludeNamed = true;
}
}
}
private void SetupWatcher()
{
FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, "com.kpro.TeleportEverything.cfg");
fileSystemWatcher.Changed += ReadConfigValues;
fileSystemWatcher.Created += ReadConfigValues;
fileSystemWatcher.Renamed += ReadConfigValues;
fileSystemWatcher.IncludeSubdirectories = true;
fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
fileSystemWatcher.EnableRaisingEvents = true;
}
private void ReadConfigValues(object sender, FileSystemEventArgs e)
{
if (!File.Exists(ConfigFileFullPath))
{
return;
}
try
{
TeleportEverythingLogger.LogDebug((object)"ReadConfigValues called");
((BaseUnityPlugin)this).Config.Reload();
}
catch
{
TeleportEverythingLogger.LogError((object)"There was an issue loading your com.kpro.TeleportEverything.cfg");
TeleportEverythingLogger.LogError((object)"Please check your config entries for spelling and format!");
}
}
private ConfigEntry<T> config<T>(string group, string name, T value, ConfigDescription description, bool synchronizedSetting = true)
{
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Expected O, but got Unknown
ConfigDescription val = new ConfigDescription(description.Description + (synchronizedSetting ? " [Synced with Server]" : " [Not Synced with Server]"), description.AcceptableValues, description.Tags);
ConfigEntry<T> val2 = ((BaseUnityPlugin)this).Config.Bind<T>(group, name, value, val);
ConfigSync.AddConfigEntry<T>(val2).SynchronizedConfig = synchronizedSetting;
return val2;
}
private ConfigEntry<T> config<T>(string group, string name, T value, string description, bool synchronizedSetting = true)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Expected O, but got Unknown
return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting);
}
static Plugin()
{
string configPath = Paths.ConfigPath;
char directorySeparatorChar = Path.DirectorySeparatorChar;
ConfigFileFullPath = configPath + directorySeparatorChar + "com.kpro.TeleportEverything.cfg";
TeleportEverythingLogger = Logger.CreateLogSource("TeleportEverything");
ConfigSync = new ConfigSync("com.kpro.TeleportEverything")
{
DisplayName = "TeleportEverything",
CurrentVersion = "2.9.1",
MinimumRequiredVersion = "2.9.1"
};
attachedTeleportingCartId = null;
currrentCartBeingTaxed = false;
TeleportTriggered = false;
IsDungeonTeleport = false;
ShowVikingsDontRun = false;
}
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.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 ServerSync
{
[PublicAPI]
internal abstract class OwnConfigEntryBase
{
public object? LocalBaseValue;
public bool SynchronizedConfig = true;
public abstract ConfigEntryBase BaseConfig { get; }
}
[PublicAPI]
internal class SyncedConfigEntry<T> : OwnConfigEntryBase
{
public readonly ConfigEntry<T> SourceConfig;
public override ConfigEntryBase BaseConfig => (ConfigEntryBase)(object)SourceConfig;
public T Value
{
get
{
return SourceConfig.Value;
}
set
{
SourceConfig.Value = value;
}
}
public SyncedConfigEntry(ConfigEntry<T> sourceConfig)
{
SourceConfig = sourceConfig;
base..ctor();
}
public void AssignLocalValue(T value)
{
if (LocalBaseValue == null)
{
Value = value;
}
else
{
LocalBaseValue = value;
}
}
}
internal abstract class CustomSyncedValueBase
{
public object? LocalBaseValue;
public readonly string Identifier;
public readonly Type Type;
private object? boxedValue;
protected bool localIsOwner;
public readonly int Priority;
public object? BoxedValue
{
get
{
return boxedValue;
}
set
{
boxedValue = value;
this.ValueChanged?.Invoke();
}
}
public event Action? ValueChanged;
protected CustomSyncedValueBase(ConfigSync configSync, string identifier, Type type, int priority)
{
Priority = priority;
Identifier = identifier;
Type = type;
configSync.AddCustomValue(this);
localIsOwner = configSync.IsSourceOfTruth;
configSync.SourceOfTruthChanged += delegate(bool truth)
{
localIsOwner = truth;
};
}
}
[PublicAPI]
internal sealed class CustomSyncedValue<T> : CustomSyncedValueBase
{
public T Value
{
get
{
return (T)base.BoxedValue;
}
set
{
base.BoxedValue = value;
}
}
public CustomSyncedValue(ConfigSync configSync, string identifier, T value = default(T), int priority = 0)
: base(configSync, identifier, typeof(T), priority)
{
Value = value;
}
public void AssignLocalValue(T value)
{
if (localIsOwner)
{
Value = value;
}
else
{
LocalBaseValue = value;
}
}
}
internal class ConfigurationManagerAttributes
{
[UsedImplicitly]
public bool? ReadOnly = false;
}
[PublicAPI]
internal class ConfigSync
{
[HarmonyPatch(typeof(ZRpc), "HandlePackage")]
private static class SnatchCurrentlyHandlingRPC
{
public static ZRpc? currentRpc;
[HarmonyPrefix]
private static void Prefix(ZRpc __instance)
{
currentRpc = __instance;
}
}
[HarmonyPatch(typeof(ZNet), "Awake")]
internal static class RegisterRPCPatch
{
[HarmonyPostfix]
private static void Postfix(ZNet __instance)
{
isServer = __instance.IsServer();
foreach (ConfigSync configSync2 in configSyncs)
{
ZRoutedRpc.instance.Register<ZPackage>(configSync2.Name + " ConfigSync", (Action<long, ZPackage>)configSync2.RPC_FromOtherClientConfigSync);
if (isServer)
{
configSync2.InitialSyncDone = true;
Debug.Log((object)("Registered '" + configSync2.Name + " ConfigSync' RPC - waiting for incoming connections"));
}
}
if (isServer)
{
((MonoBehaviour)__instance).StartCoroutine(WatchAdminListChanges());
}
static void SendAdmin(List<ZNetPeer> peers, bool isAdmin)
{
ZPackage package = ConfigsToPackage(null, null, new PackageEntry[1]
{
new PackageEntry
{
section = "Internal",
key = "lockexempt",
type = typeof(bool),
value = isAdmin
}
});
ConfigSync configSync = configSyncs.First();
if (configSync != null)
{
((MonoBehaviour)ZNet.instance).StartCoroutine(configSync.sendZPackage(peers, package));
}
}
static IEnumerator WatchAdminListChanges()
{
MethodInfo listContainsId = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null);
SyncedList adminList = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance);
List<string> CurrentList = new List<string>(adminList.GetList());
while (true)
{
yield return (object)new WaitForSeconds(30f);
if (!adminList.GetList().SequenceEqual(CurrentList))
{
CurrentList = new List<string>(adminList.GetList());
List<ZNetPeer> adminPeer = ZNet.instance.GetPeers().Where(delegate(ZNetPeer p)
{
string hostName = p.m_rpc.GetSocket().GetHostName();
return ((object)listContainsId == null) ? adminList.Contains(hostName) : ((bool)listContainsId.Invoke(ZNet.instance, new object[2] { adminList, hostName }));
}).ToList();
List<ZNetPeer> nonAdminPeer = ZNet.instance.GetPeers().Except(adminPeer).ToList();
SendAdmin(nonAdminPeer, isAdmin: false);
SendAdmin(adminPeer, isAdmin: true);
}
}
}
}
}
[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
private static class RegisterClientRPCPatch
{
[HarmonyPostfix]
private static void Postfix(ZNet __instance, ZNetPeer peer)
{
if (__instance.IsServer())
{
return;
}
foreach (ConfigSync configSync in configSyncs)
{
peer.m_rpc.Register<ZPackage>(configSync.Name + " ConfigSync", (Action<ZRpc, ZPackage>)configSync.RPC_FromServerConfigSync);
}
}
}
private class ParsedConfigs
{
public readonly Dictionary<OwnConfigEntryBase, object?> configValues = new Dictionary<OwnConfigEntryBase, object>();
public readonly Dictionary<CustomSyncedValueBase, object?> customValues = new Dictionary<CustomSyncedValueBase, object>();
}
[HarmonyPatch(typeof(ZNet), "Shutdown")]
private class ResetConfigsOnShutdown
{
[HarmonyPostfix]
private static void Postfix()
{
ProcessingServerUpdate = true;
foreach (ConfigSync configSync in configSyncs)
{
configSync.resetConfigsFromServer();
configSync.IsSourceOfTruth = true;
configSync.InitialSyncDone = false;
}
ProcessingServerUpdate = false;
}
}
[HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")]
private class SendConfigsAfterLogin
{
private class BufferingSocket : ZPlayFabSocket, ISocket
{
public volatile bool finished = false;
public volatile int versionMatchQueued = -1;
public readonly List<ZPackage> Package = new List<ZPackage>();
public readonly ISocket Original;
public BufferingSocket(ISocket original)
{
Original = original;
((ZPlayFabSocket)this)..ctor();
}
public bool IsConnected()
{
return Original.IsConnected();
}
public ZPackage Recv()
{
return Original.Recv();
}
public int GetSendQueueSize()
{
return Original.GetSendQueueSize();
}
public int GetCurrentSendRate()
{
return Original.GetCurrentSendRate();
}
public bool IsHost()
{
return Original.IsHost();
}
public void Dispose()
{
Original.Dispose();
}
public bool GotNewData()
{
return Original.GotNewData();
}
public void Close()
{
Original.Close();
}
public string GetEndPointString()
{
return Original.GetEndPointString();
}
public void GetAndResetStats(out int totalSent, out int totalRecv)
{
Original.GetAndResetStats(ref totalSent, ref totalRecv);
}
public void GetConnectionQuality(out float localQuality, out float remoteQuality, out int ping, out float outByteSec, out float inByteSec)
{
Original.GetConnectionQuality(ref localQuality, ref remoteQuality, ref ping, ref outByteSec, ref inByteSec);
}
public ISocket Accept()
{
return Original.Accept();
}
public int GetHostPort()
{
return Original.GetHostPort();
}
public bool Flush()
{
return Original.Flush();
}
public string GetHostName()
{
return Original.GetHostName();
}
public void VersionMatch()
{
if (finished)
{
Original.VersionMatch();
}
else
{
versionMatchQueued = Package.Count;
}
}
public void Send(ZPackage pkg)
{
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Expected O, but got Unknown
int pos = pkg.GetPos();
pkg.SetPos(0);
int num = pkg.ReadInt();
if ((num == StringExtensionMethods.GetStableHashCode("PeerInfo") || num == StringExtensionMethods.GetStableHashCode("RoutedRPC") || num == StringExtensionMethods.GetStableHashCode("ZDOData")) && !finished)
{
ZPackage val = new ZPackage(pkg.GetArray());
val.SetPos(pos);
Package.Add(val);
}
else
{
pkg.SetPos(pos);
Original.Send(pkg);
}
}
}
[HarmonyPriority(800)]
[HarmonyPrefix]
private static void Prefix(ref Dictionary<Assembly, BufferingSocket>? __state, ZNet __instance, ZRpc rpc)
{
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Invalid comparison between Unknown and I4
if (!__instance.IsServer())
{
return;
}
BufferingSocket bufferingSocket = new BufferingSocket(rpc.GetSocket());
AccessTools.DeclaredField(typeof(ZRpc), "m_socket").SetValue(rpc, bufferingSocket);
object? obj = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance, new object[1] { rpc });
ZNetPeer val = (ZNetPeer)((obj is ZNetPeer) ? obj : null);
if (val != null && (int)ZNet.m_onlineBackend > 0)
{
FieldInfo fieldInfo = AccessTools.DeclaredField(typeof(ZNetPeer), "m_socket");
object? value = fieldInfo.GetValue(val);
ZPlayFabSocket val2 = (ZPlayFabSocket)((value is ZPlayFabSocket) ? value : null);
if (val2 != null)
{
typeof(ZPlayFabSocket).GetField("m_remotePlayerId").SetValue(bufferingSocket, val2.m_remotePlayerId);
}
fieldInfo.SetValue(val, bufferingSocket);
}
if (__state == null)
{
__state = new Dictionary<Assembly, BufferingSocket>();
}
__state[Assembly.GetExecutingAssembly()] = bufferingSocket;
}
[HarmonyPostfix]
private static void Postfix(Dictionary<Assembly, BufferingSocket> __state, ZNet __instance, ZRpc rpc)
{
ZRpc rpc2 = rpc;
ZNet __instance2 = __instance;
Dictionary<Assembly, BufferingSocket> __state2 = __state;
ZNetPeer peer;
if (__instance2.IsServer())
{
object obj = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance2, new object[1] { rpc2 });
peer = (ZNetPeer)((obj is ZNetPeer) ? obj : null);
if (peer == null)
{
SendBufferedData();
}
else
{
((MonoBehaviour)__instance2).StartCoroutine(sendAsync());
}
}
void SendBufferedData()
{
if (rpc2.GetSocket() is BufferingSocket bufferingSocket)
{
AccessTools.DeclaredField(typeof(ZRpc), "m_socket").SetValue(rpc2, bufferingSocket.Original);
object? obj2 = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance2, new object[1] { rpc2 });
ZNetPeer val = (ZNetPeer)((obj2 is ZNetPeer) ? obj2 : null);
if (val != null)
{
AccessTools.DeclaredField(typeof(ZNetPeer), "m_socket").SetValue(val, bufferingSocket.Original);
}
}
BufferingSocket bufferingSocket2 = __state2[Assembly.GetExecutingAssembly()];
bufferingSocket2.finished = true;
for (int i = 0; i < bufferingSocket2.Package.Count; i++)
{
if (i == bufferingSocket2.versionMatchQueued)
{
bufferingSocket2.Original.VersionMatch();
}
bufferingSocket2.Original.Send(bufferingSocket2.Package[i]);
}
if (bufferingSocket2.Package.Count == bufferingSocket2.versionMatchQueued)
{
bufferingSocket2.Original.VersionMatch();
}
}
IEnumerator sendAsync()
{
foreach (ConfigSync configSync in configSyncs)
{
List<PackageEntry> entries = new List<PackageEntry>();
if (configSync.CurrentVersion != null)
{
entries.Add(new PackageEntry
{
section = "Internal",
key = "serverversion",
type = typeof(string),
value = configSync.CurrentVersion
});
}
MethodInfo listContainsId = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null);
SyncedList adminList = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance);
entries.Add(new PackageEntry
{
section = "Internal",
key = "lockexempt",
type = typeof(bool),
value = (((object)listContainsId == null) ? ((object)adminList.Contains(rpc2.GetSocket().GetHostName())) : listContainsId.Invoke(ZNet.instance, new object[2]
{
adminList,
rpc2.GetSocket().GetHostName()
}))
});
ZPackage package = ConfigsToPackage(configSync.allConfigs.Select((OwnConfigEntryBase c) => c.BaseConfig), configSync.allCustomValues, entries, partial: false);
yield return ((MonoBehaviour)__instance2).StartCoroutine(configSync.sendZPackage(new List<ZNetPeer> { peer }, package));
}
SendBufferedData();
}
}
}
private class PackageEntry
{
public string section = null;
public string key = null;
public Type type = null;
public object? value;
}
[HarmonyPatch(typeof(ConfigEntryBase), "GetSerializedValue")]
private static class PreventSavingServerInfo
{
[HarmonyPrefix]
private static bool Prefix(ConfigEntryBase __instance, ref string __result)
{
OwnConfigEntryBase ownConfigEntryBase = configData(__instance);
if (ownConfigEntryBase == null || isWritableConfig(ownConfigEntryBase))
{
return true;
}
__result = TomlTypeConverter.ConvertToString(ownConfigEntryBase.LocalBaseValue, __instance.SettingType);
return false;
}
}
[HarmonyPatch(typeof(ConfigEntryBase), "SetSerializedValue")]
private static class PreventConfigRereadChangingValues
{
[HarmonyPrefix]
private static bool Prefix(ConfigEntryBase __instance, string value)
{
OwnConfigEntryBase ownConfigEntryBase = configData(__instance);
if (ownConfigEntryBase == null || ownConfigEntryBase.LocalBaseValue == null)
{
return true;
}
try
{
ownConfigEntryBase.LocalBaseValue = TomlTypeConverter.ConvertToValue(value, __instance.SettingType);
}
catch (Exception ex)
{
Debug.LogWarning((object)$"Config value of setting \"{__instance.Definition}\" could not be parsed and will be ignored. Reason: {ex.Message}; Value: {value}");
}
return false;
}
}
private class InvalidDeserializationTypeException : Exception
{
public string expected = null;
public string received = null;
public string field = "";
}
public static bool ProcessingServerUpdate;
public readonly string Name;
public string? DisplayName;
public string? CurrentVersion;
public string? MinimumRequiredVersion;
public bool ModRequired = false;
private bool? forceConfigLocking;
private bool isSourceOfTruth = true;
private static readonly HashSet<ConfigSync> configSyncs;
private readonly HashSet<OwnConfigEntryBase> allConfigs = new HashSet<OwnConfigEntryBase>();
private HashSet<CustomSyncedValueBase> allCustomValues = new HashSet<CustomSyncedValueBase>();
private static bool isServer;
private static bool lockExempt;
private OwnConfigEntryBase? lockedConfig = null;
private const byte PARTIAL_CONFIGS = 1;
private const byte FRAGMENTED_CONFIG = 2;
private const byte COMPRESSED_CONFIG = 4;
private readonly Dictionary<string, SortedDictionary<int, byte[]>> configValueCache = new Dictionary<string, SortedDictionary<int, byte[]>>();
private readonly List<KeyValuePair<long, string>> cacheExpirations = new List<KeyValuePair<long, string>>();
private static long packageCounter;
public bool IsLocked
{
get
{
bool? flag = forceConfigLocking;
bool num;
if (!flag.HasValue)
{
if (lockedConfig == null)
{
goto IL_0052;
}
num = ((IConvertible)lockedConfig.BaseConfig.BoxedValue).ToInt32(CultureInfo.InvariantCulture) != 0;
}
else
{
num = flag.GetValueOrDefault();
}
if (!num)
{
goto IL_0052;
}
int result = ((!lockExempt) ? 1 : 0);
goto IL_0053;
IL_0053:
return (byte)result != 0;
IL_0052:
result = 0;
goto IL_0053;
}
set
{
forceConfigLocking = value;
}
}
public bool IsAdmin => lockExempt || isSourceOfTruth;
public bool IsSourceOfTruth
{
get
{
return isSourceOfTruth;
}
private set
{
if (value != isSourceOfTruth)
{
isSourceOfTruth = value;
this.SourceOfTruthChanged?.Invoke(value);
}
}
}
public bool InitialSyncDone { get; private set; } = false;
public event Action<bool>? SourceOfTruthChanged;
private event Action? lockedConfigChanged;
static ConfigSync()
{
ProcessingServerUpdate = false;
configSyncs = new HashSet<ConfigSync>();
lockExempt = false;
packageCounter = 0L;
RuntimeHelpers.RunClassConstructor(typeof(VersionCheck).TypeHandle);
}
public ConfigSync(string name)
{
Name = name;
configSyncs.Add(this);
new VersionCheck(this);
}
public SyncedConfigEntry<T> AddConfigEntry<T>(ConfigEntry<T> configEntry)
{
ConfigEntry<T> configEntry2 = configEntry;
OwnConfigEntryBase ownConfigEntryBase = configData((ConfigEntryBase)(object)configEntry2);
SyncedConfigEntry<T> syncedEntry = ownConfigEntryBase as SyncedConfigEntry<T>;
if (syncedEntry == null)
{
syncedEntry = new SyncedConfigEntry<T>(configEntry2);
AccessTools.DeclaredField(typeof(ConfigDescription), "<Tags>k__BackingField").SetValue(((ConfigEntryBase)configEntry2).Description, new object[1]
{
new ConfigurationManagerAttributes()
}.Concat(((ConfigEntryBase)configEntry2).Description.Tags ?? Array.Empty<object>()).Concat(new SyncedConfigEntry<T>[1] { syncedEntry }).ToArray());
configEntry2.SettingChanged += delegate
{
if (!ProcessingServerUpdate && syncedEntry.SynchronizedConfig)
{
Broadcast(ZRoutedRpc.Everybody, (ConfigEntryBase)configEntry2);
}
};
allConfigs.Add(syncedEntry);
}
return syncedEntry;
}
public SyncedConfigEntry<T> AddLockingConfigEntry<T>(ConfigEntry<T> lockingConfig) where T : IConvertible
{
if (lockedConfig != null)
{
throw new Exception("Cannot initialize locking ConfigEntry twice");
}
lockedConfig = AddConfigEntry<T>(lockingConfig);
lockingConfig.SettingChanged += delegate
{
this.lockedConfigChanged?.Invoke();
};
return (SyncedConfigEntry<T>)lockedConfig;
}
internal void AddCustomValue(CustomSyncedValueBase customValue)
{
CustomSyncedValueBase customValue2 = customValue;
if (allCustomValues.Select((CustomSyncedValueBase v) => v.Identifier).Concat(new string[1] { "serverversion" }).Contains(customValue2.Identifier))
{
throw new Exception("Cannot have multiple settings with the same name or with a reserved name (serverversion)");
}
allCustomValues.Add(customValue2);
allCustomValues = new HashSet<CustomSyncedValueBase>(allCustomValues.OrderByDescending((CustomSyncedValueBase v) => v.Priority));
customValue2.ValueChanged += delegate
{
if (!ProcessingServerUpdate)
{
Broadcast(ZRoutedRpc.Everybody, customValue2);
}
};
}
private void RPC_FromServerConfigSync(ZRpc rpc, ZPackage package)
{
lockedConfigChanged += serverLockedSettingChanged;
IsSourceOfTruth = false;
if (HandleConfigSyncRPC(0L, package, clientUpdate: false))
{
InitialSyncDone = true;
}
}
private void RPC_FromOtherClientConfigSync(long sender, ZPackage package)
{
HandleConfigSyncRPC(sender, package, clientUpdate: true);
}
private bool HandleConfigSyncRPC(long sender, ZPackage package, bool clientUpdate)
{
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Expected O, but got Unknown
//IL_0250: Unknown result type (might be due to invalid IL or missing references)
//IL_0257: Expected O, but got Unknown
//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
//IL_01f1: Expected O, but got Unknown
try
{
if (isServer && IsLocked)
{
ZRpc? currentRpc = SnatchCurrentlyHandlingRPC.currentRpc;
object obj;
if (currentRpc == null)
{
obj = null;
}
else
{
ISocket socket = currentRpc.GetSocket();
obj = ((socket != null) ? socket.GetHostName() : null);
}
string text = (string)obj;
if (text != null)
{
MethodInfo methodInfo = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null);
SyncedList val = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance);
if (!(((object)methodInfo == null) ? val.Contains(text) : ((bool)methodInfo.Invoke(ZNet.instance, new object[2] { val, text }))))
{
return false;
}
}
}
cacheExpirations.RemoveAll(delegate(KeyValuePair<long, string> kv)
{
if (kv.Key < DateTimeOffset.Now.Ticks)
{
configValueCache.Remove(kv.Value);
return true;
}
return false;
});
byte b = package.ReadByte();
if ((b & 2u) != 0)
{
long num = package.ReadLong();
string text2 = sender.ToString() + num;
if (!configValueCache.TryGetValue(text2, out SortedDictionary<int, byte[]> value))
{
value = new SortedDictionary<int, byte[]>();
configValueCache[text2] = value;
cacheExpirations.Add(new KeyValuePair<long, string>(DateTimeOffset.Now.AddSeconds(60.0).Ticks, text2));
}
int key = package.ReadInt();
int num2 = package.ReadInt();
value.Add(key, package.ReadByteArray());
if (value.Count < num2)
{
return false;
}
configValueCache.Remove(text2);
package = new ZPackage(value.Values.SelectMany((byte[] a) => a).ToArray());
b = package.ReadByte();
}
ProcessingServerUpdate = true;
if ((b & 4u) != 0)
{
byte[] buffer = package.ReadByteArray();
MemoryStream stream = new MemoryStream(buffer);
MemoryStream memoryStream = new MemoryStream();
using (DeflateStream deflateStream = new DeflateStream(stream, CompressionMode.Decompress))
{
deflateStream.CopyTo(memoryStream);
}
package = new ZPackage(memoryStream.ToArray());
b = package.ReadByte();
}
if ((b & 1) == 0)
{
resetConfigsFromServer();
}
ParsedConfigs parsedConfigs = ReadConfigsFromPackage(package);
ConfigFile val2 = null;
bool saveOnConfigSet = false;
foreach (KeyValuePair<OwnConfigEntryBase, object> configValue in parsedConfigs.configValues)
{
if (!isServer && configValue.Key.LocalBaseValue == null)
{
configValue.Key.LocalBaseValue = configValue.Key.BaseConfig.BoxedValue;
}
if (val2 == null)
{
val2 = configValue.Key.BaseConfig.ConfigFile;
saveOnConfigSet = val2.SaveOnConfigSet;
val2.SaveOnConfigSet = false;
}
configValue.Key.BaseConfig.BoxedValue = configValue.Value;
}
if (val2 != null)
{
val2.SaveOnConfigSet = saveOnConfigSet;
val2.Save();
}
foreach (KeyValuePair<CustomSyncedValueBase, object> customValue in parsedConfigs.customValues)
{
if (!isServer)
{
CustomSyncedValueBase key2 = customValue.Key;
if (key2.LocalBaseValue == null)
{
key2.LocalBaseValue = customValue.Key.BoxedValue;
}
}
customValue.Key.BoxedValue = customValue.Value;
}
Debug.Log((object)string.Format("Received {0} configs and {1} custom values from {2} for mod {3}", parsedConfigs.configValues.Count, parsedConfigs.customValues.Count, (isServer || clientUpdate) ? $"client {sender}" : "the server", DisplayName ?? Name));
if (!isServer)
{
serverLockedSettingChanged();
}
return true;
}
finally
{
ProcessingServerUpdate = false;
}
}
private ParsedConfigs ReadConfigsFromPackage(ZPackage package)
{
ParsedConfigs parsedConfigs = new ParsedConfigs();
Dictionary<string, OwnConfigEntryBase> dictionary = allConfigs.Where((OwnConfigEntryBase c) => c.SynchronizedConfig).ToDictionary((OwnConfigEntryBase c) => c.BaseConfig.Definition.Section + "_" + c.BaseConfig.Definition.Key, (OwnConfigEntryBase c) => c);
Dictionary<string, CustomSyncedValueBase> dictionary2 = allCustomValues.ToDictionary((CustomSyncedValueBase c) => c.Identifier, (CustomSyncedValueBase c) => c);
int num = package.ReadInt();
for (int i = 0; i < num; i++)
{
string text = package.ReadString();
string text2 = package.ReadString();
string text3 = package.ReadString();
Type type = Type.GetType(text3);
if (text3 == "" || type != null)
{
object obj;
try
{
obj = ((text3 == "") ? null : ReadValueWithTypeFromZPackage(package, type));
}
catch (InvalidDeserializationTypeException ex)
{
Debug.LogWarning((object)("Got unexpected struct internal type " + ex.received + " for field " + ex.field + " struct " + text3 + " for " + text2 + " in section " + text + " for mod " + (DisplayName ?? Name) + ", expecting " + ex.expected));
continue;
}
OwnConfigEntryBase value2;
if (text == "Internal")
{
CustomSyncedValueBase value;
if (text2 == "serverversion")
{
if (obj?.ToString() != CurrentVersion)
{
Debug.LogWarning((object)("Received server version is not equal: server version = " + (obj?.ToString() ?? "null") + "; local version = " + (CurrentVersion ?? "unknown")));
}
}
else if (text2 == "lockexempt")
{
if (obj is bool flag)
{
lockExempt = flag;
}
}
else if (dictionary2.TryGetValue(text2, out value))
{
if ((text3 == "" && (!value.Type.IsValueType || Nullable.GetUnderlyingType(value.Type) != null)) || GetZPackageTypeString(value.Type) == text3)
{
parsedConfigs.customValues[value] = obj;
continue;
}
Debug.LogWarning((object)("Got unexpected type " + text3 + " for internal value " + text2 + " for mod " + (DisplayName ?? Name) + ", expecting " + value.Type.AssemblyQualifiedName));
}
}
else if (dictionary.TryGetValue(text + "_" + text2, out value2))
{
Type type2 = configType(value2.BaseConfig);
if ((text3 == "" && (!type2.IsValueType || Nullable.GetUnderlyingType(type2) != null)) || GetZPackageTypeString(type2) == text3)
{
parsedConfigs.configValues[value2] = obj;
continue;
}
Debug.LogWarning((object)("Got unexpected type " + text3 + " for " + text2 + " in section " + text + " for mod " + (DisplayName ?? Name) + ", expecting " + type2.AssemblyQualifiedName));
}
else
{
Debug.LogWarning((object)("Received unknown config entry " + text2 + " in section " + text + " for mod " + (DisplayName ?? Name) + ". This may happen if client and server versions of the mod do not match."));
}
continue;
}
Debug.LogWarning((object)("Got invalid type " + text3 + ", abort reading of received configs"));
return new ParsedConfigs();
}
return parsedConfigs;
}
private static bool isWritableConfig(OwnConfigEntryBase config)
{
OwnConfigEntryBase config2 = config;
ConfigSync configSync = configSyncs.FirstOrDefault((ConfigSync cs) => cs.allConfigs.Contains(config2));
if (configSync == null)
{
return true;
}
return configSync.IsSourceOfTruth || !config2.SynchronizedConfig || config2.LocalBaseValue == null || (!configSync.IsLocked && (config2 != configSync.lockedConfig || lockExempt));
}
private void serverLockedSettingChanged()
{
foreach (OwnConfigEntryBase allConfig in allConfigs)
{
configAttribute<ConfigurationManagerAttributes>(allConfig.BaseConfig).ReadOnly = !isWritableConfig(allConfig);
}
}
private void resetConfigsFromServer()
{
ConfigFile val = null;
bool saveOnConfigSet = false;
foreach (OwnConfigEntryBase item in allConfigs.Where((OwnConfigEntryBase config) => config.LocalBaseValue != null))
{
if (val == null)
{
val = item.BaseConfig.ConfigFile;
saveOnConfigSet = val.SaveOnConfigSet;
val.SaveOnConfigSet = false;
}
item.BaseConfig.BoxedValue = item.LocalBaseValue;
item.LocalBaseValue = null;
}
if (val != null)
{
val.SaveOnConfigSet = saveOnConfigSet;
}
foreach (CustomSyncedValueBase item2 in allCustomValues.Where((CustomSyncedValueBase config) => config.LocalBaseValue != null))
{
item2.BoxedValue = item2.LocalBaseValue;
item2.LocalBaseValue = null;
}
lockedConfigChanged -= serverLockedSettingChanged;
serverLockedSettingChanged();
}
private IEnumerator<bool> distributeConfigToPeers(ZNetPeer peer, ZPackage package)
{
ZNetPeer peer2 = peer;
ZRoutedRpc rpc = ZRoutedRpc.instance;
if (rpc == null)
{
yield break;
}
byte[] data = package.GetArray();
if (data != null && data.LongLength > 250000)
{
int fragments = (int)(1 + (data.LongLength - 1) / 250000);
long packageIdentifier = ++packageCounter;
int fragment = 0;
while (fragment < fragments)
{
foreach (bool item in waitForQueue())
{
yield return item;
}
if (peer2.m_socket.IsConnected())
{
ZPackage fragmentedPackage = new ZPackage();
fragmentedPackage.Write((byte)2);
fragmentedPackage.Write(packageIdentifier);
fragmentedPackage.Write(fragment);
fragmentedPackage.Write(fragments);
fragmentedPackage.Write(data.Skip(250000 * fragment).Take(250000).ToArray());
SendPackage(fragmentedPackage);
if (fragment != fragments - 1)
{
yield return true;
}
int num = fragment + 1;
fragment = num;
continue;
}
break;
}
yield break;
}
foreach (bool item2 in waitForQueue())
{
yield return item2;
}
SendPackage(package);
void SendPackage(ZPackage pkg)
{
string text = Name + " ConfigSync";
if (isServer)
{
peer2.m_rpc.Invoke(text, new object[1] { pkg });
}
else
{
rpc.InvokeRoutedRPC(peer2.m_server ? 0 : peer2.m_uid, text, new object[1] { pkg });
}
}
IEnumerable<bool> waitForQueue()
{
float timeout = Time.time + 30f;
while (peer2.m_socket.GetSendQueueSize() > 20000)
{
if (Time.time > timeout)
{
Debug.Log((object)$"Disconnecting {peer2.m_uid} after 30 seconds config sending timeout");
peer2.m_rpc.Invoke("Error", new object[1] { (object)(ConnectionStatus)5 });
ZNet.instance.Disconnect(peer2);
break;
}
yield return false;
}
}
}
private IEnumerator sendZPackage(long target, ZPackage package)
{
if (!Object.op_Implicit((Object)(object)ZNet.instance))
{
return Enumerable.Empty<object>().GetEnumerator();
}
List<ZNetPeer> list = (List<ZNetPeer>)AccessTools.DeclaredField(typeof(ZRoutedRpc), "m_peers").GetValue(ZRoutedRpc.instance);
if (target != ZRoutedRpc.Everybody)
{
list = list.Where((ZNetPeer p) => p.m_uid == target).ToList();
}
return sendZPackage(list, package);
}
private IEnumerator sendZPackage(List<ZNetPeer> peers, ZPackage package)
{
ZPackage package2 = package;
if (!Object.op_Implicit((Object)(object)ZNet.instance))
{
yield break;
}
byte[] rawData = package2.GetArray();
if (rawData != null && rawData.LongLength > 10000)
{
ZPackage compressedPackage = new ZPackage();
compressedPackage.Write((byte)4);
MemoryStream output = new MemoryStream();
using (DeflateStream deflateStream = new DeflateStream(output, CompressionLevel.Optimal))
{
deflateStream.Write(rawData, 0, rawData.Length);
}
compressedPackage.Write(output.ToArray());
package2 = compressedPackage;
}
List<IEnumerator<bool>> writers = (from peer in peers
where peer.IsReady()
select peer into p
select distributeConfigToPeers(p, package2)).ToList();
writers.RemoveAll((IEnumerator<bool> writer) => !writer.MoveNext());
while (writers.Count > 0)
{
yield return null;
writers.RemoveAll((IEnumerator<bool> writer) => !writer.MoveNext());
}
}
private void Broadcast(long target, params ConfigEntryBase[] configs)
{
if (!IsLocked || isServer)
{
ZPackage package = ConfigsToPackage(configs);
ZNet instance = ZNet.instance;
if (instance != null)
{
((MonoBehaviour)instance).StartCoroutine(sendZPackage(target, package));
}
}
}
private void Broadcast(long target, params CustomSyncedValueBase[] customValues)
{
if (!IsLocked || isServer)
{
ZPackage package = ConfigsToPackage(null, customValues);
ZNet instance = ZNet.instance;
if (instance != null)
{
((MonoBehaviour)instance).StartCoroutine(sendZPackage(target, package));
}
}
}
private static OwnConfigEntryBase? configData(ConfigEntryBase config)
{
return config.Description.Tags?.OfType<OwnConfigEntryBase>().SingleOrDefault();
}
public static SyncedConfigEntry<T>? ConfigData<T>(ConfigEntry<T> config)
{
return ((ConfigEntryBase)config).Description.Tags?.OfType<SyncedConfigEntry<T>>().SingleOrDefault();
}
private static T configAttribute<T>(ConfigEntryBase config)
{
return config.Description.Tags.OfType<T>().First();
}
private static Type configType(ConfigEntryBase config)
{
return configType(config.SettingType);
}
private static Type configType(Type type)
{
return type.IsEnum ? Enum.GetUnderlyingType(type) : type;
}
private static ZPackage ConfigsToPackage(IEnumerable<ConfigEntryBase>? configs = null, IEnumerable<CustomSyncedValueBase>? customValues = null, IEnumerable<PackageEntry>? packageEntries = null, bool partial = true)
{
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Expected O, but got Unknown
List<ConfigEntryBase> list = configs?.Where((ConfigEntryBase config) => configData(config).SynchronizedConfig).ToList() ?? new List<ConfigEntryBase>();
List<CustomSyncedValueBase> list2 = customValues?.ToList() ?? new List<CustomSyncedValueBase>();
ZPackage val = new ZPackage();
val.Write((byte)(partial ? 1 : 0));
val.Write(list.Count + list2.Count + (packageEntries?.Count() ?? 0));
foreach (PackageEntry item in packageEntries ?? Array.Empty<PackageEntry>())
{
AddEntryToPackage(val, item);
}
foreach (CustomSyncedValueBase item2 in list2)
{
AddEntryToPackage(val, new PackageEntry
{
section = "Internal",
key = item2.Identifier,
type = item2.Type,
value = item2.BoxedValue
});
}
foreach (ConfigEntryBase item3 in list)
{
AddEntryToPackage(val, new PackageEntry
{
section = item3.Definition.Section,
key = item3.Definition.Key,
type = configType(item3),
value = item3.BoxedValue
});
}
return val;
}
private static void AddEntryToPackage(ZPackage package, PackageEntry entry)
{
package.Write(entry.section);
package.Write(entry.key);
package.Write((entry.value == null) ? "" : GetZPackageTypeString(entry.type));
AddValueToZPackage(package, entry.value);
}
private static string GetZPackageTypeString(Type type)
{
return type.AssemblyQualifiedName;
}
private static void AddValueToZPackage(ZPackage package, object? value)
{
Type type = value?.GetType();
if (value is Enum)
{
value = ((IConvertible)value).ToType(Enum.GetUnderlyingType(value.GetType()), CultureInfo.InvariantCulture);
}
else
{
if (value is ICollection collection)
{
package.Write(collection.Count);
{
foreach (object item in collection)
{
AddValueToZPackage(package, item);
}
return;
}
}
if ((object)type != null && type.IsValueType && !type.IsPrimitive)
{
FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
package.Write(fields.Length);
FieldInfo[] array = fields;
foreach (FieldInfo fieldInfo in array)
{
package.Write(GetZPackageTypeString(fieldInfo.FieldType));
AddValueToZPackage(package, fieldInfo.GetValue(value));
}
return;
}
}
ZRpc.Serialize(new object[1] { value }, ref package);
}
private static object ReadValueWithTypeFromZPackage(ZPackage package, Type type)
{
if ((object)type != null && type.IsValueType && !type.IsPrimitive && !type.IsEnum)
{
FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
int num = package.ReadInt();
if (num != fields.Length)
{
throw new InvalidDeserializationTypeException
{
received = $"(field count: {num})",
expected = $"(field count: {fields.Length})"
};
}
object uninitializedObject = FormatterServices.GetUninitializedObject(type);
FieldInfo[] array = fields;
foreach (FieldInfo fieldInfo in array)
{
string text = package.ReadString();
if (text != GetZPackageTypeString(fi