using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using PluginConfig.API;
using PluginConfig.API.Decorators;
using PluginConfig.API.Fields;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("TokenSkulls")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("TokenSkulls")]
[assembly: AssemblyTitle("TokenSkulls")]
[assembly: AssemblyVersion("1.0.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 TokenSkulls
{
internal sealed class ConfigUI
{
private const float PosRange = 5f;
private const float RotRange = 180f;
private const float ScaleMin = 0.05f;
private const float ScaleMax = 10f;
private const string IconFile = "icon.png";
private PluginConfigurator config;
private BoolField enabledField;
public Action<bool> OnEnabledChanged;
public Action OnPlacementChanged;
public bool IsEnabled => enabledField == null || enabledField.value;
public void Setup()
{
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Expected O, but got Unknown
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: Expected O, but got Unknown
//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
//IL_00b6: Expected O, but got Unknown
//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
//IL_00cd: Expected O, but got Unknown
//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
//IL_00f5: Expected O, but got Unknown
config = PluginConfigurator.Create("Token Skulls", "com.scout.tokenskulls");
Sprite val = LoadIcon("icon.png");
if ((Object)(object)val != (Object)null)
{
config.image = val;
}
enabledField = new BoolField(config.rootPanel, "Enabled", "enabled", true);
ConfigDivision settings = new ConfigDivision(config.rootPanel, "settings");
((ConfigField)settings).hidden = !enabledField.value;
enabledField.onValueChange += (BoolValueChangeEventDelegate)delegate(BoolValueChangeEvent e)
{
((ConfigField)settings).hidden = !e.value;
OnEnabledChanged?.Invoke(e.value);
};
ConfigPanel panel = new ConfigPanel((ConfigPanel)(object)settings, "World Skull Placement", "world_settings");
BuildPlacement(panel, "world", TokenSkullsPlugin.World);
ConfigPanel panel2 = new ConfigPanel((ConfigPanel)(object)settings, "Held Skull Placement", "held_settings");
BuildPlacement(panel2, "held", TokenSkullsPlugin.Held);
}
private Sprite LoadIcon(string fileName)
{
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Expected O, but got Unknown
//IL_006a: 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)
string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), fileName);
if (!File.Exists(path))
{
TokenSkullsPlugin.Log.LogWarning((object)"No icon which how???");
return null;
}
byte[] array = File.ReadAllBytes(path);
Texture2D val = new Texture2D(2, 2);
ImageConversion.LoadImage(val, array);
return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
}
private void BuildPlacement(ConfigPanel panel, string prefix, TokenSkullsPlugin.Placement p)
{
//IL_0016: 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_018e: Unknown result type (might be due to invalid IL or missing references)
new ConfigHeader(panel, "Position Offset", 20);
Slider(panel, "Position X", prefix + "_pos_x", p.posX, -5f, 5f, 2, delegate(float v)
{
p.posX = v;
});
Slider(panel, "Position Y", prefix + "_pos_y", p.posY, -5f, 5f, 2, delegate(float v)
{
p.posY = v;
});
Slider(panel, "Position Z", prefix + "_pos_z", p.posZ, -5f, 5f, 2, delegate(float v)
{
p.posZ = v;
});
new ConfigHeader(panel, "Rotation Offset", 20);
Slider(panel, "Rotation X", prefix + "_rot_x", p.rotX, -180f, 180f, 1, delegate(float v)
{
p.rotX = v;
});
Slider(panel, "Rotation Y", prefix + "_rot_y", p.rotY, -180f, 180f, 1, delegate(float v)
{
p.rotY = v;
});
Slider(panel, "Rotation Z", prefix + "_rot_z", p.rotZ, -180f, 180f, 1, delegate(float v)
{
p.rotZ = v;
});
new ConfigHeader(panel, "Size Multiplier", 20);
Slider(panel, "Scale", prefix + "_scale", p.scale, 0.05f, 10f, 2, delegate(float v)
{
p.scale = v;
});
}
private void Slider(ConfigPanel panel, string label, string guid, float def, float min, float max, int decimals, Action<float> apply)
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Expected O, but got Unknown
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Expected O, but got Unknown
FloatSliderField val = new FloatSliderField(panel, label, guid, new Tuple<float, float>(min, max), def, decimals);
val.onValueChange += (OnValueChangeEventDelegate)delegate(FloatSliderValueChangeEvent e)
{
apply(e.newValue);
OnPlacementChanged?.Invoke();
};
apply(val.value);
}
}
[BepInPlugin("com.scout.tokenskulls", "Token Skulls", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public sealed class TokenSkullsPlugin : BaseUnityPlugin
{
private class Variant
{
public GameObject prefab;
public Vector3 pos;
public Quaternion rot;
public Vector3 scale;
}
public class Placement
{
public float posX;
public float posY;
public float posZ;
public float rotX;
public float rotY;
public float rotZ;
public float scale = 1f;
public Vector3 PosOffset => new Vector3(posX, posY, posZ);
public Vector3 RotOffset => new Vector3(rotX, rotY, rotZ);
}
private class SkullTag : MonoBehaviour
{
public Transform clone;
public Renderer hidden;
public Variant variant;
public bool wasHeld;
}
public const string GUID = "com.scout.tokenskulls";
public const string NAME = "Token Skulls";
public const string VERSION = "1.0.0";
private const string BundleFile = "tokenskulls.bundle";
private const string PrefabRed = "TokenSkullRed";
private const string PrefabBlue = "TokenSkullBlue";
private const string PrefabSingle = "TokenSkull";
public static readonly Placement World = new Placement();
public static readonly Placement Held = new Placement();
private static Variant redVariant;
private static Variant blueVariant;
private static bool modelReady;
private static bool placementDirty;
private static bool warnedNoAnchor;
private static readonly List<SkullTag> live = new List<SkullTag>();
private static ConfigUI ui;
internal static ManualLogSource Log;
private Harmony harmony;
private static bool IsEnabled => ui != null && ui.IsEnabled;
private void Awake()
{
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_00a7: Expected O, but got Unknown
Log = ((BaseUnityPlugin)this).Logger;
ui = new ConfigUI();
ui.Setup();
ui.OnEnabledChanged = OnEnabledToggled;
ui.OnPlacementChanged = delegate
{
placementDirty = true;
};
LoadModel();
if (!modelReady)
{
Log.LogError((object)"Model never loaded");
return;
}
try
{
harmony = new Harmony("com.scout.tokenskulls");
harmony.PatchAll();
Log.LogInfo((object)"Patched Skull.Awake");
}
catch (Exception arg)
{
Log.LogError((object)$"Harmony patch failed: {arg}");
}
}
private Variant TryLoad(AssetBundle bundle, string name)
{
//IL_0056: 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_0067: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
GameObject val = bundle.LoadAsset<GameObject>(name);
if ((Object)(object)val == (Object)null)
{
return null;
}
if (val.GetComponentsInChildren<Renderer>(true).Length == 0)
{
Log.LogWarning((object)(name + " has no renderers anywhere"));
return null;
}
return new Variant
{
prefab = val,
pos = val.transform.localPosition,
rot = val.transform.localRotation,
scale = val.transform.localScale
};
}
private void LoadModel()
{
string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string text = Path.Combine(directoryName, "tokenskulls.bundle");
if (!File.Exists(text))
{
Log.LogError((object)("Bundle missing in " + text));
return;
}
AssetBundle val = AssetBundle.LoadFromFile(text);
if ((Object)(object)val == (Object)null)
{
Log.LogError((object)"Bundle failed to load");
return;
}
redVariant = TryLoad(val, "TokenSkullRed");
blueVariant = TryLoad(val, "TokenSkullBlue");
Variant variant = TryLoad(val, "TokenSkull");
if (redVariant == null)
{
redVariant = variant ?? blueVariant;
}
if (blueVariant == null)
{
blueVariant = variant ?? redVariant;
}
if (redVariant == null || blueVariant == null)
{
Log.LogError((object)("No prefabs, need TokenSkullRed and TokenSkullBlue. Bundle only has: " + string.Join(", ", val.GetAllAssetNames())));
return;
}
if ((Object)(object)redVariant.prefab == (Object)(object)blueVariant.prefab)
{
Log.LogWarning((object)"Only one prefab found, add TokenSkullRed and TokenSkullBlue");
}
modelReady = true;
Log.LogInfo((object)("Loaded " + ((Object)redVariant.prefab).name + " and " + ((Object)blueVariant.prefab).name));
}
internal static void OnSkullAwake(Skull skull)
{
if (modelReady && IsEnabled && Object.op_Implicit((Object)(object)skull))
{
Dress(skull);
}
}
private static void Dress(Skull skull)
{
Transform val = ((IEnumerable<Transform>)((Component)skull).GetComponentsInChildren<Transform>(true)).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "NewSkull"));
if (!Object.op_Implicit((Object)(object)val))
{
if (!warnedNoAnchor)
{
warnedNoAnchor = true;
Log.LogWarning((object)(((Object)skull).name + " has no NewSkull child"));
}
}
else if (!Object.op_Implicit((Object)(object)((Component)val).GetComponent<SkullTag>()))
{
Variant variant = (((Object)skull).name.ToLower().Contains("red") ? redVariant : blueVariant);
SkullTag skullTag = ((Component)val).gameObject.AddComponent<SkullTag>();
skullTag.variant = variant;
skullTag.hidden = ((Component)val).GetComponent<Renderer>();
if (Object.op_Implicit((Object)(object)skullTag.hidden))
{
skullTag.hidden.enabled = false;
}
GameObject val2 = Object.Instantiate<GameObject>(variant.prefab, val, false);
((Object)val2).name = "TokenSkullModel";
skullTag.clone = val2.transform;
live.Add(skullTag);
Place(skullTag, force: true);
}
}
private static void Place(SkullTag tag, bool force)
{
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: 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_009b: Unknown result type (might be due to invalid IL or missing references)
bool flag = ((Object)((Component)tag).transform.root).name == "Player";
if (force || flag != tag.wasHeld)
{
tag.wasHeld = flag;
Placement placement = (flag ? Held : World);
Variant variant = tag.variant;
Transform clone = tag.clone;
clone.localPosition = variant.pos + placement.PosOffset;
clone.localRotation = variant.rot * Quaternion.Euler(placement.RotOffset);
clone.localScale = variant.scale * placement.scale;
}
}
private void Update()
{
if (live.Count == 0)
{
placementDirty = false;
return;
}
bool force = placementDirty;
for (int num = live.Count - 1; num >= 0; num--)
{
SkullTag skullTag = live[num];
if (!Object.op_Implicit((Object)(object)skullTag) || !Object.op_Implicit((Object)(object)skullTag.clone))
{
live.RemoveAt(num);
}
else
{
if (Object.op_Implicit((Object)(object)skullTag.hidden) && skullTag.hidden.enabled)
{
skullTag.hidden.enabled = false;
}
Place(skullTag, force);
}
}
placementDirty = false;
}
private static void OnEnabledToggled(bool on)
{
if (!modelReady)
{
return;
}
if (on)
{
Skull[] array = Object.FindObjectsOfType<Skull>();
foreach (Skull val in array)
{
if (Object.op_Implicit((Object)(object)val))
{
Dress(val);
}
}
}
else
{
RestoreAll();
}
}
private static void RestoreAll()
{
foreach (SkullTag item in live)
{
if (Object.op_Implicit((Object)(object)item))
{
if (Object.op_Implicit((Object)(object)item.clone))
{
Object.Destroy((Object)(object)((Component)item.clone).gameObject);
}
if (Object.op_Implicit((Object)(object)item.hidden))
{
item.hidden.enabled = true;
}
Object.Destroy((Object)(object)item);
}
}
live.Clear();
}
}
[HarmonyPatch(typeof(Skull), "Awake")]
internal static class SkullAwakePatch
{
private static void Postfix(Skull __instance)
{
TokenSkullsPlugin.OnSkullAwake(__instance);
}
}
}