mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-14 01:55:19 -04:00
Add CpeTextHotKey support.
This commit is contained in:
parent
0d255b4586
commit
c81014d6ef
@ -201,7 +201,7 @@ namespace ClassicalSharp {
|
|||||||
return textInput.HandlesKeyPress( key );
|
return textInput.HandlesKeyPress( key );
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenTextInputBar( string initialText ) {
|
public void OpenTextInputBar( string initialText ) {
|
||||||
if( !game.CursorVisible )
|
if( !game.CursorVisible )
|
||||||
game.CursorVisible = true;
|
game.CursorVisible = true;
|
||||||
suppressNextPress = true;
|
suppressNextPress = true;
|
||||||
|
@ -121,6 +121,10 @@ namespace ClassicalSharp {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OpenTextInputBar( string text ) {
|
||||||
|
chat.OpenTextInputBar( text );
|
||||||
|
}
|
||||||
|
|
||||||
public override bool HandlesMouseScroll( int delta ) {
|
public override bool HandlesMouseScroll( int delta ) {
|
||||||
return chat.HandlesMouseScroll( delta );
|
return chat.HandlesMouseScroll( delta );
|
||||||
}
|
}
|
||||||
|
@ -138,6 +138,8 @@
|
|||||||
<Compile Include="Commands\Command.cs" />
|
<Compile Include="Commands\Command.cs" />
|
||||||
<Compile Include="Commands\DefaultCommands.cs" />
|
<Compile Include="Commands\DefaultCommands.cs" />
|
||||||
<Compile Include="GraphicsAPI\VertexFormats.cs" />
|
<Compile Include="GraphicsAPI\VertexFormats.cs" />
|
||||||
|
<Compile Include="Hotkeys\HotkeyList.cs" />
|
||||||
|
<Compile Include="Hotkeys\LwjglToKey.cs" />
|
||||||
<Compile Include="Ionic.Zlib\DeflateStream.cs" />
|
<Compile Include="Ionic.Zlib\DeflateStream.cs" />
|
||||||
<Compile Include="Ionic.Zlib\Inflate.cs" />
|
<Compile Include="Ionic.Zlib\Inflate.cs" />
|
||||||
<Compile Include="Ionic.Zlib\InfTree.cs" />
|
<Compile Include="Ionic.Zlib\InfTree.cs" />
|
||||||
@ -234,6 +236,7 @@
|
|||||||
<Folder Include="Map\Formats" />
|
<Folder Include="Map\Formats" />
|
||||||
<Folder Include="Model" />
|
<Folder Include="Model" />
|
||||||
<Folder Include="Network\Utils" />
|
<Folder Include="Network\Utils" />
|
||||||
|
<Folder Include="Hotkeys" />
|
||||||
<Folder Include="TexturePack" />
|
<Folder Include="TexturePack" />
|
||||||
<Folder Include="Singleplayer" />
|
<Folder Include="Singleplayer" />
|
||||||
<Folder Include="Utils" />
|
<Folder Include="Utils" />
|
||||||
|
@ -264,7 +264,7 @@ namespace ClassicalSharp {
|
|||||||
PitchDegrees = Utils.LerpAngle( lastPitch, nextPitch, t );
|
PitchDegrees = Utils.LerpAngle( lastPitch, nextPitch, t );
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void HandleKeyDown( Key key ) {
|
internal bool HandleKeyDown( Key key ) {
|
||||||
KeyMap keys = game.InputHandler.Keys;
|
KeyMap keys = game.InputHandler.Keys;
|
||||||
if( key == keys[KeyMapping.Respawn] && canRespawn ) {
|
if( key == keys[KeyMapping.Respawn] && canRespawn ) {
|
||||||
Vector3I p = Vector3I.Floor( SpawnPoint );
|
Vector3I p = Vector3I.Floor( SpawnPoint );
|
||||||
@ -289,7 +289,10 @@ namespace ClassicalSharp {
|
|||||||
flying = !flying;
|
flying = !flying;
|
||||||
} else if( key == keys[KeyMapping.NoClip] && canNoclip ) {
|
} else if( key == keys[KeyMapping.NoClip] && canNoclip ) {
|
||||||
noClip = !noClip;
|
noClip = !noClip;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Calculates the jump velocity required such that when a client presses
|
/// <summary> Calculates the jump velocity required such that when a client presses
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
using System;
|
using System;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using OpenTK.Input;
|
using OpenTK.Input;
|
||||||
|
using ClassicalSharp.Hotkeys;
|
||||||
|
|
||||||
namespace ClassicalSharp {
|
namespace ClassicalSharp {
|
||||||
|
|
||||||
public sealed class InputHandler {
|
public sealed class InputHandler {
|
||||||
|
|
||||||
|
public HotkeyList Hotkeys = new HotkeyList();
|
||||||
Game game;
|
Game game;
|
||||||
public InputHandler( Game game ) {
|
public InputHandler( Game game ) {
|
||||||
this.game = game;
|
this.game = game;
|
||||||
@ -268,12 +270,25 @@ namespace ClassicalSharp {
|
|||||||
} else if( key == Keys[KeyMapping.Screenshot] ) {
|
} else if( key == Keys[KeyMapping.Screenshot] ) {
|
||||||
game.screenshotRequested = true;
|
game.screenshotRequested = true;
|
||||||
} else if( game.activeScreen == null || !game.activeScreen.HandlesKeyDown( key ) ) {
|
} else if( game.activeScreen == null || !game.activeScreen.HandlesKeyDown( key ) ) {
|
||||||
if( !HandleBuiltinKey( key ) ) {
|
|
||||||
game.LocalPlayer.HandleKeyDown( key );
|
if( !HandleBuiltinKey( key ) && !game.LocalPlayer.HandleKeyDown( key ) ) {
|
||||||
|
HandleHotkey( key );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HandleHotkey( Key key ) {
|
||||||
|
string text;
|
||||||
|
bool more;
|
||||||
|
|
||||||
|
if( Hotkeys.IsHotkey( key, game.Keyboard, out text, out more ) ) {
|
||||||
|
if( !more )
|
||||||
|
game.Network.SendChat( text );
|
||||||
|
else if( game.activeScreen is NormalScreen )
|
||||||
|
((NormalScreen)game.activeScreen).OpenTextInputBar( text );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MouseButtonEventArgs simArgs = new MouseButtonEventArgs();
|
MouseButtonEventArgs simArgs = new MouseButtonEventArgs();
|
||||||
bool SimulateMouse( Key key, bool pressed ) {
|
bool SimulateMouse( Key key, bool pressed ) {
|
||||||
if( !(key == mapLeft || key == mapMiddle || key == mapRight ) )
|
if( !(key == mapLeft || key == mapMiddle || key == mapRight ) )
|
||||||
|
85
ClassicalSharp/Hotkeys/HotkeyList.cs
Normal file
85
ClassicalSharp/Hotkeys/HotkeyList.cs
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using OpenTK.Input;
|
||||||
|
|
||||||
|
namespace ClassicalSharp.Hotkeys {
|
||||||
|
|
||||||
|
/// <summary> Maintains the list of hotkeys defined by the client and by SetTextHotkey packets. </summary>
|
||||||
|
public sealed class HotkeyList {
|
||||||
|
|
||||||
|
struct Hotkey {
|
||||||
|
public Key BaseKey;
|
||||||
|
public byte Flags; // ctrl 1, shift 2, alt 4
|
||||||
|
public string Text; // contents to copy directly into the input bar
|
||||||
|
public bool MoreInput; // whether the user is able to enter further input
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Hotkey> hotkeys = new List<Hotkey>();
|
||||||
|
|
||||||
|
/// <summary> Creates or updates an existing hotkey with the given baseKey and modifier flags. </summary>
|
||||||
|
public void AddHotkey( Key baseKey, byte flags, string text, bool more ) {
|
||||||
|
if( !UpdateExistingHotkey( baseKey, flags, text, more ) )
|
||||||
|
AddNewHotkey( baseKey, flags, text, more );
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> Removes an existing hotkey with the given baseKey and modifier flags. </summary>
|
||||||
|
/// <returns> Whether a hotkey with the given baseKey and modifier flags was found
|
||||||
|
/// and subsequently removed. </returns>
|
||||||
|
public bool RemoveHotkey( Key baseKey, byte flags ) {
|
||||||
|
for( int i = 0; i < hotkeys.Count; i++ ) {
|
||||||
|
Hotkey hKey = hotkeys[i];
|
||||||
|
if( hKey.BaseKey == baseKey && hKey.Flags == flags ) {
|
||||||
|
hotkeys.RemoveAt( i );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UpdateExistingHotkey( Key baseKey, byte flags, string text, bool more ) {
|
||||||
|
for( int i = 0; i < hotkeys.Count; i++ ) {
|
||||||
|
Hotkey hKey = hotkeys[i];
|
||||||
|
if( hKey.BaseKey == baseKey && hKey.Flags == flags ) {
|
||||||
|
hKey.Text = text;
|
||||||
|
hKey.MoreInput = more;
|
||||||
|
hotkeys[i] = hKey;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddNewHotkey( Key baseKey, byte flags, string text, bool more ) {
|
||||||
|
Hotkey hotkey;
|
||||||
|
hotkey.BaseKey = baseKey;
|
||||||
|
hotkey.Flags = flags;
|
||||||
|
hotkey.Text = text;
|
||||||
|
hotkey.MoreInput = more;
|
||||||
|
hotkeys.Add( hotkey );
|
||||||
|
// sort so that hotkeys with largest modifiers are first
|
||||||
|
hotkeys.Sort( (a, b) => b.Flags.CompareTo( a.Flags ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> Determines whether a hotkey is active based on the given key,
|
||||||
|
/// and the currently active control, alt, and shift modifiers </summary>
|
||||||
|
public bool IsHotkey( Key key, KeyboardDevice keyboard,
|
||||||
|
out string text, out bool moreInput ) {
|
||||||
|
byte flags = 0;
|
||||||
|
if( keyboard[Key.ControlLeft] || keyboard[Key.ControlRight] ) flags |= 1;
|
||||||
|
if( keyboard[Key.ShiftLeft] || keyboard[Key.ShiftRight] ) flags |= 2;
|
||||||
|
if( keyboard[Key.AltLeft] || keyboard[Key.AltRight] ) flags |= 4;
|
||||||
|
|
||||||
|
foreach( Hotkey hKey in hotkeys ) {
|
||||||
|
if( (hKey.Flags & flags) == hKey.Flags && hKey.BaseKey == key ) {
|
||||||
|
text = hKey.Text;
|
||||||
|
moreInput = hKey.MoreInput;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
text = null;
|
||||||
|
moreInput = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
73
ClassicalSharp/Hotkeys/LwjglToKey.cs
Normal file
73
ClassicalSharp/Hotkeys/LwjglToKey.cs
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
using System;
|
||||||
|
using OpenTK.Input;
|
||||||
|
|
||||||
|
namespace ClassicalSharp.Hotkeys {
|
||||||
|
|
||||||
|
/// <summary> Maps LWJGL keycodes to OpenTK keys. </summary>
|
||||||
|
public static class LwjglToKey {
|
||||||
|
|
||||||
|
public static Key[] Map = new Key[256];
|
||||||
|
|
||||||
|
static int curIndex = 0;
|
||||||
|
static void Add( Key key ) {
|
||||||
|
Map[curIndex++] = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Add( string value ) {
|
||||||
|
for( int i = 0; i < value.Length; i++ ) {
|
||||||
|
Add( (Key)(value[i] - 'A' + (int)Key.A) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Skip( int amount ) {
|
||||||
|
curIndex += amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
static LwjglToKey() {
|
||||||
|
Add( Key.Unknown ); Add( Key.Escape );
|
||||||
|
for( int i = 0; i < 9; i++ )
|
||||||
|
Add( (Key)(i + Key.Number1) );
|
||||||
|
Add( Key.Number0 ); Add( Key.Minus );
|
||||||
|
Add( Key.Plus ); Add( Key.BackSpace );
|
||||||
|
Add( Key.Tab ); Add( "QWERTYUIOP" );
|
||||||
|
Add( Key.BracketLeft ); Add( Key.BracketRight );
|
||||||
|
Add( Key.Enter ); Add( Key.ControlLeft );
|
||||||
|
Add( "ASDFGHJKL" ); Add( Key.Semicolon );
|
||||||
|
Add( Key.Quote ); Add( Key.Tilde );
|
||||||
|
Add( Key.ShiftLeft ); Add( Key.BackSlash );
|
||||||
|
Add( "ZXCVBNM" ); Add( Key.Comma );
|
||||||
|
Add( Key.Period ); Add( Key.Slash );
|
||||||
|
Add( Key.ShiftRight ); Skip( 1 ); // TODO: multiply
|
||||||
|
Add( Key.AltLeft ); Add( Key.Space );
|
||||||
|
Add( Key.CapsLock );
|
||||||
|
for( int i = 0; i < 10; i++ )
|
||||||
|
Add( (Key)(i + Key.F1) );
|
||||||
|
Add( Key.NumLock ); Add( Key.ScrollLock );
|
||||||
|
Add( Key.Number7 ); Add( Key.Number8 );
|
||||||
|
Add( Key.Number9 ); Add( Key.KeypadSubtract );
|
||||||
|
Add( Key.Number4 ); Add( Key.Number5 );
|
||||||
|
Add( Key.Number6 ); Add( Key.KeypadAdd );
|
||||||
|
Add( Key.Number1 ); Add( Key.Number2 );
|
||||||
|
Add( Key.Number3 ); Add( Key.Number0 );
|
||||||
|
Add( Key.KeypadDecimal ); Skip( 3 );
|
||||||
|
Add( Key.F11 ); Add( Key.F12 );
|
||||||
|
Skip( 11 );
|
||||||
|
for( int i = 0; i < 6; i++ )
|
||||||
|
Add( (Key)(i + Key.F13) );
|
||||||
|
Skip( 35 ); Add( Key.KeypadAdd );
|
||||||
|
Skip( 14 ); Add( Key.KeypadEnter );
|
||||||
|
Add( Key.ControlRight ); Skip( 23 );
|
||||||
|
Add( Key.KeypadDivide ); Skip( 2 );
|
||||||
|
Add( Key.AltRight ); Skip( 12 );
|
||||||
|
Add( Key.Pause ); Skip( 1 );
|
||||||
|
Add( Key.Home ); Add( Key.Up );
|
||||||
|
Add( Key.PageUp ); Skip( 1 );
|
||||||
|
Add( Key.Left ); Skip( 1 );
|
||||||
|
Add( Key.Right ); Skip( 1 );
|
||||||
|
Add( Key.End ); Add( Key.Down );
|
||||||
|
Add( Key.PageDown ); Add( Key.Insert );
|
||||||
|
Add( Key.Delete ); Skip( 7 );
|
||||||
|
Add( Key.WinLeft ); Add( Key.WinRight );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using ClassicalSharp.TexturePack;
|
using ClassicalSharp.TexturePack;
|
||||||
using OpenTK.Input;
|
using OpenTK.Input;
|
||||||
|
using ClassicalSharp.Hotkeys;
|
||||||
|
|
||||||
namespace ClassicalSharp {
|
namespace ClassicalSharp {
|
||||||
|
|
||||||
@ -57,7 +58,7 @@ namespace ClassicalSharp {
|
|||||||
"EmoteFix", "ClickDistance", "HeldBlock", "BlockPermissions",
|
"EmoteFix", "ClickDistance", "HeldBlock", "BlockPermissions",
|
||||||
"SelectionCuboid", "MessageTypes", "CustomBlocks", "EnvColors",
|
"SelectionCuboid", "MessageTypes", "CustomBlocks", "EnvColors",
|
||||||
"HackControl", "EnvMapAppearance", "ExtPlayerList", "ChangeModel",
|
"HackControl", "EnvMapAppearance", "ExtPlayerList", "ChangeModel",
|
||||||
"EnvWeatherType", "PlayerClick", // NOTE: There are no plans to support TextHotKey.
|
"EnvWeatherType", "PlayerClick", "TextHotKey",
|
||||||
};
|
};
|
||||||
|
|
||||||
void HandleCpeExtInfo() {
|
void HandleCpeExtInfo() {
|
||||||
@ -126,6 +127,27 @@ namespace ClassicalSharp {
|
|||||||
game.Inventory.CanChangeHeldBlock = canChange;
|
game.Inventory.CanChangeHeldBlock = canChange;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HandleCpeSetTextHotkey() {
|
||||||
|
string label = reader.ReadAsciiString();
|
||||||
|
string action = reader.ReadAsciiString();
|
||||||
|
int keyCode = reader.ReadInt32();
|
||||||
|
byte keyMods = reader.ReadUInt8();
|
||||||
|
|
||||||
|
if( keyCode < 0 || keyCode > 255 ) return;
|
||||||
|
Key key = LwjglToKey.Map[keyCode];
|
||||||
|
if( key == Key.Unknown ) return;
|
||||||
|
|
||||||
|
Console.WriteLine( "CPE Hotkey added: " + key + "," + keyMods + " : " + action );
|
||||||
|
if( action == "" ) {
|
||||||
|
game.InputHandler.Hotkeys.RemoveHotkey( key, keyMods );
|
||||||
|
} else if( action[action.Length - 1] == '\n' ) { // more input needed by user
|
||||||
|
action = action.Substring( 0, action.Length - 1 );
|
||||||
|
game.InputHandler.Hotkeys.AddHotkey( key, keyMods, action, true );
|
||||||
|
} else {
|
||||||
|
game.InputHandler.Hotkeys.AddHotkey( key, keyMods, action, false );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void HandleCpeExtAddPlayerName() {
|
void HandleCpeExtAddPlayerName() {
|
||||||
short nameId = reader.ReadInt16();
|
short nameId = reader.ReadInt16();
|
||||||
string playerName = Utils.StripColours( reader.ReadAsciiString() );
|
string playerName = Utils.StripColours( reader.ReadAsciiString() );
|
||||||
|
@ -455,7 +455,7 @@ namespace ClassicalSharp {
|
|||||||
HandleMessage, HandleKick, HandleSetPermission,
|
HandleMessage, HandleKick, HandleSetPermission,
|
||||||
|
|
||||||
HandleCpeExtInfo, HandleCpeExtEntry, HandleCpeSetClickDistance,
|
HandleCpeExtInfo, HandleCpeExtEntry, HandleCpeSetClickDistance,
|
||||||
HandleCpeCustomBlockSupportLevel, HandleCpeHoldThis, null,
|
HandleCpeCustomBlockSupportLevel, HandleCpeHoldThis, HandleCpeSetTextHotkey,
|
||||||
HandleCpeExtAddPlayerName, HandleCpeExtAddEntity, HandleCpeExtRemovePlayerName,
|
HandleCpeExtAddPlayerName, HandleCpeExtAddEntity, HandleCpeExtRemovePlayerName,
|
||||||
HandleCpeEnvColours, HandleCpeMakeSelection, HandleCpeRemoveSelection,
|
HandleCpeEnvColours, HandleCpeMakeSelection, HandleCpeRemoveSelection,
|
||||||
HandleCpeSetBlockPermission, HandleCpeChangeModel, HandleCpeEnvSetMapApperance,
|
HandleCpeSetBlockPermission, HandleCpeChangeModel, HandleCpeEnvSetMapApperance,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user