using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using HarmonyLib; using JetBrains.Annotations; using LocalizationManager; using LongshipUpgrades; using Microsoft.CodeAnalysis; using ServerSync; using Splatform; using TMPro; using UnityEngine; using YamlDotNet.Serialization; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("Longship Upgrades")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Longship Upgrades")] [assembly: AssemblyCopyright("Copyright © 2024")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("9273280b-9a2b-4143-a5d8-0723a4036a85")] [assembly: AssemblyFileVersion("1.0.16")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.16.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; } } } namespace LongshipUpgrades { public class LongshipCustomizableParts : MonoBehaviour { public static bool prefabInit = false; private Ship m_ship; private ZNetView m_nview; private ZDO m_zdo; private Container m_container; private bool m_customMast; private WearNTear m_wnt; private GameObject m_beamMast; private GameObject m_beamTent; private GameObject m_beamMesh; private GameObject m_beamTentCollider; private GameObject m_beamSailCollider; private GameObject m_insects; private GameObject m_tent; private GameObject m_lantern; private GameObject m_holdersRight; private GameObject m_holdersLeft; private GameObject m_mastUpgrade; private GameObject m_storageUpgrade; private GameObject m_healthUpgrade; private GameObject m_shieldsStyles; private GameObject m_headStyles; private GameObject m_turrets; private GameObject m_turretsUpgrade; private GameObject m_itemstandObject; private GameObject m_wispUpgrade; private GameObject m_mapTableUpgrade; private GameObject m_mast; private GameObject m_ropes; private GameObject m_sail; private GameObject m_wisp; private GameObject m_mapTable; private MeshRenderer m_lampRenderer; private Light m_light; private ParticleSystem m_flare; private ShipTrophyStand m_trophyStand; private EffectArea m_fireWarmth; private GameObject[] m_containerPartsLvl1; private GameObject[] m_containerPartsLvl2; private GameObject[] m_protectiveParts; private GameObject[] m_heads; private bool m_containerUpgradedLvl1; private bool m_containerUpgradedLvl2; private bool m_healthUpgraded; private bool m_ashlandsUpgraded; private bool m_isLampLightDisabled; private int m_headStyle; private int m_shieldsStyle; private int m_tentStyle; private int m_sailStyle; private GameObject m_destroyedLootPrefab; public const string prefabName = "VikingShip"; public const string turretName = "piece_turret"; public const string moderBossStone = "BossStone_DragonQueen"; public const string wisptorchName = "piece_groundtorch_mist"; public const string mapTablePrefabName = "maptable"; private static bool prefabInitialized = false; public static int prefabInt = StringExtensionMethods.GetStableHashCode("VikingShip"); private static Shader shaderStandard; private static Material standSharedMaterial; private static Material storageSharedMaterial; private static Material plankSharedMaterial; private static GameObject s_lanternPrefab; private static GameObject s_turretPrefab; private static GameObject s_standBossDragonPrefab; private static GameObject s_wisptorchPrefab; private static GameObject s_mapTablePrefab; private static Color flareColor; private static bool isNightTime; private static bool isTimeToLight = true; public static readonly int s_mastUpgraded = StringExtensionMethods.GetStableHashCode("MastUpgraded"); public static readonly int s_mastRemoved = StringExtensionMethods.GetStableHashCode("MastRemoved"); public static readonly int s_lanternUpgraded = StringExtensionMethods.GetStableHashCode("LanternUpgraded"); public static readonly int s_lanternDisabled = StringExtensionMethods.GetStableHashCode("LanternDisabled"); public static readonly int s_tentUpgraded = StringExtensionMethods.GetStableHashCode("TentUpgraded"); public static readonly int s_tentDisabled = StringExtensionMethods.GetStableHashCode("TentDisabled"); public static readonly int s_lightsDisabled = StringExtensionMethods.GetStableHashCode("LightDisabled"); public static readonly int s_wispUpgraded = StringExtensionMethods.GetStableHashCode("WispUpgraded"); public static readonly int s_wispRemoved = StringExtensionMethods.GetStableHashCode("WispRemoved"); public static readonly int s_mapTableUpgraded = StringExtensionMethods.GetStableHashCode("MapTableUpgraded"); public static readonly int s_mapDataCompressed = StringExtensionMethods.GetStableHashCode("MapDataCompressed"); public static readonly int s_containerUpgradedLvl1 = StringExtensionMethods.GetStableHashCode("ContainerUpgradedLvl1"); public static readonly int s_containerUpgradedLvl2 = StringExtensionMethods.GetStableHashCode("ContainerUpgradedLvl2"); public static readonly int s_healthUpgraded = StringExtensionMethods.GetStableHashCode("HealthUpgraded"); public static readonly int s_ashlandsUpgraded = StringExtensionMethods.GetStableHashCode("AshlandsUpgraded"); public static readonly int s_turretsUpgraded = StringExtensionMethods.GetStableHashCode("TurretsUpgraded"); public static readonly int s_turretsDisabled = StringExtensionMethods.GetStableHashCode("TurretsDisabled"); public static readonly int s_headStyle = StringExtensionMethods.GetStableHashCode("HeadStyle"); public static readonly int s_shieldsStyle = StringExtensionMethods.GetStableHashCode("ShieldsStyle"); public static readonly int s_tentStyle = StringExtensionMethods.GetStableHashCode("TentStyle"); public static readonly int s_sailStyle = StringExtensionMethods.GetStableHashCode("SailStyle"); public bool blocksIsDirty; public readonly Dictionary s_propertyBlocks = new Dictionary(); public static Texture2D s_ashlandsHull = new Texture2D(2, 2); public static Texture2D s_ashlandsHullDamaged = new Texture2D(2, 2); public const int piece_nonsolid = 16; public const int vehicle = 28; public static List customTents = new List(); public static List customSails = new List(); public static List customShields = new List(); private static readonly Dictionary buildEffects = new Dictionary(); public static EffectList partEffects = new EffectList(); public const int fabricSwitch = 0; public const int woodSwitch = 1; public const int lampEnable = 2; public const int lampDisable = 3; public const int turretsEnable = 4; public const int turretsDisable = 5; public const int wisptorchEnable = 6; private static readonly Dictionary s_allInstances = new Dictionary(); private static readonly List s_fireResistantModifiers = new List { new DamageModPair { m_type = (DamageType)32, m_modifier = (DamageModifier)5 } }; private static readonly int s_shipMapDataRevision = StringExtensionMethods.GetStableHashCode("ShipMapDataRevision"); private float m_nextShipMapDataRequestTime; private int m_lastRequestedShipMapRevision; private void Awake() { if (prefabInit) { return; } m_ship = ((Component)this).GetComponent(); m_wnt = ((Component)this).GetComponent(); m_nview = ((Component)this).GetComponent(); ZNetView nview = m_nview; m_zdo = ((nview != null) ? nview.GetZDO() : null); ((Behaviour)this).enabled = m_nview.IsValid(); if (((Behaviour)this).enabled) { m_nview.Register("SetVariant", (Method)RPC_SetVariant); m_nview.Register("SetActive", (Method)RPC_SetActive); m_nview.Register("SetBuilt", (Action)RPC_SetBuilt); } m_lastRequestedShipMapRevision = 0; m_container = (from container in ((Component)this).GetComponentsInChildren() where ((Object)((Component)container).gameObject).name == "piece_chest" select container).FirstOrDefault(); m_destroyedLootPrefab = m_container?.m_destroyedLootPrefab; if (Object.op_Implicit((Object)(object)m_wnt)) { m_wnt.m_onDestroyed = (Action)Delegate.Combine(m_wnt.m_onDestroyed, new Action(OnDestroyed)); } if (buildEffects.Count == 0) { ObjectDB instance = ObjectDB.instance; if (instance != null) { CollectionExtensions.Do(instance.m_recipes.Where((Recipe recipe) => (Object)(object)recipe.m_craftingStation != (Object)null && recipe.m_craftingStation.m_craftItemEffects.HasEffects()), (Action)delegate(Recipe recipe) { buildEffects[recipe.m_craftingStation.m_name] = recipe.m_craftingStation.m_craftItemEffects; }); } } CheckEffects(); GetHildirMapTable(); s_allInstances.Add(((Component)this).gameObject, this); } private void Start() { if (!prefabInit) { InitializeParts(); } } public void OnDestroy() { if (!prefabInit) { s_allInstances.Remove(((Component)this).gameObject); } } private void FixedUpdate() { //IL_03b1: Unknown result type (might be due to invalid IL or missing references) //IL_05e6: Unknown result type (might be due to invalid IL or missing references) //IL_061a: Unknown result type (might be due to invalid IL or missing references) //IL_064e: Unknown result type (might be due to invalid IL or missing references) //IL_0682: Unknown result type (might be due to invalid IL or missing references) if (prefabInit || m_zdo == null || !Object.op_Implicit((Object)(object)m_ship)) { return; } RequestMissingShipMapData(); m_customMast = LongshipUpgrades.mastEnabled.Value && m_zdo.GetBool(s_mastUpgraded, false); GameObject mastUpgrade = m_mastUpgrade; if (mastUpgrade != null) { mastUpgrade.SetActive((LongshipUpgrades.mastEnabled.Value && !m_customMast) || LongshipUpgrades.mastRemovable.Value); } GameObject mast = m_mast; if (mast != null) { mast.SetActive(!m_zdo.GetBool(s_mastRemoved, false)); } GameObject ropes = m_ropes; if (ropes != null) { ropes.SetActive(m_mast.activeSelf); } GameObject wisp = m_wisp; if (wisp != null) { wisp.SetActive(LongshipUpgrades.wispEnabled.Value && m_mast.activeSelf && m_zdo.GetBool(s_wispUpgraded, false) && !m_zdo.GetBool(s_wispRemoved, false)); } GameObject mapTable = m_mapTable; if (mapTable != null) { mapTable.SetActive(LongshipUpgrades.mapTableEnabled.Value && m_zdo.GetBool(s_mapTableUpgraded, false)); } GameObject beamTent = m_beamTent; if (beamTent != null) { beamTent.SetActive(m_customMast && (LongshipUpgrades.lanternEnabled.Value || LongshipUpgrades.tentEnabled.Value)); } GameObject beamMast = m_beamMast; if (beamMast != null) { beamMast.SetActive(!m_mast.activeSelf && (Object)(object)m_beamTent != (Object)null && m_beamTent.activeInHierarchy); } GameObject beamSailCollider = m_beamSailCollider; if (beamSailCollider != null) { beamSailCollider.SetActive((!Object.op_Implicit((Object)(object)m_beamMast) || !m_beamMast.activeSelf) && m_mast.activeSelf); } GameObject wispUpgrade = m_wispUpgrade; if (wispUpgrade != null) { wispUpgrade.SetActive(LongshipUpgrades.wispEnabled.Value && m_mast.activeSelf); } GameObject mapTableUpgrade = m_mapTableUpgrade; if (mapTableUpgrade != null) { mapTableUpgrade.SetActive(LongshipUpgrades.mapTableEnabled.Value && !m_mapTable.activeSelf); } GameObject tent = m_tent; if (tent != null) { tent.SetActive(m_customMast && LongshipUpgrades.tentEnabled.Value && m_zdo.GetBool(s_tentUpgraded, false) && !m_zdo.GetBool(s_tentDisabled, false)); } GameObject lantern = m_lantern; if (lantern != null) { lantern.SetActive(LongshipUpgrades.lanternEnabled.Value && m_customMast && m_zdo.GetBool(s_lanternUpgraded, false) && !m_zdo.GetBool(s_lanternDisabled, false)); } GameObject holdersRight = m_holdersRight; if (holdersRight != null) { holdersRight.SetActive(IsTentActive()); } GameObject holdersLeft = m_holdersLeft; if (holdersLeft != null) { holdersLeft.SetActive(IsTentActive()); } if (Object.op_Implicit((Object)(object)m_fireWarmth) && m_fireWarmth.m_isHeatType != (m_fireWarmth.m_isHeatType = LongshipUpgrades.tentHeat.Value && Object.op_Implicit((Object)(object)m_lantern) && m_lantern.activeInHierarchy && IsTentActive())) { m_fireWarmth.m_type = (Type)(m_fireWarmth.m_isHeatType ? 3 : 0); if (Object.op_Implicit((Object)(object)Player.m_localPlayer)) { if (m_fireWarmth.m_isHeatType && !m_fireWarmth.m_collidedWithCharacter.Contains((Character)(object)Player.m_localPlayer)) { m_fireWarmth.m_collidedWithCharacter.Add((Character)(object)Player.m_localPlayer); } else if (!m_fireWarmth.m_isHeatType && m_fireWarmth.m_collidedWithCharacter.Contains((Character)(object)Player.m_localPlayer)) { m_fireWarmth.m_collidedWithCharacter.Remove((Character)(object)Player.m_localPlayer); } } } GameObject turretsUpgrade = m_turretsUpgrade; if (turretsUpgrade != null) { turretsUpgrade.SetActive(LongshipUpgrades.turretsEnabled.Value); } GameObject turrets = m_turrets; if (turrets != null) { turrets.SetActive(LongshipUpgrades.turretsEnabled.Value && m_zdo.GetBool(s_turretsUpgraded, false)); } GameObject itemstandObject = m_itemstandObject; if (itemstandObject != null) { itemstandObject.SetActive(LongshipUpgrades.itemStandEnabled.Value); } bool flag = false; if ((Object)(object)m_light != (Object)null && Object.op_Implicit((Object)(object)m_lantern) && m_lantern.activeInHierarchy && (m_isLampLightDisabled != m_zdo.GetBool(s_lightsDisabled, false) || (flag = isTimeToLight != IsTimeToLight()) || isNightTime != IsNightTime())) { isNightTime = IsNightTime(); isTimeToLight = IsTimeToLight(); if (LongshipUpgrades.lanternAutoSwtich.Value && flag && m_nview.IsValid() && m_nview.IsOwner()) { m_zdo.Set(s_lightsDisabled, !isTimeToLight); } m_isLampLightDisabled = m_zdo.GetBool(s_lightsDisabled, false); UpdateLights(); } if (Object.op_Implicit((Object)(object)m_beamMesh)) { m_beamMesh.transform.localPosition = new Vector3(0f, 0f, IsTentActive() ? 0f : (-0.9f)); m_beamMesh.transform.localScale = new Vector3(1f, 1f, IsTentActive() ? 1f : 0.5f); m_beamTentCollider.transform.localPosition = new Vector3(0f, 1.58f, IsTentActive() ? 0.23f : (-0.49f)); m_beamTentCollider.transform.localScale = new Vector3(0.16f, 0.16f, IsTentActive() ? 2.05f : 0.6f); } if (LongshipUpgrades.containerEnabled.Value && Object.op_Implicit((Object)(object)m_storageUpgrade) && m_containerUpgradedLvl2 != m_zdo.GetBool(s_containerUpgradedLvl2, false)) { m_containerUpgradedLvl2 = m_zdo.GetBool(s_containerUpgradedLvl2, false); GameObject[] containerPartsLvl = m_containerPartsLvl2; if (containerPartsLvl != null) { CollectionExtensions.Do((IEnumerable)containerPartsLvl, (Action)delegate(GameObject part) { if (part != null) { part.SetActive(m_containerUpgradedLvl2); } }); } if (m_containerUpgradedLvl2 && m_container.m_height < LongshipUpgrades.containerHeight.Value) { string name = ((object)m_container).GetType().Name; m_zdo.Set("HasFields", true); m_zdo.Set(StringExtensionMethods.GetStableHashCode("HasFields" + name), true); m_zdo.Set(name + ".m_height", LongshipUpgrades.containerHeight.Value); m_container.m_height = LongshipUpgrades.containerHeight.Value; } if (m_containerUpgradedLvl2 && m_container.GetInventory().GetHeight() < LongshipUpgrades.containerHeight.Value) { string name2 = ((object)m_container.GetInventory()).GetType().Name; m_zdo.Set("HasFields", true); m_zdo.Set(StringExtensionMethods.GetStableHashCode("HasFields" + name2), true); m_zdo.Set(name2 + ".m_height", LongshipUpgrades.containerHeight.Value); m_container.GetInventory().m_height = LongshipUpgrades.containerHeight.Value; } } if (LongshipUpgrades.containerEnabled.Value && Object.op_Implicit((Object)(object)m_storageUpgrade) && m_containerUpgradedLvl1 != m_zdo.GetBool(s_containerUpgradedLvl1, false)) { m_containerUpgradedLvl1 = m_zdo.GetBool(s_containerUpgradedLvl1, false); GameObject[] containerPartsLvl2 = m_containerPartsLvl1; if (containerPartsLvl2 != null) { CollectionExtensions.Do((IEnumerable)containerPartsLvl2, (Action)delegate(GameObject part) { if (part != null) { part.SetActive(m_containerUpgradedLvl1); } }); } if (m_containerUpgradedLvl1 && m_container.m_width < LongshipUpgrades.containerWidth.Value) { m_container.m_width = LongshipUpgrades.containerWidth.Value; string name3 = ((object)m_container).GetType().Name; m_zdo.Set("HasFields", true); m_zdo.Set(StringExtensionMethods.GetStableHashCode("HasFields" + name3), true); m_zdo.Set(name3 + ".m_width", LongshipUpgrades.containerWidth.Value); } if (m_containerUpgradedLvl1 && m_container.GetInventory().GetWidth() < LongshipUpgrades.containerWidth.Value) { m_container.GetInventory().m_width = LongshipUpgrades.containerWidth.Value; string name4 = ((object)m_container.GetInventory()).GetType().Name; m_zdo.Set("HasFields", true); m_zdo.Set(StringExtensionMethods.GetStableHashCode("HasFields" + name4), true); m_zdo.Set(name4 + ".m_width", LongshipUpgrades.containerWidth.Value); } } GameObject storageUpgrade = m_storageUpgrade; if (storageUpgrade != null) { storageUpgrade.SetActive(LongshipUpgrades.containerEnabled.Value && !m_containerUpgradedLvl2); } bool flag2 = false; if (LongshipUpgrades.healthEnabled.Value && m_protectiveParts != null && Object.op_Implicit((Object)(object)m_wnt) && m_healthUpgraded != m_zdo.GetBool(s_healthUpgraded, false)) { m_healthUpgraded = m_zdo.GetBool(s_healthUpgraded, false); CollectionExtensions.Do((IEnumerable)m_protectiveParts, (Action)delegate(GameObject part) { if (part != null) { part.SetActive(m_healthUpgraded); } }); if (m_healthUpgraded && m_wnt.m_health < (float)LongshipUpgrades.healthUpgradeLvl1.Value) { m_wnt.m_health = LongshipUpgrades.healthUpgradeLvl1.Value; flag2 = true; } } if (LongshipUpgrades.healthEnabled.Value && Object.op_Implicit((Object)(object)m_wnt)) { if (m_ashlandsUpgraded != (m_ashlandsUpgraded = m_zdo.GetBool(s_ashlandsUpgraded, false))) { if (m_ashlandsUpgraded && LongshipUpgrades.healthUpgradeLvl2.Value > 0 && m_wnt.m_health < (float)LongshipUpgrades.healthUpgradeLvl2.Value) { m_wnt.m_health = LongshipUpgrades.healthUpgradeLvl2.Value; flag2 = true; } string name5 = ((object)m_ship).GetType().Name; m_zdo.Set("HasFields", true); m_zdo.Set(StringExtensionMethods.GetStableHashCode("HasFields" + name5), true); m_zdo.Set(name5 + ".m_ashlandsReady", true); name5 = ((object)m_wnt).GetType().Name; m_zdo.Set(StringExtensionMethods.GetStableHashCode("HasFields" + name5), true); m_zdo.Set(name5 + ".m_ashDamageResist", true); m_zdo.Set(name5 + ".m_burnable", false); UpdateHullPropertyBlocks(); } if (m_ashlandsUpgraded && LongshipUpgrades.ashlandsProtection.Value) { m_ship.m_ashlandsReady = true; m_ship.m_ashlandsDmgTimer = 0f; if (m_ship.m_ashdamageEffects.activeSelf) { m_ship.m_ashdamageEffects.SetActive(false); CollectionExtensions.Do((IEnumerable)m_ship.m_ashlandsFxAudio, (Action)delegate(AudioSource item) { item.Stop(); }); } if (!m_wnt.m_ashDamageResist) { m_wnt.m_ashDamageResist = true; m_wnt.m_burnable = false; ((DamageModifiers)(ref m_wnt.m_damages)).Apply(s_fireResistantModifiers); } } } if (flag2 && m_nview.IsValid() && m_nview.IsOwner()) { m_nview.InvokeRPC(ZNetView.Everybody, "RPC_HealthChanged", new object[1] { m_nview.GetZDO().GetFloat(ZDOVars.s_health, m_wnt.m_health) }); } GameObject healthUpgrade = m_healthUpgrade; if (healthUpgrade != null) { healthUpgrade.SetActive(LongshipUpgrades.healthEnabled.Value && !m_ashlandsUpgraded); } if (LongshipUpgrades.changeShields.Value && LongshipUpgrades.healthEnabled.Value && m_protectiveParts != null && m_healthUpgraded && m_shieldsStyle != m_zdo.GetInt(s_shieldsStyle, 0)) { m_shieldsStyle = m_zdo.GetInt(s_shieldsStyle, 0); if (LongshipUpgrades.maxShields.Value != 0 && m_shieldsStyle > LongshipUpgrades.maxShields.Value && m_nview.IsValid() && m_nview.IsOwner()) { m_shieldsStyle %= LongshipUpgrades.maxShields.Value; m_zdo.Set(s_shieldsStyle, m_shieldsStyle, false); } UpdateShieldsPropertyBlocks(); } GameObject shieldsStyles = m_shieldsStyles; if (shieldsStyles != null) { shieldsStyles.SetActive(m_healthUpgraded); } if (LongshipUpgrades.changeTent.Value && IsTentActive() && m_tentStyle != m_zdo.GetInt(s_tentStyle, 0)) { m_tentStyle = m_zdo.GetInt(s_tentStyle, 0); UpdateTentPropertyBlocks(); } if (LongshipUpgrades.changeSail.Value && (Object)(object)m_sail != (Object)null && m_sail.activeInHierarchy && m_sailStyle != m_zdo.GetInt(s_sailStyle, 0)) { m_sailStyle = m_zdo.GetInt(s_sailStyle, 0); UpdateSailPropertyBlocks(); } if (LongshipUpgrades.changeHead.Value && m_heads != null && Object.op_Implicit((Object)(object)m_wnt) && m_headStyle != m_zdo.GetInt(s_headStyle, 0)) { m_headStyle = m_zdo.GetInt(s_headStyle, 0); for (int i = 0; i < m_heads.Length; i++) { m_heads[i].SetActive(m_headStyle == i + 1); } GameObject[] array = (GameObject[])(object)new GameObject[3] { ((Component)m_wnt.m_new.transform.Find("skull_head")).gameObject, ((Component)m_wnt.m_worn.transform.Find("skull_head")).gameObject, ((Component)m_wnt.m_broken.transform.Find("skull_head")).gameObject }; foreach (GameObject val in array) { val.SetActive(m_headStyle == 0); } } GameObject headStyles = m_headStyles; if (headStyles != null) { headStyles.SetActive(LongshipUpgrades.changeHead.Value); } SetPropertyBlocks(); } public void RPC_SetVariant(long uid, int zdoVar, int variant, int effectVariant, string position) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) if (m_nview.IsValid() && m_nview.IsOwner()) { m_zdo.Set(zdoVar, variant, false); partEffects.Create(ParseVector3(position), Quaternion.identity, (Transform)null, 1f, effectVariant); } } public void RPC_SetActive(long uid, int zdoVar, bool active, int effectVariant, string position) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) if (m_nview.IsValid() && m_nview.IsOwner()) { m_zdo.Set(zdoVar, active); partEffects.Create(ParseVector3(position), Quaternion.identity, (Transform)null, 1f, effectVariant); } } public void RPC_SetBuilt(long uid, int zdoVar, string stationName, string position) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) if (!m_nview.IsValid() || !m_nview.IsOwner()) { return; } m_zdo.Set(zdoVar, true); if (!string.IsNullOrWhiteSpace(stationName)) { EffectList obj = buildEffects[stationName]; if (obj != null) { obj.Create(ParseVector3(position), Quaternion.identity, (Transform)null, 1f, -1); } } } private void RequestMissingShipMapData() { //IL_0060: Unknown result type (might be due to invalid IL or missing references) if (!m_zdo.GetBool(s_mapTableUpgraded, false) || !m_zdo.GetBool(s_mapDataCompressed, false)) { return; } int @int = m_zdo.GetInt(s_shipMapDataRevision, 0); if (@int > 0) { if (LongshipUpgrades.TryGetShipMapData(m_zdo.m_uid, out var entry) && entry.Data != null && entry.Revision >= @int) { m_lastRequestedShipMapRevision = 0; } else if (!(Time.time < m_nextShipMapDataRequestTime) || m_lastRequestedShipMapRevision != @int) { m_lastRequestedShipMapRevision = @int; m_nextShipMapDataRequestTime = Time.time + 2f; LongshipUpgrades.RequestShipMapDataFromServer(m_zdo, @int); } } } private void UpdateSailPropertyBlocks() { GameObject sail = m_sail; Renderer val = ((sail != null) ? sail.GetComponentInChildren() : null); if (!((Object)(object)val == (Object)null)) { if (m_sailStyle == 0 || customSails.Count == 0) { ResetPropertyBlock(val); } else { SetPropertyBlock(val, ShaderProps._MainTex, customSails[(m_sailStyle - 1) % ((LongshipUpgrades.maxSails.Value == 0) ? customSails.Count : Math.Min(LongshipUpgrades.maxSails.Value, customSails.Count))]); } } } private void UpdateTentPropertyBlocks() { GameObject tent = m_tent; Renderer val = ((tent != null) ? tent.GetComponentInChildren() : null); if (!((Object)(object)val == (Object)null)) { if (m_tentStyle == 0 || customTents.Count == 0) { ResetPropertyBlock(val); } else { SetPropertyBlock(val, ShaderProps._MainTex, customTents[(m_tentStyle - 1) % ((LongshipUpgrades.maxTents.Value == 0) ? customTents.Count : Math.Min(LongshipUpgrades.maxTents.Value, customTents.Count))]); } } } private void UpdateHullPropertyBlocks() { if (!m_ashlandsUpgraded || LongshipUpgrades.healthUpgradeLvl2.Value <= 0 || !LongshipUpgrades.ashlandsProtection.Value) { return; } foreach (Renderer item in new List { ((Component)m_wnt.m_new.transform.Find("hull")).gameObject.GetComponent(), ((Component)m_wnt.m_new.transform.Find("skull_head")).gameObject.GetComponent() }) { SetPropertyBlock(item, ShaderProps._MainTex, s_ashlandsHull); } foreach (Renderer item2 in new List { ((Component)m_wnt.m_worn.transform.Find("hull")).gameObject.GetComponent(), ((Component)m_wnt.m_broken.transform.Find("hull")).gameObject.GetComponent(), ((Component)m_wnt.m_worn.transform.Find("skull_head")).gameObject.GetComponent(), ((Component)m_wnt.m_broken.transform.Find("skull_head")).gameObject.GetComponent() }) { SetPropertyBlock(item2, ShaderProps._MainTex, s_ashlandsHullDamaged); } if (m_heads == null) { return; } foreach (Renderer item3 in m_heads.Select((GameObject head) => head.GetComponent())) { SetPropertyBlock(item3, ShaderProps._MainTex, s_ashlandsHull); } } private void UpdateShieldsPropertyBlocks() { if (!LongshipUpgrades.changeShields.Value || !LongshipUpgrades.healthEnabled.Value || m_protectiveParts == null || !m_healthUpgraded) { return; } int style = ((m_shieldsStyle > 3) ? ((m_shieldsStyle - 1) % 3 + 1) : m_shieldsStyle); int num = ((m_shieldsStyle > 3) ? ((m_shieldsStyle - 4) / 3) : (-1)); foreach (Renderer item in m_protectiveParts.Select((GameObject head) => head.GetComponent())) { ResetPropertyBlock(item); SetPropertyBlock(item, ShaderProps._Style, style); if (-1 < num && num < customShields.Count) { SetPropertyBlock(item, LongshipPropertyBlocks._StyleTex, customShields[num]); } } } private void UpdatePropertyBlocks() { CollectionExtensions.Do((IEnumerable)s_propertyBlocks.Keys, (Action)delegate(Renderer renderer) { renderer.SetPropertyBlock((MaterialPropertyBlock)null); }); s_propertyBlocks.Clear(); UpdateHullPropertyBlocks(); UpdateShieldsPropertyBlocks(); UpdateTentPropertyBlocks(); UpdateSailPropertyBlocks(); SetPropertyBlocks(); } private void UpdateLights() { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) GameObject insects = m_insects; if (insects != null) { insects.SetActive(isNightTime && !m_isLampLightDisabled); } if (Object.op_Implicit((Object)(object)m_light)) { ((Component)m_light).gameObject.SetActive(!m_isLampLightDisabled); m_light.color = LongshipUpgrades.lanternLightColor.Value; } Color value = LongshipUpgrades.lanternLightColor.Value; value.a = 0f; if (Object.op_Implicit((Object)(object)m_flare)) { ((Component)m_flare).gameObject.SetActive(!m_isLampLightDisabled); MainModule main = m_flare.main; ((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(Color.Lerp(flareColor, value, 0.5f)); } if (Object.op_Implicit((Object)(object)m_lampRenderer)) { SetPropertyBlock((Renderer)(object)m_lampRenderer, ShaderProps._EmissionColor, m_isLampLightDisabled ? Color.grey : (Color.white + value)); } } private void SetPropertyBlock(Renderer renderer, int nameID, Texture2D tex) { if (!((Object)(object)renderer == (Object)null)) { GetPropertyBlock(renderer).SetTexture(nameID, (Texture)(object)tex); } } private void SetPropertyBlock(Renderer renderer, int nameID, int style) { if (!((Object)(object)renderer == (Object)null)) { GetPropertyBlock(renderer).SetInt(nameID, style); } } private void SetPropertyBlock(Renderer renderer, int nameID, Color color) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)renderer == (Object)null)) { GetPropertyBlock(renderer).SetColor(nameID, color); } } private void ResetPropertyBlock(Renderer renderer) { if (s_propertyBlocks.ContainsKey(renderer)) { renderer.SetPropertyBlock((MaterialPropertyBlock)null); s_propertyBlocks.Remove(renderer); blocksIsDirty = true; } } private MaterialPropertyBlock GetPropertyBlock(Renderer renderer) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown blocksIsDirty = true; if (!s_propertyBlocks.TryGetValue(renderer, out var value)) { value = new MaterialPropertyBlock(); s_propertyBlocks[renderer] = value; } return value; } private void CombinePropertyBlocks(MaterialPropertyBlock propertyBlockToCombine) { //IL_003a: 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) foreach (MaterialPropertyBlock value in s_propertyBlocks.Values) { if (propertyBlockToCombine.HasColor(ShaderProps._Color)) { value.SetColor(ShaderProps._Color, propertyBlockToCombine.GetColor(ShaderProps._Color)); blocksIsDirty = true; } if (propertyBlockToCombine.HasColor(ShaderProps._EmissionColor)) { value.SetColor(ShaderProps._EmissionColor, propertyBlockToCombine.GetColor(ShaderProps._EmissionColor)); blocksIsDirty = true; } } SetPropertyBlocks(); } private void SetPropertyBlocks() { if (blocksIsDirty) { CollectionExtensions.Do>((IEnumerable>)s_propertyBlocks, (Action>)delegate(KeyValuePair rendererBlock) { rendererBlock.Key.SetPropertyBlock(rendererBlock.Value.isEmpty ? null : rendererBlock.Value); }); } blocksIsDirty = false; } private void InitializeParts() { //IL_0596: Unknown result type (might be due to invalid IL or missing references) //IL_05aa: Unknown result type (might be due to invalid IL or missing references) //IL_05af: Unknown result type (might be due to invalid IL or missing references) //IL_05d4: Unknown result type (might be due to invalid IL or missing references) //IL_05ee: Unknown result type (might be due to invalid IL or missing references) //IL_0602: Unknown result type (might be due to invalid IL or missing references) //IL_0607: Unknown result type (might be due to invalid IL or missing references) //IL_066e: Unknown result type (might be due to invalid IL or missing references) //IL_068a: Unknown result type (might be due to invalid IL or missing references) //IL_06bd: Unknown result type (might be due to invalid IL or missing references) //IL_06d9: Unknown result type (might be due to invalid IL or missing references) //IL_070c: Unknown result type (might be due to invalid IL or missing references) //IL_0728: Unknown result type (might be due to invalid IL or missing references) //IL_075b: Unknown result type (might be due to invalid IL or missing references) //IL_0777: Unknown result type (might be due to invalid IL or missing references) //IL_09ca: Unknown result type (might be due to invalid IL or missing references) //IL_0a13: Unknown result type (might be due to invalid IL or missing references) //IL_0a2f: Unknown result type (might be due to invalid IL or missing references) //IL_0a4b: Unknown result type (might be due to invalid IL or missing references) //IL_0a7f: Unknown result type (might be due to invalid IL or missing references) //IL_0a9b: Unknown result type (might be due to invalid IL or missing references) //IL_0ab7: Unknown result type (might be due to invalid IL or missing references) //IL_0aeb: Unknown result type (might be due to invalid IL or missing references) //IL_0b07: Unknown result type (might be due to invalid IL or missing references) //IL_0b23: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_0fd8: Unknown result type (might be due to invalid IL or missing references) //IL_0fdf: Expected O, but got Unknown //IL_0c22: Unknown result type (might be due to invalid IL or missing references) //IL_0c27: Unknown result type (might be due to invalid IL or missing references) //IL_0c35: Expected O, but got Unknown //IL_0c4e: Unknown result type (might be due to invalid IL or missing references) //IL_0c58: Unknown result type (might be due to invalid IL or missing references) //IL_0c94: Unknown result type (might be due to invalid IL or missing references) //IL_0cc6: Unknown result type (might be due to invalid IL or missing references) //IL_0ce8: Unknown result type (might be due to invalid IL or missing references) //IL_0ced: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0d67: Unknown result type (might be due to invalid IL or missing references) //IL_0dad: Unknown result type (might be due to invalid IL or missing references) //IL_0dc9: Unknown result type (might be due to invalid IL or missing references) //IL_0de5: Unknown result type (might be due to invalid IL or missing references) //IL_0d03: Unknown result type (might be due to invalid IL or missing references) //IL_0d08: Unknown result type (might be due to invalid IL or missing references) //IL_0d0c: Unknown result type (might be due to invalid IL or missing references) //IL_0d11: Unknown result type (might be due to invalid IL or missing references) //IL_0d15: Unknown result type (might be due to invalid IL or missing references) //IL_0d1a: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_0eda: Unknown result type (might be due to invalid IL or missing references) //IL_0eec: Unknown result type (might be due to invalid IL or missing references) //IL_0ef6: Unknown result type (might be due to invalid IL or missing references) //IL_053d: Unknown result type (might be due to invalid IL or missing references) //IL_103e: Unknown result type (might be due to invalid IL or missing references) //IL_105a: Unknown result type (might be due to invalid IL or missing references) //IL_0e84: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_032c: Unknown result type (might be due to invalid IL or missing references) //IL_0360: Unknown result type (might be due to invalid IL or missing references) //IL_037c: Unknown result type (might be due to invalid IL or missing references) //IL_03da: Unknown result type (might be due to invalid IL or missing references) //IL_04f4: Unknown result type (might be due to invalid IL or missing references) //IL_0512: Unknown result type (might be due to invalid IL or missing references) //IL_0517: Unknown result type (might be due to invalid IL or missing references) //IL_0407: Unknown result type (might be due to invalid IL or missing references) //IL_042f: Unknown result type (might be due to invalid IL or missing references) //IL_045c: Unknown result type (might be due to invalid IL or missing references) //IL_0484: Unknown result type (might be due to invalid IL or missing references) //IL_04ae: Unknown result type (might be due to invalid IL or missing references) //IL_04d8: Unknown result type (might be due to invalid IL or missing references) //IL_1190: Unknown result type (might be due to invalid IL or missing references) //IL_11ac: Unknown result type (might be due to invalid IL or missing references) //IL_11c8: Unknown result type (might be due to invalid IL or missing references) //IL_11ed: Unknown result type (might be due to invalid IL or missing references) //IL_11fc: Unknown result type (might be due to invalid IL or missing references) //IL_1312: Unknown result type (might be due to invalid IL or missing references) //IL_131c: Expected O, but got Unknown //IL_1409: Unknown result type (might be due to invalid IL or missing references) //IL_1413: Expected O, but got Unknown //IL_1454: Unknown result type (might be due to invalid IL or missing references) //IL_1470: Unknown result type (might be due to invalid IL or missing references) //IL_148c: Unknown result type (might be due to invalid IL or missing references) //IL_14c0: Unknown result type (might be due to invalid IL or missing references) //IL_14dc: Unknown result type (might be due to invalid IL or missing references) //IL_14f8: Unknown result type (might be due to invalid IL or missing references) //IL_152c: Unknown result type (might be due to invalid IL or missing references) //IL_1548: Unknown result type (might be due to invalid IL or missing references) //IL_1564: Unknown result type (might be due to invalid IL or missing references) //IL_1598: Unknown result type (might be due to invalid IL or missing references) //IL_15b4: Unknown result type (might be due to invalid IL or missing references) //IL_15d0: Unknown result type (might be due to invalid IL or missing references) //IL_1604: Unknown result type (might be due to invalid IL or missing references) //IL_1620: Unknown result type (might be due to invalid IL or missing references) //IL_163c: Unknown result type (might be due to invalid IL or missing references) //IL_1670: Unknown result type (might be due to invalid IL or missing references) //IL_168c: Unknown result type (might be due to invalid IL or missing references) //IL_16a8: Unknown result type (might be due to invalid IL or missing references) //IL_1770: Unknown result type (might be due to invalid IL or missing references) //IL_1777: Expected O, but got Unknown //IL_18dd: Unknown result type (might be due to invalid IL or missing references) //IL_18f9: Unknown result type (might be due to invalid IL or missing references) //IL_1915: Unknown result type (might be due to invalid IL or missing references) //IL_19f4: Unknown result type (might be due to invalid IL or missing references) //IL_19f9: Unknown result type (might be due to invalid IL or missing references) //IL_1a07: Expected O, but got Unknown //IL_1a47: Unknown result type (might be due to invalid IL or missing references) //IL_1a63: Unknown result type (might be due to invalid IL or missing references) //IL_1b97: Unknown result type (might be due to invalid IL or missing references) //IL_1ba1: Unknown result type (might be due to invalid IL or missing references) //IL_1bc2: Unknown result type (might be due to invalid IL or missing references) //IL_1be3: Unknown result type (might be due to invalid IL or missing references) //IL_1c08: Unknown result type (might be due to invalid IL or missing references) //IL_1c24: Unknown result type (might be due to invalid IL or missing references) //IL_1c5e: Unknown result type (might be due to invalid IL or missing references) //IL_1c7f: Unknown result type (might be due to invalid IL or missing references) //IL_187d: Unknown result type (might be due to invalid IL or missing references) //IL_1d8f: Unknown result type (might be due to invalid IL or missing references) //IL_1d94: Unknown result type (might be due to invalid IL or missing references) //IL_1da2: Expected O, but got Unknown //IL_1e48: Unknown result type (might be due to invalid IL or missing references) //IL_1e52: Unknown result type (might be due to invalid IL or missing references) //IL_1ed4: Unknown result type (might be due to invalid IL or missing references) //IL_1ee1: Unknown result type (might be due to invalid IL or missing references) //IL_1eeb: Unknown result type (might be due to invalid IL or missing references) //IL_1f29: Unknown result type (might be due to invalid IL or missing references) //IL_1f4a: Unknown result type (might be due to invalid IL or missing references) //IL_1f54: Unknown result type (might be due to invalid IL or missing references) //IL_1f75: Unknown result type (might be due to invalid IL or missing references) //IL_1f96: Unknown result type (might be due to invalid IL or missing references) //IL_1fb7: Unknown result type (might be due to invalid IL or missing references) //IL_1e9b: Unknown result type (might be due to invalid IL or missing references) //IL_1ea0: Unknown result type (might be due to invalid IL or missing references) //IL_1eb1: Expected O, but got Unknown //IL_2120: Unknown result type (might be due to invalid IL or missing references) //IL_212a: Unknown result type (might be due to invalid IL or missing references) //IL_214f: Unknown result type (might be due to invalid IL or missing references) //IL_21b6: Unknown result type (might be due to invalid IL or missing references) //IL_21db: Unknown result type (might be due to invalid IL or missing references) //IL_21e0: Unknown result type (might be due to invalid IL or missing references) //IL_2359: Unknown result type (might be due to invalid IL or missing references) //IL_2363: Unknown result type (might be due to invalid IL or missing references) //IL_2388: Unknown result type (might be due to invalid IL or missing references) //IL_23ad: Unknown result type (might be due to invalid IL or missing references) //IL_2429: Unknown result type (might be due to invalid IL or missing references) //IL_2433: Expected O, but got Unknown //IL_2433: Unknown result type (might be due to invalid IL or missing references) //IL_243d: Expected O, but got Unknown //IL_2458: Unknown result type (might be due to invalid IL or missing references) //IL_2462: Expected O, but got Unknown //IL_2462: Unknown result type (might be due to invalid IL or missing references) //IL_246c: Expected O, but got Unknown //IL_24a4: Unknown result type (might be due to invalid IL or missing references) //IL_24ae: Expected O, but got Unknown //IL_24ae: Unknown result type (might be due to invalid IL or missing references) //IL_24b8: Expected O, but got Unknown //IL_24d3: Unknown result type (might be due to invalid IL or missing references) //IL_24dd: Expected O, but got Unknown //IL_24dd: Unknown result type (might be due to invalid IL or missing references) //IL_24e7: Expected O, but got Unknown //IL_2228: Unknown result type (might be due to invalid IL or missing references) //IL_2244: Unknown result type (might be due to invalid IL or missing references) //IL_2520: Unknown result type (might be due to invalid IL or missing references) //IL_253c: Unknown result type (might be due to invalid IL or missing references) //IL_2554: Unknown result type (might be due to invalid IL or missing references) Transform obj = ((Component)this).transform.Find("ship/visual/Mast"); m_mast = ((obj != null) ? ((Component)obj).gameObject : null); Transform obj2 = ((Component)this).transform.Find("ship/visual/ropes"); m_ropes = ((obj2 != null) ? ((Component)obj2).gameObject : null); Transform obj3 = ((Component)this).transform.Find("ship/visual/Mast/Sail/sail_full"); m_sail = ((obj3 != null) ? ((Component)obj3).gameObject : null); Transform val = ((Component)this).transform.Find("ship/visual/Customize"); if (!Object.op_Implicit((Object)(object)val)) { return; } ((Component)val).gameObject.SetActive(true); Transform obj4 = val.Find("ShipTentHolders"); m_holdersRight = ((obj4 != null) ? ((Component)obj4).gameObject : null); Transform obj5 = val.Find("ShipTentHolders (1)"); m_holdersLeft = ((obj5 != null) ? ((Component)obj5).gameObject : null); GameObject holdersRight = m_holdersRight; if (holdersRight != null) { holdersRight.SetActive(false); } GameObject holdersLeft = m_holdersLeft; if (holdersLeft != null) { holdersLeft.SetActive(false); } Transform val2 = val.Find("storage"); if (Object.op_Implicit((Object)(object)val2)) { List list = new List(); List list2 = new List(); List list3 = new List(); for (int j = 0; j < val2.childCount; j++) { GameObject gameObject = ((Component)val2.GetChild(j)).gameObject; if (((Object)gameObject).name.StartsWith("barrel")) { list.Add(gameObject); } else if (((Object)gameObject).name.StartsWith("Shield")) { list3.Add(gameObject); } else { list2.Add(gameObject); } gameObject.SetActive(false); } m_containerPartsLvl1 = list.ToArray(); m_containerPartsLvl2 = list2.ToArray(); m_protectiveParts = list3.ToArray(); State state = Random.state; Random.InitState((int)((ZDOID)(ref m_zdo.m_uid)).ID); for (int k = 0; k < list.Count; k++) { Transform transform = list[k].transform; transform.localEulerAngles += new Vector3(0f, Random.Range(0f, 360f), 0f); switch (k) { case 0: list[k].transform.localPosition = new Vector3(-0.69f, 0.18f, -0.88f); break; case 1: list[k].transform.localPosition = new Vector3(-0.36f, 0.18f, -0.87f); break; } BoxCollider componentInChildren = list[k].GetComponentInChildren(); GameObject gameObject2 = ((Component)componentInChildren).gameObject; Object.Destroy((Object)(object)componentInChildren); gameObject2.AddComponent(); } for (int l = 0; l < list2.Count; l++) { switch (l) { case 0: case 5: { Transform transform2 = new GameObject("ladder_TargetPoint").transform; transform2.SetParent(list2[l].transform, false); transform2.localPosition = new Vector3(0.4f, 0.82f, 0f); transform2.localEulerAngles = new Vector3(0f, 270f, 0f); Ladder val3 = list2[l].AddComponent(); val3.m_useDistance = 1.5f; val3.m_targetPos = transform2; val3.m_name = "$lu_box_name"; continue; } case 1: list2[l].transform.localPosition = new Vector3(0.08f, 0f, -0.45f); break; case 3: list2[l].transform.localPosition = new Vector3(0f, 0f, -0.84f); list2[l].transform.localScale = new Vector3(0.35f, 0.4f, 0.35f); break; case 4: list2[l].transform.localPosition = new Vector3(0.36f, -0.02f, -0.82f); list2[l].transform.localScale = new Vector3(0.35f, 0.4f, 0.35f); break; case 6: list2[l].transform.localPosition = new Vector3(0f, 0.26f, -0.57f); break; case 8: list2[l].transform.localScale = new Vector3(0.35f, 0.4f, 0.35f); break; } Transform transform3 = list2[l].transform; transform3.localEulerAngles += new Vector3(0f, Random.Range(0f, 360f), 0f); } Random.state = state; } Transform val4 = val.Find("ShipTen2_beam"); if (Object.op_Implicit((Object)(object)val4)) { m_beamMast = Object.Instantiate(((Component)val4).gameObject, val4.parent); ((Object)m_beamMast).name = "ShipTen2_mast"; Transform transform4 = m_beamMast.transform; transform4.localEulerAngles += new Vector3(90f, 0.1f, 0f); m_beamMast.transform.localPosition = new Vector3(0.58f, 0.35f, 0f); m_beamMast.SetActive(false); val4.localPosition += new Vector3(0.1f, 0f, 0f); m_beamTent = ((Component)val4).gameObject; m_beamTent.SetActive(false); m_beamMesh = ((Component)((Component)val4).GetComponentInChildren()).gameObject; Transform val5 = AddCollider(m_beamMast.transform, "mast_beam", typeof(BoxCollider)); val5.localPosition = new Vector3(0f, 1.58f, -0.48f); val5.localScale = new Vector3(0.16f, 0.16f, 2.5f); Transform val6 = AddCollider(val4, "lantern_beam", typeof(BoxCollider)); val6.localPosition = new Vector3(0f, 1.58f, -1.41f); val6.localScale = new Vector3(0.16f, 0.16f, 0.8f); Transform val7 = AddCollider(val4, "tent_beam", typeof(BoxCollider)); val7.localPosition = new Vector3(0f, 1.58f, 0.23f); val7.localScale = new Vector3(0.16f, 0.16f, 2.05f); Transform val8 = AddCollider(val4, "sail_beam", typeof(BoxCollider)); val8.localPosition = new Vector3(0f, 1.4f, -0.9f); val8.localScale = new Vector3(0.23f, 0.55f, 0.2f); m_beamTentCollider = ((Component)val7).gameObject; m_beamSailCollider = ((Component)val8).gameObject; if (LongshipUpgrades.lanternEnabled.Value) { LongshipPartController longshipPartController = ((Component)val6).gameObject.AddComponent(); longshipPartController.m_name = "$lu_part_lantern_name"; longshipPartController.m_zdoPartDisabled = (LongshipUpgrades.lanternRemovable.Value ? s_lanternDisabled : 0); longshipPartController.m_messageEnable = "$lu_part_lantern_enable"; longshipPartController.m_enableEffects = 1; longshipPartController.m_messageDisable = "$lu_part_lantern_disable"; longshipPartController.m_disableEffects = 1; longshipPartController.m_nview = m_nview; longshipPartController.m_useDistance = 3f; longshipPartController.AddUpgradeRequirement(s_lanternUpgraded, "$lu_part_lantern_upgrade", LongshipUpgrades.ParseRequirements(LongshipUpgrades.lanternUpgradeRecipe.Value), LongshipUpgrades.lanternStation.Value, LongshipUpgrades.lanternStationLvl.Value, LongshipUpgrades.lanternStationRange.Value); } if (LongshipUpgrades.tentEnabled.Value) { LongshipPartController longshipPartController2 = ((Component)val7).gameObject.AddComponent(); longshipPartController2.m_name = "$lu_part_tent_name"; longshipPartController2.m_zdoPartDisabled = (LongshipUpgrades.tentRemovable.Value ? s_tentDisabled : 0); longshipPartController2.m_messageEnable = "$lu_part_tent_enable"; longshipPartController2.m_enableEffects = 0; longshipPartController2.m_messageDisable = "$lu_part_tent_disable"; longshipPartController2.m_disableEffects = 0; longshipPartController2.m_nview = m_nview; longshipPartController2.m_useDistance = 3f; longshipPartController2.AddUpgradeRequirement(s_tentUpgraded, "$lu_part_tent_upgrade", LongshipUpgrades.ParseRequirements(LongshipUpgrades.tentUpgradeRecipe.Value), LongshipUpgrades.tentStation.Value, LongshipUpgrades.tentStationLvl.Value, LongshipUpgrades.tentStationRange.Value); } if (LongshipUpgrades.changeSail.Value) { LongshipPartController longshipPartController3 = ((Component)val8).gameObject.AddComponent(); longshipPartController3.m_name = "$lu_part_sail_name"; longshipPartController3.m_nview = m_nview; longshipPartController3.m_messageSwitch = "$lu_part_sail_switch"; longshipPartController3.m_zdoPartVariant = s_sailStyle; longshipPartController3.m_variants = customSails.Count + 1; longshipPartController3.m_switchEffects = 0; } } Transform val9 = val.Find("ShipTen2 (1)"); if (Object.op_Implicit((Object)(object)val9)) { m_tent = ((Component)val9).gameObject; Transform transform5 = new GameObject("colliders").transform; transform5.SetParent(m_tent.transform, false); Transform val10 = AddCollider(transform5, "collider_right", typeof(BoxCollider)); val10.localPosition = new Vector3(1.58f, 1.18f, -0.65f); val10.localScale = new Vector3(1.9f, 0.01f, 2.6f); val10.localEulerAngles = new Vector3(0f, 0f, -6f); Transform val11 = AddCollider(transform5, "collider_left", typeof(BoxCollider)); val11.localPosition = new Vector3(-1.05f, 0.95f, -0.65f); val11.localScale = new Vector3(1f, 0.01f, 2.5f); val11.localEulerAngles = new Vector3(0f, 0f, 23f); Transform val12 = AddCollider(transform5, "collider_left (1)", typeof(BoxCollider)); val12.localPosition = new Vector3(-2.1f, 0.7f, -0.55f); val12.localScale = new Vector3(1.15f, 0.01f, 3f); val12.localEulerAngles = new Vector3(0f, 0f, 6f); m_tent.SetActive(false); if (LongshipUpgrades.changeTent.Value) { for (int m = 0; m < transform5.childCount; m++) { LongshipPartController longshipPartController4 = ((Component)transform5.GetChild(m)).gameObject.AddComponent(); longshipPartController4.m_name = "$lu_part_tent_name"; longshipPartController4.m_nview = m_nview; longshipPartController4.m_messageSwitch = "$lu_part_tent_switch"; longshipPartController4.m_zdoPartVariant = s_tentStyle; longshipPartController4.m_variants = customTents.Count + 1; longshipPartController4.m_switchEffects = 0; } } } if (s_lanternPrefab == null) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("Lantern"); object obj6; if (itemPrefab == null) { obj6 = null; } else { Transform obj7 = itemPrefab.transform.Find("attach/equiped"); obj6 = ((obj7 != null) ? ((Component)obj7).gameObject : null); } s_lanternPrefab = (GameObject)obj6; } if (Object.op_Implicit((Object)(object)s_lanternPrefab)) { m_lantern = new GameObject("Lantern") { layer = 28 }; Transform transform6 = m_lantern.transform; transform6.SetParent(val, false); transform6.localScale = Vector3.one * 0.45f; Transform transform7 = Object.Instantiate(s_lanternPrefab, transform6).transform; ((Object)transform7).name = "Lamp"; transform7.localPosition = new Vector3(0.23f, 1.9f, 0f); ((Component)transform7).gameObject.layer = 28; m_light = ((Component)transform7).GetComponentInChildren(); m_light.color = LongshipUpgrades.lanternLightColor.Value; m_flare = ((Component)transform7.Find("flare")).GetComponent(); if (flareColor == Color.clear) { MainModule main = m_flare.main; MinMaxGradient startColor = ((MainModule)(ref main)).startColor; flareColor = ((MinMaxGradient)(ref startColor)).color; } m_lampRenderer = ((Component)transform7.Find("default")).GetComponent(); ConfigurableJoint component = ((Component)transform7).GetComponent(); ((Joint)component).autoConfigureConnectedAnchor = false; ((Joint)component).connectedBody = ((Component)this).GetComponent(); ((Joint)component).connectedAnchor = new Vector3(0f, 3.01f, -0.45f); ((Component)transform7).GetComponent().height = 0.44f; Transform val13 = AddCollider(transform6, "collider", typeof(BoxCollider)); val13.localPosition = new Vector3(0.2f, 2f, 0f); val13.localScale = new Vector3(0.02f, 0.02f, 0.5f); val13.localEulerAngles = new Vector3(90f, 0f, 0f); Transform val14 = val.Find("TraderLamp"); if (Object.op_Implicit((Object)(object)val14)) { ((Component)val14).gameObject.SetActive(false); Transform val15 = val14.Find("insects"); if (Object.op_Implicit((Object)(object)val15)) { m_insects = Object.Instantiate(((Component)val15).gameObject, transform6); ((Object)m_insects).name = "insects"; m_insects.SetActive(false); m_insects.transform.localPosition = new Vector3(0.42f, 1.85f, 0f); m_insects.layer = 8; } } GameObject gameObject3 = ((Component)AddCollider(val, "FireWarmth", typeof(SphereCollider))).gameObject; gameObject3.layer = 14; gameObject3.transform.localPosition = new Vector3(-1f, 0f, 0f); gameObject3.transform.localScale = Vector3.one * 0.45f; SphereCollider component2 = gameObject3.GetComponent(); component2.radius = 3f; ((Collider)component2).isTrigger = true; m_fireWarmth = gameObject3.gameObject.AddComponent(); m_fireWarmth.m_playerOnly = true; if (LongshipUpgrades.lanternSwitchable.Value) { LongshipPartController longshipPartController5 = ((Component)transform6).gameObject.AddComponent(); longshipPartController5.m_name = "$lu_part_lamp_name"; longshipPartController5.m_zdoPartDisabled = s_lightsDisabled; longshipPartController5.m_messageEnable = "$lu_part_lamp_enable"; longshipPartController5.m_messageDisable = "$lu_part_lamp_disable"; longshipPartController5.m_enableEffects = 2; longshipPartController5.m_disableEffects = 3; longshipPartController5.m_nview = m_nview; longshipPartController5.m_useDistance = 2f; } ((Component)transform7).gameObject.SetActive(true); m_lantern.SetActive(false); } GameObject val16 = new GameObject("interactive"); Transform transform8 = val16.transform; transform8.SetParent(val, false); if (LongshipUpgrades.mastEnabled.Value || LongshipUpgrades.mastRemovable.Value) { Transform val17 = AddCollider(transform8, "mast_controller", typeof(BoxCollider)); val17.localPosition = new Vector3(-0.05f, 0.08f, 0f); val17.localScale = new Vector3(0.6f, 0.17f, 0.26f); m_mastUpgrade = ((Component)val17).gameObject; m_mastUpgrade.layer = 16; m_mastUpgrade.SetActive(true); LongshipPartController longshipPartController6 = ((Component)val17).gameObject.AddComponent(); longshipPartController6.m_name = "$lu_part_mast_name"; longshipPartController6.m_zdoPartDisabled = (LongshipUpgrades.mastRemovable.Value ? s_mastRemoved : 0); longshipPartController6.m_messageEnable = "$lu_part_mast_enable"; longshipPartController6.m_messageDisable = "$lu_part_mast_disable"; longshipPartController6.m_enableEffects = 1; longshipPartController6.m_disableEffects = 1; longshipPartController6.m_nview = m_nview; longshipPartController6.m_useDistance = 2.5f; longshipPartController6.AddUpgradeRequirement(LongshipUpgrades.mastEnabled.Value ? s_mastUpgraded : 0, "$lu_part_mast_upgrade", LongshipUpgrades.ParseRequirements(LongshipUpgrades.mastUpgradeRecipe.Value), LongshipUpgrades.mastStation.Value, LongshipUpgrades.mastStationLvl.Value, LongshipUpgrades.mastStationRange.Value); } if (Object.op_Implicit((Object)(object)m_container)) { Transform val18 = AddCollider(transform8, "storage_controller", typeof(BoxCollider)); val18.localPosition = new Vector3(-1.9f, -0.02f, 0f); val18.localScale = new Vector3(0.45f, 0.45f, 0.18f); val18.localEulerAngles = new Vector3(0f, 270f, 0f); BoxCollider component3 = ((Component)m_container).GetComponent(); BoxCollider component4 = ((Component)val18).GetComponent(); component4.center = component3.center; component4.size = component3.size; LongshipPartController longshipPartController7 = ((Component)val18).gameObject.AddComponent(); longshipPartController7.m_name = (m_container.m_name.StartsWith("$") ? m_container.m_name : "$msg_cart_storage"); longshipPartController7.m_nview = m_nview; longshipPartController7.AddUpgradeRequirement(s_containerUpgradedLvl1, "$lu_part_container_upgrade1", LongshipUpgrades.ParseRequirements(LongshipUpgrades.containerLvl1UpgradeRecipe.Value), LongshipUpgrades.containerLvl1Station.Value, LongshipUpgrades.containerLvl1StationLvl.Value, LongshipUpgrades.containerLvl1StationRange.Value); longshipPartController7.AddUpgradeRequirement(s_containerUpgradedLvl2, "$lu_part_container_upgrade2", LongshipUpgrades.ParseRequirements(LongshipUpgrades.containerLvl2UpgradeRecipe.Value), LongshipUpgrades.containerLvl2Station.Value, LongshipUpgrades.containerLvl2StationLvl.Value, LongshipUpgrades.containerLvl2StationRange.Value); m_storageUpgrade = ((Component)val18).gameObject; m_storageUpgrade.layer = 16; m_storageUpgrade.SetActive(false); } Transform healthParent; if (m_protectiveParts != null) { m_healthUpgrade = new GameObject("health"); healthParent = m_healthUpgrade.transform; healthParent.SetParent(transform8, false); Transform val19 = ((Component)this).transform.Find("ship/colliders/left_side"); if (Object.op_Implicit((Object)(object)val19)) { for (int n = 1; n < Mathf.Min(val19.childCount, 5); n++) { AddHealthController(val19, n, "health_controller_left", 0.01f); } } Transform val20 = ((Component)this).transform.Find("ship/colliders/left_side (1)"); if (Object.op_Implicit((Object)(object)val20)) { for (int num = 1; num < Mathf.Min(val20.childCount, 5); num++) { AddHealthController(val20, num, "health_controller_right", -0.01f); } } } if (m_protectiveParts != null) { m_shieldsStyles = new GameObject("shields"); Transform transform9 = m_shieldsStyles.transform; transform9.SetParent(transform8, false); Transform val21 = AddCollider(transform9, "shield_controller_right", typeof(BoxCollider)); val21.localPosition = new Vector3(-1.16f, 0.2f, 1.11f); val21.localScale = new Vector3(0.95f, 0.45f, 0.05f); val21.localEulerAngles = new Vector3(3f, 355f, 0f); Transform val22 = AddCollider(transform9, "shield_controller_right (1)", typeof(BoxCollider)); val22.localPosition = new Vector3(-0.23f, 0.2f, 1.16f); val22.localScale = new Vector3(0.91f, 0.43f, 0.05f); val22.localEulerAngles = new Vector3(3f, 0f, 0f); Transform val23 = AddCollider(transform9, "shield_controller_right (2)", typeof(BoxCollider)); val23.localPosition = new Vector3(1.35f, 0.16f, 1.05f); val23.localScale = new Vector3(1.5f, 0.45f, 0.05f); val23.localEulerAngles = new Vector3(3f, 8f, 0f); Transform val24 = AddCollider(transform9, "shield_controller_left", typeof(BoxCollider)); val24.localPosition = new Vector3(-1.18f, 0.27f, -1.11f); val24.localScale = new Vector3(0.95f, 0.45f, 0.05f); val24.localEulerAngles = new Vector3(0f, 4f, 0f); Transform val25 = AddCollider(transform9, "shield_controller_left (1)", typeof(BoxCollider)); val25.localPosition = new Vector3(-0.25f, 0.27f, -1.16f); val25.localScale = new Vector3(0.89f, 0.45f, 0.05f); val25.localEulerAngles = new Vector3(0f, 2f, 0f); Transform val26 = AddCollider(transform9, "shield_controller_left (2)", typeof(BoxCollider)); val26.localPosition = new Vector3(1.33f, 0.23f, -1.1f); val26.localScale = new Vector3(1.37f, 0.45f, 0.05f); val26.localEulerAngles = new Vector3(0f, 352f, 0f); if (LongshipUpgrades.changeShields.Value) { for (int num2 = 0; num2 < transform9.childCount; num2++) { LongshipPartController longshipPartController8 = ((Component)transform9.GetChild(num2)).gameObject.AddComponent(); longshipPartController8.m_name = "$lu_part_shields_name"; longshipPartController8.m_nview = m_nview; longshipPartController8.m_messageSwitch = "$lu_part_shields_switch"; longshipPartController8.m_zdoPartVariant = s_shieldsStyle; longshipPartController8.m_variants = 4 + 3 * customShields.Count; longshipPartController8.m_switchEffects = 1; } } } Transform val27 = val.parent.Find("unused"); if (Object.op_Implicit((Object)(object)val27)) { GameObject val28 = new GameObject("heads"); Transform transform10 = val28.transform; transform10.SetParent(val, false); List list4 = new List(); Transform val29 = val27.Find("carnyx_head"); if (Object.op_Implicit((Object)(object)val29)) { GameObject val30 = Object.Instantiate(((Component)val29).gameObject, transform10, true); ((Object)val30).name = ((Object)val29).name; val30.SetActive(false); list4.Add(val30); } Transform val31 = val27.Find("dragon_head"); if (Object.op_Implicit((Object)(object)val31)) { GameObject val32 = Object.Instantiate(((Component)val31).gameObject, transform10, true); ((Object)val32).name = ((Object)val31).name; val32.SetActive(false); list4.Add(val32); } Transform val33 = val27.Find("oseberg_head"); if (Object.op_Implicit((Object)(object)val33)) { GameObject val34 = Object.Instantiate(((Component)val33).gameObject, transform10, true); ((Object)val34).name = ((Object)val33).name; val34.SetActive(false); val34.transform.localPosition = Vector3.zero; list4.Add(val34); } m_heads = list4.ToArray(); } if (m_heads != null) { Transform val35 = AddCollider(transform8, "heads_controller", typeof(BoxCollider)); val35.localPosition = new Vector3(-3.9f, 0.53f, 0f); val35.localScale = new Vector3(0.1f, 0.45f, 0.4f); val35.localEulerAngles = new Vector3(0f, 0f, 63f); m_headStyles = ((Component)val35).gameObject; m_headStyles.layer = 16; m_headStyles.SetActive(true); LongshipPartController longshipPartController9 = ((Component)val35).gameObject.AddComponent(); longshipPartController9.m_name = "$lu_part_head_name"; longshipPartController9.m_nview = m_nview; longshipPartController9.m_messageSwitch = "$lu_part_head_switch"; longshipPartController9.m_zdoPartVariant = s_headStyle; longshipPartController9.m_variants = 4; longshipPartController9.m_switchEffects = 1; } if (s_turretPrefab == null) { Turret? obj8 = ((IEnumerable)Resources.FindObjectsOfTypeAll()).FirstOrDefault((Func)((Turret ws) => ((Object)ws).name == "piece_turret")); s_turretPrefab = ((obj8 != null) ? ((Component)obj8).gameObject : null); } if ((Object)(object)s_turretPrefab != (Object)null) { m_turrets = new GameObject("turrets") { layer = 28 }; Transform transform11 = m_turrets.transform; transform11.SetParent(val, false); Transform val36 = AddCollider(transform8, "turrets_controller", typeof(BoxCollider)); val36.localPosition = new Vector3(-3.35f, 0.1f, 0f); val36.localScale = new Vector3(0.04f, 0.35f, 0.45f); m_turretsUpgrade = ((Component)val36).gameObject; m_turretsUpgrade.layer = 16; m_turretsUpgrade.SetActive(true); LongshipPartController longshipPartController10 = ((Component)val36).gameObject.AddComponent(); longshipPartController10.m_name = "$lu_part_turrets_name"; longshipPartController10.m_nview = m_nview; longshipPartController10.m_zdoPartDisabled = s_turretsDisabled; longshipPartController10.m_messageEnable = "$lu_part_turrets_enable"; longshipPartController10.m_enableEffects = 4; longshipPartController10.m_messageDisable = "$lu_part_turrets_disable"; longshipPartController10.m_disableEffects = 5; longshipPartController10.AddUpgradeRequirement(s_turretsUpgraded, "$lu_part_turrets_upgrade", LongshipUpgrades.ParseRequirements(LongshipUpgrades.turretsUpgradeRecipe.Value), LongshipUpgrades.turretsStation.Value, LongshipUpgrades.turretsStationLvl.Value, LongshipUpgrades.turretsStationRange.Value); GameObject val37 = Object.Instantiate(((Component)s_turretPrefab.transform.Find("New")).gameObject, transform11, false); ((Object)val37).name = "turret_right"; val37.layer = 16; val37.SetActive(true); ((Component)val37.transform.Find("Base")).gameObject.SetActive(false); val37.transform.localScale = Vector3.one * 0.25f; val37.transform.localPosition = new Vector3(-3.3f, -0.01f, 0.53f); val37.transform.localEulerAngles = new Vector3(0f, 350f, 0f); BoxCollider val38 = val37.AddComponent(); val38.center = new Vector3(0f, 0.7f, 0.1f); val38.size = new Vector3(1f, 2f, 1f); GameObject val39 = Object.Instantiate(val37, transform11, true); ((Object)val39).name = "turret_left"; val39.transform.localPosition = new Vector3(-3.3f, -0.01f, -0.53f); val39.transform.localEulerAngles = new Vector3(0f, 190f, 0f); Turret component5 = s_turretPrefab.GetComponent(); ShipTurret.m_shootEffect = component5.m_shootEffect; ShipTurret.m_addAmmoEffect = component5.m_addAmmoEffect; ShipTurret.m_reloadEffect = component5.m_reloadEffect; ShipTurret.m_warmUpStartEffect = component5.m_warmUpStartEffect; ShipTurret.m_newTargetEffect = component5.m_newTargetEffect; ShipTurret.m_lostTargetEffect = component5.m_lostTargetEffect; ShipTurret.m_setTargetEffect = component5.m_setTargetEffect; val37.AddComponent().SetPositionAtShip(isLeft: false).FillAllowedAmmo(component5.m_allowedAmmo) .m_destroyedLootPrefab = m_destroyedLootPrefab; val39.AddComponent().SetPositionAtShip(isLeft: true).FillAllowedAmmo(component5.m_allowedAmmo) .m_destroyedLootPrefab = m_destroyedLootPrefab; } if (s_standBossDragonPrefab == null) { ItemStand? obj9 = ((IEnumerable)Resources.FindObjectsOfTypeAll()).FirstOrDefault((Func)((ItemStand ws) => ((Object)((Component)((Component)ws).transform.root).gameObject).name == "BossStone_DragonQueen")); s_standBossDragonPrefab = ((obj9 != null) ? ((Component)obj9).gameObject : null); } if ((Object)(object)s_standBossDragonPrefab != (Object)null) { m_itemstandObject = new GameObject("ItemStand_Bow") { layer = 28 }; Transform transform12 = m_itemstandObject.transform; transform12.SetParent(val, false); m_itemstandObject.SetActive(false); GameObject val40 = Object.Instantiate(s_standBossDragonPrefab, transform12, false); ((Object)val40).name = "itemstand"; val40.layer = 16; Object.Destroy((Object)(object)((Component)val40.transform.Find("model/wood_pole (2)")).gameObject); Transform val41 = val40.transform.Find("model"); ((Component)val41).gameObject.layer = 16; ((Component)val41).gameObject.SetActive(true); Transform val42 = val41.Find("plate"); val42.localScale = Vector3.one * 0.3f; ((Component)val42).gameObject.layer = 16; Object.Destroy((Object)(object)((Component)val42).GetComponent()); MeshRenderer component6 = ((Component)val42).GetComponent(); if ((Object)(object)standSharedMaterial == (Object)null) { standSharedMaterial = new Material(((Renderer)component6).sharedMaterial) { shader = shaderStandard }; } ((Renderer)component6).sharedMaterial = standSharedMaterial; Transform val43 = val40.transform.Find("attach_trophie"); val43.localPosition = Vector3.zero; val43.localScale = Vector3.one * 0.75f; ((Component)val43).gameObject.layer = 16; Transform val44 = val40.transform.Find("dropspawn"); val44.localPosition = new Vector3(0.01f, 0.5f, -0.69f); ((Component)val44).gameObject.layer = 16; val40.transform.localScale = Vector3.one * 0.45f; val40.transform.localPosition = new Vector3(-4.6f, 0.7f, 0f); val40.transform.localEulerAngles = new Vector3(0f, 270f, 0f); val40.GetComponent().size = new Vector3(0.75f, 1f, 0.5f); ItemStand component7 = val40.GetComponent(); m_trophyStand = val40.AddComponent(); m_trophyStand.m_activatePowerEffects = component7.m_activatePowerEffects; m_trophyStand.m_activatePowerEffectsPlayer = component7.m_activatePowerEffectsPlayer; m_trophyStand.m_attachOther = component7.m_attachOther; m_trophyStand.m_dropSpawnPoint = component7.m_dropSpawnPoint; m_trophyStand.m_effects = component7.m_effects; m_trophyStand.m_destroyEffects = component7.m_destroyEffects; Object.Destroy((Object)(object)component7); if (LongshipUpgrades.itemStandDisableSpeaking.Value) { RandomSpeak componentInChildren2 = m_itemstandObject.GetComponentInChildren(); if (componentInChildren2 != null) { ((Component)componentInChildren2).gameObject.SetActive(false); } } m_itemstandObject.SetActive(true); } if (s_wisptorchPrefab == null) { GameObject prefab = ZNetScene.instance.GetPrefab("piece_groundtorch_mist"); s_wisptorchPrefab = ((prefab != null) ? prefab.gameObject : null); } if ((Object)(object)s_wisptorchPrefab != (Object)null) { m_wisp = Object.Instantiate(((Component)s_wisptorchPrefab.transform.Find("_enabled")).gameObject, val, false); ((Object)m_wisp).name = "wisptorch"; m_wisp.layer = 16; m_wisp.SetActive(false); m_wisp.transform.localScale = Vector3.one * 0.35f; m_wisp.transform.localPosition = new Vector3(-0.125f, 4.77f, -0.002f); Transform val45 = m_wisp.transform.Find("Particle System Force Field"); Demister component8 = ((Component)val45).GetComponent(); component8.m_disableForcefieldDelay = 0f; ((MonoBehaviour)component8).CancelInvoke("DisableForcefield"); ((Component)val45).GetComponent().endRange = 13f; val45.localPosition = new Vector3(-2f, -10f, 0f); MainModule main2 = ((Component)m_wisp.transform.Find("sparcs_front")).GetComponent().main; ((MainModule)(ref main2)).simulationSpace = (ParticleSystemSimulationSpace)1; if (LongshipUpgrades.wispEnabled.Value) { Transform val46 = AddCollider(transform8, "wisp_controller", typeof(BoxCollider)); val46.localPosition = new Vector3(-0.13f, 1.22f, 0f); val46.localScale = new Vector3(0.11f, 0.25f, 0.12f); m_wispUpgrade = ((Component)val46).gameObject; m_wispUpgrade.layer = 16; m_wispUpgrade.SetActive(true); LongshipPartController longshipPartController11 = ((Component)val46).gameObject.AddComponent(); longshipPartController11.m_name = "$lu_part_wisp_name"; longshipPartController11.m_zdoPartDisabled = s_wispRemoved; longshipPartController11.m_enableEffects = 6; longshipPartController11.m_disableEffects = 1; longshipPartController11.m_nview = m_nview; longshipPartController11.AddUpgradeRequirement(s_wispUpgraded, "$lu_part_wisp_upgrade", LongshipUpgrades.ParseRequirements(LongshipUpgrades.wispUpgradeRecipe.Value), LongshipUpgrades.wispStation.Value, LongshipUpgrades.wispStationLvl.Value, LongshipUpgrades.wispStationRange.Value); } } if ((Object)(object)s_mapTablePrefab != (Object)null) { m_mapTable = Object.Instantiate(s_mapTablePrefab, val, false); ((Object)m_mapTable).name = "maptable"; m_mapTable.layer = 16; m_mapTable.SetActive(false); m_mapTable.transform.localScale = Vector3.one * 0.45f; m_mapTable.transform.localPosition = new Vector3(-1.14f, -0.05f, -0.73f); m_mapTable.transform.localEulerAngles = new Vector3(0f, 342.6f, 0f); MapTable component9 = m_mapTable.GetComponent(); component9.m_nview = m_nview; component9.m_nview.Register("MapData", (Action)component9.RPC_MapData); component9.m_readSwitch = ((Component)((Component)component9).transform.Find("ReadMap")).GetComponent(); component9.m_readSwitch.m_onUse = (Callback)Delegate.Combine((Delegate?)(object)component9.m_readSwitch.m_onUse, (Delegate?)new Callback(component9.OnRead)); component9.m_readSwitch.m_onHover = (TooltipCallback)Delegate.Combine((Delegate?)(object)component9.m_readSwitch.m_onHover, (Delegate?)new TooltipCallback(component9.GetReadHoverText)); component9.m_writeSwitch = ((Component)((Component)component9).transform.Find("WriteMap")).GetComponent(); component9.m_writeSwitch.m_onUse = (Callback)Delegate.Combine((Delegate?)(object)component9.m_writeSwitch.m_onUse, (Delegate?)new Callback(component9.OnWrite)); component9.m_writeSwitch.m_onHover = (TooltipCallback)Delegate.Combine((Delegate?)(object)component9.m_writeSwitch.m_onHover, (Delegate?)new TooltipCallback(component9.GetWriteHoverText)); if (LongshipUpgrades.mapTableEnabled.Value) { Transform val47 = AddCollider(transform8, "mapTable_controller", typeof(BoxCollider)); val47.localPosition = m_mapTable.transform.localPosition; val47.localScale = new Vector3(0.27f, 0.04f, 0.27f); val47.localEulerAngles = m_mapTable.transform.localEulerAngles; m_mapTableUpgrade = ((Component)val47).gameObject; m_mapTableUpgrade.layer = 16; m_mapTableUpgrade.SetActive(true); LongshipPartController longshipPartController12 = ((Component)val47).gameObject.AddComponent(); longshipPartController12.m_name = "$lu_part_maptable_name"; longshipPartController12.m_nview = m_nview; longshipPartController12.AddUpgradeRequirement(s_mapTableUpgraded, "$lu_part_maptable_upgrade", LongshipUpgrades.ParseRequirements(LongshipUpgrades.mapTableUpgradeRecipe.Value), LongshipUpgrades.mapTableStation.Value, LongshipUpgrades.mapTableStationLvl.Value, LongshipUpgrades.mapTableStationRange.Value); } } void AddHealthController(Transform parent, int i, string name, float offset) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) GameObject val48 = Object.Instantiate(((Component)parent.GetChild(i)).gameObject, healthParent, true); ((Object)val48).name = ((i == 0) ? name : $"{name} ({i})"); Transform transform13 = val48.transform; transform13.localPosition += new Vector3(0f, 0f, offset); LongshipPartController longshipPartController13 = val48.gameObject.AddComponent(); longshipPartController13.m_nview = m_nview; longshipPartController13.m_name = "$lu_part_hull_name"; longshipPartController13.AddUpgradeRequirement(s_healthUpgraded, "$lu_part_hull_upgrade1", LongshipUpgrades.ParseRequirements(LongshipUpgrades.healthUpgradeRecipe.Value), LongshipUpgrades.healthLvl1Station.Value, LongshipUpgrades.healthLvl1StationLvl.Value, LongshipUpgrades.healthLvl1StationRange.Value); if (LongshipUpgrades.healthUpgradeLvl2.Value != 0) { longshipPartController13.AddUpgradeRequirement(s_ashlandsUpgraded, Localization.instance.Localize("$lu_part_hull_upgrade2", new string[1] { LongshipUpgrades.ashlandsProtection.Value ? "\n$lu_part_hull_upgrade2_ashlands" : "" }), LongshipUpgrades.ParseRequirements(LongshipUpgrades.ashlandsUpgradeRecipe.Value), LongshipUpgrades.healthLvl2Station.Value, LongshipUpgrades.healthLvl2StationLvl.Value, LongshipUpgrades.healthLvl2StationRange.Value); } val48.gameObject.SetActive(true); val48.gameObject.layer = 16; } } public void OnDestroyed() { if (m_nview.IsValid() && m_nview.IsOwner()) { DropItemStand(); DropSpentUpgrades(); } } private void DropItemStand() { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)m_trophyStand) || !m_trophyStand.HaveAttachment()) { return; } string @string = m_trophyStand.m_nview.GetZDO().GetString(ZDOVars.s_item, ""); GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(@string); if (!Object.op_Implicit((Object)(object)itemPrefab)) { return; } Vector3 val = Vector3.zero; Quaternion val2 = Quaternion.identity; Transform val3 = itemPrefab.transform.Find("attach"); if (Object.op_Implicit((Object)(object)itemPrefab.transform.Find("attachobj")) && Object.op_Implicit((Object)(object)val3)) { val2 = ((Component)val3).transform.localRotation; val = ((Component)val3).transform.localPosition; } GameObject val4 = Object.Instantiate(itemPrefab, m_trophyStand.m_dropSpawnPoint.position + val, m_trophyStand.m_dropSpawnPoint.rotation * val2); ItemDrop component = val4.GetComponent(); component.LoadFromExternalZDO(m_trophyStand.m_nview.GetZDO()); val4.GetComponent().linearVelocity = Vector3.up * 4f; if (Object.op_Implicit((Object)(object)m_destroyedLootPrefab)) { Inventory val5 = SpawnContainer(m_destroyedLootPrefab); if (val5.AddItem(component.m_itemData)) { ZNetScene.instance.Destroy(val4); } } } public void DropSpentUpgrades() { if (ZoneSystem.instance.GetGlobalKey((GlobalKeys)19)) { return; } Dictionary dictionary = new Dictionary(); LongshipPartController[] componentsInChildren = ((Component)this).GetComponentsInChildren(true); foreach (LongshipPartController longshipPartController in componentsInChildren) { longshipPartController.AddSpentUpgrades(dictionary); } if (dictionary.Count != 0) { CollectionExtensions.Do((IEnumerable)dictionary.Values, (Action)delegate(Requirement[] itemsToDrop) { DropRequirements(itemsToDrop.ToList()); }); } } public void DropRequirements(List itemsToDrop) { //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)m_destroyedLootPrefab)) { Inventory val = SpawnContainer(m_destroyedLootPrefab); while (itemsToDrop.Count > 0) { Requirement val2 = itemsToDrop[0]; if (val2.m_amount <= 0) { itemsToDrop.RemoveAt(0); } else if (val.AddItem(ObjectDB.instance.GetItemPrefab(((Object)val2.m_resItem).name), 1)) { val2.m_amount--; } else if (!val.HaveEmptySlot()) { val = SpawnContainer(m_destroyedLootPrefab); } else { itemsToDrop.RemoveAt(0); } } return; } while (itemsToDrop.Count > 0) { Requirement val3 = itemsToDrop[0]; while (val3.m_amount > 0) { Vector3 val4 = ((Component)this).transform.position + Vector3.up * 0.5f + Random.insideUnitSphere * 0.3f; Quaternion val5 = Quaternion.Euler(0f, (float)Random.Range(0, 360), 0f); ItemDrop component = Object.Instantiate(ObjectDB.instance.GetItemPrefab(((Object)val3.m_resItem).name), val4, val5).GetComponent(); if ((Object)(object)component == (Object)null) { break; } component.SetStack(val3.m_amount); val3.m_amount -= component.m_itemData.m_stack; } itemsToDrop.RemoveAt(0); } } public Inventory SpawnContainer(GameObject lootContainerPrefab) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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_0023: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ((Component)this).transform.position + Random.insideUnitSphere * 1f; return Object.Instantiate(lootContainerPrefab, val, Random.rotation).GetComponent().GetInventory(); } public bool IsTentActive() { return (Object)(object)m_tent != (Object)null && m_tent.activeInHierarchy; } public bool IsHeatActive() { return (Object)(object)m_fireWarmth != (Object)null && m_fireWarmth.m_isHeatType; } private static bool IsNightTime() { return EnvMan.IsNight(); } private static bool IsTimeToLight() { if (!EnvMan.IsDaylight() || !Object.op_Implicit((Object)(object)EnvMan.instance)) { return true; } float dayFraction = EnvMan.instance.GetDayFraction(); if (!(dayFraction <= 0.28f)) { return dayFraction >= 0.71f; } return true; } internal static void OnGlobalStart() { shaderStandard = null; isNightTime = false; isTimeToLight = true; FixPrefab(); } internal static void OnGlobalDestroy() { shaderStandard = null; s_lanternPrefab = null; s_turretPrefab = null; s_standBossDragonPrefab = null; s_wisptorchPrefab = null; Object.Destroy((Object)(object)s_mapTablePrefab); s_mapTablePrefab = null; } private static void FixPrefab() { //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Expected O, but got Unknown //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Expected O, but got Unknown //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_02e2: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_0349: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Unknown result type (might be due to invalid IL or missing references) //IL_0362: Unknown result type (might be due to invalid IL or missing references) //IL_037e: Unknown result type (might be due to invalid IL or missing references) //IL_0392: Unknown result type (might be due to invalid IL or missing references) //IL_0397: Unknown result type (might be due to invalid IL or missing references) //IL_03b7: Unknown result type (might be due to invalid IL or missing references) //IL_03cb: Unknown result type (might be due to invalid IL or missing references) //IL_03d0: Unknown result type (might be due to invalid IL or missing references) //IL_03de: Unknown result type (might be due to invalid IL or missing references) //IL_03f2: Unknown result type (might be due to invalid IL or missing references) //IL_03f7: Unknown result type (might be due to invalid IL or missing references) ZNetScene instance = ZNetScene.instance; object obj = ((instance != null) ? instance.GetPrefab("VikingShip") : null); if (obj == null) { Ship? obj2 = ((IEnumerable)Resources.FindObjectsOfTypeAll()).FirstOrDefault((Func)((Ship ws) => ((Object)ws).name == "VikingShip")); obj = ((obj2 != null) ? ((Component)obj2).gameObject : null); } GameObject val = (GameObject)obj; if ((Object)(object)val == (Object)null) { return; } shaderStandard = ((Renderer)((Component)val.transform.Find("piece_chest/visual/Cube")).GetComponent()).sharedMaterial.shader; Transform val2 = val.transform.Find("ship/visual/Customize/storage"); for (int i = 0; i < val2.childCount; i++) { Transform child = val2.GetChild(i); if (((Object)child).name.StartsWith("default")) { MeshRenderer component = ((Component)child).GetComponent(); if ((Object)(object)storageSharedMaterial == (Object)null || storageSharedMaterial == null) { storageSharedMaterial = new Material(((Renderer)component).sharedMaterial) { shader = shaderStandard }; } else { storageSharedMaterial.shader = shaderStandard; } ((Renderer)component).sharedMaterial = storageSharedMaterial; } } MeshRenderer component2 = ((Component)val.transform.Find("ship/visual/hull_worn/plank")).GetComponent(); if ((Object)(object)plankSharedMaterial == (Object)null || plankSharedMaterial == null) { plankSharedMaterial = new Material(((Renderer)component2).sharedMaterial) { shader = shaderStandard }; } else { plankSharedMaterial.shader = shaderStandard; } ((Renderer)component2).sharedMaterial = plankSharedMaterial; ((Renderer)((Component)val.transform.Find("ship/visual/hull_worn/plank (1)")).GetComponent()).sharedMaterial = plankSharedMaterial; ((Renderer)((Component)val.transform.Find("ship/visual/hull_broken/plank")).GetComponent()).sharedMaterial = plankSharedMaterial; ((Renderer)((Component)val.transform.Find("ship/visual/hull_broken/plank (1)")).GetComponent()).sharedMaterial = plankSharedMaterial; if (!prefabInitialized) { prefabInitialized = true; Transform val3 = val.transform.Find("ship/visual/Customize/ShipTen2_beam"); val3.localPosition += new Vector3(0f, 0.1f, 0f); ((Component)val3).gameObject.layer = 28; Transform val4 = val.transform.Find("ship/visual/Customize/ShipTen2 (1)"); val4.localPosition += new Vector3(0f, 0.08f, 0f); Transform val5 = val.transform.Find("OnboardTrigger"); val5.localScale += new Vector3(0.1f, 2f, 0f); val5.localPosition += new Vector3(-0.05f, 1f, 0f); Material sharedMaterial = ((Renderer)((Component)val4).GetComponentInChildren()).sharedMaterial; sharedMaterial.SetFloat("_RippleSpeed", 75f); sharedMaterial.SetFloat("_RippleDistance", 1.25f); Transform obj3 = val.transform.Find("ship/visual/Mast"); obj3.localPosition += new Vector3(0f, 0.21f, 0f); Transform obj4 = val.transform.Find("ship/visual/Customize/ShipTentHolders"); obj4.localPosition += new Vector3(0f, 0.01f, 0f); Transform val6 = val.transform.Find("ship/visual/Customize/ShipTentHolders (1)"); val6.localPosition += new Vector3(0.1f, -0.18f, 0.11f); val6.localEulerAngles += new Vector3(0f, 5f, 6.6f); Transform val7 = val.transform.Find("ship/visual/Customize/TraderLamp"); ((Component)val7).gameObject.SetActive(false); prefabInit = true; val.AddComponent(); prefabInit = false; } } private static Transform AddCollider(Transform transform, string name, Type type) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) Transform transform2 = new GameObject(name, new Type[1] { type }).transform; transform2.SetParent(transform, false); ((Component)transform2).gameObject.layer = 28; return transform2; } internal static void AddCustomTent(string filename) { AddCustomTexture(customTents, filename); } internal static void AddCustomSail(string filename) { AddCustomTexture(customSails, filename); } internal static void AddCustomShields(string filename) { AddCustomTexture(customShields, filename); } private static void AddCustomTexture(List list, string filename) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Expected O, but got Unknown Texture2D tex = new Texture2D(2, 2); if (LongshipUpgrades.LoadTextureFromConfigDirectory(filename, ref tex)) { list.Add(tex); } } private static void CheckEffects() { List effectPrefabs; if (!partEffects.HasEffects()) { effectPrefabs = new List(); AddEffect(0, "vfx_Place_HildirFabricRoll"); AddEffect(1, "sfx_gui_repairitem_workbench"); AddEffect(2, "sfx_FireAddFuel"); AddEffect(3, "fx_candle_off"); AddEffect(4, "fx_guardstone_permitted_add"); AddEffect(5, "fx_guardstone_permitted_removed"); AddEffect(6, "sfx_demister_start"); partEffects.m_effectPrefabs = effectPrefabs.ToArray(); } void AddEffect(int variant, string prefabName) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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_0039: Expected O, but got Unknown GameObject prefab = ZNetScene.instance.GetPrefab(prefabName); effectPrefabs.Insert(variant, new EffectData { m_prefab = prefab, m_enabled = ((Object)(object)prefab != (Object)null), m_variant = variant }); } } internal static void UpdatePropertyBlocks(GameObject go) { if (s_allInstances.TryGetValue(go, out var value)) { value.UpdatePropertyBlocks(); } } internal static void CombinePropertyBlocks(GameObject go, MaterialPropertyBlock propertyBlockToCombine) { if (s_allInstances.TryGetValue(go, out var value)) { value.CombinePropertyBlocks(propertyBlockToCombine); } } internal static bool HasShipComponent(GameObject go) { return s_allInstances.ContainsKey(go); } internal static bool TryGetShipComponent(Ship ship, out LongshipCustomizableParts parts) { return s_allInstances.TryGetValue(((Component)ship).gameObject, out parts) || ((Component)ship).TryGetComponent(ref parts); } public static Vector3 ParseVector3(string rString) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) string[] array = rString.Substring(1, rString.Length - 2).Split(','); float num = float.Parse(array[0].Replace('.', ',')); float num2 = float.Parse(array[1].Replace('.', ',')); float num3 = float.Parse(array[2].Replace('.', ',')); return new Vector3(num, num2, num3); } private static void GetHildirMapTable() { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)s_mapTablePrefab)) { ZoneLocation val = ZoneSystem.instance.m_locations.Find((ZoneLocation loc) => loc.m_prefabName == "Hildir_camp"); if (val != null && val.m_prefab.IsValid) { val.m_prefab.Load(); Transform obj = val.m_prefab.Asset.transform.Find("stuff/hildir_maptable"); s_mapTablePrefab = Object.Instantiate((obj != null) ? ((Component)obj).gameObject : null); ((Object)s_mapTablePrefab).name = "LongshipUpgrades_MapTable"; s_mapTablePrefab.SetActive(false); Transform val2 = s_mapTablePrefab.transform.Find("default"); LongshipUpgrades.FixMeshRendererProperties(((Component)val2).GetComponent()); val.m_prefab.Release(); Object.DestroyImmediate((Object)(object)((Component)val2).GetComponent()); Object.DestroyImmediate((Object)(object)s_mapTablePrefab.GetComponent()); Object.DestroyImmediate((Object)(object)s_mapTablePrefab.GetComponent()); Transform obj2 = s_mapTablePrefab.transform.Find("low"); Object.DestroyImmediate((Object)(object)((obj2 != null) ? ((Component)obj2).gameObject : null)); Transform val3 = AddCollider(s_mapTablePrefab.transform, "ReadMap", typeof(BoxCollider)); val3.localPosition = new Vector3(-0.2f, 0.9f, 0f); val3.localScale = new Vector3(0.4f, 0.1f, 0.6f); Switch val4 = ((Component)val3).gameObject.AddComponent(); val4.m_name = "$piece_cartographytable"; ((Component)val3).gameObject.layer = 28; ((Component)val3).gameObject.SetActive(true); Transform val5 = AddCollider(s_mapTablePrefab.transform, "WriteMap", typeof(BoxCollider)); val5.localPosition = new Vector3(0.2f, 0.9f, 0f); val5.localScale = new Vector3(0.4f, 0.1f, 0.6f); Switch val6 = ((Component)val5).gameObject.AddComponent(); val6.m_name = "$piece_cartographytable"; ((Component)val5).gameObject.layer = 28; ((Component)val5).gameObject.SetActive(true); MapTable val7 = s_mapTablePrefab.AddComponent(); GameObject prefab = ZNetScene.instance.GetPrefab("piece_cartographytable"); val7.m_writeEffects = ((prefab == null) ? null : prefab.GetComponent()?.m_writeEffects); val7.m_name = "$piece_cartographytable"; } } } } public class LongshipPartController : MonoBehaviour, Hoverable, Interactable { public class UpgradeRequirements { public int m_zdoVar; public Requirement[] m_requirements = (Requirement[])(object)new Requirement[0]; public string m_messageUpgrade = ""; public string m_stationName; public int m_stationLevel; public int m_stationRange; public UpgradeRequirements(int zdoVar, string message, Requirement[] requirements, string station, int level, int range) { m_zdoVar = zdoVar; m_requirements = requirements; m_messageUpgrade = message; m_stationName = station; m_stationLevel = level; m_stationRange = range; } public bool FillUpgradeHover(ZDO zdo, string name) { if (m_zdoVar == 0 || zdo.GetBool(m_zdoVar, false)) { return false; } sb.Clear(); if (!Player.m_localPlayer.NoCostCheat() && !string.IsNullOrWhiteSpace(m_stationName) && !Player.m_localPlayer.KnowStationLevel(m_stationName, m_stationLevel)) { AddUpgradeHintToHover("$lu_controller_message_unknownupgrade"); return true; } sb.Append(name); if (HaveCraftinStationInRange(out var lvlMet)) { if (lvlMet) { sb.Append("\n[$KEY_Use] $inventory_upgradebutton"); } AddUpgradeHintToHover(m_messageUpgrade); AddUpgradeRequirementsToHint(lvlMet); } else { AddUpgradeHintToHover(m_messageUpgrade); sb.Append("\n\n$msg_missingrequirement:"); AddRequiredStationToHover(); } return true; } public bool CheckConsume(ZNetView nview, Player player, Vector3 position, out bool result) { result = false; if (m_zdoVar == 0 || nview.GetZDO().GetBool(m_zdoVar, false)) { return false; } if (!RemoveRequiredItems(player)) { ((Character)player).Message((MessageType)2, "$msg_missingrequirement", 0, (Sprite)null); return true; } nview.InvokeRPC("SetBuilt", new object[3] { m_zdoVar, m_stationName, ((object)(Vector3)(ref position)).ToString() }); PlayerProfile playerProfile = Game.instance.GetPlayerProfile(); playerProfile.IncrementStat((PlayerStatType)1, 1f); playerProfile.IncrementStat((PlayerStatType)14, 1f); result = true; return true; } public void AddSpentUpgrades(ZDO zdo, Dictionary upgradeReqs) { if (m_zdoVar != 0 && zdo.GetBool(m_zdoVar, false) && m_requirements.Length != 0) { upgradeReqs[m_zdoVar] = m_requirements; } } private void AddUpgradeRequirementsToHint(bool lvlMet) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) if (m_requirements == null || m_requirements.Length == 0 || string.IsNullOrWhiteSpace(m_stationName)) { return; } sb.Append("\n"); if (ZoneSystem.instance.GetGlobalKey((GlobalKeys)19)) { sb.AppendFormat("\n$menu_nobuildcost", ColorUtility.ToHtmlStringRGBA(LongshipUpgrades.hintStationColor.Value)); } sb.Append("\n$hud_require"); if (lvlMet) { AddRequiredStationToHover(LongshipUpgrades.hintStationColor.Value, LongshipUpgrades.hintStationColor.Value); } else if (Mathf.Sin(Time.time * 10f) > 0f) { AddRequiredStationToHover(LongshipUpgrades.hintStationColor.Value, Color.red); } else { AddRequiredStationToHover(LongshipUpgrades.hintStationColor.Value); } sb.Append(":"); Requirement[] requirements = m_requirements; if (requirements != null) { CollectionExtensions.Do((IEnumerable)requirements, (Action)delegate(Requirement req) { AddItemRequirementToHover(req); }); } } private void AddRequiredStationToHover() { if (!string.IsNullOrWhiteSpace(m_stationName)) { sb.AppendFormat(" {0}", m_stationName); if (m_stationLevel > 1) { sb.AppendFormat(" $msg_level {0}", m_stationLevel); } } } private void AddRequiredStationToHover(Color station, Color level) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) if (!string.IsNullOrWhiteSpace(m_stationName)) { sb.AppendFormat(" {1}", ColorUtility.ToHtmlStringRGBA(station), m_stationName); if (m_stationLevel > 1) { sb.AppendFormat(" $msg_level {1}", ColorUtility.ToHtmlStringRGBA(level), m_stationLevel); } } } private void AddRequiredStationToHover(Color station) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) if (!string.IsNullOrWhiteSpace(m_stationName)) { sb.AppendFormat(" {1}", ColorUtility.ToHtmlStringRGBA(station), m_stationName); if (m_stationLevel > 1) { sb.AppendFormat(" $msg_level {0}", m_stationLevel); } } } private void AddUpgradeHintToHover(string message) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (!string.IsNullOrWhiteSpace(message)) { sb.AppendFormat("\n{1}", ColorUtility.ToHtmlStringRGBA(LongshipUpgrades.hintColor.Value), message); } } private bool HaveCraftinStationInRange(out bool lvlMet) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) lvlMet = true; if (string.IsNullOrWhiteSpace(m_stationName) || Player.m_localPlayer.NoCostCheat()) { return true; } lvlMet = false; craftingStations.Clear(); CraftingStation.FindStationsInRange(m_stationName, ((Component)Player.m_localPlayer).transform.position, (float)m_stationRange, craftingStations); if (craftingStations.Count == 0) { return false; } lvlMet = craftingStations.Any((CraftingStation station) => station.GetLevel(true) >= m_stationLevel); return true; } private void AddItemRequirementToHover(Requirement requirement) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)requirement.m_resItem == (Object)null)) { string name = requirement.m_resItem.m_itemData.m_shared.m_name; sb.AppendFormat("\n{1} {3}", ColorUtility.ToHtmlStringRGBA(LongshipUpgrades.hintAmountColor.Value), requirement.GetAmount(1), ColorUtility.ToHtmlStringRGBA(LongshipUpgrades.hintItemColor.Value), (Player.m_localPlayer.NoCostCheat() || Player.m_localPlayer.IsMaterialKnown(name)) ? name : "$lu_controller_message_unknownitem"); } } private bool RemoveRequiredItems(Player player) { if (player.NoCostCheat()) { return true; } if (!string.IsNullOrWhiteSpace(m_stationName) && m_stationLevel > 0 && !player.KnowStationLevel(m_stationName, m_stationLevel)) { return false; } if (!HaveCraftinStationInRange(out var lvlMet) || !lvlMet) { return false; } if (ZoneSystem.instance.GetGlobalKey((GlobalKeys)19)) { return true; } if (m_requirements.Length == 0) { return true; } tempRecipe.m_resources = m_requirements; if (!player.HaveRequirementItems(tempRecipe, false, 1, 1)) { return false; } player.ConsumeResources(m_requirements, 1, -1, 1); return true; } } public ZNetView m_nview; public Ship m_ship; public Piece m_piece; public string m_name = "Part"; public bool m_checkGuardStone = true; public float m_useDistance = 0f; public string m_messageEnable = "$lu_controller_message_enable"; public string m_messageSwitch = "$lu_controller_message_switch"; public string m_messageDisable = "$lu_controller_message_disable"; public UpgradeRequirements[] m_upgradeRequirements = new UpgradeRequirements[0]; public int m_zdoPartDisabled; public int m_zdoPartVariant; public int m_variants; public int m_switchEffects = -1; public int m_enableEffects = -1; public int m_disableEffects = -1; private static readonly StringBuilder sb = new StringBuilder(20); private static Recipe tempRecipe; private static readonly List craftingStations = new List(); public void Awake() { if ((Object)(object)tempRecipe == (Object)null) { tempRecipe = ScriptableObject.CreateInstance(); ((Object)tempRecipe).name = "LongshipPartUpgradeTempRecipe"; } if ((Object)(object)m_nview == (Object)null) { m_nview = ((Component)this).GetComponentInParent(); } m_ship = ((Component)this).GetComponentInParent(); m_piece = ((Component)this).GetComponentInParent(); } public string GetHoverText() { //IL_00c3: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)m_nview) || !m_nview.IsValid()) { return ""; } if (!IsPositionToInteract()) { return ""; } if (!InUseDistance((Humanoid)(object)Player.m_localPlayer)) { return Localization.instance.Localize("$piece_toofar"); } if (LongshipUpgrades.onlyCreatorUpgrades.Value && (Object)(object)m_piece != (Object)null && !m_piece.IsCreator()) { return Localization.instance.Localize("$piece_noaccess"); } if (m_checkGuardStone && !PrivateArea.CheckAccess(((Component)this).transform.position, 0f, false, false)) { return Localization.instance.Localize(m_name + "\n$piece_noaccess"); } ZDO zDO = m_nview.GetZDO(); UpgradeRequirements[] upgradeRequirements = m_upgradeRequirements; foreach (UpgradeRequirements upgradeRequirements2 in upgradeRequirements) { if (upgradeRequirements2.FillUpgradeHover(zDO, m_name)) { return Localization.instance.Localize(sb.ToString()); } } if (m_zdoPartVariant != 0 && m_variants > 1) { sb.Clear(); sb.Append(m_name); sb.Append("\n[$KEY_Use] "); sb.Append(m_messageSwitch); return Localization.instance.Localize(sb.ToString()); } if (m_zdoPartDisabled != 0) { sb.Clear(); sb.Append(m_name); sb.Append("\n[$KEY_Use] "); sb.Append(zDO.GetBool(m_zdoPartDisabled, false) ? m_messageEnable : m_messageDisable); return Localization.instance.Localize(sb.ToString()); } return ""; } public string GetHoverName() { return m_name; } public bool Interact(Humanoid human, bool hold, bool alt) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) if (hold) { return false; } if (LongshipUpgrades.onlyCreatorUpgrades.Value && (Object)(object)m_piece != (Object)null && !m_piece.IsCreator()) { return false; } if (m_checkGuardStone && !PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false)) { return false; } if (!InUseDistance(human)) { return false; } if (!Object.op_Implicit((Object)(object)m_nview) || !m_nview.IsValid()) { return false; } if (!IsPositionToInteract()) { return false; } Player player = (Player)(object)((human is Player) ? human : null); ZDO zDO = m_nview.GetZDO(); UpgradeRequirements[] upgradeRequirements = m_upgradeRequirements; foreach (UpgradeRequirements upgradeRequirements2 in upgradeRequirements) { if (upgradeRequirements2.CheckConsume(m_nview, player, ((Component)this).transform.position, out var result)) { return result; } } Vector3 position; if (m_zdoPartVariant != 0 && m_variants > 1) { ZNetView nview = m_nview; object[] obj = new object[4] { m_zdoPartVariant, (zDO.GetInt(m_zdoPartVariant, 0) + 1) % m_variants, m_switchEffects, null }; position = ((Component)this).transform.position; obj[3] = ((object)(Vector3)(ref position)).ToString(); nview.InvokeRPC("SetVariant", obj); return true; } if (m_zdoPartDisabled == 0) { return false; } bool flag = !zDO.GetBool(m_zdoPartDisabled, false); ZNetView nview2 = m_nview; object[] obj2 = new object[4] { m_zdoPartDisabled, flag, flag ? m_disableEffects : m_enableEffects, null }; position = ((Component)this).transform.position; obj2[3] = ((object)(Vector3)(ref position)).ToString(); nview2.InvokeRPC("SetActive", obj2); return true; } public bool UseItem(Humanoid user, ItemData item) { return false; } public bool InUseDistance(Humanoid human) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) return m_useDistance == 0f || Vector3.Distance(((Component)human).transform.position, ((Component)this).transform.position) < m_useDistance; } public void AddUpgradeRequirement(int zdoVar, string message, Requirement[] requirements, string station, int level, int range) { if (zdoVar != 0) { m_upgradeRequirements = CollectionExtensions.AddItem((IEnumerable)m_upgradeRequirements, new UpgradeRequirements(zdoVar, message, requirements, station, level, range)).ToArray(); } } public void AddSpentUpgrades(Dictionary upgradeReqs) { ZDO zDO = m_nview.GetZDO(); UpgradeRequirements[] upgradeRequirements = m_upgradeRequirements; foreach (UpgradeRequirements upgradeRequirements2 in upgradeRequirements) { upgradeRequirements2.AddSpentUpgrades(zDO, upgradeReqs); } } private bool IsPositionToInteract() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) return (Object)(object)Ship.GetLocalShip() == (Object)(object)m_ship && Vector3.Dot(((Component)this).transform.position - ((Character)Player.m_localPlayer).GetEyePoint(), ((Component)this).transform.position - ((Component)Utils.GetMainCamera()).transform.position) > 0f && Vector3.Dot(((Component)this).transform.position - ((Component)Player.m_localPlayer).transform.position, ((Component)this).transform.position - ((Component)Utils.GetMainCamera()).transform.position) > 0f; } } public static class LongshipPropertyBlocks { [HarmonyPatch(typeof(MaterialMan), "RegisterRenderers")] public static class MaterialMan_RegisterRenderers_KeepPropertyBlocks { public static void Postfix(MaterialMan __instance, GameObject gameObject) { if (LongshipCustomizableParts.HasShipComponent(gameObject) && __instance.m_blocks.TryGetValue(((Object)gameObject).GetInstanceID(), out var value)) { s_objectProperties[value] = gameObject; } } } [HarmonyPatch(typeof(MaterialMan), "ResetValue")] public static class MaterialMan_ResetValue_KeepPropertyBlocks { public static void Postfix(MaterialMan __instance, GameObject go) { if (LongshipCustomizableParts.HasShipComponent(go) && __instance.m_blocks.TryGetValue(((Object)go).GetInstanceID(), out var value)) { s_objectProperties[value] = go; } } } [HarmonyPatch(typeof(PropertyContainer), "UpdateBlock")] public static class MaterialMan_PropertyContainer_UpdateBlock_AfterPropertyBlock { public static void Postfix(PropertyContainer __instance, MaterialPropertyBlock ___m_propertyBlock) { if (s_objectProperties.TryGetValue(__instance, out var value)) { if (!___m_propertyBlock.isEmpty) { LongshipCustomizableParts.CombinePropertyBlocks(value, ___m_propertyBlock); } else { LongshipCustomizableParts.UpdatePropertyBlocks(value); } } } } [HarmonyPatch(typeof(MaterialMan), "UnregisterRenderers")] public static class MaterialMan_UnregisterRenderers_Remove { public static void Prefix(MaterialMan __instance, GameObject gameObject) { if (__instance.m_blocks.TryGetValue(((Object)gameObject).GetInstanceID(), out var value)) { s_objectProperties.Remove(value); } } } public static readonly int _StyleTex = Shader.PropertyToID("_StyleTex"); private static readonly Dictionary s_objectProperties = new Dictionary(); } [BepInPlugin("shudnal.LongshipUpgrades", "Longship Upgrades", "1.0.16")] public class LongshipUpgrades : BaseUnityPlugin { [HarmonyPatch(typeof(ZoneSystem), "Start")] public static class ZoneSystem_Start_FixCustomizableParts { [HarmonyPriority(0)] private static void Postfix() { RegisterShipMapRpcs(); LongshipCustomizableParts.OnGlobalStart(); } } [HarmonyPatch(typeof(ZoneSystem), "OnDestroy")] public static class ZoneSystem_OnDestroy_ClearValues { [HarmonyPriority(0)] private static void Postfix() { ClearShipMapRuntime(); LongshipCustomizableParts.OnGlobalDestroy(); } } [HarmonyPatch(typeof(Ship))] public static class Ship_OnTrigger_IgnoreFireWarmthCollider { private static readonly Dictionary> triggerCounter = new Dictionary>(); private static bool IsHeatActive(Ship ship) { LongshipCustomizableParts parts; return LongshipCustomizableParts.TryGetShipComponent(ship, out parts) && parts.IsHeatActive(); } [HarmonyPostfix] [HarmonyPatch("OnEnable")] public static void OnEnablePostfix(Ship __instance) { triggerCounter.Add(__instance, new Dictionary()); } [HarmonyPostfix] [HarmonyPatch("OnDisable")] public static void OnDisablePostfix(Ship __instance) { triggerCounter.Remove(__instance); } [HarmonyPrefix] [HarmonyPatch("OnTriggerEnter")] public static bool OnTriggerEnterPrefix(Ship __instance, Collider collider) { if (!Object.op_Implicit((Object)(object)((Component)collider).GetComponent())) { return true; } if (!triggerCounter.TryGetValue(__instance, out var value)) { return true; } if (!value.ContainsKey(collider)) { value[collider] = 1; return true; } value[collider]++; return false; } [HarmonyPrefix] [HarmonyPatch("OnTriggerExit")] public static bool OnTriggerExitPrefix(Ship __instance, Collider collider) { if (!Object.op_Implicit((Object)(object)((Component)collider).GetComponent())) { return true; } if (!triggerCounter.TryGetValue(__instance, out var value)) { return true; } if (!value.TryGetValue(collider, out var value2)) { return true; } if (value2 == 1) { value.Remove(collider); return true; } value[collider]--; return false; } } public class ShipMapDataEntry { public int Revision; public byte[] Data; public int Hash; public float LastAccessTime; } [HarmonyPatch(typeof(ZDOMan), "Load")] public static class ZDOMan_Load_TrackShipMapZdos { public static void Postfix(ZDOMan __instance) { RebuildTrackedShipZdos(__instance.m_objectsByID.Values); } } [HarmonyPatch(typeof(ZDOMan), "CreateNewZDO", new Type[] { typeof(Vector3), typeof(int) })] public static class ZDOMan_CreateNewZDO_TrackShipMapZdos { public static void Postfix(ZDO __result) { TrackShipZdo(__result); } } [HarmonyPatch(typeof(ZDOMan), "CreateNewZDO", new Type[] { typeof(ZDOID), typeof(Vector3), typeof(int) })] public static class ZDOMan_CreateNewZDO_WithUid_TrackShipMapZdos { public static void Postfix(ZDO __result) { TrackShipZdo(__result); } } [HarmonyPatch(typeof(ZDOMan), "HandleDestroyedZDO")] public static class ZDOMan_HandleDestroyedZDO_ClearShipMapStore { public static void Prefix(ZDOID uid) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) RemoveShipMapData(uid); } } [HarmonyPatch(typeof(ZDO), "Deserialize")] public static class ZDO_Deserialize_TrackShipMapData { public static void Postfix(ZDO __instance) { TrackShipZdo(__instance); } } [HarmonyPatch(typeof(ZDOMan), "PrepareSave")] public static class ZDOMan_PrepareSave_InjectShipMapData { public static void Prefix() { if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer()) { InjectAllTrackedShipMapDataIntoRuntime(); } } public static void Postfix() { RemoveInjectedShipMapDataFromRuntime(); } } [HarmonyPatch(typeof(ZDOMan), "Update")] public static class ZDOMan_Update_PruneClientShipMapStore { public static void Postfix() { PruneClientShipMapStore(); } } [HarmonyPatch(typeof(Ship), "UpdateControlls")] public static class Ship_UpdateControlls_SpeedLimitWithoutMast { public static void Prefix(Ship __instance) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) if (IsControlledComponent((Component)(object)__instance) && Object.op_Implicit((Object)(object)__instance.m_nview) && __instance.m_nview.IsValid() && __instance.IsSailUp() && __instance.m_nview.GetZDO().GetBool(LongshipCustomizableParts.s_mastRemoved, false)) { __instance.m_speed = (Speed)2; } } } [HarmonyPatch(typeof(Container), "Awake")] public static class Container_Awake_CargoUpgrades { private static bool CheckAccess(Container container) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) return (!container.m_checkGuardStone || PrivateArea.CheckAccess(((Component)container).transform.position, 0f, false, false)) && container.CheckAccess(Game.instance.GetPlayerProfile().GetPlayerID()); } public static void Prefix(Container __instance) { if (!containerEnabled.Value || !IsControlledComponent((Component)(object)__instance)) { return; } ZNetView val = (Object.op_Implicit((Object)(object)__instance.m_rootObjectOverride) ? ((Component)__instance.m_rootObjectOverride).GetComponent() : ((Component)__instance).GetComponent()); if (!((Object)(object)val == (Object)null) && val.IsValid()) { if (val.GetZDO().GetBool(LongshipCustomizableParts.s_containerUpgradedLvl1, false) && __instance.m_width < containerWidth.Value) { __instance.m_width = containerWidth.Value; string name = ((object)__instance).GetType().Name; val.GetZDO().Set("HasFields", true); val.GetZDO().Set(StringExtensionMethods.GetStableHashCode("HasFields" + name), true); val.GetZDO().Set(name + ".m_width", containerWidth.Value); } if (val.GetZDO().GetBool(LongshipCustomizableParts.s_containerUpgradedLvl2, false) && __instance.m_height < containerHeight.Value) { __instance.m_height = containerHeight.Value; string name2 = ((object)__instance).GetType().Name; val.GetZDO().Set("HasFields", true); val.GetZDO().Set(StringExtensionMethods.GetStableHashCode("HasFields" + name2), true); val.GetZDO().Set(name2 + ".m_height", containerHeight.Value); } } } } [HarmonyPatch(typeof(Ladder), "GetHoverText")] public static class Ladder_GetHoverText_BoxClimb { public static bool Prefix(Ladder __instance, ref string __result) { if (!IsBoxLadder(__instance)) { return true; } if (__instance.InUseDistance((Humanoid)(object)Player.m_localPlayer) && !((Character)Player.m_localPlayer).IsAttached()) { __result = Localization.instance.Localize(__instance.m_name + "\n[$KEY_Use] $lu_box_climb"); } else { __result = ""; } return false; } } [HarmonyPatch(typeof(Ladder), "Interact")] public static class Ladder_Interact_BoxClimb { public static bool Prefix(Ladder __instance, Humanoid character) { return !IsBoxLadder(__instance) || !((Character)character).IsAttached(); } public static void Postfix(Ladder __instance, Humanoid character, bool hold) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (IsBoxLadder(__instance) && !hold && __instance.InUseDistance(character) && !((Character)character).IsAttached()) { ((Character)character).SetMoveDir(__instance.m_targetPos.forward); ((Character)character).UpdateWalking(Time.deltaTime); } } } [HarmonyPatch(typeof(MapTable), "OnRead", new Type[] { typeof(Switch), typeof(Humanoid), typeof(ItemData) })] public static class MapTable_OnRead_TrackCompressionContext { public static void Prefix(MapTable __instance, ref bool __state) { __state = IsShipMapTable(__instance); if (__state) { if (IsValidMapTable(__instance)) { InjectShipMapDataIntoZdo(__instance.m_nview.GetZDO()); } s_mapTableDataCompressionFlags.Push(IsValidMapTable(__instance) && __instance.m_nview.GetZDO().GetBool(LongshipCustomizableParts.s_mapDataCompressed, false)); } } public static Exception Finalizer(MapTable __instance, bool __state, Exception __exception) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) if (__state) { if (s_mapTableWriteDepth == 0 && IsValidMapTable(__instance)) { RemoveShipMapDataFromRuntime(__instance.m_nview.GetZDO().m_uid); } if (s_mapTableDataCompressionFlags.Count > 0) { s_mapTableDataCompressionFlags.Pop(); } } return __exception; } } [HarmonyPatch(typeof(MapTable), "OnWrite")] public static class MapTable_OnWrite_ScaleWriteEffects { public static bool inCall; public static void Prefix(MapTable __instance, ref bool __state) { inCall = IsShipMapTable(__instance); __state = inCall; if (__state) { if (IsValidMapTable(__instance)) { InjectShipMapDataIntoZdo(__instance.m_nview.GetZDO()); } s_mapTableWriteDepth++; s_mapTableDataCompressionFlags.Push(IsValidMapTable(__instance) && __instance.m_nview.GetZDO().GetBool(LongshipCustomizableParts.s_mapDataCompressed, false)); } } public static Exception Finalizer(MapTable __instance, bool __state, Exception __exception) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) inCall = false; if (__state) { if (IsValidMapTable(__instance)) { RemoveShipMapDataFromRuntime(__instance.m_nview.GetZDO().m_uid); } if (s_mapTableDataCompressionFlags.Count > 0) { s_mapTableDataCompressionFlags.Pop(); } s_mapTableWriteDepth = Math.Max(0, s_mapTableWriteDepth - 1); } return __exception; } } [HarmonyPatch(typeof(MapTable), "RPC_MapData")] public static class MapTable_RPC_MapData_MarkCompressed { public static void Prefix(MapTable __instance, ref byte[] __state) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) __state = null; if (IsShipMapTable(__instance) && IsValidMapTable(__instance) && __instance.m_nview.IsOwner()) { ZDO zDO = __instance.m_nview.GetZDO(); InjectShipMapDataIntoZdo(zDO); if (TryGetShipMapData(zDO.m_uid, out var entry) && entry.Data != null) { __state = (byte[])entry.Data.Clone(); } } } public static void Postfix(MapTable __instance, byte[] __state) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) if (!IsShipMapTable(__instance) || !__instance.m_nview.IsValid() || !__instance.m_nview.IsOwner()) { return; } ZDO zDO = __instance.m_nview.GetZDO(); byte[] byteArray = zDO.GetByteArray(ZDOVars.s_data, (byte[])null); bool flag = ((__state == null) ? (byteArray != null) : (byteArray == null || !StructuralComparisons.StructuralEqualityComparer.Equals(__state, byteArray))); int num = Math.Max(zDO.GetInt(s_shipMapDataRevision, 0), GetShipMapRevision(zDO.m_uid)); if (byteArray != null) { num = (flag ? Math.Max(1, num + 1) : Math.Max(1, num)); SetShipMapData(zDO.m_uid, num, byteArray); zDO.Set(LongshipCustomizableParts.s_mapDataCompressed, true); SyncShipMapRevision(zDO, num); if ((Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer()) { SubmitShipMapDataToServer(zDO, num, byteArray); } } RemoveShipMapDataFromRuntime(zDO.m_uid); } } [HarmonyPatch(typeof(ZDO), "Serialize")] public static class ZDO_Serialize_SkipUnchangedShipMapData { public struct SerializeState { public bool Removed; public byte[] Data; } public static void Prefix(ZDO __instance, ref SerializeState __state) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) __state = default(SerializeState); byte[] array = default(byte[]); if (__instance.GetPrefab() == LongshipCustomizableParts.prefabInt && __instance.GetBool(LongshipCustomizableParts.s_mapDataCompressed, false) && ZDOExtraData.s_byteArrays.TryGetValue(__instance.m_uid, out var value) && value.TryGetValue(ZDOVars.s_data, ref array) && array != null) { __state.Removed = value.Remove(ZDOVars.s_data); __state.Data = array; if (__state.Removed && value.Count == 0) { ZDOExtraData.s_byteArrays.Remove(__instance.m_uid); } } } public static void Postfix(ZDO __instance, SerializeState __state) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) if (__state.Removed) { ZDOExtraData.Set(__instance.m_uid, ZDOVars.s_data, __state.Data); } } } [HarmonyPatch(typeof(Minimap), "ReadExploredArray")] public static class Minimap_ReadExploredArray_CompressedShipMapData { public static bool Prefix(Minimap __instance, ZPackage pkg, int version, ref List __result) { if (!IsCompressedMapDataContext()) { return true; } int num = pkg.ReadInt(); if (num != __instance.m_explored.Length) { ZLog.LogWarning((object)("Map exploration array size missmatch:" + num + " VS " + __instance.m_explored.Length)); __result = null; return false; } byte[] array = pkg.ReadByteArray(); BitArray bitArray = new BitArray(array); List list = new List(num); for (int i = 0; i < num; i++) { list.Add(i < bitArray.Count && bitArray[i]); } LogInfo($"Ship map data read: explored payload unpacked {array.Length} -> {num} bytes ({Math.Max(0, num - array.Length)} bytes added)"); __result = list; return false; } } [HarmonyPatch(typeof(Minimap), "GetSharedMapData")] public static class Minimap_GetSharedMapData_CompressShipMapData { public static void Postfix(ref byte[] __result) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) if (s_mapTableWriteDepth == 0) { return; } ZPackage val = new ZPackage(__result); int num = val.ReadInt(); int num2 = val.ReadInt(); bool[] array = new bool[num2]; for (int i = 0; i < num2; i++) { array[i] = val.ReadBool(); } BitArray bitArray = new BitArray(array); byte[] array2 = new byte[(bitArray.Length - 1) / 8 + 1]; bitArray.CopyTo(array2, 0); LogInfo($"Ship map data write: explored payload compressed {num2} -> {array2.Length} bytes ({Math.Max(0, num2 - array2.Length)} bytes saved)"); ZPackage val2 = new ZPackage(); val2.Write(num); val2.Write(num2); val2.Write(array2); if (num >= 2) { int num3 = val.ReadInt(); val2.Write(num3); for (int j = 0; j < num3; j++) { long num4 = val.ReadLong(); string text = val.ReadString(); Vector3 val3 = val.ReadVector3(); int num5 = val.ReadInt(); bool flag = val.ReadBool(); string text2 = ((num >= 3) ? val.ReadString() : string.Empty); val2.Write(num4); val2.Write(text); val2.Write(val3); val2.Write(num5); val2.Write(flag); if (num >= 3) { val2.Write(text2); } } } __result = val2.GetArray(); } } [HarmonyPatch(typeof(EffectList), "Create")] public static class EffectList_Create_ScaleWriteEffects { public static void Prefix(EffectList __instance, ref float scale, ref bool __state) { if (MapTable_OnWrite_ScaleWriteEffects.inCall) { scale = 0.1f; if (__instance.HasEffects() && !__instance.m_effectPrefabs[0].m_scale) { __state = true; __instance.m_effectPrefabs[0].m_scale = true; } } } public static void Postfix(EffectList __instance, bool __state) { if (__state) { __instance.m_effectPrefabs[0].m_scale = false; } } } [HarmonyPatch(typeof(MapTable), "Start")] public static class MapTable_Start_PreventStartScript { [HarmonyPriority(800)] public static bool Prefix(MapTable __instance) { return ((Object)__instance).name != "maptable" || !IsControlledComponent((Component)(object)__instance); } } public const string pluginID = "shudnal.LongshipUpgrades"; public const string pluginName = "Longship Upgrades"; public const string pluginVersion = "1.0.16"; private readonly Harmony harmony = new Harmony("shudnal.LongshipUpgrades"); internal static readonly ConfigSync configSync = new ConfigSync("shudnal.LongshipUpgrades") { DisplayName = "Longship Upgrades", CurrentVersion = "1.0.16", MinimumRequiredVersion = "1.0.16" }; internal static LongshipUpgrades instance; internal static ConfigEntry configLocked; internal static ConfigEntry loggingEnabled; internal static ConfigEntry onlyCreatorUpgrades; internal static ConfigEntry onlyCreatorStand; internal static ConfigEntry hintStationColor; internal static ConfigEntry hintColor; internal static ConfigEntry hintAmountColor; internal static ConfigEntry hintItemColor; internal static ConfigEntry containerEnabled; internal static ConfigEntry containerHeight; internal static ConfigEntry containerWidth; internal static ConfigEntry containerLvl1Station; internal static ConfigEntry containerLvl1StationLvl; internal static ConfigEntry containerLvl1StationRange; internal static ConfigEntry containerLvl1UpgradeRecipe; internal static ConfigEntry containerLvl2Station; internal static ConfigEntry containerLvl2StationLvl; internal static ConfigEntry containerLvl2StationRange; internal static ConfigEntry containerLvl2UpgradeRecipe; internal static ConfigEntry healthEnabled; internal static ConfigEntry healthUpgradeLvl1; internal static ConfigEntry healthUpgradeLvl2; internal static ConfigEntry ashlandsProtection; internal static ConfigEntry healthLvl1Station; internal static ConfigEntry healthLvl1StationLvl; internal static ConfigEntry healthLvl1StationRange; internal static ConfigEntry healthUpgradeRecipe; internal static ConfigEntry healthLvl2Station; internal static ConfigEntry healthLvl2StationLvl; internal static ConfigEntry healthLvl2StationRange; internal static ConfigEntry ashlandsUpgradeRecipe; internal static ConfigEntry lanternEnabled; internal static ConfigEntry lanternRemovable; internal static ConfigEntry lanternAutoSwtich; internal static ConfigEntry lanternSwitchable; internal static ConfigEntry lanternLightColor; internal static ConfigEntry lanternStation; internal static ConfigEntry lanternStationLvl; internal static ConfigEntry lanternStationRange; internal static ConfigEntry lanternUpgradeRecipe; internal static ConfigEntry turretsEnabled; internal static ConfigEntry turretsStation; internal static ConfigEntry turretsStationLvl; internal static ConfigEntry turretsStationRange; internal static ConfigEntry turretsUpgradeRecipe; internal static ConfigEntry itemStandEnabled; internal static ConfigEntry itemStandDisableSpeaking; internal static ConfigEntry itemStandTrophyRescale; internal static ConfigEntry itemStandForsakenPower; internal static ConfigEntry mastEnabled; internal static ConfigEntry mastRemovable; internal static ConfigEntry mastStation; internal static ConfigEntry mastStationLvl; internal static ConfigEntry mastStationRange; internal static ConfigEntry mastUpgradeRecipe; internal static ConfigEntry tentEnabled; internal static ConfigEntry tentHeat; internal static ConfigEntry tentRemovable; internal static ConfigEntry tentStation; internal static ConfigEntry tentStationLvl; internal static ConfigEntry tentStationRange; internal static ConfigEntry tentUpgradeRecipe; internal static ConfigEntry wispEnabled; internal static ConfigEntry wispStation; internal static ConfigEntry wispStationLvl; internal static ConfigEntry wispStationRange; internal static ConfigEntry wispUpgradeRecipe; internal static ConfigEntry mapTableEnabled; internal static ConfigEntry mapTableStation; internal static ConfigEntry mapTableStationLvl; internal static ConfigEntry mapTableStationRange; internal static ConfigEntry mapTableUpgradeRecipe; internal static ConfigEntry changeHead; internal static ConfigEntry changeShields; internal static ConfigEntry changeTent; internal static ConfigEntry changeSail; internal static ConfigEntry maxShields; internal static ConfigEntry maxTents; internal static ConfigEntry maxSails; public static string configDirectory; public const string tentsDirectory = "tents"; public const string sailsDirectory = "sails"; public const string shieldsDirectory = "shields"; private const string shipMapRequestRpc = "LU_RequestShipMapData"; private const string shipMapResponseRpc = "LU_ShipMapDataResponse"; private const string shipMapSubmitRpc = "LU_SubmitShipMapData"; private static readonly Dictionary s_shipMapStore = new Dictionary(); private static readonly HashSet s_trackedShipZdos = new HashSet(); private static readonly List s_saveInjectedShipMapZdos = new List(); private static bool s_shipMapRpcsRegistered = false; private static float s_nextClientShipMapPruneTime = 0f; private static readonly Stack s_mapTableDataCompressionFlags = new Stack(); private static int s_mapTableWriteDepth = 0; private static readonly int s_shipMapDataRevision = StringExtensionMethods.GetStableHashCode("ShipMapDataRevision"); private void Awake() { harmony.PatchAll(); instance = this; ConfigInit(); configSync.AddLockingConfigEntry(configLocked); configDirectory = Path.Combine(Paths.ConfigPath, "shudnal.LongshipUpgrades"); Game.isModded = true; LoadTextures(); ((MonoBehaviour)this).StartCoroutine(Localizer.Load()); } public void ConfigInit() { //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0488: Unknown result type (might be due to invalid IL or missing references) config("General", "NexusID", 2885, "Nexus mod ID for updates", synchronizedSetting: false); configLocked = config("General", "Lock Configuration", defaultValue: true, "Configuration is locked and can be changed by server admins only."); loggingEnabled = config("General", "Logging enabled", defaultValue: false, "Enable logging. [Not Synced with Server]", synchronizedSetting: false); onlyCreatorUpgrades = config("General", "Only creator can upgrade ship", defaultValue: true, "Only ship's creator can upgrade it."); onlyCreatorStand = config("General", "Only creator can change trophy", defaultValue: true, "Only ship's creator can put and get trophy from stand."); hintStationColor = config("Hint", "Station color", new Color(0.75f, 1f, 0.75f, 1f), "Color of hint in upgrade tooltip. [Not Synced with Server]", synchronizedSetting: false); hintColor = config("Hint", "Hint color", new Color(0.678f, 0.847f, 0.902f, 1f), "Color of hint in upgrade tooltip. [Not Synced with Server]", synchronizedSetting: false); hintAmountColor = config("Hint", "Entry amount color", Color.yellow, "Color for amount. [Not Synced with Server]", synchronizedSetting: false); hintItemColor = config("Hint", "Entry item name color", new Color(0.85f, 0.85f, 0.85f, 1f), "Color for item name. [Not Synced with Server]", synchronizedSetting: false); containerEnabled = config("Container", "Enable upgrades", defaultValue: true, "Container upgrades. Pls be aware items in upgraded slots will be unavailable after mod disabling. But it will drop on ship destruction."); containerWidth = config("Container", "Upgrade - Lvl 1 - Container Width", 7, "Width of ship container after first upgrade."); containerLvl1Station = config("Container", "Upgrade - Lvl 1 - Station name", "$piece_workbench", "Station name token. The center of the ship is the starting point of the check."); containerLvl1StationLvl = config("Container", "Upgrade - Lvl 1 - Station level", 4, "Station level. At least one station in the range must meet the level requirement."); containerLvl1StationRange = config("Container", "Upgrade - Lvl 1 - Station range", 100, "Station range check. You don't have to park the ship inside your main house to be able to upgrade it."); containerLvl1UpgradeRecipe = config("Container", "Upgrade - Lvl 1 - Recipe", "ElderBark:20,Silver:5,Obsidian:10", "Container lvl 1 upgrade recipe. World restart or ship rebuild required to apply changes."); containerHeight = config("Container", "Upgrade - Lvl 2 - Container Height", 4, "Height of ship container after second upgrade."); containerLvl2Station = config("Container", "Upgrade - Lvl 2 - Station name", "$piece_artisanstation", "Station name token. The center of the ship is the starting point of the check."); containerLvl2StationLvl = config("Container", "Upgrade - Lvl 2 - Station level", 1, "Station level. At least one station in the range must meet the level requirement."); containerLvl2StationRange = config("Container", "Upgrade - Lvl 2 - Station range", 100, "Station range check. You don't have to park the ship inside your main house to be able to upgrade it."); containerLvl2UpgradeRecipe = config("Container", "Upgrade - Lvl 2 - Recipe", "BlackMetal:20,YggdrasilWood:20,Finewood:20", "Container lvl 2 upgrade recipe. World restart or ship rebuild required to apply changes."); healthEnabled = config("Hull", "Enable upgrades", defaultValue: true, "Health upgrades."); healthUpgradeLvl1 = config("Hull", "Upgrade - Lvl 1 - Health", 1500, "Health of ship hull after first upgrade."); healthLvl1Station = config("Hull", "Upgrade - Lvl 1 - Station name", "$piece_forge", "Station name token. The center of the ship is the starting point of the check."); healthLvl1StationLvl = config("Hull", "Upgrade - Lvl 1 - Station level", 7, "Station level. At least one station in the range must meet the level requirement."); healthLvl1StationRange = config("Hull", "Upgrade - Lvl 1 - Station range", 100, "Station range check. You don't have to park the ship inside your main house to be able to upgrade it."); healthUpgradeRecipe = config("Hull", "Upgrade - Lvl 1 - Recipe", "FineWood:20,BlackMetal:10,Raspberry:2,Blueberries:2,Coal:2", "Hull lvl 1 upgrade recipe. World restart or ship rebuild required to apply changes."); healthUpgradeLvl2 = config("Hull", "Upgrade - Lvl 2 - Health", 2000, "Health of ship hull after second upgrade. Set to 0 to disable upgrade."); ashlandsProtection = config("Hull", "Upgrade - Lvl 2 - Ashlands protection", defaultValue: true, "Should ship be protected from ashlands ocean after second upgrade. If disabled - second upgrade will not be available."); healthLvl2Station = config("Hull", "Upgrade - Lvl 2 - Station name", "$piece_blackforge", "Station name token. The center of the ship is the starting point of the check."); healthLvl2StationLvl = config("Hull", "Upgrade - Lvl 2 - Station level", 3, "Station level. At least one station in the range must meet the level requirement."); healthLvl2StationRange = config("Hull", "Upgrade - Lvl 2 - Station range", 100, "Station range check. You don't have to park the ship inside your main house to be able to upgrade it."); ashlandsUpgradeRecipe = config("Hull", "Upgrade - Lvl 2 - Recipe", "CeramicPlate:20,Tar:20,YggdrasilWood:20,IronNails:50", "Hull lvl 2 upgrade recipe. World restart or ship rebuild required to apply changes."); lanternEnabled = config("Lantern", "Enable upgrades", defaultValue: true, "Lantern upgrades requires mast to be upgraded."); lanternRemovable = config("Lantern", "Make removable", defaultValue: true, "Make lantern removable. World restart or ship rebuild required to apply changes."); lanternAutoSwtich = config("Lantern", "Light auto enabled and disabled", defaultValue: true, "Light will be automatically enabled in night time or dark environments and automatically disabled in day light"); lanternSwitchable = config("Lantern", "Light switch enabled", defaultValue: true, "Enable manual light switch. World restart or ship rebuild required to apply changes."); lanternLightColor = config("Lantern", "Light color", new Color(0.96f, 0.78f, 0.68f, 1f), "Color of lantern light. Switch light to apply changes."); lanternUpgradeRecipe = config("Lantern", "Recipe", "SurtlingCore:3,BronzeNails:10,FineWood:6,Chain:1", "Lantern upgrade recipe. World restart or ship rebuild required to apply changes."); lanternStation = config("Lantern", "Station name", "$piece_forge", "Station name token. The center of the ship is the starting point of the check."); lanternStationLvl = config("Lantern", "Station level", 4, "Station level. At least one station in the range must meet the level requirement."); lanternStationRange = config("Lantern", "Station range", 100, "Station range check. You don't have to park the ship inside your main house to be able to upgrade it."); mastEnabled = config("Mast", "Enable upgrades", defaultValue: true, "Mast upgrade also makes lantern, tent and wisp torch upgrades possible."); mastRemovable = config("Mast", "Make removable", defaultValue: true, "Enable mast removal. World restart or ship rebuild required to apply changes."); mastUpgradeRecipe = config("Mast", "Recipe", "RoundLog:2,IronNails:10,Finewood:4,Raspberries:2,Blueberries:2,Coal:2", "Mast upgrade recipe. World restart or ship rebuild required to apply changes."); mastStation = config("Mast", "Station name", "$piece_workbench", "Station name token. The center of the ship is the starting point of the check."); mastStationLvl = config("Mast", "Station level", 4, "Station level. At least one station in the range must meet the level requirement."); mastStationRange = config("Mast", "Station range", 100, "Station range check. You don't have to park the ship inside your main house to be able to upgrade it."); tentEnabled = config("Tent", "Enable upgrades", defaultValue: true, "Tent upgrades requires mast to be upgraded."); tentHeat = config("Tent", "Heat enabled", defaultValue: true, "Enable heat zone under the tent to get place to rest. Enabled lantern required."); tentRemovable = config("Tent", "Make removable", defaultValue: true, "Enable tent removal. World restart or ship rebuild required to apply changes."); tentUpgradeRecipe = config("Tent", "Recipe", "JuteRed:2,LoxPelt:2,LinenThread:6,RoundLog:2", "Tent upgrade recipe. World restart or ship rebuild required to apply changes."); tentStation = config("Tent", "Station name", "$piece_workbench", "Station name token. The center of the ship is the starting point of the check."); tentStationLvl = config("Tent", "Station level", 4, "Station level. At least one station in the range must meet the level requirement."); tentStationRange = config("Tent", "Station range", 100, "Station range check. You don't have to park the ship inside your main house to be able to upgrade it."); wispEnabled = config("Wisp torch", "Enable upgrades", defaultValue: true, "Wisp torch pushes away the surrounding magic mist."); wispUpgradeRecipe = config("Wisp torch", "Recipe", "YggdrasilWood:10,Wisp:5,Eitr:5", "Wisp Torch upgrade recipe. World restart or ship rebuild required to apply changes."); wispStation = config("Wisp torch", "Station name", "$piece_magetable", "Station name token. The center of the ship is the starting point of the check."); wispStationLvl = config("Wisp torch", "Station level", 1, "Station level. At least one station in the range must meet the level requirement."); wispStationRange = config("Wisp torch", "Station range", 100, "Station range check. You don't have to park the ship inside your main house to be able to upgrade it."); turretsEnabled = config("Turrets", "Enable upgrades", defaultValue: true, "Enable turrets upgrades."); turretsUpgradeRecipe = config("Turrets", "Recipe", "BlackMetal:15,YggdrasilWood:15,MechanicalSpring:5", "Turrets upgrade recipe. World restart or ship rebuild required to apply changes."); turretsStation = config("Turrets", "Station name", "$piece_artisanstation", "Station name token. The center of the ship is the starting point of the check."); turretsStationLvl = config("Turrets", "Station level", 1, "Station level. At least one station in the range must meet the level requirement."); turretsStationRange = config("Turrets", "Station range", 100, "Station range check. You don't have to park the ship inside your main house to be able to upgrade it."); itemStandEnabled = config("Item stand", "Enabled", defaultValue: true, "Enable item stand on bow for trophy."); itemStandDisableSpeaking = config("Item stand", "Trophy speaking disabled", defaultValue: false, "Trophis will not do random speak. World restart or ship rebuild required to apply changes."); itemStandTrophyRescale = config("Item stand", "Trophy rescale", "TrophyBonemass:0,7;TrophyBonemawSerpent:0,7;TrophySeekerQueen:0,7;TrophyGoblinKing:0,7", "Some trophies are ginormous. Set smaller scale for them. Trophy rehook required to apply changes."); itemStandForsakenPower = config("Item stand", "Forsaken power enabled", defaultValue: true, "Boss trophies brings an option to cast another Forsaken power while on ship."); mapTableEnabled = config("Map table", "Enable upgrades", defaultValue: true, "Cartography table allows to exchange map data between players."); mapTableUpgradeRecipe = config("Map table", "Recipe", "FineWood:10,Bronze:2,LeatherScraps:5,Raspberry:4", "Map Table upgrade recipe. World restart or ship rebuild required to apply changes."); mapTableStation = config("Map table", "Station name", "$piece_forge", "Station name token. The center of the ship is the starting point of the check."); mapTableStationLvl = config("Map table", "Station level", 3, "Station level. At least one station in the range must meet the level requirement."); mapTableStationRange = config("Map table", "Station range", 100, "Station range check. You don't have to park the ship inside your main house to be able to upgrade it."); changeHead = config("Style", "Change heads", defaultValue: true, "Change ship's head style."); changeShields = config("Style", "Change shields color", defaultValue: true, "Change shields colors. World restart or ship rebuild required to apply changes."); changeTent = config("Style", "Change tent color", defaultValue: true, "Change tent colors. World restart or ship rebuild required to apply changes."); changeSail = config("Style", "Change sail color", defaultValue: true, "Change sail colors. World restart or ship rebuild required to apply changes."); maxShields = config("Style", "Max shields amount", 0, "Maximum amount of shield variants. If 0 - amount is taken from custom textures count.\n By default every custom texture counts as 3 shields. World restart or ship rebuild required to apply changes."); maxTents = config("Style", "Max tents amount", 0, "Maximum amount of tent variants. If 0 - amount is taken from custom textures count. World restart or ship rebuild required to apply changes."); maxSails = config("Style", "Max sails amount", 0, "Maximum amount of sail variants. If 0 - amount is taken from custom textures count. "); } private void OnDestroy() { ((BaseUnityPlugin)this).Config.Save(); instance = null; Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } public static void LogInfo(object data) { if (loggingEnabled.Value) { ((BaseUnityPlugin)instance).Logger.LogInfo(data); } } public static void LogWarning(object data) { ((BaseUnityPlugin)instance).Logger.LogWarning(data); } private ConfigEntry config(string group, string name, T defaultValue, ConfigDescription description, bool synchronizedSetting = true) { ConfigEntry val = ((BaseUnityPlugin)this).Config.Bind(group, name, defaultValue, description); SyncedConfigEntry syncedConfigEntry = configSync.AddConfigEntry(val); syncedConfigEntry.SynchronizedConfig = synchronizedSetting; return val; } private ConfigEntry config(string group, string name, T defaultValue, 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, defaultValue, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty()), synchronizedSetting); } private void LoadTextures() { LoadTexture("ashlands_hull.png", ref LongshipCustomizableParts.s_ashlandsHull); LoadTexture("ashlands_hull_damaged.png", ref LongshipCustomizableParts.s_ashlandsHullDamaged); Directory.CreateDirectory(configDirectory); string path = Path.Combine(configDirectory, "sail_original.png"); string path2 = Path.Combine(configDirectory, "tent_original.png"); string path3 = Path.Combine(configDirectory, "shields_original.png"); if (!File.Exists(path) || !File.Exists(path2) || !File.Exists(path3)) { File.WriteAllBytes(path, GetEmbeddedFileData("sail_original.png")); File.WriteAllBytes(path2, GetEmbeddedFileData("tent_original.png")); File.WriteAllBytes(path3, GetEmbeddedFileData("shields_original.png")); } string text = Path.Combine(configDirectory, "tents"); if (!Directory.Exists(text)) { Directory.CreateDirectory(text); File.WriteAllBytes(Path.Combine(text, "tent_01.png"), GetEmbeddedFileData("tent_01.png")); File.WriteAllBytes(Path.Combine(text, "tent_02.png"), GetEmbeddedFileData("tent_02.png")); File.WriteAllBytes(Path.Combine(text, "tent_03.png"), GetEmbeddedFileData("tent_03.png")); File.WriteAllBytes(Path.Combine(text, "tent_04.png"), GetEmbeddedFileData("tent_04.png")); File.WriteAllBytes(Path.Combine(text, "tent_05.png"), GetEmbeddedFileData("tent_05.png")); } string text2 = Path.Combine(configDirectory, "sails"); if (!Directory.Exists(text2)) { Directory.CreateDirectory(text2); File.WriteAllBytes(Path.Combine(text2, "sail_01.png"), GetEmbeddedFileData("sail_01.png")); File.WriteAllBytes(Path.Combine(text2, "sail_02.png"), GetEmbeddedFileData("sail_02.png")); File.WriteAllBytes(Path.Combine(text2, "sail_03.png"), GetEmbeddedFileData("sail_03.png")); File.WriteAllBytes(Path.Combine(text2, "sail_04.png"), GetEmbeddedFileData("sail_04.png")); File.WriteAllBytes(Path.Combine(text2, "sail_05.png"), GetEmbeddedFileData("sail_05.png")); } string text3 = Path.Combine(configDirectory, "shields"); if (!Directory.Exists(text3)) { Directory.CreateDirectory(text3); File.WriteAllBytes(Path.Combine(text3, "shields_01.png"), GetEmbeddedFileData("shields_01.png")); } foreach (FileInfo item in from file in new DirectoryInfo(text).EnumerateFiles() orderby file.Name select file) { LongshipCustomizableParts.AddCustomTent(Path.Combine("tents", item.Name)); } foreach (FileInfo item2 in from file in new DirectoryInfo(text2).EnumerateFiles() orderby file.Name select file) { LongshipCustomizableParts.AddCustomSail(Path.Combine("sails", item2.Name)); } foreach (FileInfo item3 in from file in new DirectoryInfo(text3).EnumerateFiles() orderby file.Name select file) { LongshipCustomizableParts.AddCustomShields(Path.Combine("shields", item3.Name)); } } internal static void LoadIcon(string filename, ref Sprite icon) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Expected O, but got Unknown //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) Texture2D tex = new Texture2D(2, 2); if (LoadTexture(filename, ref tex)) { icon = Sprite.Create(tex, new Rect(0f, 0f, (float)((Texture)tex).width, (float)((Texture)tex).height), Vector2.zero); } } internal static bool LoadTextureFromConfigDirectory(string filename, ref Texture2D tex) { string path = Path.Combine(configDirectory, filename); if (!File.Exists(path)) { return false; } LogInfo("Loaded image from config folder: " + filename); return ImageConversion.LoadImage(tex, File.ReadAllBytes(path)); } internal static bool LoadTexture(string filename, ref Texture2D tex) { if (LoadTextureFromConfigDirectory(filename, ref tex)) { return true; } ((Object)tex).name = Path.GetFileNameWithoutExtension(filename); return ImageConversion.LoadImage(tex, GetEmbeddedFileData(filename), true); } internal static byte[] GetEmbeddedFileData(string filename) { Assembly executingAssembly = Assembly.GetExecutingAssembly(); string name = executingAssembly.GetManifestResourceNames().Single((string str) => str.EndsWith(filename)); Stream manifestResourceStream = executingAssembly.GetManifestResourceStream(name); byte[] array = new byte[manifestResourceStream.Length]; manifestResourceStream.Read(array, 0, array.Length); return array; } internal static Requirement[] ParseRequirements(string recipe) { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Expected O, but got Unknown List list = new List(); string[] array = recipe.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (string text in array) { string[] array2 = text.Split(new char[1] { ':' }, StringSplitOptions.RemoveEmptyEntries); if (array2.Length != 2) { continue; } int num = int.Parse(array2[1]); if (num > 0) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(array2[0].Trim()); if (!((Object)(object)itemPrefab == (Object)null)) { list.Add(new Requirement { m_amount = num, m_resItem = itemPrefab.GetComponent(), m_recover = true }); } } } return list.ToArray(); } private static bool IsControlledComponent(Component component) { return Utils.GetPrefabName(((Component)component.transform.root).gameObject) == "VikingShip"; } private static int GetShipMapHash(byte[] data) { if (data == null) { return 0; } int num = 17; for (int i = 0; i < data.Length; i++) { num = num * 31 + data[i]; } return num; } private static bool IsShipZdo(ZDO zdo) { return zdo != null && zdo.GetPrefab() == LongshipCustomizableParts.prefabInt; } private static bool IsShipZdo(ZDOID id) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) return ZDOMan.instance != null && IsShipZdo(ZDOMan.instance.GetZDO(id)); } public static bool IsValidMapTable(MapTable mapTable) { return Object.op_Implicit((Object)(object)mapTable.m_nview) && mapTable.m_nview.IsValid(); } internal static void RegisterShipMapRpcs() { if (!s_shipMapRpcsRegistered && ZRoutedRpc.instance != null) { ZRoutedRpc.instance.Register("LU_RequestShipMapData", (Action)RPC_RequestShipMapData); ZRoutedRpc.instance.Register("LU_ShipMapDataResponse", (Action)RPC_ShipMapDataResponse); ZRoutedRpc.instance.Register("LU_SubmitShipMapData", (Action)RPC_SubmitShipMapData); s_shipMapRpcsRegistered = true; } } internal static bool TryGetShipMapData(ZDOID id, out ShipMapDataEntry entry) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) if (s_shipMapStore.TryGetValue(id, out entry) && entry != null && entry.Data != null) { entry.LastAccessTime = Time.time; return true; } entry = null; return false; } internal static int GetShipMapRevision(ZDOID id) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) ShipMapDataEntry value; return s_shipMapStore.TryGetValue(id, out value) ? value.Revision : 0; } internal static int SyncShipMapRevision(ZDO zdo, int? preferredRevision = null) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) if (!IsShipZdo(zdo)) { return 0; } int num = preferredRevision ?? Math.Max(zdo.GetInt(s_shipMapDataRevision, 0), GetShipMapRevision(zdo.m_uid)); if (num <= 0) { num = 1; } if (zdo.GetInt(s_shipMapDataRevision, 0) != num) { zdo.Set(s_shipMapDataRevision, num, false); } if (s_shipMapStore.TryGetValue(zdo.m_uid, out var value)) { value.Revision = Math.Max(value.Revision, num); } return num; } private static bool RemoveShipMapDataFromRuntime(ZDOID id) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) if (!ZDOExtraData.s_byteArrays.TryGetValue(id, out var value)) { return false; } bool flag = value.Remove(ZDOVars.s_data); if (flag && value.Count == 0) { ZDOExtraData.s_byteArrays.Remove(id); } return flag; } internal static bool InjectShipMapDataIntoZdo(ZDO zdo) { //IL_000a: 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) if (!IsShipZdo(zdo) || !TryGetShipMapData(zdo.m_uid, out var entry)) { return false; } ZDOExtraData.Set(zdo.m_uid, ZDOVars.s_data, entry.Data); return true; } internal static bool ExtractShipMapDataFromZdo(ZDO zdo, bool removeFromRuntime = true) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) if (!IsShipZdo(zdo)) { return false; } byte[] byteArray = zdo.GetByteArray(ZDOVars.s_data, (byte[])null); if (byteArray == null) { return false; } int revision = SyncShipMapRevision(zdo); SetShipMapData(zdo.m_uid, revision, byteArray); if (removeFromRuntime) { RemoveShipMapDataFromRuntime(zdo.m_uid); } return true; } internal static bool SetShipMapData(ZDOID id, int revision, byte[] data) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) if (data == null || revision <= 0) { return false; } byte[] array = (byte[])data.Clone(); int shipMapHash = GetShipMapHash(array); if (s_shipMapStore.TryGetValue(id, out var value)) { if (revision < value.Revision) { return false; } if (revision == value.Revision && value.Hash == shipMapHash && StructuralComparisons.StructuralEqualityComparer.Equals(value.Data, array)) { value.LastAccessTime = Time.time; return false; } value.Revision = revision; value.Data = array; value.Hash = shipMapHash; value.LastAccessTime = Time.time; return true; } s_shipMapStore[id] = new ShipMapDataEntry { Revision = revision, Data = array, Hash = shipMapHash, LastAccessTime = Time.time }; return true; } internal static void RemoveShipMapData(ZDOID id) { //IL_0006: 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_0019: Unknown result type (might be due to invalid IL or missing references) s_trackedShipZdos.Remove(id); s_shipMapStore.Remove(id); RemoveShipMapDataFromRuntime(id); } internal static void ClearShipMapRuntime() { s_shipMapStore.Clear(); s_trackedShipZdos.Clear(); s_saveInjectedShipMapZdos.Clear(); s_shipMapRpcsRegistered = false; s_nextClientShipMapPruneTime = 0f; } internal static void TrackShipZdo(ZDO zdo, bool extractFromRuntime = true) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) if (IsShipZdo(zdo)) { s_trackedShipZdos.Add(zdo.m_uid); if (extractFromRuntime) { ExtractShipMapDataFromZdo(zdo); } } } internal static void RebuildTrackedShipZdos(IEnumerable zdos) { s_trackedShipZdos.Clear(); foreach (ZDO zdo in zdos) { TrackShipZdo(zdo); } } internal static bool RequestShipMapDataFromServer(ZDO zdo, int currentRevision) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_002b: Unknown result type (might be due to invalid IL or missing references) if (zdo == null || !zdo.IsValid() || currentRevision <= 0 || ZRoutedRpc.instance == null) { return false; } ZPackage val = new ZPackage(); val.Write(zdo.m_uid); val.Write(currentRevision); ZRoutedRpc.instance.InvokeRoutedRPC("LU_RequestShipMapData", new object[1] { val }); LogInfo($"Ship map data requested for {zdo}"); return true; } private static void SubmitShipMapDataToServer(ZDO zdo, int revision, byte[] data) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) if (zdo != null && revision > 0 && data != null && ZRoutedRpc.instance != null && (!((Object)(object)ZNet.instance != (Object)null) || !ZNet.instance.IsServer())) { ZPackage val = new ZPackage(); val.Write(zdo.m_uid); val.Write(revision); val.Write(data); ZRoutedRpc.instance.InvokeRoutedRPC("LU_SubmitShipMapData", new object[1] { val }); LogInfo($"Ship map data submitted to server for {zdo}"); } } private static void InjectAllTrackedShipMapDataIntoRuntime() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) s_saveInjectedShipMapZdos.Clear(); foreach (ZDOID item in s_shipMapStore.Keys.ToList()) { ZDOMan obj = ZDOMan.instance; ZDO val = ((obj != null) ? obj.GetZDO(item) : null); if (val != null && InjectShipMapDataIntoZdo(val)) { s_saveInjectedShipMapZdos.Add(item); } } } private static void RemoveInjectedShipMapDataFromRuntime() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) foreach (ZDOID s_saveInjectedShipMapZdo in s_saveInjectedShipMapZdos) { RemoveShipMapDataFromRuntime(s_saveInjectedShipMapZdo); } s_saveInjectedShipMapZdos.Clear(); } private static void PruneClientShipMapStore() { //IL_0067: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZNet.instance == (Object)null || ZNet.instance.IsServer() || ZDOMan.instance == null || Time.time < s_nextClientShipMapPruneTime) { return; } s_nextClientShipMapPruneTime = Time.time + 10f; foreach (ZDOID item in s_shipMapStore.Keys.ToList()) { if (ZDOMan.instance.GetZDO(item) == null) { RemoveShipMapData(item); } } } private static void RPC_RequestShipMapData(long sender, ZPackage pkg) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer() && pkg != null) { ZDOID val = pkg.ReadZDOID(); int num = pkg.ReadInt(); if (TryGetShipMapData(val, out var entry) && entry.Revision >= num) { ZPackage val2 = new ZPackage(); val2.Write(val); val2.Write(entry.Revision); val2.Write(entry.Data); ZRoutedRpc.instance.InvokeRoutedRPC(sender, "LU_ShipMapDataResponse", new object[1] { val2 }); LogInfo($"Ship map data for {val} sent to {sender}"); } } } private static void RPC_ShipMapDataResponse(long sender, ZPackage pkg) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0049: 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_006a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)ZNet.instance == (Object)null) && !ZNet.instance.IsServer() && pkg != null) { ZDOID val = pkg.ReadZDOID(); int num = pkg.ReadInt(); byte[] array = pkg.ReadByteArray(); if (array != null && num > GetShipMapRevision(val)) { SetShipMapData(val, num, array); LogInfo($"Ship map data response for {val} from {sender}"); } } } private static void RPC_SubmitShipMapData(long sender, ZPackage pkg) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer() || pkg == null) { return; } ZDOID val = pkg.ReadZDOID(); int num = pkg.ReadInt(); byte[] array = pkg.ReadByteArray(); if (array == null || num <= 0 || !SetShipMapData(val, num, array)) { return; } ZDOMan obj = ZDOMan.instance; ZDO val2 = ((obj != null) ? obj.GetZDO(val) : null); if (val2 != null) { if (!val2.GetBool(LongshipCustomizableParts.s_mapDataCompressed, false)) { val2.Set(LongshipCustomizableParts.s_mapDataCompressed, true); } SyncShipMapRevision(val2, num); RemoveShipMapDataFromRuntime(val); } LogInfo($"Ship map data for {val} submitted from {sender}"); } private static bool IsBoxLadder(Ladder ladder) { return ladder.m_name == "$lu_box_name"; } private static bool IsShipMapTable(MapTable mapTable) { return ((Object)mapTable).name == "maptable" && IsControlledComponent((Component)(object)mapTable); } private static bool IsCompressedMapDataContext() { return s_mapTableDataCompressionFlags.Count > 0 && s_mapTableDataCompressionFlags.Peek(); } public static void FixMeshRendererProperties(MeshRenderer renderer) { ((Renderer)renderer).sharedMaterial = DeepCopyMaterial(((Renderer)renderer).sharedMaterial); MeshFilter component = ((Component)renderer).GetComponent(); if (component != null) { FixSharedMesh(component); } } private static Texture2D CopyTexture(Texture2D source) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)source == (Object)null) { return null; } Texture2D val = new Texture2D(((Texture)source).width, ((Texture)source).height, (TextureFormat)4, ((Texture)source).mipmapCount > 1); RenderTexture temporary = RenderTexture.GetTemporary(((Texture)source).width, ((Texture)source).height, 0, (RenderTextureFormat)7, (RenderTextureReadWrite)0); try { Graphics.Blit((Texture)(object)source, temporary); RenderTexture.active = temporary; val.ReadPixels(new Rect(0f, 0f, (float)((Texture)source).width, (float)((Texture)source).height), 0, 0); val.Apply(true, true); ((Texture)val).filterMode = ((Texture)source).filterMode; } finally { RenderTexture.active = null; RenderTexture.ReleaseTemporary(temporary); } return val; } private static Material DeepCopyMaterial(Material original) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown Material val = new Material(original.shader); val.CopyPropertiesFromMaterial(original); string[] texturePropertyNames = original.GetTexturePropertyNames(); foreach (string propertyName in texturePropertyNames) { CopyTextureIfExists(original, val, propertyName); } return val; } private static void CopyTextureIfExists(Material original, Material copy, string propertyName) { if (original.HasProperty(propertyName)) { Texture texture = original.GetTexture(propertyName); Texture2D val = (Texture2D)(object)((texture is Texture2D) ? texture : null); if (!((Object)(object)val == (Object)null)) { copy.SetTexture(propertyName, (Texture)(object)CopyTexture(val)); } } } private static void FixSharedMesh(MeshFilter meshFilter) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Expected O, but got Unknown if (!((Object)(object)meshFilter.sharedMesh == (Object)null)) { Mesh val = new Mesh { vertices = meshFilter.sharedMesh.vertices, triangles = meshFilter.sharedMesh.triangles, normals = meshFilter.sharedMesh.normals, uv = meshFilter.sharedMesh.uv, uv2 = meshFilter.sharedMesh.uv2, tangents = meshFilter.sharedMesh.tangents, colors = meshFilter.sharedMesh.colors, bindposes = meshFilter.sharedMesh.bindposes, boneWeights = meshFilter.sharedMesh.boneWeights, subMeshCount = meshFilter.sharedMesh.subMeshCount }; for (int i = 0; i < meshFilter.sharedMesh.subMeshCount; i++) { val.SetTriangles(meshFilter.sharedMesh.GetTriangles(i), i); } val.RecalculateBounds(); meshFilter.mesh = val; meshFilter.sharedMesh = val; } } } public class ShipTrophyStand : MonoBehaviour, Hoverable, Interactable { public string m_name = "$guardianstone_hook_name"; public Transform m_attachOther; public Transform m_dropSpawnPoint; public EffectList m_effects = new EffectList(); public EffectList m_destroyEffects = new EffectList(); [Header("Guardian power")] public float m_powerActivationDelay = 2f; public StatusEffect m_guardianPower; public EffectList m_activatePowerEffects = new EffectList(); public EffectList m_activatePowerEffectsPlayer = new EffectList(); public string m_visualName = ""; public int m_visualVariant; public GameObject m_visualItem; [NonSerialized] public string m_currentItemName = ""; public ItemData m_queuedItem; public ZNetView m_nview; public Piece m_piece; public static ItemType supportedItemType = (ItemType)13; private static readonly List tempItems = new List(); private static readonly StringBuilder sb = new StringBuilder(20); private static readonly Dictionary trophyEffects = new Dictionary(); public void Awake() { m_nview = ((Component)this).GetComponentInParent(); if (m_nview.IsValid()) { m_nview.Register("DropItem", (Action)RPC_DropItem); m_nview.Register("RequestOwn", (Action)RPC_RequestOwn); m_nview.Register("DestroyAttachment", (Action)RPC_DestroyAttachment); m_nview.Register("SetVisualItem", (Action)RPC_SetVisualItem); ((MonoBehaviour)this).InvokeRepeating("UpdateVisual", 1f, 4f); } if (trophyEffects.Count == 0) { FillTrophyEffects(); } m_piece = ((Component)this).GetComponentInParent(); } public string GetHoverText() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)Player.m_localPlayer)) { return ""; } if (!PrivateArea.CheckAccess(((Component)this).transform.position, 0f, false, false)) { return Localization.instance.Localize(m_name + "\n$piece_noaccess"); } sb.Clear(); if (HaveAttachment()) { sb.Append(m_currentItemName); if (!LongshipUpgrades.onlyCreatorStand.Value || (Object)(object)m_piece == (Object)null || m_piece.IsCreator()) { sb.Append("\n[$KEY_Use] $piece_itemstand_take"); } if (LongshipUpgrades.itemStandForsakenPower.Value && (Object)(object)m_guardianPower != (Object)null) { if (((MonoBehaviour)this).IsInvoking("DelayedPowerActivation")) { return ""; } sb.Append("\n"); sb.AppendFormat("\n{0}", m_guardianPower.m_name); if (IsGuardianPowerActive((Humanoid)(object)Player.m_localPlayer)) { sb.Append("\n$guardianstone_hook_power_activate"); } else if (IsGuardianPowerOnCooldown(Player.m_localPlayer)) { sb.Append("\n$hud_powernotready"); } else { string arg = ((!ZInput.IsNonClassicFunctionality() || !ZInput.IsGamepadActive()) ? "$KEY_AltPlace" : "$KEY_JoyAltKeys"); sb.AppendFormat("\n[{0} + $KEY_Use] $guardianstone_hook_activate", arg); } sb.Append("\n\n"); sb.Append(m_guardianPower.GetTooltipString()); } } else { sb.Append(m_name); if (!LongshipUpgrades.onlyCreatorStand.Value || (Object)(object)m_piece == (Object)null || m_piece.IsCreator()) { sb.Append("\n[$KEY_Use][1-8] $piece_itemstand_attach"); } } return Localization.instance.Localize(sb.ToString()); } public string GetHoverName() { return m_name; } public bool Interact(Humanoid user, bool hold, bool alt) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) if (hold) { return false; } if (!PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false)) { return true; } if (HaveAttachment()) { if (!alt) { if (!LongshipUpgrades.onlyCreatorStand.Value || (Object)(object)m_piece == (Object)null || m_piece.IsCreator()) { m_nview.InvokeRPC("DropItem", Array.Empty()); } return true; } if (LongshipUpgrades.itemStandForsakenPower.Value && (Object)(object)m_guardianPower != (Object)null) { if (((MonoBehaviour)this).IsInvoking("DelayedPowerActivation")) { return false; } if (IsGuardianPowerActive(user)) { return false; } if (IsGuardianPowerOnCooldown((Player)(object)((user is Player) ? user : null))) { return false; } ((Character)user).Message((MessageType)2, "$guardianstone_hook_power_activate", 0, (Sprite)null); m_activatePowerEffects.Create(((Component)this).transform.position, ((Component)this).transform.rotation, (Transform)null, 1f, -1); m_activatePowerEffectsPlayer.Create(((Component)user).transform.position, Quaternion.identity, ((Component)user).transform, 1f, -1); ((MonoBehaviour)this).Invoke("DelayedPowerActivation", m_powerActivationDelay); return true; } } else { if (!LongshipUpgrades.onlyCreatorStand.Value || (Object)(object)m_piece == (Object)null || m_piece.IsCreator()) { user.GetInventory().GetAllItems(supportedItemType, tempItems); if (tempItems.Count > 0) { UseItem(user, tempItems[0]); return true; } } ((Character)user).Message((MessageType)2, "$piece_itemstand_missingitem", 0, (Sprite)null); } return false; } public bool IsGuardianPowerActive(Humanoid user) { return ((Character)user).GetSEMan().HaveStatusEffect(m_guardianPower.m_nameHash); } public bool IsGuardianPowerOnCooldown(Player player) { return (Object)(object)player != (Object)null && player.GetGuardianPowerName() != "" && player.m_guardianPowerCooldown > 0f; } public void DelayedPowerActivation() { Player localPlayer = Player.m_localPlayer; if (Object.op_Implicit((Object)(object)localPlayer) && (Object)(object)m_guardianPower != (Object)null) { if (localPlayer.GetGuardianPowerName() == "") { localPlayer.SetGuardianPower(((Object)m_guardianPower).name); } ((Character)localPlayer).GetSEMan().AddStatusEffect(m_guardianPower, false, 0, 0f); localPlayer.m_guardianPowerCooldown = m_guardianPower.m_cooldown; } } public bool UseItem(Humanoid user, ItemData item) { if (HaveAttachment()) { return false; } if (!CanAttach(item)) { ((Character)user).Message((MessageType)2, "$piece_itemstand_cantattach", 0, (Sprite)null); return true; } if (!m_nview.IsOwner()) { m_nview.InvokeRPC("RequestOwn", Array.Empty()); } m_queuedItem = item; ((MonoBehaviour)this).CancelInvoke("UpdateAttach"); ((MonoBehaviour)this).InvokeRepeating("UpdateAttach", 0f, 0.1f); return true; } public void RPC_DropItem(long sender) { if (m_nview.IsOwner()) { DropItem(); } } public void DestroyAttachment() { m_nview.InvokeRPC("DestroyAttachment", Array.Empty()); } public void RPC_DestroyAttachment(long sender) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) if (m_nview.IsOwner() && HaveAttachment()) { m_nview.GetZDO().Set(ZDOVars.s_item, ""); m_nview.InvokeRPC(ZNetView.Everybody, "SetVisualItem", new object[3] { "", 0, 0 }); m_destroyEffects.Create(m_dropSpawnPoint.position, Quaternion.identity, (Transform)null, 1f, -1); } } public void DropItem() { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) if (!HaveAttachment()) { return; } string @string = m_nview.GetZDO().GetString(ZDOVars.s_item, ""); GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(@string); if (Object.op_Implicit((Object)(object)itemPrefab)) { Vector3 val = Vector3.zero; Quaternion val2 = Quaternion.identity; Transform val3 = itemPrefab.transform.Find("attach"); if (Object.op_Implicit((Object)(object)itemPrefab.transform.Find("attachobj")) && Object.op_Implicit((Object)(object)val3)) { val2 = ((Component)val3).transform.localRotation; val = ((Component)val3).transform.localPosition; } GameObject val4 = Object.Instantiate(itemPrefab, m_dropSpawnPoint.position + val, m_dropSpawnPoint.rotation * val2); val4.GetComponent().LoadFromExternalZDO(m_nview.GetZDO()); val4.GetComponent().linearVelocity = Vector3.up * 4f; m_effects.Create(m_dropSpawnPoint.position, Quaternion.identity, (Transform)null, 1f, -1); } m_nview.GetZDO().Set(ZDOVars.s_item, ""); m_nview.InvokeRPC(ZNetView.Everybody, "SetVisualItem", new object[3] { "", 0, 0 }); } public Transform GetAttach(ItemData item) { return m_attachOther; } public void UpdateAttach() { //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) if (m_nview.IsOwner()) { ((MonoBehaviour)this).CancelInvoke("UpdateAttach"); Player localPlayer = Player.m_localPlayer; if (m_queuedItem != null && (Object)(object)localPlayer != (Object)null && ((Humanoid)localPlayer).GetInventory().ContainsItem(m_queuedItem) && !HaveAttachment()) { ItemData val = m_queuedItem.Clone(); val.m_stack = 1; m_nview.GetZDO().Set(ZDOVars.s_item, ((Object)m_queuedItem.m_dropPrefab).name); ItemDrop.SaveToZDO(val, m_nview.GetZDO()); ((Humanoid)localPlayer).UnequipItem(m_queuedItem, true); ((Humanoid)localPlayer).GetInventory().RemoveOneItem(m_queuedItem); m_nview.InvokeRPC(ZNetView.Everybody, "SetVisualItem", new object[3] { ((Object)val.m_dropPrefab).name, val.m_variant, val.m_quality }); Transform attach = GetAttach(m_queuedItem); m_effects.Create(((Component)attach).transform.position, Quaternion.identity, (Transform)null, 1f, -1); Game.instance.IncrementPlayerStat((PlayerStatType)24, 1f); } m_queuedItem = null; } } public void RPC_RequestOwn(long sender) { if (m_nview.IsOwner()) { m_nview.GetZDO().SetOwner(sender); } } public void UpdateVisual() { if (!((Object)(object)m_nview == (Object)null) && m_nview.IsValid()) { string @string = m_nview.GetZDO().GetString(ZDOVars.s_item, ""); int @int = m_nview.GetZDO().GetInt(ZDOVars.s_variant, 0); int int2 = m_nview.GetZDO().GetInt(ZDOVars.s_quality, 1); SetVisualItem(@string, @int, int2); } } public void RPC_SetVisualItem(long sender, string itemName, int variant, int quality) { SetVisualItem(itemName, variant, quality); } public void SetVisualItem(string itemName, int variant, int quality) { //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) if (m_visualName == itemName && m_visualVariant == variant) { return; } m_visualName = itemName; m_visualVariant = variant; m_currentItemName = ""; m_guardianPower = (StatusEffect)(object)(trophyEffects.TryGetValue(itemName, out var value) ? value : null); if (m_visualName == "") { Object.Destroy((Object)(object)m_visualItem); return; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(itemName); if ((Object)(object)itemPrefab == (Object)null) { LongshipUpgrades.LogWarning("Missing item prefab " + itemName); return; } GameObject attachPrefab = GetAttachPrefab(itemPrefab); if ((Object)(object)attachPrefab == (Object)null) { LongshipUpgrades.LogWarning("Failed to get attach prefab for item " + itemName); return; } ItemDrop component = itemPrefab.GetComponent(); m_currentItemName = component.m_itemData.m_shared.m_name; Transform attach = GetAttach(component.m_itemData); GameObject attachGameObject = GetAttachGameObject(attachPrefab); m_visualItem = Object.Instantiate(attachGameObject, attach.position, attach.rotation, attach); m_visualItem.transform.localPosition = attachPrefab.transform.localPosition; m_visualItem.transform.localRotation = attachPrefab.transform.localRotation; m_visualItem.transform.localScale = Vector3.Scale(attachPrefab.transform.localScale, component.m_itemData.GetScale((float)quality)); if (TryFindScaleOverride(itemName, out var scale)) { m_visualItem.transform.localScale = Vector3.one * scale; } IEquipmentVisual componentInChildren = m_visualItem.GetComponentInChildren(); if (componentInChildren != null) { componentInChildren.Setup(m_visualVariant); } CollectionExtensions.DoIf((IEnumerable)m_visualItem.GetComponentsInChildren(), (Func)((Collider collider) => collider.enabled && !collider.isTrigger), (Action)Object.Destroy); } public bool CanAttach(ItemData item) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) if (LongshipUpgrades.onlyCreatorStand.Value && (Object)(object)m_piece != (Object)null && !m_piece.IsCreator()) { return false; } return (Object)(object)GetAttachPrefab(item.m_dropPrefab) != (Object)null && item.m_shared.m_itemType == supportedItemType; } public bool HaveAttachment() { return GetAttachedItem() != ""; } public string GetAttachedItem() { return m_nview.IsValid() ? m_nview.GetZDO().GetString(ZDOVars.s_item, "") : ""; } internal static bool TryFindScaleOverride(string itemName, out float scale) { string[] array = LongshipUpgrades.itemStandTrophyRescale.Value.Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries); foreach (string text in array) { string[] array2 = text.Split(new char[1] { ':' }, StringSplitOptions.RemoveEmptyEntries); if (array2.Length == 2 && array2[0] == itemName && float.TryParse(array2[1], out scale)) { return true; } } scale = 0f; return false; } public static GameObject GetAttachPrefab(GameObject item) { Transform obj = item.transform.Find("attach"); return (obj != null) ? ((Component)obj).gameObject : null; } public static GameObject GetAttachGameObject(GameObject prefab) { Transform obj = prefab.transform.Find("attachobj"); return ((obj != null) ? ((Component)obj).gameObject : null) ?? prefab; } internal static void FillTrophyEffects() { trophyEffects.Clear(); foreach (ItemStand item in from itemstand in Resources.FindObjectsOfTypeAll() where itemstand.m_guardianPower is SE_Stats && itemstand.m_supportedItems.Count == 1 && (Object)(object)itemstand.m_supportedItems[0] != (Object)null select itemstand) { Dictionary dictionary = trophyEffects; string name = ((Object)item.m_supportedItems[0]).name; StatusEffect guardianPower = item.m_guardianPower; dictionary[name] = (SE_Stats)(object)((guardianPower is SE_Stats) ? guardianPower : null); } } } public class ShipTurret : MonoBehaviour, Hoverable, Interactable { public string m_name = "$piece_turret"; public ZNetView m_nview; [Header("Turret")] public GameObject m_turretBody; public GameObject m_turretBodyArmed; public GameObject m_turretBodyUnarmed; public GameObject m_turretNeck; public GameObject m_eye; [Header("Look & Scan")] public float m_turnRate = 50f; public float m_horizontalAngle = 60f; public float m_verticalAngle = 70f; public float m_viewDistance = 30f; public float m_noTargetScanRate = 7f; public float m_lookAcceleration = 1.4f; public float m_lookDeacceleration = 0.05f; public float m_lookMinDegreesDelta = 0.005f; [Header("Attack Settings (rest in projectile)")] public ItemDrop m_defaultAmmo; public float m_attackCooldown = 2f; public float m_attackWarmup = 1f; public float m_hitNoise = 10f; public float m_shootWhenAimDiff = 0.99998f; public float m_predictionModifier = 2f; public float m_updateTargetIntervalNear = 1f; public float m_updateTargetIntervalFar = 4f; [Header("Ammo")] public int m_maxAmmo = 100; public string m_ammoType = "$ammo_turretbolt"; public List m_allowedAmmo = new List(); public bool m_returnAmmoOnDestroy = true; public float m_holdRepeatInterval = 0.2f; [Header("Target mode: Everything")] public bool m_targetEnemies = true; [Header("Target mode: Configured")] public bool m_targetTamedConfig = true; public List m_configTargets = new List(); public int m_maxConfigTargets = 1; public GameObject m_lastProjectile; public ItemData m_lastAmmo; public Character m_target; public bool m_haveTarget; public Quaternion m_lastRotation; public float m_aimDiffToTarget; public float m_updateTargetTimer; public float m_lastUseTime; public float m_scan; public readonly List m_targetItems = new List(); public readonly List m_targetCharacters = new List(); public string m_targetsText; public readonly StringBuilder sb = new StringBuilder(20); public uint m_lastUpdateTargetRevision = uint.MaxValue; public int m_scanDirection = 1; public float m_scanDistance = 1f; public bool m_isLeftTurret; public static readonly int s_lastAttackLeft = StringExtensionMethods.GetStableHashCode("lastAttackLeft"); public static readonly int s_lastAttackRight = StringExtensionMethods.GetStableHashCode("lastAttackRight"); public static readonly int s_targetsLeft = StringExtensionMethods.GetStableHashCode("targetsLeft"); public static readonly int s_targetsRight = StringExtensionMethods.GetStableHashCode("targetsRight"); [Header("Effects")] public static EffectList m_shootEffect = new EffectList(); public static EffectList m_addAmmoEffect = new EffectList(); public static EffectList m_reloadEffect = new EffectList(); public static EffectList m_warmUpStartEffect = new EffectList(); public static EffectList m_newTargetEffect = new EffectList(); public static EffectList m_lostTargetEffect = new EffectList(); public static EffectList m_setTargetEffect = new EffectList(); public GameObject m_destroyedLootPrefab; public ShipTurret SetPositionAtShip(bool isLeft) { m_isLeftTurret = isLeft; if (m_isLeftTurret) { m_scanDirection = -1; m_scan = m_noTargetScanRate * 0.05f; WearNTear componentInParent = ((Component)this).GetComponentInParent(); if (Object.op_Implicit((Object)(object)componentInParent)) { componentInParent.m_onDestroyed = (Action)Delegate.Combine(componentInParent.m_onDestroyed, new Action(OnDestroyed)); } } if (Object.op_Implicit((Object)(object)m_nview) && m_nview.IsValid()) { m_nview.Register(GetNameSetTargetRPC(), (Action)RPC_SetTarget); if (m_isLeftTurret) { m_nview.Register("RPC_AddAmmo", (Action)RPC_AddAmmo); } } return this; } public ShipTurret FillAllowedAmmo(List turretList) { //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_001c: 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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) foreach (AmmoType turret in turretList) { m_allowedAmmo.Add(new AmmoType { m_ammo = turret.m_ammo, m_visual = ((Component)m_turretBody.transform.Find(((Object)turret.m_visual).name)).gameObject }); } if (Object.op_Implicit((Object)(object)m_nview) && m_nview.IsValid()) { UpdateVisualBolt(); } return this; } public void Awake() { m_nview = ((Component)this).GetComponentInParent(); m_turretBody = ((Component)((Component)this).transform.Find("BodyRotation")).gameObject; m_turretBodyArmed = ((Component)((Component)this).transform.Find("BodyRotation/Body")).gameObject; m_turretBodyUnarmed = ((Component)((Component)this).transform.Find("BodyRotation/Body_Unarmed")).gameObject; m_turretNeck = ((Component)((Component)this).transform.Find("NeckRotation")).gameObject; m_eye = ((Component)((Component)this).transform.Find("BodyRotation/Eye")).gameObject; m_updateTargetTimer = Random.Range(0f, m_updateTargetIntervalNear); ReadTargets(); } public void FixedUpdate() { float fixedDeltaTime = Time.fixedDeltaTime; UpdateReloadState(); if (!m_nview.IsValid()) { return; } UpdateTurretRotation(fixedDeltaTime); UpdateVisualBolt(); if (!m_nview.IsOwner()) { if (m_nview.IsValid() && m_lastUpdateTargetRevision != m_nview.GetZDO().DataRevision) { m_lastUpdateTargetRevision = m_nview.GetZDO().DataRevision; ReadTargets(); } } else { UpdateTarget(fixedDeltaTime); UpdateAttack(); } } public void UpdateTurretRotation(float dt) { //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0353: Unknown result type (might be due to invalid IL or missing references) //IL_0358: Unknown result type (might be due to invalid IL or missing references) //IL_035a: Unknown result type (might be due to invalid IL or missing references) //IL_0379: Unknown result type (might be due to invalid IL or missing references) //IL_037e: Unknown result type (might be due to invalid IL or missing references) //IL_038c: Unknown result type (might be due to invalid IL or missing references) //IL_0391: Unknown result type (might be due to invalid IL or missing references) //IL_03a1: Unknown result type (might be due to invalid IL or missing references) //IL_03c4: Unknown result type (might be due to invalid IL or missing references) //IL_03d3: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_03e9: Unknown result type (might be due to invalid IL or missing references) //IL_03eb: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_031d: Unknown result type (might be due to invalid IL or missing references) //IL_0332: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Unknown result type (might be due to invalid IL or missing references) if (IsCoolingDown()) { return; } bool flag = false; Vector3 val2; Quaternion rotation; if (HasAmmoAndEnabled()) { flag = Object.op_Implicit((Object)(object)m_target); if (flag) { if (m_lastAmmo == null) { m_lastAmmo = GetAmmoItem(); } if (m_lastAmmo == null) { LongshipUpgrades.LogWarning("Turret had invalid ammo, resetting ammo"); m_nview.GetZDO().Set(ZDOVars.s_ammo, 0, false); return; } float num = Vector2.Distance(Vector2.op_Implicit(((Component)m_target).transform.position), Vector2.op_Implicit(m_eye.transform.position)) / m_lastAmmo.m_shared.m_attack.m_projectileVel; Vector3 val = m_target.GetVelocity() * num * m_predictionModifier; val2 = ((Component)m_target).transform.position + val - m_turretBody.transform.position; CapsuleCollider componentInChildren = ((Component)m_target).GetComponentInChildren(); val2.y += (Object.op_Implicit((Object)(object)componentInChildren) ? (componentInChildren.height / 2f) : 1f); } else { m_scan += dt; if (m_scan > m_noTargetScanRate * 2f) { m_scan = 0f; m_scanDistance = Random.Range(0.5f, 1f); } rotation = ((Component)this).transform.rotation; val2 = Quaternion.Euler(0f, ((Quaternion)(ref rotation)).eulerAngles.y + (float)((m_scan - m_noTargetScanRate > 0f) ? m_scanDirection : (-m_scanDirection)) * m_horizontalAngle * m_scanDistance, 0f) * Vector3.forward; } } else { val2 = ((Component)this).transform.forward + new Vector3(0f, -0.3f, 0f); } ((Vector3)(ref val2)).Normalize(); Quaternion val3 = Quaternion.LookRotation(val2, Vector3.up); Vector3 eulerAngles = ((Quaternion)(ref val3)).eulerAngles; rotation = ((Component)this).transform.rotation; float y = ((Quaternion)(ref rotation)).eulerAngles.y; eulerAngles.y -= y; if (m_horizontalAngle >= 0f) { float num2 = eulerAngles.y; if (num2 > 180f) { num2 -= 360f; } else if (num2 < -180f) { num2 += 360f; } if (num2 > m_horizontalAngle) { ((Vector3)(ref eulerAngles))..ctor(eulerAngles.x, m_horizontalAngle + y, eulerAngles.z); ((Quaternion)(ref val3)).eulerAngles = eulerAngles; } else if (num2 < 0f - m_horizontalAngle) { ((Vector3)(ref eulerAngles))..ctor(eulerAngles.x, 0f - m_horizontalAngle + y, eulerAngles.z); ((Quaternion)(ref val3)).eulerAngles = eulerAngles; } } Quaternion val4 = Utils.RotateTorwardsSmooth(m_turretBody.transform.rotation, val3, m_lastRotation, m_turnRate * dt, m_lookAcceleration, m_lookDeacceleration, m_lookMinDegreesDelta); m_lastRotation = m_turretBody.transform.rotation; m_turretBody.transform.rotation = val4; m_turretNeck.transform.localEulerAngles = new Vector3(0f, m_turretBody.transform.localEulerAngles.y, 0f); m_aimDiffToTarget = (flag ? Math.Abs(Quaternion.Dot(val4, val3)) : (-1f)); } public void UpdateTarget(float dt) { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) if (!m_nview.IsValid()) { return; } if (!HasAmmoAndEnabled()) { if (m_haveTarget) { m_nview.InvokeRPC(ZNetView.Everybody, GetNameSetTargetRPC(), new object[1] { ZDOID.None }); } return; } m_updateTargetTimer -= dt; if (m_updateTargetTimer <= 0f) { m_updateTargetTimer = (Character.IsCharacterInRange(((Component)this).transform.position, 40f) ? m_updateTargetIntervalNear : m_updateTargetIntervalFar); Character val = BaseAI.FindClosestCreature(((Component)this).transform, m_eye.transform.position, 0f, m_viewDistance, m_horizontalAngle, false, false, true, false, m_targetItems.Count > 0 && m_targetTamedConfig, m_targetEnemies, m_targetCharacters); if ((Object)(object)val != (Object)(object)m_target) { if (Object.op_Implicit((Object)(object)val)) { m_newTargetEffect.Create(((Component)this).transform.position, ((Component)this).transform.rotation, (Transform)null, 1f, -1); } else { m_lostTargetEffect.Create(((Component)this).transform.position, ((Component)this).transform.rotation, (Transform)null, 1f, -1); } m_nview.InvokeRPC(ZNetView.Everybody, GetNameSetTargetRPC(), new object[1] { Object.op_Implicit((Object)(object)val) ? val.GetZDOID() : ZDOID.None }); } } if (m_haveTarget && (!Object.op_Implicit((Object)(object)m_target) || m_target.IsDead())) { LongshipUpgrades.LogInfo("Target is gone"); m_nview.InvokeRPC(ZNetView.Everybody, GetNameSetTargetRPC(), new object[1] { ZDOID.None }); m_lostTargetEffect.Create(((Component)this).transform.position, ((Component)this).transform.rotation, (Transform)null, 1f, -1); } } public void UpdateAttack() { if (Object.op_Implicit((Object)(object)m_target) && !(m_aimDiffToTarget < m_shootWhenAimDiff) && HasAmmoAndEnabled() && !IsCoolingDown()) { ShootProjectile(); } } public void ShootProjectile() { //IL_0013: 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_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Expected O, but got Unknown //IL_02ad: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_031a: Unknown result type (might be due to invalid IL or missing references) Transform transform = m_eye.transform; m_shootEffect.Create(transform.position, transform.rotation, (Transform)null, 1f, -1); m_nview.GetZDO().Set(GetLastAttackZDO(), (float)ZNet.instance.GetTimeSeconds()); m_lastAmmo = GetAmmoItem(); int ammo = GetAmmo(); int num = Mathf.Min(1, (m_maxAmmo == 0) ? m_lastAmmo.m_shared.m_attack.m_projectiles : Mathf.Min(ammo, m_lastAmmo.m_shared.m_attack.m_projectiles)); if (m_maxAmmo > 0) { m_nview.GetZDO().Set(ZDOVars.s_ammo, ammo - num, false); } LongshipUpgrades.LogInfo($"Turret '{((Object)this).name}' is shooting {num} projectiles, ammo: {ammo}/{m_maxAmmo}"); for (int i = 0; i < num; i++) { Vector3 forward = transform.forward; Vector3 val = Vector3.Cross(forward, Vector3.up); float projectileAccuracy = m_lastAmmo.m_shared.m_attack.m_projectileAccuracy; Quaternion val2 = Quaternion.AngleAxis(Random.Range(0f - projectileAccuracy, projectileAccuracy), Vector3.up); forward = Quaternion.AngleAxis(Random.Range(0f - projectileAccuracy, projectileAccuracy), val) * forward; forward = val2 * forward; m_lastProjectile = Object.Instantiate(m_lastAmmo.m_shared.m_attack.m_attackProjectile, transform.position, transform.rotation); HitData val3 = new HitData { m_toolTier = (short)m_lastAmmo.m_shared.m_toolTier, m_pushForce = m_lastAmmo.m_shared.m_attackForce, m_backstabBonus = m_lastAmmo.m_shared.m_backstabBonus, m_staggerMultiplier = m_lastAmmo.m_shared.m_attack.m_staggerMultiplier, m_statusEffectHash = (Object.op_Implicit((Object)(object)m_lastAmmo.m_shared.m_attackStatusEffect) ? m_lastAmmo.m_shared.m_attackStatusEffect.NameHash() : 0), m_blockable = m_lastAmmo.m_shared.m_blockable, m_dodgeable = m_lastAmmo.m_shared.m_dodgeable, m_skill = m_lastAmmo.m_shared.m_skillType, m_itemWorldLevel = (byte)Game.m_worldLevel, m_hitType = (HitType)16 }; ((DamageTypes)(ref val3.m_damage)).Add(m_lastAmmo.GetDamage(), 1); if ((Object)(object)m_lastAmmo.m_shared.m_attackStatusEffect != (Object)null) { val3.m_statusEffectHash = m_lastAmmo.m_shared.m_attackStatusEffect.NameHash(); } IProjectile component = m_lastProjectile.GetComponent(); if (component != null) { component.Setup((Character)null, forward * m_lastAmmo.m_shared.m_attack.m_projectileVel, m_hitNoise, val3, (ItemData)null, m_lastAmmo); } } } public bool IsCoolingDown() { if (!m_nview.IsValid()) { return false; } return (double)(m_nview.GetZDO().GetFloat(GetLastAttackZDO(), 0f) + m_attackCooldown) > ZNet.instance.GetTimeSeconds(); } public bool HasAmmoAndEnabled() { return !IsDeactivated() && HasAmmo(); } public bool IsDeactivated() { return m_nview.GetZDO().GetBool(LongshipCustomizableParts.s_turretsDisabled, false); } public bool HasAmmo() { if (m_maxAmmo != 0) { return GetAmmo() > 0; } return true; } public int GetAmmo() { return m_nview.GetZDO().GetInt(ZDOVars.s_ammo, 0); } public string GetAmmoType() { if (!Object.op_Implicit((Object)(object)m_defaultAmmo)) { return m_nview.GetZDO().GetString(ZDOVars.s_ammoType, ""); } return ((Object)m_defaultAmmo).name; } public void UpdateReloadState() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) bool flag = IsCoolingDown(); if (!m_turretBodyArmed.activeInHierarchy && !flag) { m_reloadEffect.Create(((Component)this).transform.position, ((Component)this).transform.rotation, (Transform)null, 1f, -1); } m_turretBodyArmed.SetActive(!flag); m_turretBodyUnarmed.SetActive(flag); } public ItemData GetAmmoItem() { string ammoType = GetAmmoType(); GameObject prefab = ZNetScene.instance.GetPrefab(ammoType); if (!Object.op_Implicit((Object)(object)prefab)) { LongshipUpgrades.LogWarning("Turret '" + ((Object)this).name + "' is trying to fire but has no ammo or default ammo!"); return null; } return prefab.GetComponent().m_itemData; } public string GetHoverText() { //IL_0047: Unknown result type (might be due to invalid IL or missing references) if (!m_nview.IsValid()) { return ""; } if (!m_targetEnemies) { return Localization.instance.Localize(m_name); } if (!PrivateArea.CheckAccess(((Component)this).transform.position, 0f, false, false)) { return Localization.instance.Localize(m_name + "\n$piece_noaccess"); } sb.Clear(); sb.Append(m_name); if (IsDeactivated()) { sb.Append(" disabled"); } if (HasAmmo()) { sb.AppendFormat(" ({0} / {1})", GetAmmo(), m_maxAmmo); } else { sb.Append(" ($piece_turret_noammo)"); } if (m_targetCharacters.Count == 0) { sb.Append("\n$piece_turret_target $piece_turret_target_everything"); } else { sb.Append("\n$piece_turret_target "); sb.Append(m_targetsText); } sb.Append("\n[$KEY_Use] $piece_turret_addammo\n[1-8] $piece_turret_target_set"); return Localization.instance.Localize(sb.ToString()); } public string GetHoverName() { return m_name; } public bool Interact(Humanoid character, bool hold, bool alt) { if (hold) { if (m_holdRepeatInterval <= 0f) { return false; } if (Time.time - m_lastUseTime < m_holdRepeatInterval) { return false; } } m_lastUseTime = Time.time; return UseItem(character, null); } public bool UseItem(Humanoid user, ItemData item) { //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) if (item == null) { item = FindAmmoItem(user.GetInventory(), onlyCurrentlyLoadableType: true); if (item == null) { if (GetAmmo() > 0 && FindAmmoItem(user.GetInventory(), onlyCurrentlyLoadableType: false) != null) { ItemDrop component = ZNetScene.instance.GetPrefab(GetAmmoType()).GetComponent(); ((Character)user).Message((MessageType)2, Localization.instance.Localize("$msg_turretotherammo ") + Localization.instance.Localize(component.m_itemData.m_shared.m_name), 0, (Sprite)null); return false; } ((Character)user).Message((MessageType)2, "$msg_noturretammo", 0, (Sprite)null); return false; } } foreach (TrophyTarget configTarget in m_configTargets) { if (!(item.m_shared.m_name == configTarget.m_item.m_itemData.m_shared.m_name)) { continue; } if (m_targetItems.Contains(configTarget.m_item)) { m_targetItems.Remove(configTarget.m_item); } else { if (m_targetItems.Count >= m_maxConfigTargets) { m_targetItems.RemoveAt(0); } m_targetItems.Add(configTarget.m_item); } SetTargets(); ((Character)Player.m_localPlayer).Message((MessageType)2, Localization.instance.Localize("$piece_turret_target_set_msg " + ((m_targetCharacters.Count == 0) ? "$piece_turret_target_everything" : m_targetsText)), 0, (Sprite)null); m_setTargetEffect.Create(((Component)this).transform.position, ((Component)this).transform.rotation, (Transform)null, 1f, -1); Game.instance.IncrementPlayerStat((PlayerStatType)79, 1f); return true; } if (!IsItemAllowed(((Object)item.m_dropPrefab).name)) { ((Character)user).Message((MessageType)2, "$msg_wontwork", 0, (Sprite)null); return false; } if (GetAmmo() > 0 && GetAmmoType() != ((Object)item.m_dropPrefab).name) { ItemDrop component2 = ZNetScene.instance.GetPrefab(GetAmmoType()).GetComponent(); ((Character)user).Message((MessageType)2, Localization.instance.Localize("$msg_turretotherammo ") + Localization.instance.Localize(component2.m_itemData.m_shared.m_name), 0, (Sprite)null); return false; } LongshipUpgrades.LogInfo("trying to add ammo " + item.m_shared.m_name); if (GetAmmo() >= m_maxAmmo) { ((Character)user).Message((MessageType)2, "$msg_itsfull", 0, (Sprite)null); return false; } ((Character)user).Message((MessageType)2, "$msg_added " + item.m_shared.m_name, 0, (Sprite)null); if (!((Player)((user is Player) ? user : null)).NoCostCheat() && !ZoneSystem.instance.GetGlobalKey((GlobalKeys)20)) { user.GetInventory().RemoveItem(item, 1); } Game.instance.IncrementPlayerStat((PlayerStatType)78, 1f); m_nview.InvokeRPC("RPC_AddAmmo", new object[1] { ((Object)item.m_dropPrefab).name }); return true; } public void RPC_AddAmmo(long sender, string name) { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) if (!m_nview.IsOwner()) { return; } if (!IsItemAllowed(name)) { LongshipUpgrades.LogInfo("Item not allowed " + name); return; } m_nview.GetZDO().Set(ZDOVars.s_ammo, GetAmmo() + 1, false); m_nview.GetZDO().Set(ZDOVars.s_ammoType, name); ShipTurret[] componentsInChildren = ((Component)((Component)this).transform.parent).GetComponentsInChildren(); foreach (ShipTurret shipTurret in componentsInChildren) { m_addAmmoEffect.Create(shipTurret.m_turretBody.transform.position, shipTurret.m_turretBody.transform.rotation, (Transform)null, 1f, -1); } UpdateVisualBolt(); LongshipUpgrades.LogInfo("Added ammo " + name); } public void RPC_SetTarget(long sender, ZDOID character) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) GameObject val = ZNetScene.instance.FindInstance(character); if (Object.op_Implicit((Object)(object)val)) { Character component = val.GetComponent(); if (Object.op_Implicit((Object)(object)component)) { m_target = component; m_haveTarget = true; return; } } m_target = null; m_haveTarget = false; m_scan = 0f; } public void UpdateVisualBolt() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) string ammoType = GetAmmoType(); bool flag = HasAmmo() && !IsCoolingDown(); foreach (AmmoType item in m_allowedAmmo) { bool flag2 = ((Object)item.m_ammo).name == ammoType; item.m_visual.SetActive(flag2 && flag); } } public bool IsItemAllowed(string itemName) { //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) foreach (AmmoType item in m_allowedAmmo) { if (((Object)item.m_ammo).name == itemName) { return true; } } return false; } public ItemData FindAmmoItem(Inventory inventory, bool onlyCurrentlyLoadableType) { if (onlyCurrentlyLoadableType && HasAmmo()) { return inventory.GetAmmoItem(m_ammoType, GetAmmoType()); } return inventory.GetAmmoItem(m_ammoType, (string)null); } public void OnDestroyed() { if (m_nview.IsOwner() && m_returnAmmoOnDestroy) { DropAllItems(); } } public void DropAllItems() { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) int num = GetAmmo(); if (num <= 0) { return; } GameObject prefab = ZNetScene.instance.GetPrefab(GetAmmoType()); if (Object.op_Implicit((Object)(object)m_destroyedLootPrefab)) { Inventory val = SpawnContainer(m_destroyedLootPrefab); while (num > 0) { if (val.AddItem(prefab, 1)) { num--; continue; } if (!val.HaveEmptySlot()) { val = SpawnContainer(m_destroyedLootPrefab); continue; } break; } return; } while (num > 0) { Vector3 val2 = ((Component)this).transform.position + Vector3.up * 0.5f + Random.insideUnitSphere * 0.3f; Quaternion val3 = Quaternion.Euler(0f, (float)Random.Range(0, 360), 0f); ItemDrop component = Object.Instantiate(prefab, val2, val3).GetComponent(); if ((Object)(object)component == (Object)null) { break; } component.SetStack(num); num -= component.m_itemData.m_stack; } } public Inventory SpawnContainer(GameObject lootContainerPrefab) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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_0023: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ((Component)this).transform.position + Random.insideUnitSphere * 1f; return Object.Instantiate(lootContainerPrefab, val, Random.rotation).GetComponent().GetInventory(); } public void SetTargets() { if (!m_nview.IsOwner()) { m_nview.ClaimOwnership(); } m_nview.GetZDO().Set(GetTargetsZDO(), m_targetItems.Count, false); for (int i = 0; i < m_targetItems.Count; i++) { m_nview.GetZDO().Set(GetTargetZDO(i), m_targetItems[i].m_itemData.m_shared.m_name); } ReadTargets(); } public string GetNameSetTargetRPC() { return m_isLeftTurret ? "RPC_SetTargetLeft" : "RPC_SetTargetRight"; } public int GetTargetsZDO() { return m_isLeftTurret ? s_targetsLeft : s_targetsRight; } public int GetLastAttackZDO() { return m_isLeftTurret ? s_lastAttackLeft : s_lastAttackRight; } public string GetTargetZDO(int i) { return (m_isLeftTurret ? "targetleft" : "targetright") + i; } public void ReadTargets() { //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)m_nview) || !m_nview.IsValid()) { return; } m_targetItems.Clear(); m_targetCharacters.Clear(); m_targetsText = ""; int @int = m_nview.GetZDO().GetInt(GetTargetsZDO(), 0); for (int i = 0; i < @int; i++) { string @string = m_nview.GetZDO().GetString(GetTargetZDO(i), ""); foreach (TrophyTarget configTarget in m_configTargets) { if (!(configTarget.m_item.m_itemData.m_shared.m_name == @string)) { continue; } m_targetItems.Add(configTarget.m_item); m_targetCharacters.AddRange(configTarget.m_targets); if (m_targetsText.Length > 0) { m_targetsText += ", "; } if (!string.IsNullOrEmpty(configTarget.m_nameOverride)) { m_targetsText += configTarget.m_nameOverride; break; } for (int j = 0; j < configTarget.m_targets.Count; j++) { m_targetsText += configTarget.m_targets[j].m_name; if (j + 1 < configTarget.m_targets.Count) { m_targetsText += ", "; } } break; } } } } } namespace LocalizationManager { [PublicAPI] public class Localizer { [CompilerGenerated] private sealed class d__12 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__12(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitUntil((Func)(() => PlatformManager.DistributionPlatform != null && PlatformInitializer.PreferencesInitialized)); <>1__state = 1; return true; case 1: <>1__state = -1; if (string.IsNullOrEmpty(PlatformPrefs.GetString("language", ""))) { PlatformPrefs.SetString("language", "English"); } LoadLocalization(Localization.instance, Localization.instance.GetSelectedLanguage()); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private const string defaultLanguage = "English"; private static readonly Dictionary>> PlaceholderProcessors; private static readonly Dictionary> loadedTexts; private static readonly ConditionalWeakTable localizationLanguage; private static readonly List> localizationObjects; private static BaseUnityPlugin? _plugin; private static readonly List fileExtensions; private static BaseUnityPlugin Plugin { get { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown if (_plugin == null) { IEnumerable source; try { source = Assembly.GetExecutingAssembly().DefinedTypes.ToList(); } catch (ReflectionTypeLoadException ex) { source = from t in ex.Types where t != null select t.GetTypeInfo(); } _plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First((TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t))); } return _plugin; } } private static void UpdatePlaceholderText(Localization localization, string key) { localizationLanguage.TryGetValue(localization, out string value); string text = loadedTexts[value][key]; if (PlaceholderProcessors.TryGetValue(key, out Dictionary> value2)) { text = value2.Aggregate(text, (string current, KeyValuePair> kv) => current.Replace("{" + kv.Key + "}", kv.Value())); } localization.AddWord(key, text); } public static void AddPlaceholder(string key, string placeholder, ConfigEntry config, Func? convertConfigValue = null) where T : notnull { string key2 = key; string placeholder2 = placeholder; Func convertConfigValue2 = convertConfigValue; ConfigEntry config2 = config; if (convertConfigValue2 == null) { convertConfigValue2 = (T val) => val.ToString(); } if (!PlaceholderProcessors.ContainsKey(key2)) { PlaceholderProcessors[key2] = new Dictionary>(); } config2.SettingChanged += delegate { UpdatePlaceholder(); }; if (loadedTexts.ContainsKey(Localization.instance.GetSelectedLanguage())) { UpdatePlaceholder(); } void UpdatePlaceholder() { PlaceholderProcessors[key2][placeholder2] = () => convertConfigValue2(config2.Value); UpdatePlaceholderText(Localization.instance, key2); } } public static void AddText(string key, string text) { List> list = new List>(); foreach (WeakReference localizationObject in localizationObjects) { if (localizationObject.TryGetTarget(out var target)) { Dictionary dictionary = loadedTexts[localizationLanguage.GetOrCreateValue(target)]; if (!target.m_translations.ContainsKey(key)) { dictionary[key] = text; target.AddWord(key, text); } } else { list.Add(localizationObject); } } foreach (WeakReference item in list) { localizationObjects.Remove(item); } } [IteratorStateMachine(typeof(d__12))] public static IEnumerator Load() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__12(0); } private static void LoadLocalization(Localization __instance, string language) { //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Expected O, but got Unknown //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Expected O, but got Unknown if (!localizationLanguage.Remove(__instance)) { localizationObjects.Add(new WeakReference(__instance)); } localizationLanguage.Add(__instance, language); Dictionary localizationFiles = new Dictionary(); string[] prefixes = new string[2] { Plugin.Info.Metadata.Name + ".", Plugin.Info.Metadata.Name.Replace(" ", "") + "." }; Scan(Paths.ConfigPath, warn: true); Scan(Paths.PluginPath, warn: false); byte[] array = LoadTranslationFromAssembly("English"); if (array == null) { throw new Exception("Found no English localizations in mod " + Plugin.Info.Metadata.Name + ". Expected an embedded resource Translations/English.json or Translations/English.yml."); } Dictionary dictionary = ((BuilderSkeleton)new DeserializerBuilder()).IgnoreFields().Build().Deserialize>(Encoding.UTF8.GetString(array)); if (dictionary == null) { throw new Exception("Localization for mod " + Plugin.Info.Metadata.Name + " failed: Localization file was empty."); } string text = null; if (language != "English") { if (localizationFiles.ContainsKey(language)) { text = File.ReadAllText(localizationFiles[language]); } else { byte[] array2 = LoadTranslationFromAssembly(language); if (array2 != null) { text = Encoding.UTF8.GetString(array2); } } } if (text == null && localizationFiles.ContainsKey("English")) { text = File.ReadAllText(localizationFiles["English"]); } if (text != null) { Dictionary dictionary2; try { dictionary2 = ((BuilderSkeleton)new DeserializerBuilder()).IgnoreFields().Build().Deserialize>(text) ?? new Dictionary(); } catch (Exception arg) { global::LongshipUpgrades.LongshipUpgrades.LogInfo($"Failed to deserialize localization for language '{language}'. Using base localization only.\n{arg}"); dictionary2 = new Dictionary(); } foreach (KeyValuePair item in dictionary2) { dictionary[item.Key] = item.Value; } } loadedTexts[language] = dictionary; foreach (KeyValuePair item2 in dictionary) { UpdatePlaceholderText(__instance, item2.Key); } void Scan(string root, bool warn) { foreach (string item3 in from f in Directory.GetFiles(root, "*.*", SearchOption.AllDirectories) where fileExtensions.Contains(Path.GetExtension(f)) select f) { string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(item3); string[] array3 = prefixes; foreach (string text2 in array3) { if (fileNameWithoutExtension.StartsWith(text2)) { string text3 = fileNameWithoutExtension.Substring(text2.Length); if (!string.IsNullOrWhiteSpace(text3)) { if (localizationFiles.ContainsKey(text3)) { if (warn) { global::LongshipUpgrades.LongshipUpgrades.LogWarning("Duplicate localization '" + text3 + "' for " + Plugin.Info.Metadata.Name + ". Skipping " + item3); } } else { localizationFiles[text3] = item3; } } break; } } } } } static Localizer() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown PlaceholderProcessors = new Dictionary>>(); loadedTexts = new Dictionary>(); localizationLanguage = new ConditionalWeakTable(); localizationObjects = new List>(); fileExtensions = new List { ".json", ".yml" }; Harmony val = new Harmony("org.bepinex.helpers.LocalizationManager"); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "LoadCSV", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalization", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private static byte[]? LoadTranslationFromAssembly(string language) { foreach (string fileExtension in fileExtensions) { byte[] array = ReadEmbeddedFileBytes("translations." + language + fileExtension); if (array != null) { return array; } } return null; } public static byte[]? ReadEmbeddedFileBytes(string resourceFileName, Assembly? containingAssembly = null) { string resourceFileName2 = resourceFileName; using MemoryStream memoryStream = new MemoryStream(); if ((object)containingAssembly == null) { containingAssembly = Assembly.GetCallingAssembly(); } string text = containingAssembly.GetManifestResourceNames().FirstOrDefault((string str) => str.EndsWith(resourceFileName2, StringComparison.Ordinal)); if (text != null) { containingAssembly.GetManifestResourceStream(text)?.CopyTo(memoryStream); } return (memoryStream.Length == 0L) ? null : memoryStream.ToArray(); } } } 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 : OwnConfigEntryBase { public readonly ConfigEntry SourceConfig; public override ConfigEntryBase BaseConfig => (ConfigEntryBase)(object)SourceConfig; public T Value { get { return SourceConfig.Value; } set { SourceConfig.Value = value; } } public SyncedConfigEntry(ConfigEntry 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 : 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(configSync2.Name + " ConfigSync", (Action)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 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 CurrentList = new List(adminList.GetList()); while (true) { yield return (object)new WaitForSeconds(30f); if (!adminList.GetList().SequenceEqual(CurrentList)) { CurrentList = new List(adminList.GetList()); List 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 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(configSync.Name + " ConfigSync", (Action)configSync.RPC_FromServerConfigSync); } } } private class ParsedConfigs { public readonly Dictionary configValues = new Dictionary(); public readonly Dictionary customValues = new Dictionary(); } [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 Package = new List(); 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? __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(); } __state[Assembly.GetExecutingAssembly()] = bufferingSocket; } [HarmonyPostfix] private static void Postfix(Dictionary __state, ZNet __instance, ZRpc rpc) { ZRpc rpc2 = rpc; ZNet __instance2 = __instance; Dictionary __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 entries = new List(); 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 { 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 configSyncs; private readonly HashSet allConfigs = new HashSet(); private HashSet allCustomValues = new HashSet(); 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> configValueCache = new Dictionary>(); private readonly List> cacheExpirations = new List>(); 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? SourceOfTruthChanged; private event Action? lockedConfigChanged; static ConfigSync() { ProcessingServerUpdate = false; configSyncs = new HashSet(); lockExempt = false; packageCounter = 0L; RuntimeHelpers.RunClassConstructor(typeof(VersionCheck).TypeHandle); } public ConfigSync(string name) { Name = name; configSyncs.Add(this); new VersionCheck(this); } public SyncedConfigEntry AddConfigEntry(ConfigEntry configEntry) { ConfigEntry configEntry2 = configEntry; OwnConfigEntryBase ownConfigEntryBase = configData((ConfigEntryBase)(object)configEntry2); SyncedConfigEntry syncedEntry = ownConfigEntryBase as SyncedConfigEntry; if (syncedEntry == null) { syncedEntry = new SyncedConfigEntry(configEntry2); AccessTools.DeclaredField(typeof(ConfigDescription), "k__BackingField").SetValue(((ConfigEntryBase)configEntry2).Description, new object[1] { new ConfigurationManagerAttributes() }.Concat(((ConfigEntryBase)configEntry2).Description.Tags ?? Array.Empty()).Concat(new SyncedConfigEntry[1] { syncedEntry }).ToArray()); configEntry2.SettingChanged += delegate { if (!ProcessingServerUpdate && syncedEntry.SynchronizedConfig) { Broadcast(ZRoutedRpc.Everybody, (ConfigEntryBase)configEntry2); } }; allConfigs.Add(syncedEntry); } return syncedEntry; } public SyncedConfigEntry AddLockingConfigEntry(ConfigEntry lockingConfig) where T : IConvertible { if (lockedConfig != null) { throw new Exception("Cannot initialize locking ConfigEntry twice"); } lockedConfig = AddConfigEntry(lockingConfig); lockingConfig.SettingChanged += delegate { this.lockedConfigChanged?.Invoke(); }; return (SyncedConfigEntry)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(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 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 value)) { value = new SortedDictionary(); configValueCache[text2] = value; cacheExpirations.Add(new KeyValuePair(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 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 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 dictionary = allConfigs.Where((OwnConfigEntryBase c) => c.SynchronizedConfig).ToDictionary((OwnConfigEntryBase c) => c.BaseConfig.Definition.Section + "_" + c.BaseConfig.Definition.Key, (OwnConfigEntryBase c) => c); Dictionary 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(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 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 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().GetEnumerator(); } List list = (List)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 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> writers = (from peer in peers where peer.IsReady() select peer into p select distributeConfigToPeers(p, package2)).ToList(); writers.RemoveAll((IEnumerator writer) => !writer.MoveNext()); while (writers.Count > 0) { yield return null; writers.RemoveAll((IEnumerator 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().SingleOrDefault(); } public static SyncedConfigEntry? ConfigData(ConfigEntry config) { return ((ConfigEntryBase)config).Description.Tags?.OfType>().SingleOrDefault(); } private static T configAttribute(ConfigEntryBase config) { return config.Description.Tags.OfType().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? configs = null, IEnumerable? customValues = null, IEnumerable? 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 list = configs?.Where((ConfigEntryBase config) => configData(config).SynchronizedConfig).ToList() ?? new List(); List list2 = customValues?.ToList() ?? new List(); 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()) { 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(fieldInfo.FieldType)) { throw new InvalidDeserializationTypeException { received = text, expected = GetZPackageTypeString(fieldInfo.FieldType), field = fieldInfo.Name }; } fieldInfo.SetValue(uninitializedObject, ReadValueWithTypeFromZPackage(package, fieldInfo.FieldType)); } return uninitializedObject; } if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<, >)) { int num2 = package.ReadInt(); IDictionary dictionary = (IDictionary)Activator.CreateInstance(type); Type type2 = typeof(KeyValuePair<, >).MakeGenericType(type.GenericTypeArguments); FieldInfo field = type2.GetField("key", BindingFlags.Instance | BindingFlags.NonPublic); FieldInfo field2 = type2.GetField("value", BindingFlags.Instance | BindingFlags.NonPublic); for (int j = 0; j < num2; j++) { object obj = ReadValueWithTypeFromZPackage(package, type2); dictionary.Add(field.GetValue(obj), field2.GetValue(obj)); } return dictionary; } if (type != typeof(List) && type.IsGenericType) { Type type3 = typeof(ICollection<>).MakeGenericType(type.GenericTypeArguments[0]); if ((object)type3 != null && type3.IsAssignableFrom(type)) { int num3 = package.ReadInt(); object obj2 = Activator.CreateInstance(type); MethodInfo method = type3.GetMethod("Add"); for (int k = 0; k < num3; k++) { method.Invoke(obj2, new object[1] { ReadValueWithTypeFromZPackage(package, type.GenericTypeArguments[0]) }); } return obj2; } } ParameterInfo parameterInfo = (ParameterInfo)FormatterServices.GetUninitializedObject(typeof(ParameterInfo)); AccessTools.DeclaredField(typeof(ParameterInfo), "ClassImpl").SetValue(parameterInfo, type); List source = new List(); ZRpc.Deserialize(new ParameterInfo[2] { null, parameterInfo }, package, ref source); return source.First(); } } [PublicAPI] [HarmonyPatch] internal class VersionCheck { private static readonly HashSet versionChecks; private static readonly Dictionary notProcessedNames; public string Name; private string? displayName; private string? currentVersion; private string? minimumRequiredVersion; public bool ModRequired = true; private string? ReceivedCurrentVersion; private string? ReceivedMinimumRequiredVersion; private readonly List ValidatedClients = new List(); private ConfigSync? ConfigSync; public string DisplayName { get { return displayName ?? Name; } set { displayName = value; } } public string CurrentVersion { get { return currentVersion ?? "0.0.0"; } set { currentVersion = value; } } public string MinimumRequiredVersion { get { return minimumRequiredVersion ?? (ModRequired ? CurrentVersion : "0.0.0"); } set { minimumRequiredVersion = value; } } private static void PatchServerSync() { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown Patches patchInfo = PatchProcessor.GetPatchInfo((MethodBase)AccessTools.DeclaredMethod(typeof(ZNet), "Awake", (Type[])null, (Type[])null)); if (patchInfo != null && patchInfo.Postfixes.Count((Patch p) => p.PatchMethod.DeclaringType == typeof(ConfigSync.RegisterRPCPatch)) > 0) { return; } Harmony val = new Harmony("org.bepinex.helpers.ServerSync"); foreach (Type item in from t in typeof(ConfigSync).GetNestedTypes(BindingFlags.NonPublic).Concat(new Type[1] { typeof(VersionCheck) }) where t.IsClass select t) { val.PatchAll(item); } } static VersionCheck() { versionChecks = new HashSet(); notProcessedNames = new Dictionary(); typeof(ThreadingHelper).GetMethod("StartSyncInvoke").Invoke(ThreadingHelper.Instance, new object[1] { new Action(PatchServerSync) }); } public VersionCheck(string name) { Name = name; ModRequired = true; versionChecks.Add(this); } public VersionCheck(ConfigSync configSync) { ConfigSync = configSync; Name = ConfigSync.Name; versionChecks.Add(this); } public void Initialize() { ReceivedCurrentVersion = null; ReceivedMinimumRequiredVersion = null; if (ConfigSync != null) { Name = ConfigSync.Name; DisplayName = ConfigSync.DisplayName; CurrentVersion = ConfigSync.CurrentVersion; MinimumRequiredVersion = ConfigSync.MinimumRequiredVersion; ModRequired = ConfigSync.ModRequired; } } private bool IsVersionOk() { if (ReceivedMinimumRequiredVersion == null || ReceivedCurrentVersion == null) { return !ModRequired; } bool flag = new Version(CurrentVersion) >= new Version(ReceivedMinimumRequiredVersion); bool flag2 = new Version(ReceivedCurrentVersion) >= new Version(MinimumRequiredVersion); return flag && flag2; } private string ErrorClient() { if (ReceivedMinimumRequiredVersion == null) { return DisplayName + " is not installed on the server."; } return (new Version(CurrentVersion) >= new Version(ReceivedMinimumRequiredVersion)) ? (DisplayName + " may not be higher than version " + ReceivedCurrentVersion + ". You have version " + CurrentVersion + ".") : (DisplayName + " needs to be at least version " + ReceivedMinimumRequiredVersion + ". You have version " + CurrentVersion + "."); } private string ErrorServer(ZRpc rpc) { return "Disconnect: The client (" + rpc.GetSocket().GetHostName() + ") doesn't have the correct " + DisplayName + " version " + MinimumRequiredVersion; } private string Error(ZRpc? rpc = null) { return (rpc == null) ? ErrorClient() : ErrorServer(rpc); } private static VersionCheck[] GetFailedClient() { return versionChecks.Where((VersionCheck check) => !check.IsVersionOk()).ToArray(); } private static VersionCheck[] GetFailedServer(ZRpc rpc) { ZRpc rpc2 = rpc; return versionChecks.Where((VersionCheck check) => check.ModRequired && !check.ValidatedClients.Contains(rpc2)).ToArray(); } private static void Logout() { Game.instance.Logout(true, true); AccessTools.DeclaredField(typeof(ZNet), "m_connectionStatus").SetValue(null, (object)(ConnectionStatus)3); } private static void DisconnectClient(ZRpc rpc) { rpc.Invoke("Error", new object[1] { 3 }); } private static void CheckVersion(ZRpc rpc, ZPackage pkg) { CheckVersion(rpc, pkg, null); } private static void CheckVersion(ZRpc rpc, ZPackage pkg, Action? original) { string text = pkg.ReadString(); string text2 = pkg.ReadString(); string text3 = pkg.ReadString(); bool flag = false; foreach (VersionCheck versionCheck in versionChecks) { if (!(text != versionCheck.Name)) { Debug.Log((object)("Received " + versionCheck.DisplayName + " version " + text3 + " and minimum version " + text2 + " from the " + (ZNet.instance.IsServer() ? "client" : "server") + ".")); versionCheck.ReceivedMinimumRequiredVersion = text2; versionCheck.ReceivedCurrentVersion = text3; if (ZNet.instance.IsServer() && versionCheck.IsVersionOk()) { versionCheck.ValidatedClients.Add(rpc); } flag = true; } } if (flag) { return; } pkg.SetPos(0); if (original != null) { original(rpc, pkg); if (pkg.GetPos() == 0) { notProcessedNames.Add(text, text3); } } } [HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")] [HarmonyPrefix] private static bool RPC_PeerInfo(ZRpc rpc, ZNet __instance) { VersionCheck[] array = (__instance.IsServer() ? GetFailedServer(rpc) : GetFailedClient()); if (array.Length == 0) { return true; } VersionCheck[] array2 = array; foreach (VersionCheck versionCheck in array2) { Debug.LogWarning((object)versionCheck.Error(rpc)); } if (__instance.IsServer()) { DisconnectClient(rpc); } else { Logout(); } return false; } [HarmonyPatch(typeof(ZNet), "OnNewConnection")] [HarmonyPrefix] private static void RegisterAndCheckVersion(ZNetPeer peer, ZNet __instance) { //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Expected O, but got Unknown notProcessedNames.Clear(); IDictionary dictionary = (IDictionary)typeof(ZRpc).GetField("m_functions", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(peer.m_rpc); if (dictionary.Contains(StringExtensionMethods.GetStableHashCode("ServerSync VersionCheck"))) { object obj = dictionary[StringExtensionMethods.GetStableHashCode("ServerSync VersionCheck")]; Action action = (Action)obj.GetType().GetField("m_action", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(obj); peer.m_rpc.Register("ServerSync VersionCheck", (Action)delegate(ZRpc rpc, ZPackage pkg) { CheckVersion(rpc, pkg, action); }); } else { peer.m_rpc.Register("ServerSync VersionCheck", (Action)CheckVersion); } foreach (VersionCheck versionCheck in versionChecks) { versionCheck.Initialize(); if (versionCheck.ModRequired || __instance.IsServer()) { Debug.Log((object)("Sending " + versionCheck.DisplayName + " version " + versionCheck.CurrentVersion + " and minimum version " + versionCheck.MinimumRequiredVersion + " to the " + (__instance.IsServer() ? "client" : "server") + ".")); ZPackage val = new ZPackage(); val.Write(versionCheck.Name); val.Write(versionCheck.MinimumRequiredVersion); val.Write(versionCheck.CurrentVersion); peer.m_rpc.Invoke("ServerSync VersionCheck", new object[1] { val }); } } } [HarmonyPatch(typeof(ZNet), "Disconnect")] [HarmonyPrefix] private static void RemoveDisconnected(ZNetPeer peer, ZNet __instance) { if (!__instance.IsServer()) { return; } foreach (VersionCheck versionCheck in versionChecks) { versionCheck.ValidatedClients.Remove(peer.m_rpc); } } [HarmonyPatch(typeof(FejdStartup), "ShowConnectError")] [HarmonyPostfix] private static void ShowConnectionError(FejdStartup __instance) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) if (!__instance.m_connectionFailedPanel.activeSelf || (int)ZNet.GetConnectionStatus() != 3) { return; } bool flag = false; VersionCheck[] failedClient = GetFailedClient(); if (failedClient.Length != 0) { string text = string.Join("\n", failedClient.Select((VersionCheck check) => check.Error())); TMP_Text connectionFailedError = __instance.m_connectionFailedError; connectionFailedError.text = connectionFailedError.text + "\n" + text; flag = true; } foreach (KeyValuePair item in notProcessedNames.OrderBy, string>((KeyValuePair kv) => kv.Key)) { if (!__instance.m_connectionFailedError.text.Contains(item.Key)) { TMP_Text connectionFailedError2 = __instance.m_connectionFailedError; connectionFailedError2.text = connectionFailedError2.text + "\nServer expects you to have " + item.Key + " (Version: " + item.Value + ") installed."; flag = true; } } if (flag) { RectTransform component = ((Component)__instance.m_connectionFailedPanel.transform.Find("Image")).GetComponent(); Vector2 sizeDelta = component.sizeDelta; sizeDelta.x = 675f; component.sizeDelta = sizeDelta; __instance.m_connectionFailedError.ForceMeshUpdate(false, false); float num = __instance.m_connectionFailedError.renderedHeight + 105f; RectTransform component2 = ((Component)((Component)component).transform.Find("ButtonOk")).GetComponent(); component2.anchoredPosition = new Vector2(component2.anchoredPosition.x, component2.anchoredPosition.y - (num - component.sizeDelta.y) / 2f); sizeDelta = component.sizeDelta; sizeDelta.y = num; component.sizeDelta = sizeDelta; } } } }