Add BauSystem module

Fix ci java version
Fix LinkageProcessor
This commit is contained in:
2024-08-05 13:28:50 +02:00
parent 41d31e6c9c
commit 3366a30b0c
526 changed files with 43550 additions and 149479 deletions
@@ -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 <https://www.gnu.org/licenses/>.
*/
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();
}
}
@@ -0,0 +1,37 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.script;
import de.steamwar.command.SWCommand;
import de.steamwar.linkage.Linked;
import org.bukkit.entity.Player;
@Linked
public class ScriptCommand extends SWCommand {
public ScriptCommand() {
super("script");
}
@Register
public void genericCommand(@Validator Player player) {
ScriptGUI.open(player);
}
}
@@ -0,0 +1,141 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.script;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.SWUtils;
import de.steamwar.bausystem.features.script.lua.SteamWarPlatform;
import de.steamwar.bausystem.utils.ItemUtils;
import de.steamwar.inventory.SWAnvilInv;
import de.steamwar.inventory.SWItem;
import de.steamwar.inventory.SWListInv;
import de.steamwar.linkage.Linked;
import de.steamwar.sql.Script;
import de.steamwar.sql.SteamwarUser;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BookMeta;
import org.luaj.vm2.Globals;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
@Linked
public class ScriptGUI implements Listener {
public static void open(Player player) {
open(player, null);
}
private static void open(Player player, ItemStack setCursor) {
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
List<SWListInv.SWListEntry<Script>> entries = new ArrayList<>();
List<String> lore = new ArrayList<>();
Globals globals = SteamWarPlatform.createGlobalParser(
(eventType, luaFunction) -> lore.add(BauSystem.MESSAGE.parse("SCRIPT_EVENT_ITEM_NAME", player, eventType.name())),
(s, luaFunction) -> lore.add(BauSystem.MESSAGE.parse("SCRIPT_HOTKEY_ITEM_NAME", player, s)),
commandRegister -> lore.add(BauSystem.MESSAGE.parse("SCRIPT_COMMAND_ITEM_NAME", player, commandRegister.getName()))
);
Script.list(user).forEach(script -> {
try {
globals.load(script.getCode()).call();
} catch (Exception e) {
String[] sp = e.getMessage().split(":");
lore.add(BauSystem.MESSAGE.parse("SCRIPT_ERROR_GUI", player, String.join(":", Arrays.copyOfRange(sp, 1, sp.length))));
}
if(!lore.isEmpty()) {
lore.add("");
}
lore.add(BauSystem.MESSAGE.parse("SCRIPT_MENU_GUI_ITEM_LORE_1", player));
lore.add(BauSystem.MESSAGE.parse("SCRIPT_MENU_GUI_ITEM_LORE_2", player));
lore.add(BauSystem.MESSAGE.parse("SCRIPT_MENU_GUI_ITEM_LORE_3", player));
lore.add(BauSystem.MESSAGE.parse("SCRIPT_MENU_GUI_ITEM_LORE_4", player));
entries.add(new SWListInv.SWListEntry<>(new SWItem(Material.ENCHANTED_BOOK, script.getName(), new ArrayList<>(lore), false, clickType -> {}), script));
lore.clear();
});
SWListInv<Script> inv = new SWListInv<>(player, BauSystem.MESSAGE.parse("SCRIPT_MENU_GUI_NAME", player), false, entries, (clickType, script) -> {
ItemStack itemStack = ScriptHelper.getScriptItem(script, clickType.isRightClick());
if(clickType == ClickType.MIDDLE) {
player.openBook(itemStack);
} else if(!clickType.isShiftClick()) {
script.delete();
ScriptRunner.updateGlobalScript(player);
open(player, itemStack);
} else {
player.getOpenInventory().setCursor(itemStack);
}
});
inv.setItem(49, Material.HOPPER, BauSystem.MESSAGE.parse("SCRIPT_MENU_GUI_ITEM_ADD_NAME", player), Collections.singletonList(BauSystem.MESSAGE.parse("SCRIPT_MENU_GUI_ITEM_ADD_LORE", player)), false, click -> {
if(player.getOpenInventory().getCursor() != null) {
ItemStack cursor = player.getOpenInventory().getCursor();
if(!(cursor.getItemMeta() instanceof BookMeta)) {
return;
}
BookMeta meta = (BookMeta) cursor.getItemMeta();
if(meta == null) {
return;
}
saveWithName(player, meta, meta.getTitle());
}
});
inv.open();
if(setCursor != null) {
player.getOpenInventory().setCursor(setCursor);
}
}
private static void saveWithName(Player player, BookMeta meta, String name) {
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
if(name != null && Script.list(user).stream().noneMatch(script -> script.getName().equalsIgnoreCase(name))) {
Script.create(user, name, ScriptHelper.getScriptString(meta.getPages()));
player.getOpenInventory().setCursor(null);
ScriptRunner.updateGlobalScript(player);
open(player);
} else {
SWAnvilInv inv = new SWAnvilInv(player, BauSystem.MESSAGE.parse("SCRIPT_MENU_GUI_ENTER_NAME", player), name == null ? "" : name);
AtomicBoolean saved = new AtomicBoolean(false);
ItemStack itemStack = player.getOpenInventory().getCursor();
inv.setCallback(s -> {
saveWithName(player, meta, s);
saved.set(true);
});
inv.addCloseCallback(() -> {
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
if (saved.get()) return;
SWUtils.giveItemToPlayer(player, itemStack);
}, 1);
});
inv.open();
}
}
}
@@ -0,0 +1,55 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.script;
import de.steamwar.sql.Script;
import de.steamwar.sql.SteamwarUser;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BookMeta;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class ScriptHelper {
private static final String PAGE_SEPARATOR = "\n\0\n";
public static ItemStack getScriptItem(Script script, boolean writeable) {
ItemStack itemStack = new ItemStack(writeable ? Material.WRITABLE_BOOK : Material.WRITTEN_BOOK);
BookMeta meta = (BookMeta) itemStack.getItemMeta();
if(!writeable) {
meta.setTitle(script.getName());
meta.setAuthor(SteamwarUser.get(script.getUserId()).getUserName());
}
meta.setPages(getScriptPages(script));
itemStack.setItemMeta(meta);
return itemStack;
}
public static List<String> getScriptPages(Script script) {
return Arrays.stream(script.getCode().split(PAGE_SEPARATOR)).collect(Collectors.toList());
}
public static String getScriptString(List<String> pages) {
return String.join(PAGE_SEPARATOR, pages);
}
}
@@ -0,0 +1,84 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.script;
import de.steamwar.bausystem.Permission;
import de.steamwar.bausystem.utils.BauMemberUpdateEvent;
import de.steamwar.bausystem.utils.FlatteningWrapper;
import de.steamwar.linkage.Linked;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BookMeta;
import java.util.HashSet;
import java.util.Set;
@Linked
public class ScriptListener implements Listener {
private final Set<Player> playerSet = new HashSet<>();
@EventHandler(priority = EventPriority.HIGH)
public void onLeftClick(PlayerInteractEvent event) {
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
ItemStack item = event.getItem();
if (item == null || FlatteningWrapper.impl.isNoBook(item) || item.getItemMeta() == null) {
return;
}
if (event.getAction() != Action.LEFT_CLICK_AIR && event.getAction() != Action.LEFT_CLICK_BLOCK) {
if (event.getAction() == Action.RIGHT_CLICK_AIR) {
playerSet.add(event.getPlayer());
}
return;
}
if (playerSet.remove(event.getPlayer())) {
return;
}
event.setCancelled(true);
ScriptRunner.runScript(((BookMeta) item.getItemMeta()).getPages().stream().reduce((s, s2) -> s + "\n" + s2).orElse(null), event.getPlayer());
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
ScriptRunner.remove(event.getPlayer());
}
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
ScriptRunner.updateGlobalScript(event.getPlayer());
}
@EventHandler
public void onBauMemberUpdate(BauMemberUpdateEvent event) {
event.getNewSpectator().forEach(ScriptRunner::remove);
event.getNewBuilder().forEach(ScriptRunner::updateGlobalScript);
}
}
@@ -0,0 +1,211 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.script;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.features.script.lua.CommandRegister;
import de.steamwar.bausystem.features.script.lua.SteamWarGlobalLuaPlugin;
import de.steamwar.bausystem.features.script.lua.SteamWarPlatform;
import de.steamwar.sql.Script;
import de.steamwar.sql.SteamwarUser;
import lombok.experimental.UtilityClass;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.luaj.vm2.*;
import org.luaj.vm2.lib.OneArgFunction;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
@UtilityClass
public class ScriptRunner {
// Script Table
// User
// Key -> bau-script-<BUCH NAME>
// Value -> <LUA Script>
private static final Map<Player, Map<SteamWarGlobalLuaPlugin.EventType, List<LuaFunction>>> EVENT_MAP = new HashMap<>();
private static final Map<Player, Map<Hotkey, List<LuaFunction>>> HOTKEY_MAP = new HashMap<>();
private static final Map<Player, Map<String, CommandRegister>> COMMAND_MAP = new HashMap<>();
public Set<String> getCommandsOfPlayer(Player player) {
return COMMAND_MAP.getOrDefault(player, new HashMap<>()).keySet();
}
public static void runScript(String script, Player player) {
Globals globals = SteamWarPlatform.createClickGlobals(player);
catchScript("SCRIPT_ERROR_CLICK", player, () -> globals.load(script).call());
}
public static void updateGlobalScript(Player player) {
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
ScriptRunner.createGlobalScript(Script.list(user).stream().map(Script::getCode).collect(Collectors.toList()), player);
}
public static void createGlobalScript(List<String> scripts, Player player) {
remove(player);
Globals globals = SteamWarPlatform.createGlobalGlobals(player,
(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) {
catchScript("SCRIPT_ERROR_GLOBAL", player, () -> globals.load(script).call());
}
}
public static void remove(Player player) {
EVENT_MAP.remove(player);
COMMAND_MAP.remove(player);
HOTKEY_MAP.remove(player);
}
public static void callEvent(Player player, SteamWarGlobalLuaPlugin.EventType event, LuaValue eventValue, Event wrappedEvent) {
List<LuaFunction> luaFunctions = EVENT_MAP.getOrDefault(player, Collections.emptyMap()).getOrDefault(event, Collections.emptyList());
if (luaFunctions.isEmpty()) {
if(event == SteamWarGlobalLuaPlugin.EventType.DoubleSwap) {
player.performCommand("gui");
}
return;
}
if (eventValue == LuaValue.NIL) {
eventValue = LuaValue.tableOf();
}
AtomicBoolean cancelled = new AtomicBoolean(false);
if (wrappedEvent instanceof Cancellable) {
eventValue.set("setCancelled", new OneArgFunction() {
@Override
public LuaValue call(LuaValue arg) {
cancelled.set(arg.checkboolean());
return valueOf(cancelled.get());
}
});
} else {
eventValue.set("setCancelled", new OneArgFunction() {
@Override
public LuaValue call(LuaValue arg) {
throw new LuaError("Event is not cancellable");
}
});
}
final LuaValue finalEventValue = eventValue;
for (LuaFunction luaFunction : luaFunctions) {
catchScript("SCRIPT_ERROR_GLOBAL", player, () -> luaFunction.call(finalEventValue));
}
if (wrappedEvent instanceof Cancellable) {
((Cancellable) wrappedEvent).setCancelled(cancelled.get());
}
}
public static boolean callCommand(Player player, String command, String[] argsArray) {
CommandRegister commandRegister = COMMAND_MAP.getOrDefault(player, Collections.emptyMap()).get(command);
if (commandRegister == null) {
return false;
}
LuaValue[] values = new LuaValue[argsArray.length - 1];
for (int i = 1; i < argsArray.length; i++) {
values[i - 1] = LuaValue.valueOf(argsArray[i]);
}
LuaTable args = LuaValue.listOf(values);
args.set("alias", command);
args.set("hasShortFlag", new OneArgFunction() {
@Override
public LuaValue call(LuaValue arg) {
String s = arg.checkjstring();
if (!s.matches("-?[a-zA-Z]")) {
throw new LuaError("Short Flag must be one character");
}
String flag = s.charAt(s.length() - 1) + "";
boolean hasFlag = false;
for (String arg1 : argsArray) {
if (arg1.startsWith("-") && arg1.contains(flag)) {
hasFlag = true;
break;
}
}
return valueOf(hasFlag);
}
});
args.set("removeShortFlag", new OneArgFunction() {
@Override
public LuaValue call(LuaValue arg) {
String s = arg.checkjstring();
if (!s.matches("-?[a-zA-Z]")) {
throw new LuaError("Short Flag must be one character");
}
String flag = s.charAt(s.length() - 1) + "";
boolean hasFlag = false;
for (int i = 0; i < argsArray.length; i++) {
String arg1 = argsArray[i];
if (arg1.startsWith("-") && arg1.contains(flag)) {
String newArg = arg1.replace(flag, "");
if (newArg.equals("-")) {
args.remove(i);
} else {
args.set(i, newArg);
}
hasFlag = true;
break;
}
}
return valueOf(hasFlag);
}
});
catchScript("SCRIPT_ERROR_GLOBAL", player, () -> commandRegister.getFunction().call(args));
return true;
}
public static void callHotkey(int mods, int key, Player player, boolean pressed) {
Hotkey hotkey = Hotkey.fromChar(key, mods);
catchScript("SCRIPT_ERROR_GLOBAL", player, () -> HOTKEY_MAP.getOrDefault(player, Collections.emptyMap()).getOrDefault(hotkey, Collections.emptyList()).forEach(luaFunction -> luaFunction.call(LuaValue.valueOf(pressed))));
}
public static void catchScript(String errorMsg, Player player, Runnable run) {
try {
run.run();
} catch (Exception e) {
String[] sp = e.getMessage().split(":");
int index = 0;
for (int i = sp.length - 1; i >= 0; i--) {
String[] ss = sp[i].split(" ");
boolean num = ss[0].chars().mapToObj(Character::isDigit).allMatch(b -> b);
if (num && !ss[0].isEmpty()) {
index = i;
break;
}
}
BauSystem.MESSAGE.send(errorMsg, player, String.join(":", Arrays.copyOfRange(sp, index, sp.length)));
}
}
}
@@ -0,0 +1,44 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.script;
import de.steamwar.bausystem.utils.FlatteningWrapper;
import de.steamwar.command.SWCommand;
import de.steamwar.linkage.Linked;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
@Linked
public class UnsignCommand extends SWCommand {
public UnsignCommand() {
super("unsign");
}
@Register(description = "UNSIGN_HELP")
public void unsignCommand(Player p) {
ItemStack itemStack = p.getInventory().getItemInMainHand();
if (FlatteningWrapper.impl.isNoBook(itemStack)) return;
ItemStack clone = new ItemStack(Material.WRITABLE_BOOK);
clone.setItemMeta(itemStack.getItemMeta());
p.getInventory().setItemInMainHand(clone);
}
}
@@ -0,0 +1,65 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.script.event;
import de.steamwar.bausystem.Permission;
import de.steamwar.bausystem.features.script.ScriptRunner;
import de.steamwar.linkage.Linked;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.luaj.vm2.LuaValue;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@Linked
public class CommandListener implements Listener {
private Map<Player, Set<String>> calledCommands = new HashMap<>();
@EventHandler
public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) {
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
String[] split = event.getMessage().split(" ");
if (calledCommands.getOrDefault(event.getPlayer(), new HashSet<>()).contains(split[0])) {
return;
}
calledCommands.getOrDefault(event.getPlayer(), new HashSet<>()).add(split[0]);
event.setCancelled(ScriptRunner.callCommand(event.getPlayer(), split[0].substring(1), split));
calledCommands.getOrDefault(event.getPlayer(), new HashSet<>()).remove(split[0]);
}
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
calledCommands.put(event.getPlayer(), new HashSet<>());
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
calledCommands.remove(event.getPlayer());
}
}
@@ -0,0 +1,205 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.script.event;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.Permission;
import de.steamwar.bausystem.features.script.ScriptRunner;
import de.steamwar.bausystem.features.script.lua.SteamWarGlobalLuaPlugin;
import de.steamwar.bausystem.features.script.lua.libs.StorageLib;
import de.steamwar.bausystem.features.tpslimit.TPSUtils;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.region.utils.RegionExtensionType;
import de.steamwar.bausystem.region.utils.RegionType;
import de.steamwar.linkage.Linked;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.entity.EntitySpawnEvent;
import org.bukkit.event.player.*;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@Linked
public class EventListener implements Listener {
private static final Map<Player, Long> LAST_FS = new HashMap<>();
static {
Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), () -> {
long millis = System.currentTimeMillis();
LAST_FS.entrySet().removeIf(entry -> millis - entry.getValue() > 200);
}, 1, 1);
}
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerJoin(PlayerJoinEvent event) {
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
ScriptRunner.callEvent(event.getPlayer(), SteamWarGlobalLuaPlugin.EventType.SelfJoin, LuaValue.NIL, event);
}
@EventHandler(priority = EventPriority.HIGH)
public void onPlayerQuit(PlayerQuitEvent event) {
StorageLib.removePlayer(event.getPlayer());
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
ScriptRunner.callEvent(event.getPlayer(), SteamWarGlobalLuaPlugin.EventType.SelfLeave, LuaValue.NIL, event);
}
@EventHandler(priority = EventPriority.HIGH)
public void onPlayerSwapHandItems(PlayerSwapHandItemsEvent event) {
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
if (LAST_FS.containsKey(event.getPlayer())) {
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
ScriptRunner.callEvent(event.getPlayer(), SteamWarGlobalLuaPlugin.EventType.DoubleSwap, LuaValue.NIL, event);
}, 1);
} else {
LAST_FS.put(event.getPlayer(), System.currentTimeMillis());
}
}
@EventHandler(priority = EventPriority.HIGH)
public void onBlockPlace(BlockPlaceEvent event) {
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
LuaTable table = new LuaTable();
table.set("x", event.getBlock().getX());
table.set("y", event.getBlock().getY());
table.set("z", event.getBlock().getZ());
table.set("type", event.getBlock().getType().name());
ScriptRunner.callEvent(event.getPlayer(), SteamWarGlobalLuaPlugin.EventType.PlaceBlock, table, event);
}
@EventHandler(priority = EventPriority.HIGH)
public void onBlockBreak(BlockBreakEvent event) {
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
LuaTable table = new LuaTable();
table.set("x", event.getBlock().getX());
table.set("y", event.getBlock().getY());
table.set("z", event.getBlock().getZ());
table.set("type", event.getBlock().getType().name());
ScriptRunner.callEvent(event.getPlayer(), SteamWarGlobalLuaPlugin.EventType.BreakBlock, table, event);
}
private final Set<Player> ignore = new HashSet<>();
@EventHandler(priority = EventPriority.LOW)
public void onPlayerInteract(PlayerInteractEvent event) {
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
if (ignore.remove(event.getPlayer())) {
return;
}
LuaTable table = new LuaTable();
table.set("action", event.getAction().name());
if (event.getHand() == null) {
table.set("hand", "null");
} else {
table.set("hand", event.getHand().name());
}
table.set("block", event.getItem() == null ? Material.AIR.name() : event.getItem().getType().name());
if(event.getAction() == Action.RIGHT_CLICK_BLOCK || event.getAction() == Action.LEFT_CLICK_BLOCK) {
table.set("hasBlock", LuaValue.valueOf(true));
table.set("blockX", event.getClickedBlock().getX());
table.set("blockY", event.getClickedBlock().getY());
table.set("blockZ", event.getClickedBlock().getZ());
table.set("blockFace", event.getBlockFace().name());
table.set("blockType", event.getClickedBlock().getType().name());
} else {
table.set("hasBlock", LuaValue.valueOf(false));
}
if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) {
ScriptRunner.callEvent(event.getPlayer(), SteamWarGlobalLuaPlugin.EventType.RightClick, table, event);
} else if (event.getAction() == Action.LEFT_CLICK_AIR || event.getAction() == Action.LEFT_CLICK_BLOCK) {
ScriptRunner.callEvent(event.getPlayer(), SteamWarGlobalLuaPlugin.EventType.LeftClick, table, event);
}
}
@EventHandler(priority = EventPriority.HIGH)
public void onEntitySpawn(EntitySpawnEvent event) {
if (event.getEntityType() != EntityType.PRIMED_TNT) {
return;
}
Region tntRegion = Region.getRegion(event.getLocation());
for (Player player : Bukkit.getOnlinePlayers()) {
if(!Permission.BUILD.hasPermission(player)) continue;
if (tntRegion.inRegion(player.getLocation(), RegionType.NORMAL, RegionExtensionType.NORMAL)) {
ScriptRunner.callEvent(player, SteamWarGlobalLuaPlugin.EventType.TNTSpawn, LuaValue.NIL, event);
}
}
}
@EventHandler(priority = EventPriority.LOWEST)
public void onEntityExplode(EntityExplodeEvent event) {
if (event.getEntityType() != EntityType.PRIMED_TNT) {
return;
}
Region tntRegion = Region.getRegion(event.getLocation());
LuaTable table = new LuaTable();
table.set("x", event.getLocation().getX());
table.set("y", event.getLocation().getY());
table.set("z", event.getLocation().getZ());
boolean inBuild = event.blockList().stream().anyMatch(block -> tntRegion.inRegion(block.getLocation(), RegionType.BUILD, RegionExtensionType.EXTENSION));
for (Player player : Bukkit.getOnlinePlayers()) {
if(!Permission.BUILD.hasPermission(player)) continue;
if (tntRegion.inRegion(player.getLocation(), RegionType.NORMAL, RegionExtensionType.NORMAL)) {
ScriptRunner.callEvent(player, SteamWarGlobalLuaPlugin.EventType.TNTExplode, table, event);
if (inBuild) {
ScriptRunner.callEvent(player, SteamWarGlobalLuaPlugin.EventType.TNTExplodeInBuild, table, event);
}
}
}
}
@EventHandler(priority = EventPriority.HIGH)
public void onPlayerDropItem(PlayerDropItemEvent event) {
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
ignore.add(event.getPlayer());
LuaTable table = new LuaTable();
table.set("type", event.getItemDrop().getItemStack().getType().name());
ScriptRunner.callEvent(event.getPlayer(), SteamWarGlobalLuaPlugin.EventType.DropItem, table, event);
}
@EventHandler(priority = EventPriority.HIGH)
public void onEntityDeath(EntityDeathEvent event) {
for (Player player : Bukkit.getOnlinePlayers()) {
if(!Permission.BUILD.hasPermission(player)) continue;
LuaTable table = new LuaTable();
table.set("type", event.getEntityType().name());
ScriptRunner.callEvent(player, SteamWarGlobalLuaPlugin.EventType.EntityDeath, table, event);
}
}
}
@@ -0,0 +1,57 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.script.event;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.Permission;
import de.steamwar.bausystem.features.script.ScriptRunner;
import de.steamwar.linkage.Linked;
import de.steamwar.linkage.api.Plain;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.plugin.messaging.PluginMessageListener;
@Linked
public class HotkeyListener implements PluginMessageListener, Plain {
{
Bukkit.getServer().getMessenger().registerIncomingPluginChannel(BauSystem.getInstance(), "sw:hotkeys", this);
}
@Override
public void onPluginMessageReceived(String channel, Player player, byte[] message) {
if(!Permission.BUILD.hasPermission(player)) return;
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);
}
}
}
@@ -0,0 +1,32 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.script.lua;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.luaj.vm2.LuaFunction;
@AllArgsConstructor
@Getter
public class CommandRegister {
private final String name;
private final LuaFunction function;
}
@@ -0,0 +1,105 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.script.lua;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import org.luaj.vm2.LuaFunction;
import org.luaj.vm2.LuaString;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.lib.TwoArgFunction;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class SteamWarGlobalLuaPlugin extends TwoArgFunction {
private final BiConsumer<EventType, LuaFunction> eventConsumer;
private final BiConsumer<String, LuaFunction> hotkeyConsumer;
private final Consumer<CommandRegister> commandRegisterConsumer;
@Override
public LuaValue call(LuaValue modname, LuaValue env) {
LuaValue types = tableOf();
for (EventType value : EventType.values()) {
types.set(value.name(), value.ordinal());
}
env.set("events", types);
env.set("event", new On());
env.set("command", new TwoArgFunction() {
@Override
public LuaValue call(LuaValue arg1, LuaValue arg2) {
LuaString command = arg1.checkstring();
LuaFunction function = arg2.checkfunction();
commandRegisterConsumer.accept(new CommandRegister(command.tojstring().toLowerCase(), function));
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;
}
class On extends TwoArgFunction {
@Override
public LuaValue call(LuaValue eventName, LuaValue function) {
int ord = eventName.checkint();
LuaFunction luaFunction = function.checkfunction();
int nArgs = luaFunction.narg();
if (nArgs != 1) {
return LuaValue.valueOf("Expected 1 argument, got " + nArgs);
}
eventConsumer.accept(EventType.values()[ord], luaFunction);
return LuaValue.NIL;
}
}
public enum EventType {
DoubleSwap,
PlaceBlock,
BreakBlock,
RightClick,
LeftClick,
TNTSpawn,
TNTExplode,
TNTExplodeInBuild,
SelfJoin,
SelfLeave,
DropItem,
EntityDeath
}
}
@@ -0,0 +1,273 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.script.lua;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.bukkit.BukkitPlayer;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.event.platform.CommandEvent;
import com.sk89q.worldedit.extension.platform.Actor;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.configplayer.Config;
import de.steamwar.bausystem.features.script.ScriptRunner;
import de.steamwar.bausystem.features.script.lua.libs.LuaLib;
import de.steamwar.bausystem.features.world.WorldEditListener;
import de.steamwar.bausystem.utils.WorldEditUtils;
import de.steamwar.inventory.SWAnvilInv;
import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.chat.BaseComponent;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.luaj.vm2.LuaFunction;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Varargs;
import org.luaj.vm2.lib.*;
import java.lang.reflect.Proxy;
import java.net.InetSocketAddress;
import java.util.*;
import java.util.logging.Level;
public class SteamWarLuaPlugin extends TwoArgFunction {
private static final boolean hasFAWE = Bukkit.getPluginManager().getPlugin("FastAsyncWorldEdit") != null;
protected static final Map<Class<?>, List<LuaLib>> LUA_LIBS = new HashMap<>();
public static void add(LuaLib luaLib) {
LUA_LIBS.computeIfAbsent(luaLib.parent(), l -> new ArrayList<>()).add(luaLib);
}
private final Player player;
public SteamWarLuaPlugin(Player player) {
this.player = player;
}
@Override
public LuaValue call(LuaValue modname, LuaValue env) {
LuaValue materialLib = tableOf();
for (Material mat : Material.values()) {
materialLib.set(mat.name().toLowerCase(), valueOf(mat.name()));
}
initialize(env, null);
env.set("print", new Print());
env.set("input", new TwoArgFunction() {
@Override
public LuaValue call(LuaValue arg1, LuaValue arg2) {
String message = arg1.tojstring();
LuaFunction callback = arg2.checkfunction();
SWAnvilInv inv = new SWAnvilInv(player, message);
inv.setCallback(s -> ScriptRunner.catchScript("SCRIPT_ERROR_CLICK", player, () -> callback.call(valueOf(s))));
inv.open();
return LuaValue.NIL;
}
});
env.set("delayed", new TwoArgFunction() {
@Override
public LuaValue call(LuaValue arg1, LuaValue arg2) {
long time = arg1.checklong();
LuaFunction callback = arg2.checkfunction();
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> ScriptRunner.catchScript("SCRIPT_ERROR_CLICK", player, callback::call), time);
return LuaValue.NIL;
}
});
env.set("pos", new ThreeArgFunction() {
@Override
public LuaValue call(LuaValue arg1, LuaValue arg2, LuaValue arg3) {
double x = arg1.checkdouble();
double y = arg2.checkdouble();
double z = arg3.checkdouble();
return pos(x, y, z);
}
});
env.set("exec", new VarArgFunction() {
@Override
public Varargs invoke(Varargs args) {
String command = varArgsToString(args);
PlayerCommandPreprocessEvent preprocessEvent = new PlayerCommandPreprocessEvent(player, "/" + command);
Bukkit.getServer().getPluginManager().callEvent(preprocessEvent);
if (preprocessEvent.isCancelled()) {
return LuaValue.NIL;
}
command = preprocessEvent.getMessage().substring(1);
Bukkit.getLogger().log(Level.INFO, player.getName() + " dispatched command: " + command);
String[] commandSplit = command.split(" ");
if (!commandSplit[0].equals("select") && hasFAWE && WorldEditListener.isWorldEditCommand("/" + commandSplit[0])) {
EditSession editSession = WorldEditUtils.getEditSession(player);
Actor actor = BukkitAdapter.adapt(player);
WorldEdit.getInstance().getPlatformManager().getPlatformCommandManager().handleCommandOnCurrentThread(new CommandEvent(actor, command, editSession));
editSession.flushSession();
WorldEditUtils.addToPlayer(player, editSession);
} else {
Bukkit.getServer().dispatchCommand(player, command);
}
return LuaValue.NIL;
}
});
env.set("length", new OneArgFunction() {
@Override
public LuaValue call(LuaValue arg) {
return arg.len();
}
});
env.set("join", new TwoArgFunction() {
@Override
public LuaValue call(LuaValue arg1, LuaValue arg2) {
String separator = arg1.checkjstring();
LuaTable table = arg2.checktable();
StringBuilder builder = new StringBuilder();
for (int i = 1; i <= table.length(); i++) {
if (builder.length() != 0) builder.append(separator);
builder.append(table.get(i).tojstring());
}
return valueOf(builder.toString());
}
});
env.set("collectgarbage", NIL);
env.set("dofile", NIL);
env.set("load", NIL);
env.set("loadfile", NIL);
env.set("pcall", NIL);
env.set("rawequal", NIL);
env.set("rawget", NIL);
env.set("rawlen", NIL);
env.set("rawset", NIL);
env.set("xpcall", NIL);
return null;
}
public static LuaTable pos(double x, double y, double z) {
LuaTable position = new LuaTable();
position.set("x", x);
position.set("y", y);
position.set("z", z);
position.set("add", new OneArgFunction() {
@Override
public LuaValue call(LuaValue luaValue) {
LuaTable table = luaValue.checktable();
double dx = table.get("x").checkdouble();
double dy = table.get("y").checkdouble();
double dz = table.get("z").checkdouble();
return pos(x + dx, y + dy, z + dz);
}
});
position.set("subtract", new OneArgFunction() {
@Override
public LuaValue call(LuaValue luaValue) {
LuaTable table = luaValue.checktable();
double dx = table.get("x").checkdouble();
double dy = table.get("y").checkdouble();
double dz = table.get("z").checkdouble();
return pos(x - dx, y - dy, z - dz);
}
});
position.set("addX", new OneArgFunction() {
@Override
public LuaValue call(LuaValue luaValue) {
return pos(x + luaValue.checkdouble(), y, z);
}
});
position.set("subtractX", new OneArgFunction() {
@Override
public LuaValue call(LuaValue luaValue) {
return pos(x - luaValue.checkdouble(), y, z);
}
});
position.set("addY", new OneArgFunction() {
@Override
public LuaValue call(LuaValue luaValue) {
return pos(x, y + luaValue.checkdouble(), z);
}
});
position.set("subtractY", new OneArgFunction() {
@Override
public LuaValue call(LuaValue luaValue) {
return pos(x, y - luaValue.checkdouble(), z);
}
});
position.set("addZ", new OneArgFunction() {
@Override
public LuaValue call(LuaValue luaValue) {
return pos(x, y, z + luaValue.checkdouble());
}
});
position.set("subtractZ", new OneArgFunction() {
@Override
public LuaValue call(LuaValue luaValue) {
return pos(x, y, z - luaValue.checkdouble());
}
});
position.set("blockPos", new ZeroArgFunction() {
@Override
public LuaValue call() {
Location location = new Location(Bukkit.getWorlds().get(0), x, y, z);
return pos(location.getBlockX(), location.getBlockY(), location.getBlockZ());
}
});
return position;
}
public static String varArgsToString(Varargs args) {
StringBuilder builder = new StringBuilder();
for (int i = 1; i <= args.narg(); i++) {
if (builder.length() != 0) builder.append(" ");
LuaValue arg = args.arg(i);
builder.append(arg.tojstring());
}
return builder.toString();
}
private void initialize(LuaValue parent, Class<? extends LuaLib> clazz) {
LUA_LIBS.getOrDefault(clazz, Collections.emptyList()).forEach(luaLib -> {
LuaTable luaTable = luaLib.get(player);
parent.set(luaLib.name(), luaTable);
initialize(luaTable, luaLib.getClass());
});
}
class Print extends VarArgFunction {
@Override
public Varargs invoke(Varargs args) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', varArgsToString(args)));
return LuaValue.NIL;
}
}
}
@@ -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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.script.lua;
import de.steamwar.bausystem.BauSystem;
import org.bukkit.entity.Player;
import org.luaj.vm2.Globals;
import org.luaj.vm2.LoadState;
import org.luaj.vm2.LuaError;
import org.luaj.vm2.LuaFunction;
import org.luaj.vm2.compiler.LuaC;
import org.luaj.vm2.lib.Bit32Lib;
import org.luaj.vm2.lib.PackageLib;
import org.luaj.vm2.lib.StringLib;
import org.luaj.vm2.lib.TableLib;
import org.luaj.vm2.lib.jse.JseBaseLib;
import org.luaj.vm2.lib.jse.JseMathLib;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
public class SteamWarPlatform {
public static Globals createClickGlobals(Player player) {
Globals globals = new Globals();
globals.load(new JseBaseLib());
globals.load(new PackageLib());
globals.load(new JseMathLib());
globals.load(new TableLib());
globals.load(new Bit32Lib());
globals.load(new StringLib());
globals.load(new SteamWarLuaPlugin(player));
globals.load(new SteamWarGlobalLuaPlugin((eventType, luaFunction) -> {
throw new LuaError(BauSystem.MESSAGE.parse("SCRIPT_ERROR_ONLY_IN_GLOBAL", player));
}, (s, luaFunction) -> {
throw new LuaError(BauSystem.MESSAGE.parse("SCRIPT_ERROR_ONLY_IN_GLOBAL", player));
}, commandRegister -> {
throw new LuaError(BauSystem.MESSAGE.parse("SCRIPT_ERROR_ONLY_IN_GLOBAL", player));
}));
LoadState.install(globals);
LuaC.install(globals);
return globals;
}
public static Globals createGlobalGlobals(Player player, BiConsumer<SteamWarGlobalLuaPlugin.EventType, LuaFunction> eventConsumer, BiConsumer<String, LuaFunction> hotkeyConsumer, Consumer<CommandRegister> commandConsumer) {
Globals globals = createClickGlobals(player);
globals.load(new SteamWarGlobalLuaPlugin(eventConsumer, hotkeyConsumer, commandConsumer));
return globals;
}
public static Globals createGlobalParser(BiConsumer<SteamWarGlobalLuaPlugin.EventType, LuaFunction> eventConsumer, BiConsumer<String, LuaFunction> hotkeyConsumer, Consumer<CommandRegister> commandConsumer) {
Globals globals = new Globals();
globals.load(new SteamWarGlobalLuaPlugin(eventConsumer, hotkeyConsumer, commandConsumer));
LoadState.install(globals);
LuaC.install(globals);
return globals;
}
}
@@ -0,0 +1,130 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.script.lua.libs;
import de.steamwar.linkage.Linked;
import org.bukkit.Bukkit;
import org.bukkit.boss.BarColor;
import org.bukkit.boss.BarFlag;
import org.bukkit.boss.BarStyle;
import org.bukkit.boss.BossBar;
import org.bukkit.entity.Player;
import org.luaj.vm2.LuaError;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.lib.OneArgFunction;
import org.luaj.vm2.lib.ThreeArgFunction;
import org.luaj.vm2.lib.ZeroArgFunction;
@Linked
public class BossbarLib implements LuaLib {
@Override
public String name() {
return "bossbar";
}
@Override
public LuaTable get(Player player) {
LuaTable table = new LuaTable();
table.set("create", new ThreeArgFunction() {
@Override
public LuaValue call(LuaValue arg1, LuaValue arg2, LuaValue arg3) {
String title = arg1.checkjstring();
BarStyle style;
BarColor color;
try {
color = BarColor.valueOf(arg2.checkjstring());
style = BarStyle.valueOf(arg3.checkjstring());
} catch (IllegalArgumentException e) {
throw new LuaError("Invalid color or style");
}
BossBar bossBar = Bukkit.createBossBar(title, color, style);
bossBar.addPlayer(player);
LuaTable bbTable = new LuaTable();
bbTable.set("title", getterAndSetter("title", bossBar::getTitle, bossBar::setTitle));
bbTable.set("style", getterAndSetter("style", () -> bossBar.getStyle().name(), s -> {
try {
bossBar.setStyle(BarStyle.valueOf(s));
} catch (IllegalArgumentException e) {
throw new LuaError("Invalid style");
}
}));
bbTable.set("color", getterAndSetter("color", () -> bossBar.getColor().name(), s -> {
try {
bossBar.setColor(BarColor.valueOf(s));
} catch (IllegalArgumentException e) {
throw new LuaError("Invalid color");
}
}));
bbTable.set("progress", getterAndSetter("progress", bossBar::getProgress, bossBar::setProgress));
bbTable.set("visible", getterAndSetter("visible", bossBar::isVisible, bossBar::setVisible));
bbTable.set("hasFlag", new OneArgFunction() {
@Override
public LuaValue call(LuaValue arg) {
try {
return LuaValue.valueOf(bossBar.hasFlag(BarFlag.valueOf(arg.checkjstring())));
} catch (IllegalArgumentException e) {
throw new LuaError("Invalid flag");
}
}
});
bbTable.set("addFlag", new OneArgFunction() {
@Override
public LuaValue call(LuaValue arg) {
try {
bossBar.addFlag(BarFlag.valueOf(arg.checkjstring()));
return LuaValue.TRUE;
} catch (IllegalArgumentException e) {
throw new LuaError("Invalid flag");
}
}
});
bbTable.set("removeFlag", new OneArgFunction() {
@Override
public LuaValue call(LuaValue arg) {
try {
bossBar.removeFlag(BarFlag.valueOf(arg.checkjstring()));
return LuaValue.TRUE;
} catch (IllegalArgumentException e) {
throw new LuaError("Invalid flag");
}
}
});
bbTable.set("destroy", new ZeroArgFunction() {
@Override
public LuaValue call() {
bossBar.removeAll();
return LuaValue.NIL;
}
});
return bbTable;
}
});
return table;
}
}
@@ -0,0 +1,167 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.script.lua.libs;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.inventory.SWInventory;
import de.steamwar.inventory.SWItem;
import de.steamwar.linkage.Linked;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.luaj.vm2.LuaFunction;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Varargs;
import org.luaj.vm2.lib.OneArgFunction;
import org.luaj.vm2.lib.TwoArgFunction;
import org.luaj.vm2.lib.VarArgFunction;
import org.luaj.vm2.lib.ZeroArgFunction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@Linked
public class InventoryLib implements LuaLib {
@Override
public String name() {
return "inventory";
}
@Override
public LuaTable get(Player player) {
LuaTable inventoryLib = new LuaTable();
inventoryLib.set("create", new TwoArgFunction() {
@Override
public LuaValue call(LuaValue arg1, LuaValue arg2) {
String title = arg1.checkjstring();
int size = arg2.checkint();
SWInventory inventory = new SWInventory(player, size * 9, ChatColor.translateAlternateColorCodes('&', title));
LuaTable table = new LuaTable();
table.set("setItem", new VarArgFunction() {
@Override
public Varargs invoke(Varargs args) {
BauSystem.MESSAGE.send("SCRIPT_DEPRECATED", player, "inventory.setItem", "inventory.item");
int slot = args.checkint(1);
Material material = SWItem.getMaterial(args.checkjstring(2));
String name = ChatColor.translateAlternateColorCodes('&', args.checkjstring(3));
SWItem item = new SWItem(material, name);
if (args.narg() >= 5) {
LuaTable lore = args.checktable(4);
List<String> loreList = new ArrayList<>(lore.length());
for (int i = 1; i <= lore.length(); i++) {
loreList.add(ChatColor.translateAlternateColorCodes('&', lore.get(i).checkjstring()));
}
item.setLore(loreList);
}
if (args.narg() >= 6) {
item.setEnchanted(args.checkboolean(5));
}
if (args.narg() >= 7) {
item.getItemStack().setAmount(args.checkint(6));
}
LuaFunction handler = args.checkfunction(args.narg());
item.setCallback(clickType -> {
try {
handler.call(LuaValue.valueOf(clickType.name()));
} catch (Exception e) {
String[] sp = e.getMessage().split(":");
BauSystem.MESSAGE.send("SCRIPT_ERROR_CLICK", player, String.join(":", Arrays.copyOfRange(sp, 1, sp.length)));
}
});
inventory.setItem(slot, item);
return LuaValue.NIL;
}
});
table.set("item", new VarArgFunction() {
@Override
public Varargs invoke(Varargs args) {
int slot = args.checkint(1);
Material material = SWItem.getMaterial(args.checkjstring(2));
String name = ChatColor.translateAlternateColorCodes('&', args.checkjstring(3));
LuaFunction handler = args.checkfunction(4);
SWItem item = new SWItem(material, name, clickType -> {
try {
handler.call(LuaValue.valueOf(clickType.name()));
} catch (Exception e) {
String[] sp = e.getMessage().split(":");
BauSystem.MESSAGE.send("SCRIPT_ERROR_CLICK", player, String.join(":", Arrays.copyOfRange(sp, 1, sp.length)));
}
});
if (args.narg() >= 5) {
LuaTable lore = args.checktable(5);
List<String> loreList = new ArrayList<>(lore.length());
for (int i = 1; i <= lore.length(); i++) {
loreList.add(ChatColor.translateAlternateColorCodes('&', lore.get(i).checkjstring()));
}
item.setLore(loreList);
}
if (args.narg() >= 6) {
item.setEnchanted(args.checkboolean(6));
}
if (args.narg() >= 7) {
item.getItemStack().setAmount(args.checkint(7));
}
inventory.setItem(slot, item);
return LuaValue.NIL;
}
});
table.set("setCloseHandler", new OneArgFunction() {
@Override
public LuaValue call(LuaValue arg) {
LuaFunction function = arg.checkfunction();
inventory.addCloseRunnable(() -> {
try {
function.call();
} catch (Exception e) {
String[] sp = e.getMessage().split(":");
BauSystem.MESSAGE.send("SCRIPT_ERROR_CLICK", player, String.join(":", Arrays.copyOfRange(sp, 1, sp.length)));
}
});
return LuaValue.NIL;
}
});
table.set("open", new ZeroArgFunction() {
@Override
public LuaValue call() {
inventory.open();
return LuaValue.NIL;
}
});
return table;
}
});
return inventoryLib;
}
}
@@ -0,0 +1,136 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.script.lua.libs;
import de.steamwar.bausystem.region.Point;
import lombok.AllArgsConstructor;
import org.bukkit.entity.Player;
import org.luaj.vm2.*;
import org.luaj.vm2.lib.VarArgFunction;
import org.luaj.vm2.lib.ZeroArgFunction;
import java.util.function.Consumer;
import java.util.function.Supplier;
public interface LuaLib {
static <T> LuaValue runGetter(Supplier<T> supplier) {
T value = supplier.get();
if (value == null) {
return LuaValue.NIL;
}
Class<?> clazz = value.getClass();
if (clazz == Integer.class) {
return LuaValue.valueOf((int) value);
} else if (clazz == Long.class) {
return LuaValue.valueOf((int) (long) value);
} else if (clazz == Double.class) {
return LuaValue.valueOf((double) value);
} else if (clazz == Float.class) {
return LuaValue.valueOf((float) value);
} else if (clazz == String.class) {
return LuaValue.valueOf((String) value);
} else if (clazz == Boolean.class) {
return LuaValue.valueOf((boolean) value);
}
return LuaValue.NIL;
}
default <T> LuaFunction getter(Supplier<T> supplier) {
return new ZeroArgFunction() {
@Override
public LuaValue call() {
return runGetter(supplier);
}
};
}
default <T> LuaFunction getterAndSetter(String name, Supplier<T> supplier, Consumer<T> consumer) {
return new GetterAndSetter<>(name, supplier, consumer);
}
default String varArgsToString(Varargs varargs) {
return de.steamwar.bausystem.features.script.lua.SteamWarLuaPlugin.varArgsToString(varargs);
}
default LuaTable toPos(Point point) {
if (point == null) return LuaTable.tableOf();
return LuaValue.tableOf(new LuaValue[] {
LuaValue.valueOf("x"), LuaValue.valueOf(point.getX()),
LuaValue.valueOf("y"), LuaValue.valueOf(point.getY()),
LuaValue.valueOf("z"), LuaValue.valueOf(point.getZ())
});
}
default Class<? extends LuaLib> parent() {
return null;
}
String name();
LuaTable get(Player player);
@AllArgsConstructor
class GetterAndSetter<T> extends VarArgFunction {
private String name;
private Supplier<T> supplier;
private Consumer consumer;
@Override
public Varargs invoke(Varargs args) {
if (args.narg() == 0) {
return runGetter(supplier);
} else {
if (args.narg() == 1) {
LuaValue luaValue = args.arg(1);
try {
try {
consumer.accept(luaValue.toboolean());
return NIL;
} catch (Exception ingored) {}
try {
consumer.accept((long) luaValue.toint());
return NIL;
} catch (Exception ignored) {}
try {
consumer.accept(luaValue.toint());
return NIL;
} catch (Exception ignored) {}
try {
consumer.accept(luaValue.todouble());
return NIL;
} catch (Exception ignored) {}
try {
consumer.accept((float) luaValue.todouble());
return NIL;
} catch (Exception ignored) {}
try {
consumer.accept(luaValue.toString());
return NIL;
} catch (Exception ignored) {}
throw new LuaError("Invalid lua type: " + luaValue.typename());
} catch (Throwable throwable) {
throw new LuaError("Error in '" + name + "' " + throwable.getMessage());
}
}
return NIL;
}
}
}
}
@@ -0,0 +1,122 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.script.lua.libs;
import de.steamwar.bausystem.features.script.lua.SteamWarLuaPlugin;
import de.steamwar.linkage.Linked;
import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Varargs;
import org.luaj.vm2.lib.VarArgFunction;
import org.luaj.vm2.lib.ZeroArgFunction;
@Linked
public class PlayerLib implements LuaLib {
public String name() {
return "player";
}
public LuaTable get(Player player) {
LuaTable table = new LuaTable();
table.set("name", getter(player::getName));
table.set("chat", new Print(player));
table.set("actionbar", new SendActionbar(player));
table.set("pos", getter(() -> {
return SteamWarLuaPlugin.pos(player.getLocation().getX(), player.getLocation().getY(), player.getLocation().getZ());
}));
table.set("blockPos", getter(() -> {
return SteamWarLuaPlugin.pos(player.getLocation().getBlockX(), player.getLocation().getBlockY(), player.getLocation().getBlockZ());
}));
table.set("x", getterAndSetter("x", () -> player.getLocation().getX(), x -> {
Location location = player.getLocation();
location.setX(x);
player.teleport(location);
}));
table.set("y", getterAndSetter("y", () -> player.getLocation().getY(), y -> {
Location location = player.getLocation();
location.setY(y);
player.teleport(location);
}));
table.set("z", getterAndSetter("z", () -> player.getLocation().getZ(), z -> {
Location location = player.getLocation();
location.setZ(z);
player.teleport(location);
}));
table.set("yaw", getterAndSetter("yaw", () -> player.getLocation().getYaw(), yaw -> {
Location location = player.getLocation();
location.setYaw(yaw);
player.teleport(location);
}));
table.set("pitch", getterAndSetter("pitch", () -> player.getLocation().getPitch(), pitch -> {
Location location = player.getLocation();
location.setPitch(pitch);
player.teleport(location);
}));
table.set("sneaking", getter(player::isSneaking));
table.set("sprinting", getter(player::isSprinting));
table.set("slot", getterAndSetter("slot", () -> player.getInventory().getHeldItemSlot(), player.getInventory()::setHeldItemSlot));
table.set("item", getter(() -> player.getInventory().getItemInMainHand().getType().name()));
table.set("offHandItem", getter(() -> player.getInventory().getItemInOffHand().getType().name()));
table.set("closeInventory", new ZeroArgFunction() {
@Override
public LuaValue call() {
player.closeInventory();
return LuaValue.NIL;
}
});
return table;
}
private class Print extends VarArgFunction {
private final Player player;
public Print(Player player) {
this.player = player;
}
@Override
public Varargs invoke(Varargs args) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', varArgsToString(args)));
return LuaValue.NIL;
}
}
private class SendActionbar extends VarArgFunction {
private final Player player;
public SendActionbar(Player player) {
this.player = player;
}
@Override
public Varargs invoke(Varargs args) {
player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(ChatColor.translateAlternateColorCodes('&', varArgsToString(args))));
return LuaValue.NIL;
}
}
}
@@ -0,0 +1,95 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.script.lua.libs;
import de.steamwar.linkage.Linked;
import org.bukkit.entity.Player;
import org.luaj.vm2.LuaError;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Varargs;
import org.luaj.vm2.lib.VarArgFunction;
import java.util.Random;
@Linked
public class RandomLib implements LuaLib {
private static Random random = new Random();
@Override
public String name() {
return "random";
}
@Override
public LuaTable get(Player player) {
LuaTable randomLib = new LuaTable();
randomLib.set("nextInt", new NextInt());
randomLib.set("nextDouble", new NextDouble());
randomLib.set("nextBool", new NextBool());
return randomLib;
}
private static class NextInt extends VarArgFunction {
@Override
public Varargs invoke(Varargs args) {
if (args.narg() == 0) {
return LuaValue.valueOf(random.nextInt());
}
if (args.narg() == 1) {
return LuaValue.valueOf(random.nextInt(args.checkint(1)));
}
if (args.narg() == 2) {
return LuaValue.valueOf(random.nextInt(args.checkint(1), args.checkint(2)));
}
throw new LuaError("Invalid number of arguments for random.nextInt() zero, one or two expected got " + args.narg());
}
}
private static class NextDouble extends VarArgFunction {
@Override
public Varargs invoke(Varargs args) {
if (args.narg() == 0) {
return LuaValue.valueOf(random.nextDouble());
}
if (args.narg() == 1) {
return LuaValue.valueOf(random.nextDouble(args.checkdouble(1)));
}
if (args.narg() == 2) {
return LuaValue.valueOf(random.nextDouble(args.checkdouble(1), args.checkdouble(2)));
}
throw new LuaError("Invalid number of arguments for random.nextDouble() zero, one or two expected got " + args.narg());
}
}
private static class NextBool extends VarArgFunction {
@Override
public Varargs invoke(Varargs args) {
if (args.narg() == 0) {
return LuaValue.valueOf(random.nextBoolean());
}
throw new LuaError("Invalid number of arguments for random.nextBoolean() zero expected got " + args.narg());
}
}
}
@@ -0,0 +1,110 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.script.lua.libs;
import de.steamwar.bausystem.features.loader.Loader;
import de.steamwar.bausystem.region.GlobalRegion;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.region.flags.Flag;
import de.steamwar.bausystem.region.flags.flagvalues.FireMode;
import de.steamwar.bausystem.region.flags.flagvalues.FreezeMode;
import de.steamwar.bausystem.region.flags.flagvalues.ProtectMode;
import de.steamwar.bausystem.region.flags.flagvalues.TNTMode;
import de.steamwar.linkage.Linked;
import org.bukkit.entity.Player;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.lib.OneArgFunction;
import java.util.function.Supplier;
@Linked
public class RegionLib implements LuaLib {
@Override
public String name() {
return "region";
}
private LuaTable create(Supplier<Region> region, Player player) {
LuaTable table = LuaValue.tableOf();
table.set("name", getter(() -> region.get().getName()));
table.set("type", getter(() -> {
Region region1 = region.get();
if (region1 instanceof GlobalRegion) {
return "global";
} else {
return region1.getPrototype().getName();
}
}));
LuaValue tntLib = LuaValue.tableOf();
tntLib.set("mode", getter(() -> region.get().getPlain(Flag.TNT, TNTMode.class).name()));
tntLib.set("enabled", getter(() -> region.get().getPlain(Flag.TNT, TNTMode.class) != TNTMode.DENY));
tntLib.set("onlyTb", getter(() -> region.get().getPlain(Flag.TNT, TNTMode.class) == TNTMode.ONLY_TB));
tntLib.set("onlyBuild", getter(() -> region.get().getPlain(Flag.TNT, TNTMode.class) == TNTMode.ONLY_BUILD));
table.set("tnt", tntLib);
table.set("fire", getter(() -> region.get().getPlain(Flag.FIRE, FireMode.class) == FireMode.ALLOW));
table.set("freeze", getter(() -> region.get().getPlain(Flag.FREEZE, FreezeMode.class) == FreezeMode.ACTIVE));
table.set("protect", getter(() -> region.get().getPlain(Flag.PROTECT, ProtectMode.class) == ProtectMode.ACTIVE));
//LuaValue traceLib = LuaValue.tableOf();
//traceLib.set("active", getter(() -> !region.get().isGlobal() && Recorder.INSTANCE.get(region.get()) instanceof ActiveTracer));
//traceLib.set("auto", getter(() -> !region.get().isGlobal() && Recorder.INSTANCE.get(region.get()) instanceof AutoTraceRecorder));
//traceLib.set("status", getter(() -> Recorder.INSTANCE.get(region.get()).scriptState()));
//traceLib.set("time", getter(() -> Recorder.INSTANCE.get(region.get()).scriptTime()));
//table.set("trace", traceLib);
Loader loader = Loader.getLoader(player);
table.set("loader", getter(() -> loader == null ? "OFF" : loader.getStage().name()));
table.set("copyPoint", getter(() -> toPos(region.get().getCopyPoint())));
table.set("minPointBuild", getter(() -> toPos(region.get().getMinPointBuild())));
table.set("maxPointBuild", getter(() -> toPos(region.get().getMaxPointBuild())));
table.set("minPointBuildExtension", getter(() -> toPos(region.get().getMinPointBuildExtension())));
table.set("maxPointBuildExtension", getter(() -> toPos(region.get().getMaxPointBuildExtension())));
table.set("testblockPoint", getter(() -> toPos(region.get().getTestBlockPoint())));
table.set("minPointTestblock", getter(() -> toPos(region.get().getMinPointTestblock())));
table.set("maxPointTestblock", getter(() -> toPos(region.get().getMaxPointTestblock())));
table.set("minPointTestblockExtension", getter(() -> toPos(region.get().getMinPointTestblockExtension())));
table.set("maxPointTestblockExtension", getter(() -> toPos(region.get().getMaxPointTestblockExtension())));
return table;
}
@Override
public LuaTable get(Player player) {
LuaTable table = create(() -> Region.getRegion(player.getLocation()), player);
table.set("get", new OneArgFunction() {
@Override
public LuaValue call(LuaValue arg) {
return create(() -> Region.getREGION_MAP().get(arg.checkjstring()), player);
}
});
table.set("list", getter(() -> LuaValue.listOf(Region.getREGION_MAP().values().stream().map(region -> create(() -> region, player)).toArray(LuaTable[]::new))));
return table;
}
}
@@ -0,0 +1,75 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2024 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.script.lua.libs;
import de.steamwar.bausystem.features.world.BauScoreboard;
import de.steamwar.bausystem.utils.ScoreboardElement;
import de.steamwar.linkage.Linked;
import org.bukkit.entity.Player;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Varargs;
import org.luaj.vm2.lib.TwoArgFunction;
import org.luaj.vm2.lib.VarArgFunction;
@Linked
public class ScoreboardLib implements LuaLib {
@Override
public String name() {
return "scoreboard";
}
@Override
public LuaTable get(Player player) {
LuaTable luaTable = new LuaTable();
LuaTable groups = new LuaTable();
for (ScoreboardElement.ScoreboardGroup group : ScoreboardElement.ScoreboardGroup.values()) {
groups.set(group.name(), group.ordinal());
}
luaTable.set("group", groups);
luaTable.set("element", new VarArgFunction() {
@Override
public Varargs invoke(Varargs varargs) {
if (varargs.narg() < 2) {
return NIL;
}
String elementKey = varargs.arg(1).checkjstring();
ScoreboardElement.ScoreboardGroup elementGroup = ScoreboardElement.ScoreboardGroup.values()[varargs.arg(2).checkint()];
int priority = varargs.narg() > 2 ? varargs.arg(2).checkint() : Integer.MAX_VALUE;
return new VarArgFunction() {
@Override
public Varargs invoke(Varargs args) {
if (args.narg() == 0) {
BauScoreboard.setAdditionalElement(player, elementKey, elementGroup, priority, null);
} else {
BauScoreboard.setAdditionalElement(player, elementKey, elementGroup, priority, args.arg1().checkjstring());
}
return NIL;
}
};
}
});
return luaTable;
}
}
@@ -0,0 +1,96 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.script.lua.libs;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.Permission;
import de.steamwar.bausystem.features.loader.Loader;
import de.steamwar.bausystem.features.loader.LoaderRecorder;
import de.steamwar.bausystem.features.tpslimit.TPSUtils;
import de.steamwar.inventory.SWItem;
import de.steamwar.linkage.Linked;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.luaj.vm2.LuaString;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.lib.OneArgFunction;
import org.luaj.vm2.lib.TwoArgFunction;
import java.text.SimpleDateFormat;
import java.util.Calendar;
@Linked
public class ServerLib implements LuaLib {
@Override
public String name() {
return "server";
}
@Override
public LuaTable get(Player player) {
LuaTable serverLib = LuaValue.tableOf();
serverLib.set("time", getter(() -> new SimpleDateFormat(BauSystem.MESSAGE.parse("TIME", player)).format(Calendar.getInstance().getTime())));
serverLib.set("onlinePlayerCount", getter(Bukkit.getOnlinePlayers()::size));
serverLib.set("ticks", getter(TPSUtils.currentTick));
serverLib.set("getBlockAt", new OneArgFunction() {
@Override
public LuaValue call(LuaValue arg1) {
if (!Permission.SUPERVISOR.hasPermission(player)) {
return LuaValue.NIL;
}
LuaTable pos = arg1.checktable();
return valueOf(player.getWorld().getBlockAt(pos.get("x").checkint(), pos.get("y").checkint(), pos.get("z").checkint()).getType().name());
}
});
serverLib.set("setBlockAt", new TwoArgFunction() {
@Override
public LuaValue call(LuaValue arg1, LuaValue arg2) {
if (!Permission.SUPERVISOR.hasPermission(player)) {
return LuaValue.NIL;
}
LuaTable pos = arg1.checktable();
LuaString material = arg2.checkstring();
Material mat = SWItem.getMaterial(material.tojstring());
if (mat == null) {
return NIL;
}
player.getWorld().getBlockAt(pos.get("x").checkint(), pos.get("y").checkint(), pos.get("z").checkint()).setType(mat);
return NIL;
}
});
serverLib.set("interactAt", new OneArgFunction() {
@Override
public LuaValue call(LuaValue arg1) {
LuaTable pos = arg1.checktable();
Block block = player.getWorld().getBlockAt(pos.get("x").checkint(), pos.get("y").checkint(), pos.get("z").checkint());
LoaderRecorder.getLoaderInteractionElement(block, (loaderInteractionElement, s) -> {
loaderInteractionElement.execute(aLong -> {
// Ignore
});
});
return NIL;
}
});
return serverLib;
}
}
@@ -0,0 +1,358 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.script.lua.libs;
import com.google.gson.*;
import de.steamwar.bausystem.region.Region;
import de.steamwar.core.Core;
import de.steamwar.linkage.Linked;
import de.steamwar.linkage.api.Disable;
import de.steamwar.linkage.api.Enable;
import de.steamwar.sql.SteamwarUser;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Varargs;
import org.luaj.vm2.lib.OneArgFunction;
import org.luaj.vm2.lib.TwoArgFunction;
import org.luaj.vm2.lib.VarArgFunction;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
@Linked
public class StorageLib implements LuaLib, Enable, Disable {
private final Gson gson = new Gson();
private final File storageDirectory = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "script_storage");
private static final HashMap<String, LuaValue> GLOBAL_STORAGE = new HashMap<>();
private static final HashMap<UUID, HashMap<String, LuaValue>> PLAYER_STORAGE = new HashMap<>();
private static final HashMap<Region, HashMap<String, LuaValue>> REGION_STORAGE = new HashMap<>();
@Override
public void enable() {
if (Core.getVersion() <= 15) return;
if (!storageDirectory.exists()) storageDirectory.mkdirs();
try {
JsonObject jsonObject = JsonParser.parseReader(new FileReader(new File(storageDirectory, "global.json"))).getAsJsonObject();
jsonObject.keySet().forEach(key -> {
GLOBAL_STORAGE.put(key, fromJson(jsonObject.get(key)));
});
} catch (Exception e) {}
File regionStorageDirectory = new File(storageDirectory, "region");
regionStorageDirectory.mkdirs();
for (File regionStorage : regionStorageDirectory.listFiles()) {
try {
JsonObject jsonObject = JsonParser.parseReader(new FileReader(regionStorage)).getAsJsonObject();
HashMap<String, LuaValue> map = new HashMap<>();
jsonObject.keySet().forEach(key -> {
map.put(key, fromJson(jsonObject.get(key)));
});
Region region = Region.getREGION_MAP().get(regionStorage.getName().substring(0, regionStorage.getName().length() - ".json".length()));
REGION_STORAGE.put(region, map);
} catch (Exception e) {}
}
File playerStorageDirectory = new File(storageDirectory, "player");
playerStorageDirectory.mkdirs();
for (File playerStorage : playerStorageDirectory.listFiles()) {
try {
JsonObject jsonObject = JsonParser.parseReader(new FileReader(playerStorage)).getAsJsonObject();
HashMap<String, LuaValue> map = new HashMap<>();
jsonObject.keySet().forEach(key -> {
map.put(key, fromJson(jsonObject.get(key)));
});
SteamwarUser steamwarUser = SteamwarUser.get(Integer.parseInt(playerStorage.getName().substring(0, playerStorage.getName().length() - ".json".length())));
PLAYER_STORAGE.put(steamwarUser.getUUID(), map);
} catch (Exception e) {}
}
}
private LuaValue fromJson(JsonElement jsonElement) {
if (jsonElement.isJsonNull()) {
return LuaValue.NIL;
}
if (jsonElement.isJsonPrimitive()) {
JsonPrimitive jsonPrimitive = jsonElement.getAsJsonPrimitive();
if (jsonPrimitive.isBoolean()) {
return LuaValue.valueOf(jsonPrimitive.getAsBoolean());
}
if (jsonPrimitive.isNumber()) {
try {
return LuaValue.valueOf(jsonPrimitive.getAsInt());
} catch (NumberFormatException e) {}
try {
return LuaValue.valueOf(jsonPrimitive.getAsDouble());
} catch (NumberFormatException e) {}
}
if (jsonPrimitive.isString()) {
return LuaValue.valueOf(jsonPrimitive.getAsString());
}
return null;
}
if (jsonElement.isJsonObject()) {
JsonObject jsonObject = jsonElement.getAsJsonObject();
LuaTable luaTable = new LuaTable();
jsonObject.keySet().forEach(string -> {
LuaValue value = fromJson(jsonObject.get(string));
if (value == null) return;
luaTable.set(string, value);
});
return luaTable;
}
return null;
}
@Override
public void disable() {
if (Core.getVersion() <= 15) return;
if (!storageDirectory.exists()) storageDirectory.mkdirs();
try {
FileWriter fileWriter = new FileWriter(new File(storageDirectory, "global.json"));
gson.toJson(toJson(GLOBAL_STORAGE), fileWriter);
fileWriter.close();
} catch (IOException e) {}
File regionStorageDirectory = new File(storageDirectory, "region");
regionStorageDirectory.mkdirs();
for (Map.Entry<Region, HashMap<String, LuaValue>> entry : REGION_STORAGE.entrySet()) {
try {
FileWriter fileWriter = new FileWriter(new File(regionStorageDirectory, entry.getKey().getName() + ".json"));
gson.toJson(toJson(entry.getValue()), fileWriter);
fileWriter.close();
} catch (IOException e) {}
}
File playerStorageDirectory = new File(storageDirectory, "player");
playerStorageDirectory.mkdirs();
for (Map.Entry<UUID, HashMap<String, LuaValue>> entry : PLAYER_STORAGE.entrySet()) {
try {
FileWriter fileWriter = new FileWriter(new File(playerStorageDirectory, SteamwarUser.get(entry.getKey()).getId() + ".json"));
gson.toJson(toJson(entry.getValue()), fileWriter);
fileWriter.close();
} catch (IOException e) {}
}
}
private JsonObject toJson(HashMap<String, LuaValue> valueMap) {
JsonObject jsonObject = new JsonObject();
valueMap.forEach((string, luaValue) -> {
JsonElement value = toJson(luaValue);
if (value == null) return;
jsonObject.add(string, value);
});
return jsonObject;
}
private JsonElement toJson(LuaValue luaValue) {
if (luaValue.isnil()) {
return JsonNull.INSTANCE;
}
try {
return new JsonPrimitive(luaValue.checkboolean());
} catch (Exception e) {}
try {
return new JsonPrimitive(luaValue.checkint());
} catch (Exception e) {}
try {
return new JsonPrimitive(luaValue.checkdouble());
} catch (Exception e) {}
if (luaValue.isstring()) {
return new JsonPrimitive(luaValue.tojstring());
}
if (luaValue.istable()) {
LuaTable luaTable = luaValue.checktable();
JsonObject jsonObject = new JsonObject();
for (LuaValue key : luaTable.keys()) {
JsonElement value = toJson(luaTable.get(key));
if (value == null) continue;
try {
jsonObject.add(key.checkjstring(), value);
} catch (Exception e) {}
}
return jsonObject;
}
return null;
}
@Override
public String name() {
return "storage";
}
@Override
public LuaTable get(Player player) {
LuaTable storageLib = new LuaTable();
LuaTable global = new LuaTable();
global.set("get", new OneArgFunction() {
@Override
public LuaValue call(LuaValue arg) {
return GLOBAL_STORAGE.getOrDefault(arg.checkjstring(), NIL);
}
});
global.set("set", new TwoArgFunction() {
@Override
public LuaValue call(LuaValue arg1, LuaValue arg2) {
return GLOBAL_STORAGE.put(arg1.checkjstring(), arg2);
}
});
global.set("has", new OneArgFunction() {
@Override
public LuaValue call(LuaValue arg) {
return valueOf(GLOBAL_STORAGE.containsKey(arg.checkjstring()));
}
});
global.set("remove", new OneArgFunction() {
@Override
public LuaValue call(LuaValue arg) {
return GLOBAL_STORAGE.remove(arg.checkjstring());
}
});
global.set("accessor", new OneArgFunction() {
@Override
public LuaValue call(LuaValue arg) {
String key = arg.checkjstring();
return new VarArgFunction() {
@Override
public Varargs invoke(Varargs args) {
if (args.narg() == 0) {
return GLOBAL_STORAGE.getOrDefault(key, NIL);
} else {
GLOBAL_STORAGE.put(key, args.arg(1));
return NIL;
}
}
};
};
});
storageLib.set("global", global);
LuaTable playerStorage = new LuaTable();
HashMap<String, LuaValue> playerStorageMap = PLAYER_STORAGE.computeIfAbsent(player.getUniqueId(), k -> new HashMap<>());
playerStorage.set("get", new OneArgFunction() {
@Override
public LuaValue call(LuaValue arg) {
return playerStorageMap.getOrDefault(arg.checkjstring(), NIL);
}
});
playerStorage.set("set", new TwoArgFunction() {
@Override
public LuaValue call(LuaValue arg1, LuaValue arg2) {
return playerStorageMap.put(arg1.checkjstring(), arg2);
}
});
playerStorage.set("has", new OneArgFunction() {
@Override
public LuaValue call(LuaValue arg) {
return valueOf(playerStorageMap.containsKey(arg.checkjstring()));
}
});
playerStorage.set("remove", new OneArgFunction() {
@Override
public LuaValue call(LuaValue arg) {
return playerStorageMap.remove(arg.checkjstring());
}
});
playerStorage.set("accessor", new OneArgFunction() {
@Override
public LuaValue call(LuaValue arg) {
String key = arg.checkjstring();
return new VarArgFunction() {
@Override
public Varargs invoke(Varargs args) {
if (args.narg() == 0) {
return playerStorageMap.getOrDefault(key, NIL);
} else {
playerStorageMap.put(key, args.arg(1));
return NIL;
}
}
};
};
});
storageLib.set("player", playerStorage);
LuaTable regionStorage = new LuaTable();
regionStorage.set("get", new OneArgFunction() {
@Override
public LuaValue call(LuaValue arg) {
HashMap<String, LuaValue> regionStorageMap = REGION_STORAGE.computeIfAbsent(Region.getRegion(player.getLocation()), k -> new HashMap<>());
return regionStorageMap.getOrDefault(arg.checkjstring(), NIL);
}
});
regionStorage.set("set", new TwoArgFunction() {
@Override
public LuaValue call(LuaValue arg1, LuaValue arg2) {
HashMap<String, LuaValue> regionStorageMap = REGION_STORAGE.computeIfAbsent(Region.getRegion(player.getLocation()), k -> new HashMap<>());
return regionStorageMap.put(arg1.checkjstring(), arg2);
}
});
regionStorage.set("has", new OneArgFunction() {
@Override
public LuaValue call(LuaValue arg) {
HashMap<String, LuaValue> regionStorageMap = REGION_STORAGE.computeIfAbsent(Region.getRegion(player.getLocation()), k -> new HashMap<>());
return valueOf(regionStorageMap.containsKey(arg.checkjstring()));
}
});
regionStorage.set("remove", new OneArgFunction() {
@Override
public LuaValue call(LuaValue arg) {
HashMap<String, LuaValue> regionStorageMap = REGION_STORAGE.computeIfAbsent(Region.getRegion(player.getLocation()), k -> new HashMap<>());
return regionStorageMap.remove(arg.checkjstring());
}
});
regionStorage.set("accessor", new OneArgFunction() {
@Override
public LuaValue call(LuaValue arg) {
HashMap<String, LuaValue> regionStorageMap = REGION_STORAGE.computeIfAbsent(Region.getRegion(player.getLocation()), k -> new HashMap<>());
String key = arg.checkjstring();
return new VarArgFunction() {
@Override
public Varargs invoke(Varargs args) {
if (args.narg() == 0) {
return regionStorageMap.getOrDefault(key, NIL);
} else {
regionStorageMap.put(key, args.arg(1));
return NIL;
}
}
};
};
});
storageLib.set("region", regionStorage);
return storageLib;
}
public static void removePlayer(Player player) {
PLAYER_STORAGE.remove(player);
}
}
@@ -0,0 +1,57 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2024 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.script.lua.libs;
import de.steamwar.bausystem.features.tpslimit.TPSSystem;
import de.steamwar.core.TPSWatcher;
import de.steamwar.linkage.Linked;
import de.steamwar.linkage.LinkedInstance;
import org.bukkit.entity.Player;
import org.luaj.vm2.LuaTable;
@Linked
public class TpsLib implements LuaLib {
@LinkedInstance
public TPSSystem tpsSystem;
@Override
public Class<? extends LuaLib> parent() {
return ServerLib.class;
}
@Override
public String name() {
return "tps";
}
@Override
public LuaTable get(Player player) {
LuaTable tpsLib = new LuaTable();
tpsLib.set("oneSecond", getter(() -> TPSWatcher.getTPS(TPSWatcher.TPSType.ONE_SECOND)));
tpsLib.set("tenSecond", getter(() -> TPSWatcher.getTPS(TPSWatcher.TPSType.TEN_SECONDS)));
tpsLib.set("oneMinute", getter(() -> TPSWatcher.getTPS(TPSWatcher.TPSType.ONE_MINUTE)));
tpsLib.set("fiveMinute", getter(() -> TPSWatcher.getTPS(TPSWatcher.TPSType.FIVE_MINUTES)));
tpsLib.set("tenMinute", getter(() -> TPSWatcher.getTPS(TPSWatcher.TPSType.TEN_MINUTES)));
tpsLib.set("current", getter(TPSWatcher::getTPS));
tpsLib.set("limit", getter(tpsSystem::getCurrentTPSLimit));
return tpsLib;
}
}
@@ -0,0 +1,71 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.script.lua.libs;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.bukkit.BukkitPlayer;
import com.sk89q.worldedit.math.BlockVector3;
import de.steamwar.bausystem.region.Point;
import de.steamwar.bausystem.utils.FlatteningWrapper;
import de.steamwar.linkage.Linked;
import org.bukkit.entity.Player;
import org.luaj.vm2.LuaTable;
@Linked
public class WorldEditLib implements LuaLib {
@Override
public String name() {
return "_worldedit";
}
@Override
public LuaTable get(Player player) {
LuaTable table = new LuaTable();
table.set("selection", getterAndSetter("selection", () -> {
LuaTable selection = new LuaTable();
selection.set("min", posFromVec(WorldEdit.getInstance().getSessionManager().get(new BukkitPlayer(player)).getSelectionWorld().getMinimumPoint()));
selection.set("max", posFromVec(WorldEdit.getInstance().getSessionManager().get(new BukkitPlayer(player)).getSelectionWorld().getMaximumPoint()));
return selection;
}, o -> {
LuaTable selection = o.checktable();
if(selection.length() != 2) {
throw new IllegalArgumentException("selection must have exactly 2 elements");
}
Point one = vecFromPos(selection.get(1).checktable());
Point two = vecFromPos(selection.get(2).checktable());
FlatteningWrapper.impl.setSelection(player, one, two);
}));
return table;
}
public static LuaTable posFromVec(BlockVector3 vec) {
LuaTable table = new LuaTable();
table.set("x", vec.getBlockX());
table.set("y", vec.getBlockY());
table.set("z", vec.getBlockZ());
return table;
}
public static Point vecFromPos(LuaTable table) {
return new Point(table.get("x").checkint(), table.get("y").checkint(), table.get("z").checkint());
}
}