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<bool> Enabled;
internal static ConfigEntry<bool> SnapToHull;
internal static ConfigEntry<float> PushOut;
internal static ConfigEntry<float> ScaleMultiplier;
internal static ConfigEntry<float> OffsetX;
internal static ConfigEntry<float> OffsetY;
internal static ConfigEntry<float> OffsetZ;
private void Awake()
{
Instance = this;
Log = ((BaseUnityPlugin)this).Logger;
Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Stickers", "Enabled", true, "Show the bumper stickers.");
SnapToHull = ((BaseUnityPlugin)this).Config.Bind<bool>("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<float>("Placement", "PushOut", 0.15f, "Extra distance (m) to lift each sticker off the hull surface, along its own facing.");
ScaleMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Placement", "ScaleMultiplier", 1f, "Multiplies the sizes authored in the Unity editor (1.0 = exactly as authored).");
OffsetX = ((BaseUnityPlugin)this).Config.Bind<float>("Placement", "OffsetX", 0f, "Nudge all stickers, ship-local X (m).");
OffsetY = ((BaseUnityPlugin)this).Config.Bind<float>("Placement", "OffsetY", 0f, "Nudge all stickers, ship-local Y (m).");
OffsetZ = ((BaseUnityPlugin)this).Config.Bind<float>("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<ShipKind, Placement[]> ByShip = new Dictionary<ShipKind, Placement[]>
{
[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<GameObject> Stickers = new List<GameObject>();
private static readonly Dictionary<string, Texture2D> TexCache = new Dictionary<string, Texture2D>();
private static PlayerControlledShip _lastShip;
private static readonly List<Vector3> HullVerts = new List<Vector3>();
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<PlayerControlledShip>();
}
}
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<Collider>());
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<MeshRenderer>();
((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<MeshRenderer>();
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<MeshFilter>();
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<string> list = new List<string>();
MeshRenderer[] componentsInChildren = ((Component)root).GetComponentsInChildren<MeshRenderer>();
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<MeshRenderer>();
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<MeshRenderer>();
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 <x> <y> <z>, scale <s>, 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 <x> <y> <z> (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 <multiplier> (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 <metres> (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 <m> | pos <x> <y> <z> | scale <s> | info | dump", true);
break;
}
}
private static bool TryF(string s, out float f)
{
return float.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out f);
}
}
}