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 AllyOutline v1.0.0
AllyOutline.dll
Decompiled 11 hours agousing System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using Microsoft.CodeAnalysis; using RiskOfOptions; using RiskOfOptions.Options; using RoR2; using UnityEngine; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("AllyOutline")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Outlines teammates through walls")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("AllyOutline")] [assembly: AssemblyTitle("AllyOutline")] [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 AllyOutline { internal static class AllyOutliner { private static Object _requester; private static bool _hooked; private static bool _requesting; private static readonly List<CharacterBody> Targets = new List<CharacterBody>(); private static readonly ReadOnlyCollection<TeamComponent> EmptyTeam = new ReadOnlyCollection<TeamComponent>(Array.Empty<TeamComponent>()); internal static void Init(Object requester) { _requester = requester; try { OutlineHighlight.onPreRenderOutlineHighlight = (Action<OutlineHighlight>)Delegate.Combine(OutlineHighlight.onPreRenderOutlineHighlight, new Action<OutlineHighlight>(OnPreRenderOutlineHighlight)); _hooked = true; } catch (Exception ex) { Plugin.Log.LogError((object)("OutlineHighlight のフックに失敗しました。縁取りは無効になります: " + ex)); } } internal static void Shutdown() { if (_hooked) { OutlineHighlight.onPreRenderOutlineHighlight = (Action<OutlineHighlight>)Delegate.Remove(OutlineHighlight.onPreRenderOutlineHighlight, new Action<OutlineHighlight>(OnPreRenderOutlineHighlight)); _hooked = false; } ReleaseRequest(); _requester = null; } internal static void Tick() { if (!_hooked) { return; } bool flag = ModConfig.Enabled.Value && HasAnyTarget(); if (flag != _requesting) { if (flag) { _requesting = true; OutlineHighlight.AddPreRenderHighlightRequest(_requester); } else { ReleaseRequest(); } } } private static void ReleaseRequest() { if (_requesting) { _requesting = false; OutlineHighlight.ReleasePreRenderHighlightRequest(_requester); } } private static void OnPreRenderOutlineHighlight(OutlineHighlight outlineHighlight) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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) if (!ModConfig.Enabled.Value || !Object.op_Implicit((Object)(object)outlineHighlight)) { return; } try { SceneCamera sceneCamera = outlineHighlight.sceneCamera; if (!Object.op_Implicit((Object)(object)sceneCamera)) { return; } CameraRigController cameraRigController = sceneCamera.cameraRigController; if (Object.op_Implicit((Object)(object)cameraRigController)) { Color outlineColor = GetOutlineColor(); SilhouetteFill.BeginFrame(outlineHighlight, outlineColor); CollectTargets(cameraRigController); for (int i = 0; i < Targets.Count; i++) { AddOutline(outlineHighlight, Targets[i], outlineColor); } Targets.Clear(); } } catch (Exception ex) { Plugin.Log.LogError((object)("縁取りの追加に失敗しました: " + ex)); } } private static bool HasAnyTarget() { ReadOnlyCollection<CameraRigController> readOnlyInstancesList = CameraRigController.readOnlyInstancesList; for (int i = 0; i < readOnlyInstancesList.Count; i++) { CameraRigController val = readOnlyInstancesList[i]; if (Object.op_Implicit((Object)(object)val) && ((Behaviour)val).enabled) { CollectTargets(val); int count = Targets.Count; Targets.Clear(); if (count > 0) { return true; } } } return false; } internal static void CollectTargets(CameraRigController rig) { Targets.Clear(); CharacterBody targetBody = rig.targetBody; ReadOnlyCollection<TeamComponent> allies = GetAllies(rig); for (int i = 0; i < allies.Count; i++) { CharacterBody outlineTarget = GetOutlineTarget(allies[i], targetBody); if (Object.op_Implicit((Object)(object)outlineTarget)) { Targets.Add(outlineTarget); } } } private static ReadOnlyCollection<TeamComponent> GetAllies(CameraRigController rig) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 //IL_000b: Unknown result type (might be due to invalid IL or missing references) TeamIndex targetTeamIndex = rig.targetTeamIndex; if ((int)targetTeamIndex != -1) { return TeamComponent.GetTeamMembers(targetTeamIndex); } return EmptyTeam; } private static CharacterBody GetOutlineTarget(TeamComponent teamComponent, CharacterBody viewer) { if (!Object.op_Implicit((Object)(object)teamComponent)) { return null; } CharacterBody body = teamComponent.body; if (!Object.op_Implicit((Object)(object)body)) { return null; } if (!ModConfig.ShowSelf.Value && (Object)(object)body == (Object)(object)viewer) { return null; } if (ModConfig.ShowMinions.Value) { return body; } if (!IsPlayer(body)) { return null; } return body; } private static bool IsPlayer(CharacterBody body) { CharacterMaster master = body.master; if (Object.op_Implicit((Object)(object)master)) { return Object.op_Implicit((Object)(object)master.playerCharacterMasterController); } return false; } private static void AddOutline(OutlineHighlight outlineHighlight, CharacterBody body, Color color) { //IL_0010: 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) CharacterModel model = GetModel(body); if (!Object.op_Implicit((Object)(object)model) || (int)model.visibility == 0) { return; } RendererInfo[] baseRendererInfos = model.baseRendererInfos; if (baseRendererInfos == null) { return; } for (int i = 0; i < baseRendererInfos.Length; i++) { Renderer renderer = baseRendererInfos[i].renderer; if (Object.op_Implicit((Object)(object)renderer) && renderer.enabled && ((Component)renderer).gameObject.activeInHierarchy && !SilhouetteFill.TryDraw(renderer)) { outlineHighlight.AddHighlight(renderer, color); } } } internal static CharacterModel GetModel(CharacterBody body) { ModelLocator modelLocator = body.modelLocator; if (!Object.op_Implicit((Object)(object)modelLocator)) { return null; } Transform modelTransform = modelLocator.modelTransform; if (!Object.op_Implicit((Object)(object)modelTransform)) { return null; } return ((Component)modelTransform).GetComponent<CharacterModel>(); } private static Color GetOutlineColor() { //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_000f: Unknown result type (might be due to invalid IL or missing references) return Color32.op_Implicit(Color32.op_Implicit(ModConfig.OutlineColor.Value)); } } internal static class ModConfig { public static ConfigEntry<bool> Enabled; public static ConfigEntry<bool> ShowSelf; public static ConfigEntry<bool> ShowMinions; public static ConfigEntry<Color> OutlineColor; public static void Init(ConfigFile config) { //IL_0075: Unknown result type (might be due to invalid IL or missing references) EnsureColorConverter(); Enabled = config.Bind<bool>("General", "Enabled", true, "味方プレイヤーを縁取る。off にするとバニラの見た目に戻る。"); ShowSelf = config.Bind<bool>("General", "Show Self", false, "自分自身も縁取る。自分は常に画面の中心に居るので既定では縁取らない。"); ShowMinions = config.Bind<bool>("General", "Show Minions", true, "味方が連れているドローン・タレット・召喚も縁取る。off にすると操作プレイヤーだけになる。"); OutlineColor = config.Bind<Color>("General", "Outline Color", new Color(0.2f, 0.8f, 1f, 1f), "縁取りの色。アルファは縁取りの濃さになる。RoR2 は色ごとにマテリアルを作って保持し続けるので、毎フレーム変わるような使い方はしない。"); if (!Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions")) { Plugin.Log.LogInfo((object)"Risk of Options が見つからないので設定画面は登録しません。"); return; } try { RegisterRiskOfOptions(); Plugin.Log.LogInfo((object)"Risk of Options へ設定を登録しました。"); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Risk of Options への設定登録に失敗しました: " + ex)); } } [MethodImpl(MethodImplOptions.NoInlining)] private static void RegisterRiskOfOptions() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown ModSettingsManager.SetModDescription("味方の輪郭を壁越しに表示します。誰がどこにいるか常に分かります。連れているタレットやドローンも含みます。自分自身は既定では縁取りません。"); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(Enabled)); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(ShowMinions)); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(ShowSelf)); ModSettingsManager.AddOption((BaseOption)new ColorOption(OutlineColor)); } private static void EnsureColorConverter() { //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_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown if (TomlTypeConverter.CanConvert(typeof(Color))) { return; } TomlTypeConverter.AddConverter(typeof(Color), new TypeConverter { ConvertToString = (object obj, Type type) => "#" + ColorUtility.ToHtmlStringRGBA((Color)obj), ConvertToObject = delegate(string str, Type type) { //IL_0010: 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_000f: Unknown result type (might be due to invalid IL or missing references) Color white = default(Color); if (!ColorUtility.TryParseHtmlString(str, ref white)) { white = Color.white; } return white; } }); } } [BepInPlugin("OchaDashiMan.AllyOutline", "AllyOutline", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string Guid = "OchaDashiMan.AllyOutline"; public const string ModName = "AllyOutline"; public const string Version = "1.0.0"; internal const string RiskOfOptionsGuid = "com.rune580.riskofoptions"; internal static ManualLogSource Log; private void Awake() { Log = ((BaseUnityPlugin)this).Logger; ModConfig.Init(((BaseUnityPlugin)this).Config); AllyOutliner.Init((Object)(object)this); Log.LogInfo((object)"AllyOutline 1.0.0 loaded."); } private void Update() { AllyOutliner.Tick(); } private void OnDestroy() { AllyOutliner.Shutdown(); } } internal static class SilhouetteFill { internal const string DefaultShaderName = "Hopoo Games/FX/Cloud Remap"; private const string ZTestName = "_ZTest"; private static readonly int ColorId = Shader.PropertyToID("_Color"); private static readonly int TintColorId = Shader.PropertyToID("_TintColor"); private static readonly int ZTestId = Shader.PropertyToID("_ZTest"); private static readonly int ZWriteId = Shader.PropertyToID("_ZWrite"); private static readonly int CullId = Shader.PropertyToID("_Cull"); private static readonly int SrcBlendId = Shader.PropertyToID("_SrcBlend"); private static readonly int DstBlendId = Shader.PropertyToID("_DstBlend"); private static readonly int MainTexId = Shader.PropertyToID("_MainTex"); private static FieldInfo _commandBufferField; private static bool _commandBufferFieldMissing; private static Material _material; private static string _materialShaderName; private static bool _shaderMissingLogged; private static CommandBuffer _buffer; private static bool _active; internal static void BeginFrame(OutlineHighlight outlineHighlight, Color color) { //IL_0038: 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) _active = false; Material material = GetMaterial(ResolveShaderName()); if (!Object.op_Implicit((Object)(object)material)) { return; } CommandBuffer commandBuffer = GetCommandBuffer(outlineHighlight); if (commandBuffer != null) { if (material.HasProperty(ColorId)) { material.SetColor(ColorId, color); } if (material.HasProperty(TintColorId)) { material.SetColor(TintColorId, color); } _buffer = commandBuffer; _material = material; _active = true; } } internal static bool TryDraw(Renderer renderer) { if (!_active) { return false; } _buffer.DrawRenderer(renderer, _material, 0, 0); return true; } private static string ResolveShaderName() { return "Hopoo Games/FX/Cloud Remap"; } private static Material GetMaterial(string shaderName) { //IL_0058: 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_0066: Expected O, but got Unknown if (Object.op_Implicit((Object)(object)_material) && _materialShaderName == shaderName) { return _material; } Shader val = FindLoadedShader(shaderName); if (!Object.op_Implicit((Object)(object)val)) { if (!_shaderMissingLogged) { _shaderMissingLogged = true; Plugin.Log.LogWarning((object)("塗りつぶし用のシェーダー \"" + shaderName + "\" が見つかりません。バニラの塗りつぶしへ落とします(縁取りは出ますが壁越しにはなりません)。")); } return null; } Material val2 = new Material(val) { hideFlags = (HideFlags)61 }; if (val2.HasProperty(ZTestId)) { val2.SetInt(ZTestId, 8); } if (val2.HasProperty(ZWriteId)) { val2.SetInt(ZWriteId, 0); } if (val2.HasProperty(CullId)) { val2.SetInt(CullId, 0); } if (val2.HasProperty(SrcBlendId)) { val2.SetInt(SrcBlendId, 1); } if (val2.HasProperty(DstBlendId)) { val2.SetInt(DstBlendId, 0); } if (val2.HasProperty(MainTexId)) { val2.SetTexture(MainTexId, (Texture)(object)Texture2D.whiteTexture); } SuppressFading(val2); _material = val2; _materialShaderName = shaderName; return val2; } private static void SuppressFading(Material material) { material.DisableKeyword("SOFTPARTICLES_ON"); SetIfPresent(material, "_FadeCloseOn", 0f); SetIfPresent(material, "_FadeCloseDistance", 0f); SetIfPresent(material, "_VertexColorOn", 0f); SetIfPresent(material, "_VertexAlphaOn", 0f); SetIfPresent(material, "_VertColor", 0f); SetIfPresent(material, "_Fade", 1f); SetIfPresent(material, "_ExternalAlpha", 1f); SetIfPresent(material, "_AlphaBias", 0f); SetIfPresent(material, "_Cutoff", 0f); SetIfPresent(material, "_WireframeOnly", 0f); } private static void SetIfPresent(Material material, string name, float value) { if (material.HasProperty(name)) { material.SetFloat(name, value); } } internal static Shader FindLoadedShader(string name) { Shader[] array = Resources.FindObjectsOfTypeAll<Shader>(); for (int i = 0; i < array.Length; i++) { if (Object.op_Implicit((Object)(object)array[i]) && ((Object)array[i]).name == name) { return array[i]; } } return null; } private static CommandBuffer GetCommandBuffer(OutlineHighlight outlineHighlight) { if (_commandBufferFieldMissing) { return null; } if (_commandBufferField == null) { _commandBufferField = typeof(OutlineHighlight).GetField("commandBuffer", BindingFlags.Instance | BindingFlags.NonPublic); if (_commandBufferField == null) { _commandBufferFieldMissing = true; Plugin.Log.LogWarning((object)"OutlineHighlight.commandBuffer が見つかりません。バニラの塗りつぶしへ落とします(縁取りは出ますが壁越しにはなりません)。"); return null; } } object? value = _commandBufferField.GetValue(outlineHighlight); return (CommandBuffer)((value is CommandBuffer) ? value : null); } } }