using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using HarmonyLib;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using MimesisSlotKeys;
using Mimic.Actors;
using Mimic.InputSystem;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(SlotKeysMod), "MimesisSlotKeys", "1.0.0", "vonhoon", null)]
[assembly: MelonGame(null, "MIMESIS")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("MimesisSlotKeys")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("MimesisSlotKeys")]
[assembly: AssemblyTitle("MimesisSlotKeys")]
[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 MimesisSlotKeys
{
public enum EmoteMode
{
Numpad,
ShiftNumber,
CtrlNumber
}
public class SlotKeysMod : MelonMod
{
internal static Instance Log;
private static MelonPreferences_Category _cat;
private static MelonPreferences_Entry<int> _emoteModeEntry;
internal const int KeyCount = 4;
internal const int EmoteCount = 10;
private static InputManager _appliedInputman;
private static EmoteMode _appliedMode;
private static readonly string[] _modeLabels = new string[3] { "Numpad", "Shift + #", "Ctrl + #" };
internal static EmoteMode Mode
{
get
{
int num = ((_emoteModeEntry != null) ? _emoteModeEntry.Value : 0);
if (num < 0 || num > 2)
{
num = 0;
}
return (EmoteMode)num;
}
set
{
if (_emoteModeEntry != null)
{
_emoteModeEntry.Value = (int)value;
MelonPreferences_Category cat = _cat;
if (cat != null)
{
cat.SaveToFile(false);
}
}
_appliedInputman = null;
}
}
public override void OnInitializeMelon()
{
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Expected O, but got Unknown
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_00a7: Expected O, but got Unknown
Log = ((MelonBase)this).LoggerInstance;
_cat = MelonPreferences.CreateCategory("MimesisSlotKeys");
_emoteModeEntry = _cat.CreateEntry<int>("EmoteMode", 0, (string)null, "Emote binding: 0 = Numpad 1-4, 1 = Shift + top-row 1-4, 2 = Ctrl + top-row 1-4. Top-row 1-4 always selects inventory slots 1-4.", false, false, (ValueValidator)null, (string)null);
Type typeFromHandle = typeof(ProtoActor);
((MelonBase)this).HarmonyInstance.Patch((MethodBase)AccessTools.Method(typeFromHandle, "ProcessUISelectKey", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(SlotKeysMod), "InventoryPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
((MelonBase)this).HarmonyInstance.Patch((MethodBase)AccessTools.Method(typeFromHandle, "ProcessEmoteKey", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(SlotKeysMod), "EmotePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
Log.Msg($"Initialized. EmoteMode={Mode}. Top-row 1-4 = inventory slots.");
}
private static InputManager GetInputman()
{
if (!((Object)(object)Hub.s == (Object)null))
{
return Traverse.Create((object)Hub.s).Property("inputman", (object[])null).GetValue<InputManager>();
}
return null;
}
private static MMEmoteTable GetEmoteTable()
{
if ((Object)(object)Hub.s == (Object)null)
{
return null;
}
object value = Traverse.Create((object)Hub.s).Property("tableman", (object[])null).GetValue();
if (value != null)
{
return Traverse.Create(value).Field("emote").GetValue<MMEmoteTable>();
}
return null;
}
private static void ShowEmoteBlockedToast()
{
try
{
object value = Traverse.Create(Traverse.Create((object)Hub.s).Property("tableman", (object[])null).GetValue()).Field("uiprefabs").GetValue();
string value2 = Traverse.Create(typeof(Hub)).Method("GetL10NText", new object[1] { "STRING_DO_NOT_EMOTE" }).GetValue<string>();
Traverse.Create(value).Method("ShowTimerDialog", new object[3] { "ToastSimple", 0f, value2 }).GetValue();
}
catch
{
}
}
private static bool ShiftHeld(Keyboard kb)
{
if (!((ButtonControl)kb.leftShiftKey).isPressed)
{
return ((ButtonControl)kb.rightShiftKey).isPressed;
}
return true;
}
private static bool CtrlHeld(Keyboard kb)
{
if (!((ButtonControl)kb.leftCtrlKey).isPressed)
{
return ((ButtonControl)kb.rightCtrlKey).isPressed;
}
return true;
}
private static bool EmoteModifierHeld(Keyboard kb)
{
return Mode switch
{
EmoteMode.ShiftNumber => ShiftHeld(kb),
EmoteMode.CtrlNumber => CtrlHeld(kb),
_ => false,
};
}
private static KeyControl Digit(Keyboard kb, int i)
{
return (KeyControl)(i switch
{
0 => kb.digit1Key,
1 => kb.digit2Key,
2 => kb.digit3Key,
_ => kb.digit4Key,
});
}
private static void EnsureEmoteBindings(InputManager im)
{
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)im == (Object)null || (Object)(object)im.data == (Object)null || im.data.data == null)
{
return;
}
EmoteMode mode = Mode;
if (im == _appliedInputman && mode == _appliedMode)
{
return;
}
foreach (Mapping datum in im.data.data)
{
int num = EmoteActionIndex(datum.action);
if (num < 1 || num > 10)
{
continue;
}
HashSet<string> hashSet = SplitKeys(datum.keys);
string item = "k_num" + ((num != 10) ? num : 0);
if (num <= 4)
{
hashSet.Clear();
if (mode == EmoteMode.Numpad)
{
hashSet.Add(item);
}
}
else
{
if (mode != EmoteMode.Numpad)
{
continue;
}
hashSet.Add(item);
}
datum.keys = string.Join(",", hashSet);
}
im.RefreshInputAssign();
_appliedInputman = im;
_appliedMode = mode;
Instance log = Log;
if (log != null)
{
log.Msg($"Applied emote bindings for mode {mode}.");
}
}
private static HashSet<string> SplitKeys(string keys)
{
HashSet<string> hashSet = new HashSet<string>();
if (string.IsNullOrEmpty(keys))
{
return hashSet;
}
string[] array = keys.Split(',');
for (int i = 0; i < array.Length; i++)
{
string text = array[i].Trim();
if (text.Length > 0)
{
hashSet.Add(text);
}
}
return hashSet;
}
private static int EmoteActionIndex(InputAction a)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0002: Expected I4, but got Unknown
int num = (int)a;
if (num < 21 || num > 30)
{
return 0;
}
return num - 20;
}
private static void InventoryPostfix(ProtoActor __instance)
{
try
{
EnsureEmoteBindings(GetInputman());
Keyboard current = Keyboard.current;
if (current == null)
{
return;
}
bool flag = Mode != EmoteMode.Numpad;
bool flag2 = flag && EmoteModifierHeld(current);
for (int i = 0; i < 4; i++)
{
if (((ButtonControl)Digit(current, i)).wasPressedThisFrame && !(flag && flag2))
{
SelectInventorySlot(__instance, i);
}
}
}
catch (Exception ex)
{
Instance log = Log;
if (log != null)
{
log.Error("InventoryPostfix: " + ex);
}
}
}
private static void EmotePostfix(ProtoActor __instance)
{
try
{
if (Mode == EmoteMode.Numpad)
{
return;
}
Keyboard current = Keyboard.current;
if (current == null || !EmoteModifierHeld(current))
{
return;
}
for (int i = 0; i < 4; i++)
{
if (((ButtonControl)Digit(current, i)).wasPressedThisFrame)
{
TriggerEmote(__instance, i + 1);
break;
}
}
}
catch (Exception ex)
{
Instance log = Log;
if (log != null)
{
log.Error("EmotePostfix: " + ex);
}
}
}
private static void SelectInventorySlot(ProtoActor actor, int index)
{
Traverse val = Traverse.Create((object)actor);
object value = val.Field("inventory").GetValue();
if (value == null)
{
return;
}
Traverse val2 = Traverse.Create(value);
int num = 0;
Traverse val3 = val2.Field("slotSize");
if (val3.FieldExists())
{
num = val3.GetValue<int>();
}
if (num <= 0 || index < num)
{
object value2 = val.Property("main", (object[])null).GetValue();
if (value2 != null)
{
Traverse.Create(value2).Method("TryPerformInteractionEnd", Array.Empty<object>()).GetValue();
}
val2.Method("SelectSlot", new object[1] { index }).GetValue();
}
}
private static void TriggerEmote(ProtoActor actor, int emoteNumber)
{
//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_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
Traverse val = Traverse.Create((object)actor);
Traverse val2 = val.Field("movementInput");
if (val2.FieldExists())
{
Vector2 value = val2.GetValue<Vector2>();
if (((Vector2)(ref value)).sqrMagnitude > 0f)
{
return;
}
}
EmotePlayer value2 = val.Field("emotePlayer").GetValue<EmotePlayer>();
if (value2 == null)
{
return;
}
if (value2.IsEmoteDisabledByHandheldItem())
{
ShowEmoteBlockedToast();
return;
}
MMEmoteTable emoteTable = GetEmoteTable();
InputAction val3 = (InputAction)(20 + emoteNumber);
Emote val4 = default(Emote);
if ((Object)(object)emoteTable != (Object)null && emoteTable.TryGetEmote(val3, ref val4) && val4 != null)
{
value2.SendStartEmote(val4.emoteMasterID);
}
}
public override void OnGUI()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
Scene activeScene = SceneManager.GetActiveScene();
if (!(((Scene)(ref activeScene)).name != "MainMenuScene"))
{
GUILayout.BeginArea(new Rect((float)Screen.width - 250f - 16f, (float)Screen.height - 84f - 56f, 250f, 84f), GUI.skin.box);
GUILayout.Label("Emote keys (top-row 1-4 = inventory)", Array.Empty<GUILayoutOption>());
int mode = (int)Mode;
int num = GUILayout.Toolbar(mode, _modeLabels, Array.Empty<GUILayoutOption>());
if (num != mode)
{
Mode = (EmoteMode)num;
}
GUILayout.EndArea();
}
}
}
}