using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Extensions; using HarmonyLib; using Mirror; using MoreMountains.Feedbacks; using MoreMountains.Tools; using TryConnect.Utils; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("TryConnect")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("TryConnect")] [assembly: AssemblyCopyright("Copyright © 2023")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("763c314a-61d3-4716-bc7f-118e5a9364ce")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] namespace TryConnect { [DisallowMultipleComponent] public sealed class TryConnectInteractableProxy : MonoBehaviour, IInteractable { [SerializeField] private MonoBehaviour _targetBehaviour; private IInteractable Target { get { if ((Object)(object)_targetBehaviour == (Object)null || !(_targetBehaviour is IInteractable)) { _targetBehaviour = ResolveTargetBehaviour(); } MonoBehaviour targetBehaviour = _targetBehaviour; return (IInteractable)(object)((targetBehaviour is IInteractable) ? targetBehaviour : null); } } public float HoldDuration { get { return (Target != null) ? Target.HoldDuration : 0f; } set { IInteractable target = Target; if (target != null) { target.HoldDuration = value; } } } public bool HoldInteract { get { return Target != null && Target.HoldInteract; } set { IInteractable target = Target; if (target != null) { target.HoldInteract = value; } } } public bool IsInteractable { get { return Target != null && Target.IsInteractable; } set { IInteractable target = Target; if (target != null) { target.IsInteractable = value; } } } public bool MeetRequirements { get { return Target != null && Target.MeetRequirements; } set { IInteractable target = Target; if (target != null) { target.MeetRequirements = value; } } } public bool IsBeingHovered { get { return Target != null && Target.IsBeingHovered; } set { IInteractable target = Target; if (target != null) { target.IsBeingHovered = value; } } } public bool IsBeingHold { get { return Target != null && Target.IsBeingHold; } set { IInteractable target = Target; if (target != null) { target.IsBeingHold = value; } } } public float HoldProgress { get { return (Target != null) ? Target.HoldProgress : 0f; } set { IInteractable target = Target; if (target != null) { target.HoldProgress = value; } } } public string TooltipMessage { get { return (Target != null) ? Target.TooltipMessage : string.Empty; } set { IInteractable target = Target; if (target != null) { target.TooltipMessage = value; } } } public string InteractableName { get { return (Target != null) ? Target.InteractableName : string.Empty; } set { IInteractable target = Target; if (target != null) { target.InteractableName = value; } } } public CursorType CursorType { get { //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_001a: Unknown result type (might be due to invalid IL or missing references) return (CursorType)((Target != null) ? ((int)Target.CursorType) : 0); } set { //IL_0012: Unknown result type (might be due to invalid IL or missing references) IInteractable target = Target; if (target != null) { target.CursorType = value; } } } public event Action OnInteractableChanged { add { IInteractable target = Target; if (target != null) { target.OnInteractableChanged += value; } } remove { IInteractable target = Target; if (target != null) { target.OnInteractableChanged -= value; } } } internal void Bind(MonoBehaviour targetBehaviour) { _targetBehaviour = targetBehaviour; } public void OnHover(PlayerInteract playerInteract) { IInteractable target = Target; if (target != null) { target.OnHover(playerInteract); } } public void ServerOnHover(PlayerInteract playerInteract) { IInteractable target = Target; if (target != null) { target.ServerOnHover(playerInteract); } } public void OnHoverExit(PlayerInteract playerInteract) { IInteractable target = Target; if (target != null) { target.OnHoverExit(playerInteract); } } public void ServerOnHoverExit(PlayerInteract playerInteract) { IInteractable target = Target; if (target != null) { target.ServerOnHoverExit(playerInteract); } } public void OnHold(PlayerInteract playerInteract) { IInteractable target = Target; if (target != null) { target.OnHold(playerInteract); } } public void ServerOnHold(PlayerInteract playerInteract) { IInteractable target = Target; if (target != null) { target.ServerOnHold(playerInteract); } } public void OnHoldExit(PlayerInteract playerInteract) { IInteractable target = Target; if (target != null) { target.OnHoldExit(playerInteract); } } public void ServerOnHoldExit(PlayerInteract playerInteract) { IInteractable target = Target; if (target != null) { target.ServerOnHoldExit(playerInteract); } } public void OnInteract(PlayerInteract playerInteract) { IInteractable target = Target; if (target != null) { target.OnInteract(playerInteract); } } public void ServerOnInteract(PlayerInteract playerInteract) { IInteractable target = Target; if (target != null) { target.ServerOnInteract(playerInteract); } } public void RpcOnInteract(PlayerInteract playerInteract) { IInteractable target = Target; if (target != null) { target.RpcOnInteract(playerInteract); } } private MonoBehaviour ResolveTargetBehaviour() { Transform parent = ((Component)this).transform.parent; while ((Object)(object)parent != (Object)null) { MonoBehaviour[] components = ((Component)parent).GetComponents(); foreach (MonoBehaviour val in components) { if ((Object)(object)val != (Object)null && val is IInteractable) { return val; } } parent = parent.parent; } return null; } } internal static class RuntimeItemRegistry { private sealed class CustomItemDefinition { internal string OwnerGuid; internal string Key; internal uint AssetId; internal GameObject BasePrefab; internal GameObject SpawnPrefab; internal int BasePrice; internal string Description; internal string DisplayName; internal GameObject MarkerPrefab; internal bool ApplyTint; internal Vector3 ModelScaleMultiplier; internal int PriceIncreasePerFloor; internal int ReplacementChancePercent; internal SpawnableSO Spawnable; internal Color Tint; } private sealed class CustomItemRequest { internal string OwnerGuid; internal string Key; internal int SpawnableId; internal uint AssetId; internal string DisplayName; internal string Description; internal SpawnableSO BaseSpawnable; internal int BaseSpawnableId; internal Type BaseItemComponentType; internal GameObject CustomPrefab; internal GameObject MarkerPrefab; internal bool ApplyTint; internal Color Tint; internal Vector3 ModelScaleMultiplier; internal int ReplacementChancePercent; internal int ExtraBasePrice; internal int ExtraFloorPrice; internal bool HasLoggedBuildFailure; } private const int TicketFizzSpawnableId = 900001; private const int LoadedChipSpawnableId = 900002; private static readonly Dictionary RequestsBySpawnableId = new Dictionary(); private static readonly Dictionary RequestsByUniqueKey = new Dictionary(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary RequestsByAssetId = new Dictionary(); private static readonly Dictionary DefinitionsBySpawnableId = new Dictionary(); private static readonly Dictionary DefinitionsByAssetId = new Dictionary(); private static readonly Dictionary DefinitionsByMarkerPrefab = new Dictionary(); private static readonly Dictionary> DefinitionsByBasePrefab = new Dictionary>(); private static readonly MethodInfo SetParentHierarchyAfterDelayMethod = AccessTools.Method(typeof(ItemStamp), "SetParentHierarchyAfterDelay", (Type[])null, (Type[])null); private static readonly FieldInfo AssetIdField = AccessTools.Field(typeof(NetworkIdentity), "_assetId"); private static readonly FieldInfo SpawnHandlersField = AccessTools.Field(typeof(NetworkClient), "spawnHandlers"); private static TryConnectPlugin _plugin; private static bool _builtInRegistrationsAdded; internal static void Initialize(TryConnectPlugin plugin) { _plugin = plugin; EnsureBuiltInRegistrations(); } internal static void Dispose() { foreach (CustomItemDefinition value in DefinitionsBySpawnableId.Values) { NetworkClient.UnregisterSpawnHandler(value.AssetId); if ((Object)(object)value.MarkerPrefab != (Object)null) { Object.Destroy((Object)(object)value.MarkerPrefab); } if ((Object)(object)value.Spawnable != (Object)null) { Object.Destroy((Object)(object)value.Spawnable); } } RequestsBySpawnableId.Clear(); RequestsByUniqueKey.Clear(); RequestsByAssetId.Clear(); DefinitionsBySpawnableId.Clear(); DefinitionsByAssetId.Clear(); DefinitionsByMarkerPrefab.Clear(); DefinitionsByBasePrefab.Clear(); _builtInRegistrationsAdded = false; _plugin = null; } internal static TryConnectRegistrationResult RegisterCustomItem(TryConnectItemRegistration registration) { EnsureBuiltInRegistrations(); if (!TryNormalizeRegistration(registration)) { return TryConnectRegistrationResult.InvalidRegistration; } string key = BuildUniqueKey(registration.OwnerGuid, registration.Key); if (RequestsByUniqueKey.ContainsKey(key) || RequestsBySpawnableId.ContainsKey(registration.SpawnableId)) { return TryConnectRegistrationResult.AlreadyRegistered; } AddRequest(CreateRequest(registration)); TryRegisterRuntimeContent(); return TryConnectRegistrationResult.Accepted; } internal static void TryRegisterRuntimeContent() { EnsureBuiltInRegistrations(); if ((Object)(object)_plugin == (Object)null) { return; } SpawnableSettings val = Resources.Load("SpawnableSettings"); if ((Object)(object)val == (Object)null || !val.isEnabled) { return; } ItemPriceSettings priceSettings = Resources.Load("ItemPriceSettings"); bool flag = false; foreach (CustomItemRequest value in RequestsBySpawnableId.Values) { flag |= EnsureDefinition(val, priceSettings, value); } TryEnsureAllClientRegistrations(); if (flag) { val.NotifyChanged(); TryConnectPlugin.Log.LogInfo((object)$"Registered {DefinitionsBySpawnableId.Count} runtime custom item(s)."); } } internal static void TryEnsureAllClientRegistrations() { foreach (CustomItemDefinition value in DefinitionsBySpawnableId.Values) { EnsureClientSpawnHandler(value); } } internal static void TryEnsureClientRegistration(uint assetId) { if (!DefinitionsByAssetId.TryGetValue(assetId, out var value)) { value = TryBuildDefinitionForAssetId(assetId); } if (value != null) { EnsureClientSpawnHandler(value); } } internal static SpawnableSO GetCustomSpawnable(int id) { if (!DefinitionsBySpawnableId.TryGetValue(id, out var value)) { value = TryBuildDefinitionForSpawnableId(id); } return value?.Spawnable; } internal static bool TryGetRegisteredItemInfo(int spawnableId, out TryConnectRegisteredItemInfo itemInfo) { itemInfo = null; if (!RequestsBySpawnableId.TryGetValue(spawnableId, out var value)) { return false; } CustomItemDefinition value2; bool flag = DefinitionsBySpawnableId.TryGetValue(spawnableId, out value2); itemInfo = new TryConnectRegisteredItemInfo(value.OwnerGuid, value.Key, value.SpawnableId, value.AssetId, value.DisplayName, value.Description, flag ? value2.Spawnable : null, flag); return true; } internal static TryConnectRegisteredItemInfo[] GetRegisteredItemInfos() { List list = new List(RequestsBySpawnableId.Count); foreach (CustomItemRequest value2 in RequestsBySpawnableId.Values) { CustomItemDefinition value; bool flag = DefinitionsBySpawnableId.TryGetValue(value2.SpawnableId, out value); list.Add(new TryConnectRegisteredItemInfo(value2.OwnerGuid, value2.Key, value2.SpawnableId, value2.AssetId, value2.DisplayName, value2.Description, flag ? value.Spawnable : null, flag)); } list.Sort((TryConnectRegisteredItemInfo left, TryConnectRegisteredItemInfo right) => left.SpawnableId.CompareTo(right.SpawnableId)); return list.ToArray(); } internal static bool TryGetVanillaSpawnable(int spawnableId, out SpawnableSO spawnable) { spawnable = null; SpawnableSettings val = Resources.Load("SpawnableSettings"); if ((Object)(object)val == (Object)null) { return false; } return TryFindSpawnable(val, (SpawnableSO candidate) => (Object)(object)candidate != (Object)null && candidate.spawnableID == spawnableId, out spawnable); } internal static bool TryFindVanillaSpawnable(string searchTerm, out SpawnableSO spawnable) { spawnable = null; if (string.IsNullOrWhiteSpace(searchTerm)) { return false; } SpawnableSettings val = Resources.Load("SpawnableSettings"); if ((Object)(object)val == (Object)null) { return false; } string trimmed = searchTerm.Trim(); return TryFindSpawnable(val, delegate(SpawnableSO candidate) { if ((Object)(object)candidate == (Object)null) { return false; } if (string.Equals(candidate.spawnableName, trimmed, StringComparison.OrdinalIgnoreCase)) { return true; } return string.Equals(((Object)candidate).name, trimmed, StringComparison.OrdinalIgnoreCase) || ((Object)(object)candidate.prefab != (Object)null && string.Equals(((Object)candidate.prefab).name, trimmed, StringComparison.OrdinalIgnoreCase)); }, out spawnable); } internal static bool TryGetCustomBasePrice(SpawnableSO spawnableSO, ref int basePrice) { if (!TryGetDefinition(spawnableSO, out var definition)) { definition = TryBuildDefinitionForSpawnableId(((Object)(object)spawnableSO != (Object)null) ? spawnableSO.spawnableID : 0); if (definition == null) { return false; } } basePrice = definition.BasePrice; return true; } internal static bool TryGetCustomFloorPrice(SpawnableSO spawnableSO, ref int priceIncreasePerFloor) { if (!TryGetDefinition(spawnableSO, out var definition)) { definition = TryBuildDefinitionForSpawnableId(((Object)(object)spawnableSO != (Object)null) ? spawnableSO.spawnableID : 0); if (definition == null) { return false; } } priceIncreasePerFloor = definition.PriceIncreasePerFloor; return true; } internal static bool TryGetCustomDescription(SpawnableSO spawnableSO, ref string description) { if (!TryGetDefinition(spawnableSO, out var definition)) { definition = TryBuildDefinitionForSpawnableId(((Object)(object)spawnableSO != (Object)null) ? spawnableSO.spawnableID : 0); if (definition == null) { return false; } } description = definition.Description; return true; } internal static GameObject GetShopReplacement(MMLootTableGameObjectSO lootTable, Vector3 stampPosition, GameObject fallbackPrefab) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)fallbackPrefab == (Object)null) { return null; } if (!DefinitionsByBasePrefab.TryGetValue(fallbackPrefab, out var value) || value.Count == 0) { return fallbackPrefab; } int seed = 0; if ((Object)(object)NetworkSingleton.Instance != (Object)null) { seed = NetworkSingleton.Instance.CurrentSeed; } string text = (((Object)(object)lootTable != (Object)null) ? ((Object)lootTable).name : "ItemStamp"); int deterministicPercent = ModUtils.GetDeterministicPercent(stampPosition, seed, text + "|" + ((Object)fallbackPrefab).name); int num = 0; for (int i = 0; i < value.Count; i++) { num += value[i].ReplacementChancePercent; if (deterministicPercent < num) { return value[i].MarkerPrefab; } } return fallbackPrefab; } internal static bool TrySpawnCustomItemStampPrefab(ItemStamp stamp, GameObject prefab, Vector3 position, Quaternion rotation, Vector3 scale) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)stamp == (Object)null) { return false; } return TrySpawnRegisteredPrefab(prefab, position, rotation, scale, stamp); } internal static bool TrySpawnConsolePrefab(GameObject prefab, Vector3 position) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) return TrySpawnRegisteredPrefab(prefab, position, Quaternion.identity, Vector3.one, null); } private static bool TrySpawnRegisteredPrefab(GameObject prefab, Vector3 position, Quaternion rotation, Vector3 scale, ItemStamp stamp) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)prefab == (Object)null || !DefinitionsByMarkerPrefab.TryGetValue(prefab, out var value)) { return false; } GameObject val = Object.Instantiate(value.SpawnPrefab, position, rotation); ApplyDefinitionToServerInstance(value, val, scale); NetworkServer.Spawn(val, value.AssetId, (NetworkConnectionToClient)null); TryConnectPlugin.Log.LogInfo((object)$"Spawned custom item '{value.DisplayName}'."); if ((Object)(object)stamp != (Object)null && (Object)(object)NetworkSingleton.Instance != (Object)null) { NetworkSingleton.Instance.RegisterSpawnedInstance(val, stamp); StartParentHierarchyCoroutine(stamp, val); } return true; } private static void StartParentHierarchyCoroutine(ItemStamp stamp, GameObject spawnedObject) { if (!(SetParentHierarchyAfterDelayMethod == null) && SetParentHierarchyAfterDelayMethod.Invoke(stamp, new object[1] { spawnedObject }) is IEnumerator enumerator) { ((MonoBehaviour)stamp).StartCoroutine(enumerator); } } private static bool EnsureDefinition(SpawnableSettings spawnableSettings, ItemPriceSettings priceSettings, CustomItemRequest request) { if (request == null) { return false; } if (!DefinitionsBySpawnableId.TryGetValue(request.SpawnableId, out var value)) { value = BuildDefinition(spawnableSettings, priceSettings, request); if (value == null) { return false; } CacheDefinition(value); } return EnsureDefinition(spawnableSettings, value); } private static bool EnsureDefinition(SpawnableSettings spawnableSettings, CustomItemDefinition definition) { if (definition == null || (Object)(object)definition.Spawnable == (Object)null) { return false; } bool flag = false; for (int i = 0; i < spawnableSettings.spawnables.Count; i++) { SpawnableSO val = spawnableSettings.spawnables[i]; if ((Object)(object)val != (Object)null && val.spawnableID == definition.Spawnable.spawnableID) { flag = true; break; } } if (!flag) { spawnableSettings.spawnables.Add(definition.Spawnable); return true; } return false; } private static void EnsureBuiltInRegistrations() { //IL_00b5: 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_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_017c: 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_0196: 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) if (!_builtInRegistrationsAdded && !((Object)(object)_plugin == (Object)null) && TryConnectPlugin.EnableCustomItems != null && TryConnectPlugin.EnableCustomItems.Value) { _builtInRegistrationsAdded = true; CustomItemRequest customItemRequest = new CustomItemRequest(); customItemRequest.OwnerGuid = "com.Try-4646.TryConnect"; customItemRequest.Key = "ticket_fizz"; customItemRequest.SpawnableId = 900001; customItemRequest.AssetId = ModUtils.GetStableAssetId("com.Try-4646.TryConnect", "ticket_fizz"); customItemRequest.DisplayName = "Ticket Fizz"; customItemRequest.Description = "A TryConnect house drink. Behaves like the vanilla Drink, but shows up as injected custom shop loot."; customItemRequest.BaseItemComponentType = typeof(Drink); customItemRequest.ApplyTint = true; customItemRequest.Tint = new Color(0.22f, 0.95f, 0.92f); customItemRequest.ModelScaleMultiplier = new Vector3(1.08f, 1.08f, 1.08f); customItemRequest.ReplacementChancePercent = ModUtils.ClampPercent(TryConnectPlugin.TicketFizzReplacementChance.Value); customItemRequest.ExtraBasePrice = 2; customItemRequest.ExtraFloorPrice = 1; AddRequest(customItemRequest); customItemRequest = new CustomItemRequest(); customItemRequest.OwnerGuid = "com.Try-4646.TryConnect"; customItemRequest.Key = "loaded_chip"; customItemRequest.SpawnableId = 900002; customItemRequest.AssetId = ModUtils.GetStableAssetId("com.Try-4646.TryConnect", "loaded_chip"); customItemRequest.DisplayName = "Loaded Chip"; customItemRequest.Description = "A counterfeit high-roller token. Behaves like the vanilla Golden Chip when applied to a game."; customItemRequest.BaseItemComponentType = typeof(GoldenChip); customItemRequest.ApplyTint = true; customItemRequest.Tint = new Color(1f, 0.72f, 0.12f); customItemRequest.ModelScaleMultiplier = new Vector3(1.12f, 1.12f, 1.12f); customItemRequest.ReplacementChancePercent = ModUtils.ClampPercent(TryConnectPlugin.LoadedChipReplacementChance.Value); customItemRequest.ExtraBasePrice = 3; customItemRequest.ExtraFloorPrice = 1; AddRequest(customItemRequest); } } private static void AddRequest(CustomItemRequest request) { RequestsBySpawnableId.Add(request.SpawnableId, request); RequestsByUniqueKey.Add(BuildUniqueKey(request.OwnerGuid, request.Key), request); RequestsByAssetId.Add(request.AssetId, request); } private static CustomItemRequest CreateRequest(TryConnectItemRegistration registration) { //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: 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) return new CustomItemRequest { OwnerGuid = registration.OwnerGuid, Key = registration.Key, SpawnableId = registration.SpawnableId, AssetId = ModUtils.GetStableAssetId(registration.OwnerGuid, registration.Key), DisplayName = registration.DisplayName, Description = (registration.Description ?? string.Empty), BaseSpawnable = registration.BaseSpawnable, BaseSpawnableId = registration.BaseSpawnableId, BaseItemComponentType = registration.BaseItemComponentType, CustomPrefab = registration.CustomPrefab, MarkerPrefab = registration.MarkerPrefab, ApplyTint = registration.ApplyTint, Tint = registration.Tint, ModelScaleMultiplier = registration.ModelScaleMultiplier, ReplacementChancePercent = ModUtils.ClampPercent(registration.ReplacementChancePercent), ExtraBasePrice = registration.ExtraBasePrice, ExtraFloorPrice = registration.ExtraFloorPrice }; } private static bool TryNormalizeRegistration(TryConnectItemRegistration registration) { if (registration == null) { return false; } if (string.IsNullOrWhiteSpace(registration.OwnerGuid) || string.IsNullOrWhiteSpace(registration.Key) || string.IsNullOrWhiteSpace(registration.DisplayName)) { return false; } if ((Object)(object)registration.CustomPrefab == (Object)null && (Object)(object)registration.BaseSpawnable == (Object)null && registration.BaseSpawnableId == 0 && registration.BaseItemComponentType == null) { return false; } if (registration.BaseItemComponentType != null && !typeof(Component).IsAssignableFrom(registration.BaseItemComponentType)) { return false; } if ((Object)(object)registration.CustomPrefab != (Object)null && (Object)(object)registration.CustomPrefab.GetComponent() == (Object)null) { return false; } if ((Object)(object)registration.MarkerPrefab != (Object)null && (Object)(object)registration.MarkerPrefab.GetComponent() == (Object)null) { return false; } registration.OwnerGuid = registration.OwnerGuid.Trim(); registration.Key = registration.Key.Trim(); registration.DisplayName = registration.DisplayName.Trim(); registration.Description = registration.Description ?? string.Empty; if (registration.SpawnableId == 0) { registration.SpawnableId = ModUtils.GetStableSpawnableId(registration.OwnerGuid, registration.Key); } if ((Object)(object)registration.CustomPrefab != (Object)null) { TryConnectApi.RefreshItemPrefab(registration.CustomPrefab); } if ((Object)(object)registration.MarkerPrefab != (Object)null) { TryConnectApi.RefreshItemPrefab(registration.MarkerPrefab); } return true; } private static string BuildUniqueKey(string ownerGuid, string key) { return ownerGuid + ":" + key; } private static void CacheDefinition(CustomItemDefinition definition) { DefinitionsBySpawnableId.Add(definition.Spawnable.spawnableID, definition); DefinitionsByAssetId.Add(definition.AssetId, definition); DefinitionsByMarkerPrefab.Add(definition.MarkerPrefab, definition); if ((Object)(object)definition.BasePrefab != (Object)null) { if (!DefinitionsByBasePrefab.TryGetValue(definition.BasePrefab, out var value)) { value = new List(); DefinitionsByBasePrefab.Add(definition.BasePrefab, value); } value.Add(definition); value.Sort((CustomItemDefinition left, CustomItemDefinition right) => left.Spawnable.spawnableID.CompareTo(right.Spawnable.spawnableID)); } } private static CustomItemDefinition TryBuildDefinitionForAssetId(uint assetId) { if (DefinitionsByAssetId.TryGetValue(assetId, out var value)) { return value; } if (!RequestsByAssetId.TryGetValue(assetId, out var value2)) { return null; } return TryBuildDefinition(value2); } private static CustomItemDefinition TryBuildDefinitionForSpawnableId(int spawnableId) { if (spawnableId == 0) { return null; } if (DefinitionsBySpawnableId.TryGetValue(spawnableId, out var value)) { return value; } if (!RequestsBySpawnableId.TryGetValue(spawnableId, out var value2)) { return null; } return TryBuildDefinition(value2); } private static CustomItemDefinition TryBuildDefinition(CustomItemRequest request) { SpawnableSettings val = Resources.Load("SpawnableSettings"); if ((Object)(object)val == (Object)null || !val.isEnabled) { return null; } ItemPriceSettings priceSettings = Resources.Load("ItemPriceSettings"); EnsureDefinition(val, priceSettings, request); DefinitionsBySpawnableId.TryGetValue(request.SpawnableId, out var value); return value; } private static CustomItemDefinition BuildDefinition(SpawnableSettings spawnableSettings, ItemPriceSettings priceSettings, CustomItemRequest request) { //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_02aa: Unknown result type (might be due to invalid IL or missing references) SpawnableSO val = ResolveBaseSpawnable(spawnableSettings, request); GameObject val2 = (((Object)(object)request.CustomPrefab != (Object)null) ? request.CustomPrefab : (((Object)(object)val != (Object)null) ? val.prefab : null)); if ((Object)(object)val2 == (Object)null) { LogBuildFailureOnce(request, "Could not resolve a spawn prefab."); return null; } if ((Object)(object)request.CustomPrefab != (Object)null) { TryConnectApi.PrepareRuntimeNetworkTemplate(val2); TryConnectApi.RefreshItemPrefab(val2); } if ((Object)(object)val2.GetComponent() == (Object)null) { LogBuildFailureOnce(request, $"Custom prefab for '{request.DisplayName}' is missing an Item-derived component."); return null; } GameObject val3 = (((Object)(object)request.MarkerPrefab != (Object)null) ? request.MarkerPrefab : val2); GameObject val4 = Object.Instantiate(val3); ((Object)val4).name = request.Key + "_Marker"; ((Object)val4).hideFlags = (HideFlags)61; val4.SetActive(false); Object.DontDestroyOnLoad((Object)(object)val4); TryConnectApi.PrepareRuntimeNetworkTemplate(val4); TryConnectApi.RefreshItemPrefab(val4); Item component = val4.GetComponent(); if ((Object)(object)component == (Object)null) { Object.Destroy((Object)(object)val4); LogBuildFailureOnce(request, $"Marker prefab for '{request.DisplayName}' is missing an Item-derived component."); return null; } SpawnableSO val5 = ScriptableObject.CreateInstance(); ((Object)val5).hideFlags = (HideFlags)61; ((Object)val5).name = request.Key + "_SpawnableSO"; val5.spawnableID = request.SpawnableId; val5.spawnableName = request.DisplayName; val5.spawnableDescription = request.Description; val5.prefab = val4; component.spawnableSo = val5; int basePrice = 4; int priceIncreasePerFloor = 1; if ((Object)(object)priceSettings != (Object)null && (Object)(object)val != (Object)null) { basePrice = Math.Max(1, priceSettings.GetBasePrice(val) + request.ExtraBasePrice); priceIncreasePerFloor = Math.Max(0, priceSettings.GetPriceIncreasePerFloor(val) + request.ExtraFloorPrice); } CustomItemDefinition customItemDefinition = new CustomItemDefinition(); customItemDefinition.OwnerGuid = request.OwnerGuid; customItemDefinition.Key = request.Key; customItemDefinition.AssetId = request.AssetId; customItemDefinition.BasePrefab = (((Object)(object)val != (Object)null) ? val.prefab : null); customItemDefinition.SpawnPrefab = val2; customItemDefinition.BasePrice = basePrice; customItemDefinition.Description = request.Description; customItemDefinition.DisplayName = request.DisplayName; customItemDefinition.MarkerPrefab = val4; customItemDefinition.ApplyTint = request.ApplyTint; customItemDefinition.ModelScaleMultiplier = request.ModelScaleMultiplier; customItemDefinition.PriceIncreasePerFloor = priceIncreasePerFloor; customItemDefinition.ReplacementChancePercent = request.ReplacementChancePercent; customItemDefinition.Spawnable = val5; customItemDefinition.Tint = request.Tint; ApplyDefinitionToMarker(customItemDefinition, val4); EnsureClientSpawnHandler(customItemDefinition); return customItemDefinition; } private static void LogBuildFailureOnce(CustomItemRequest request, string message) { if (request != null && !request.HasLoggedBuildFailure) { request.HasLoggedBuildFailure = true; if (TryConnectPlugin.Log != null) { TryConnectPlugin.Log.LogWarning((object)$"Custom item '{request.DisplayName}' ({request.OwnerGuid}) could not be registered yet. {message}"); } } } private static SpawnableSO ResolveBaseSpawnable(SpawnableSettings spawnableSettings, CustomItemRequest request) { if ((Object)(object)request.BaseSpawnable != (Object)null) { return request.BaseSpawnable; } if (request.BaseSpawnableId != 0) { return FindBaseSpawnableById(spawnableSettings, request.BaseSpawnableId); } if (request.BaseItemComponentType != null) { return FindBaseSpawnable(spawnableSettings, request.BaseItemComponentType); } return null; } private static bool TryFindSpawnable(SpawnableSettings spawnableSettings, Predicate predicate, out SpawnableSO spawnable) { spawnable = null; if ((Object)(object)spawnableSettings == (Object)null || predicate == null) { return false; } for (int i = 0; i < spawnableSettings.spawnables.Count; i++) { SpawnableSO val = spawnableSettings.spawnables[i]; if (predicate(val)) { spawnable = val; return true; } } return false; } private static SpawnableSO FindBaseSpawnableById(SpawnableSettings spawnableSettings, int spawnableId) { SpawnableSO spawnable; return TryFindSpawnable(spawnableSettings, (SpawnableSO candidate) => (Object)(object)candidate != (Object)null && candidate.spawnableID == spawnableId, out spawnable) ? spawnable : null; } private static SpawnableSO FindBaseSpawnable(SpawnableSettings spawnableSettings, Type componentType) { SpawnableSO spawnable; return TryFindSpawnable(spawnableSettings, (SpawnableSO candidate) => (Object)(object)candidate != (Object)null && (Object)(object)candidate.prefab != (Object)null && (Object)(object)candidate.prefab.GetComponent(componentType) != (Object)null, out spawnable) ? spawnable : null; } private static void ApplyDefinitionToMarker(CustomItemDefinition definition, GameObject markerPrefab) { if (!((Object)(object)markerPrefab == (Object)null)) { ((Object)markerPrefab).name = definition.DisplayName; ApplyDefinitionVisuals(definition, markerPrefab.transform); Item component = markerPrefab.GetComponent(); if ((Object)(object)component != (Object)null) { component.spawnableSo = definition.Spawnable; } } } private static void ApplyDefinitionToServerInstance(CustomItemDefinition definition, GameObject spawnedObject, Vector3 scaleMultiplier) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) ApplyDefinitionToInstance(definition, spawnedObject, Vector3.Scale(spawnedObject.transform.localScale, scaleMultiplier)); } private static void ApplyDefinitionToClientInstance(CustomItemDefinition definition, GameObject spawnedObject, Vector3 scale) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) ApplyDefinitionToInstance(definition, spawnedObject, scale); } private static void ApplyDefinitionToInstance(CustomItemDefinition definition, GameObject spawnedObject, Vector3 resolvedScale) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) TryConnectApi.PrepareRuntimeNetworkTemplate(spawnedObject); TryConnectApi.RefreshItemPrefab(spawnedObject); ((Object)spawnedObject).name = definition.DisplayName; spawnedObject.transform.localScale = resolvedScale; spawnedObject.SetActive(true); TryConnectApi.RefreshItemPrefab(spawnedObject); NetworkIdentity component = spawnedObject.GetComponent(); if ((Object)(object)component != (Object)null) { SetNetworkAssetId(component, definition.AssetId); } Item component2 = spawnedObject.GetComponent(); if ((Object)(object)component2 != (Object)null) { component2.spawnableSo = definition.Spawnable; } ApplyDefinitionVisuals(definition, spawnedObject.transform); } private static void ApplyDefinitionVisuals(CustomItemDefinition definition, Transform root) { //IL_0036: 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_0041: 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) Item component = ((Component)root).GetComponent(); Transform val = (((Object)(object)component != (Object)null) ? component.modelTransform : root.Find("Model")); if ((Object)(object)val == (Object)null) { val = root; } val.localScale = Vector3.Scale(val.localScale, definition.ModelScaleMultiplier); if (!definition.ApplyTint) { return; } Renderer[] componentsInChildren = ((Component)root).GetComponentsInChildren(true); foreach (Renderer val2 in componentsInChildren) { if ((Object)(object)val2 == (Object)null) { continue; } Material[] materials = val2.materials; foreach (Material val3 in materials) { if (ModUtils.TrySetMaterialTint(val3, definition.Tint) && val3.HasProperty("_Metallic")) { val3.SetFloat("_Metallic", Mathf.Clamp01(val3.GetFloat("_Metallic") + 0.15f)); } } val2.materials = materials; } } private static void EnsureClientSpawnHandler(CustomItemDefinition definition) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown //IL_0071: Expected O, but got Unknown if (definition != null) { IDictionary dictionary = ((SpawnHandlersField != null) ? (SpawnHandlersField.GetValue(null) as IDictionary) : null); if (dictionary == null || !dictionary.Contains(definition.AssetId)) { NetworkClient.RegisterSpawnHandler(definition.AssetId, new SpawnHandlerDelegate(SpawnCustomPrefab), new UnSpawnDelegate(UnspawnCustomPrefab)); TryConnectPlugin.Log.LogInfo((object)$"Registered custom spawn handler for '{definition.DisplayName}' ({definition.AssetId})."); } } } private static void SetNetworkAssetId(NetworkIdentity networkIdentity, uint assetId) { if (AssetIdField != null) { AssetIdField.SetValue(networkIdentity, assetId); } } private static bool TryGetDefinition(SpawnableSO spawnableSO, out CustomItemDefinition definition) { definition = null; if ((Object)(object)spawnableSO == (Object)null) { return false; } return DefinitionsBySpawnableId.TryGetValue(spawnableSO.spawnableID, out definition); } private static GameObject SpawnCustomPrefab(SpawnMessage message) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (!DefinitionsByAssetId.TryGetValue(message.assetId, out var value)) { value = TryBuildDefinitionForAssetId(message.assetId); if (value == null) { return null; } } GameObject val = Object.Instantiate(value.SpawnPrefab, message.position, message.rotation); ApplyDefinitionToClientInstance(value, val, message.scale); return val; } private static void UnspawnCustomPrefab(GameObject spawnedObject) { if ((Object)(object)spawnedObject != (Object)null) { Object.Destroy((Object)(object)spawnedObject); } } } public static class TryConnectApi { public const int ApiVersion = 4; public const string PluginGuid = "com.Try-4646.TryConnect"; private static readonly FieldInfo SceneIdField = typeof(NetworkIdentity).GetField("sceneId", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo HasSpawnedField = typeof(NetworkIdentity).GetField("hasSpawned", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo DestroyCalledField = typeof(NetworkIdentity).GetField("destroyCalled", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo NetIdField = typeof(NetworkIdentity).GetField("k__BackingField", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo AssetIdBackingField = typeof(NetworkIdentity).GetField("_assetId", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo IsClientField = typeof(NetworkIdentity).GetField("k__BackingField", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo IsServerField = typeof(NetworkIdentity).GetField("k__BackingField", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo IsLocalPlayerField = typeof(NetworkIdentity).GetField("k__BackingField", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo IsOwnedField = typeof(NetworkIdentity).GetField("k__BackingField", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo SpawnedFromInstantiateField = typeof(NetworkIdentity).GetField("k__BackingField", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo ConnectionToServerField = typeof(NetworkIdentity).GetField("k__BackingField", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo ConnectionToClientField = typeof(NetworkIdentity).GetField("_connectionToClient", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo ItemColliderCacheField = typeof(Item).GetField("_allColliders", BindingFlags.Instance | BindingFlags.NonPublic); public static bool IsInitialized => (Object)(object)TryConnectPlugin.Instance != (Object)null; public static int GenerateSpawnableId(string ownerGuid, string key) { ValidateIdentity(ownerGuid, key); return ModUtils.GetStableSpawnableId(ownerGuid, key); } public static TryConnectRegistrationResult RegisterCustomItem(TryConnectItemRegistration registration) { return RuntimeItemRegistry.RegisterCustomItem(registration); } public static bool TryGetCustomSpawnable(int spawnableId, out SpawnableSO spawnable) { spawnable = RuntimeItemRegistry.GetCustomSpawnable(spawnableId); return (Object)(object)spawnable != (Object)null; } public static bool TryGetRegisteredItem(int spawnableId, out TryConnectRegisteredItemInfo itemInfo) { return RuntimeItemRegistry.TryGetRegisteredItemInfo(spawnableId, out itemInfo); } public static bool TryGetVanillaSpawnable(int spawnableId, out SpawnableSO spawnable) { return RuntimeItemRegistry.TryGetVanillaSpawnable(spawnableId, out spawnable); } public static bool TryFindVanillaSpawnable(string searchTerm, out SpawnableSO spawnable) { return RuntimeItemRegistry.TryFindVanillaSpawnable(searchTerm, out spawnable); } public static bool TryFindVanillaSpawnable(Type componentType, out SpawnableSO spawnable) { spawnable = null; if (componentType == null) { throw new ArgumentNullException("componentType"); } if (!typeof(Component).IsAssignableFrom(componentType)) { throw new ArgumentException("componentType must derive from UnityEngine.Component.", "componentType"); } SpawnableSettings val = Resources.Load("SpawnableSettings"); if ((Object)(object)val == (Object)null || val.spawnables == null) { return false; } for (int i = 0; i < val.spawnables.Count; i++) { SpawnableSO val2 = val.spawnables[i]; if ((Object)(object)val2 != (Object)null && (Object)(object)val2.prefab != (Object)null && (Object)(object)val2.prefab.GetComponent(componentType) != (Object)null) { spawnable = val2; return true; } } return false; } public static bool TryFindVanillaSpawnable(out SpawnableSO spawnable) where TComponent : Component { return TryFindVanillaSpawnable(typeof(TComponent), out spawnable); } public static SpawnableSO FindVanillaSpawnable() where TComponent : Component { SpawnableSO spawnable; return TryFindVanillaSpawnable(out spawnable) ? spawnable : null; } public static GameObject CreatePrefabTemplate(SpawnableSO baseSpawnable, string templateName = null) { if ((Object)(object)baseSpawnable == (Object)null || (Object)(object)baseSpawnable.prefab == (Object)null) { throw new ArgumentException("baseSpawnable and its prefab are required.", "baseSpawnable"); } return CreatePrefabTemplate(baseSpawnable.prefab, templateName); } public static GameObject CreatePrefabTemplate(GameObject sourcePrefab, string templateName = null) { if ((Object)(object)sourcePrefab == (Object)null) { throw new ArgumentNullException("sourcePrefab"); } GameObject val = Object.Instantiate(sourcePrefab); ((Object)val).name = (string.IsNullOrWhiteSpace(templateName) ? (((Object)sourcePrefab).name + "_TryConnectTemplate") : templateName.Trim()); ((Object)val).hideFlags = (HideFlags)61; val.SetActive(false); Object.DontDestroyOnLoad((Object)(object)val); PrepareRuntimeNetworkTemplate(val); return val; } public static TTarget SwapPrefabComponent(GameObject prefab) where TSource : Component where TTarget : TSource { if ((Object)(object)prefab == (Object)null) { throw new ArgumentNullException("prefab"); } TSource component = prefab.GetComponent(); if ((Object)(object)component == (Object)null) { throw new InvalidOperationException($"Prefab '{((Object)prefab).name}' is missing component '{typeof(TSource).FullName}'."); } TTarget val = prefab.AddComponent(); CopyPrefabComponentState((Component)(object)component, (Component)(object)val); object obj = component; Behaviour val2 = (Behaviour)((obj is Behaviour) ? obj : null); object obj2 = val; Behaviour val3 = (Behaviour)((obj2 is Behaviour) ? obj2 : null); if ((Object)(object)val2 != (Object)null && (Object)(object)val3 != (Object)null) { val3.enabled = val2.enabled; } Object.DestroyImmediate((Object)(object)component); return val; } public static int RemoveNonTriggerColliders(GameObject root) { if ((Object)(object)root == (Object)null) { throw new ArgumentNullException("root"); } List list = CollectNonTriggerColliders(root); for (int i = 0; i < list.Count; i++) { Object.DestroyImmediate((Object)(object)list[i]); } RefreshItemPrefab(root); return list.Count; } public static void RefreshItemPrefab(GameObject prefab) { if ((Object)(object)prefab == (Object)null) { throw new ArgumentNullException("prefab"); } Item[] componentsInChildren = prefab.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { RefreshItemState(componentsInChildren[i]); } } public static Transform GetPrefabVisualRoot(GameObject prefab) { if ((Object)(object)prefab == (Object)null) { throw new ArgumentNullException("prefab"); } return ResolveVisualRoot(prefab); } public static GameObject ReplaceVisualsWithPrimitive(GameObject prefab, PrimitiveType primitiveType, Color color, Vector3 localScale, bool replaceColliders = true) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00be: 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) if ((Object)(object)prefab == (Object)null) { throw new ArgumentNullException("prefab"); } Transform val = ResolveVisualRoot(prefab); int layer = ((((Component)val).gameObject.layer != 0) ? ((Component)val).gameObject.layer : prefab.layer); SetRenderersEnabled(val, isEnabled: false); if (replaceColliders) { RemoveNonTriggerColliders(prefab); } GameObject val2 = GameObject.CreatePrimitive(primitiveType); ((Object)val2).name = ((object)(PrimitiveType)(ref primitiveType)).ToString() + "Visual"; val2.layer = layer; val2.transform.SetParent(val, false); val2.transform.localPosition = Vector3.zero; val2.transform.localRotation = Quaternion.identity; val2.transform.localScale = localScale; Renderer component = val2.GetComponent(); if ((Object)(object)component != (Object)null && (Object)(object)component.sharedMaterial != (Object)null) { Material val3 = Object.Instantiate(component.sharedMaterial); val3.color = color; component.sharedMaterial = val3; } RefreshItemPrefab(prefab); return val2; } public static GameObject ReplaceVisualsWithPrefab(GameObject prefab, GameObject visualPrefab, Vector3 localScale, bool replaceColliders = true) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) return ReplaceVisualsWithPrefab(prefab, visualPrefab, localScale, replaceColliders, Vector3.zero, Vector3.zero); } public static GameObject ReplaceVisualsWithPrefab(GameObject prefab, GameObject visualPrefab, Vector3 localScale, bool replaceColliders, Vector3 localPosition, Vector3 localEulerAngles) { //IL_00b4: 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_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)prefab == (Object)null) { throw new ArgumentNullException("prefab"); } if ((Object)(object)visualPrefab == (Object)null) { throw new ArgumentNullException("visualPrefab"); } Transform val = ResolveVisualRoot(prefab); int layer = ((((Component)val).gameObject.layer != 0) ? ((Component)val).gameObject.layer : prefab.layer); SetRenderersEnabled(val, isEnabled: false); if (replaceColliders) { RemoveNonTriggerColliders(prefab); } GameObject val2 = Object.Instantiate(visualPrefab); ((Object)val2).name = (string.IsNullOrWhiteSpace(((Object)visualPrefab).name) ? "CustomVisual" : ((Object)visualPrefab).name); RemoveNestedRigidbodies(val2); val2.transform.SetParent(val, false); val2.transform.localPosition = localPosition; val2.transform.localRotation = Quaternion.Euler(localEulerAngles); val2.transform.localScale = localScale; SetLayerRecursively(val2, layer); val2.SetActive(true); SetRenderersEnabled(val2.transform, isEnabled: true); RefreshItemPrefab(prefab); return val2; } public static TryConnectRegistrationResult RegisterBundledCustomItem(BaseUnityPlugin plugin, TryConnectBundledItemRegistration registration) where TBaseItem : Item { return RegisterBundledCustomItem(plugin, registration); } public static TryConnectRegistrationResult RegisterBundledCustomItem(BaseUnityPlugin plugin, TryConnectBundledItemRegistration registration) where TBaseItem : Item where TCustomItem : TBaseItem { //IL_0101: 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_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_012f: 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_0151: Unknown result type (might be due to invalid IL or missing references) //IL_016c: 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_0237: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)plugin == (Object)null) { throw new ArgumentNullException("plugin"); } if (registration == null) { throw new ArgumentNullException("registration"); } ValidateBundledRegistration(registration); SpawnableSO val = ResolveBundledBaseSpawnable(registration); if ((Object)(object)val == (Object)null) { throw new InvalidOperationException($"Could not resolve a base spawnable for '{typeof(TBaseItem).FullName}'."); } GameObject val2 = CreatePrefabTemplate(val, BuildTemplateName(registration.CustomPrefabName, registration.Key, "CustomPrefab")); GameObject val3 = CreatePrefabTemplate(val, BuildTemplateName(registration.MarkerPrefabName, registration.Key, "MarkerPrefab")); if (typeof(TBaseItem) != typeof(TCustomItem)) { TryConnectApi.SwapPrefabComponent(val2); } Material fallbackMaterial = (registration.UseBaseMaterialFallback ? CloneFirstMaterial(val2) : null); AssetBundle val4 = TryConnectAssetBundles.LoadRelativeToPlugin(plugin, registration.BundlePath); try { GameObject visualPrefab = TryConnectAssetBundles.LoadAsset(val4, registration.VisualPrefabName); GameObject root = ReplaceVisualsWithPrefab(val2, visualPrefab, registration.VisualLocalScale, registration.ReplaceColliders, registration.VisualLocalPosition, registration.VisualLocalEulerAngles); GameObject root2 = ReplaceVisualsWithPrefab(val3, visualPrefab, registration.VisualLocalScale, registration.ReplaceColliders, registration.VisualLocalPosition, registration.VisualLocalEulerAngles); EnsureVisibleMaterials(root, fallbackMaterial, registration.ForceVisualMaterial, registration.ApplyVisualColor, registration.VisualColor); EnsureVisibleMaterials(root2, fallbackMaterial, registration.ForceVisualMaterial, registration.ApplyVisualColor, registration.VisualColor); } finally { val4.Unload(false); } TryConnectItemRegistration tryConnectItemRegistration = new TryConnectItemRegistration(); tryConnectItemRegistration.OwnerGuid = plugin.Info.Metadata.GUID; tryConnectItemRegistration.Key = registration.Key; tryConnectItemRegistration.SpawnableId = registration.SpawnableId; tryConnectItemRegistration.DisplayName = registration.DisplayName; tryConnectItemRegistration.Description = registration.Description; tryConnectItemRegistration.BaseSpawnable = val; tryConnectItemRegistration.BaseSpawnableId = registration.BaseSpawnableId; tryConnectItemRegistration.BaseItemComponentType = typeof(TBaseItem); tryConnectItemRegistration.CustomPrefab = val2; tryConnectItemRegistration.MarkerPrefab = val3; tryConnectItemRegistration.ApplyTint = registration.ApplyTint; tryConnectItemRegistration.Tint = registration.Tint; tryConnectItemRegistration.ModelScaleMultiplier = registration.ModelScaleMultiplier; tryConnectItemRegistration.ReplacementChancePercent = registration.ReplacementChancePercent; tryConnectItemRegistration.ExtraBasePrice = registration.ExtraBasePrice; tryConnectItemRegistration.ExtraFloorPrice = registration.ExtraFloorPrice; return RegisterCustomItem(tryConnectItemRegistration); } public static TryConnectRegisteredItemInfo[] GetRegisteredItems() { return RuntimeItemRegistry.GetRegisteredItemInfos(); } internal static void PrepareRuntimeNetworkTemplate(GameObject prefab) { if ((Object)(object)prefab == (Object)null) { return; } NetworkIdentity[] componentsInChildren = prefab.GetComponentsInChildren(true); foreach (NetworkIdentity val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { if (SceneIdField != null) { SceneIdField.SetValue(val, 0uL); } if (HasSpawnedField != null) { HasSpawnedField.SetValue(val, false); } if (DestroyCalledField != null) { DestroyCalledField.SetValue(val, false); } if (NetIdField != null) { NetIdField.SetValue(val, 0u); } if (AssetIdBackingField != null) { AssetIdBackingField.SetValue(val, 0u); } if (IsClientField != null) { IsClientField.SetValue(val, false); } if (IsServerField != null) { IsServerField.SetValue(val, false); } if (IsLocalPlayerField != null) { IsLocalPlayerField.SetValue(val, false); } if (IsOwnedField != null) { IsOwnedField.SetValue(val, false); } if (SpawnedFromInstantiateField != null) { SpawnedFromInstantiateField.SetValue(val, false); } if (ConnectionToClientField != null) { ConnectionToClientField.SetValue(val, null); } if (ConnectionToServerField != null) { ConnectionToServerField.SetValue(val, null); } } } } private static void ValidateIdentity(string ownerGuid, string key) { if (string.IsNullOrWhiteSpace(ownerGuid)) { throw new ArgumentException("ownerGuid is required.", "ownerGuid"); } if (string.IsNullOrWhiteSpace(key)) { throw new ArgumentException("key is required.", "key"); } } private static void ValidateBundledRegistration(TryConnectBundledItemRegistration registration) { if (string.IsNullOrWhiteSpace(registration.Key)) { throw new ArgumentException("registration.Key is required.", "registration"); } if (string.IsNullOrWhiteSpace(registration.DisplayName)) { throw new ArgumentException("registration.DisplayName is required.", "registration"); } if (string.IsNullOrWhiteSpace(registration.BundlePath)) { throw new ArgumentException("registration.BundlePath is required.", "registration"); } if (string.IsNullOrWhiteSpace(registration.VisualPrefabName)) { throw new ArgumentException("registration.VisualPrefabName is required.", "registration"); } } private static SpawnableSO ResolveBundledBaseSpawnable(TryConnectBundledItemRegistration registration) where TBaseItem : Item { if ((Object)(object)registration.BaseSpawnable != (Object)null) { return registration.BaseSpawnable; } if (registration.BaseSpawnableId != 0 && TryGetVanillaSpawnable(registration.BaseSpawnableId, out var spawnable)) { return spawnable; } return TryConnectApi.FindVanillaSpawnable(); } private static string BuildTemplateName(string explicitName, string key, string suffix) { if (!string.IsNullOrWhiteSpace(explicitName)) { return explicitName.Trim(); } return key.Trim() + "_" + suffix; } private static Material CloneFirstMaterial(GameObject root) { if ((Object)(object)root == (Object)null) { return null; } Renderer[] componentsInChildren = root.GetComponentsInChildren(true); foreach (Renderer val in componentsInChildren) { if ((Object)(object)val == (Object)null) { continue; } Material[] sharedMaterials = val.sharedMaterials; for (int j = 0; j < sharedMaterials.Length; j++) { if ((Object)(object)sharedMaterials[j] != (Object)null) { return Object.Instantiate(sharedMaterials[j]); } } } return null; } private static void EnsureVisibleMaterials(GameObject root, Material fallbackMaterial, bool forceMaterial, bool applyColor, Color color) { //IL_0106: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)root == (Object)null) { return; } Renderer[] componentsInChildren = root.GetComponentsInChildren(true); foreach (Renderer val in componentsInChildren) { if ((Object)(object)val == (Object)null) { continue; } Material[] sharedMaterials = val.sharedMaterials; bool flag = sharedMaterials == null || sharedMaterials.Length == 0; if (!flag) { for (int j = 0; j < sharedMaterials.Length; j++) { if ((Object)(object)sharedMaterials[j] == (Object)null) { flag = true; break; } } } if (!forceMaterial && !applyColor && !flag) { val.enabled = true; continue; } int num = ((sharedMaterials == null || sharedMaterials.Length == 0) ? 1 : sharedMaterials.Length); Material[] array = (Material[])(object)new Material[num]; for (int k = 0; k < num; k++) { Material sourceMaterial = ((sharedMaterials != null && k < sharedMaterials.Length) ? sharedMaterials[k] : null); Material val2 = CreateRendererMaterial(sourceMaterial, fallbackMaterial, forceMaterial); if ((Object)(object)val2 != (Object)null && applyColor) { ModUtils.TrySetMaterialTint(val2, color); } array[k] = val2; } val.sharedMaterials = array; val.enabled = true; } } private static Material CreateRendererMaterial(Material sourceMaterial, Material fallbackMaterial, bool forceMaterial) { //IL_007a: Unknown result type (might be due to invalid IL or missing references) Material val = null; if (!forceMaterial && (Object)(object)sourceMaterial != (Object)null) { val = sourceMaterial; } else if ((Object)(object)fallbackMaterial != (Object)null) { val = fallbackMaterial; } else if ((Object)(object)sourceMaterial != (Object)null) { val = sourceMaterial; } if ((Object)(object)val != (Object)null) { return Object.Instantiate(val); } Shader val2 = Shader.Find("Standard") ?? Shader.Find("Universal Render Pipeline/Lit"); return (!((Object)(object)val2 != (Object)null)) ? ((Material)null) : new Material(val2); } private static Transform ResolveVisualRoot(GameObject prefab) { Item val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent() : null); Transform val2 = (((Object)(object)val != (Object)null) ? val.modelTransform : null); if ((Object)(object)val2 == (Object)null && (Object)(object)prefab != (Object)null) { val2 = prefab.transform.Find("Model"); } return val2 ?? (((Object)(object)prefab != (Object)null) ? prefab.transform : null); } private static void SetRenderersEnabled(Transform root, bool isEnabled) { if ((Object)(object)root == (Object)null) { return; } Renderer[] componentsInChildren = ((Component)root).GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null) { componentsInChildren[i].enabled = isEnabled; } } } private static void SetLayerRecursively(GameObject root, int layer) { if ((Object)(object)root == (Object)null) { return; } Transform[] componentsInChildren = root.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null) { ((Component)componentsInChildren[i]).gameObject.layer = layer; } } } private static void RemoveNestedRigidbodies(GameObject root) { if ((Object)(object)root == (Object)null) { return; } Rigidbody[] componentsInChildren = root.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null) { Object.DestroyImmediate((Object)(object)componentsInChildren[i]); } } } private static void RefreshItemState(Item item) { if (!((Object)(object)item == (Object)null)) { Transform val = item.modelTransform; if ((Object)(object)val == (Object)null) { val = (item.modelTransform = ((Component)item).transform.Find("Model")); } item.handRig = ResolveHandRig(val); item.handMesh = ResolveHandMesh(item.handRig); item.onHandFb = ResolveFeedbackPlayer(((Component)item).transform, "OnHand"); item.onDropFb = ResolveFeedbackPlayer(((Component)item).transform, "OnDrop"); item.onThrowVfx = ResolveThrowVfx(((Component)item).transform); if (ItemColliderCacheField != null) { ItemColliderCacheField.SetValue(item, CollectNonTriggerColliders(item)); } EnsureInteractableProxies(item); } } private static GameObject ResolveHandRig(Transform modelTransform) { if ((Object)(object)modelTransform == (Object)null) { return null; } Transform val = modelTransform.Find("HandRig"); return ((Object)(object)val != (Object)null) ? ((Component)val).gameObject : null; } private static SkinnedMeshRenderer ResolveHandMesh(GameObject handRig) { if ((Object)(object)handRig == (Object)null) { return null; } SkinnedMeshRenderer[] componentsInChildren = handRig.GetComponentsInChildren(true); return (componentsInChildren.Length != 0) ? componentsInChildren[0] : null; } private static MMF_Player ResolveFeedbackPlayer(Transform itemTransform, string feedbackName) { Transform val = (((Object)(object)itemTransform != (Object)null) ? itemTransform.Find("Feedbacks") : null); if ((Object)(object)val == (Object)null) { return null; } Transform val2 = val.Find(feedbackName); return ((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponent() : null; } private static ParticleSystem ResolveThrowVfx(Transform itemTransform) { Transform val = (((Object)(object)itemTransform != (Object)null) ? itemTransform.Find("Feedbacks") : null); if ((Object)(object)val == (Object)null) { return null; } Transform val2 = val.Find("OnThrowVFX"); return ((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponent() : null; } private static List CollectNonTriggerColliders(Item item) { return ((Object)(object)item != (Object)null) ? CollectNonTriggerColliders(((Component)item).gameObject) : new List(); } private static List CollectNonTriggerColliders(GameObject root) { List list = new List(); Collider[] array = (Collider[])(((Object)(object)root != (Object)null) ? ((Array)root.GetComponentsInChildren(true)) : ((Array)new Collider[0])); foreach (Collider val in array) { if ((Object)(object)val != (Object)null && !val.isTrigger) { list.Add(val); } } return list; } private static void EnsureInteractableProxies(Item item) { if ((Object)(object)item == (Object)null) { return; } Collider[] componentsInChildren = ((Component)item).GetComponentsInChildren(true); foreach (Collider val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !val.isTrigger && !((Object)(object)((Component)val).transform == (Object)(object)((Component)item).transform) && ((Component)val).GetComponent() == null) { TryConnectInteractableProxy tryConnectInteractableProxy = ((Component)val).GetComponent(); if ((Object)(object)tryConnectInteractableProxy == (Object)null) { tryConnectInteractableProxy = ((Component)val).gameObject.AddComponent(); } tryConnectInteractableProxy.Bind((MonoBehaviour)(object)item); } } } private static void CopyPrefabComponentState(Component source, Component target) { Type type = ((object)source).GetType(); while (type != null && type != typeof(NetworkBehaviour)) { FieldInfo[] fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (!fieldInfo.IsStatic && !fieldInfo.IsInitOnly) { fieldInfo.SetValue(target, fieldInfo.GetValue(source)); } } type = type.BaseType; } } } public sealed class TryConnectBundledItemRegistration { public string Key { get; set; } public int SpawnableId { get; set; } public string DisplayName { get; set; } public string Description { get; set; } public SpawnableSO BaseSpawnable { get; set; } public int BaseSpawnableId { get; set; } public string BundlePath { get; set; } public string VisualPrefabName { get; set; } public string CustomPrefabName { get; set; } public string MarkerPrefabName { get; set; } public Vector3 VisualLocalPosition { get; set; } = Vector3.zero; public Vector3 VisualLocalEulerAngles { get; set; } = Vector3.zero; public Vector3 VisualLocalScale { get; set; } = Vector3.one; public bool ReplaceColliders { get; set; } public bool UseBaseMaterialFallback { get; set; } = true; public bool ForceVisualMaterial { get; set; } public bool ApplyVisualColor { get; set; } public Color VisualColor { get; set; } = Color.white; public bool ApplyTint { get; set; } public Color Tint { get; set; } = Color.white; public Vector3 ModelScaleMultiplier { get; set; } = Vector3.one; public int ReplacementChancePercent { get; set; } public int ExtraBasePrice { get; set; } public int ExtraFloorPrice { get; set; } } public static class TryConnectAssetBundles { public static AssetBundle Load(string fullPath) { if (string.IsNullOrWhiteSpace(fullPath)) { throw new ArgumentException("fullPath is required.", "fullPath"); } string fullPath2 = Path.GetFullPath(fullPath.Trim()); if (!File.Exists(fullPath2)) { throw new FileNotFoundException("Asset bundle file was not found.", fullPath2); } AssetBundle val = AssetBundle.LoadFromFile(fullPath2); if ((Object)(object)val == (Object)null) { throw new InvalidOperationException($"Failed to load asset bundle '{fullPath2}'."); } return val; } public static AssetBundle LoadRelativeToPlugin(BaseUnityPlugin plugin, string relativePath) { return Load(ResolvePluginRelativePath(plugin, relativePath)); } public static T LoadAsset(AssetBundle bundle, string assetName) where T : Object { if ((Object)(object)bundle == (Object)null) { throw new ArgumentNullException("bundle"); } if (string.IsNullOrWhiteSpace(assetName)) { throw new ArgumentException("assetName is required.", "assetName"); } T val = bundle.LoadAsset(assetName.Trim()); if ((Object)(object)val == (Object)null) { throw new InvalidOperationException($"Asset '{assetName}' of type '{typeof(T).FullName}' was not found in bundle '{((Object)bundle).name}'."); } return val; } public static GameObject CreatePrefabTemplateFromBundle(AssetBundle bundle, string prefabName, string templateName = null) { GameObject sourcePrefab = TryConnectAssetBundles.LoadAsset(bundle, prefabName); return TryConnectApi.CreatePrefabTemplate(sourcePrefab, templateName); } public static GameObject CreatePrefabTemplateFromBundle(BaseUnityPlugin plugin, string bundlePath, string prefabName, string templateName = null) { AssetBundle val = LoadRelativeToPlugin(plugin, bundlePath); try { return CreatePrefabTemplateFromBundle(val, prefabName, templateName); } finally { val.Unload(false); } } public static string ResolvePluginRelativePath(BaseUnityPlugin plugin, string relativePath) { if ((Object)(object)plugin == (Object)null) { throw new ArgumentNullException("plugin"); } if (string.IsNullOrWhiteSpace(relativePath)) { throw new ArgumentException("relativePath is required.", "relativePath"); } string location = ((object)plugin).GetType().Assembly.Location; if (string.IsNullOrWhiteSpace(location)) { throw new InvalidOperationException($"Could not resolve assembly location for plugin '{((object)plugin).GetType().FullName}'."); } string directoryName = Path.GetDirectoryName(location); if (string.IsNullOrWhiteSpace(directoryName)) { throw new InvalidOperationException($"Could not resolve plugin directory for '{location}'."); } return Path.GetFullPath(Path.Combine(directoryName, relativePath.Trim())); } } public sealed class TryConnectItemRegistration { public string OwnerGuid { get; set; } public string Key { get; set; } public int SpawnableId { get; set; } public string DisplayName { get; set; } public string Description { get; set; } public SpawnableSO BaseSpawnable { get; set; } public int BaseSpawnableId { get; set; } public Type BaseItemComponentType { get; set; } public GameObject CustomPrefab { get; set; } public GameObject MarkerPrefab { get; set; } public bool ApplyTint { get; set; } public Color Tint { get; set; } = Color.white; public Vector3 ModelScaleMultiplier { get; set; } = Vector3.one; public int ReplacementChancePercent { get; set; } public int ExtraBasePrice { get; set; } public int ExtraFloorPrice { get; set; } } public sealed class TryConnectRegisteredItemInfo { public string OwnerGuid { get; private set; } public string Key { get; private set; } public int SpawnableId { get; private set; } public uint AssetId { get; private set; } public string DisplayName { get; private set; } public string Description { get; private set; } public SpawnableSO Spawnable { get; private set; } public bool IsRegistered { get; private set; } internal TryConnectRegisteredItemInfo(string ownerGuid, string key, int spawnableId, uint assetId, string displayName, string description, SpawnableSO spawnable, bool isRegistered) { OwnerGuid = ownerGuid; Key = key; SpawnableId = spawnableId; AssetId = assetId; DisplayName = displayName; Description = description; Spawnable = spawnable; IsRegistered = isRegistered; } } public enum TryConnectRegistrationResult { Accepted, AlreadyRegistered, InvalidRegistration } [BepInPlugin("com.Try-4646.TryConnect", "TryConnect", "1.0.0")] public sealed class TryConnectPlugin : BaseUnityPlugin { public const string PluginGuid = "com.Try-4646.TryConnect"; public const string PluginDisplayName = "TryConnect"; public const string PluginVersion = "1.0.0"; internal const string MyGUID = "com.Try-4646.TryConnect"; internal const string PluginName = "TryConnect"; internal const string VersionString = "1.0.0"; private Harmony _harmony; public static TryConnectPlugin Instance { get; private set; } internal static ManualLogSource Log { get; private set; } internal static ConfigEntry EnableCustomItems { get; private set; } internal static ConfigEntry TicketFizzReplacementChance { get; private set; } internal static ConfigEntry LoadedChipReplacementChance { get; private set; } private void Awake() { //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; EnableCustomItems = ((BaseUnityPlugin)this).Config.Bind("Custom Items", "Enable", true, "Enable TryConnect runtime shop item registration."); TicketFizzReplacementChance = ((BaseUnityPlugin)this).Config.Bind("Custom Items", "TicketFizzReplacementChance", 35, "Chance for shop item stamps to replace a vanilla Drink roll with Ticket Fizz."); LoadedChipReplacementChance = ((BaseUnityPlugin)this).Config.Bind("Custom Items", "LoadedChipReplacementChance", 25, "Chance for shop item stamps to replace a vanilla Golden Chip roll with Loaded Chip."); RuntimeItemRegistry.Initialize(this); SceneManager.sceneLoaded += OnSceneLoaded; ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("PluginName: {0}, VersionString: {1} is loading...", "TryConnect", "1.0.0")); _harmony = new Harmony("com.Try-4646.TryConnect"); _harmony.PatchAll(); RuntimeItemRegistry.TryRegisterRuntimeContent(); ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("PluginName: {0}, VersionString: {1} is loaded.", "TryConnect", "1.0.0")); } private void OnDestroy() { SceneManager.sceneLoaded -= OnSceneLoaded; RuntimeItemRegistry.Dispose(); if (_harmony != null) { _harmony.UnpatchSelf(); } } private static void OnSceneLoaded(Scene scene, LoadSceneMode mode) { RuntimeItemRegistry.TryRegisterRuntimeContent(); } } } namespace TryConnect.Utils { internal static class ModUtils { internal static uint GetStableAssetId(string key) { return GetStableAssetId("com.Try-4646.TryConnect", key); } internal static uint GetStableAssetId(string ownerGuid, string key) { uint num = GetStableHash(ownerGuid + ":" + key); if (num == 0) { num = 1u; } return num; } internal static int GetStableSpawnableId(string ownerGuid, string key) { uint stableHash = GetStableHash(ownerGuid + ":" + key); return (int)(0x40000000 | (stableHash & 0x3FFFFFFF)); } internal static int ClampPercent(int value) { return Mathf.Clamp(value, 0, 100); } internal static int GetDeterministicPercent(Vector3 position, int seed, string key) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) int num = seed; num = (num * 397) ^ Mathf.RoundToInt(position.x * 100f); num = (num * 397) ^ Mathf.RoundToInt(position.y * 100f); num = (num * 397) ^ Mathf.RoundToInt(position.z * 100f); for (int i = 0; i < key.Length; i++) { num = (num * 397) ^ key[i]; } if (num == int.MinValue) { num = int.MaxValue; } return Mathf.Abs(num) % 100; } internal static bool TrySetMaterialTint(Material material, Color tint) { //IL_0027: 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) if ((Object)(object)material == (Object)null) { return false; } if (material.HasProperty("_BaseColor")) { material.SetColor("_BaseColor", tint); return true; } if (material.HasProperty("_Color")) { material.SetColor("_Color", tint); return true; } return false; } private static uint GetStableHash(string text) { uint num = 2166136261u; for (int i = 0; i < text.Length; i++) { num ^= text[i]; num *= 16777619; } return num; } } } namespace TryConnect.Patches { [HarmonyPatch(typeof(SpawnableSettings), "GetSpawnableSoById")] internal static class SpawnableSettingsPatches { private static void Postfix(int id, ref SpawnableSO __result) { if ((Object)(object)__result == (Object)null) { __result = RuntimeItemRegistry.GetCustomSpawnable(id); } } } [HarmonyPatch(typeof(ItemPriceSettings), "GetBasePrice")] internal static class ItemPriceSettingsBasePricePatches { private static bool Prefix(SpawnableSO spawnableSO, ref int __result) { return !RuntimeItemRegistry.TryGetCustomBasePrice(spawnableSO, ref __result); } } [HarmonyPatch(typeof(ItemPriceSettings), "GetPriceIncreasePerFloor")] internal static class ItemPriceSettingsFloorPricePatches { private static bool Prefix(SpawnableSO spawnableSO, ref int __result) { return !RuntimeItemRegistry.TryGetCustomFloorPrice(spawnableSO, ref __result); } } [HarmonyPatch(typeof(ItemDescriptionSettings), "GetDescription")] internal static class ItemDescriptionSettingsPatches { private static bool Prefix(SpawnableSO spawnableSO, ref string __result) { return !RuntimeItemRegistry.TryGetCustomDescription(spawnableSO, ref __result); } } [HarmonyPatch(typeof(ItemStampManager), "GetUniqueLoot", new Type[] { typeof(MMLootTableGameObjectSO), typeof(Vector3) })] internal static class ItemStampManagerLootPatches { private static void Postfix(MMLootTableGameObjectSO lootTable, Vector3 stampPosition, ref GameObject __result) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) __result = RuntimeItemRegistry.GetShopReplacement(lootTable, stampPosition, __result); } } [HarmonyPatch(typeof(ItemStamp), "SpawnItem")] internal static class ItemStampSpawnPatches { private static bool Prefix(ItemStamp __instance, GameObject prefab, Vector3 position, Quaternion rotation, Vector3 scale) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) return !RuntimeItemRegistry.TrySpawnCustomItemStampPrefab(__instance, prefab, position, rotation, scale); } } [HarmonyPatch(typeof(NewConsole), "SpawnPrefabServer")] internal static class NewConsoleSpawnPatches { private static bool Prefix(GameObject prefab, Vector3 position) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) return !RuntimeItemRegistry.TrySpawnConsolePrefab(prefab, position); } } [HarmonyPatch] internal static class CustomNetworkManagerPatches { [CompilerGenerated] private sealed class d__0 : IEnumerable, IEnumerable, IEnumerator, IDisposable, IEnumerator { private int <>1__state; private MethodBase <>2__current; private int <>l__initialThreadId; MethodBase IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__0(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = AccessTools.Method(typeof(CustomNetworkManager), "OnStartServer", (Type[])null, (Type[])null); <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = AccessTools.Method(typeof(CustomNetworkManager), "OnClientConnect", (Type[])null, (Type[])null); <>1__state = 2; return true; case 2: <>1__state = -1; <>2__current = AccessTools.Method(typeof(CustomNetworkManager), "OnClientSceneChanged", (Type[])null, (Type[])null); <>1__state = 3; return true; case 3: <>1__state = -1; 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(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; return this; } return new d__0(0); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } [IteratorStateMachine(typeof(d__0))] private static IEnumerable TargetMethods() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__0(-2); } private static void Postfix() { RuntimeItemRegistry.TryRegisterRuntimeContent(); } } [HarmonyPatch] internal static class NetworkClientSpawnLifecyclePatches { [CompilerGenerated] private sealed class d__0 : IEnumerable, IEnumerable, IEnumerator, IDisposable, IEnumerator { private int <>1__state; private MethodBase <>2__current; private int <>l__initialThreadId; MethodBase IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__0(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = AccessTools.Method(typeof(NetworkClient), "ClearSpawners", (Type[])null, (Type[])null); <>1__state = 1; return true; case 1: <>1__state = -1; 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(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; return this; } return new d__0(0); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } [IteratorStateMachine(typeof(d__0))] private static IEnumerable TargetMethods() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__0(-2); } private static void Postfix() { RuntimeItemRegistry.TryEnsureAllClientRegistrations(); } } [HarmonyPatch(typeof(NetworkClient), "OnSpawn")] internal static class NetworkClientOnSpawnPatches { private static void Prefix(SpawnMessage message) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) RuntimeItemRegistry.TryEnsureClientRegistration(message.assetId); } } } namespace TryConnect.MonoBehaviours { internal class TryConnectComponent : MonoBehaviour { public void Awake() { } public void Start() { } public void Update() { } public void LateUpdate() { } } }