diff --git a/.gitignore b/.gitignore
index c24589a..608c619 100644
--- a/.gitignore
+++ b/.gitignore
@@ -79,3 +79,7 @@ ModelManifest.xml
.vs
.vscode
+
+# JetBrains Rider
+*.sln.iml
+.idea
diff --git a/CSharpManager/CSharpManager.csproj b/CSharpManager/CSharpManager.csproj
index 9ec4149..20ff991 100644
--- a/CSharpManager/CSharpManager.csproj
+++ b/CSharpManager/CSharpManager.csproj
@@ -1,24 +1,25 @@
-
- Exe
- net472
- enable
- True
- latest
- 0.0.6.0
-
+
+ Exe
+ net472
+ enable
+ latest
+ true
+ True
+ 0.0.6.0
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
diff --git a/CSharpManager/CSharpModManager.cs b/CSharpManager/CSharpModManager.cs
index c9c28ff..56ea48f 100644
--- a/CSharpManager/CSharpModManager.cs
+++ b/CSharpManager/CSharpModManager.cs
@@ -1,175 +1,181 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
using System.Reflection;
-using System.Threading;
-using System.Threading.Tasks;
using CSharpModBase;
using CSharpModBase.Input;
using Mono.Cecil;
+using static CSharpModBase.Common;
-namespace CSharpManager
+namespace CSharpManager;
+
+public class CSharpModManager
{
- public class CSharpModManager
- {
- static string? LoadingModName { get; set; }
+ private Thread? _loopThread;
+ private static string? LoadingModName { get; set; }
- public List LoadedMods { get; } = new();
- public InputManager InputManager { get; } = new();
- public bool Develop { get; set; }
- private Thread? loopThread;
+ public List LoadedMods { get; } = [];
+ public InputManager InputManager { get; } = new();
+ public bool Develop { get; set; }
- static CSharpModManager()
- {
- AppDomain currentDomain = AppDomain.CurrentDomain;
- currentDomain.AssemblyResolve += AssemblyResolve;
- currentDomain.UnhandledException += OnUnhandledException;
+ static CSharpModManager()
+ {
+ var currentDomain = AppDomain.CurrentDomain;
+ currentDomain.AssemblyResolve += AssemblyResolve;
+ currentDomain.UnhandledException += OnUnhandledException;
- TaskScheduler.UnobservedTaskException += OnUnobservedTaskException;
- }
+ TaskScheduler.UnobservedTaskException += OnUnobservedTaskException;
+ }
- private static Assembly? TryLoadDll(string path)
+ public CSharpModManager()
+ {
+ Utils.InitInputManager(InputManager);
+ // load config from ini
+ Ini iniFile = new(Path.Combine(LoaderDir, "b1cs.ini"));
+ Develop = iniFile.GetValue("Develop", "Settings", "1").Trim() == "1";
+ Log.Debug($"Develop: {Develop}");
+ }
+
+ private static Assembly? TryLoadDll(string path)
+ {
+ if (File.Exists(path))
{
- if (File.Exists(path))
- {
- return Assembly.LoadFrom(path);
- }
- return null;
+ return Assembly.LoadFrom(path);
}
- private static Assembly? AssemblyResolve(object sender, ResolveEventArgs args)
+ return null;
+ }
+
+ private static Assembly? AssemblyResolve(object sender, ResolveEventArgs args)
+ {
+ try
{
- try
+ if (LoadingModName == null)
{
- if (LoadingModName == null)
- {
- return null;
- }
- string dllName = $"{new AssemblyName(args.Name).Name}.dll";
- return TryLoadDll(Path.Combine(Common.ModDir, LoadingModName, dllName)) ??
- TryLoadDll(Path.Combine(Common.ModDir, "Common", dllName)) ??
- TryLoadDll(Path.Combine(Common.LoaderDir, dllName));
+ return null;
}
- catch (Exception e)
- {
- Log.Error($"Load assembly {args.Name} failed:");
- Log.Error(e);
- }
- return Assembly.Load(args.Name);
- }
- private static void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
- {
- Log.Error($"UnhandledException:");
- Log.Error((Exception)e.ExceptionObject);
+ var dllName = $"{new AssemblyName(args.Name).Name}.dll";
+ return TryLoadDll(Path.Combine(ModDir, LoadingModName, dllName)) ??
+ TryLoadDll(Path.Combine(ModDir, "CommonDirs", dllName)) ??
+ TryLoadDll(Path.Combine(LoaderDir, dllName));
}
-
- private static void OnUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
+ catch (Exception e)
{
- Log.Error($"UnobservedTaskException:");
- Log.Error(e.Exception);
+ Log.Error($"Load assembly {args.Name} failed:");
+ Log.Error(e);
}
- public CSharpModManager()
+ return Assembly.Load(args.Name);
+ }
+
+ private static void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
+ {
+ Log.Error("UnhandledException:");
+ Log.Error((Exception)e.ExceptionObject);
+ }
+
+ private static void OnUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
+ {
+ Log.Error("UnobservedTaskException:");
+ Log.Error(e.Exception);
+ }
+
+ public void LoadMods()
+ {
+ LoadedMods.Clear();
+ if (!Directory.Exists(ModDir))
{
- Utils.InitInputManager(InputManager);
- // load config from ini
- Ini iniFile = new(Path.Combine(Common.LoaderDir, "b1cs.ini"));
- Develop = iniFile.GetValue("Develop", "Settings", "1").Trim() == "1";
- Log.Debug($"Develop: {Develop}");
+ Log.Error($"Mod dir {ModDir} not exists");
+ return;
}
- public void LoadMods()
+ string[] dirs = Directory.GetDirectories(ModDir);
+ var ICSharpModType = typeof(ICSharpMod);
+ foreach (var dir in dirs)
{
- LoadedMods.Clear();
- if (!Directory.Exists(Common.ModDir))
+ LoadingModName = Path.GetFileName(dir);
+ var dllPath = Path.Combine(dir, $"{LoadingModName}.dll");
+ if (!File.Exists(dllPath))
{
- Log.Error($"Mod dir {Common.ModDir} not exists");
- return;
+ continue;
}
- string[] dirs = Directory.GetDirectories(Common.ModDir);
- Type ICSharpModType = typeof(ICSharpMod);
- foreach (var dir in dirs)
+
+ try
{
- LoadingModName = Path.GetFileName(dir);
- string dllPath = Path.Combine(dir, $"{LoadingModName}.dll");
- if (!File.Exists(dllPath)) continue;
- try
+ Log.Debug($"======== Loading {dllPath} ========");
+ Assembly assembly;
+ if (Develop)
{
- Log.Debug($"======== Loading {dllPath} ========");
- Assembly assembly;
- if (Develop)
- {
- using var assemblyDef = AssemblyDefinition.ReadAssembly(dllPath);
- assemblyDef.Name.Name += DateTime.Now.ToString("_yyyyMMdd_HHmmssffff");
- using MemoryStream stream = new();
- assemblyDef.Write(stream);
- assembly = Assembly.Load(stream.GetBuffer());
- }
- else
- {
- assembly = Assembly.LoadFrom(dllPath);
- }
- foreach (Type type in assembly.GetTypes())
+ using var assemblyDef = AssemblyDefinition.ReadAssembly(dllPath);
+ assemblyDef.Name.Name += DateTime.Now.ToString("_yyyyMMdd_HHmmssffff");
+ using MemoryStream stream = new();
+ assemblyDef.Write(stream);
+ assembly = Assembly.Load(stream.GetBuffer());
+ }
+ else
+ {
+ assembly = Assembly.LoadFrom(dllPath);
+ }
+
+ foreach (var type in assembly.GetTypes())
+ {
+ if (ICSharpModType.IsAssignableFrom(type))
{
- if (ICSharpModType.IsAssignableFrom(type))
+ Log.Debug($"Found ICSharpMod: {type}");
+
+ if (Activator.CreateInstance(type) is ICSharpMod mod)
{
- Log.Debug($"Found ICSharpMod: {type}");
-
- if (Activator.CreateInstance(type) is ICSharpMod mod)
- {
- mod.Init();
- LoadedMods.Add(mod);
- Log.Debug($"Loaded mod {mod.Name} {mod.Version}");
- }
+ mod.Init();
+ LoadedMods.Add(mod);
+ Log.Debug($"Loaded mod {mod.Name} {mod.Version}");
}
}
- LoadingModName = null;
- }
- catch (Exception e)
- {
- Log.Error($"Load {dllPath} failed:");
- Log.Error(e);
}
+
+ LoadingModName = null;
+ }
+ catch (Exception e)
+ {
+ Log.Error($"Load {dllPath} failed:");
+ Log.Error(e);
}
}
+ }
- public void ReloadMods()
+ public void ReloadMods()
+ {
+ Log.Debug("ReloadMods");
+ InputManager.Clear();
+ foreach (var mod in LoadedMods)
{
- Log.Debug("ReloadMods");
- InputManager.Clear();
- foreach (var mod in LoadedMods)
+ try
{
- try
- {
- mod.DeInit();
- }
- catch (Exception e)
- {
- Log.Error($"DeInit {mod.Name} failed:");
- Log.Error(e);
- }
+ mod.DeInit();
+ }
+ catch (Exception e)
+ {
+ Log.Error($"DeInit {mod.Name} failed:");
+ Log.Error(e);
}
- LoadMods();
}
- public void StartLoop()
+ LoadMods();
+ }
+
+ public void StartLoop()
+ {
+ InputManager.RegisterBuiltinKeyBind(ModifierKeys.Control, Key.F5, ReloadMods);
+ _loopThread = new Thread(Loop)
{
- InputManager.RegisterBuiltinKeyBind(ModifierKeys.Control, Key.F5, ReloadMods);
- loopThread = new Thread(Loop)
- {
- // IsBackground = true,
- };
- loopThread.Start();
- }
+ // IsBackground = true,
+ };
+ _loopThread.Start();
+ }
- private void Loop()
+ private void Loop()
+ {
+ while (true)
{
- while (true)
- {
- InputManager.Update();
- Thread.Sleep(10); // 10ms
- }
+ InputManager.Update();
+ Thread.Sleep(10); // 10ms
}
}
-}
+}
\ No newline at end of file
diff --git a/CSharpManager/Ini.cs b/CSharpManager/Ini.cs
index e19d41c..d342f20 100644
--- a/CSharpManager/Ini.cs
+++ b/CSharpManager/Ini.cs
@@ -1,96 +1,92 @@
-// https://gist.github.com/Larry57/5725301
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
using System.Text;
+namespace CSharpManager;
+
public class Ini
{
- Dictionary> ini = new Dictionary>(StringComparer.InvariantCultureIgnoreCase);
- string file;
+ private readonly string _file;
+ private readonly Dictionary> _ini = new(StringComparer.InvariantCultureIgnoreCase);
///
- /// Initialize an INI file
- /// Load it if it exists
+ /// Initialize an INI file
+ /// Load it if it exists
///
/// Full path where the INI file has to be read from or written to
public Ini(string file)
{
- this.file = file;
+ _file = file;
if (!File.Exists(file))
+ {
return;
+ }
Load();
}
///
- /// Load the INI file content
+ /// Load the INI file content
///
public void Load()
{
- var txt = File.ReadAllText(file);
+ var txt = File.ReadAllText(_file);
- Dictionary currentSection = new Dictionary(StringComparer.InvariantCultureIgnoreCase);
+ Dictionary currentSection = new(StringComparer.InvariantCultureIgnoreCase);
- ini[""] = currentSection;
+ _ini[""] = currentSection;
foreach (var l in txt.Split(new[] { "\n" }, StringSplitOptions.RemoveEmptyEntries)
- .Select((t, i) => new
- {
- idx = i,
- text = t.Trim()
- }))
- // .Where(t => !string.IsNullOrWhiteSpace(t) && !t.StartsWith(";")))
+ .Select((t, i) => new
+ {
+ idx = i,
+ text = t.Trim()
+ }))
+ // .Where(t => !string.IsNullOrWhiteSpace(t) && !t.StartsWith(";")))
{
var line = l.text;
if (line.StartsWith(";") || string.IsNullOrWhiteSpace(line))
{
- currentSection.Add(";" + l.idx.ToString(), line);
+ currentSection.Add(";" + l.idx, line);
continue;
}
if (line.StartsWith("[") && line.EndsWith("]"))
{
currentSection = new Dictionary(StringComparer.InvariantCultureIgnoreCase);
- ini[line.Substring(1, line.Length - 2)] = currentSection;
+ _ini[line.Substring(1, line.Length - 2)] = currentSection;
continue;
}
- var idx = line.IndexOf("=");
+ var idx = line.IndexOf("=", StringComparison.Ordinal);
if (idx == -1)
+ {
currentSection[line] = "";
+ }
else
+ {
currentSection[line.Substring(0, idx)] = line.Substring(idx + 1);
+ }
}
}
///
- /// Get a parameter value at the root level
+ /// Get a parameter value at the root level
///
/// parameter key
///
- public string GetValue(string key)
- {
- return GetValue(key, "", "");
- }
+ public string GetValue(string key) => GetValue(key, "", "");
///
- /// Get a parameter value in the section
+ /// Get a parameter value in the section
///
/// parameter key
/// section
///
- public string GetValue(string key, string section)
- {
- return GetValue(key, section, "");
- }
+ public string GetValue(string key, string section) => GetValue(key, section, "");
///
- /// Returns a parameter value in the section, with a default value if not found
+ /// Returns a parameter value in the section, with a default value if not found
///
/// parameter key
/// section
@@ -98,22 +94,26 @@ public string GetValue(string key, string section)
///
public string GetValue(string key, string section, string @default)
{
- if (!ini.ContainsKey(section))
+ if (!_ini.TryGetValue(section, out var value))
+ {
return @default;
+ }
- if (!ini[section].ContainsKey(key))
+ if (!value.ContainsKey(key))
+ {
return @default;
+ }
- return ini[section][key];
+ return _ini[section][key];
}
///
- /// Save the INI file
+ /// Save the INI file
///
public void Save()
{
var sb = new StringBuilder();
- foreach (var section in ini)
+ foreach (var section in _ini)
{
if (section.Key != "")
{
@@ -135,27 +135,31 @@ public void Save()
}
}
- if (!endWithCRLF(sb))
+ if (!EndWithCrlf(sb))
+ {
sb.AppendLine();
+ }
}
- File.WriteAllText(file, sb.ToString());
+ File.WriteAllText(_file, sb.ToString());
}
- bool endWithCRLF(StringBuilder sb)
+ private static bool EndWithCrlf(StringBuilder sb)
{
if (sb.Length < 4)
+ {
return sb[sb.Length - 2] == '\r' &&
sb[sb.Length - 1] == '\n';
- else
- return sb[sb.Length - 4] == '\r' &&
- sb[sb.Length - 3] == '\n' &&
- sb[sb.Length - 2] == '\r' &&
- sb[sb.Length - 1] == '\n';
+ }
+
+ return sb[sb.Length - 4] == '\r' &&
+ sb[sb.Length - 3] == '\n' &&
+ sb[sb.Length - 2] == '\r' &&
+ sb[sb.Length - 1] == '\n';
}
///
- /// Write a parameter value at the root level
+ /// Write a parameter value at the root level
///
/// parameter key
/// parameter value
@@ -165,7 +169,7 @@ public void WriteValue(string key, string value)
}
///
- /// Write a parameter value in a section
+ /// Write a parameter value in a section
///
/// parameter key
/// section
@@ -173,36 +177,40 @@ public void WriteValue(string key, string value)
public void WriteValue(string key, string section, string value)
{
Dictionary currentSection;
- if (!ini.ContainsKey(section))
+ if (!_ini.ContainsKey(section))
{
currentSection = new Dictionary();
- ini.Add(section, currentSection);
+ _ini.Add(section, currentSection);
}
else
- currentSection = ini[section];
+ {
+ currentSection = _ini[section];
+ }
currentSection[key] = value;
}
///
- /// Get all the keys names in a section
+ /// Get all the keys names in a section
///
/// section
///
public string[] GetKeys(string section)
{
- if (!ini.ContainsKey(section))
- return new string[0];
+ if (!_ini.TryGetValue(section, out var value))
+ {
+ return [];
+ }
- return ini[section].Keys.ToArray();
+ return value.Keys.ToArray();
}
///
- /// Get all the section names of the INI file
+ /// Get all the section names of the INI file
///
///
public string[] GetSections()
{
- return ini.Keys.Where(t => t != "").ToArray();
+ return _ini.Keys.Where(t => t != "").ToArray();
}
-}
+}
\ No newline at end of file
diff --git a/CSharpManager/InputManager.cs b/CSharpManager/InputManager.cs
index 70e97d6..d8846e4 100644
--- a/CSharpManager/InputManager.cs
+++ b/CSharpManager/InputManager.cs
@@ -1,177 +1,180 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
-using System.Threading;
using CSharpModBase;
using CSharpModBase.Input;
-namespace CSharpManager
+namespace CSharpManager;
+
+public class InputManager : IInputManager
{
- public class InputManager : IInputManager
+ // public static GamePadButtonEventHandler? GamePadButtonDown { get; set; }
+
+ private IntPtr HWnd;
+ public List BuiltinHotKeyItems { get; } = [];
+ public List HotKeyItems { get; } = [];
+ public bool EnableGamePad { get; set; } = true;
+ public static GamePadButton CurrentGamePadButton { get; set; }
+
+ public HotKeyItem RegisterKeyBind(Key key, Action action)
{
- public List BuiltinHotKeyItems { get; } = new();
- public List HotKeyItems { get; } = new();
- public bool EnableGamePad { get; set; } = true;
- public static GamePadButton CurrentGamePadButton { get; set; }
- // public static GamePadButtonEventHandler? GamePadButtonDown { get; set; }
+ var item = new HotKeyItem(ModifierKeys.None, key, action);
+ RegisterKeyBind(item);
+ return item;
+ }
- private IntPtr HWnd;
+ public HotKeyItem RegisterKeyBind(ModifierKeys modifiers, Key key, Action action)
+ {
+ var item = new HotKeyItem(modifiers, key, action);
+ RegisterKeyBind(item);
+ return item;
+ }
- public InputManager()
+ public HotKeyItem RegisterGamePadBind(GamePadButton button, Action action)
+ {
+ var item = new HotKeyItem(ModifierKeys.None, Key.None, action)
{
- }
+ GamePadButton = button
+ };
+ RegisterKeyBind(item);
+ return item;
+ }
- private void FindMainWindow()
+ private void FindMainWindow()
+ {
+ var currentProcessId = GetCurrentProcessId();
+ StringBuilder stringBuilder = new(64);
+ EnumWindows((hWnd, lParam) =>
{
- uint currentProcessId = GetCurrentProcessId();
- StringBuilder stringBuilder = new(64);
- EnumWindows(new EnumWindowsProc((hWnd, lParam) =>
+ GetWindowThreadProcessId(hWnd, out var processId);
+ if (processId == GetCurrentProcessId() &&
+ GetClassName(hWnd, stringBuilder, stringBuilder.Capacity) > 0 &&
+ stringBuilder.ToString() == "UnrealWindow")
{
- GetWindowThreadProcessId(hWnd, out uint processId);
- if (processId == GetCurrentProcessId() &&
- GetClassName(hWnd, stringBuilder, stringBuilder.Capacity) > 0 &&
- stringBuilder.ToString() == "UnrealWindow")
- {
- HWnd = hWnd;
- return false;
- }
- return true; // 继续枚举
- }), IntPtr.Zero);
- }
+ HWnd = hWnd;
+ return false;
+ }
+
+ return true; // 继续枚举
+ }, IntPtr.Zero);
+ }
- private void HandleKeys(List items)
+ private void HandleKeys(List items)
+ {
+ var now = DateTime.Now.Ticks / 10000;
+ var modifiers = KeyUtils.Modifiers;
+ foreach (var item in items)
{
- var now = DateTime.Now.Ticks / 10000;
- var modifiers = KeyUtils.Modifiers;
- foreach (var item in items)
+ if ((item.Modifiers == modifiers && KeyUtils.IsKeyDown(item.Key)) ||
+ (CurrentGamePadButton != GamePadButton.None && item.GamePadButton != GamePadButton.None && CurrentGamePadButton.HasFlag(item.GamePadButton)))
{
- if (item.Modifiers == modifiers && KeyUtils.IsKeyDown(item.Key) ||
- CurrentGamePadButton != GamePadButton.None && item.GamePadButton != GamePadButton.None && CurrentGamePadButton.HasFlag(item.GamePadButton))
+ if (item.IsPressed && (item.RepeatMs == 0 || (item.LastTriggerMs > 0 && now - item.LastTriggerMs < item.RepeatMs)))
{
- if (item.IsPressed && (item.RepeatMs == 0 || item.LastTriggerMs > 0 && now - item.LastTriggerMs < item.RepeatMs))
- {
- continue;
- }
- item.IsPressed = true;
- if (item.RunOnGameThread)
- {
- Utils.TryRunOnGameThread(item.Action);
- }
- else
- {
- Utils.TryRun(item.Action);
- }
+ continue;
}
- else if (item.IsPressed)
+
+ item.IsPressed = true;
+ if (item.RunOnGameThread)
{
- item.IsPressed = false;
+ Utils.TryRunOnGameThread(item.Action);
+ }
+ else
+ {
+ Utils.TryRun(item.Action);
}
}
- }
-
- public void Update()
- {
- if (!IsProgramFocused()) return;
- if (EnableGamePad)
- {
- GamePadUtils.GetGamePadButtons(out var buttons);
- // if (buttons != GamePadButton.None)
- // {
- // GamePadButtonDown?.Invoke(new GamePadButtonEvent { Button = buttons });
- // }
- CurrentGamePadButton = buttons;
- }
- HandleKeys(BuiltinHotKeyItems);
- lock (HotKeyItems)
+ else if (item.IsPressed)
{
- HandleKeys(HotKeyItems);
+ item.IsPressed = false;
}
}
+ }
- public void Clear()
+ public void Update()
+ {
+ if (!IsProgramFocused())
{
- lock (HotKeyItems)
- {
- HotKeyItems.Clear();
- }
+ return;
}
- public bool IsProgramFocused()
+ if (EnableGamePad)
{
- if (HWnd == IntPtr.Zero)
- {
- Thread.Sleep(1000);
- FindMainWindow();
- }
- var hwnd = GetForegroundWindow();
- if (hwnd == IntPtr.Zero) return false;
- return hwnd == HWnd;
+ GamePadUtils.GetGamePadButtons(out var buttons);
+ // if (buttons != GamePadButton.None)
+ // {
+ // GamePadButtonDown?.Invoke(new GamePadButtonEvent { Button = buttons });
+ // }
+ CurrentGamePadButton = buttons;
}
- [DllImport("user32.dll")]
- private extern static IntPtr GetForegroundWindow();
-
- [DllImport("user32.dll", SetLastError = true)]
- static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
-
- [DllImport("kernel32.dll")]
- static extern uint GetCurrentProcessId();
-
- private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
-
- // 导入Win32 API函数
- [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
- private static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
-
- [DllImport("user32.dll", CharSet = CharSet.Unicode)]
- public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
-
- public HotKeyItem RegisterBuiltinKeyBind(Key key, Action action)
+ HandleKeys(BuiltinHotKeyItems);
+ lock (HotKeyItems)
{
- var item = new HotKeyItem(ModifierKeys.None, key, action);
- BuiltinHotKeyItems.Add(item);
- return item;
+ HandleKeys(HotKeyItems);
}
+ }
- public HotKeyItem RegisterBuiltinKeyBind(ModifierKeys modifiers, Key key, Action action)
+ public void Clear()
+ {
+ lock (HotKeyItems)
{
- var item = new HotKeyItem(modifiers, key, action);
- BuiltinHotKeyItems.Add(item);
- return item;
+ HotKeyItems.Clear();
}
+ }
- public void RegisterKeyBind(HotKeyItem item)
+ public bool IsProgramFocused()
+ {
+ if (HWnd == IntPtr.Zero)
{
- lock (HotKeyItems)
- {
- HotKeyItems.Add(item);
- }
+ Thread.Sleep(1000);
+ FindMainWindow();
}
- public HotKeyItem RegisterKeyBind(Key key, Action action)
+ var hwnd = GetForegroundWindow();
+ if (hwnd == IntPtr.Zero)
{
- var item = new HotKeyItem(ModifierKeys.None, key, action);
- RegisterKeyBind(item);
- return item;
+ return false;
}
- public HotKeyItem RegisterKeyBind(ModifierKeys modifiers, Key key, Action action)
- {
- var item = new HotKeyItem(modifiers, key, action);
- RegisterKeyBind(item);
- return item;
- }
+ return hwnd == HWnd;
+ }
+
+ [DllImport("user32.dll")]
+ private static extern IntPtr GetForegroundWindow();
+
+ [DllImport("user32.dll", SetLastError = true)]
+ private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
+
+ [DllImport("kernel32.dll")]
+ private static extern uint GetCurrentProcessId();
- public HotKeyItem RegisterGamePadBind(GamePadButton button, Action action)
+ // 导入Win32 API函数
+ [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
+ private static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
+
+ [DllImport("user32.dll", CharSet = CharSet.Unicode)]
+ public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
+
+ public HotKeyItem RegisterBuiltinKeyBind(Key key, Action action)
+ {
+ var item = new HotKeyItem(ModifierKeys.None, key, action);
+ BuiltinHotKeyItems.Add(item);
+ return item;
+ }
+
+ public HotKeyItem RegisterBuiltinKeyBind(ModifierKeys modifiers, Key key, Action action)
+ {
+ var item = new HotKeyItem(modifiers, key, action);
+ BuiltinHotKeyItems.Add(item);
+ return item;
+ }
+
+ public void RegisterKeyBind(HotKeyItem item)
+ {
+ lock (HotKeyItems)
{
- var item = new HotKeyItem(ModifierKeys.None, Key.None, action)
- {
- GamePadButton = button
- };
- RegisterKeyBind(item);
- return item;
+ HotKeyItems.Add(item);
}
}
-}
+
+ private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
+}
\ No newline at end of file
diff --git a/CSharpManager/Program.cs b/CSharpManager/Program.cs
index 963df59..ac08eb6 100644
--- a/CSharpManager/Program.cs
+++ b/CSharpManager/Program.cs
@@ -1,13 +1,11 @@
-
-namespace CSharpManager
+namespace CSharpManager;
+
+internal class Program
{
- internal class Program
+ public static void Main(string[] args)
{
- public static void Main(string[] args)
- {
- CSharpModManager manager = new();
- manager.LoadMods();
- manager.StartLoop();
- }
+ CSharpModManager manager = new();
+ manager.LoadMods();
+ manager.StartLoop();
}
-}
+}
\ No newline at end of file
diff --git a/CSharpManager/README.md b/CSharpManager/README.md
index 6440321..759de20 100644
--- a/CSharpManager/README.md
+++ b/CSharpManager/README.md
@@ -1,4 +1,5 @@
# CSharpManager
+
C# mod的管理器,CSharpLoader会加载CSharpManager,通过CSharpManager加载其他C# mod
## 编译
diff --git a/CSharpManager/b1cs.ini b/CSharpManager/b1cs.ini
index 04de55c..5adfe08 100644
--- a/CSharpManager/b1cs.ini
+++ b/CSharpManager/b1cs.ini
@@ -1,4 +1,4 @@
[Settings]
-Develop=1
-Console=1
-EnableJit=1
\ No newline at end of file
+Develop = 1
+Console = 1
+EnableJit = 1
\ No newline at end of file
diff --git a/CSharpModBase/CSharpModBase.cs b/CSharpModBase/CSharpModBase.cs
index 5f5b904..0dce7c7 100644
--- a/CSharpModBase/CSharpModBase.cs
+++ b/CSharpModBase/CSharpModBase.cs
@@ -1,33 +1,24 @@
-namespace CSharpModBase
-{
- public static class Common
- {
- public const string LoaderDir = "CSharpLoader";
- public const string ModDir = "CSharpLoader\\Mods";
- public const string DataDir = "CSharpLoader\\Data";
- }
+namespace CSharpModBase;
+public interface ICSharpMod
+{
+ ///
+ /// mod name
+ ///
+ string Name { get; }
- public interface ICSharpMod
- {
- ///
- /// mod name
- ///
- string Name { get; }
+ ///
+ /// mod version
+ ///
+ string Version { get; }
- ///
- /// mod version
- ///
- string Version { get; }
+ ///
+ /// when mod loaded, will call OnInit
+ ///
+ void Init();
- ///
- /// when mod loaded, will call OnInit
- ///
- void Init();
- ///
- /// when manamger reload mods, will call OnDeInit,
- ///
- ///
- void DeInit();
- }
-}
+ ///
+ /// when manager reload mods, will call OnDeInit,
+ ///
+ void DeInit();
+}
\ No newline at end of file
diff --git a/CSharpModBase/CSharpModBase.csproj b/CSharpModBase/CSharpModBase.csproj
index 68192f0..2e319a4 100644
--- a/CSharpModBase/CSharpModBase.csproj
+++ b/CSharpModBase/CSharpModBase.csproj
@@ -1,27 +1,28 @@
-
- net472
- enable
- latest
- True
- 0.0.6.0
-
+
+ net472
+ enable
+ latest
+ true
+ True
+ 0.0.6.0
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
- ..\GameDll\UnrealEngine.Runtime.dll
- False
-
-
+
+
+ ..\GameDll\UnrealEngine.Runtime.dll
+ False
+
+
diff --git a/CSharpModBase/Common.cs b/CSharpModBase/Common.cs
new file mode 100644
index 0000000..b1be0f3
--- /dev/null
+++ b/CSharpModBase/Common.cs
@@ -0,0 +1,8 @@
+namespace CSharpModBase;
+
+public static class Common
+{
+ public const string LoaderDir = "CSharpLoader";
+ public const string ModDir = @"CSharpLoader\Mods";
+ public const string DataDir = @"CSharpLoader\Data";
+}
\ No newline at end of file
diff --git a/CSharpModBase/Input/GamePad.cs b/CSharpModBase/Input/GamePad.cs
index b225fc3..340a992 100644
--- a/CSharpModBase/Input/GamePad.cs
+++ b/CSharpModBase/Input/GamePad.cs
@@ -1,60 +1,36 @@
-using System;
using SharpDX.XInput;
-namespace CSharpModBase.Input
-{
- [Flags]
- public enum GamePadButton
- {
- None = GamepadButtonFlags.None,
- DPadUp = GamepadButtonFlags.DPadUp,
- DPadDown = GamepadButtonFlags.DPadDown,
- DPadLeft = GamepadButtonFlags.DPadLeft,
- DPadRight = GamepadButtonFlags.DPadRight,
- Start = GamepadButtonFlags.Start,
- Back = GamepadButtonFlags.Back,
- LeftThumb = GamepadButtonFlags.LeftThumb,
- RightThumb = GamepadButtonFlags.RightThumb,
- LeftShoulder = GamepadButtonFlags.LeftShoulder,
- RightShoulder = GamepadButtonFlags.RightShoulder,
- A = GamepadButtonFlags.A,
- B = GamepadButtonFlags.B,
- X = GamepadButtonFlags.X,
- Y = GamepadButtonFlags.Y,
- LeftTrigger = 0x10000,
- RightTrigger = 0x20000,
- DPadRightUp = DPadRight | DPadUp,
- DPadLeftDown = DPadLeft | DPadDown,
- DPadRightDown = DPadRight | DPadDown,
- DPadLeftUp = DPadLeft | DPadUp,
- }
-
-
- public static class GamePadUtils
- {
- private static readonly Controller controller = new Controller(UserIndex.One);
-
- public static bool GetGamePadButtons(out GamePadButton flags)
- {
- flags = GamePadButton.None;
- if (controller.GetState(out State state))
- {
- Gamepad gamepad = state.Gamepad;
- flags = (GamePadButton)gamepad.Buttons;
- if (gamepad.LeftTrigger > 100) flags |= GamePadButton.LeftTrigger;
- if (gamepad.RightTrigger > 100) flags |= GamePadButton.RightTrigger;
- return true;
- }
- return false;
- }
- }
-
-
- public class GamePadButtonEvent : EventArgs
- {
- public GamePadButton Button { get; set; }
- }
+namespace CSharpModBase.Input;
+[Flags]
+public enum GamePadButton
+{
+ None = GamepadButtonFlags.None,
+ DPadUp = GamepadButtonFlags.DPadUp,
+ DPadDown = GamepadButtonFlags.DPadDown,
+ DPadLeft = GamepadButtonFlags.DPadLeft,
+ DPadRight = GamepadButtonFlags.DPadRight,
+ Start = GamepadButtonFlags.Start,
+ Back = GamepadButtonFlags.Back,
+ LeftThumb = GamepadButtonFlags.LeftThumb,
+ RightThumb = GamepadButtonFlags.RightThumb,
+ LeftShoulder = GamepadButtonFlags.LeftShoulder,
+ RightShoulder = GamepadButtonFlags.RightShoulder,
+ A = GamepadButtonFlags.A,
+ B = GamepadButtonFlags.B,
+ X = GamepadButtonFlags.X,
+ Y = GamepadButtonFlags.Y,
+ LeftTrigger = 0x10000,
+ RightTrigger = 0x20000,
+ DPadRightUp = DPadRight | DPadUp,
+ DPadLeftDown = DPadLeft | DPadDown,
+ DPadRightDown = DPadRight | DPadDown,
+ DPadLeftUp = DPadLeft | DPadUp
+}
- public delegate void GamePadButtonEventHandler(GamePadButtonEvent e);
+public sealed class GamePadButtonEvent : EventArgs
+{
+ public GamePadButton Button { get; set; }
}
+
+public delegate void GamePadButtonEventHandler(GamePadButtonEvent e);
\ No newline at end of file
diff --git a/CSharpModBase/Input/GamePadUtils.cs b/CSharpModBase/Input/GamePadUtils.cs
new file mode 100644
index 0000000..3fe6eed
--- /dev/null
+++ b/CSharpModBase/Input/GamePadUtils.cs
@@ -0,0 +1,31 @@
+using SharpDX.XInput;
+
+namespace CSharpModBase.Input;
+
+public static class GamePadUtils
+{
+ private static readonly Controller Controller = new(UserIndex.One);
+
+ public static bool GetGamePadButtons(out GamePadButton flags)
+ {
+ flags = GamePadButton.None;
+ if (Controller.GetState(out var state))
+ {
+ var gamepad = state.Gamepad;
+ flags = (GamePadButton)gamepad.Buttons;
+ if (gamepad.LeftTrigger > 100)
+ {
+ flags |= GamePadButton.LeftTrigger;
+ }
+
+ if (gamepad.RightTrigger > 100)
+ {
+ flags |= GamePadButton.RightTrigger;
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/CSharpModBase/Input/HotKeyData.cs b/CSharpModBase/Input/HotKeyData.cs
new file mode 100644
index 0000000..8883578
--- /dev/null
+++ b/CSharpModBase/Input/HotKeyData.cs
@@ -0,0 +1,60 @@
+namespace CSharpModBase.Input;
+
+public class HotKeyData
+{
+ public ModifierKeys Modifiers { get; set; }
+ public Key Key { get; set; }
+ public GamePadButton GamePadButton { get; set; }
+
+ public bool IsValid => Key != Key.None || GamePadButton != GamePadButton.None;
+ public string KeyString => KeyUtils.KeyToString(Modifiers, Key);
+
+ public uint Code
+ {
+ get
+ {
+ if (GamePadButton != GamePadButton.None)
+ {
+ return 0xF0000000 | (uint)GamePadButton;
+ }
+
+ return GetCode(Modifiers, Key);
+ }
+ }
+
+ public HotKeyData(ModifierKeys modifiers, Key key)
+ {
+ Modifiers = modifiers;
+ Key = key;
+ }
+
+ public HotKeyData() : this(ModifierKeys.None, Key.None)
+ {
+ }
+
+ public static uint GetCode(ModifierKeys modifiers, Key key) => ((uint)modifiers << 16) | (uint)key;
+
+ public void SetFromCode(uint code)
+ {
+ if (code >> 24 == 0xF0)
+ {
+ GamePadButton = (GamePadButton)(code & 0xFFFF);
+ Modifiers = ModifierKeys.None;
+ Key = Key.None;
+ }
+ else
+ {
+ GamePadButton = GamePadButton.None;
+ Modifiers = (ModifierKeys)(code >> 16);
+ Key = (Key)(code & 0xFF);
+ }
+ }
+
+ public void SetKey(ModifierKeys modifiers, Key key)
+ {
+ Modifiers = modifiers;
+ Key = key;
+ }
+
+ public override string ToString() => KeyString;
+}
\ No newline at end of file
diff --git a/CSharpModBase/Input/HotKeyItem.cs b/CSharpModBase/Input/HotKeyItem.cs
index 852e36b..8690ec6 100644
--- a/CSharpModBase/Input/HotKeyItem.cs
+++ b/CSharpModBase/Input/HotKeyItem.cs
@@ -1,112 +1,44 @@
-using System;
+namespace CSharpModBase.Input;
-namespace CSharpModBase.Input
+public class HotKeyItem : HotKeyData
{
- public class HotKeyData
- {
- public HotKeyData(ModifierKeys modifiers, Key key)
- {
- Modifiers = modifiers;
- Key = key;
- }
-
- public HotKeyData() : this(ModifierKeys.None, Key.None) {}
-
- public ModifierKeys Modifiers { get; set; }
- public Key Key { get; set; }
- public GamePadButton GamePadButton { get; set; }
+ public string Label { get; set; }
+ public Action Action { get; set; }
- public bool IsValid => Key != Key.None || GamePadButton != GamePadButton.None;
- public string KeyString => KeyUtils.KeyToString(Modifiers, Key);
+ ///
+ /// 0为不支持连按,大于0为连按触发毫秒间隔
+ ///
+ public int RepeatMs { get; set; }
- public static uint GetCode(ModifierKeys modifiers, Key key)
- {
- return ((uint)modifiers << 16) | (uint)key;
- }
+ ///
+ /// 上一次触发的时间,毫秒
+ ///
+ public long LastTriggerMs { get; set; }
- public uint Code
- {
- get
- {
- if (GamePadButton != GamePadButton.None)
- {
- return 0xF0000000 | (uint)GamePadButton;
- }
- else
- {
- return GetCode(Modifiers, Key);
- }
- }
- }
+ ///
+ /// 正在被按下
+ ///
+ public bool IsPressed { get; set; }
- public void SetFromCode(uint code)
- {
- if ((code >> 24) == 0xF0)
- {
- GamePadButton = (GamePadButton)(code & 0xFFFF);
- Modifiers = ModifierKeys.None;
- Key = Key.None;
- }
- else
- {
- GamePadButton = GamePadButton.None;
- Modifiers = (ModifierKeys)(code >> 16);
- Key = (Key)(code & 0xFF);
- }
- }
+ public bool RunOnGameThread { get; set; } = true;
- public void SetKey(ModifierKeys modifiers, Key key)
- {
- Modifiers = modifiers;
- Key = key;
- }
-
- public override string ToString()
- {
- return KeyString;
- }
+ public HotKeyItem(ModifierKeys modifiers, Key key, Action action) : this("", modifiers, key, action)
+ {
}
-
- public class HotKeyItem : HotKeyData
+ public HotKeyItem(string label, ModifierKeys modifiers, Key key, Action action) : base(modifiers, key)
{
- public string Label { get; set; }
- public Action Action { get; set; }
- ///
- /// 0为不支持连按,大于0为连按触发毫秒间隔
- ///
- public int RepeatMs { get; set; }
- ///
- /// 上一次触发的时间,毫秒
- ///
- public long LastTriggerMs { get; set; }
- ///
- /// 正在被按下
- ///
- public bool IsPressed { get; set; }
- public bool RunOnGameThread { get; set; } = true;
-
- public HotKeyItem WithKey(ModifierKeys Modifiers, Key Key)
- {
- return new(Label, Modifiers, Key, Action);
- }
-
- public HotKeyItem(ModifierKeys modifiers, Key key, Action action) : this("", modifiers, key, action)
- {
- }
+ Label = label;
+ Action = action;
+ }
- public HotKeyItem(string label, ModifierKeys modifiers, Key key, Action action) : base(modifiers, key)
- {
- Label = label;
- Action = action;
- }
+ public HotKeyItem() : this("", ModifierKeys.None, Key.None, EmptyAction)
+ {
+ }
- public HotKeyItem() : this("", ModifierKeys.None, Key.None, EmptyAction)
- {
- }
+ public HotKeyItem WithKey(ModifierKeys modifiers, Key key) => new(Label, modifiers, key, Action);
- private static void EmptyAction()
- {
- }
+ private static void EmptyAction()
+ {
}
-}
+}
\ No newline at end of file
diff --git a/CSharpModBase/Input/IInputManager.cs b/CSharpModBase/Input/IInputManager.cs
index 2412625..d7ac1ad 100644
--- a/CSharpModBase/Input/IInputManager.cs
+++ b/CSharpModBase/Input/IInputManager.cs
@@ -1,12 +1,9 @@
-using System;
+namespace CSharpModBase.Input;
-namespace CSharpModBase.Input
+public interface IInputManager
{
- public interface IInputManager
- {
- HotKeyItem RegisterKeyBind(Key key, Action action);
+ HotKeyItem RegisterKeyBind(Key key, Action action);
- HotKeyItem RegisterKeyBind(ModifierKeys modifiers, Key key, Action action);
- HotKeyItem RegisterGamePadBind(GamePadButton button, Action action);
- }
-}
+ HotKeyItem RegisterKeyBind(ModifierKeys modifiers, Key key, Action action);
+ HotKeyItem RegisterGamePadBind(GamePadButton button, Action action);
+}
\ No newline at end of file
diff --git a/CSharpModBase/Input/Key.cs b/CSharpModBase/Input/Key.cs
index 9ae37b4..571f2a9 100644
--- a/CSharpModBase/Input/Key.cs
+++ b/CSharpModBase/Input/Key.cs
@@ -1,146 +1,145 @@
-namespace CSharpModBase.Input
+namespace CSharpModBase.Input;
+
+public enum Key
{
- public enum Key
- {
- None = 0x00,
- LBUTTON = 0x01,
- RBUTTON = 0x02,
- CANCEL = 0x03,
- MBUTTON = 0x04,
- XBUTTON1 = 0x05,
- XBUTTON2 = 0x06,
- BACK = 0x08,
- TAB = 0x09,
- CLEAR = 0x0C,
- RETURN = 0x0D,
- ENTER = RETURN,
- SHIFT = 0x10,
- CONTROL = 0x11,
- MENU = 0x12,
- PAUSE = 0x13,
- CAPITAL = 0x14,
- KANA = 0x15,
- HANGEUL = 0x15,
- HANGUL = 0x15,
- ESCAPE = 0x1B,
- CONVERT = 0x1C,
- NONCONVERT = 0x1D,
- ACCEPT = 0x1E,
- MODECHANGE = 0x1F,
- SPACE = 0x20,
- PRIOR = 0x21,
- NEXT = 0x22,
- END = 0x23,
- HOME = 0x24,
- LEFT = 0x25,
- UP = 0x26,
- RIGHT = 0x27,
- DOWN = 0x28,
- SELECT = 0x29,
- PRINT = 0x2A,
- EXECUTE = 0x2B,
- SNAPSHOT = 0x2C,
- INSERT = 0x2D,
- DELETE = 0x2E,
- HELP = 0x2F,
- D0 = 0x30,
- D1 = 0x31,
- D2 = 0x32,
- D3 = 0x33,
- D4 = 0x34,
- D5 = 0x35,
- D6 = 0x36,
- D7 = 0x37,
- D8 = 0x38,
- D9 = 0x39,
- A = 0x41,
- B = 0x42,
- C = 0x43,
- D = 0x44,
- E = 0x45,
- F = 0x46,
- G = 0x47,
- H = 0x48,
- I = 0x49,
- J = 0x4A,
- K = 0x4B,
- L = 0x4C,
- M = 0x4D,
- N = 0x4E,
- O = 0x4F,
- P = 0x50,
- Q = 0x51,
- R = 0x52,
- S = 0x53,
- T = 0x54,
- U = 0x55,
- V = 0x56,
- W = 0x57,
- X = 0x58,
- Y = 0x59,
- Z = 0x5A,
- LWIN = 0x5B,
- RWIN = 0x5C,
- APPS = 0x5D,
- SLEEP = 0x5F,
- NUMPAD0 = 0x60,
- NUMPAD1 = 0x61,
- NUMPAD2 = 0x62,
- NUMPAD3 = 0x63,
- NUMPAD4 = 0x64,
- NUMPAD5 = 0x65,
- NUMPAD6 = 0x66,
- NUMPAD7 = 0x67,
- NUMPAD8 = 0x68,
- NUMPAD9 = 0x69,
- MULTIPLY = 0x6A,
- ADD = 0x6B,
- SEPARATOR = 0x6C,
- SUBTRACT = 0x6D,
- DECIMAL = 0x6E,
- DIVIDE = 0x6F,
- F1 = 0x70,
- F2 = 0x71,
- F3 = 0x72,
- F4 = 0x73,
- F5 = 0x74,
- F6 = 0x75,
- F7 = 0x76,
- F8 = 0x77,
- F9 = 0x78,
- F10 = 0x79,
- F11 = 0x7A,
- F12 = 0x7B,
- F13 = 0x7C,
- F14 = 0x7D,
- F15 = 0x7E,
- F16 = 0x7F,
- F17 = 0x80,
- F18 = 0x81,
- F19 = 0x82,
- F20 = 0x83,
- F21 = 0x84,
- F22 = 0x85,
- F23 = 0x86,
- F24 = 0x87,
- NUMLOCK = 0x90,
- SCROLL = 0x91,
- LSHIFT = 0xA0,
- RSHIFT = 0xA1,
- LCONTROL = 0xA2,
- RCONTROL = 0xA3,
- LMENU = 0xA4,
- RMENU = 0xA5,
- OEM_1 = 0xBA, // ';'
- OEM_PLUS = 0xBB, // '+'
- OEM_COMMA = 0xBC, // ','
- OEM_MINUS = 0xBD, // '-'
- OEM_PERIOD = 0xBE, // '.'
- OEM_2 = 0xBF, // '/'
- OEM_3 = 0xC0, // '`'
- OEM_4 = 0xDB, // '['
- OEM_5 = 0xDC, // '\\'
- OEM_6 = 0xDD, // ']'
- OEM_7 = 0xDE, // '\''
- }
-}
+ None = 0x00,
+ LBUTTON = 0x01,
+ RBUTTON = 0x02,
+ CANCEL = 0x03,
+ MBUTTON = 0x04,
+ XBUTTON1 = 0x05,
+ XBUTTON2 = 0x06,
+ BACK = 0x08,
+ TAB = 0x09,
+ CLEAR = 0x0C,
+ RETURN = 0x0D,
+ ENTER = RETURN,
+ SHIFT = 0x10,
+ CONTROL = 0x11,
+ MENU = 0x12,
+ PAUSE = 0x13,
+ CAPITAL = 0x14,
+ KANA = 0x15,
+ HANGEUL = 0x15,
+ HANGUL = 0x15,
+ ESCAPE = 0x1B,
+ CONVERT = 0x1C,
+ NONCONVERT = 0x1D,
+ ACCEPT = 0x1E,
+ MODECHANGE = 0x1F,
+ SPACE = 0x20,
+ PRIOR = 0x21,
+ NEXT = 0x22,
+ END = 0x23,
+ HOME = 0x24,
+ LEFT = 0x25,
+ UP = 0x26,
+ RIGHT = 0x27,
+ DOWN = 0x28,
+ SELECT = 0x29,
+ PRINT = 0x2A,
+ EXECUTE = 0x2B,
+ SNAPSHOT = 0x2C,
+ INSERT = 0x2D,
+ DELETE = 0x2E,
+ HELP = 0x2F,
+ D0 = 0x30,
+ D1 = 0x31,
+ D2 = 0x32,
+ D3 = 0x33,
+ D4 = 0x34,
+ D5 = 0x35,
+ D6 = 0x36,
+ D7 = 0x37,
+ D8 = 0x38,
+ D9 = 0x39,
+ A = 0x41,
+ B = 0x42,
+ C = 0x43,
+ D = 0x44,
+ E = 0x45,
+ F = 0x46,
+ G = 0x47,
+ H = 0x48,
+ I = 0x49,
+ J = 0x4A,
+ K = 0x4B,
+ L = 0x4C,
+ M = 0x4D,
+ N = 0x4E,
+ O = 0x4F,
+ P = 0x50,
+ Q = 0x51,
+ R = 0x52,
+ S = 0x53,
+ T = 0x54,
+ U = 0x55,
+ V = 0x56,
+ W = 0x57,
+ X = 0x58,
+ Y = 0x59,
+ Z = 0x5A,
+ LWIN = 0x5B,
+ RWIN = 0x5C,
+ APPS = 0x5D,
+ SLEEP = 0x5F,
+ NUMPAD0 = 0x60,
+ NUMPAD1 = 0x61,
+ NUMPAD2 = 0x62,
+ NUMPAD3 = 0x63,
+ NUMPAD4 = 0x64,
+ NUMPAD5 = 0x65,
+ NUMPAD6 = 0x66,
+ NUMPAD7 = 0x67,
+ NUMPAD8 = 0x68,
+ NUMPAD9 = 0x69,
+ MULTIPLY = 0x6A,
+ ADD = 0x6B,
+ SEPARATOR = 0x6C,
+ SUBTRACT = 0x6D,
+ DECIMAL = 0x6E,
+ DIVIDE = 0x6F,
+ F1 = 0x70,
+ F2 = 0x71,
+ F3 = 0x72,
+ F4 = 0x73,
+ F5 = 0x74,
+ F6 = 0x75,
+ F7 = 0x76,
+ F8 = 0x77,
+ F9 = 0x78,
+ F10 = 0x79,
+ F11 = 0x7A,
+ F12 = 0x7B,
+ F13 = 0x7C,
+ F14 = 0x7D,
+ F15 = 0x7E,
+ F16 = 0x7F,
+ F17 = 0x80,
+ F18 = 0x81,
+ F19 = 0x82,
+ F20 = 0x83,
+ F21 = 0x84,
+ F22 = 0x85,
+ F23 = 0x86,
+ F24 = 0x87,
+ NUMLOCK = 0x90,
+ SCROLL = 0x91,
+ LSHIFT = 0xA0,
+ RSHIFT = 0xA1,
+ LCONTROL = 0xA2,
+ RCONTROL = 0xA3,
+ LMENU = 0xA4,
+ RMENU = 0xA5,
+ OEM_1 = 0xBA, // ';'
+ OEM_PLUS = 0xBB, // '+'
+ OEM_COMMA = 0xBC, // ','
+ OEM_MINUS = 0xBD, // '-'
+ OEM_PERIOD = 0xBE, // '.'
+ OEM_2 = 0xBF, // '/'
+ OEM_3 = 0xC0, // '`'
+ OEM_4 = 0xDB, // '['
+ OEM_5 = 0xDC, // '\\'
+ OEM_6 = 0xDD, // ']'
+ OEM_7 = 0xDE, // '\''
+}
\ No newline at end of file
diff --git a/CSharpModBase/Input/KeyUtils.cs b/CSharpModBase/Input/KeyUtils.cs
index 1f2618b..3bdcf36 100644
--- a/CSharpModBase/Input/KeyUtils.cs
+++ b/CSharpModBase/Input/KeyUtils.cs
@@ -1,89 +1,103 @@
-using System.Collections.Generic;
using System.Runtime.InteropServices;
-namespace CSharpModBase.Input
+namespace CSharpModBase.Input;
+
+public static class KeyUtils
{
- public static class KeyUtils
+ public static ModifierKeys Modifiers
{
- ///
- /// Keys转字符串,支持组合键
- ///
- ///
- ///
- public static string KeyToString(ModifierKeys modifiers, Key key, List buf)
+ get
{
- if (modifiers.HasFlag(ModifierKeys.Control)) buf.Add("Ctrl");
- if (modifiers.HasFlag(ModifierKeys.Shift)) buf.Add("Shift");
- if (modifiers.HasFlag(ModifierKeys.Alt)) buf.Add("Alt");
- string? keyCodeStr = null;
- char oemKeyChar = OemKeyChar(key);
- if (oemKeyChar != default) {
- keyCodeStr = oemKeyChar.ToString();
- } else {
- keyCodeStr = key switch
- {
- Key.None => "",
- _ => key.ToString(),
- };
+ var modifiers = ModifierKeys.None;
+ if (GetKeyState((uint)Key.MENU) < 0)
+ {
+ modifiers |= ModifierKeys.Alt;
}
- if (keyCodeStr != null)
+
+ if (GetKeyState((uint)Key.CONTROL) < 0)
{
- buf.Add(keyCodeStr);
+ modifiers |= ModifierKeys.Control;
}
- return string.Join("+", buf);
+
+ if (GetKeyState((uint)Key.SHIFT) < 0)
+ {
+ modifiers |= ModifierKeys.Shift;
+ }
+
+ return modifiers;
}
+ }
- public static string KeyToString(ModifierKeys modifiers, Key key)
+ ///
+ /// Keys转字符串,支持组合键
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static string KeyToString(ModifierKeys modifiers, Key key, List buf)
+ {
+ if (modifiers.HasFlag(ModifierKeys.Control))
{
- return KeyToString(modifiers, key, new());
+ buf.Add("Ctrl");
}
- public static char OemKeyChar(Key key)
+ if (modifiers.HasFlag(ModifierKeys.Shift))
{
- return key switch
- {
- Key.OEM_PLUS => '+',
- Key.OEM_COMMA => ',',
- Key.OEM_MINUS => '-',
- Key.OEM_PERIOD => '.',
- Key.OEM_1 => ';',
- Key.OEM_2 => '/',
- Key.OEM_3 => '`',
- Key.OEM_4 => '[',
- Key.OEM_5 => '\\',
- Key.OEM_6 => ']',
- Key.OEM_7 => '\'',
- _ => default,
- };
+ buf.Add("Shift");
}
- [DllImport("user32.dll")]
- private static extern short GetKeyState(uint vk);
-
- public static bool IsKeyDown(Key key)
+ if (modifiers.HasFlag(ModifierKeys.Alt))
{
- return GetKeyState((uint)key) < 0;
+ buf.Add("Alt");
}
- public static ModifierKeys Modifiers
+ string? keyCodeStr;
+ var oemKeyChar = OemKeyChar(key);
+ if (oemKeyChar != default)
+ {
+ keyCodeStr = oemKeyChar.ToString();
+ }
+ else
{
- get
+ keyCodeStr = key switch
{
- ModifierKeys modifiers = ModifierKeys.None;
- if (GetKeyState((uint)Key.MENU) < 0)
- {
- modifiers |= ModifierKeys.Alt;
- }
- if (GetKeyState((uint)Key.CONTROL) < 0)
- {
- modifiers |= ModifierKeys.Control;
- }
- if (GetKeyState((uint)Key.SHIFT) < 0)
- {
- modifiers |= ModifierKeys.Shift;
- }
- return modifiers;
- }
+ Key.None => "",
+ _ => key.ToString()
+ };
}
+
+ if (keyCodeStr != null)
+ {
+ buf.Add(keyCodeStr);
+ }
+
+ return string.Join("+", buf);
}
-}
+
+ public static string KeyToString(ModifierKeys modifiers, Key key) => KeyToString(modifiers, key, new List());
+
+ public static char OemKeyChar(Key key)
+ {
+ return key switch
+ {
+ Key.OEM_PLUS => '+',
+ Key.OEM_COMMA => ',',
+ Key.OEM_MINUS => '-',
+ Key.OEM_PERIOD => '.',
+ Key.OEM_1 => ';',
+ Key.OEM_2 => '/',
+ Key.OEM_3 => '`',
+ Key.OEM_4 => '[',
+ Key.OEM_5 => '\\',
+ Key.OEM_6 => ']',
+ Key.OEM_7 => '\'',
+ _ => default
+ };
+ }
+
+ [DllImport("user32.dll")]
+ private static extern short GetKeyState(uint vk);
+
+ public static bool IsKeyDown(Key key) => GetKeyState((uint)key) < 0;
+}
\ No newline at end of file
diff --git a/CSharpModBase/Input/ModifierKeys.cs b/CSharpModBase/Input/ModifierKeys.cs
index 7876a83..adbdde7 100644
--- a/CSharpModBase/Input/ModifierKeys.cs
+++ b/CSharpModBase/Input/ModifierKeys.cs
@@ -1,14 +1,11 @@
-using System;
+namespace CSharpModBase.Input;
-namespace CSharpModBase.Input
+[Flags]
+public enum ModifierKeys
{
- [Flags]
- public enum ModifierKeys
- {
- None = 0,
- Alt = 1,
- Control = 2,
- Shift = 4,
- Windows = 8
- }
-}
+ None = 0,
+ Alt = 1,
+ Control = 2,
+ Shift = 4,
+ Windows = 8
+}
\ No newline at end of file
diff --git a/CSharpModBase/Log.cs b/CSharpModBase/Log.cs
index f6a0eb8..29ff3dc 100644
--- a/CSharpModBase/Log.cs
+++ b/CSharpModBase/Log.cs
@@ -1,78 +1,68 @@
-using System;
-using System.IO;
+namespace CSharpModBase;
-namespace CSharpModBase
+public static class Log
{
- public static class Log
- {
- private static string DateTimeString => DateTime.Now.ToString("MM-dd HH:mm:ss"); // .fff
- // private static readonly StreamWriter LogFile = File.CreateText("CSharpLog.txt");
+ private static string DateTimeString => DateTime.Now.ToString("MM-dd HH:mm:ss"); // .fff
+ // private static readonly StreamWriter LogFile = File.CreateText("CSharpLog.txt");
- public static void Info(string message)
- {
- string text = $"{DateTimeString} [I] {message}";
- Console.WriteLine(text);
- // LogFile.WriteLine(text);
- }
+ public static void Info(string message)
+ {
+ var text = $"{DateTimeString} [I] {message}";
+ Console.WriteLine(text);
+ // LogFile.WriteLine(text);
+ }
- public static void Debug(string message)
- {
- using (var color = new ChangeConsoleColor(ConsoleColor.Gray))
- {
- string text = $"{DateTimeString} [D] {message}";
- Console.WriteLine(text);
- // LogFile.WriteLine(text);
- }
- }
+ public static void Debug(string message)
+ {
+ using var color = new ChangeConsoleColor(ConsoleColor.Gray);
+ var text = $"{DateTimeString} [D] {message}";
+ Console.WriteLine(text);
+ // LogFile.WriteLine(text);
+ }
- public static void Warn(string message)
- {
- using (var color = new ChangeConsoleColor(ConsoleColor.Yellow))
- {
- string text = $"{DateTimeString} [W] {message}";
- Console.WriteLine(text);
- // LogFile.WriteLine(text);
- }
- }
+ public static void Warn(string message)
+ {
+ using var color = new ChangeConsoleColor(ConsoleColor.Yellow);
+ var text = $"{DateTimeString} [W] {message}";
+ Console.WriteLine(text);
+ // LogFile.WriteLine(text);
+ }
- public static void WarnIf(bool condition, string message)
+ public static void WarnIf(bool condition, string message)
+ {
+ if (condition)
{
- if (condition) {
- Warn(message);
- }
+ Warn(message);
}
+ }
- public static void Error(string message)
- {
- using (var color = new ChangeConsoleColor(ConsoleColor.Red))
- {
- string text = $"{DateTimeString} [E] {message}";
- Console.Error.WriteLine(text);
- // LogFile.WriteLine(text);
- }
- }
+ public static void Error(string message)
+ {
+ using var color = new ChangeConsoleColor(ConsoleColor.Red);
+ var text = $"{DateTimeString} [E] {message}";
+ Console.Error.WriteLine(text);
+ // LogFile.WriteLine(text);
+ }
- public static void Error(Exception e)
- {
- Error(e.Message);
- Error(e.StackTrace);
- }
+ public static void Error(Exception e)
+ {
+ Error(e.Message);
+ Error(e.StackTrace);
}
+}
+public readonly struct ChangeConsoleColor : IDisposable
+{
+ private readonly ConsoleColor _currentForeground;
- public readonly struct ChangeConsoleColor : IDisposable
+ public ChangeConsoleColor(ConsoleColor color)
{
- readonly ConsoleColor currentForeground;
-
- public ChangeConsoleColor(ConsoleColor color)
- {
- currentForeground = Console.ForegroundColor;
- Console.ForegroundColor = color;
- }
+ _currentForeground = Console.ForegroundColor;
+ Console.ForegroundColor = color;
+ }
- public void Dispose()
- {
- Console.ForegroundColor = currentForeground;
- }
+ public void Dispose()
+ {
+ Console.ForegroundColor = _currentForeground;
}
-}
+}
\ No newline at end of file
diff --git a/CSharpModBase/Utils.cs b/CSharpModBase/Utils.cs
index 5901f8b..47d2d4d 100644
--- a/CSharpModBase/Utils.cs
+++ b/CSharpModBase/Utils.cs
@@ -1,58 +1,47 @@
-using System;
using CSharpModBase.Input;
using UnrealEngine.Runtime;
-namespace CSharpModBase
+namespace CSharpModBase;
+
+public static class Utils
{
- public static class Utils
+ private static IInputManager? _inputManager;
+
+ public static void InitInputManager(IInputManager inputManager)
{
- private static IInputManager? InputManager;
+ _inputManager = inputManager;
+ }
- public static void InitInputManager(IInputManager inputManager)
- {
- InputManager = inputManager;
- }
+ public static HotKeyItem RegisterKeyBind(Key key, Action action) => _inputManager!.RegisterKeyBind(key, action);
- public static HotKeyItem RegisterKeyBind(Key key, Action action)
- {
- return InputManager!.RegisterKeyBind(key, action);
- }
+ public static HotKeyItem RegisterKeyBind(ModifierKeys modifiers, Key key, Action action) => _inputManager!.RegisterKeyBind(modifiers, key, action);
- public static HotKeyItem RegisterKeyBind(ModifierKeys modifiers, Key key, Action action)
+ public static HotKeyItem RegisterGamePadBind(GamePadButton button, Action action) => _inputManager!.RegisterGamePadBind(button, action);
+
+ public static void TryRun(Action action)
+ {
+ try
{
- return InputManager!.RegisterKeyBind(modifiers, key, action);
+ action();
}
-
- public static HotKeyItem RegisterGamePadBind(GamePadButton button, Action action)
+ catch (Exception e)
{
- return InputManager!.RegisterGamePadBind(button, action);
+ Log.Error(e);
}
+ }
- public static void TryRun(Action aciton)
+ public static void TryRunOnGameThread(Action action)
+ {
+ FThreading.RunOnGameThread(() =>
{
try
{
- aciton();
+ action();
}
catch (Exception e)
{
Log.Error(e);
- };
- }
-
- public static void TryRunOnGameThread(Action aciton)
- {
- FThreading.RunOnGameThread(() =>
- {
- try
- {
- aciton();
- }
- catch (Exception e)
- {
- Log.Error(e);
- }
- });
- }
+ }
+ });
}
-}
+}
\ No newline at end of file
diff --git a/README.en.md b/README.en.md
index e0f9fe8..01b5005 100644
--- a/README.en.md
+++ b/README.en.md
@@ -59,7 +59,7 @@ In version 0.0.7 of the C# loader, to enable C# patch/hook features, the game's
Suggest install [.net 8 sdk](https://dotnet.microsoft.com/) to develop with latest syntax.
You can use vscode, visual studio or rider to write code.
-See CSharpModExample.
+For mod template, follow [B1.Mod.Template](https://github.com/BlackMythWukongMods/B1.Mod.Template)'s Readme to install and use it
### Mod entrance
diff --git a/README.md b/README.md
index 56ead34..c20bfda 100644
--- a/README.md
+++ b/README.md
@@ -60,7 +60,7 @@ version.dll是常用的插件名字,如果你使用了其他有名称冲突的
建议安装.net 8 sdk,方便使用最新的语法。
开发工具可以使用vscode, visual studio 或者 rider。
-示例工程可以参考CSharpModExample
+Mod 模板可以参考[模板仓库](https://github.com/BlackMythWukongMods/B1.Mod.Template)的 Readme 进行安装使用
### mod入口