Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ValheimVehicle v1.5.4
BepInEx/plugins/ValheimVehicle/ValheimVehicle.dll
Decompiled a week agousing System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Newtonsoft.Json.Linq; using Splatform; using UnityEngine; using UnityEngine.Networking; [assembly: Guid("0ff27dff-2359-4065-842f-ba66aaac02ff")] [assembly: CompilationRelaxations(8)] [assembly: ComVisible(false)] [assembly: AssemblyFileVersion("1.5.3.1")] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyTitle("ValheimVehicle")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ValheimVehicle")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: AssemblyVersion("1.5.3.1")] [BepInPlugin("Dropoff.VehicleMod", "Vehicle Mod", "1.5.4")] public class BepInExPlugin : BaseUnityPlugin { [HarmonyPatch(typeof(Player), "SetControls")] private static class DriverMovementPatch { private static void Prefix(Player __instance, ref Vector3 movedir, ref bool run, ref bool autoRun, bool jump) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && ((Character)__instance).IsAttached()) { Transform attachPoint = __instance.GetAttachPoint(); RearWheelDrive rearWheelDrive = (Object.op_Implicit((Object)(object)attachPoint) ? ((Component)attachPoint).GetComponentInParent<RearWheelDrive>() : null); if (Object.op_Implicit((Object)(object)rearWheelDrive) && rearWheelDrive.IsLocalDriver()) { rearWheelDrive.SetMovementInput((InputBlocked() || jump) ? Vector3.zero : movedir); movedir = Vector3.zero; run = (autoRun = false); __instance.m_autoRun = false; } } } } [HarmonyPatch(typeof(ZNetScene), "Awake")] private static class RegisterVehicle { private static void Prefix(ZNetScene __instance) { if (!Object.op_Implicit((Object)(object)VehiclePrefab)) { return; } GameObject val = __instance.m_prefabs.Find((GameObject p) => Object.op_Implicit((Object)(object)p) && ((Object)p).name == ((Object)VehiclePrefab).name); if (Object.op_Implicit((Object)(object)val) && (Object)(object)val != (Object)(object)VehiclePrefab) { ((BaseUnityPlugin)instance).Logger.LogError((object)("A different mod already registered prefab " + ((Object)VehiclePrefab).name)); return; } ImpactEffect component = VehiclePrefab.GetComponent<ImpactEffect>(); if (Object.op_Implicit((Object)(object)component)) { component.m_hitEffect.m_effectPrefabs = (from name in new string[1] { "vfx_HitSparks" } select __instance.m_prefabs.Find((GameObject p) => Object.op_Implicit((Object)(object)p) && ((Object)p).name == name) into p where Object.op_Implicit((Object)(object)p) select p).Select(delegate(GameObject p) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown EffectData val2 = new EffectData(); val2.m_prefab = p; return val2; }).ToArray(); } if (!Object.op_Implicit((Object)(object)val)) { __instance.m_prefabs.Add(VehiclePrefab); } } } [HarmonyPatch(typeof(Chair), "Interact")] private static class VehicleSeats { private static float lastSitTime = -10f; private static bool Prefix(Chair __instance, Humanoid human, bool hold, ref bool __result) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) RearWheelDrive componentInParent = ((Component)__instance).GetComponentInParent<RearWheelDrive>(); if (!Object.op_Implicit((Object)(object)componentInParent)) { return true; } __result = false; Player val = (Player)(object)((human is Player) ? human : null); if (hold || !Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)__instance.m_attachPoint) || ((Character)val).IsEncumbered() || Time.time - lastSitTime < 2f || Vector3.Distance(((Component)val).transform.position, __instance.m_attachPoint.position) >= __instance.m_useDistance) { return false; } if (__instance.IsInUse()) { ((Character)val).Message((MessageType)2, "$msg_blocked", 0, (Sprite)null, false); return false; } ZNetView component = ((Component)componentInParent).GetComponent<ZNetView>(); if (!Object.op_Implicit((Object)(object)component) || !component.IsValid()) { return false; } if (((Object)__instance.m_attachPoint).name == "attachpoint_driver") { if (component.GetZDO().GetLong("Dropoff.VehicleMod.Creator", 0L) != val.GetPlayerID()) { ((Character)val).Message((MessageType)2, "Only the player who spawned this vehicle can drive it", 0, (Sprite)null, false); return false; } component.ClaimOwnership(); } ((Character)val).AttachStart(__instance.m_attachPoint, ((Component)componentInParent).gameObject, false, false, true, __instance.m_attachAnimation, __instance.m_detachOffset, (Transform)null); lastSitTime = Time.time; return false; } } public const string PluginId = "Dropoff.VehicleMod"; internal const string CreatorKey = "Dropoff.VehicleMod.Creator"; internal const string LightsKey = "Dropoff.VehicleMod.Lights"; internal static ConfigEntry<KeyCode> SpawnKey; internal static ConfigEntry<KeyCode> BrakeKey; internal static ConfigEntry<KeyCode> FlipKey; internal static ConfigEntry<KeyCode> LightKey; internal static ConfigEntry<KeyCode> DespawnKey; private readonly Harmony harmony = new Harmony("Dropoff.VehicleMod"); private GameObject spawnedPrefab; private AssetBundle bundle; private GameObject templateRoot; private static BepInExPlugin instance; private bool spawnHeld; private bool despawnHeld; public static GameObject VehiclePrefab { get; private set; } private void Awake() { //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Expected O, but got Unknown instance = this; SpawnKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "Spawn", (KeyCode)278, "Spawn or recall your vehicle."); BrakeKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "Brake", (KeyCode)121, "Hold to brake."); FlipKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "Flip", (KeyCode)277, "Right the vehicle while in the driver seat."); LightKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "Headlights", (KeyCode)104, "Toggle headlights while in the driver seat."); DespawnKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "Despawn", (KeyCode)279, "Store your unoccupied vehicle; trunk items are kept with the character."); ConfigEntry<int> version = ((BaseUnityPlugin)this).Config.Bind<int>("Compatibility", "ControlsVersion", 0, "Internal migration version. Leave this value unchanged."); MigrateLegacyControls(SpawnKey, DespawnKey, FlipKey, version); try { bundle = GetAssetBundleFromResources("greenwood"); if (!Object.op_Implicit((Object)(object)bundle)) { throw new InvalidOperationException("Could not load the embedded vehicle AssetBundle."); } GameObject val = bundle.LoadAsset<GameObject>("Assets/ValheimVehicles/greenwood/greenwood.prefab"); if (!Object.op_Implicit((Object)(object)val)) { throw new InvalidOperationException("Original vehicle framework is missing."); } templateRoot = new GameObject("ValheimVehicle_Templates"); templateRoot.SetActive(false); Object.DontDestroyOnLoad((Object)(object)templateRoot); VehiclePrefab = Object.Instantiate<GameObject>(val, templateRoot.transform, false); ((Object)VehiclePrefab).name = ((Object)val).name; if (!Object.op_Implicit((Object)(object)VehiclePrefab) || !Object.op_Implicit((Object)(object)VehiclePrefab.GetComponent<RearWheelDrive>()) || !Object.op_Implicit((Object)(object)VehiclePrefab.GetComponent<ZNetView>())) { throw new InvalidOperationException("Vehicle prefab or its required scripts are missing."); } VehicleCollisionGeometry.Apply(VehiclePrefab); VehiclePrefab.SetActive(true); Chair[] componentsInChildren = VehiclePrefab.GetComponentsInChildren<Chair>(true); foreach (Chair val2 in componentsInChildren) { val2.m_inShip = true; } VehiclePrefab.AddComponent<VehicleTrunk>(); harmony.PatchAll(typeof(BepInExPlugin).Assembly); ((Component)this).gameObject.AddComponent<VehicleRadio>().Initialize(this); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Original Greenwood model from 1.2.1 ready; Radio X available in vehicle."); ((BaseUnityPlugin)this).Logger.LogInfo((object)("ValheimVehicle 1.5.4 loaded for Valheim " + Version.GetVersionString(false) + "; Unity " + Application.unityVersion)); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Vehicle initialization failed: " + ex)); ((Behaviour)this).enabled = false; } } internal static void MigrateLegacyControls(ConfigEntry<KeyCode> spawn, ConfigEntry<KeyCode> despawn, ConfigEntry<KeyCode> flip, ConfigEntry<int> version) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Invalid comparison between Unknown and I4 //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Invalid comparison between Unknown and I4 if (version.Value < 1) { if ((int)spawn.Value == 116) { spawn.Value = (KeyCode)278; } if ((int)despawn.Value == 103) { despawn.Value = (KeyCode)279; } if ((int)flip.Value == 102) { flip.Value = (KeyCode)277; } version.Value = 1; } } internal static void LogInfo(string text) { if (Object.op_Implicit((Object)(object)instance)) { ((BaseUnityPlugin)instance).Logger.LogInfo((object)text); } } internal static void LogError(string text) { if (Object.op_Implicit((Object)(object)instance)) { ((BaseUnityPlugin)instance).Logger.LogError((object)text); } } internal static void LogWarning(string text) { if (Object.op_Implicit((Object)(object)instance)) { ((BaseUnityPlugin)instance).Logger.LogWarning((object)text); } } public static AssetBundle GetAssetBundleFromResources(string fileName) { Assembly assembly = typeof(BepInExPlugin).Assembly; string name = assembly.GetManifestResourceNames().Single((string n) => n.EndsWith("." + fileName, StringComparison.Ordinal)); using Stream stream = assembly.GetManifestResourceStream(name); using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); return AssetBundle.LoadFromMemory(memoryStream.ToArray()); } public static bool InputBlocked() { if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && (!Object.op_Implicit((Object)(object)Chat.instance) || !Chat.instance.HasFocus()) && !Menu.IsVisible() && !Console.IsVisible() && !TextInput.IsVisible() && !InventoryGui.IsVisible() && !Hud.InRadial() && !StoreGui.IsVisible() && !Minimap.IsOpen()) { if (Object.op_Implicit((Object)(object)TextViewer.instance)) { return TextViewer.instance.IsVisible(); } return false; } return true; } internal static bool Pressed(KeyCode key, ref bool wasHeld) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) bool key2 = ZInput.GetKey(key, true); bool result = key2 && !wasHeld; wasHeld = key2; return result; } private void Update() { //IL_0005: 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) bool flag = Pressed(SpawnKey.Value, ref spawnHeld); bool flag2 = Pressed(DespawnKey.Value, ref despawnHeld); if (!InputBlocked()) { if (Object.op_Implicit((Object)(object)VehiclePrefab) && Object.op_Implicit((Object)(object)ZNetScene.instance) && flag) { SpawnOrRecall(); } if (Object.op_Implicit((Object)(object)ZNetScene.instance) && flag2) { Despawn(); } } } public GameObject SpawnOrRecall() { //IL_0046: 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_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: 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_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: 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_0124: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: 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) Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer) || !Object.op_Implicit((Object)(object)VehiclePrefab) || !Object.op_Implicit((Object)(object)ZNetScene.instance) || ((Character)localPlayer).IsTeleporting() || ((Character)localPlayer).IsAttached() || ((Character)localPlayer).IsDead()) { return null; } Vector3 val = ((Component)localPlayer).transform.position + ((Component)localPlayer).transform.forward * 5f + Vector3.up * 4f; Quaternion val2 = ((Component)localPlayer).transform.rotation * Quaternion.Euler(0f, -90f, 0f); if (!Object.op_Implicit((Object)(object)spawnedPrefab)) { spawnedPrefab = FindOwnedVehicle(localPlayer.GetPlayerID()); } if (!Object.op_Implicit((Object)(object)spawnedPrefab)) { spawnedPrefab = Object.Instantiate<GameObject>(VehiclePrefab, val, val2); spawnedPrefab.GetComponent<ZNetView>().GetZDO().Set("Dropoff.VehicleMod.Creator", localPlayer.GetPlayerID()); Piece component = spawnedPrefab.GetComponent<Piece>(); if (Object.op_Implicit((Object)(object)component)) { component.SetCreator(localPlayer.GetPlayerID(), ((IUser)PlatformManager.DistributionPlatform.LocalUser).PlatformUserID); } } else { foreach (Player allPlayer in Player.GetAllPlayers()) { if (((Character)allPlayer).IsAttached() && Object.op_Implicit((Object)(object)allPlayer.GetAttachPoint()) && allPlayer.GetAttachPoint().IsChildOf(spawnedPrefab.transform)) { ((Character)localPlayer).Message((MessageType)2, "Vehicle is occupied", 0, (Sprite)null, false); return spawnedPrefab; } } ZNetView component2 = spawnedPrefab.GetComponent<ZNetView>(); component2.ClaimOwnership(); Rigidbody component3 = spawnedPrefab.GetComponent<Rigidbody>(); component3.position = val; component2.GetZDO().SetPosition(val); component3.rotation = val2; component3.linearVelocity = Vector3.zero; component3.angularVelocity = Vector3.zero; component3.WakeUp(); } return spawnedPrefab; } private static GameObject FindOwnedVehicle(long creator) { VehicleTrunk[] array = Object.FindObjectsByType<VehicleTrunk>((FindObjectsSortMode)0); foreach (VehicleTrunk vehicleTrunk in array) { ZNetView component = ((Component)vehicleTrunk).GetComponent<ZNetView>(); if (Object.op_Implicit((Object)(object)component) && component.IsValid() && component.GetZDO().GetLong("Dropoff.VehicleMod.Creator", 0L) == creator) { return ((Component)vehicleTrunk).gameObject; } } return null; } public bool Despawn() { Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer) || !Object.op_Implicit((Object)(object)ZNetScene.instance)) { return false; } if (!Object.op_Implicit((Object)(object)spawnedPrefab)) { spawnedPrefab = FindOwnedVehicle(localPlayer.GetPlayerID()); } if (!Object.op_Implicit((Object)(object)spawnedPrefab)) { return false; } foreach (Player allPlayer in Player.GetAllPlayers()) { if (((Character)allPlayer).IsAttached() && Object.op_Implicit((Object)(object)allPlayer.GetAttachPoint()) && allPlayer.GetAttachPoint().IsChildOf(spawnedPrefab.transform)) { ((Character)localPlayer).Message((MessageType)2, "Сначала все должны выйти из машины", 0, (Sprite)null, false); return false; } } VehicleTrunk component = spawnedPrefab.GetComponent<VehicleTrunk>(); if (Object.op_Implicit((Object)(object)component)) { component.CloseAndPersist(); } spawnedPrefab.GetComponent<ZNetView>().ClaimOwnership(); ZNetScene.instance.Destroy(spawnedPrefab); spawnedPrefab = null; return true; } private void OnDestroy() { harmony.UnpatchAll("Dropoff.VehicleMod"); if (Object.op_Implicit((Object)(object)templateRoot)) { Object.Destroy((Object)(object)templateRoot); } VehicleCollisionGeometry.Release(); if (Object.op_Implicit((Object)(object)bundle)) { bundle.Unload(false); } VehiclePrefab = null; instance = null; } } public class MeshesDeformation : MonoBehaviour { public MeshFilter[] meshFilters; public MeshCollider[] colliders; public float impactDamage; public float deformationRadius; public float maxDeformation; public float minVelocity; private float delayTimeDeform = 0.1f; private Vector3[][] originalVertices; private float nextTimeDeform; private void Start() { originalVertices = new Vector3[meshFilters.Length][]; for (int i = 0; i < meshFilters.Length; i++) { originalVertices[i] = meshFilters[i].mesh.vertices; meshFilters[i].mesh.MarkDynamic(); } } private void DeformationMesh(Mesh mesh, Transform localTransform, List<Vector3> contactPoints, Vector3 contactVelocity, int i) { //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) //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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_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_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_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_00fd: Unknown result type (might be due to invalid IL or missing references) bool flag = false; Vector3 val = localTransform.InverseTransformDirection(contactVelocity); Vector3[] vertices = mesh.vertices; for (int j = 0; j < vertices.Length; j++) { foreach (Vector3 contactPoint in contactPoints) { Vector3 val2 = localTransform.InverseTransformPoint(contactPoint); Vector3 val3 = val2 - vertices[j]; float magnitude = ((Vector3)(ref val3)).magnitude; if (magnitude <= deformationRadius) { ref Vector3 reference = ref vertices[j]; reference += val * (deformationRadius - magnitude) * impactDamage; Vector3 val4 = vertices[j] - originalVertices[i][j]; if (((Vector3)(ref val4)).magnitude > maxDeformation) { ref Vector3 reference2 = ref vertices[j]; reference2 = originalVertices[i][j] + ((Vector3)(ref val4)).normalized * maxDeformation; } flag = true; } } } if (flag) { mesh.vertices = vertices; mesh.RecalculateNormals(); mesh.RecalculateBounds(); if (colliders.Length != 0 && (Object)(object)colliders[i] != (Object)null) { colliders[i].sharedMesh = mesh; } } } private void OnCollisionEnter(Collision collision) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) if (!((Behaviour)this).isActiveAndEnabled || originalVertices == null || !(Time.time > nextTimeDeform)) { return; } Vector3 relativeVelocity = collision.relativeVelocity; if (!(((Vector3)(ref relativeVelocity)).magnitude > minVelocity)) { return; } List<ContactPoint> list = new List<ContactPoint>(collision.contactCount); collision.GetContacts(list); List<Vector3> list2 = new List<Vector3>(collision.contactCount); for (int i = 0; i < collision.contactCount; i++) { ContactPoint val = list[i]; list2.Add(((ContactPoint)(ref val)).point); } Vector3 contactVelocity = collision.relativeVelocity * 0.02f; for (int j = 0; j < meshFilters.Length; j++) { if ((Object)(object)meshFilters[j] != (Object)null) { DeformationMesh(meshFilters[j].mesh, ((Component)meshFilters[j]).transform, list2, contactVelocity, j); } } nextTimeDeform = Time.time + delayTimeDeform; } } public class RearWheelDrive : MonoBehaviour { public WheelCollider[] wheels; public float maxAngle = 30f; public float maxTorque = 150f; public GameObject wheelShape; private Rigidbody body; private ZNetView view; private Transform driverSeat; private Transform headlights; private readonly VehicleWaterDrive waterDrive = new VehicleWaterDrive(); private readonly List<Transform> wheelVisuals = new List<Transform>(); private float steer; private float throttle; private bool brake; private bool flipHeld; private bool lightsHeld; public bool InWater => waterDrive.InWater; public void Start() { //IL_004f: Unknown result type (might be due to invalid IL or missing references) body = ((Component)this).GetComponent<Rigidbody>(); view = ((Component)this).GetComponent<ZNetView>(); if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)view)) { ((Behaviour)this).enabled = false; return; } body.centerOfMass = new Vector3(0f, 0.04f, 0f); wheels = ((Component)this).GetComponentsInChildren<WheelCollider>(); driverSeat = ((Component)this).transform.Find("attachpoint_driver"); headlights = ((Component)this).transform.Find("Headlights"); WheelCollider[] array = wheels; foreach (WheelCollider val in array) { Transform item = null; if (Object.op_Implicit((Object)(object)wheelShape)) { GameObject val2 = Object.Instantiate<GameObject>(wheelShape, ((Component)val).transform, false); MeshRenderer componentInChildren = val2.GetComponentInChildren<MeshRenderer>(); if (Object.op_Implicit((Object)(object)componentInChildren)) { ((Renderer)componentInChildren).enabled = true; } item = val2.transform; } wheelVisuals.Add(item); } } public bool IsLocalDriver() { Player localPlayer = Player.m_localPlayer; if (Object.op_Implicit((Object)(object)localPlayer) && Object.op_Implicit((Object)(object)view) && view.IsValid() && ((Character)localPlayer).IsAttached() && (Object)(object)localPlayer.GetAttachPoint() == (Object)(object)driverSeat) { return view.GetZDO().GetLong("Dropoff.VehicleMod.Creator", 0L) == localPlayer.GetPlayerID(); } return false; } internal void SetMovementInput(Vector3 movement) { steer = Mathf.Clamp(movement.x, -1f, 1f); throttle = Mathf.Clamp(movement.z, -1f, 1f); } public void Update() { //IL_002b: 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_0057: 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_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_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_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_00ed: 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_010c: 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_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: 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) if (!Object.op_Implicit((Object)(object)view) || !view.IsValid()) { return; } if (!IsLocalDriver() || BepInExPlugin.InputBlocked()) { SetMovementInput(Vector3.zero); } brake = false; bool flag = BepInExPlugin.Pressed(BepInExPlugin.FlipKey.Value, ref flipHeld); bool flag2 = BepInExPlugin.Pressed(BepInExPlugin.LightKey.Value, ref lightsHeld); if (IsLocalDriver()) { if (!view.IsOwner()) { view.ClaimOwnership(); } if (!BepInExPlugin.InputBlocked()) { brake = ZInput.GetKey(BepInExPlugin.BrakeKey.Value, true); if (flag) { Rigidbody obj = body; obj.position += Vector3.up * 0.5f; Rigidbody obj2 = body; Quaternion rotation = body.rotation; obj2.rotation = Quaternion.Euler(0f, ((Quaternion)(ref rotation)).eulerAngles.y, 0f); body.linearVelocity = Vector3.zero; body.angularVelocity = Vector3.zero; } if (flag2) { view.GetZDO().Set("Dropoff.VehicleMod.Lights", !view.GetZDO().GetBool("Dropoff.VehicleMod.Lights", false)); } } } if (Object.op_Implicit((Object)(object)headlights)) { ((Component)headlights).gameObject.SetActive(view.GetZDO().GetBool("Dropoff.VehicleMod.Lights", false)); } Vector3 val2 = default(Vector3); Quaternion val3 = default(Quaternion); for (int i = 0; i < wheels.Length; i++) { Transform val = wheelVisuals[i]; if (Object.op_Implicit((Object)(object)val)) { wheels[i].GetWorldPose(ref val2, ref val3); val.SetPositionAndRotation(val2, val3); Transform val4 = ((((Component)wheels[i]).transform.childCount > 1) ? ((Component)wheels[i]).transform.GetChild(0) : null); if (Object.op_Implicit((Object)(object)val4) && (Object)(object)val4 != (Object)(object)val) { val4.position = val2; } } } } private void FixedUpdate() { //IL_00e8: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)view) && view.IsValid() && wheels != null) { bool flag = view.IsOwner(); bool flag2 = flag && IsLocalDriver() && !BepInExPlugin.InputBlocked(); if (flag && !body.isKinematic) { waterDrive.Step(body, flag2, throttle, steer, brake); } WheelCollider[] array = wheels; foreach (WheelCollider val in array) { val.motorTorque = ((flag2 && !brake) ? (maxTorque * throttle) : 0f); val.brakeTorque = ((flag2 && brake) ? maxTorque : 0f); val.steerAngle = ((flag2 && ((Component)val).transform.localPosition.z > 0f) ? (maxAngle * steer) : 0f); } } } public bool IsOnGround() { if (wheels == null) { return false; } WheelCollider[] array = wheels; foreach (WheelCollider val in array) { if (Object.op_Implicit((Object)(object)val) && val.isGrounded) { return true; } } return false; } } internal static class VehicleCollisionGeometry { private static readonly List<Mesh> generated = new List<Mesh>(); internal static Bounds GetPartBounds(Transform root, string part) { //IL_0004: 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_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_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: 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_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) bool flag = false; Bounds result = default(Bounds); MeshFilter[] componentsInChildren = ((Component)root).GetComponentsInChildren<MeshFilter>(true); foreach (MeshFilter val in componentsInChildren) { if (((Object)val).name != part || !Object.op_Implicit((Object)(object)val.sharedMesh)) { continue; } Renderer component = ((Component)val).GetComponent<Renderer>(); if (!Object.op_Implicit((Object)(object)component) || !component.enabled) { continue; } bool flag2 = true; Transform val2 = ((Component)val).transform; while (Object.op_Implicit((Object)(object)val2) && (Object)(object)val2 != (Object)(object)root) { if (!((Component)val2).gameObject.activeSelf) { flag2 = false; break; } val2 = val2.parent; } if (!flag2) { continue; } Vector3[] vertices = val.sharedMesh.vertices; foreach (Vector3 val3 in vertices) { Vector3 val4 = root.InverseTransformPoint(((Component)val).transform.TransformPoint(val3)); if (!flag) { result = new Bounds(val4, Vector3.zero); flag = true; } else { ((Bounds)(ref result)).Encapsulate(val4); } } } if (!flag) { throw new InvalidOperationException("Original car mesh not found: " + part); } return result; } internal static void Apply(GameObject car) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_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_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) Bounds partBounds = GetPartBounds(car.transform, "boot_ok"); Bounds partBounds2 = GetPartBounds(car.transform, "bonnet_ok"); MeshCollider val = null; MeshCollider[] componentsInChildren = car.GetComponentsInChildren<MeshCollider>(true); foreach (MeshCollider val2 in componentsInChildren) { if (((Collider)val2).enabled && ((Object)val2).name == "col_back") { val = val2; break; } } if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.sharedMesh)) { throw new InvalidOperationException("Original body collision mesh is missing."); } Vector3[] vertices = val.sharedMesh.vertices; for (int j = 0; j < vertices.Length; j++) { ref Vector3 reference = ref vertices[j]; reference = car.transform.InverseTransformPoint(((Component)val).transform.TransformPoint(vertices[j])); } int[] triangles = val.sharedMesh.triangles; AddSection(car, val, vertices, triangles, "Rear", float.NegativeInfinity, ((Bounds)(ref partBounds)).max.z); AddSection(car, val, vertices, triangles, "Cabin", ((Bounds)(ref partBounds)).max.z, ((Bounds)(ref partBounds2)).min.z); AddSection(car, val, vertices, triangles, "Front", ((Bounds)(ref partBounds2)).min.z, float.PositiveInfinity); ((Collider)val).enabled = false; } private static void AddSection(GameObject car, MeshCollider original, Vector3[] points, int[] faces, string name, float minimum, float maximum) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown BuildSectionData(points, faces, minimum, maximum, out var vertices, out var triangles); if (triangles.Count < 12) { throw new InvalidOperationException("Body collision section is empty: " + name); } Mesh val = new Mesh(); ((Object)val).name = "VehicleCollision_" + name; val.SetVertices(vertices); val.SetTriangles(triangles, 0); val.RecalculateBounds(); generated.Add(val); GameObject val2 = new GameObject("VehicleBody_" + name); val2.layer = ((Component)original).gameObject.layer; val2.transform.SetParent(car.transform, false); MeshCollider val3 = val2.AddComponent<MeshCollider>(); ((Collider)val3).sharedMaterial = ((Collider)original).sharedMaterial; val3.convex = true; val3.sharedMesh = val; ((Collider)val3).contactOffset = ((Collider)original).contactOffset; } internal static void BuildSectionData(Vector3[] points, int[] faces, float minimum, float maximum, out List<Vector3> vertices, out List<int> triangles) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: 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_00bf: 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_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) vertices = new List<Vector3>(); triangles = new List<int>(); for (int i = 0; i < faces.Length; i += 3) { List<Vector3> list = new List<Vector3>(); list.Add(points[faces[i]]); list.Add(points[faces[i + 1]]); list.Add(points[faces[i + 2]]); List<Vector3> list2 = list; if (!float.IsNegativeInfinity(minimum)) { list2 = Clip(list2, minimum, above: true); } if (!float.IsPositiveInfinity(maximum)) { list2 = Clip(list2, maximum, above: false); } if (list2.Count < 3) { continue; } int count = vertices.Count; vertices.AddRange(list2); for (int j = 1; j + 1 < list2.Count; j++) { Vector3 val = Vector3.Cross(list2[j] - list2[0], list2[j + 1] - list2[0]); if (!(((Vector3)(ref val)).sqrMagnitude < 1E-12f)) { triangles.Add(count); triangles.Add(count + j); triangles.Add(count + j + 1); } } } } private static List<Vector3> Clip(List<Vector3> input, float plane, bool above) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: 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_00a6: Unknown result type (might be due to invalid IL or missing references) List<Vector3> list = new List<Vector3>(); if (input.Count == 0) { return list; } Vector3 val = input[input.Count - 1]; bool flag = (above ? (val.z >= plane) : (val.z <= plane)); foreach (Vector3 item in input) { bool flag2 = (above ? (item.z >= plane) : (item.z <= plane)); if (flag2 != flag) { float num = (plane - val.z) / (item.z - val.z); list.Add(Vector3.LerpUnclamped(val, item, num)); } if (flag2) { list.Add(item); } val = item; flag = flag2; } return list; } internal static void Release() { foreach (Mesh item in generated) { if (Object.op_Implicit((Object)(object)item)) { Object.Destroy((Object)(object)item); } } generated.Clear(); } } public sealed class VehicleRadio : MonoBehaviour { private ConfigEntry<KeyCode> toggleKey; private ConfigEntry<KeyCode> nextKey; private ConfigEntry<bool> radioEnabled; private ConfigEntry<float> volume; private VehicleRadioFiles.Track[] tracks = new VehicleRadioFiles.Track[0]; private BepInExPlugin plugin; private string musicFolder; private AudioSource source; private AudioClip clip; private UnityWebRequest request; private Coroutine loadingRoutine; private int index; private int generation; private bool loading; private bool initialized; private bool paused; private bool started; private bool observedPlaying; private bool toggleHeld; private bool nextHeld; private bool wasInVehicle; private float playRequestedAt; public int TrackIndex => index; public int TrackCount => tracks.Length; public string TrackTitle { get { if (tracks.Length != 0) { return tracks[index].title; } return ""; } } public bool IsPlaying { get { if (Object.op_Implicit((Object)(object)source)) { return source.isPlaying; } return false; } } public bool IsEnabled { get { if (radioEnabled != null) { return radioEnabled.Value; } return false; } } public bool IsLoading => loading; public AudioSource Source => source; public void Initialize(BepInExPlugin owner) { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected O, but got Unknown toggleKey = ((BaseUnityPlugin)owner).Config.Bind<KeyCode>("Controls", "RadioToggle", (KeyCode)289, "Turn Radio X on or off while seated in the car."); nextKey = ((BaseUnityPlugin)owner).Config.Bind<KeyCode>("Controls", "RadioNext", (KeyCode)290, "Next Radio X track while seated in the car."); radioEnabled = ((BaseUnityPlugin)owner).Config.Bind<bool>("Radio", "Enabled", false, "Remember whether Radio X is switched on. Playback only occurs inside this mod's car."); volume = ((BaseUnityPlugin)owner).Config.Bind<float>("Radio", "Volume", 0.55f, new ConfigDescription("Radio volume. Also follows the game's master volume; does not change other game audio.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[0])); plugin = owner; LoadPlaylist(); GameObject val = new GameObject("ValheimVehicle_RadioX_Local"); val.transform.SetParent(((Component)this).transform, false); source = val.AddComponent<AudioSource>(); source.playOnAwake = false; source.loop = false; source.spatialBlend = 0f; source.priority = 64; source.bypassReverbZones = true; source.ignoreListenerPause = false; initialized = true; } private void LoadPlaylist() { try { musicFolder = VehicleRadioFiles.ResolveFolder((((BaseUnityPlugin)plugin).Info == null) ? null : ((BaseUnityPlugin)plugin).Info.Location, typeof(VehicleRadio).Assembly.Location); tracks = VehicleRadioFiles.Load(musicFolder, Warn); index = 0; BepInExPlugin.LogInfo("Radio X: " + tracks.Length + " tracks from " + musicFolder); if (tracks.Length == 0) { Warn("No supported audio files found in '" + musicFolder + "'. Press the radio toggle to retry after adding files."); } } catch (Exception ex) { tracks = new VehicleRadioFiles.Track[0]; Warn("Cannot load radio files from '" + musicFolder + "': " + ex.Message); } } private static AudioType GetAudioType(string file) { return (AudioType)(Path.GetExtension(file).ToLowerInvariant() switch { ".mp3" => 13, ".ogg" => 14, ".wav" => 20, _ => 0, }); } private static bool InVehicle() { Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer) || ((Character)localPlayer).IsDead() || ((Character)localPlayer).IsTeleporting() || !((Character)localPlayer).IsAttached()) { return false; } Transform attachPoint = localPlayer.GetAttachPoint(); if (Object.op_Implicit((Object)(object)attachPoint)) { return Object.op_Implicit((Object)(object)((Component)attachPoint).GetComponentInParent<RearWheelDrive>()); } return false; } private bool ShouldPlay() { if (initialized && IsEnabled) { return InVehicle(); } return false; } private void Update() { //IL_000f: 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_007f: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) if (!initialized) { return; } bool flag = BepInExPlugin.Pressed(toggleKey.Value, ref toggleHeld); bool flag2 = BepInExPlugin.Pressed(nextKey.Value, ref nextHeld); bool flag3 = InVehicle(); if (flag3 && !wasInVehicle) { Notify(string.Concat("Radio X: ", IsEnabled ? "включено" : "выключено", " [", toggleKey.Value, "] · Следующая [", nextKey.Value, "]")); } wasInVehicle = flag3; if (flag3 && !BepInExPlugin.InputBlocked()) { if (flag) { if (tracks.Length == 0) { LoadPlaylist(); } if (tracks.Length == 0) { radioEnabled.Value = false; Notify("Radio X: музыка не найдена. Путь указан в LogOutput.log; F8 — повторить поиск"); } else { radioEnabled.Value = !radioEnabled.Value; Notify("Radio X: " + (IsEnabled ? "включено" : "выключено")); } } if (flag2 && tracks.Length > 0) { Advance(); Notify("Radio X: " + TrackTitle); } } source.volume = Mathf.Clamp01(volume.Value) * Mathf.Clamp01(PlatformPrefs.GetFloat("MasterVolume", 1f)); if (!ShouldPlay()) { Pause(); } else if (tracks.Length == 0) { radioEnabled.Value = false; } else { if (loading) { return; } if (!Object.op_Implicit((Object)(object)clip)) { loading = true; loadingRoutine = ((MonoBehaviour)this).StartCoroutine(LoadTrack(generation)); return; } if (paused) { source.UnPause(); paused = false; playRequestedAt = Time.realtimeSinceStartup; } else if (!started) { source.Play(); started = true; playRequestedAt = Time.realtimeSinceStartup; } if (source.isPlaying) { observedPlaying = true; } if (started && observedPlaying && !paused && !source.isPlaying && !AudioListener.pause && Time.timeScale > 0f && Time.realtimeSinceStartup - playRequestedAt > 0.25f) { Advance(); } } } private void Pause() { if (Object.op_Implicit((Object)(object)source) && Object.op_Implicit((Object)(object)clip) && started && !paused) { source.Pause(); paused = true; } } private void Advance() { CancelLoad(); ClearClip(); if (tracks.Length > 0) { index = (index + 1) % tracks.Length; } } private IEnumerator LoadTrack(int ticket) { int attempt = 0; while (true) { if (attempt < tracks.Length) { string path = Path.Combine(musicFolder, tracks[index].file); UnityWebRequestAsyncOperation operation = null; string error = null; try { if (!File.Exists(path)) { throw new FileNotFoundException("Track is missing.", tracks[index].file); } request = UnityWebRequestMultimedia.GetAudioClip(new Uri(path).AbsoluteUri, GetAudioType(path)); ((DownloadHandlerAudioClip)request.downloadHandler).streamAudio = true; request.timeout = 30; operation = request.SendWebRequest(); } catch (Exception ex) { error = ex.Message; } if (operation != null) { yield return operation; } if (ticket != generation) { break; } AudioClip loaded = null; try { if (error == null) { if ((int)request.result != 1) { error = request.error; } else { loaded = DownloadHandlerAudioClip.GetContent(request); } if (!Object.op_Implicit((Object)(object)loaded) && error == null) { error = "Decoder did not return an audio clip."; } } } catch (Exception ex2) { error = ex2.Message; } if (request != null) { request.Dispose(); request = null; } if (Object.op_Implicit((Object)(object)loaded) && error == null) { clip = loaded; ((Object)clip).name = TrackTitle; source.clip = clip; VehicleRadio vehicleRadio = this; VehicleRadio vehicleRadio2 = this; VehicleRadio vehicleRadio3 = this; bool flag = false; vehicleRadio3.observedPlaying = false; vehicleRadio.started = (vehicleRadio2.paused = flag); loading = false; loadingRoutine = null; if (ShouldPlay()) { Notify("Radio X · " + (index + 1) + "/" + tracks.Length + ": " + TrackTitle); } break; } if (Object.op_Implicit((Object)(object)loaded)) { Object.Destroy((Object)(object)loaded); } Warn("Skipping " + tracks[index].file + ": " + error); index = (index + 1) % tracks.Length; attempt++; continue; } loading = false; loadingRoutine = null; radioEnabled.Value = false; Notify("Radio X: записи не удалось открыть. Проверь папку RadioX."); break; } } private void CancelLoad() { generation++; if (request != null) { request.Abort(); } if (loadingRoutine != null) { ((MonoBehaviour)this).StopCoroutine(loadingRoutine); } loadingRoutine = null; if (request != null) { request.Dispose(); request = null; } loading = false; } private void ClearClip() { if (Object.op_Implicit((Object)(object)source)) { source.Stop(); source.clip = null; } if (Object.op_Implicit((Object)(object)clip)) { Object.Destroy((Object)(object)clip); } clip = null; started = (paused = (observedPlaying = false)); } private void OnDisable() { Pause(); CancelLoad(); } private void OnDestroy() { CancelLoad(); ClearClip(); if (Object.op_Implicit((Object)(object)source)) { Object.Destroy((Object)(object)((Component)source).gameObject); } } private void Notify(string message) { if (Object.op_Implicit((Object)(object)Player.m_localPlayer)) { ((Character)Player.m_localPlayer).Message((MessageType)1, message, 0, (Sprite)null, false); } } private void Warn(string message) { BepInExPlugin.LogWarning("Radio X: " + message); } } internal static class VehicleRadioFiles { internal sealed class Track { public string file; public string title; } internal static string ResolveFolder(string pluginLocation, string assemblyLocation) { string text = null; string[] array = new string[2] { pluginLocation, assemblyLocation }; foreach (string text2 in array) { if (!string.IsNullOrWhiteSpace(text2)) { string text3 = Path.Combine(Path.GetDirectoryName(Path.GetFullPath(text2)), "RadioX"); if (text == null) { text = text3; } if (Directory.Exists(text3)) { return text3; } } } if (text == null) { throw new InvalidDataException("BepInEx did not provide the plugin location."); } return text; } internal static Track[] Load(string folder, Action<string> warn) { //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Invalid comparison between Unknown and I4 //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Invalid comparison between Unknown and I4 string text = Path.Combine(folder, "playlist.json"); if (File.Exists(text)) { try { JToken obj = JObject.Parse(File.ReadAllText(text))["tracks"]; JArray val = (JArray)(object)((obj is JArray) ? obj : null); if (val == null || ((JContainer)val).Count == 0) { throw new InvalidDataException("Empty or absent tracks array."); } List<Track> list = new List<Track>(); foreach (JToken item in val) { JObject val2 = (JObject)(object)((item is JObject) ? item : null); if (val2 == null || val2["file"] == null || (int)val2["file"].Type != 8) { throw new InvalidDataException("Playlist entry has no string file name."); } string text2 = (string)val2["file"]; if (!IsLocalAudioFileName(text2)) { throw new InvalidDataException("Playlist entries must be local MP3, OGG or WAV file names."); } string text3 = ((val2["title"] != null && (int)val2["title"].Type == 8) ? ((string)val2["title"]) : null); list.Add(new Track { file = text2, title = (string.IsNullOrWhiteSpace(text3) ? Path.GetFileNameWithoutExtension(text2) : text3) }); } return list.ToArray(); } catch (Exception ex) { warn("Cannot read playlist '" + text + "': " + ex.Message + " Using local file order."); } } List<Track> list2 = new List<Track>(); if (Directory.Exists(folder)) { string[] files = Directory.GetFiles(folder); Array.Sort(files, (IComparer<string>?)StringComparer.OrdinalIgnoreCase); string[] array = files; foreach (string path in array) { string fileName = Path.GetFileName(path); if (IsLocalAudioFileName(fileName)) { list2.Add(new Track { file = fileName, title = Path.GetFileNameWithoutExtension(fileName) }); } } } return list2.ToArray(); } internal static bool IsLocalAudioFileName(string file) { if (string.IsNullOrWhiteSpace(file) || file != Path.GetFileName(file) || Path.IsPathRooted(file) || file.IndexOfAny(new char[3] { '/', '\\', ':' }) >= 0) { return false; } string extension = Path.GetExtension(file); if (!string.Equals(extension, ".mp3", StringComparison.OrdinalIgnoreCase) && !string.Equals(extension, ".ogg", StringComparison.OrdinalIgnoreCase)) { return string.Equals(extension, ".wav", StringComparison.OrdinalIgnoreCase); } return true; } } public class VehicleTrunk : MonoBehaviour { [HarmonyPatch(typeof(Container), "Save")] private static class Changed { private static void Postfix(Container __instance) { VehicleTrunk componentInParent = ((Component)__instance).GetComponentInParent<VehicleTrunk>(); if (Object.op_Implicit((Object)(object)componentInParent)) { componentInParent.Persist(); } } } [HarmonyPatch(typeof(Container), "Load")] private static class PersonalInventory { private static bool Prefix(Container __instance, ref bool __result) { VehicleTrunk componentInParent = ((Component)__instance).GetComponentInParent<VehicleTrunk>(); if (!Object.op_Implicit((Object)(object)componentInParent) || (!componentInParent.Ready && !componentInParent.LoadFailed)) { return true; } __result = false; return false; } } [HarmonyPatch(typeof(Container), "CheckAccess")] private static class Access { private static bool Prefix(Container __instance, long playerID, ref bool __result) { VehicleTrunk componentInParent = ((Component)__instance).GetComponentInParent<VehicleTrunk>(); if (!Object.op_Implicit((Object)(object)componentInParent)) { return true; } __result = Object.op_Implicit((Object)(object)componentInParent.view) && componentInParent.view.IsValid() && !componentInParent.LoadFailed && componentInParent.view.GetZDO().GetLong("Dropoff.VehicleMod.Creator", 0L) == playerID; if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && playerID == Player.m_localPlayer.GetPlayerID()) { __result &= componentInParent.Ready; } return false; } } [HarmonyPatch(typeof(Container), "OnDestroyed")] private static class KeepContents { private static bool Prefix(Container __instance) { VehicleTrunk componentInParent = ((Component)__instance).GetComponentInParent<VehicleTrunk>(); if (!Object.op_Implicit((Object)(object)componentInParent)) { return true; } componentInParent.CloseAndPersist(); return false; } } [HarmonyPatch(typeof(Player), "Save")] private static class SaveWithCharacter { private static void Prefix(Player __instance) { foreach (VehicleTrunk item in live) { if (Object.op_Implicit((Object)(object)item) && (Object)(object)item.character == (Object)(object)__instance) { item.Persist(); } } } } public const string StorageKey = "Dropoff.VehicleMod.Trunk.v1"; private static readonly List<VehicleTrunk> live = new List<VehicleTrunk>(); private static readonly MethodInfo saveContainer = AccessTools.Method(typeof(Container), "Save", (Type[])null, (Type[])null); private static readonly MethodInfo closeContainer = AccessTools.Method(typeof(InventoryGui), "CloseContainer", (Type[])null, (Type[])null); private static readonly FieldInfo currentContainer = AccessTools.Field(typeof(InventoryGui), "m_currentContainer"); private ZNetView view; private Player character; private bool restoring; public Container Container { get; private set; } public bool Ready { get; private set; } public bool LoadFailed { get; private set; } private void Start() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_0098: 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_00a7: 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) view = ((Component)this).GetComponent<ZNetView>(); if (Object.op_Implicit((Object)(object)view) && view.IsValid()) { live.Add(this); GameObject val = new GameObject("VehicleTrunk"); val.SetActive(false); val.transform.SetParent(((Component)this).transform, false); Bounds partBounds = VehicleCollisionGeometry.GetPartBounds(((Component)this).transform, "boot_ok"); val.transform.localPosition = ((Bounds)(ref partBounds)).center; val.layer = LayerMask.NameToLayer("piece"); BoxCollider val2 = val.AddComponent<BoxCollider>(); val2.size = ((Bounds)(ref partBounds)).size + Vector3.one * 0.04f; ((Collider)val2).isTrigger = true; Container = val.AddComponent<Container>(); Container.m_rootObjectOverride = view; Container.m_name = "Багажник"; Container.m_width = 8; Container.m_height = 4; Container.m_privacy = (PrivacySetting)0; Container.m_checkGuardStone = false; Container.m_autoDestroyEmpty = false; val.SetActive(true); TryInitialize(); } } private void Update() { if (!Ready && !LoadFailed && Object.op_Implicit((Object)(object)Container)) { TryInitialize(); } } private void TryInitialize() { //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Expected O, but got Unknown //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Expected O, but got Unknown //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Expected O, but got Unknown Player player = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)view) || !view.IsValid() || !Object.op_Implicit((Object)(object)player) || !Object.op_Implicit((Object)(object)Container) || Container.GetInventory() == null || view.GetZDO().GetLong("Dropoff.VehicleMod.Creator", 0L) != player.GetPlayerID() || live.Any((VehicleTrunk t) => Object.op_Implicit((Object)(object)t) && (Object)(object)t != (Object)(object)this && t.Ready && (Object)(object)t.character == (Object)(object)player)) { return; } character = player; view.ClaimOwnership(); restoring = true; try { if (player.m_customData.TryGetValue("Dropoff.VehicleMod.Trunk.v1", out var value)) { string[] array = value.Split(new char[1] { '|' }, 3); if (array.Length != 3 || array[0] != "1" || !int.TryParse(array[1], out var result) || result < 0 || result > 32) { throw new InvalidOperationException("Unsupported trunk save format."); } byte[] array2 = Convert.FromBase64String(array[2]); Inventory val = new Inventory("Vehicle trunk validation", (Sprite)null, 8, 4); val.Load(new ZPackage(array2)); if (val.NrOfItems() != result) { throw new InvalidOperationException("Some saved items are unavailable; original trunk data retained."); } Container.GetInventory().Load(new ZPackage(array2)); } else { Container.GetInventory().RemoveAll(); } Ready = true; saveContainer.Invoke(Container, null); } catch (Exception ex) { LoadFailed = true; BepInExPlugin.LogError("Trunk could not be restored; saved contents were preserved: " + ex); ((Character)player).Message((MessageType)2, "Багажник не загружен. Исходные вещи сохранены; проверьте LogOutput.log.", 0, (Sprite)null, false); } finally { restoring = false; } if (Ready) { Persist(); } } public void Persist() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown if (Ready && !restoring && !LoadFailed && Object.op_Implicit((Object)(object)character) && Object.op_Implicit((Object)(object)Container) && Container.GetInventory() != null) { ZPackage val = new ZPackage(); Inventory inventory = Container.GetInventory(); inventory.Save(val); character.m_customData["Dropoff.VehicleMod.Trunk.v1"] = "1|" + inventory.NrOfItems() + "|" + Convert.ToBase64String(val.GetArray()); } } public void CloseAndPersist() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown if (Object.op_Implicit((Object)(object)Container) && Object.op_Implicit((Object)(object)InventoryGui.instance) && (Object)(Container)currentContainer.GetValue(InventoryGui.instance) == (Object)(object)Container) { closeContainer.Invoke(InventoryGui.instance, null); } Persist(); } private void OnDestroy() { CloseAndPersist(); live.Remove(this); } } public sealed class VehicleWaterDrive { private readonly Vector3[] pontoons = (Vector3[])(object)new Vector3[4] { new Vector3(-0.85f, -1.2f, 2.6f), new Vector3(0.85f, -1.2f, 2.6f), new Vector3(-0.85f, -1.2f, -2.6f), new Vector3(0.85f, -1.2f, -2.6f) }; public bool InWater { get; private set; } public float Immersion { get; private set; } public void Step(Rigidbody body, bool driving, float throttle, float steer, bool brake) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0117: 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_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_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_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: 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_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_0209: 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_0216: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0272: 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_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Unknown result type (might be due to invalid IL or missing references) Immersion = 0f; Vector3[] array = pontoons; foreach (Vector3 val in array) { Vector3 val2 = ((Component)body).transform.TransformPoint(val); float liquidLevel = Floating.GetLiquidLevel(val2, 1f, (LiquidType)0); if (!(liquidLevel < -9999f) && !(liquidLevel <= val2.y)) { float num = liquidLevel - val2.y; Immersion += Mathf.Clamp01(num / 0.3f) * 0.25f; float num2 = Mathf.Clamp(num * 30f - body.GetPointVelocity(val2).y * 3f, 0f, 35f); body.AddForceAtPosition(Vector3.up * (body.mass * num2 * 0.25f), val2, (ForceMode)0); } } InWater = Immersion > 0.05f; if (InWater) { body.WakeUp(); Vector3 val3 = Vector3.ProjectOnPlane(((Component)body).transform.forward, Vector3.up); Vector3 normalized = ((Vector3)(ref val3)).normalized; Vector3 val4 = Vector3.Cross(Vector3.up, normalized); float num3 = Vector3.Dot(body.linearVelocity, normalized); float num4 = Vector3.Dot(body.linearVelocity, val4); bool flag = driving && Vector3.Dot(((Component)body).transform.up, Vector3.up) > 0.3f; float num5 = ((flag && !brake) ? (throttle * 3.2f) : 0f); float num6 = ((brake && flag) ? 2.5f : 0.4f); Vector3 val5 = normalized * (num5 - num3 * num6) - val4 * (num4 * 2f); body.AddForce(val5 * Immersion, (ForceMode)5); float num7 = ((flag && !brake) ? (steer * 0.65f * ((throttle < -0.1f) ? (-1f) : 1f)) : 0f); Vector3 angularVelocity = body.angularVelocity; Quaternion val6 = Quaternion.FromToRotation(((Component)body).transform.up, Vector3.up); float num8 = default(float); Vector3 val7 = default(Vector3); ((Quaternion)(ref val6)).ToAngleAxis(ref num8, ref val7); if (num8 > 180f) { num8 -= 360f; } Vector3 val8 = ((Mathf.Abs(num8) < 0.01f) ? Vector3.zero : (((Vector3)(ref val7)).normalized * Mathf.Clamp(num8 * ((float)Math.PI / 180f) * 60f, -60f, 60f))); Vector3 val9 = default(Vector3); ((Vector3)(ref val9))..ctor((0f - angularVelocity.x) * 12f, (num7 - angularVelocity.y) * 3f, (0f - angularVelocity.z) * 12f); body.AddTorque((val8 + val9) * Immersion, (ForceMode)5); } } }