diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/Hotkey.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/Hotkey.java
new file mode 100644
index 00000000..d149eedd
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/Hotkey.java
@@ -0,0 +1,77 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2023 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.bausystem.features.script;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.EqualsAndHashCode;
+
+@AllArgsConstructor
+@Builder
+@EqualsAndHashCode
+public class Hotkey {
+
+ private final int charcode;
+
+ private final boolean ctrl;
+ private final boolean shift;
+ private final boolean alt;
+ private final boolean meta;
+
+ public static Hotkey fromString(String string) {
+ String[] parts = string.split("\\+");
+ HotkeyBuilder builder = Hotkey.builder();
+
+ for (String part : parts) {
+ switch (part.toLowerCase()) {
+ case "ctrl":
+ builder.ctrl(true);
+ break;
+ case "shift":
+ builder.shift(true);
+ break;
+ case "alt":
+ builder.alt(true);
+ break;
+ case "meta":
+ builder.meta(true);
+ break;
+ default:
+ if (part.length() == 1) {
+ builder.charcode(Character.toLowerCase(part.charAt(0)));
+ } else {
+ throw new IllegalArgumentException("Invalid hotkey: " + string);
+ }
+ }
+ }
+
+ return builder.build();
+ }
+
+ public static Hotkey fromChar(int c, int mods) {
+ return Hotkey.builder()
+ .charcode(Character.toLowerCase(c))
+ .shift((mods & 1) != 0)
+ .ctrl((mods & 2) != 0)
+ .alt((mods & 4) != 0)
+ .meta((mods & 8) != 0)
+ .build();
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptRunner.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptRunner.java
index 7c3bac7f..ab4feb4a 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptRunner.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptRunner.java
@@ -27,10 +27,7 @@ import org.luaj.vm2.Globals;
import org.luaj.vm2.LuaFunction;
import org.luaj.vm2.LuaValue;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
public class ScriptRunner {
@@ -40,6 +37,7 @@ public class ScriptRunner {
// Value ->
private static final Map>> EVENT_MAP = new HashMap<>();
+ private static final Map>> HOTKEY_MAP = new HashMap<>();
private static final Map> COMMAND_MAP = new HashMap<>();
public static void runScript(String script, Player player) {
@@ -55,7 +53,8 @@ public class ScriptRunner {
public static void createGlobalScript(List scripts, Player player) {
EVENT_MAP.remove(player);
Globals globals = SteamWarPlatform.createGlobalGlobals(player,
- (s, luaFunction) -> EVENT_MAP.computeIfAbsent(player, player1 -> new HashMap<>()).computeIfAbsent(s, s1 -> new ArrayList<>()).add(luaFunction),
+ (s, luaFunction) -> EVENT_MAP.computeIfAbsent(player, player1 -> new EnumMap<>(SteamWarGlobalLuaPlugin.EventType.class)).computeIfAbsent(s, s1 -> new ArrayList<>()).add(luaFunction),
+ (s, luaFunction) -> HOTKEY_MAP.computeIfAbsent(player, player1 -> new HashMap<>()).computeIfAbsent(Hotkey.fromString(s), s1 -> new ArrayList<>()).add(luaFunction),
commandRegister -> COMMAND_MAP.computeIfAbsent(player, player1 -> new HashMap<>()).put(commandRegister.getName(), commandRegister));
for (String script : scripts) {
@@ -91,4 +90,9 @@ public class ScriptRunner {
commandRegister.getFunction().call(args);
}
+
+ public static void callHotkey(int mods, int key, Player player, boolean pressed) {
+ Hotkey hotkey = Hotkey.fromChar(key, mods);
+ HOTKEY_MAP.get(player).getOrDefault(hotkey, Collections.emptyList()).forEach(luaFunction -> luaFunction.call(LuaValue.valueOf(pressed)));
+ }
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/HotkeyListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/HotkeyListener.java
new file mode 100644
index 00000000..d6280b50
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/HotkeyListener.java
@@ -0,0 +1,54 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2023 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.bausystem.features.script.event;
+
+import de.steamwar.bausystem.BauSystem;
+import de.steamwar.bausystem.features.script.ScriptRunner;
+import de.steamwar.linkage.Linked;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+import org.bukkit.plugin.messaging.PluginMessageListener;
+
+@Linked
+public class HotkeyListener implements PluginMessageListener {
+
+ {
+ Bukkit.getServer().getMessenger().registerIncomingPluginChannel(BauSystem.getInstance(), "sw:hotkeys", this);
+ }
+
+ @Override
+ public void onPluginMessageReceived(String channel, Player player, byte[] message) {
+ if (!channel.equals("sw:hotkeys")) return;
+ if (message.length < 5) return;
+ int action = message[4] & 0xFF;
+ if (action == 2) return;
+ int key = (message[0] & 0xFF) << 24 | (message[1] & 0xFF) << 16 | (message[2] & 0xFF) << 8 | (message[3] & 0xFF);
+ if (!(key >= 'A' && key <= 'Z' || key >= '0' && key <= '9')) return;
+ if (message.length >= 9) {
+ int mods = (message[5] & 0xFF) << 24 | (message[6] & 0xFF) << 16 | (message[7] & 0xFF) << 8 | (message[8] & 0xFF);
+ // player.sendMessage("Hotkey: " + (char) key + " " + action + " " + Long.toBinaryString(mods));
+ ScriptRunner.callHotkey(mods, key, player, action == 1);
+ } else {
+ // player.sendMessage("Hotkey: " + (char) key + " " + action);
+ ScriptRunner.callHotkey(0, key, player, action == 1);
+ }
+ }
+
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/SteamWarGlobalLuaPlugin.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/SteamWarGlobalLuaPlugin.java
index 3e5dc4a0..f45d4549 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/SteamWarGlobalLuaPlugin.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/SteamWarGlobalLuaPlugin.java
@@ -23,9 +23,7 @@ import lombok.AllArgsConstructor;
import org.luaj.vm2.LuaFunction;
import org.luaj.vm2.LuaString;
import org.luaj.vm2.LuaValue;
-import org.luaj.vm2.Varargs;
import org.luaj.vm2.lib.TwoArgFunction;
-import org.luaj.vm2.lib.VarArgFunction;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
@@ -33,6 +31,7 @@ import java.util.function.Consumer;
@AllArgsConstructor
public class SteamWarGlobalLuaPlugin extends TwoArgFunction {
private final BiConsumer eventConsumer;
+ private final BiConsumer hotkeyConsumer;
private final Consumer commandRegisterConsumer;
@Override
@@ -56,6 +55,17 @@ public class SteamWarGlobalLuaPlugin extends TwoArgFunction {
return NIL;
}
});
+ env.set("hotkey", new TwoArgFunction() {
+ @Override
+ public LuaValue call(LuaValue arg1, LuaValue arg2) {
+ LuaString key = arg1.checkstring();
+ LuaFunction function = arg2.checkfunction();
+
+ hotkeyConsumer.accept(key.tojstring().toLowerCase(), function);
+
+ return null;
+ }
+ });
return NIL;
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/SteamWarPlatform.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/SteamWarPlatform.java
index 2cd2e023..a20fa190 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/SteamWarPlatform.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/SteamWarPlatform.java
@@ -51,9 +51,9 @@ public class SteamWarPlatform {
return globals;
}
- public static Globals createGlobalGlobals(Player player, BiConsumer eventConsumer, Consumer commandConsumer) {
+ public static Globals createGlobalGlobals(Player player, BiConsumer eventConsumer, BiConsumer hotkeyConsumer, Consumer commandConsumer) {
Globals globals = createClickGlobals(player);
- globals.load(new SteamWarGlobalLuaPlugin(eventConsumer, commandConsumer));
+ globals.load(new SteamWarGlobalLuaPlugin(eventConsumer, hotkeyConsumer, commandConsumer));
return globals;
}
}