using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using CG; using CG.Game; using CG.Space; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Rendering; using VoidManager; using VoidManager.Chat.Router; using VoidManager.MPModChecks; using VoidManager.Utilities; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("BumperStickers")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0+0256cffb3034001545d82efd1fc25564eb71288f")] [assembly: AssemblyProduct("BumperStickers")] [assembly: AssemblyTitle("Joke bumper stickers on the ship's stern")] [assembly: AssemblyVersion("0.1.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace BumperStickers { [BepInPlugin("fredthesled.VoidCrew.BumperStickers", "Bumper Stickers", "1.3.2")] [BepInProcess("Void Crew.exe")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class BepinPlugin : BaseUnityPlugin { internal static BepinPlugin Instance; internal static ManualLogSource Log; internal static ConfigEntry Enabled; internal static ConfigEntry SnapToHull; internal static ConfigEntry PushOut; internal static ConfigEntry ScaleMultiplier; internal static ConfigEntry OffsetX; internal static ConfigEntry OffsetY; internal static ConfigEntry OffsetZ; private void Awake() { Instance = this; Log = ((BaseUnityPlugin)this).Logger; Enabled = ((BaseUnityPlugin)this).Config.Bind("Stickers", "Enabled", true, "Show the bumper stickers."); SnapToHull = ((BaseUnityPlugin)this).Config.Bind("Placement", "SnapToHull", true, "Keep the editor-authored X/Y/rotation but find the real hull surface depth in-game. Turn off to use the authored Z exactly."); PushOut = ((BaseUnityPlugin)this).Config.Bind("Placement", "PushOut", 0.15f, "Extra distance (m) to lift each sticker off the hull surface, along its own facing."); ScaleMultiplier = ((BaseUnityPlugin)this).Config.Bind("Placement", "ScaleMultiplier", 1f, "Multiplies the sizes authored in the Unity editor (1.0 = exactly as authored)."); OffsetX = ((BaseUnityPlugin)this).Config.Bind("Placement", "OffsetX", 0f, "Nudge all stickers, ship-local X (m)."); OffsetY = ((BaseUnityPlugin)this).Config.Bind("Placement", "OffsetY", 0f, "Nudge all stickers, ship-local Y (m)."); OffsetZ = ((BaseUnityPlugin)this).Config.Bind("Placement", "OffsetZ", 0f, "Nudge all stickers, ship-local Z (m). Negative = further behind."); Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "fredthesled.VoidCrew.BumperStickers"); try { ModdingUtils.RegisterLocalMod(); Log.LogInfo((object)"Registered as a local (cosmetic, client-side) mod."); } catch (Exception ex) { Log.LogWarning((object)("Could not register as a local mod: " + ex.Message)); } Log.LogInfo((object)"Bumper Stickers 1.3.2 loaded."); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "fredthesled.VoidCrew.BumperStickers"; public const string PLUGIN_NAME = "BumperStickers"; public const string USERS_PLUGIN_NAME = "Bumper Stickers"; public const string PLUGIN_VERSION = "1.3.2"; public const string PLUGIN_DESCRIPTION = "Slaps joke bumper stickers on the stern of your ship. Client-side; /stickers to adjust."; public const string PLUGIN_AUTHORS = "fredthesled"; } internal enum ShipKind { Unknown, Frigate, Striker, Destroyer } internal struct Placement { public readonly string Resource; public readonly Vector3 LocalPosition; public readonly Quaternion LocalRotation; public readonly Vector3 LocalScale; public Placement(string resource, Vector3 pos, Quaternion rot, Vector3 scale) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: 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_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) Resource = resource; LocalPosition = pos; LocalRotation = rot; LocalScale = scale; } } internal static class Placements { internal static readonly Dictionary ByShip = new Dictionary { [ShipKind.Frigate] = new Placement[4] { new Placement("honk", new Vector3(-1.6903f, 4.5724f, -20.73f), new Quaternion(0f, 0f, -0.034899496f, 0.99939084f), new Vector3(3.13536f, 0.78384f, 1f)), new Placement("honors", new Vector3(2.2289f, 4.5724f, -20.73f), new Quaternion(0f, 0f, 0.026176948f, 0.9996573f), new Vector3(3.13536f, 0.78384f, 1f)), new Placement("pride", new Vector3(-1.6903f, 3.475f, -20.73f), new Quaternion(0f, 0f, 0.021814885f, 0.99976206f), new Vector3(3.13536f, 0.78384f, 1f)), new Placement("rescued", new Vector3(2.2289f, 3.475f, -20.73f), new Quaternion(0f, 0f, -0.026176948f, 0.9996573f), new Vector3(3.13536f, 0.78384f, 1f)) }, [ShipKind.Striker] = new Placement[4] { new Placement("honk", new Vector3(-1.54f, 4.22f, -22.17f), new Quaternion(0f, 0f, -0.034899496f, 0.99939084f), new Vector3(2.42948f, 0.60737f, 1f)), new Placement("honors", new Vector3(1.44f, 4.17f, -22.1f), new Quaternion(0f, 0f, 0.026176948f, 0.9996573f), new Vector3(2.1492748f, 0.5373187f, 1f)), new Placement("pride", new Vector3(-4.09f, 4.414f, -20.497f), new Quaternion(0.16727015f, 0.5717232f, -0.1114021f, 0.7954514f), new Vector3(2.7063954f, 0.67659885f, 1f)), new Placement("rescued", new Vector3(4.493f, 4.393f, -19.612f), new Quaternion(0.1981368f, -0.56696314f, 0.11385787f, 0.79141074f), new Vector3(4f, 1f, 1f)) }, [ShipKind.Destroyer] = new Placement[4] { new Placement("honk", new Vector3(-2.03f, 3.55f, -39.62f), new Quaternion(0f, 0f, -0.034899496f, 0.99939084f), new Vector3(2.83116f, 0.70779f, 1f)), new Placement("honors", new Vector3(1.5089f, 3.55f, -39.62f), new Quaternion(0f, 0f, 0.026176948f, 0.9996573f), new Vector3(2.83116f, 0.70779f, 1f)), new Placement("pride", new Vector3(-2.03f, 2.55906f, -39.62f), new Quaternion(0f, 0f, 0.021814885f, 0.99976206f), new Vector3(2.83116f, 0.70779f, 1f)), new Placement("rescued", new Vector3(1.5089f, 2.55906f, -39.62f), new Quaternion(0f, 0f, -0.026176948f, 0.9996573f), new Vector3(2.83116f, 0.70779f, 1f)) } }; } [HarmonyPatch(typeof(PlayerControlledShip), "Start")] internal static class ShipStartPatch { private static void Postfix(PlayerControlledShip __instance) { ((MonoBehaviour)BepinPlugin.Instance).StartCoroutine(StickerManager.AttachDelayed(__instance)); } } internal static class StickerManager { private static readonly List Stickers = new List(); private static readonly Dictionary TexCache = new Dictionary(); private static PlayerControlledShip _lastShip; private static readonly List HullVerts = new List(); private static readonly Regex PhantomCollider = new Regex("repulsion|shield|barrier|forcefield|force_field", RegexOptions.IgnoreCase); internal static PlayerControlledShip CurrentShip { get { if ((Object)(object)_lastShip != (Object)null) { return _lastShip; } ClientGame current = ClientGame.Current; if (current == null) { return null; } PlayerControlledShip playerShip = current.PlayerShip; if (playerShip == null) { return null; } GameObject gameObject = ((AbstractCloneStarObject)playerShip).GameObject; if (gameObject == null) { return null; } return gameObject.GetComponent(); } } internal static IEnumerator AttachDelayed(PlayerControlledShip ship) { yield return (object)new WaitForSeconds(2f); if ((Object)(object)ship != (Object)null) { Attach(ship); } } internal static void Attach(PlayerControlledShip ship) { //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0343: Unknown result type (might be due to invalid IL or missing references) //IL_0348: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: 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_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) Clear(); if ((Object)(object)ship == (Object)null || !BepinPlugin.Enabled.Value) { return; } _lastShip = ship; Transform transform = ((Component)ship).transform; string how; ShipKind shipKind = IdentifyShip(transform, out how); if (shipKind == ShipKind.Unknown || !Placements.ByShip.TryGetValue(shipKind, out var value)) { BepinPlugin.Log.LogWarning((object)("Unrecognised ship (" + how + "); no stickers placed.")); return; } BepinPlugin.Log.LogInfo((object)$"Ship identified as {shipKind} ({how}); placing {value.Length} stickers."); int num = ExteriorLayer(transform); float value2 = BepinPlugin.ScaleMultiplier.Value; Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(BepinPlugin.OffsetX.Value, BepinPlugin.OffsetY.Value, BepinPlugin.OffsetZ.Value); LogExteriorGeometry(transform); BuildHullVertexCache(transform); Placement[] array = value; for (int i = 0; i < array.Length; i++) { Placement placement = array[i]; Texture2D val2 = LoadTexture("BumperStickers.Assets." + placement.Resource + ".png"); if ((Object)(object)val2 == (Object)null) { continue; } Vector3 val3 = placement.LocalPosition + val; if (BepinPlugin.SnapToHull.Value) { float num2 = HullSurfaceZ(transform, val3.x, val3.y, Mathf.Max(placement.LocalScale.x, placement.LocalScale.y) * 0.5f); if (!float.IsNaN(num2)) { BepinPlugin.Log.LogInfo((object)$" {placement.Resource}: authored z={val3.z:F2} -> hull surface z={num2:F2}"); val3.z = num2; } else { BepinPlugin.Log.LogInfo((object)$" {placement.Resource}: no hull vertices near ({val3.x:F1}, {val3.y:F1}); keeping authored z={val3.z:F2}"); } } val3 += placement.LocalRotation * new Vector3(0f, 0f, 0f - BepinPlugin.PushOut.Value); GameObject val4 = GameObject.CreatePrimitive((PrimitiveType)5); ((Object)val4).name = "BumperSticker_" + placement.Resource; Object.Destroy((Object)(object)val4.GetComponent()); val4.layer = num; val4.transform.SetParent(transform, false); val4.transform.localPosition = val3; val4.transform.localRotation = placement.LocalRotation; val4.transform.localScale = new Vector3(placement.LocalScale.x * value2, placement.LocalScale.y * value2, 1f); MeshRenderer component = val4.GetComponent(); ((Renderer)component).material = MakeMaterial(val2); ((Renderer)component).shadowCastingMode = (ShadowCastingMode)0; Stickers.Add(val4); } ManualLogSource log = BepinPlugin.Log; string text = $"Attached {Stickers.Count} stickers to {shipKind} (layer {num}); "; object obj; if (Stickers.Count <= 0) { obj = "n/a"; } else { Vector3 position = Stickers[0].transform.position; obj = ((Vector3)(ref position)).ToString("F1"); } log.LogInfo((object)(text + "first at world " + (string?)obj + ".")); } private static ShipKind IdentifyShip(Transform root, out string how) { MeshRenderer[] componentsInChildren = ((Component)root).GetComponentsInChildren(); foreach (MeshRenderer val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { string text = ((Object)val).name.ToLowerInvariant(); if (text.Contains("striker")) { how = "name '" + ((Object)val).name + "'"; return ShipKind.Striker; } if (text.Contains("frigate")) { how = "name '" + ((Object)val).name + "'"; return ShipKind.Frigate; } if (text.Contains("destroyer")) { how = "name '" + ((Object)val).name + "'"; return ShipKind.Destroyer; } } } float num = MeasuredWidth(root); how = $"width {num:F1}m"; if (num <= 0f) { return ShipKind.Unknown; } if (num < 50f) { return ShipKind.Frigate; } if (num < 80f) { return ShipKind.Destroyer; } return ShipKind.Striker; } private static void BuildHullVertexCache(Transform root) { //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: 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) HullVerts.Clear(); int num = 0; MeshFilter[] componentsInChildren = ((Component)root).GetComponentsInChildren(); foreach (MeshFilter val in componentsInChildren) { if ((Object)(object)val == (Object)null || (Object)(object)val.sharedMesh == (Object)null || !val.sharedMesh.isReadable) { continue; } string text = ((Object)val).name.ToLowerInvariant(); if ((text.Contains("exterior") || text.Contains("hull")) && !text.Contains("lod1") && !text.Contains("lod2") && !text.Contains("lod3") && !text.Contains("shadow") && !text.Contains("interior")) { num++; Transform transform = ((Component)val).transform; Vector3[] vertices = val.sharedMesh.vertices; foreach (Vector3 val2 in vertices) { HullVerts.Add(root.InverseTransformPoint(transform.TransformPoint(val2))); } } } BepinPlugin.Log.LogInfo((object)$"Hull vertex cache: {HullVerts.Count} verts from {num} exterior mesh(es)."); } private static float HullSurfaceZ(Transform root, float x, float y, float radius) { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: 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_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_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0173: 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_002f: 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_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < 4; i++) { if (HullVerts.Count <= 0) { break; } float num = radius * (float)(1 << i); float num2 = float.MaxValue; foreach (Vector3 hullVert in HullVerts) { if (!(Mathf.Abs(hullVert.x - x) > num) && !(Mathf.Abs(hullVert.y - y) > num) && hullVert.z < num2) { num2 = hullVert.z; } } if (num2 < float.MaxValue) { return num2; } } RaycastHit[] array = Physics.RaycastAll(root.TransformPoint(new Vector3(x, y, -400f)), root.forward, 800f, -1, (QueryTriggerInteraction)1); bool flag = false; RaycastHit val = default(RaycastHit); RaycastHit[] array2 = array; for (int j = 0; j < array2.Length; j++) { RaycastHit val2 = array2[j]; if (!((Object)(object)((RaycastHit)(ref val2)).collider == (Object)null) && ((Component)((RaycastHit)(ref val2)).collider).transform.IsChildOf(root) && !PhantomCollider.IsMatch(((Object)((RaycastHit)(ref val2)).collider).name) && (!flag || ((RaycastHit)(ref val2)).distance < ((RaycastHit)(ref val)).distance)) { val = val2; flag = true; } } if (flag) { BepinPlugin.Log.LogInfo((object)(" (ray hit collider '" + ((Object)((RaycastHit)(ref val)).collider).name + "')")); return root.InverseTransformPoint(((RaycastHit)(ref val)).point).z; } return float.NaN; } private static void LogExteriorGeometry(Transform root) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_0106: 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_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0124: 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_0128: 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_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) List list = new List(); MeshRenderer[] componentsInChildren = ((Component)root).GetComponentsInChildren(); Vector3 val2 = default(Vector3); Vector3 val3 = default(Vector3); foreach (MeshRenderer val in componentsInChildren) { if ((Object)(object)val == (Object)null || !((Renderer)val).enabled || ((Object)val).name.StartsWith("BumperSticker")) { continue; } string text = ((Object)val).name.ToLowerInvariant(); if (text.Contains("exterior") || text.Contains("hull")) { Bounds bounds = ((Renderer)val).bounds; Vector3 center = ((Bounds)(ref bounds)).center; Vector3 extents = ((Bounds)(ref bounds)).extents; ((Vector3)(ref val2))..ctor(float.MaxValue, float.MaxValue, float.MaxValue); ((Vector3)(ref val3))..ctor(float.MinValue, float.MinValue, float.MinValue); for (int j = 0; j < 8; j++) { Vector3 val4 = center + new Vector3((((j & 1) == 0) ? (-1f) : 1f) * extents.x, (((j & 2) == 0) ? (-1f) : 1f) * extents.y, (((j & 4) == 0) ? (-1f) : 1f) * extents.z); Vector3 val5 = root.InverseTransformPoint(val4); val2 = Vector3.Min(val2, val5); val3 = Vector3.Max(val3, val5); } list.Add($" '{((Object)val).name}' local min={val2:F1} max={val3:F1}"); } } BepinPlugin.Log.LogInfo((object)$"Exterior meshes in ship-local space ({list.Count}):"); foreach (string item in list) { BepinPlugin.Log.LogInfo((object)item); } } private static float MeasuredWidth(Transform root) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_0062: 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: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) float num = float.MaxValue; float num2 = float.MinValue; MeshRenderer[] componentsInChildren = ((Component)root).GetComponentsInChildren(); foreach (MeshRenderer val in componentsInChildren) { if ((Object)(object)val == (Object)null || !((Renderer)val).enabled || ((Object)val).name.StartsWith("BumperSticker")) { continue; } Bounds bounds = ((Renderer)val).bounds; Vector3 center = ((Bounds)(ref bounds)).center; Vector3 extents = ((Bounds)(ref bounds)).extents; for (int j = 0; j < 8; j++) { Vector3 val2 = center + new Vector3((((j & 1) == 0) ? (-1f) : 1f) * extents.x, (((j & 2) == 0) ? (-1f) : 1f) * extents.y, (((j & 4) == 0) ? (-1f) : 1f) * extents.z); float x = root.InverseTransformPoint(val2).x; if (x < num) { num = x; } if (x > num2) { num2 = x; } } } if (!(num2 > num)) { return 0f; } return num2 - num; } private static int ExteriorLayer(Transform root) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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_006c: Unknown result type (might be due to invalid IL or missing references) float num = -1f; int layer = ((Component)root).gameObject.layer; MeshRenderer[] componentsInChildren = ((Component)root).GetComponentsInChildren(); foreach (MeshRenderer val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && ((Renderer)val).enabled && !((Object)val).name.StartsWith("BumperSticker")) { Bounds bounds = ((Renderer)val).bounds; float num2 = ((Bounds)(ref bounds)).size.x * ((Bounds)(ref bounds)).size.y * ((Bounds)(ref bounds)).size.z; if (num2 > num) { num = num2; layer = ((Component)val).gameObject.layer; } } } return layer; } internal static void Clear() { foreach (GameObject sticker in Stickers) { if ((Object)(object)sticker != (Object)null) { Object.Destroy((Object)(object)sticker); } } Stickers.Clear(); } internal static bool Reapply(out string status) { PlayerControlledShip currentShip = CurrentShip; if ((Object)(object)currentShip == (Object)null) { status = "No player ship right now - stickers will appear when one spawns."; return false; } Attach(currentShip); status = $"Stickers reapplied ({Stickers.Count})."; return true; } internal static string Describe() { PlayerControlledShip currentShip = CurrentShip; if ((Object)(object)currentShip == (Object)null) { return "No player ship right now."; } string how; ShipKind shipKind = IdentifyShip(((Component)currentShip).transform, out how); return $"ship={shipKind} ({how}) | placed={Stickers.Count} | scale x{BepinPlugin.ScaleMultiplier.Value} " + $"offset=({BepinPlugin.OffsetX.Value}, {BepinPlugin.OffsetY.Value}, {BepinPlugin.OffsetZ.Value}) " + $"enabled={BepinPlugin.Enabled.Value}"; } internal static void DumpHierarchy(Transform t, int depth, int maxDepth) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown BepinPlugin.Log.LogInfo((object)$"{new string(' ', depth * 2)}{((Object)t).name} [{t.childCount} children, layer {((Component)t).gameObject.layer}]"); if (depth >= maxDepth) { return; } foreach (Transform item in t) { DumpHierarchy(item, depth + 1, maxDepth); } } private static Material MakeMaterial(Texture2D tex) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown //IL_0104: Unknown result type (might be due to invalid IL or missing references) Shader val = null; string text = null; string[] array = new string[4] { "HDRP/Unlit", "HDRP/Lit", "Unlit/Texture", "Standard" }; foreach (string text2 in array) { val = Shader.Find(text2); if ((Object)(object)val != (Object)null) { text = text2; break; } } if ((Object)(object)val == (Object)null) { BepinPlugin.Log.LogError((object)"No usable shader found for stickers."); val = Shader.Find("Hidden/InternalErrorShader"); } Material val2 = new Material(val); array = new string[3] { "_UnlitColorMap", "_BaseColorMap", "_MainTex" }; foreach (string text3 in array) { if (val2.HasProperty(text3)) { val2.SetTexture(text3, (Texture)(object)tex); } } array = new string[3] { "_UnlitColor", "_BaseColor", "_Color" }; foreach (string text4 in array) { if (val2.HasProperty(text4)) { val2.SetColor(text4, Color.white); } } BepinPlugin.Log.LogInfo((object)("Sticker material uses shader '" + text + "'.")); return val2; } private static Texture2D LoadTexture(string resourceName) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown if (TexCache.TryGetValue(resourceName, out var value) && (Object)(object)value != (Object)null) { return value; } using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName); if (stream == null) { BepinPlugin.Log.LogError((object)("Embedded resource '" + resourceName + "' not found. Available: " + string.Join(", ", Assembly.GetExecutingAssembly().GetManifestResourceNames()))); return null; } byte[] array = new byte[stream.Length]; stream.Read(array, 0, array.Length); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true); if (!ImageConversion.LoadImage(val, array)) { BepinPlugin.Log.LogError((object)("Failed to decode '" + resourceName + "'.")); return null; } ((Texture)val).wrapMode = (TextureWrapMode)1; TexCache[resourceName] = val; return val; } } public class VoidManagerPlugin : VoidPlugin { public override MultiplayerType MPType => (MultiplayerType)8; public override string Author => "fredthesled"; public override string Description => "Slaps joke bumper stickers on the stern of your ship. Client-side; /stickers to adjust."; } } namespace BumperStickers.Commands { public class StickersCommand : ChatCommand { public override string[] CommandAliases() { return new string[2] { "stickers", "sticker" }; } public override string Description() { return "Toggle/tune the bumper stickers. Subcommands: on, off, respawn, pos , scale , info, dump."; } public override string[] UsageExamples() { return new string[4] { "/stickers", "/stickers pos 0 -0.5 0", "/stickers scale 1.2", "/stickers info" }; } public override void Execute(string arguments) { string[] array = (arguments ?? "").Trim().Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries); string status; switch ((array.Length == 0) ? "toggle" : array[0].ToLowerInvariant()) { case "on": BepinPlugin.Enabled.Value = true; StickerManager.Reapply(out status); Messaging.Echo("Stickers ON. " + status, true); break; case "off": BepinPlugin.Enabled.Value = false; StickerManager.Clear(); Messaging.Echo("Stickers OFF.", true); break; case "toggle": if (!BepinPlugin.Enabled.Value) { goto case "on"; } goto case "off"; case "reload": case "respawn": StickerManager.Reapply(out status); Messaging.Echo(status, true); break; case "pos": { if (array.Length == 4 && TryF(array[1], out var f) && TryF(array[2], out var f2) && TryF(array[3], out var f3)) { BepinPlugin.OffsetX.Value = f; BepinPlugin.OffsetY.Value = f2; BepinPlugin.OffsetZ.Value = f3; StickerManager.Reapply(out status); Messaging.Echo($"Offset set to ({f}, {f2}, {f3}). {status}", true); } else { Messaging.Echo("Usage: /stickers pos (ship-local metres; -z = further back)", true); } break; } case "scale": { if (array.Length == 2 && TryF(array[1], out var f5) && f5 > 0f) { BepinPlugin.ScaleMultiplier.Value = f5; StickerManager.Reapply(out status); Messaging.Echo($"Scale multiplier set to {f5}. {status}", true); } else { Messaging.Echo("Usage: /stickers scale (1 = exactly as authored)", true); } break; } case "snap": BepinPlugin.SnapToHull.Value = !BepinPlugin.SnapToHull.Value; StickerManager.Reapply(out status); Messaging.Echo("Snap-to-hull " + (BepinPlugin.SnapToHull.Value ? "ON (find real hull depth)" : "OFF (use authored depth)") + ". " + status, true); break; case "out": { if (array.Length == 2 && TryF(array[1], out var f4)) { BepinPlugin.PushOut.Value = f4; StickerManager.Reapply(out status); Messaging.Echo($"Lift off hull set to {f4}m. {status}", true); } else { Messaging.Echo("Usage: /stickers out (how far to lift stickers off the hull)", true); } break; } case "info": Messaging.Echo(StickerManager.Describe(), true); break; case "dump": { PlayerControlledShip currentShip = StickerManager.CurrentShip; if ((Object)(object)currentShip == (Object)null) { Messaging.Echo("No player ship right now.", true); break; } StickerManager.DumpHierarchy(((Component)currentShip).transform, 0, 3); Messaging.Echo("Ship hierarchy dumped to BepInEx\\LogOutput.log (depth 3).", true); break; } default: Messaging.Echo("Subcommands: on | off | respawn | snap | out | pos | scale | info | dump", true); break; } } private static bool TryF(string s, out float f) { return float.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out f); } } }