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 EnhancedSpectator v1.0.5
BepInEx/plugins/EnhancedSpectator.dll
Decompiled 2 years agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using EnhancedSpectator.Patches; using EnhancedSpectator.Utils; using Figgle; using GameNetcodeStuff; using HarmonyLib; using LethalCompanyInputUtils.Api; using LethalConfig; using LethalConfig.ConfigItems; using LethalConfig.ConfigItems.Options; using TMPro; using Unity.Netcode; using UnityEngine; using UnityEngine.InputSystem; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("EnhancedSpectator")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("EnhancedSpectator")] [assembly: AssemblyCopyright("Copyright © 2024")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("ad2f8592-b408-49e8-b12b-f7b70966761f")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.5.0")] namespace EnhancedSpectator { public class PluginMetadata { public const string Author = "PXC"; public const string Name = "EnhancedSpectator"; public const string Id = "PXC.EnhancedSpectator"; public const string Version = "1.0.5"; public string FullName => string.Format("{0} v{1}", "EnhancedSpectator", "1.0.5"); } [BepInPlugin("PXC.EnhancedSpectator", "EnhancedSpectator", "1.0.5")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] internal class LCES : BaseUnityPlugin { public static PluginMetadata pluginMetadata = new PluginMetadata(); public static ManualLogSource Log = new ManualLogSource("PXC.EnhancedSpectator"); public static LCES Instance; public static ConfigInputs Inputs { get; set; } private void Awake() { if ((Object)(object)Instance == (Object)null) { Instance = this; } Log = ((BaseUnityPlugin)this).Logger; Log.LogInfo((object)("Initializing plugin: " + pluginMetadata.FullName + " by PXC")); Harmony.CreateAndPatchAll(typeof(HUDManagerPatches), (string)null); Log.LogInfo((object)"[Patched] HUDManager"); Harmony.CreateAndPatchAll(typeof(PlayerControllerBPatches), (string)null); Log.LogInfo((object)"[Patched] PlayerControllerB"); Harmony.CreateAndPatchAll(typeof(StartOfRoundPatches), (string)null); Log.LogInfo((object)"[Patched] StartOfRound"); HUDManagerPatches.SpectatedTextSpacer = "\n\n"; ConfigSettings.Initialize(((BaseUnityPlugin)this).Config, "Enhances the spectating experience."); Inputs = new ConfigInputs(); Inputs.FlashlightBinding.performed += OnFlashlightPressed; Inputs.NightVisionBinding.performed += OnNightVisionPressed; ConfigSettings.FlashlightAllowed.SettingChanged += FlashlightAllowed_SettingChanged; ConfigSettings.NightVisionAllowed.SettingChanged += NightVisionAllowed_SettingChanged; Log.LogInfo((object)("Loaded!\n" + FiggleFonts.Doom.Render(pluginMetadata.FullName, (int?)null))); } private void ToggleSpecFlashlight() { if (!((Object)(object)GameNetworkManager.Instance != (Object)null) || !((Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null)) { return; } PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController; if ((Object)(object)HUDManager.Instance != (Object)null && ((NetworkBehaviour)localPlayerController).IsOwner && localPlayerController.isPlayerDead && !StartOfRound.Instance.shipIsLeaving && (!((NetworkBehaviour)localPlayerController).IsServer || localPlayerController.isHostPlayerObject)) { Light component = ((Component)HUDManager.Instance.playersManager.spectateCamera).GetComponent<Light>(); if ((Object)(object)component != (Object)null && ConfigSettings.FlashlightAllowed.Value) { ((Behaviour)component).enabled = !((Behaviour)component).enabled; } else { ((Behaviour)component).enabled = false; } HUDManagerPatches.FlashLightStatus = ((Behaviour)component).enabled; } } private void ToggleSpecNightVision() { if (!((Object)(object)GameNetworkManager.Instance != (Object)null) || !((Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null)) { return; } PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController; if ((Object)(object)HUDManager.Instance != (Object)null && ((NetworkBehaviour)localPlayerController).IsOwner && localPlayerController.isPlayerDead && !StartOfRound.Instance.shipIsLeaving && (!((NetworkBehaviour)localPlayerController).IsServer || localPlayerController.isHostPlayerObject)) { if (ConfigSettings.NightVisionAllowed.Value) { PlayerControllerBPatches.NightVisionToggled = !PlayerControllerBPatches.NightVisionToggled; } else { PlayerControllerBPatches.NightVisionToggled = false; } HUDManagerPatches.NightvisionStatus = PlayerControllerBPatches.NightVisionToggled; } } private void OnFlashlightPressed(CallbackContext context) { if (((CallbackContext)(ref context)).performed) { ToggleSpecFlashlight(); } } private void OnNightVisionPressed(CallbackContext context) { if (((CallbackContext)(ref context)).performed) { ToggleSpecNightVision(); } } private void FlashlightAllowed_SettingChanged(object sender, EventArgs e) { ToggleSpecFlashlight(); } private void NightVisionAllowed_SettingChanged(object sender, EventArgs e) { ToggleSpecNightVision(); } public static bool PluginExists(string Name, bool ShowWarning = true) { if (Chainloader.PluginInfos.ContainsKey(Name)) { KeyValuePair<string, PluginInfo> keyValuePair = Chainloader.PluginInfos.FirstOrDefault((KeyValuePair<string, PluginInfo> n) => n.Key == Name); if (ShowWarning) { Log.LogInfo((object)$"[SoftDependency] Found plugin: {keyValuePair.Value.Metadata.Name} ({keyValuePair.Value.Metadata.GUID}) v{keyValuePair.Value.Metadata.Version} - Initializing methods..."); } return true; } if (ShowWarning) { Log.LogWarning((object)("[SoftDependency] Unable to find plugin '" + Name + "' - Skipping its initialization!")); } return false; } } } namespace EnhancedSpectator.Utils { internal class ConfigInputs : LcInputActions { public InputAction FlashlightBinding => ((LcInputActions)this).Asset["FlashlightBinding"]; public InputAction NightVisionBinding => ((LcInputActions)this).Asset["NightVisionBinding"]; public override void CreateInputActions(in InputActionMapBuilder builder) { ((LcInputActions)this).CreateInputActions(ref builder); builder.NewActionBinding().WithActionId("FlashlightBinding").WithActionType((InputActionType)1) .WithKbmPath(ConfigSettings.FlashlightKeybind.Value) .WithBindingName("Flashlight") .Finish(); builder.NewActionBinding().WithActionId("NightVisionBinding").WithActionType((InputActionType)1) .WithKbmPath(ConfigSettings.NightVisionKeybind.Value) .WithBindingName("NightVision") .Finish(); } } public class ConfigSettings { public static ConfigEntry<bool> NightVisionAllowed; public static ConfigEntry<float> NightVisionIntensity; public static ConfigEntry<bool> ModifyDarkness; public static ConfigEntry<float> DarknessModifier; public static ConfigEntry<string> NightVisionKeybind; public static ConfigEntry<bool> FlashlightAllowed; public static ConfigEntry<string> FlashlightKeybind; public static ConfigEntry<bool> ClockAllowed; public static ConfigEntry<bool> RaisedClockSupport; public static ConfigEntry<float> RaisedClockOffset; public static void Initialize(ConfigFile config, string description) { string text = "Night Vision"; NightVisionAllowed = config.Bind<bool>(text, "Allowed", true, "Allow night vision while spectating."); NightVisionIntensity = config.Bind<float>(text, "Intensity", 7500f, "This is how bright the night vision makes the environment when enabled."); ModifyDarkness = config.Bind<bool>(text, "Modify Darkness", false, "Some mods (Diversity) change the default darkness intensity value. This setting enables the below option."); DarknessModifier = config.Bind<float>(text, "Darkness Modifier", 1f, "This option modifies the default darkness intensity value."); NightVisionKeybind = config.Bind<string>(text, "Keybind", "<Keyboard>/n", "Input binding to toggle night vision while spectating."); text = "Flashlight"; FlashlightAllowed = config.Bind<bool>(text, "Allowed", true, "Allow flashlight while spectating."); FlashlightKeybind = config.Bind<string>(text, "Keybind", "<Keyboard>/f", "Input binding to toggle flashlight while spectating."); text = "Clock"; ClockAllowed = config.Bind<bool>(text, "Allowed", true, "Allow clock while spectating."); RaisedClockSupport = config.Bind<bool>(text, "Raised Clock Support", false, "Moves the text showing who you are spectating down a bit to support mods that move the clock position higher (e.g. LCBetterClock)."); RaisedClockOffset = config.Bind<float>(text, "Offset", -25f, "How much to offset the spectating text by on the Y axis."); try { if (LCES.PluginExists("ainavt.lc.lethalconfig")) { SetupLethalConfig(description); } } catch { } } private static void SetupLethalConfig(string description) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown //IL_005c: 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_006c: Expected O, but got Unknown //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Expected O, but got Unknown //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected O, but got Unknown //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Expected O, but got Unknown //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Expected O, but got Unknown //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Expected O, but got Unknown //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Expected O, but got Unknown //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Expected O, but got Unknown //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Expected O, but got Unknown LethalConfigManager.SetModDescription(description); LethalConfigManager.AddConfigItem((BaseConfigItem)new BoolCheckBoxConfigItem(NightVisionAllowed, false)); ConfigEntry<float> nightVisionIntensity = NightVisionIntensity; FloatSliderOptions val = new FloatSliderOptions(); ((BaseRangeOptions<float>)val).Min = 100f; ((BaseRangeOptions<float>)val).Max = 100000f; ((BaseOptions)val).RequiresRestart = false; LethalConfigManager.AddConfigItem((BaseConfigItem)new FloatSliderConfigItem(nightVisionIntensity, val)); LethalConfigManager.AddConfigItem((BaseConfigItem)new BoolCheckBoxConfigItem(ModifyDarkness, false)); ConfigEntry<float> darknessModifier = DarknessModifier; FloatSliderOptions val2 = new FloatSliderOptions(); ((BaseRangeOptions<float>)val2).Min = 0f; ((BaseRangeOptions<float>)val2).Max = 1f; ((BaseOptions)val2).RequiresRestart = false; LethalConfigManager.AddConfigItem((BaseConfigItem)new FloatSliderConfigItem(darknessModifier, val2)); LethalConfigManager.AddConfigItem((BaseConfigItem)new TextInputFieldConfigItem(NightVisionKeybind, true)); LethalConfigManager.AddConfigItem((BaseConfigItem)new BoolCheckBoxConfigItem(FlashlightAllowed, false)); LethalConfigManager.AddConfigItem((BaseConfigItem)new TextInputFieldConfigItem(FlashlightKeybind, true)); LethalConfigManager.AddConfigItem((BaseConfigItem)new BoolCheckBoxConfigItem(ClockAllowed, false)); LethalConfigManager.AddConfigItem((BaseConfigItem)new BoolCheckBoxConfigItem(RaisedClockSupport, false)); ConfigEntry<float> raisedClockOffset = RaisedClockOffset; FloatSliderOptions val3 = new FloatSliderOptions(); ((BaseRangeOptions<float>)val3).Min = -465f; ((BaseRangeOptions<float>)val3).Max = 30f; ((BaseOptions)val3).RequiresRestart = false; LethalConfigManager.AddConfigItem((BaseConfigItem)new FloatSliderConfigItem(raisedClockOffset, val3)); } } } namespace EnhancedSpectator.Patches { [HarmonyPatch(typeof(HUDManager), "Update")] internal class HUDManagerPatches { private static string FlashLightAction { get; set; } private static string NightvisionAction { get; set; } private static string SpectatedPlayerText { get; set; } public static string SpectatedTextSpacer { get; set; } public static bool FlashLightStatus { get; set; } public static bool NightvisionStatus { get; set; } public static bool FoundSpectating { get; set; } public static bool? ClockStatus { get; set; } public static bool? ModifiedSpectateText { get; set; } public static GameObject Spectating { get; set; } public static Vector3 SpectatingPos { get; set; } private static void Postfix(HUDManager __instance) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_014a: 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_0169: 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) if (SpectatedTextSpacer == null) { SpectatedTextSpacer = ""; } if ((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null) { return; } _ = (Object)(object)Spectating == (Object)null; Spectating = Spectating ?? (Spectating = GameObject.Find("/Systems/UI/Canvas/DeathScreen/SpectateUI/Spectating")); if (!FoundSpectating && Object.op_Implicit((Object)(object)Spectating)) { FoundSpectating = true; SpectatingPos = Spectating.transform.localPosition; } if (ConfigSettings.RaisedClockSupport.Value) { if (!Object.op_Implicit((Object)(object)Spectating)) { string text = Regex.Replace(((TMP_Text)__instance.spectatingPlayerText).text, "\\n", "", RegexOptions.IgnoreCase); if (string.IsNullOrEmpty(SpectatedPlayerText)) { SpectatedPlayerText = text; } else if (!Regex.IsMatch(text, $"^{Regex.Escape(SpectatedPlayerText)}$", RegexOptions.IgnoreCase)) { SpectatedPlayerText = text; ((TMP_Text)__instance.spectatingPlayerText).text = SpectatedTextSpacer + text; } else if (!Regex.IsMatch(((TMP_Text)__instance.spectatingPlayerText).text, "\\n", RegexOptions.IgnoreCase)) { ((TMP_Text)__instance.spectatingPlayerText).text = SpectatedTextSpacer + text; } } else { Spectating.transform.localPosition = new Vector3(SpectatingPos.x, SpectatingPos.y + ConfigSettings.RaisedClockOffset.Value, SpectatingPos.z); } } else if (!Object.op_Implicit((Object)(object)Spectating)) { ((TMP_Text)__instance.spectatingPlayerText).text = Regex.Replace(((TMP_Text)__instance.spectatingPlayerText).text, "\\n", "", RegexOptions.IgnoreCase); } else { Spectating.transform.localPosition = SpectatingPos; } if (!GameNetworkManager.Instance.localPlayerController.isPlayerDead) { return; } Light component = ((Component)__instance.playersManager.spectateCamera).GetComponent<Light>(); if (StartOfRound.Instance.shipIsLeaving) { if ((Object)(object)component != (Object)null) { ((Behaviour)component).enabled = false; } return; } string bindingDisplayString = InputActionRebindingExtensions.GetBindingDisplayString(LCES.Inputs.FlashlightBinding, (DisplayStringOptions)0, (string)null); string bindingDisplayString2 = InputActionRebindingExtensions.GetBindingDisplayString(LCES.Inputs.NightVisionBinding, (DisplayStringOptions)0, (string)null); FlashLightStatus = ((Behaviour)component).enabled; FlashLightAction = (((Behaviour)component).enabled ? "Disable" : "Enable"); NightvisionAction = (NightvisionStatus ? "Disable" : "Enable"); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("\n\n\n\n\n"); if (ConfigSettings.FlashlightAllowed.Value) { stringBuilder.AppendLine($"{FlashLightAction} Flashlight : [{bindingDisplayString}]"); } if (ConfigSettings.NightVisionAllowed.Value) { stringBuilder.AppendLine($"{NightvisionAction} Night Vision : [{bindingDisplayString2}]"); } TextMeshProUGUI holdButtonToEndGameEarlyText = __instance.holdButtonToEndGameEarlyText; ((TMP_Text)holdButtonToEndGameEarlyText).text = ((TMP_Text)holdButtonToEndGameEarlyText).text + stringBuilder.ToString(); } [HarmonyPrefix] private static void ClockOnSpectate(HUDManager __instance) { if (!((Object)(object)__instance != (Object)null) || HUDManager.Instance?.Clock == null || !((Object)(object)GameNetworkManager.Instance?.localPlayerController != (Object)null) || !GameNetworkManager.Instance.localPlayerController.isPlayerDead) { return; } if (ConfigSettings.ClockAllowed.Value) { if (HUDManager.Instance.Clock != null) { HUDManager.Instance.HideHUD(false); HUDManager.Instance.SetClockVisible(true); HUDManager.Instance.Clock.targetAlpha = 1f; HUDManager.Instance.Inventory.targetAlpha = 0f; HUDManager.Instance.PlayerInfo.targetAlpha = 0f; ClockStatus = true; } } else { HUDManager.Instance.HideHUD(true); HUDManager.Instance.SetClockVisible(false); ClockStatus = false; } } } [HarmonyPatch(typeof(PlayerControllerB), "Update")] internal class PlayerControllerBPatches { internal static bool NightVisionToggled; internal static bool WasToggledOnce; public static bool IsDead; [HarmonyPrefix] private static void Prefix(PlayerControllerB __instance) { if ((Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null && (Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null) { PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController; if (WasToggledOnce && StartOfRound.Instance.shipIsLeaving) { LCES.Log.LogInfo((object)"Ship is leaving - Resetting toggle states..."); WasToggledOnce = false; IsDead = false; NightVisionToggle(__instance, ToggleAction: false); } if (localPlayerController.isPlayerDead && !StartOfRound.Instance.shipIsLeaving) { NightVisionToggle(__instance, NightVisionToggled); if (!WasToggledOnce) { WasToggledOnce = true; IsDead = true; } } else if (WasToggledOnce) { NightVisionToggled = false; NightVisionToggle(__instance, ToggleAction: false); } } else if (WasToggledOnce) { NightVisionToggled = false; NightVisionToggle(__instance, ToggleAction: false); } } public static void NightVisionToggle(PlayerControllerB __instance, bool ToggleAction) { if (!ConfigSettings.NightVisionAllowed.Value) { ToggleAction = false; } if (!IsDead) { ToggleAction = false; } if (ToggleAction) { __instance.nightVision.intensity = ConfigSettings.NightVisionIntensity.Value; __instance.nightVision.range = 100000f; __instance.nightVision.shadowStrength = 0f; __instance.nightVision.shadows = (LightShadows)0; __instance.nightVision.shape = (LightShape)2; } else { float num = (ConfigSettings.ModifyDarkness.Value ? Mathf.Clamp(1f - ConfigSettings.DarknessModifier.Value, 0f, 1f) : 1f); __instance.nightVision.intensity = 366.9317f * num; __instance.nightVision.range = 12f; __instance.nightVision.shadowStrength = 1f; __instance.nightVision.shadows = (LightShadows)0; __instance.nightVision.shape = (LightShape)0; } } } [HarmonyPatch] internal class StartOfRoundPatches { [HarmonyPostfix] [HarmonyPatch(typeof(StartOfRound), "AutoSaveShipData")] private static void AutoSaveShipData() { PlayerControllerBPatches.IsDead = false; PlayerControllerBPatches.NightVisionToggle(GameNetworkManager.Instance.localPlayerController, ToggleAction: false); HUDManager.Instance.PlayerInfo.targetAlpha = 1f; HUDManager.Instance.Inventory.targetAlpha = 1f; HUDManagerPatches.ClockStatus = false; } [HarmonyPostfix] [HarmonyPatch(typeof(StartOfRound), "ReviveDeadPlayers")] private static void PlayerHasRevivedServerRpc() { PlayerControllerBPatches.IsDead = false; PlayerControllerBPatches.NightVisionToggle(GameNetworkManager.Instance.localPlayerController, ToggleAction: false); } [HarmonyPostfix] [HarmonyPatch(typeof(StartOfRound), "EndOfGameClientRpc")] private static void RefreshDay() { PlayerControllerBPatches.IsDead = false; PlayerControllerBPatches.NightVisionToggle(GameNetworkManager.Instance.localPlayerController, ToggleAction: false); } } }
BepInEx/plugins/Figgle.dll
Decompiled 2 years agousing System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Text.RegularExpressions; using Microsoft.CodeAnalysis; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("Drew Noakes")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright Drew Noakes 2017-2023")] [assembly: AssemblyDescription("ASCII banner generation for .NET")] [assembly: AssemblyFileVersion("0.5.1.0")] [assembly: AssemblyInformationalVersion("0.5.1+83b4a47d24d50442e09efa6c4a0d9a32c68e3f4d")] [assembly: AssemblyProduct("Figgle")] [assembly: AssemblyTitle("Figgle")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/drewnoakes/figgle.git")] [assembly: AssemblyVersion("0.5.1.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class IsReadOnlyAttribute : Attribute { } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.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 Figgle { public sealed class FiggleException : Exception { public FiggleException(string message) : base(message) { } } internal readonly struct Line { public string Content { get; } public byte SpaceBefore { get; } public byte SpaceAfter { get; } public char FrontChar { get { if (Content.Length != SpaceBefore) { return Content[SpaceBefore]; } return ' '; } } public char BackChar { get { if (Content.Length != SpaceAfter) { return Content[Content.Length - SpaceAfter - 1]; } return ' '; } } public Line(string content, byte spaceBefore, byte spaceAfter) { Content = content; SpaceBefore = spaceBefore; SpaceAfter = spaceAfter; } } internal sealed class FiggleCharacter { public IReadOnlyList<Line> Lines { get; } public FiggleCharacter(IReadOnlyList<Line> lines) { Lines = lines; } } public enum FiggleTextDirection { LeftToRight, RightToLeft } public sealed class FiggleFont { private readonly IReadOnlyList<FiggleCharacter> _requiredCharacters; private readonly IReadOnlyDictionary<int, FiggleCharacter> _sparseCharacters; private readonly char _hardBlank; private readonly int _smushMode; private const int SM_SMUSH = 128; private const int SM_KERN = 64; private const int SM_HARDBLANK = 32; private const int SM_BIGX = 16; private const int SM_PAIR = 8; private const int SM_HIERARCHY = 4; private const int SM_LOWLINE = 2; private const int SM_EQUAL = 1; private const int SM_FULLWIDTH = 0; public int Height { get; } public int Baseline { get; } public FiggleTextDirection Direction { get; } internal FiggleFont(IReadOnlyList<FiggleCharacter> requiredCharacters, IReadOnlyDictionary<int, FiggleCharacter> sparseCharacters, char hardBlank, int height, int baseline, FiggleTextDirection direction, int smushMode) { _requiredCharacters = requiredCharacters; _sparseCharacters = sparseCharacters; _hardBlank = hardBlank; _smushMode = smushMode; Height = height; Baseline = baseline; Direction = direction; } private FiggleCharacter GetCharacter(char c) { if (c < '\0' || c > 'ÿ') { _sparseCharacters.TryGetValue(c, out FiggleCharacter value); return value ?? _requiredCharacters[0]; } return _requiredCharacters[c] ?? _requiredCharacters[0]; } public bool Contains(char c) { if (c < '\0' || c > 'ÿ') { return _sparseCharacters.ContainsKey(c); } return _requiredCharacters[c] != null; } public string Render(string message, int? smushOverride = null) { int smush = smushOverride ?? _smushMode; List<StringBuilder> list = (from _ in Enumerable.Range(0, Height) select new StringBuilder()).ToList(); FiggleCharacter figgleCharacter = null; foreach (char c in message) { FiggleCharacter character = GetCharacter(c); if (character == null) { continue; } int num = CalculateFitMove(figgleCharacter, character); for (int j = 0; j < Height; j++) { Line line = character.Lines[j]; StringBuilder stringBuilder = list[j]; if (num != 0) { int num2 = num; if (figgleCharacter != null) { byte spaceAfter = figgleCharacter.Lines[j].SpaceAfter; if (spaceAfter != 0) { int num3 = Math.Min(spaceAfter, num2); for (int k = 0; k < num3; k++) { if (stringBuilder[stringBuilder.Length - 1] != ' ') { break; } num2--; stringBuilder.Length--; } } } int num4 = stringBuilder.Length - 1; char l2 = stringBuilder[num4]; stringBuilder.Append((num2 == 0) ? line.Content : line.Content.Substring(num2)); if (num2 != 0 && stringBuilder.Length != 0 && character.Lines[j].Content.Length != 0) { char r2 = character.Lines[j].Content[num2 - 1]; char c2 = TrySmush(l2, r2); if (c2 != 0 && num4 >= 0) { stringBuilder[num4] = c2; } } } else { stringBuilder.Append(line.Content); } } figgleCharacter = character; } StringBuilder stringBuilder2 = new StringBuilder(); foreach (StringBuilder item in list) { stringBuilder2.AppendLine(item.Replace(_hardBlank, ' ').ToString()); } return stringBuilder2.ToString(); int CalculateFitMove(FiggleCharacter? l, FiggleCharacter r) { if (smush == 0) { return 0; } if (l == null) { return 0; } int num5 = int.MaxValue; for (int m = 0; m < Height; m++) { Line line2 = l.Lines[m]; Line line3 = r.Lines[m]; int num6 = line2.SpaceAfter + line3.SpaceBefore; if (TrySmush(line2.BackChar, line3.FrontChar) != 0) { num6++; } num6 = Math.Min(num6, line3.Content.Length); if (num6 < num5) { num5 = num6; } } return num5; } char TrySmush(char l, char r) { if (l == ' ') { return r; } if (r == ' ') { return l; } if ((_smushMode & 0x80) == 0) { return '\0'; } if ((_smushMode & 0x3F) == 0) { if (l == _hardBlank) { return r; } if (r == _hardBlank) { return l; } if (Direction != 0) { return l; } return r; } if (((uint)_smushMode & 0x20u) != 0 && l == _hardBlank && r == _hardBlank) { return l; } if (l == _hardBlank && r == _hardBlank) { return '\0'; } if (((uint)_smushMode & (true ? 1u : 0u)) != 0 && l == r) { return l; } if (((uint)_smushMode & 2u) != 0) { if (l == '_' && Enumerable.Contains("|/\\[]{}()<>", r)) { return r; } if (r == '_' && Enumerable.Contains("|/\\[]{}()<>", l)) { return l; } } if (((uint)_smushMode & 4u) != 0) { if (l == '|' && Enumerable.Contains("/\\[]{}()<>", r)) { return r; } if (r == '|' && Enumerable.Contains("/\\[]{}()<>", l)) { return l; } if (Enumerable.Contains("/\\", l) && Enumerable.Contains("[]{}()<>", r)) { return r; } if (Enumerable.Contains("/\\", r) && Enumerable.Contains("[]{}()<>", l)) { return l; } if (Enumerable.Contains("[]", l) && Enumerable.Contains("{}()<>", r)) { return r; } if (Enumerable.Contains("[]", r) && Enumerable.Contains("{}()<>", l)) { return l; } if (Enumerable.Contains("{}", l) && Enumerable.Contains("()<>", r)) { return r; } if (Enumerable.Contains("{}", r) && Enumerable.Contains("()<>", l)) { return l; } if (Enumerable.Contains("()", l) && Enumerable.Contains("<>", r)) { return r; } if (Enumerable.Contains("()", r) && Enumerable.Contains("<>", l)) { return l; } } if (((uint)_smushMode & 8u) != 0) { if (l == '[' && r == ']') { return '|'; } if (r == '[' && l == ']') { return '|'; } if (l == '{' && r == '}') { return '|'; } if (r == '{' && l == '}') { return '|'; } if (l == '(' && r == ')') { return '|'; } if (r == '(' && l == ')') { return '|'; } } if (((uint)_smushMode & 0x10u) != 0) { if (l == '/' && r == '\\') { return '|'; } if (r == '/' && l == '\\') { return 'Y'; } if (l == '>' && r == '<') { return 'X'; } } return '\0'; } } } public static class FiggleFontParser { private const int SM_SMUSH = 128; private const int SM_KERN = 64; private const int SM_FULLWIDTH = 0; private static readonly Regex _firstLinePattern = new Regex("^flf2 # signature\r\n a # always 'a'\r\n (?<hardblank>.) # any single character\r\n \\s(?<height>\\d+) # the number of rows, shared across all characters\r\n \\s(?<baseline>\\d+) # the number of rows from the top of the char to the baseline (excludes descenders)\r\n \\s(\\d+) # the maximum width of character data in the file, including endmarks\r\n \\s(?<layoutold>-?\\d+) # layout settings (old format)\r\n \\s(?<commentlinecount>\\d+) # number of comment lines after first line, before first character\r\n (\\s(?<direction>\\d+))? # print direction (0 is left-to-right, 1 is right-to-left)\r\n (\\s(?<layoutnew>\\d+))? # layout settings (new format)\r\n (\\s(\\d+))? # number of code-tagged (non-required) characters in the font, equal to total number of characters minus 102\r\n (\\s|$)", RegexOptions.Compiled | RegexOptions.IgnorePatternWhitespace); public static FiggleFont Parse(Stream stream, StringPool? pool = null) { StringPool pool2 = pool; if (stream == null) { throw new ArgumentNullException("stream"); } StreamReader reader = new StreamReader(stream); string text = reader.ReadLine(); if (text == null) { throw new FiggleException("Font file is empty."); } Match match = _firstLinePattern.Match(text); if (!match.Success) { throw new FiggleException("Font file has invalid first line."); } char hardBlank = match.Groups["hardblank"].Value[0]; int height = int.Parse(match.Groups["height"].Value); int baseline = int.Parse(match.Groups["baseline"].Value); int layoutOld = int.Parse(match.Groups["layoutold"].Value); int num = int.Parse(match.Groups["commentlinecount"].Value); Group group = match.Groups["layoutnew"]; int smushMode = (group.Success ? int.Parse(group.Value) : UpgradeLayout()); Group group2 = match.Groups["direction"]; FiggleTextDirection direction = (group2.Success ? ((FiggleTextDirection)int.Parse(group2.Value)) : FiggleTextDirection.LeftToRight); for (int i = 0; i < num; i++) { reader.ReadLine(); } if (pool2 == null) { pool2 = new StringPool(); } FiggleCharacter[] array = new FiggleCharacter[256]; for (int j = 32; j < 127; j++) { array[j] = ReadCharacter(); } array[196] = ReadCharacter(); array[214] = ReadCharacter(); array[220] = ReadCharacter(); array[228] = ReadCharacter(); array[246] = ReadCharacter(); array[252] = ReadCharacter(); array[223] = ReadCharacter(); Dictionary<int, FiggleCharacter> dictionary = new Dictionary<int, FiggleCharacter>(); while (true) { string text2 = reader.ReadLine(); if (text2 == null) { break; } if (!string.IsNullOrWhiteSpace(text2)) { if (!ParseUtil.TryParse(text2, out var i2)) { throw new FiggleException("Unsupported code-tagged character code string \"" + text2 + "\"."); } if (i2 >= 0 && i2 < 256) { array[i2] = ReadCharacter(); } else { dictionary[i2] = ReadCharacter(); } } } return new FiggleFont(array, dictionary, hardBlank, height, baseline, direction, smushMode); static byte CountEolSpaces(string s) { byte b = 0; int num2 = s.Length - 1; while (num2 > 0 && s[num2] == ' ') { num2--; b++; } return b; } static byte CountSolSpaces(string s) { byte b2 = 0; while (b2 < s.Length && s[b2] == ' ') { b2++; } return b2; } FiggleCharacter ReadCharacter() { Line[] array2 = new Line[height]; for (int k = 0; k < height; k++) { string text3 = reader.ReadLine(); if (text3 == null) { throw new FiggleException("Unexpected EOF in Font file."); } char c = text3[text3.Length - 1]; text3 = text3.TrimEnd(new char[1] { c }); array2[k] = new Line(pool2.Pool(text3), CountSolSpaces(text3), CountEolSpaces(text3)); } return new FiggleCharacter(array2); } int UpgradeLayout() { if (layoutOld == 0) { return 64; } if (layoutOld < 0) { return 0; } return (layoutOld & 0x1F) | 0x80; } } } public static class FiggleFonts { private static readonly ConcurrentDictionary<string, FiggleFont> _fontByName = new ConcurrentDictionary<string, FiggleFont>(StringComparer.Ordinal); private static readonly StringPool _stringPool = new StringPool(); public static FiggleFont OneRow => GetByName("1row"); public static FiggleFont ThreeD => GetByName("3-d"); public static FiggleFont ThreeDDiagonal => GetByName("3d_diagonal"); public static FiggleFont ThreeByFive => GetByName("3x5"); public static FiggleFont FourMax => GetByName("4max"); public static FiggleFont FiveLineOblique => GetByName("5lineoblique"); public static FiggleFont Acrobatic => GetByName("acrobatic"); public static FiggleFont Alligator => GetByName("alligator"); public static FiggleFont Alligator2 => GetByName("alligator2"); public static FiggleFont Alligator3 => GetByName("alligator3"); public static FiggleFont Alpha => GetByName("alpha"); public static FiggleFont Alphabet => GetByName("alphabet"); public static FiggleFont Amc3Line => GetByName("amc3line"); public static FiggleFont Amc3Liv1 => GetByName("amc3liv1"); public static FiggleFont AmcAaa01 => GetByName("amcaaa01"); public static FiggleFont AmcNeko => GetByName("amcneko"); public static FiggleFont AmcRazor2 => GetByName("amcrazo2"); public static FiggleFont AmcRazor => GetByName("amcrazor"); public static FiggleFont AmcSlash => GetByName("amcslash"); public static FiggleFont AmcSlder => GetByName("amcslder"); public static FiggleFont AmcThin => GetByName("amcthin"); public static FiggleFont AmcTubes => GetByName("amctubes"); public static FiggleFont AmcUn1 => GetByName("amcun1"); public static FiggleFont Arrows => GetByName("arrows"); public static FiggleFont AsciiNewroman => GetByName("ascii_new_roman"); public static FiggleFont Avatar => GetByName("avatar"); public static FiggleFont B1FF => GetByName("B1FF"); public static FiggleFont Banner => GetByName("banner"); public static FiggleFont Banner3 => GetByName("banner3"); public static FiggleFont Banner3D => GetByName("banner3-D"); public static FiggleFont Banner4 => GetByName("banner4"); public static FiggleFont BarbWire => GetByName("barbwire"); public static FiggleFont Basic => GetByName("basic"); public static FiggleFont Bear => GetByName("bear"); public static FiggleFont Bell => GetByName("bell"); public static FiggleFont Benjamin => GetByName("benjamin"); public static FiggleFont Big => GetByName("big"); public static FiggleFont BigChief => GetByName("bigchief"); public static FiggleFont BigFig => GetByName("bigfig"); public static FiggleFont Binary => GetByName("binary"); public static FiggleFont Block => GetByName("block"); public static FiggleFont Blocks => GetByName("blocks"); public static FiggleFont Bolger => GetByName("bolger"); public static FiggleFont Braced => GetByName("braced"); public static FiggleFont Bright => GetByName("bright"); public static FiggleFont Broadway => GetByName("broadway"); public static FiggleFont BroadwayKB => GetByName("broadway_kb"); public static FiggleFont Bubble => GetByName("bubble"); public static FiggleFont Bulbhead => GetByName("bulbhead"); public static FiggleFont Caligraphy2 => GetByName("calgphy2"); public static FiggleFont Caligraphy => GetByName("caligraphy"); public static FiggleFont Cards => GetByName("cards"); public static FiggleFont CatWalk => GetByName("catwalk"); public static FiggleFont Chiseled => GetByName("chiseled"); public static FiggleFont Chunky => GetByName("chunky"); public static FiggleFont Coinstak => GetByName("coinstak"); public static FiggleFont Cola => GetByName("cola"); public static FiggleFont Colossal => GetByName("colossal"); public static FiggleFont Computer => GetByName("computer"); public static FiggleFont Contessa => GetByName("contessa"); public static FiggleFont Contrast => GetByName("contrast"); public static FiggleFont Cosmic => GetByName("cosmic"); public static FiggleFont Cosmike => GetByName("cosmike"); public static FiggleFont Crawford => GetByName("crawford"); public static FiggleFont Crazy => GetByName("crazy"); public static FiggleFont Cricket => GetByName("cricket"); public static FiggleFont Cursive => GetByName("cursive"); public static FiggleFont CyberLarge => GetByName("cyberlarge"); public static FiggleFont CyberMedium => GetByName("cybermedium"); public static FiggleFont CyberSmall => GetByName("cybersmall"); public static FiggleFont Cygnet => GetByName("cygnet"); public static FiggleFont DANC4 => GetByName("DANC4"); public static FiggleFont DancingFont => GetByName("dancingfont"); public static FiggleFont Decimal => GetByName("decimal"); public static FiggleFont DefLeppard => GetByName("defleppard"); public static FiggleFont Diamond => GetByName("diamond"); public static FiggleFont DietCola => GetByName("dietcola"); public static FiggleFont Digital => GetByName("digital"); public static FiggleFont Doh => GetByName("doh"); public static FiggleFont Doom => GetByName("doom"); public static FiggleFont DosRebel => GetByName("dosrebel"); public static FiggleFont DotMatrix => GetByName("dotmatrix"); public static FiggleFont Double => GetByName("double"); public static FiggleFont DoubleShorts => GetByName("doubleshorts"); public static FiggleFont DRPepper => GetByName("drpepper"); public static FiggleFont DWhistled => GetByName("dwhistled"); public static FiggleFont EftiChess => GetByName("eftichess"); public static FiggleFont EftiFont => GetByName("eftifont"); public static FiggleFont EftiPiti => GetByName("eftipiti"); public static FiggleFont EftiRobot => GetByName("eftirobot"); public static FiggleFont EftiItalic => GetByName("eftitalic"); public static FiggleFont EftiWall => GetByName("eftiwall"); public static FiggleFont EftiWater => GetByName("eftiwater"); public static FiggleFont Epic => GetByName("epic"); public static FiggleFont Fender => GetByName("fender"); public static FiggleFont Filter => GetByName("filter"); public static FiggleFont FireFontK => GetByName("fire_font-k"); public static FiggleFont FireFontS => GetByName("fire_font-s"); public static FiggleFont Flipped => GetByName("flipped"); public static FiggleFont FlowerPower => GetByName("flowerpower"); public static FiggleFont FourTops => GetByName("fourtops"); public static FiggleFont Fraktur => GetByName("fraktur"); public static FiggleFont FunFace => GetByName("funface"); public static FiggleFont FunFaces => GetByName("funfaces"); public static FiggleFont Fuzzy => GetByName("fuzzy"); public static FiggleFont Georgia16 => GetByName("georgi16"); public static FiggleFont Georgia11 => GetByName("Georgia11"); public static FiggleFont Ghost => GetByName("ghost"); public static FiggleFont Ghoulish => GetByName("ghoulish"); public static FiggleFont Glenyn => GetByName("glenyn"); public static FiggleFont Goofy => GetByName("goofy"); public static FiggleFont Gothic => GetByName("gothic"); public static FiggleFont Graceful => GetByName("graceful"); public static FiggleFont Gradient => GetByName("gradient"); public static FiggleFont Graffiti => GetByName("graffiti"); public static FiggleFont Greek => GetByName("greek"); public static FiggleFont HeartLeft => GetByName("heart_left"); public static FiggleFont HeartRight => GetByName("heart_right"); public static FiggleFont Henry3d => GetByName("henry3d"); public static FiggleFont Hex => GetByName("hex"); public static FiggleFont Hieroglyphs => GetByName("hieroglyphs"); public static FiggleFont Hollywood => GetByName("hollywood"); public static FiggleFont HorizontalLeft => GetByName("horizontalleft"); public static FiggleFont HorizontalRight => GetByName("horizontalright"); public static FiggleFont ICL1900 => GetByName("ICL-1900"); public static FiggleFont Impossible => GetByName("impossible"); public static FiggleFont Invita => GetByName("invita"); public static FiggleFont Isometric1 => GetByName("isometric1"); public static FiggleFont Isometric2 => GetByName("isometric2"); public static FiggleFont Isometric3 => GetByName("isometric3"); public static FiggleFont Isometric4 => GetByName("isometric4"); public static FiggleFont Italic => GetByName("italic"); public static FiggleFont Ivrit => GetByName("ivrit"); public static FiggleFont Jacky => GetByName("jacky"); public static FiggleFont Jazmine => GetByName("jazmine"); public static FiggleFont Jerusalem => GetByName("jerusalem"); public static FiggleFont Katakana => GetByName("katakana"); public static FiggleFont Kban => GetByName("kban"); public static FiggleFont Keyboard => GetByName("keyboard"); public static FiggleFont Knob => GetByName("knob"); public static FiggleFont Konto => GetByName("konto"); public static FiggleFont KontoSlant => GetByName("kontoslant"); public static FiggleFont Larry3d => GetByName("larry3d"); public static FiggleFont Lcd => GetByName("lcd"); public static FiggleFont Lean => GetByName("lean"); public static FiggleFont Letters => GetByName("letters"); public static FiggleFont LilDevil => GetByName("lildevil"); public static FiggleFont LineBlocks => GetByName("lineblocks"); public static FiggleFont Linux => GetByName("linux"); public static FiggleFont LockerGnome => GetByName("lockergnome"); public static FiggleFont Madrid => GetByName("madrid"); public static FiggleFont Marquee => GetByName("marquee"); public static FiggleFont MaxFour => GetByName("maxfour"); public static FiggleFont Merlin1 => GetByName("merlin1"); public static FiggleFont Merlin2 => GetByName("merlin2"); public static FiggleFont Mike => GetByName("mike"); public static FiggleFont Mini => GetByName("mini"); public static FiggleFont Mirror => GetByName("mirror"); public static FiggleFont Mnemonic => GetByName("mnemonic"); public static FiggleFont Modular => GetByName("modular"); public static FiggleFont Morse => GetByName("morse"); public static FiggleFont Morse2 => GetByName("morse2"); public static FiggleFont Moscow => GetByName("moscow"); public static FiggleFont Mshebrew210 => GetByName("mshebrew210"); public static FiggleFont Muzzle => GetByName("muzzle"); public static FiggleFont NancyJ => GetByName("nancyj"); public static FiggleFont NancyJFancy => GetByName("nancyj-fancy"); public static FiggleFont NancyJImproved => GetByName("nancyj-improved"); public static FiggleFont NancyJUnderlined => GetByName("nancyj-underlined"); public static FiggleFont Nipples => GetByName("nipples"); public static FiggleFont NScript => GetByName("nscript"); public static FiggleFont NTGreek => GetByName("ntgreek"); public static FiggleFont NVScript => GetByName("nvscript"); public static FiggleFont O8 => GetByName("o8"); public static FiggleFont Octal => GetByName("octal"); public static FiggleFont Ogre => GetByName("ogre"); public static FiggleFont OldBanner => GetByName("oldbanner"); public static FiggleFont OS2 => GetByName("os2"); public static FiggleFont Pawp => GetByName("pawp"); public static FiggleFont Peaks => GetByName("peaks"); public static FiggleFont PeaksSlant => GetByName("peaksslant"); public static FiggleFont Pebbles => GetByName("pebbles"); public static FiggleFont Pepper => GetByName("pepper"); public static FiggleFont Poison => GetByName("poison"); public static FiggleFont Puffy => GetByName("puffy"); public static FiggleFont Puzzle => GetByName("puzzle"); public static FiggleFont Pyramid => GetByName("pyramid"); public static FiggleFont Rammstein => GetByName("rammstein"); public static FiggleFont Rectangles => GetByName("rectangles"); public static FiggleFont RedPhoenix => GetByName("red_phoenix"); public static FiggleFont Relief => GetByName("relief"); public static FiggleFont Relief2 => GetByName("relief2"); public static FiggleFont Rev => GetByName("rev"); public static FiggleFont Reverse => GetByName("reverse"); public static FiggleFont Roman => GetByName("roman"); public static FiggleFont Rot13 => GetByName("rot13"); public static FiggleFont Rotated => GetByName("rotated"); public static FiggleFont Rounded => GetByName("rounded"); public static FiggleFont RowanCap => GetByName("rowancap"); public static FiggleFont Rozzo => GetByName("rozzo"); public static FiggleFont Runic => GetByName("runic"); public static FiggleFont Runyc => GetByName("runyc"); public static FiggleFont SantaClara => GetByName("santaclara"); public static FiggleFont SBlood => GetByName("sblood"); public static FiggleFont Script => GetByName("script"); public static FiggleFont ScriptSlant => GetByName("slscript"); public static FiggleFont SerifCap => GetByName("serifcap"); public static FiggleFont Shadow => GetByName("shadow"); public static FiggleFont Shimrod => GetByName("shimrod"); public static FiggleFont Short => GetByName("short"); public static FiggleFont Slant => GetByName("slant"); public static FiggleFont Slide => GetByName("slide"); public static FiggleFont Small => GetByName("small"); public static FiggleFont SmallCaps => GetByName("smallcaps"); public static FiggleFont IsometricSmall => GetByName("smisome1"); public static FiggleFont KeyboardSmall => GetByName("smkeyboard"); public static FiggleFont PoisonSmall => GetByName("smpoison"); public static FiggleFont ScriptSmall => GetByName("smscript"); public static FiggleFont ShadowSmall => GetByName("smshadow"); public static FiggleFont SlantSmall => GetByName("smslant"); public static FiggleFont TengwarSmall => GetByName("smtengwar"); public static FiggleFont Soft => GetByName("soft"); public static FiggleFont Speed => GetByName("speed"); public static FiggleFont Spliff => GetByName("spliff"); public static FiggleFont SRelief => GetByName("s-relief"); public static FiggleFont Stacey => GetByName("stacey"); public static FiggleFont Stampate => GetByName("stampate"); public static FiggleFont Stampatello => GetByName("stampatello"); public static FiggleFont Standard => GetByName("standard"); public static FiggleFont Starstrips => GetByName("starstrips"); public static FiggleFont Starwars => GetByName("starwars"); public static FiggleFont Stellar => GetByName("stellar"); public static FiggleFont Stforek => GetByName("stforek"); public static FiggleFont Stop => GetByName("stop"); public static FiggleFont Straight => GetByName("straight"); public static FiggleFont SubZero => GetByName("sub-zero"); public static FiggleFont Swampland => GetByName("swampland"); public static FiggleFont Swan => GetByName("swan"); public static FiggleFont Sweet => GetByName("sweet"); public static FiggleFont Tanja => GetByName("tanja"); public static FiggleFont Tengwar => GetByName("tengwar"); public static FiggleFont Term => GetByName("term"); public static FiggleFont Test1 => GetByName("test1"); public static FiggleFont Thick => GetByName("thick"); public static FiggleFont Thin => GetByName("thin"); public static FiggleFont ThreePoint => GetByName("threepoint"); public static FiggleFont Ticks => GetByName("ticks"); public static FiggleFont TicksSlant => GetByName("ticksslant"); public static FiggleFont Tiles => GetByName("tiles"); public static FiggleFont TinkerToy => GetByName("tinker-toy"); public static FiggleFont Tombstone => GetByName("tombstone"); public static FiggleFont Train => GetByName("train"); public static FiggleFont Trek => GetByName("trek"); public static FiggleFont Tsalagi => GetByName("tsalagi"); public static FiggleFont Tubular => GetByName("tubular"); public static FiggleFont Twisted => GetByName("twisted"); public static FiggleFont TwoPoint => GetByName("twopoint"); public static FiggleFont Univers => GetByName("univers"); public static FiggleFont UsaFlag => GetByName("usaflag"); public static FiggleFont Varsity => GetByName("varsity"); public static FiggleFont Wavy => GetByName("wavy"); public static FiggleFont Weird => GetByName("weird"); public static FiggleFont WetLetter => GetByName("wetletter"); public static FiggleFont Whimsy => GetByName("whimsy"); public static FiggleFont Wow => GetByName("wow"); private static FiggleFont GetByName(string name) { return _fontByName.GetOrAdd(name, FontFactory); static FiggleFont FontFactory(string name) { return ParseEmbeddedFont(name) ?? throw new FiggleException("No embedded font exists with name \"" + name + "\"."); } } public static FiggleFont? TryGetByName(string name) { if (_fontByName.TryGetValue(name, out FiggleFont value)) { return value; } value = ParseEmbeddedFont(name); if (value != null) { _fontByName.TryAdd(name, value); } return value; } private static FiggleFont? ParseEmbeddedFont(string name) { using Stream stream = typeof(FiggleFonts).GetTypeInfo().Assembly.GetManifestResourceStream("Figgle.Fonts.zip"); if (stream == null) { throw new FiggleException("Unable to open embedded font archive."); } using ZipArchive zipArchive = new ZipArchive(stream, ZipArchiveMode.Read); ZipArchiveEntry entry = zipArchive.GetEntry(name + ".flf"); if (entry == null) { return null; } using Stream stream2 = entry.Open(); return FiggleFontParser.Parse(stream2, _stringPool); } } internal static class ParseUtil { public static bool TryParse(string s, out int i) { int num = 0; int num2 = 0; bool flag = false; foreach (char c in s) { switch (num) { case 0: case 1: switch (c) { case '0': num = 2; break; case '-': if (num == 0) { flag = true; num = 1; break; } i = 0; return false; default: if (char.IsDigit(c)) { num2 = c - 48; num = 3; } else if (num != 0 || !char.IsWhiteSpace(c)) { i = 0; return false; } break; } break; case 2: switch (c) { case 'X': case 'h': case 'x': num = 5; break; case ' ': i = 0; return true; default: if (char.IsDigit(c)) { num2 = c - 48; num = 4; break; } i = 0; return false; } break; case 3: if (char.IsDigit(c)) { num2 *= 10; num2 += c - 48; break; } if (char.IsWhiteSpace(c)) { i = (flag ? (-num2) : num2); return true; } i = 0; return false; case 4: { int num5 = c - 48; if (num5 >= 0 && num5 < 8) { num2 *= 8; num2 += num5; break; } if (char.IsWhiteSpace(c)) { i = (flag ? (-num2) : num2); return true; } i = 0; return false; } case 5: case 6: { if (c >= '0' && c <= '9') { num = 6; int num3 = c - 48; num2 *= 16; num2 += num3; break; } char c2 = char.ToLower(c); if (c2 >= 'a' && c <= 'f') { num = 6; int num4 = c2 - 97 + 10; num2 *= 16; num2 += num4; break; } if (num == 6 && char.IsWhiteSpace(c)) { i = (flag ? (-num2) : num2); return true; } i = 0; return false; } } } switch (num) { case 3: case 4: case 6: i = (flag ? (-num2) : num2); return true; case 2: i = 0; return true; default: i = 0; return false; } } } public sealed class StringPool { private readonly Dictionary<string, string> _pool = new Dictionary<string, string>(StringComparer.Ordinal); public string Pool(string s) { lock (_pool) { if (_pool.TryGetValue(s, out string value)) { return value; } _pool[s] = s; return s; } } } }