using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: AssemblyCompany("CustomTranslatorCharLimit")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("A template for Lethal Company")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2+43206f0475d7dae18e393eaa115cfd192399712f")]
[assembly: AssemblyProduct("CustomTranslatorCharLimit")]
[assembly: AssemblyTitle("CustomTranslatorCharLimit")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.2.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[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 CustomTranslatorCharLimit
{
[BepInPlugin("CustomTranslatorCharLimit", "CustomTranslatorCharLimit", "1.0.2")]
public class Plugin : BaseUnityPlugin
{
private readonly Harmony harmony = new Harmony("CustomTranslatorCharLimit");
private static Plugin Instance;
public static ManualLogSource Logger;
public static ConfigEntry<int> MaxCharLength;
public static ConfigEntry<float> MinSecondsToWait;
public static ConfigEntry<float> MaxSecondsToWait;
public static ConfigEntry<float> SecondsToWait;
public static ConfigEntry<bool> UseRNG;
public static ConfigEntry<bool> AllowSpecialCharacters;
private void Awake()
{
if ((Object)(object)Instance == (Object)null)
{
Instance = this;
}
Logger = ((BaseUnityPlugin)this).Logger;
Logger.LogInfo((object)"Plugin CustomTranslatorCharLimit is loaded!");
MaxCharLength = ((BaseUnityPlugin)this).Config.Bind<int>("General", "MaxCharLength", 10, "Maximum number of characters to be able to transmit with the Signal Translator");
MinSecondsToWait = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MinSecondsToWait", 0.7f, "Minimum number of seconds to potentially wait before sending another message");
MaxSecondsToWait = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MaxSecondsToWait", 2.7f, "Maximum number of seconds to potentially wait before sending another character");
SecondsToWait = ((BaseUnityPlugin)this).Config.Bind<float>("General", "SecondsToWait", 0.7f, "Number of seconds to constantly wait before sending another character (RNG must be false for this)");
UseRNG = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "UseRNG", true, "Use RNG to determine how long to wait before sending another character");
AllowSpecialCharacters = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AllowSpecialCharacters", true, "Allow special characters (e.g. !@#$%^&*():) to be used in the terminal");
harmony.PatchAll(Assembly.GetExecutingAssembly());
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "CustomTranslatorCharLimit";
public const string PLUGIN_NAME = "CustomTranslatorCharLimit";
public const string PLUGIN_VERSION = "1.0.2";
}
}
namespace CustomTranslatorCharLimit.Patches
{
[HarmonyPatch]
internal class PatchHUDManger
{
[HarmonyPatch(typeof(HUDManager), "UseSignalTranslatorServerRpc")]
[HarmonyTranspiler]
public static IEnumerable<CodeInstruction> Patch(IEnumerable<CodeInstruction> codes)
{
return codes.Select(delegate(CodeInstruction code)
{
if (code.opcode == OpCodes.Ldc_I4_S && (sbyte)code.operand == 12)
{
code.opcode = OpCodes.Ldc_I4;
code.operand = Plugin.MaxCharLength.Value + 2;
}
return code;
});
}
[HarmonyPatch(typeof(HUDManager), "UseSignalTranslatorClientRpc")]
[HarmonyTranspiler]
public static IEnumerable<CodeInstruction> PatchUseSignalTranslatorClientRpc(IEnumerable<CodeInstruction> codes)
{
return codes.Select(delegate(CodeInstruction code)
{
if (code.opcode == OpCodes.Ldc_I4_S && (sbyte)code.operand == 10)
{
code.opcode = OpCodes.Ldc_I4;
code.operand = Plugin.MaxCharLength.Value;
}
return code;
});
}
[HarmonyPatch(/*Could not decode attribute arguments.*/)]
[HarmonyTranspiler]
public static IEnumerable<CodeInstruction> TranspileMoveNext(IEnumerable<CodeInstruction> codes)
{
List<CodeInstruction> list = codes.ToList();
if (Plugin.MinSecondsToWait.Value != 0.7f && Plugin.UseRNG.Value)
{
int num = list.FindIndex((CodeInstruction code) => code.opcode == OpCodes.Ldc_R4 && (float)code.operand == 0.7f);
if (num == -1)
{
Plugin.Logger.LogError((object)"HUDManager::DisplaySignalTranslatorMessage: Could not find index of ldc.r4 0.7!");
return list.AsEnumerable();
}
list[num].operand = Plugin.MinSecondsToWait.Value;
}
if (Plugin.MaxSecondsToWait.Value != 2.7f && Plugin.UseRNG.Value)
{
int num2 = list.FindIndex((CodeInstruction code) => code.opcode == OpCodes.Ldc_I4_M1) + 1;
while (true)
{
num2 = list.FindIndex(num2 + 1, (CodeInstruction code) => code.opcode == OpCodes.Ldc_I4_M1) + 1;
if (num2 != -1 && list[num2].opcode == OpCodes.Ldc_I4_4)
{
break;
}
if (num2 == -1)
{
Plugin.Logger.LogError((object)"HUDManager::DisplaySignalTranslatorMessage: Could not find index of ldc.i4.m1!");
return list.AsEnumerable();
}
}
float num3 = (Plugin.MaxSecondsToWait.Value - Plugin.MinSecondsToWait.Value) * 2f;
float num4 = 0f - num3 / 2f;
if (num3 < 0f - num4)
{
num3 = 0f - num4;
}
list[num2 - 1].opcode = OpCodes.Ldc_I4;
list[num2 - 1].operand = Mathf.RoundToInt(num4);
list[num2].opcode = OpCodes.Ldc_I4;
list[num2].operand = Mathf.RoundToInt(num3);
}
if (!Plugin.UseRNG.Value && Plugin.SecondsToWait.Value != 0.7f)
{
int num5 = list.FindIndex((CodeInstruction code) => code.opcode == OpCodes.Ldc_R4 && (float)code.operand == 0.7f);
if (num5 == -1)
{
return list.AsEnumerable();
}
list[num5].operand = Plugin.SecondsToWait.Value;
list[num5 + 1].opcode = OpCodes.Ldc_R4;
list[num5 + 1].operand = 0f;
}
return list.AsEnumerable();
}
}
[HarmonyPatch]
internal class PatchTerminal
{
[HarmonyPatch(typeof(Terminal), "ParsePlayerSentence")]
[HarmonyTranspiler]
public static IEnumerable<CodeInstruction> PatchParsePlayerSentence(IEnumerable<CodeInstruction> codes)
{
List<CodeInstruction> list = codes.ToList();
int index = list.FindIndex((CodeInstruction code) => code.opcode == OpCodes.Call && code.operand.ToString().Contains("Min")) - 1;
list[index].opcode = OpCodes.Ldc_I4;
list[index].operand = ((Plugin.MaxCharLength.Value == 0) ? 10 : Plugin.MaxCharLength.Value);
return list.AsEnumerable();
}
[HarmonyPatch(typeof(Terminal), "Start")]
[HarmonyPostfix]
public static void PatchStart(Terminal __instance)
{
foreach (TerminalNode specialNode in __instance.terminalNodes.specialNodes)
{
if ((((Object)specialNode).name == "Start" || ((Object)specialNode).name == "HelpCommands" || ((Object)specialNode).name == "ParserError1" || ((Object)specialNode).name == "SendSignalTranslator") && specialNode.maxCharactersToType <= 35)
{
specialNode.maxCharactersToType = 9999;
}
}
}
[HarmonyPatch(typeof(Terminal), "RemovePunctuation")]
[HarmonyPrefix]
public static bool PatchRemovePunctuation(ref string __result, string s)
{
if (Plugin.AllowSpecialCharacters.Value)
{
__result = s;
return false;
}
return true;
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}