using CommunityToolkit.Mvvm.ComponentModel;
using System;
using System.Windows.Forms;
using System.Windows.Input;
using Windows.Networking.PushNotifications;
using static Vanara.PInvoke.User32;
namespace BetterGenshinImpact.Core.Config;
///
/// 原神按键绑定配置
///
[Serializable]
public partial class KeyBindingsConfig:ObservableObject
{
#region Actions(操作)
///
/// 向前移动
///
[ObservableProperty]
private KeyId _moveForward = KeyId.W;
///
/// 向后移动
///
[ObservableProperty]
private KeyId _moveBackward = KeyId.S;
///
/// 向左移动
///
[ObservableProperty]
private KeyId _moveLeft = KeyId.A;
///
/// 向右移动
///
[ObservableProperty]
private KeyId _moveRight = KeyId.D;
///
/// 切换走/跑;特定操作模式下向下移动
///
[ObservableProperty]
private KeyId _switchToWalkOrRun = KeyId.LeftCtrl;
///
/// 普通攻击
///
[ObservableProperty]
private KeyId _normalAttack = KeyId.MouseLeftButton;
///
/// 元素战技
///
[ObservableProperty]
private KeyId _elementalSkill = KeyId.E;
///
/// 元素爆发
///
[ObservableProperty]
private KeyId _elementalBurst = KeyId.Q;
///
/// 冲刺(键盘)
///
[ObservableProperty]
private KeyId _sprintKeyboard = KeyId.LeftShift;
///
/// 冲刺(鼠标)
///
[ObservableProperty]
private KeyId _sprintMouse = KeyId.MouseRightButton;
///
/// 切换瞄准模式
///
[ObservableProperty]
private KeyId _switchAimingMode = KeyId.R;
///
/// 跳跃;特定操作模式下向上移动
///
[ObservableProperty]
private KeyId _jump = KeyId.Space;
///
/// 落下
///
[ObservableProperty]
private KeyId _drop = KeyId.X;
///
/// 拾取/交互(自动拾取由AutoPick模块管理)
///
[ObservableProperty]
private KeyId _pickUpOrInteract = KeyId.F;
///
/// 快捷使用小道具
///
[ObservableProperty]
private KeyId _quickUseGadget = KeyId.Z;
///
/// 特定玩法内交互操作
///
[ObservableProperty]
private KeyId _interactionInSomeMode = KeyId.T;
///
/// 开启任务追踪
///
[ObservableProperty]
private KeyId _questNavigation = KeyId.V;
///
/// 中断挑战
///
[ObservableProperty]
private KeyId _abandonChallenge = KeyId.P;
///
/// 切换小队角色1
///
[ObservableProperty]
private KeyId _switchMember1 = KeyId.D1;
///
/// 切换小队角色2
///
[ObservableProperty]
private KeyId _switchMember2 = KeyId.D2;
///
/// 切换小队角色3
///
[ObservableProperty]
private KeyId _switchMember3 = KeyId.D3;
///
/// 切换小队角色4
///
[ObservableProperty]
private KeyId _switchMember4 = KeyId.D4;
///
/// 切换小队角色5
///
[ObservableProperty]
private KeyId _switchMember5 = KeyId.D5;
///
/// 呼出快捷轮盘
///
[ObservableProperty]
private KeyId _shortcutWheel = KeyId.Tab;
#endregion
#region Menus(菜单)
///
/// 打开背包
///
[ObservableProperty]
private KeyId _openInventory = KeyId.B;
///
/// 打开角色界面
///
[ObservableProperty]
private KeyId _openCharacterScreen = KeyId.C;
///
/// 打开地图
///
[ObservableProperty]
private KeyId _openMap = KeyId.M;
///
/// 打开派蒙界面
///
[ObservableProperty]
private KeyId _openPaimonMenu = KeyId.Escape;
///
/// 打开冒险之证界面
///
[ObservableProperty]
private KeyId _openAdventurerHandbook = KeyId.F1;
///
/// 打开多人游戏界面
///
[ObservableProperty]
private KeyId _openCoOpScreen = KeyId.F2;
///
/// 打开祈愿界面
///
[ObservableProperty]
private KeyId _openWishScreen = KeyId.F3;
///
/// 打开纪行界面
///
[ObservableProperty]
private KeyId _openBattlePassScreen = KeyId.F4;
///
/// 打开活动面板
///
[ObservableProperty]
private KeyId _openTheEventsMenu = KeyId.F5;
///
/// 打开玩法系统界面(尘歌壶内猫尾酒馆内)
///
[ObservableProperty]
private KeyId _openTheSettingsMenu = KeyId.F6;
///
/// 打开摆设界面(尘歌壶内)
///
[ObservableProperty]
private KeyId _openTheFurnishingScreen = KeyId.F7;
///
/// 打开星之归还(条件符合期间生效)
///
[ObservableProperty]
private KeyId _openStellarReunion = KeyId.F8;
///
/// 开关任务菜单
///
[ObservableProperty]
private KeyId _openQuestMenu = KeyId.J;
///
/// 打开通知详情
///
[ObservableProperty]
private KeyId _openNotificationDetails = KeyId.Y;
///
/// 打开聊天界面
///
[ObservableProperty]
private KeyId _openChatScreen = KeyId.Enter;
///
/// 打开特殊环境说明
///
[ObservableProperty]
private KeyId _openSpecialEnvironmentInformation = KeyId.U;
///
/// 查看教程详情
///
[ObservableProperty]
private KeyId _checkTutorialDetails = KeyId.G;
///
/// 长按打开元素视野
///
[ObservableProperty]
private KeyId _elementalSight = KeyId.MouseMiddleButton;
///
/// 呼出鼠标
///
[ObservableProperty]
private KeyId _showCursor = KeyId.LeftAlt;
///
/// 打开队伍配置界面
///
[ObservableProperty]
private KeyId _openPartySetupScreen = KeyId.L;
///
/// 打开好友界面
///
[ObservableProperty]
private KeyId _openFriendsScreen = KeyId.O;
///
/// 隐藏主界面
///
[ObservableProperty]
private KeyId _hideUI = KeyId.Slash;
#endregion
}
public static class KeyIdConverter
{
///
/// 将KeyId转换为字符串(可在后续支持多语言),按键名称的显示尽量与原神UI一致
///
///
///
public static string ToName(this KeyId value)
{
return ToChineseName(value);
}
private static string ToChineseName(KeyId value)
{
return value switch
{
// 需要单独翻译的按键
KeyId.None => "<未指定>",
KeyId.Unknown => "<未知>",
KeyId.MouseLeftButton => "鼠标左键",
KeyId.MouseRightButton => "鼠标右键",
KeyId.MouseMiddleButton => "鼠标中键",
KeyId.MouseSideButton1 => "鼠标侧键1",
KeyId.MouseSideButton2 => "鼠标侧键2",
KeyId.Apps => "菜单键",
// 无需单独翻译的部分
_ => EnglishKeyNameToChinese(value),
};
}
private static string EnglishKeyNameToChinese(KeyId value)
{
var engName = ToEnglishName(value);
if (engName.StartsWith("Left ") || engName.StartsWith("Right "))
{
return engName.Replace("Left ", "左").Replace("Right ", "右");
}
return engName;
}
private static string ToEnglishName(KeyId value)
{
return value switch
{
// 需要转换的部分
KeyId.None => "",
KeyId.Unknown => "",
KeyId.MouseLeftButton => "Mouse LButton",
KeyId.MouseRightButton => "Mouse RButton",
KeyId.MouseMiddleButton => "Mouse MButton",
KeyId.MouseSideButton1 => "Mouse XButton1",
KeyId.MouseSideButton2 => "Mouse XButton2",
KeyId.Escape => "Esc",
KeyId.PageUp => "Page Up",
KeyId.PageDown => "Page Down",
KeyId.CapsLock => "Caps Lock",
KeyId.ScrollLock => "Scroll Lock",
KeyId.LeftShift => "Left Shift",
KeyId.RightShift => "Right Shift",
KeyId.LeftCtrl => "Left Crtl",
KeyId.RightCtrl => "Right Ctrl",
KeyId.LeftAlt => "Left Alt",
KeyId.RightAlt => "Right Alt",
KeyId.LeftWin => "Left Win",
KeyId.RightWin => "Right Win",
KeyId.Apps => "Menu",
KeyId.Left => "←",
KeyId.Up => "↑",
KeyId.Right => "→",
KeyId.Down => "↓",
KeyId.D0 => "0",
KeyId.D1 => "1",
KeyId.D2 => "2",
KeyId.D3 => "3",
KeyId.D4 => "4",
KeyId.D5 => "5",
KeyId.D6 => "6",
KeyId.D7 => "7",
KeyId.D8 => "8",
KeyId.D9 => "9",
KeyId.Apostrophe => "'",
KeyId.Comma => ",",
KeyId.Minus => "-",
KeyId.Equal => "=",
KeyId.Period => ".",
KeyId.Slash => "/",
KeyId.Backslash => @"\",
KeyId.Semicolon => ";",
KeyId.LeftSquareBracket => "[",
KeyId.RightSquareBracket => "]",
KeyId.Tilde => "`",
KeyId.NumLock => "Num Lock",
KeyId.NumPad0 => "Num 0",
KeyId.NumPad1 => "Num 1",
KeyId.NumPad2 => "Num 2",
KeyId.NumPad3 => "Num 3",
KeyId.NumPad4 => "Num 4",
KeyId.NumPad5 => "Num 5",
KeyId.NumPad6 => "Num 6",
KeyId.NumPad7 => "Num 7",
KeyId.NumPad8 => "Num 8",
KeyId.NumPad9 => "Num 9",
KeyId.Decimal => "Num .",
KeyId.Divide => "Num /",
KeyId.Multiply => "Num *",
KeyId.Subtract => "Num -",
KeyId.Add => "Num +",
KeyId.NumEnter => "Num Enter",
// 默认使用枚举名
_ => value.ToString(),
};
}
///
/// 将KeyId转换为VK
///
///
///
public static VK ToVK(this KeyId value)
{
return value switch
{
// 这两个值在VK中没有,抛异常
KeyId.None => throw new ArgumentOutOfRangeException(nameof(value), "未指定按键,无法转换为VK。"),
KeyId.Unknown => throw new ArgumentOutOfRangeException(nameof(value), "未知按键,无法转换为VK。"),
// 剩下的值相同,直接转
_ => (VK)value,
};
}
///
/// 将KeyId转换为System.Windows.Input.Key
///
///
///
public static Key ToInputKey(this KeyId value)
{
// 部分按键名称相同,使用名称转换
try
{
return Enum.Parse(value.ToString());
}
catch
{
// 其他键使用查表法转换
return value switch
{
KeyId.LeftWin => Key.LWin,
KeyId.RightWin => Key.RWin,
KeyId.Apostrophe => Key.Oem7,
KeyId.Comma => Key.OemComma,
KeyId.Minus => Key.OemMinus,
KeyId.Equal => Key.OemPlus,
KeyId.Period => Key.OemPeriod,
KeyId.Slash => Key.Oem2,
KeyId.Semicolon => Key.Oem1,
KeyId.LeftSquareBracket => Key.Oem4,
KeyId.Backslash => Key.Oem5,
KeyId.RightSquareBracket => Key.Oem6,
KeyId.Tilde => Key.Oem3,
KeyId.Enter => Key.Enter,
KeyId.ScrollLock => Key.Scroll,
KeyId.PageUp => Key.Prior,
KeyId.PageDown => Key.Next,
KeyId.Backspace => Key.Back,
KeyId.CapsLock => Key.Capital,
// None、Unknown和鼠标按键抛异常
_ => throw new ArgumentOutOfRangeException(nameof(value)),
};
}
}
///
/// 将KeyId转换为MouseButton
///
///
///
///
public static MouseButton ToMouseButton(this KeyId value)
{
return value switch
{
KeyId.MouseLeftButton => MouseButton.Left,
KeyId.MouseRightButton => MouseButton.Right,
KeyId.MouseMiddleButton => MouseButton.Middle,
KeyId.MouseSideButton1 => MouseButton.XButton1,
KeyId.MouseSideButton2 => MouseButton.XButton2,
_ => throw new ArgumentOutOfRangeException(nameof(value), "键盘按键请使用ToInputKey方法"),
};
}
///
/// [实验] 将KeyId转换为WinForm中的Keys(用于兼容按键连发功能)
///
///
///
public static Keys ToWinFormKeys(this KeyId value)
{
try
{
return Enum.Parse(value.ToInputKey().ToString());
}
catch
{
return default;
}
}
///
/// 将VK转换为KeyId
///
///
///
public static KeyId FromVK(VK value)
{
// 尝试通过VK的值获取KeyId的枚举名。若成功,表示对应的VK在KeyId支持的范围内,直接转换;否则返回Unknown
return string.IsNullOrEmpty(Enum.GetName(typeof(KeyId), value)) ? KeyId.Unknown : (KeyId)value;
}
///
/// 将System.Windows.Input.Key转换为KeyId
///
///
///
public static KeyId FromInputKey(Key value)
{
// 部分按键名称相同,使用名称转换
try
{
return Enum.Parse(value.ToString());
}
catch
{
// 其他键使用查表法转换
return value switch
{
Key.LWin => KeyId.LeftWin,
Key.RWin => KeyId.RightWin,
Key.Oem7 => KeyId.Apostrophe,
Key.OemComma => KeyId.Comma,
Key.OemMinus => KeyId.Minus,
Key.OemPlus => KeyId.Equal,
Key.OemPeriod => KeyId.Period,
Key.Oem2 => KeyId.Slash,
Key.Oem1 => KeyId.Semicolon,
Key.Oem4 => KeyId.LeftSquareBracket,
Key.Oem5 => KeyId.Backslash,
Key.Oem6 => KeyId.RightSquareBracket,
Key.Oem3 => KeyId.Tilde,
Key.Enter => KeyId.Enter,
Key.Scroll => KeyId.ScrollLock,
Key.Prior => KeyId.PageUp,
Key.Next => KeyId.PageDown,
Key.Back => KeyId.Backspace,
Key.Capital => KeyId.CapsLock,
// 支持列表外的值返回Unknown
_ => KeyId.Unknown,
};
}
}
///
/// 将MouseButton转换为KeyId
///
///
///
public static KeyId FromMouseButton(MouseButton value)
{
return value switch
{
MouseButton.Left => KeyId.MouseLeftButton,
MouseButton.Right => KeyId.MouseRightButton,
MouseButton.Middle => KeyId.MouseMiddleButton,
MouseButton.XButton1 => KeyId.MouseSideButton1,
MouseButton.XButton2 => KeyId.MouseSideButton2,
_ => KeyId.Unknown,
};
}
}
///
/// 用于与VK/Windows.Input.Key解耦,值与VK对应,但是仅包含美式键盘(104键,不包括媒体控制等)和鼠标中的按键
///
public enum KeyId
{
/// 无
None = 0x00,
/// 未知按键
Unknown = 0xFF,
#region 鼠标按键
/// 鼠标左键
MouseLeftButton = 0x01,
/// 鼠标右键
MouseRightButton = 0x02,
/// 鼠标中键(滚轮)
MouseMiddleButton = 0x04,
/// 鼠标侧键1(后退)
MouseSideButton1 = 0x05,
/// 鼠标侧键2(前进)
MouseSideButton2 = 0x06,
#endregion
#region F键区
/// F1
F1 = 0x70,
/// F2
F2 = 0x71,
/// F3
F3 = 0x72,
/// F4
F4 = 0x73,
/// F5
F5 = 0x74,
/// F6
F6 = 0x75,
/// F7
F7 = 0x76,
/// F8
F8 = 0x77,
/// F9
F9 = 0x78,
/// F10
F10 = 0x79,
/// F11
F11 = 0x7A,
/// F12
F12 = 0x7B,
#endregion
#region 控制&功能键
/// Esc
Escape = 0x1B,
/// PrintScreen
PrintScreen = 0x2C,
/// ScrollLock
ScrollLock = 0x91,
/// Pause
Pause = 0x13,
/// Insert
Insert = 0x2D,
/// Delete
Delete = 0x2E,
/// Home
Home = 0x24,
/// End
End = 0x23,
/// Page Up
PageUp = 0x21,
/// Page Down
PageDown = 0x22,
/// Backspace退格
Backspace = 0x08,
/// Tab
Tab = 0x09,
/// Caps Lock大写锁定
CapsLock = 0x14,
/// Enter回车
Enter = 0x0D,
///// Shift
//Shift = 0x10,
/// 左Shift
LeftShift = 0xA0,
/// 右Shift
RightShift = 0xA1,
///// Ctrl
//Ctrl = 0x11,
/// 左Ctrl
LeftCtrl = 0xA2,
/// 右Ctrl
RightCtrl = 0xA3,
///// Alt
//Alt = 0x12,
/// 左Alt
LeftAlt = 0xA4,
/// 右Alt
RightAlt = 0xA5,
/// 左Win键 (Microsoft Natural Keyboard)
LeftWin = 0x5B,
/// 右Win键 (Microsoft Natural Keyboard)
RightWin = 0x5C,
/// 菜单键 (Microsoft Natural Keyboard)
Apps = 0x5D,
/// Space空格键
Space = 0x20,
#endregion
#region 方向键
/// 方向键 ←
Left = 0x25,
/// 方向键 ↑
Up = 0x26,
/// 方向键 →
Right = 0x27,
/// 方向键 ↓
Down = 0x28,
#endregion
#region 字母区 - 字母
/// A
A = 0x41,
/// B
B = 0x42,
/// C
C = 0x43,
/// D
D = 0x44,
/// E
E = 0x45,
/// F
F = 0x46,
/// G
G = 0x47,
/// H
H = 0x48,
/// I
I = 0x49,
/// J
J = 0x4A,
/// K
K = 0x4B,
/// L
L = 0x4C,
/// M
M = 0x4D,
/// N
N = 0x4E,
/// O
O = 0x4F,
/// P
P = 0x50,
/// Q
Q = 0x51,
/// R
R = 0x52,
/// S
S = 0x53,
/// T
T = 0x54,
/// U
U = 0x55,
/// V
V = 0x56,
/// W
W = 0x57,
/// X
X = 0x58,
/// Y
Y = 0x59,
/// Z
Z = 0x5A,
#endregion
#region 字母区 - 数字
/// 0
D0 = 0x30,
/// 1
D1 = 0x31,
/// 2
D2 = 0x32,
/// 3
D3 = 0x33,
/// 4
D4 = 0x34,
/// 5
D5 = 0x35,
/// 6
D6 = 0x36,
/// 7
D7 = 0x37,
/// 8
D8 = 0x38,
/// 9
D9 = 0x39,
#endregion
#region 字母区 - 符号
/// 引号 '
Apostrophe = 0xDE,
/// 逗号 ,
Comma = 0xBC,
/// 连接符 -
Minus = 0xBD,
/// 等于号 =
Equal = 0xBB,
/// 句号 .
Period = 0xBE,
/// 斜杠 /
Slash = 0xBF,
/// 反斜杠 \
Backslash = 0xE2,
/// 分号 ;
Semicolon = 0xBA,
/// 左方括号 [
LeftSquareBracket = 0xDB,
/// 右方括号 ]
RightSquareBracket = 0xDD,
/// 波浪号 `
Tilde = 0xC0,
#endregion
#region 小键盘区
/// Num Lock
NumLock = 0x90,
/// Num 0
NumPad0 = 0x60,
/// Num 1
NumPad1 = 0x61,
/// Num 2
NumPad2 = 0x62,
/// Num 3
NumPad3 = 0x63,
/// Num 4
NumPad4 = 0x64,
/// Num 5
NumPad5 = 0x65,
/// Num 6
NumPad6 = 0x66,
/// Num 7
NumPad7 = 0x67,
/// Num 8
NumPad8 = 0x68,
/// Num 9
NumPad9 = 0x69,
/// Num .
Decimal = 0x6E,
/// Num /
Divide = 0x6F,
/// Num *
Multiply = 0x6A,
/// Num -
Subtract = 0x6D,
/// Num +
Add = 0x6B,
/// Num Enter
NumEnter = 0x0E,
#endregion
}