forked from SteamWar/SteamWar
Compare commits
48
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de4f32feb2 | ||
|
|
a3d2d2be1e | ||
|
|
7a000efb93 | ||
|
|
42c9d6d612 | ||
|
|
67c679a20f | ||
|
|
a071d8a1f2 | ||
|
|
7b25bd31fc | ||
|
|
139a2c275c | ||
|
|
aa787b5a25 | ||
|
|
54adc12045 | ||
|
|
32c85b9bd5 | ||
|
|
15bb92fbba | ||
|
|
d6a5caf95d | ||
|
|
66d18e316b | ||
|
|
5cdad8c2f4 | ||
|
|
87a7120a6a | ||
|
|
b5a9564808 | ||
|
|
f93362a023 | ||
|
|
b1bef4ced5 | ||
|
|
e7e1e2d968 | ||
|
|
713275ba11 | ||
|
|
e72ae3cf94 | ||
|
|
d36753dec1 | ||
|
|
84cc292df4 | ||
|
|
f89c4e88f9 | ||
|
|
a38f9222dd | ||
|
|
5ee9d3e167 | ||
|
|
98321de46c | ||
|
|
239ba3f213 | ||
|
|
3d7dedd3ad | ||
|
|
ef66b8c1f1 | ||
|
|
1201b16ee4 | ||
|
|
4ddd88f540 | ||
|
|
ca35ab9234 | ||
|
|
3df84a7dad | ||
|
|
83c20729fa | ||
|
|
925901e40e | ||
|
|
059dd314d1 | ||
|
|
86ff619548 | ||
|
|
76e00b07db | ||
|
|
4edfd32ff5 | ||
|
|
5669725f9b | ||
|
|
335649fa87 | ||
|
|
9001e83321 | ||
|
|
32703c6659 | ||
|
|
e393aad25f | ||
|
|
50543ddd4e | ||
|
|
ae7d394ae2 |
+37
@@ -0,0 +1,37 @@
|
|||||||
|
package de.steamwar.bausystem.features.printerTool;
|
||||||
|
|
||||||
|
import de.steamwar.bausystem.utils.ItemUtils;
|
||||||
|
import de.steamwar.inventory.SWItem;
|
||||||
|
import de.steamwar.linkage.Linked;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
|
||||||
|
@Linked
|
||||||
|
public class PrinterToolItem implements Listener {
|
||||||
|
public static ItemStack getItem(Player p) {
|
||||||
|
ItemStack itemStack = new SWItem(Material.WOODEN_PICKAXE, "Printer Tool").getItemStack();
|
||||||
|
ItemMeta itemMeta = itemStack.getItemMeta();
|
||||||
|
itemMeta.setCustomModelData(1);
|
||||||
|
itemStack.setItemMeta(itemMeta);
|
||||||
|
ItemUtils.setItem(itemStack, "printer_tool");
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isItem(ItemStack itemStack) {
|
||||||
|
return itemStack != null && ItemUtils.isItem(itemStack, "printer_tool");
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPlayerInteract(PlayerInteractEvent event) {
|
||||||
|
ItemStack item = event.getItem();
|
||||||
|
|
||||||
|
if(PrinterToolItem.isItem(item)) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -226,7 +226,7 @@ public class FreezeListener implements Listener, ScoreboardElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR)
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
public void onBlockBreak(BlockBreakEvent e) {
|
public void onBlockBreak(BlockBreakEvent e) {
|
||||||
if (Core.getVersion() < 19) return;
|
if (Core.getVersion() < 19) return;
|
||||||
if (e.getPlayer().getInventory().getItemInMainHand().getType() == Material.DEBUG_STICK) return;
|
if (e.getPlayer().getInventory().getItemInMainHand().getType() == Material.DEBUG_STICK) return;
|
||||||
|
|||||||
+2
-1
@@ -25,6 +25,7 @@ import com.sk89q.worldedit.world.block.BaseBlock;
|
|||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||||
import de.steamwar.bausystem.utils.WorldEditUtils;
|
import de.steamwar.bausystem.utils.WorldEditUtils;
|
||||||
|
import de.steamwar.core.Core;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
@@ -56,7 +57,7 @@ public class Panzern {
|
|||||||
|
|
||||||
private BaseBlock blockType;
|
private BaseBlock blockType;
|
||||||
private BaseBlock slabType;
|
private BaseBlock slabType;
|
||||||
private static final BaseBlock jukeboxType = BlockTypes.JUKEBOX.getDefaultState().toBaseBlock();
|
private static final BaseBlock jukeboxType = (Core.getVersion() > 19 ? BlockTypes.get("lodestone"): BlockTypes.get("jukebox")).getDefaultState().toBaseBlock();
|
||||||
private static final BaseBlock cobwebType = BlockTypes.COBWEB.getDefaultState().toBaseBlock();
|
private static final BaseBlock cobwebType = BlockTypes.COBWEB.getDefaultState().toBaseBlock();
|
||||||
private static final BaseBlock airType = BlockTypes.AIR.getDefaultState().toBaseBlock();
|
private static final BaseBlock airType = BlockTypes.AIR.getDefaultState().toBaseBlock();
|
||||||
|
|
||||||
|
|||||||
+6
-1
@@ -179,7 +179,12 @@ public class SpectatorListener implements Listener {
|
|||||||
|
|
||||||
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||||
public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) {
|
public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) {
|
||||||
if (event.getMessage().startsWith("/schem save") || event.getMessage().startsWith("//schem save") || event.getMessage().startsWith("/schematic save") || event.getMessage().startsWith("//schematic save")) {
|
if (event.getMessage().startsWith("/schem save") ||
|
||||||
|
event.getMessage().startsWith("//schem save") ||
|
||||||
|
event.getMessage().startsWith("/schematic save") ||
|
||||||
|
event.getMessage().startsWith("//schematic save") ||
|
||||||
|
event.getMessage().startsWith("/download") ||
|
||||||
|
event.getMessage().startsWith("//download")) {
|
||||||
if (!Permission.SUPERVISOR.hasPermission(event.getPlayer())) {
|
if (!Permission.SUPERVISOR.hasPermission(event.getPlayer())) {
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
event.setMessage("/");
|
event.setMessage("/");
|
||||||
|
|||||||
@@ -0,0 +1,204 @@
|
|||||||
|
package de.steamwar.bausystem.utils.cursor;
|
||||||
|
|
||||||
|
import de.steamwar.bausystem.utils.RayTraceUtils;
|
||||||
|
import de.steamwar.entity.REntity;
|
||||||
|
import de.steamwar.entity.REntityServer;
|
||||||
|
import de.steamwar.entity.RFallingBlockEntity;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.block.BlockFace;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.block.Action;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
|
import yapion.hierarchy.types.YAPIONType;
|
||||||
|
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class RCursor {
|
||||||
|
private final World WORLD = Bukkit.getWorlds().get(0);
|
||||||
|
|
||||||
|
private final REntityServer targetServer;
|
||||||
|
private final REntityServer cursorServer;
|
||||||
|
|
||||||
|
private final Player owner;
|
||||||
|
private final Material highlightMaterial;
|
||||||
|
private final ClickHandler onClickHandler;
|
||||||
|
|
||||||
|
private RFallingBlockEntity cursorEntity;
|
||||||
|
|
||||||
|
private Location cursorLocation;
|
||||||
|
private boolean isHittingEntity = false;
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
private Material cursorMaterial;
|
||||||
|
@Setter
|
||||||
|
private CursorMode cursorMode;
|
||||||
|
private boolean visible = true;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public RCursor(REntityServer targetServer, Player owner, Material highlightMaterial, Material cursorMaterial, CursorMode cursorMode, ClickHandler onClickHandler) {
|
||||||
|
this.targetServer = targetServer;
|
||||||
|
this.owner = owner;
|
||||||
|
this.highlightMaterial = highlightMaterial;
|
||||||
|
this.cursorMaterial = cursorMaterial;
|
||||||
|
this.cursorMode = cursorMode;
|
||||||
|
this.onClickHandler = onClickHandler;
|
||||||
|
|
||||||
|
cursorServer = new REntityServer();
|
||||||
|
cursorServer.addPlayer(owner);
|
||||||
|
|
||||||
|
RCursorManager.getInstance().registerCursor(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void render() {
|
||||||
|
if (!visible) return;
|
||||||
|
|
||||||
|
RayTraceUtils.RRayTraceResult rayTraceResult = RayTraceUtils.traceREntity(owner, owner.getLocation(), targetServer.getEntities());
|
||||||
|
if (rayTraceResult == null) {
|
||||||
|
if(cursorEntity != null) cursorEntity.die();
|
||||||
|
cursorEntity = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
REntity hitEntity = rayTraceResult.getHitEntity() == cursorEntity ? null : rayTraceResult.getHitEntity();
|
||||||
|
|
||||||
|
|
||||||
|
Material activeCursorMaterial = hitEntity == null ? cursorMaterial : highlightMaterial;
|
||||||
|
Location activeCursorLocation = hitEntity == null ? cursorMode.positionTransform.apply(owner, rayTraceResult).toLocation(WORLD)
|
||||||
|
: new Vector(hitEntity.getX(), hitEntity.getY(), hitEntity.getZ()).toLocation(WORLD);
|
||||||
|
|
||||||
|
cursorLocation = activeCursorLocation;
|
||||||
|
isHittingEntity = hitEntity != null;
|
||||||
|
|
||||||
|
if (cursorEntity == null) {
|
||||||
|
cursorEntity = new RFallingBlockEntity(cursorServer, activeCursorLocation, activeCursorMaterial);
|
||||||
|
cursorEntity.setNoGravity(true);
|
||||||
|
} if (cursorEntity.getMaterial() == activeCursorMaterial) {
|
||||||
|
cursorEntity.move(activeCursorLocation);
|
||||||
|
} else {
|
||||||
|
cursorEntity.die();
|
||||||
|
cursorEntity = new RFallingBlockEntity(cursorServer, activeCursorLocation, activeCursorMaterial);
|
||||||
|
cursorEntity.setNoGravity(true);
|
||||||
|
if(activeCursorMaterial == highlightMaterial) {
|
||||||
|
cursorEntity.setGlowing(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void hide() {
|
||||||
|
visible = false;
|
||||||
|
if (cursorEntity != null) {
|
||||||
|
cursorEntity.die();
|
||||||
|
cursorEntity = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void show() {
|
||||||
|
visible = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleClick(Action action) {
|
||||||
|
if(!visible || cursorLocation == null) return;
|
||||||
|
|
||||||
|
onClickHandler.handle(cursorLocation, isHittingEntity, action);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() {
|
||||||
|
cursorServer.close();
|
||||||
|
RCursorManager.getInstance().unregisterCursor(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum CursorMode {
|
||||||
|
FREE((player, rayTraceResult) -> {
|
||||||
|
Vector pos = rayTraceResult.getHitPosition();
|
||||||
|
|
||||||
|
BlockFace face = rayTraceResult.getHitBlockFace();
|
||||||
|
if (face != null) {
|
||||||
|
switch (face) {
|
||||||
|
case DOWN:
|
||||||
|
pos.setY(pos.getY() - 0.98);
|
||||||
|
break;
|
||||||
|
case EAST:
|
||||||
|
pos.setX(pos.getX() + 0.49);
|
||||||
|
break;
|
||||||
|
case WEST:
|
||||||
|
pos.setX(pos.getX() - 0.49);
|
||||||
|
break;
|
||||||
|
case NORTH:
|
||||||
|
pos.setZ(pos.getZ() - 0.49);
|
||||||
|
break;
|
||||||
|
case SOUTH:
|
||||||
|
pos.setZ(pos.getZ() + 0.49);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (face.getModY() == 0 && player.isSneaking()) {
|
||||||
|
pos.setY(pos.getY() - 0.49);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!player.isSneaking()) {
|
||||||
|
pos.setX(pos.getBlockX() + 0.5);
|
||||||
|
if (face == null || face.getModY() == 0)
|
||||||
|
pos.setY(pos.getBlockY() + 0.0);
|
||||||
|
pos.setZ(pos.getBlockZ() + 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pos;
|
||||||
|
}),
|
||||||
|
BLOCK_ALIGNED((player, rayTraceResult) -> {
|
||||||
|
Vector pos = rayTraceResult.getHitPosition();
|
||||||
|
|
||||||
|
BlockFace face = rayTraceResult.getHitBlockFace();
|
||||||
|
if (face != null) {
|
||||||
|
switch (face) {
|
||||||
|
case DOWN:
|
||||||
|
pos.setY(pos.getY() - 0.98);
|
||||||
|
break;
|
||||||
|
case EAST:
|
||||||
|
pos.setX(pos.getX() + 0.49);
|
||||||
|
break;
|
||||||
|
case WEST:
|
||||||
|
pos.setX(pos.getX() - 0.49);
|
||||||
|
break;
|
||||||
|
case NORTH:
|
||||||
|
pos.setZ(pos.getZ() - 0.49);
|
||||||
|
break;
|
||||||
|
case SOUTH:
|
||||||
|
pos.setZ(pos.getZ() + 0.49);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pos.setX(pos.getBlockX() + 0.5);
|
||||||
|
if (pos.getY() - pos.getBlockY() != 0 && face == BlockFace.UP) {
|
||||||
|
pos.setY(pos.getBlockY() + 1.0);
|
||||||
|
} else {
|
||||||
|
pos.setY(pos.getBlockY());
|
||||||
|
}
|
||||||
|
pos.setZ(pos.getBlockZ() + 0.5);
|
||||||
|
return pos;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
private final BiFunction<Player, RayTraceUtils.RRayTraceResult, Vector> positionTransform;
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ClickHandler{
|
||||||
|
public void handle(Location cursorLocation, boolean didHitEntity, Action action);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
package de.steamwar.bausystem.utils.cursor;
|
||||||
|
|
||||||
|
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||||
|
import de.steamwar.Reflection;
|
||||||
|
import de.steamwar.bausystem.BauSystem;
|
||||||
|
import de.steamwar.linkage.Linked;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
|
|
||||||
|
import java.lang.ref.SoftReference;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
|
@Linked
|
||||||
|
public class RCursorManager implements Listener {
|
||||||
|
@Getter
|
||||||
|
private static RCursorManager instance;
|
||||||
|
|
||||||
|
private final Set<Player> calculationActive = new HashSet<>();
|
||||||
|
private final Map<Player, RCursor> activeCursors = new HashMap<>();
|
||||||
|
|
||||||
|
public RCursorManager() {
|
||||||
|
if (instance == null) {
|
||||||
|
instance = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BiFunction<Player, Object, Object> function = (player, object) -> {
|
||||||
|
updateCursor(player);
|
||||||
|
return object;
|
||||||
|
};
|
||||||
|
|
||||||
|
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||||
|
Set<Player> playersWithActiveCursor = activeCursors.keySet();
|
||||||
|
|
||||||
|
playersWithActiveCursor.forEach(this::updateCursor);
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
Class<?> positionPacketClass = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$Pos");
|
||||||
|
Class<?> lookPacketClass = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$Rot");
|
||||||
|
Class<?> positionLookPacketClass = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$PosRot");
|
||||||
|
|
||||||
|
TinyProtocol.instance.addFilter(positionPacketClass, function);
|
||||||
|
TinyProtocol.instance.addFilter(lookPacketClass, function);
|
||||||
|
TinyProtocol.instance.addFilter(positionLookPacketClass, function);
|
||||||
|
}
|
||||||
|
|
||||||
|
void registerCursor(RCursor cursor) {
|
||||||
|
closeCursorOf(cursor.getOwner());
|
||||||
|
|
||||||
|
activeCursors.put(cursor.getOwner(), cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void unregisterCursor(RCursor cursor) {
|
||||||
|
activeCursors.remove(cursor.getOwner());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void closeCursorOf(Player player) {
|
||||||
|
RCursor currentPlayerCursor = activeCursors.get(player);
|
||||||
|
|
||||||
|
if(currentPlayerCursor != null) {
|
||||||
|
currentPlayerCursor.close();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void updateCursor(Player player) {
|
||||||
|
if (!activeCursors.containsKey(player)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (calculationActive) {
|
||||||
|
if (calculationActive.contains(player)) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
calculationActive.add(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RCursor cursor = activeCursors.get(player);
|
||||||
|
|
||||||
|
if (cursor != null) {
|
||||||
|
cursor.render();
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (calculationActive) {
|
||||||
|
calculationActive.remove(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
private void handlePlayerInteract(PlayerInteractEvent event) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
|
||||||
|
RCursor cursorOfPlayer = activeCursors.get(player);
|
||||||
|
|
||||||
|
cursorOfPlayer.handleClick(event.getAction());
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
private void handlePlayerQuit(PlayerQuitEvent event) {
|
||||||
|
closeCursorOf(event.getPlayer());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -34,3 +34,19 @@ dependencies {
|
|||||||
implementation(project(":BauSystem:BauSystem_20"))
|
implementation(project(":BauSystem:BauSystem_20"))
|
||||||
implementation(project(":BauSystem:BauSystem_21"))
|
implementation(project(":BauSystem:BauSystem_21"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks.register<DevServer>("DevBau20") {
|
||||||
|
group = "run"
|
||||||
|
description = "Run a 1.20 Dev Bau"
|
||||||
|
dependsOn(":SpigotCore:shadowJar")
|
||||||
|
dependsOn(":BauSystem:shadowJar")
|
||||||
|
template = "Bau20"
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.register<DevServer>("DevBau21") {
|
||||||
|
group = "run"
|
||||||
|
description = "Run a 1.21 Dev Bau"
|
||||||
|
dependsOn(":SpigotCore:shadowJar")
|
||||||
|
dependsOn(":BauSystem:shadowJar")
|
||||||
|
template = "Bau21"
|
||||||
|
}
|
||||||
|
|||||||
+24
-15
@@ -34,6 +34,7 @@ import org.bukkit.command.CommandSender;
|
|||||||
|
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
public class TechhiderbugCommand implements CommandExecutor {
|
public class TechhiderbugCommand implements CommandExecutor {
|
||||||
|
|
||||||
@@ -45,25 +46,33 @@ public class TechhiderbugCommand implements CommandExecutor {
|
|||||||
public boolean onCommand(CommandSender sender, Command cmd, String alias, String[] args) {
|
public boolean onCommand(CommandSender sender, Command cmd, String alias, String[] args) {
|
||||||
StringWriter writer = new StringWriter();
|
StringWriter writer = new StringWriter();
|
||||||
|
|
||||||
writer.append("ArenaMode: ").append(Config.mode.name()).append('\n');
|
try {
|
||||||
writer.append("FightState: ").append(FightState.getFightState().name()).append('\n');
|
writer.append("ArenaMode: ").append(Config.mode.name()).append('\n');
|
||||||
writer.append("TechHider enabled: ").append(FightState.getStateDependentFeatures().get(FightSystem.getTechHider()).toString()).append('\n');
|
writer.append("FightState: ").append(FightState.getFightState().name()).append('\n');
|
||||||
|
writer.append("TechHider enabled: ").append(FightState.getStateDependentFeatures().get(FightSystem.getTechHider()).toString()).append('\n');
|
||||||
|
|
||||||
writer.append("Arena region: ").append(Config.ArenaRegion.toString()).append('\n');
|
writer.append("Arena region: ").append(Config.ArenaRegion.toString()).append('\n');
|
||||||
writer.append("Team regions: ");
|
writer.append("Team regions: ");
|
||||||
Fight.teams().forEach(t -> writer.append(t.getName()).append(':').append(t.getExtendRegion().toString()).append(' '));
|
Fight.teams().forEach(t -> writer.append(t.getName()).append(':').append(t.getExtendRegion().toString()).append(' '));
|
||||||
writer.append('\n');
|
writer.append('\n');
|
||||||
|
|
||||||
writer.append("HullHider regions: ");
|
writer.append("HullHider regions: ");
|
||||||
FightSystem.getHullHider().getHullMap().forEach((t, h) -> writer.append(t.getName()).append(':').append(h.getRegion().toString()).append(' '));
|
FightSystem.getHullHider().getHullMap().forEach((t, h) -> writer.append(t.getName()).append(':').append(h.getRegion().toString()).append(' '));
|
||||||
writer.append('\n');
|
writer.append('\n');
|
||||||
|
|
||||||
writer.append("Hidden regions: ");
|
writer.append("Hidden regions: ");
|
||||||
FightSystem.getTechHider().getHiddenRegion().forEach((p, r) -> writer.append(p.getName()).append(':').append(r.toString()).append(' '));
|
FightSystem.getTechHider().getHiddenRegion().forEach((p, r) -> writer.append(p.getName()).append(':').append(r.toString()).append(' '));
|
||||||
writer.append('\n');
|
writer.append('\n');
|
||||||
|
|
||||||
writer.append('\n').append("Netty pipelines:\n");
|
writer.append("TinyProtocol: ");
|
||||||
Bukkit.getOnlinePlayers().forEach(p -> writer.append(p.getName()).append(": ").append(String.join(" ", TinyProtocol.instance.getPlayerInterceptors().get(p).getChannel().pipeline().names())).append('\n'));
|
writer.append(TinyProtocol.instance.toString()).append('\n');
|
||||||
|
|
||||||
|
writer.append('\n').append("Netty pipelines:\n");
|
||||||
|
Bukkit.getOnlinePlayers().forEach(p -> writer.append(p.getName()).append(": ").append(String.join(" ", TinyProtocol.instance.getPlayerInterceptors().get(p).getChannel().pipeline().names())).append('\n'));
|
||||||
|
} catch (Exception e) {
|
||||||
|
writer.append("Error while generating bug report: ").append(e.getMessage()).append('\n');
|
||||||
|
Bukkit.getLogger().log(Level.SEVERE, "Error while generating bug report", e);
|
||||||
|
}
|
||||||
|
|
||||||
SWException.log("Techhider-Bug reported by " + sender.getName() + ": " + Arrays.toString(args), writer.toString());
|
SWException.log("Techhider-Bug reported by " + sender.getName() + ": " + Arrays.toString(args), writer.toString());
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -29,11 +29,15 @@ import de.steamwar.fightsystem.states.FightState;
|
|||||||
import de.steamwar.fightsystem.states.StateDependentListener;
|
import de.steamwar.fightsystem.states.StateDependentListener;
|
||||||
import de.steamwar.fightsystem.states.StateDependentTask;
|
import de.steamwar.fightsystem.states.StateDependentTask;
|
||||||
import de.steamwar.fightsystem.utils.ItemBuilder;
|
import de.steamwar.fightsystem.utils.ItemBuilder;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.Cancellable;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.block.Action;
|
import org.bukkit.event.block.Action;
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||||
|
import org.bukkit.event.inventory.InventoryOpenEvent;
|
||||||
import org.bukkit.event.player.PlayerInteractEvent;
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
import org.bukkit.inventory.EquipmentSlot;
|
import org.bukkit.inventory.EquipmentSlot;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
@@ -107,6 +111,19 @@ public class HotbarKit extends Kit {
|
|||||||
|
|
||||||
Player player = event.getPlayer();
|
Player player = event.getPlayer();
|
||||||
int slot = player.getInventory().getHeldItemSlot();
|
int slot = player.getInventory().getHeldItemSlot();
|
||||||
|
click(player, slot, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onInventoryClick(InventoryClickEvent event) {
|
||||||
|
int slot = event.getSlot();
|
||||||
|
if (slot < 0 || slot >= HOTBAR_SIZE) return;
|
||||||
|
|
||||||
|
Player player = (Player) event.getWhoClicked();
|
||||||
|
click(player, slot, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void click(Player player, int slot, Cancellable event) {
|
||||||
Kit activeKit = activeKits.get(player);
|
Kit activeKit = activeKits.get(player);
|
||||||
if(!(activeKit instanceof HotbarKit) || PersonalKitCreator.inKitCreator(player) || activeKit.getInventory()[slot] == null)
|
if(!(activeKit instanceof HotbarKit) || PersonalKitCreator.inKitCreator(player) || activeKit.getInventory()[slot] == null)
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -39,3 +39,13 @@ dependencies {
|
|||||||
implementation(project(":FightSystem:FightSystem_20"))
|
implementation(project(":FightSystem:FightSystem_20"))
|
||||||
implementation(project(":FightSystem:FightSystem_21"))
|
implementation(project(":FightSystem:FightSystem_21"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks.register<FightServer>("WarGear20") {
|
||||||
|
group = "run"
|
||||||
|
description = "Run a WarGear 1.20 Fight Server"
|
||||||
|
dependsOn(":SpigotCore:shadowJar")
|
||||||
|
dependsOn(":FightSystem:shadowJar")
|
||||||
|
template = "WarGear20"
|
||||||
|
worldName = "arenas/Pentraki"
|
||||||
|
config = "WarGear20.yml"
|
||||||
|
}
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ public class JumpAndRun extends BasicListener {
|
|||||||
|
|
||||||
int count = CLICKED_COUNT.getOrDefault(player, -1);
|
int count = CLICKED_COUNT.getOrDefault(player, -1);
|
||||||
if (count >= 0) {
|
if (count >= 0) {
|
||||||
if (count > 60) {
|
if (count > 20) {
|
||||||
toReset.add(player);
|
toReset.add(player);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -104,12 +104,18 @@ public class JumpAndRun extends BasicListener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Vector point = points.get(index);
|
Vector point = points.get(index);
|
||||||
if (location.getY() < point.getY()) {
|
if (location.getY() < point.getY()) index = -2;
|
||||||
return;
|
if (location.toVector().distanceSquared(point) >= 17) index = -2;
|
||||||
}
|
if (index > 0 && index < points.size() - 1) {
|
||||||
if (location.toVector().distanceSquared(point) >= 12.25) {
|
Vector nextPoint = points.get(index + 1);
|
||||||
|
if (location.getY() >= nextPoint.getY() && location.toVector().distanceSquared(nextPoint) < 17) {
|
||||||
|
index = index + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (index == -2) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CURRENT_POS.put(event.getPlayer(), index);
|
CURRENT_POS.put(event.getPlayer(), index);
|
||||||
event.getPlayer().playSound(event.getPlayer().getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 0.4F, 1);
|
event.getPlayer().playSound(event.getPlayer().getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 0.4F, 1);
|
||||||
if (index < points.size() - 1) {
|
if (index < points.size() - 1) {
|
||||||
|
|||||||
@@ -71,6 +71,17 @@ public class TinyProtocol implements Listener {
|
|||||||
@Getter
|
@Getter
|
||||||
private final Map<Player, PacketInterceptor> playerInterceptors = new HashMap<>();
|
private final Map<Player, PacketInterceptor> playerInterceptors = new HashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "TinyProtocol{" +
|
||||||
|
"plugin=" + plugin +
|
||||||
|
", connections=" + connections +
|
||||||
|
", closed=" + closed +
|
||||||
|
", packetFilters=" + packetFilters +
|
||||||
|
", playerInterceptors=" + playerInterceptors +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
private TinyProtocol(final Plugin plugin) {
|
private TinyProtocol(final Plugin plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.connections = networkManagers.get(getServerConnection(plugin));
|
this.connections = networkManagers.get(getServerConnection(plugin));
|
||||||
@@ -84,6 +95,7 @@ public class TinyProtocol implements Listener {
|
|||||||
|
|
||||||
@EventHandler(priority = EventPriority.LOWEST)
|
@EventHandler(priority = EventPriority.LOWEST)
|
||||||
public void onPlayerLogin(PlayerLoginEvent e) {
|
public void onPlayerLogin(PlayerLoginEvent e) {
|
||||||
|
plugin.getLogger().info("Creating PacketInterceptor for: " + e.getPlayer().getName() + " (" + closed + ")");
|
||||||
if(closed)
|
if(closed)
|
||||||
return;
|
return;
|
||||||
new PacketInterceptor(e.getPlayer());
|
new PacketInterceptor(e.getPlayer());
|
||||||
@@ -118,6 +130,8 @@ public class TinyProtocol implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final void close() {
|
public final void close() {
|
||||||
|
plugin.getLogger().log(Level.INFO, "Closing PacketInterceptor", new Exception("Stacktrace"));
|
||||||
|
|
||||||
if(closed)
|
if(closed)
|
||||||
return;
|
return;
|
||||||
closed = true;
|
closed = true;
|
||||||
@@ -157,6 +171,7 @@ public class TinyProtocol implements Listener {
|
|||||||
synchronized (playerInterceptors) {
|
synchronized (playerInterceptors) {
|
||||||
playerInterceptors.put(player, this);
|
playerInterceptors.put(player, this);
|
||||||
}
|
}
|
||||||
|
plugin.getLogger().info("Adding Techhider for: " + player.getName());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
channel.pipeline().addBefore("packet_handler", HANDLER_NAME, this);
|
channel.pipeline().addBefore("packet_handler", HANDLER_NAME, this);
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import de.steamwar.Reflection;
|
|||||||
import de.steamwar.command.*;
|
import de.steamwar.command.*;
|
||||||
import de.steamwar.core.authlib.AuthlibInjector;
|
import de.steamwar.core.authlib.AuthlibInjector;
|
||||||
import de.steamwar.core.events.*;
|
import de.steamwar.core.events.*;
|
||||||
import de.steamwar.inventory.ui.test.TestInvCommand;
|
|
||||||
import de.steamwar.message.Message;
|
import de.steamwar.message.Message;
|
||||||
import de.steamwar.network.NetworkReceiver;
|
import de.steamwar.network.NetworkReceiver;
|
||||||
import de.steamwar.network.handlers.ServerDataHandler;
|
import de.steamwar.network.handlers.ServerDataHandler;
|
||||||
@@ -68,7 +67,6 @@ public class Core extends JavaPlugin{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
new TestInvCommand();
|
|
||||||
errorHandler = new ErrorHandler();
|
errorHandler = new ErrorHandler();
|
||||||
crashDetector = new CrashDetector();
|
crashDetector = new CrashDetector();
|
||||||
|
|
||||||
|
|||||||
@@ -1,76 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 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.inventory.ui;
|
|
||||||
|
|
||||||
import de.steamwar.inventory.ui.util.UpdateStream;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public abstract class StatefulUIInventory<T> extends UIInventory implements UpdateStream.Subscriber<T> {
|
|
||||||
|
|
||||||
private T state;
|
|
||||||
private final UpdateStream<T> stream;
|
|
||||||
private UpdateStream.Unsubscriber unsubscriber;
|
|
||||||
|
|
||||||
protected abstract UIComponent render(T state);
|
|
||||||
protected abstract void update(T state);
|
|
||||||
|
|
||||||
public StatefulUIInventory(UpdateStream<T> stateObservable, int playerSlots) {
|
|
||||||
super(playerSlots);
|
|
||||||
this.stream = stateObservable;
|
|
||||||
}
|
|
||||||
|
|
||||||
public StatefulUIInventory(UpdateStream<T> stateObservable) {
|
|
||||||
super();
|
|
||||||
this.stream = stateObservable;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void dispose() {
|
|
||||||
unsubscriber.unsubscribe();
|
|
||||||
this.unsubscriber = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UIComponent render() {
|
|
||||||
return render(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onUpdate(T current) {
|
|
||||||
state = current;
|
|
||||||
update(current);
|
|
||||||
updateUI();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void onClose() {
|
|
||||||
if (viewers.isEmpty()) {
|
|
||||||
dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addViewer(Player... players) {
|
|
||||||
if (viewers.isEmpty()) {
|
|
||||||
unsubscriber = stream.subscribe(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
super.addViewer(players);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 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.inventory.ui;
|
|
||||||
|
|
||||||
import de.steamwar.inventory.ui.item.Enchanted;
|
|
||||||
import de.steamwar.inventory.ui.item.OnClick;
|
|
||||||
import de.steamwar.inventory.ui.layout.FixedSizeContainer;
|
|
||||||
import de.steamwar.inventory.ui.util.*;
|
|
||||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
public interface UIComponent {
|
|
||||||
ComponentRender render(RenderContext context);
|
|
||||||
|
|
||||||
default UIComponent onClick(Consumer<InventoryClickEvent> event) {
|
|
||||||
return onClick(false, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
default UIComponent onClick(boolean allowDoubleClick, Consumer<InventoryClickEvent> event) {
|
|
||||||
return new OnClick(this, allowDoubleClick, inventoryClickEvent -> {
|
|
||||||
event.accept(inventoryClickEvent);
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
default UIComponent onClickWithUpdate(Function<InventoryClickEvent, Boolean> event) {
|
|
||||||
return onClickWithUpdate(false, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
default UIComponent onClickWithUpdate(boolean allowDoubleClick, Function<InventoryClickEvent, Boolean> event) {
|
|
||||||
return new OnClick(this, allowDoubleClick, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
default UIComponent onClickNoUpdate(Consumer<InventoryClickEvent> event) {
|
|
||||||
return onClickNoUpdate(false, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
default UIComponent onClickNoUpdate(boolean allowDoubleClick, Consumer<InventoryClickEvent> event) {
|
|
||||||
return new OnClick(this, allowDoubleClick, inventoryClickEvent -> {
|
|
||||||
event.accept(inventoryClickEvent);
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
default UIComponent cancelOnClick() {
|
|
||||||
return new OnClick(this, true, inventoryClickEvent -> false);
|
|
||||||
}
|
|
||||||
|
|
||||||
default UIComponent enchanted() {
|
|
||||||
return new Enchanted(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
default UIComponent enchanted(boolean enchanted) {
|
|
||||||
if (enchanted)
|
|
||||||
return enchanted();
|
|
||||||
else
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
default UIComponent size(Size size) {
|
|
||||||
return new FixedSizeContainer(size, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 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.inventory.ui;
|
|
||||||
|
|
||||||
import de.steamwar.inventory.ui.util.ComponentRender;
|
|
||||||
import de.steamwar.inventory.ui.util.RenderContext;
|
|
||||||
|
|
||||||
public abstract class UIFragment implements UIComponent {
|
|
||||||
|
|
||||||
abstract public UIComponent build(RenderContext context);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ComponentRender render(RenderContext context) {
|
|
||||||
return build(context).render(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,242 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 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.inventory.ui;
|
|
||||||
|
|
||||||
import de.steamwar.core.Core;
|
|
||||||
import de.steamwar.inventory.ui.util.ComponentRender;
|
|
||||||
import de.steamwar.inventory.ui.util.RenderContext;
|
|
||||||
import de.steamwar.inventory.ui.util.RenderItem;
|
|
||||||
import de.steamwar.inventory.ui.util.Size;
|
|
||||||
import de.steamwar.message.Message;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
|
||||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
|
||||||
import org.bukkit.inventory.Inventory;
|
|
||||||
import org.bukkit.inventory.InventoryView;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public abstract class UIInventory {
|
|
||||||
protected final List<Player> viewers = new ArrayList<>();
|
|
||||||
private final Map<Player, OpenPlayerInventory> callbacks = new HashMap<>();
|
|
||||||
private final Map<Player, ItemStack[]> originalItems = new HashMap<>();
|
|
||||||
|
|
||||||
private UIInventory parent;
|
|
||||||
private Player currentRender;
|
|
||||||
private final int playerSlots;
|
|
||||||
|
|
||||||
private List<MemoHookMeta<?>> memoHooks = new ArrayList<>();
|
|
||||||
private int buildHookCount = 0;
|
|
||||||
|
|
||||||
protected UIInventory() {
|
|
||||||
this(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected UIInventory(int playerSlots) {
|
|
||||||
this.playerSlots = playerSlots;
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract UIComponent render();
|
|
||||||
public abstract Inventory createInventory(Player player);
|
|
||||||
public abstract Message getMessages();
|
|
||||||
|
|
||||||
void onClose() { }
|
|
||||||
|
|
||||||
public <T> T useMemo(Supplier<T> supplier, List<Object> dependencies) {
|
|
||||||
int currentHook = buildHookCount++;
|
|
||||||
|
|
||||||
if (currentHook >= memoHooks.size()) {
|
|
||||||
T value = supplier.get();
|
|
||||||
memoHooks.add(new MemoHookMeta<>(dependencies, value));
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
MemoHookMeta<T> hook = (MemoHookMeta<T>) memoHooks.get(currentHook);
|
|
||||||
|
|
||||||
if (!hook.getDependencies().equals(dependencies)) {
|
|
||||||
hook.setDependencies(dependencies);
|
|
||||||
T value = supplier.get();
|
|
||||||
hook.setValue(value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
return hook.getValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T> T useMemo(Supplier<T> supplier) {
|
|
||||||
return useMemo(supplier, Collections.emptyList());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addViewer(Player... players) {
|
|
||||||
viewers.addAll(Arrays.asList(players));
|
|
||||||
|
|
||||||
for (Player player : players) {
|
|
||||||
openInventory(player);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void openInventory(Player player) {
|
|
||||||
if (playerSlots > 0) {
|
|
||||||
originalItems.put(player, player.getInventory().getContents());
|
|
||||||
}
|
|
||||||
Inventory inventory = createInventory(player);
|
|
||||||
renderPlayer(player, inventory);
|
|
||||||
InventoryView view = player.openInventory(inventory);
|
|
||||||
Core.getInstance().getLogger().info("[UIINV] Opened " + view.getTitle() + " for " + player.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void renderPlayer(Player player, Inventory inventory) {
|
|
||||||
int width = Math.min(inventory.getSize(), 9);
|
|
||||||
if (width < 9 && playerSlots > 0) {
|
|
||||||
throw new IllegalArgumentException("Player Inventory is only supported in Chests");
|
|
||||||
}
|
|
||||||
|
|
||||||
int inventoryHeight = Math.max(inventory.getSize() / 9, 1);
|
|
||||||
int height = inventoryHeight + playerSlots;
|
|
||||||
int invSize = inventoryHeight * width;
|
|
||||||
|
|
||||||
currentRender = player;
|
|
||||||
buildHookCount = 0;
|
|
||||||
ComponentRender render = render().render(new RenderContext(new Size(width, height), new Size(width, height), this));
|
|
||||||
buildHookCount = -1;
|
|
||||||
currentRender = null;
|
|
||||||
|
|
||||||
if (render.getSize().getWidth() > width || render.getSize().getHeight() > height) {
|
|
||||||
throw new IllegalArgumentException("The UIComponent does not fit in the inventory");
|
|
||||||
}
|
|
||||||
|
|
||||||
Message message = getMessages();
|
|
||||||
|
|
||||||
ItemStack[] itemStacks = new ItemStack[inventory.getSize()];
|
|
||||||
ItemStack[] playerStacks = new ItemStack[playerSlots > 0 ? 4 * 9 : 0];
|
|
||||||
|
|
||||||
for (RenderItem item : render.getItems()) {
|
|
||||||
int slot = item.getX() + item.getY() * 9;
|
|
||||||
if (slot < invSize) {
|
|
||||||
itemStacks[item.getX() + item.getY() * 9] = item.getItemStack().message(message).build(player);
|
|
||||||
} else {
|
|
||||||
playerStacks[(item.getX() + item.getY() * 9) - invSize] = item.getItemStack().message(message).build(player);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inventory.setContents(itemStacks);
|
|
||||||
if (playerSlots > 0) {
|
|
||||||
ItemStack[] lastRow = new ItemStack[9];
|
|
||||||
System.arraycopy(playerStacks, playerStacks.length - 9, lastRow, 0, 9);
|
|
||||||
System.arraycopy(playerStacks, 0, playerStacks, 9, playerStacks.length - 9);
|
|
||||||
System.arraycopy(lastRow, 0, playerStacks, 0, 9);
|
|
||||||
|
|
||||||
// TODO: Update to Client-Side Only Update
|
|
||||||
player.getInventory().setContents(playerStacks);
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<Integer, Function<InventoryClickEvent, Boolean>> clickEventMap = render.getItems().stream()
|
|
||||||
.filter(item -> item.getClickEvent() != null)
|
|
||||||
.collect(Collectors.toMap(renderItem -> renderItem.getX() + renderItem.getY() * 9, RenderItem::getClickEvent));
|
|
||||||
|
|
||||||
callbacks.computeIfAbsent(player, p -> new OpenPlayerInventory(p, clickEventMap).register()).setCallbacks(clickEventMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void updateTitle(String title, Object... params) {
|
|
||||||
if (currentRender != null) {
|
|
||||||
currentRender.getOpenInventory().setTitle(getMessages().parse(title, currentRender, params));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void updateUI() {
|
|
||||||
viewers.forEach(player -> renderPlayer(player, player.getOpenInventory().getTopInventory()));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void push(Player player, UIInventory inventory) {
|
|
||||||
inventory.parent = this;
|
|
||||||
inventory.addViewer(player);
|
|
||||||
viewers.remove(player);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void pop(Player player) {
|
|
||||||
if(parent == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
parent.addViewer(player);
|
|
||||||
}
|
|
||||||
|
|
||||||
@AllArgsConstructor
|
|
||||||
@Setter
|
|
||||||
private class OpenPlayerInventory implements Listener {
|
|
||||||
private final Player player;
|
|
||||||
private Map<Integer, Function<InventoryClickEvent, Boolean>> callbacks;
|
|
||||||
|
|
||||||
OpenPlayerInventory register() {
|
|
||||||
Core.getInstance().getServer().getPluginManager().registerEvents(this, Core.getInstance());
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onInventoryClick(InventoryClickEvent e) {
|
|
||||||
if (!player.equals(e.getWhoClicked()))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (callbacks.containsKey(e.getRawSlot()) && callbacks.get(e.getRawSlot()) != null) {
|
|
||||||
e.setCancelled(true);
|
|
||||||
Core.getInstance().getLogger().info("[UIINV] " + e.getWhoClicked().getName() + " " + e.getClick().name() + " clicked " + e.getRawSlot() + " on " + (e.getCurrentItem() != null ? e.getCurrentItem().getItemMeta().getDisplayName() : "[EMPTY]") + " in " + e.getView().getTitle());
|
|
||||||
if (callbacks.get(e.getRawSlot()).apply(e)) {
|
|
||||||
updateUI();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onInventoryClose(InventoryCloseEvent e){
|
|
||||||
if(!player.equals(e.getPlayer()))
|
|
||||||
return;
|
|
||||||
|
|
||||||
InventoryClickEvent.getHandlerList().unregister(this);
|
|
||||||
InventoryCloseEvent.getHandlerList().unregister(this);
|
|
||||||
Core.getInstance().getLogger().info("[UIINV] " + player.getName() + " closed " + e.getView().getTitle());
|
|
||||||
if(callbacks.containsKey(-1))
|
|
||||||
callbacks.get(-1).apply(null);
|
|
||||||
|
|
||||||
viewers.remove(player);
|
|
||||||
UIInventory.this.callbacks.remove(player);
|
|
||||||
if (playerSlots > 0) {
|
|
||||||
player.getInventory().setContents(originalItems.remove(player));
|
|
||||||
}
|
|
||||||
|
|
||||||
onClose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@AllArgsConstructor
|
|
||||||
private class MemoHookMeta<T> {
|
|
||||||
private List<Object> dependencies;
|
|
||||||
private T value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 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.inventory.ui.fragments;
|
|
||||||
|
|
||||||
import de.steamwar.inventory.ui.UIComponent;
|
|
||||||
import de.steamwar.inventory.ui.UIFragment;
|
|
||||||
import de.steamwar.inventory.ui.item.ItemBuilder;
|
|
||||||
import de.steamwar.inventory.ui.item.UIItem;
|
|
||||||
import de.steamwar.inventory.ui.layout.Row;
|
|
||||||
import de.steamwar.inventory.ui.util.RenderContext;
|
|
||||||
import de.steamwar.inventory.ui.util.Size;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
public class ActionBar extends UIFragment {
|
|
||||||
private static final UIComponent DEFAULT_FILLER = new UIItem(ItemBuilder.of(Material.GRAY_STAINED_GLASS_PANE).displayName("§e")).cancelOnClick();
|
|
||||||
|
|
||||||
private final Map<Integer, UIComponent> actionBar;
|
|
||||||
private UIComponent filler = DEFAULT_FILLER;
|
|
||||||
|
|
||||||
public ActionBar(Map<Integer, UIComponent> actionBar) {
|
|
||||||
this.actionBar = actionBar;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActionBar filler(UIComponent filler) {
|
|
||||||
this.filler = filler;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UIComponent build(RenderContext context) {
|
|
||||||
UIComponent[] components = context.useMemo(() -> {
|
|
||||||
UIComponent[] cmp = new UIComponent[context.getContainerSize().getWidth()];
|
|
||||||
for (int i = 0; i < cmp.length; i++) {
|
|
||||||
cmp[i] = actionBar.getOrDefault(i, filler);
|
|
||||||
}
|
|
||||||
|
|
||||||
return cmp;
|
|
||||||
}, Arrays.asList(actionBar));
|
|
||||||
|
|
||||||
return new Row(Arrays.asList(components)).size(new Size(context.getContainerSize().getWidth(), 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-97
@@ -1,97 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 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.inventory.ui.fragments;
|
|
||||||
|
|
||||||
import de.steamwar.core.Core;
|
|
||||||
import de.steamwar.inventory.ui.UIComponent;
|
|
||||||
import de.steamwar.inventory.ui.UIFragment;
|
|
||||||
import de.steamwar.inventory.ui.item.ItemBuilder;
|
|
||||||
import de.steamwar.inventory.ui.item.UIItem;
|
|
||||||
import de.steamwar.inventory.ui.layout.Column;
|
|
||||||
import de.steamwar.inventory.ui.layout.FixedSizeContainer;
|
|
||||||
import de.steamwar.inventory.ui.layout.Row;
|
|
||||||
import de.steamwar.inventory.ui.util.RenderContext;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.bukkit.DyeColor;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
@Setter
|
|
||||||
public class HorizontalScrollLayout extends UIFragment {
|
|
||||||
private List<UIComponent> data;
|
|
||||||
private int scroll = 0;
|
|
||||||
private final Map<Integer, UIComponent> actionBar = new HashMap<>();
|
|
||||||
|
|
||||||
public HorizontalScrollLayout(List<UIComponent> data) {
|
|
||||||
this.data = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int maxScroll() {
|
|
||||||
return Math.max(0, Math.min(scroll, data.size() - 9 + 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
public HorizontalScrollLayout actionBar(Map<Integer, UIComponent> actionBar) {
|
|
||||||
this.actionBar.clear();
|
|
||||||
this.actionBar.putAll(actionBar);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HorizontalScrollLayout data(List<UIComponent> data) {
|
|
||||||
this.data = data;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UIComponent build(RenderContext context) {
|
|
||||||
scroll = maxScroll();
|
|
||||||
boolean hasPrev = scroll > 0;
|
|
||||||
boolean hasNext = data.size() - scroll > 9;
|
|
||||||
|
|
||||||
Map<Integer, UIComponent> actionBar = context.useMemo(() -> {
|
|
||||||
Map<Integer, UIComponent> content = new HashMap<>(this.actionBar);
|
|
||||||
|
|
||||||
content.put(0, new UIItem(ItemBuilder.color(hasPrev ? DyeColor.LIME : DyeColor.GRAY).message(Core.MESSAGE).translateName(hasPrev ? "SWLISINV_PREVIOUS_PAGE_ACTIVE" : "SWLISINV_PREVIOUS_PAGE_INACTIVE")).onClickWithUpdate(inventoryClickEvent -> {
|
|
||||||
if (scroll > 0) {
|
|
||||||
scroll = Math.max(0, scroll - 9);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
content.put(8, new UIItem(ItemBuilder.color(hasNext ? DyeColor.LIME : DyeColor.GRAY).message(Core.MESSAGE).translateName(hasNext ? "SWLISINV_NEXT_PAGE_ACTIVE" : "SWLISINV_NEXT_PAGE_INACTIVE")).onClickWithUpdate(inventoryClickEvent -> {
|
|
||||||
if (hasNext) {
|
|
||||||
scroll = Math.min(scroll + 9, data.size() - 9);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
return content;
|
|
||||||
}, Arrays.asList(hasPrev, hasNext));
|
|
||||||
|
|
||||||
return new Column(
|
|
||||||
new FixedSizeContainer(context.getContainerSize().shrink(0, 1),
|
|
||||||
new Row(data.subList(scroll, Math.min(data.size(), scroll + 9)))
|
|
||||||
),
|
|
||||||
new ActionBar(actionBar)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,114 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 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.inventory.ui.fragments;
|
|
||||||
|
|
||||||
import de.steamwar.core.Core;
|
|
||||||
import de.steamwar.inventory.ui.UIComponent;
|
|
||||||
import de.steamwar.inventory.ui.UIFragment;
|
|
||||||
import de.steamwar.inventory.ui.item.ItemBuilder;
|
|
||||||
import de.steamwar.inventory.ui.item.UIItem;
|
|
||||||
import de.steamwar.inventory.ui.layout.Column;
|
|
||||||
import de.steamwar.inventory.ui.layout.FixedSizeContainer;
|
|
||||||
import de.steamwar.inventory.ui.layout.Grid;
|
|
||||||
import de.steamwar.inventory.ui.util.RenderContext;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.bukkit.DyeColor;
|
|
||||||
import org.bukkit.event.inventory.ClickType;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
public class PageLayout<T> extends UIFragment {
|
|
||||||
|
|
||||||
private final List<UIListEntry<T>> items;
|
|
||||||
private final UIListCallback<T> callback;
|
|
||||||
private int page = 0;
|
|
||||||
private Consumer<Integer> onPageChange = null;
|
|
||||||
private Map<Integer, UIItem> itemsOnBar = Collections.emptyMap();
|
|
||||||
|
|
||||||
public PageLayout(List<UIListEntry<T>> items, UIListCallback<T> callback) {
|
|
||||||
System.out.println(items.size());
|
|
||||||
this.items = items;
|
|
||||||
this.callback = callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UIComponent build(RenderContext context) {
|
|
||||||
|
|
||||||
int itemsOnPage = context.getContainerSize().getWidth() * (context.getContainerSize().getHeight() - 1);
|
|
||||||
|
|
||||||
List<UIComponent> uiItems = context.useMemo(() -> {
|
|
||||||
int i = page * itemsOnPage;
|
|
||||||
|
|
||||||
int ipageLimit = items.size() - page * itemsOnPage;
|
|
||||||
if (ipageLimit > itemsOnPage) {
|
|
||||||
ipageLimit = itemsOnPage;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<UIComponent> pageItems = new ArrayList<>();
|
|
||||||
for (int ipage = 0; ipage < ipageLimit; ipage++) {
|
|
||||||
UIListEntry<T> e = items.get(i);
|
|
||||||
|
|
||||||
pageItems.add(new UIItem(e.item).onClickNoUpdate(inventoryClickEvent -> callback.clicked(inventoryClickEvent.getClick(), e.object)));
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return pageItems;
|
|
||||||
}, Arrays.asList(page, items.size(), itemsOnPage));
|
|
||||||
|
|
||||||
Map<Integer, UIComponent> uiBar = context.useMemo(() -> {
|
|
||||||
Map<Integer, UIComponent> content = new HashMap<>(itemsOnBar);
|
|
||||||
|
|
||||||
if (page != 0) {
|
|
||||||
content.put(0, new UIItem(ItemBuilder.color(DyeColor.LIME).message(Core.MESSAGE).translateName("SWLISINV_PREVIOUS_PAGE_ACTIVE")).onClick(inventoryClickEvent -> page--));
|
|
||||||
} else {
|
|
||||||
content.put(0, new UIItem(ItemBuilder.color(DyeColor.GRAY).message(Core.MESSAGE).translateName("SWLISINV_PREVIOUS_PAGE_INACTIVE")).cancelOnClick());
|
|
||||||
}
|
|
||||||
if (page < items.size() / itemsOnPage - (items.size() % itemsOnPage == 0 ? 1 : 0)) {
|
|
||||||
content.put(8, new UIItem(ItemBuilder.color(DyeColor.LIME).message(Core.MESSAGE).translateName("SWLISINV_NEXT_PAGE_ACTIVE")).onClick(inventoryClickEvent -> page++));
|
|
||||||
} else {
|
|
||||||
content.put(8, new UIItem(ItemBuilder.color(DyeColor.GRAY).message(Core.MESSAGE).translateName("SWLISINV_NEXT_PAGE_INACTIVE")).cancelOnClick());
|
|
||||||
}
|
|
||||||
|
|
||||||
return content;
|
|
||||||
}, Arrays.asList(page, items.size(), itemsOnPage));
|
|
||||||
|
|
||||||
return new Column(
|
|
||||||
new FixedSizeContainer(context.getContainerSize().shrink(0, 1),
|
|
||||||
new Grid(uiItems)),
|
|
||||||
new ActionBar(uiBar)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public interface UIListCallback<T>{
|
|
||||||
void clicked(ClickType click, T element);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public static class UIListEntry<T>{
|
|
||||||
final ItemBuilder item;
|
|
||||||
final T object;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 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.inventory.ui.item;
|
|
||||||
|
|
||||||
import de.steamwar.inventory.ui.UIComponent;
|
|
||||||
import de.steamwar.inventory.ui.util.ComponentRender;
|
|
||||||
import de.steamwar.inventory.ui.util.RenderContext;
|
|
||||||
import de.steamwar.inventory.ui.util.RenderItem;
|
|
||||||
|
|
||||||
public class Enchanted implements UIComponent {
|
|
||||||
private final UIComponent children;
|
|
||||||
|
|
||||||
public Enchanted(UIComponent children) {
|
|
||||||
this.children = children;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ComponentRender render(RenderContext context) {
|
|
||||||
ComponentRender render = children.render(context);
|
|
||||||
|
|
||||||
for (RenderItem item : render.getItems()) {
|
|
||||||
item.getItemStack().enchanted();
|
|
||||||
}
|
|
||||||
|
|
||||||
return render;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,205 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 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.inventory.ui.item;
|
|
||||||
|
|
||||||
import de.steamwar.core.FlatteningWrapper;
|
|
||||||
import de.steamwar.core.TrickyTrialsWrapper;
|
|
||||||
import de.steamwar.inventory.SWItem;
|
|
||||||
import de.steamwar.message.Message;
|
|
||||||
import de.steamwar.message.SubMessage;
|
|
||||||
import org.bukkit.DyeColor;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.OfflinePlayer;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemFlag;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class ItemBuilder {
|
|
||||||
private static final Map<DyeColor, Integer> DYE_COLOR_INTEGER_MAP = new EnumMap<>(DyeColor.class);
|
|
||||||
|
|
||||||
static {
|
|
||||||
DYE_COLOR_INTEGER_MAP.put(DyeColor.BLACK, 16);
|
|
||||||
DYE_COLOR_INTEGER_MAP.put(DyeColor.RED, 1);
|
|
||||||
DYE_COLOR_INTEGER_MAP.put(DyeColor.GREEN, 2);
|
|
||||||
DYE_COLOR_INTEGER_MAP.put(DyeColor.BROWN, 3);
|
|
||||||
DYE_COLOR_INTEGER_MAP.put(DyeColor.BLUE, 4);
|
|
||||||
DYE_COLOR_INTEGER_MAP.put(DyeColor.PURPLE, 5);
|
|
||||||
DYE_COLOR_INTEGER_MAP.put(DyeColor.CYAN, 6);
|
|
||||||
DYE_COLOR_INTEGER_MAP.put(DyeColor.LIGHT_GRAY, 7);
|
|
||||||
DYE_COLOR_INTEGER_MAP.put(DyeColor.GRAY, 8);
|
|
||||||
DYE_COLOR_INTEGER_MAP.put(DyeColor.PINK, 9);
|
|
||||||
DYE_COLOR_INTEGER_MAP.put(DyeColor.LIME, 10);
|
|
||||||
DYE_COLOR_INTEGER_MAP.put(DyeColor.YELLOW, 11);
|
|
||||||
DYE_COLOR_INTEGER_MAP.put(DyeColor.LIGHT_BLUE, 12);
|
|
||||||
DYE_COLOR_INTEGER_MAP.put(DyeColor.MAGENTA, 13);
|
|
||||||
DYE_COLOR_INTEGER_MAP.put(DyeColor.ORANGE, 14);
|
|
||||||
DYE_COLOR_INTEGER_MAP.put(DyeColor.WHITE, 15);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final ItemStack itemStack;
|
|
||||||
private final ItemMeta itemMeta;
|
|
||||||
private Message message = null;
|
|
||||||
private SubMessage translateName = null;
|
|
||||||
private List<SubMessage> translateLore = null;
|
|
||||||
|
|
||||||
private ItemBuilder(Material material) {
|
|
||||||
this(new ItemStack(material));
|
|
||||||
}
|
|
||||||
private ItemBuilder(ItemStack item) {
|
|
||||||
this.itemStack = item;
|
|
||||||
this.itemMeta = itemStack.getItemMeta();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ItemBuilder of(Material material) {
|
|
||||||
return new ItemBuilder(material);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ItemBuilder of(ItemStack itemStack) {
|
|
||||||
return new ItemBuilder(itemStack.getType()).amount(itemStack.getAmount());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ItemBuilder of(Material material, Byte meta) {
|
|
||||||
ItemStack itemStack;
|
|
||||||
try {
|
|
||||||
itemStack = new ItemStack(material, 1, (short)0, meta);
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
itemStack = new ItemStack(material, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ItemBuilder(itemStack);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ItemBuilder color(DyeColor color) {
|
|
||||||
return ItemBuilder.of(SWItem.getDye(DYE_COLOR_INTEGER_MAP.get(color)), DYE_COLOR_INTEGER_MAP.get(color).byteValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ItemBuilder skull(OfflinePlayer player) {
|
|
||||||
return skull(player.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ItemBuilder skull(String name) {
|
|
||||||
return ItemBuilder.of(FlatteningWrapper.impl.setSkullOwner(name));
|
|
||||||
}
|
|
||||||
|
|
||||||
public ItemBuilder message(Message message) {
|
|
||||||
if (this.message == null) {
|
|
||||||
this.message = message;
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ItemStack build(Player player) {
|
|
||||||
if (message != null) {
|
|
||||||
if (translateName != null) {
|
|
||||||
itemMeta.setDisplayName(message.parse(translateName.getMessage(), player, translateName.getParams()));
|
|
||||||
}
|
|
||||||
if (translateLore != null) {
|
|
||||||
itemMeta.setLore(translateLore.stream().map(subMessage -> message.parse(subMessage.getMessage(), player, subMessage.getParams())).collect(Collectors.toList()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
itemStack.setItemMeta(itemMeta);
|
|
||||||
return itemStack;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ItemBuilder amount(int amount) {
|
|
||||||
itemStack.setAmount(amount);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ItemBuilder displayName(String name) {
|
|
||||||
itemMeta.setDisplayName(name);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ItemBuilder lore(String... lore) {
|
|
||||||
if (itemMeta.hasLore()) {
|
|
||||||
List<String> loreList = itemMeta.getLore();
|
|
||||||
loreList.addAll(Arrays.asList(lore));
|
|
||||||
itemMeta.setLore(loreList);
|
|
||||||
} else {
|
|
||||||
itemMeta.setLore(Arrays.asList(lore));
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ItemBuilder translateName(String name, Object... params) {
|
|
||||||
this.translateName = new SubMessage(name, params);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ItemBuilder addTranslateLore(SubMessage... lore) {
|
|
||||||
if (this.translateLore == null) {
|
|
||||||
this.translateLore = Arrays.asList(lore);
|
|
||||||
} else {
|
|
||||||
this.translateLore.addAll(Arrays.asList(lore));
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ItemBuilder enchanted() {
|
|
||||||
itemMeta.addEnchant(TrickyTrialsWrapper.impl.getUnbreakingEnchantment(), 10, true);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ItemBuilder enchanted(boolean enchanted) {
|
|
||||||
if(enchanted) {
|
|
||||||
return enchanted();
|
|
||||||
} else {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ItemBuilder hideFlags() {
|
|
||||||
for (ItemFlag flag : EnumSet.allOf(ItemFlag.class)) {
|
|
||||||
itemMeta.addItemFlags(flag);
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ItemBuilder customModel(int modelData) {
|
|
||||||
itemMeta.setCustomModelData(modelData);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
|
|
||||||
ItemBuilder that = (ItemBuilder) o;
|
|
||||||
return Objects.equals(itemStack, that.itemStack) && Objects.equals(itemMeta, that.itemMeta) && Objects.equals(message, that.message) && Objects.equals(translateName, that.translateName) && Objects.equals(translateLore, that.translateLore);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "ItemBuilder{" +
|
|
||||||
"itemStack=" + itemStack +
|
|
||||||
", itemMeta=" + itemMeta +
|
|
||||||
", message=" + message +
|
|
||||||
", translateName=" + translateName +
|
|
||||||
", translateLore=" + translateLore +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 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.inventory.ui.item;
|
|
||||||
|
|
||||||
import de.steamwar.inventory.ui.UIComponent;
|
|
||||||
import de.steamwar.inventory.ui.util.ComponentRender;
|
|
||||||
import de.steamwar.inventory.ui.util.RenderContext;
|
|
||||||
import de.steamwar.inventory.ui.util.RenderItem;
|
|
||||||
import org.bukkit.event.inventory.ClickType;
|
|
||||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
|
||||||
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
public class OnClick implements UIComponent {
|
|
||||||
private final UIComponent children;
|
|
||||||
private final boolean allowDoubleClick;
|
|
||||||
private final Function<InventoryClickEvent, Boolean> event;
|
|
||||||
|
|
||||||
public OnClick(UIComponent children, boolean allowDoubleClick, Function<InventoryClickEvent, Boolean> event) {
|
|
||||||
this.children = children;
|
|
||||||
this.allowDoubleClick = allowDoubleClick;
|
|
||||||
this.event = event;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ComponentRender render(RenderContext context) {
|
|
||||||
ComponentRender render = children.render(context);
|
|
||||||
|
|
||||||
for (RenderItem item : render.getItems()) {
|
|
||||||
item.setClickEvent(ev -> {
|
|
||||||
if (ev.getClick() != ClickType.DOUBLE_CLICK || allowDoubleClick) {
|
|
||||||
return event.apply(ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return render;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "OnClick{" +
|
|
||||||
"children=" + children +
|
|
||||||
", allowDoubleClick=" + allowDoubleClick +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
|
|
||||||
OnClick onClick = (OnClick) o;
|
|
||||||
return allowDoubleClick == onClick.allowDoubleClick && children.equals(onClick.children);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 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.inventory.ui.item;
|
|
||||||
|
|
||||||
import de.steamwar.inventory.ui.UIComponent;
|
|
||||||
import de.steamwar.inventory.ui.util.ComponentRender;
|
|
||||||
import de.steamwar.inventory.ui.util.RenderContext;
|
|
||||||
import de.steamwar.inventory.ui.util.Size;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
public class Space implements UIComponent {
|
|
||||||
@Override
|
|
||||||
public ComponentRender render(RenderContext context) {
|
|
||||||
return new ComponentRender(
|
|
||||||
new ArrayList<>(),
|
|
||||||
new Size(1, 1)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
return obj instanceof Space;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 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.inventory.ui.item;
|
|
||||||
|
|
||||||
import de.steamwar.inventory.ui.UIComponent;
|
|
||||||
import de.steamwar.inventory.ui.util.*;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
public class UIItem implements UIComponent {
|
|
||||||
|
|
||||||
private final ItemBuilder itemStack;
|
|
||||||
|
|
||||||
public UIItem(ItemStack itemStack) {
|
|
||||||
this(ItemBuilder.of(itemStack));
|
|
||||||
}
|
|
||||||
|
|
||||||
public UIItem(ItemBuilder itemStack) {
|
|
||||||
this.itemStack = itemStack;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ComponentRender render(RenderContext context) {
|
|
||||||
return new ComponentRender(
|
|
||||||
Arrays.asList(new RenderItem(0, 0, itemStack, null)),
|
|
||||||
new Size(1, 1)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "UIItem{" +
|
|
||||||
"itemStack=" + itemStack +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
|
|
||||||
UIItem uiItem = (UIItem) o;
|
|
||||||
return Objects.equals(itemStack, uiItem.itemStack);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 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.inventory.ui.layout;
|
|
||||||
|
|
||||||
public enum Alignment {
|
|
||||||
START,
|
|
||||||
CENTER,
|
|
||||||
END,
|
|
||||||
BETWEEN
|
|
||||||
}
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 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.inventory.ui.layout;
|
|
||||||
|
|
||||||
import de.steamwar.inventory.ui.UIComponent;
|
|
||||||
import de.steamwar.inventory.ui.util.*;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class Column implements UIComponent {
|
|
||||||
|
|
||||||
private final List<UIComponent> components;
|
|
||||||
|
|
||||||
private Alignment alignment;
|
|
||||||
private boolean shrinkWrap = false;
|
|
||||||
|
|
||||||
public Column(UIComponent... components) {
|
|
||||||
this(Arrays.asList(components));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Column(List<UIComponent> components) {
|
|
||||||
this.components = components;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Column centered() {
|
|
||||||
this.alignment = Alignment.CENTER;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Column setShrinkWrap(boolean shrinkWrap) {
|
|
||||||
this.shrinkWrap = shrinkWrap;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ComponentRender render(RenderContext context) {
|
|
||||||
List<RenderItem> renderItems = new ArrayList<>();
|
|
||||||
|
|
||||||
int height = 0;
|
|
||||||
int maxWidth = 0;
|
|
||||||
|
|
||||||
for (UIComponent component : components) {
|
|
||||||
ComponentRender render = component.render(context.withContainerSize(context.getContainerSize().withHeight(context.getContainerSize().getHeight() - height)));
|
|
||||||
for(RenderItem item : render.getItems()){
|
|
||||||
renderItems.add(item.shift(0, height));
|
|
||||||
}
|
|
||||||
maxWidth = Math.max(maxWidth, render.getSize().getWidth());
|
|
||||||
height += render.getSize().getHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (alignment == Alignment.CENTER) {
|
|
||||||
int shiftAmount = (context.getContainerSize().getHeight() - height) / 2;
|
|
||||||
for (RenderItem item : renderItems) {
|
|
||||||
item.shift(0, shiftAmount);
|
|
||||||
}
|
|
||||||
} else if (alignment == Alignment.BETWEEN) {
|
|
||||||
int shiftAmount = (context.getContainerSize().getHeight() - height) / (components.size() - 1);
|
|
||||||
for (int i = 0; i < components.size() - 1; i++) {
|
|
||||||
RenderItem item = renderItems.get(i);
|
|
||||||
item.shift(0, shiftAmount * i);
|
|
||||||
}
|
|
||||||
} else if (alignment == Alignment.END) {
|
|
||||||
int shiftAmount = (context.getContainerSize().getHeight() - height);
|
|
||||||
for (RenderItem item : renderItems) {
|
|
||||||
item.shift(0, shiftAmount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ComponentRender(
|
|
||||||
renderItems,
|
|
||||||
new Size(maxWidth, shrinkWrap ? height : context.getContainerSize().getHeight())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-40
@@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 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.inventory.ui.layout;
|
|
||||||
|
|
||||||
import de.steamwar.inventory.ui.UIComponent;
|
|
||||||
import de.steamwar.inventory.ui.util.ComponentRender;
|
|
||||||
import de.steamwar.inventory.ui.util.RenderContext;
|
|
||||||
import de.steamwar.inventory.ui.util.Size;
|
|
||||||
|
|
||||||
public class FixedSizeContainer implements UIComponent {
|
|
||||||
private final UIComponent children;
|
|
||||||
private final Size size;
|
|
||||||
|
|
||||||
public FixedSizeContainer(Size size, UIComponent children) {
|
|
||||||
this.children = children;
|
|
||||||
this.size = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ComponentRender render(RenderContext context) {
|
|
||||||
return children.render(context.withContainerSize(size)).withSize(size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 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.inventory.ui.layout;
|
|
||||||
|
|
||||||
import de.steamwar.inventory.ui.UIComponent;
|
|
||||||
import de.steamwar.inventory.ui.util.ComponentRender;
|
|
||||||
import de.steamwar.inventory.ui.util.RenderContext;
|
|
||||||
import de.steamwar.inventory.ui.util.RenderItem;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class Grid implements UIComponent {
|
|
||||||
private final List<UIComponent> children;
|
|
||||||
|
|
||||||
public Grid(UIComponent... children) {
|
|
||||||
this(Arrays.asList(children));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Grid(List<UIComponent> children) {
|
|
||||||
this.children = children;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ComponentRender render(RenderContext context) {
|
|
||||||
List<RenderItem> renderItems = new ArrayList<>();
|
|
||||||
int x = 0;
|
|
||||||
int y = 0;
|
|
||||||
int currentRowMaxHeight = 0;
|
|
||||||
|
|
||||||
for (UIComponent child : children) {
|
|
||||||
ComponentRender render = child.render(context.withContainerSize(
|
|
||||||
context.getContainerSize()
|
|
||||||
.withWidth(context.getContainerSize().getWidth() - x)
|
|
||||||
.withHeight(context.getContainerSize().getHeight() - y)));
|
|
||||||
currentRowMaxHeight = Math.max(currentRowMaxHeight, render.getSize().getHeight());
|
|
||||||
for (RenderItem item : render.getItems()) {
|
|
||||||
renderItems.add(item.shift(x, y));
|
|
||||||
}
|
|
||||||
x += render.getSize().getWidth();
|
|
||||||
if(x >= context.getContainerSize().getWidth()){
|
|
||||||
x = 0;
|
|
||||||
y += currentRowMaxHeight;
|
|
||||||
currentRowMaxHeight = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ComponentRender(renderItems, context.getContainerSize());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 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.inventory.ui.layout;
|
|
||||||
|
|
||||||
import de.steamwar.inventory.ui.UIComponent;
|
|
||||||
import de.steamwar.inventory.ui.util.*;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class Row implements UIComponent {
|
|
||||||
|
|
||||||
private final List<UIComponent> components;
|
|
||||||
|
|
||||||
private Alignment alignment;
|
|
||||||
private boolean shrinkWrap = false;
|
|
||||||
|
|
||||||
public Row(UIComponent... components) {
|
|
||||||
this(Arrays.asList(components));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Row(List<UIComponent> components) {
|
|
||||||
this.components = components;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Row centered() {
|
|
||||||
this.alignment = Alignment.CENTER;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Row alignment(Alignment alignment) {
|
|
||||||
this.alignment = alignment;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Row setShrinkWrap(boolean shrinkWrap) {
|
|
||||||
this.shrinkWrap = shrinkWrap;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ComponentRender render(RenderContext context) {
|
|
||||||
List<RenderItem> renderItems = new ArrayList<>();
|
|
||||||
|
|
||||||
int width = 0;
|
|
||||||
int maxHeight = 0;
|
|
||||||
|
|
||||||
for (UIComponent component : components) {
|
|
||||||
ComponentRender render = component.render(context.withContainerSize(context.getContainerSize().withWidth(context.getContainerSize().getWidth() - width)));
|
|
||||||
for(RenderItem item : render.getItems()){
|
|
||||||
renderItems.add(item.shift(width, 0));
|
|
||||||
}
|
|
||||||
maxHeight = Math.max(maxHeight, render.getSize().getHeight());
|
|
||||||
width += render.getSize().getWidth();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (alignment == Alignment.CENTER) {
|
|
||||||
int shiftAmount = (context.getContainerSize().getWidth() - width) / 2;
|
|
||||||
for (RenderItem item : renderItems) {
|
|
||||||
item.shift(shiftAmount, 0);
|
|
||||||
}
|
|
||||||
} else if (alignment == Alignment.BETWEEN) {
|
|
||||||
int shiftAmount = (context.getContainerSize().getWidth() - width) / (components.size() - 1);
|
|
||||||
for (int i = 0; i < components.size() - 1; i++) {
|
|
||||||
RenderItem item = renderItems.get(i);
|
|
||||||
item.shift(shiftAmount * i, 0);
|
|
||||||
}
|
|
||||||
} else if (alignment == Alignment.END) {
|
|
||||||
int shiftAmount = (context.getContainerSize().getWidth() - width);
|
|
||||||
for (RenderItem item : renderItems) {
|
|
||||||
item.shift(shiftAmount, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ComponentRender(
|
|
||||||
renderItems,
|
|
||||||
new Size(shrinkWrap ? width : context.getContainerSize().getWidth(), maxHeight)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 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.inventory.ui.test;
|
|
||||||
|
|
||||||
import de.steamwar.command.SWCommand;
|
|
||||||
import de.steamwar.inventory.ui.util.UpdateStream;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class TestInvCommand extends SWCommand {
|
|
||||||
|
|
||||||
public static final UpdateStream<List<Integer>> STREAM = new UpdateStream<>(new ArrayList<>());
|
|
||||||
|
|
||||||
public TestInvCommand() {
|
|
||||||
super("testinv");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Register
|
|
||||||
public void run(Player player) {
|
|
||||||
new TestInventory(STREAM).addViewer(player);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 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.inventory.ui.test;
|
|
||||||
|
|
||||||
import de.steamwar.core.Core;
|
|
||||||
import de.steamwar.inventory.ui.StatefulUIInventory;
|
|
||||||
import de.steamwar.inventory.ui.UIComponent;
|
|
||||||
import de.steamwar.inventory.ui.fragments.HorizontalScrollLayout;
|
|
||||||
import de.steamwar.inventory.ui.item.ItemBuilder;
|
|
||||||
import de.steamwar.inventory.ui.item.UIItem;
|
|
||||||
import de.steamwar.inventory.ui.util.UpdateStream;
|
|
||||||
import de.steamwar.message.Message;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.Inventory;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import static de.steamwar.inventory.ui.test.TestInvCommand.STREAM;
|
|
||||||
|
|
||||||
public class TestInventory extends StatefulUIInventory<List<Integer>> {
|
|
||||||
|
|
||||||
private HorizontalScrollLayout scrollLayout;
|
|
||||||
private static int counter = 1;
|
|
||||||
|
|
||||||
public TestInventory(UpdateStream<List<Integer>> stateObservable) {
|
|
||||||
super(stateObservable);
|
|
||||||
scrollLayout = new HorizontalScrollLayout(new ArrayList<>());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected UIComponent render(List<Integer> state) {
|
|
||||||
return scrollLayout;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void update(List<Integer> state) {
|
|
||||||
System.out.println("Update");
|
|
||||||
List<UIComponent> items = state.stream().map(integer -> new UIItem(ItemBuilder.of(Material.ACACIA_PLANKS).displayName(String.valueOf(integer))).onClickNoUpdate(inventoryClickEvent -> STREAM.update(current -> {
|
|
||||||
current.remove(integer);
|
|
||||||
return current;
|
|
||||||
}))).collect(Collectors.toList());
|
|
||||||
items.add(new UIItem(ItemBuilder.of(Material.BUCKET).displayName("Add")).onClickNoUpdate(inventoryClickEvent -> STREAM.update(current -> {
|
|
||||||
current.add(counter++);
|
|
||||||
return current;
|
|
||||||
})));
|
|
||||||
scrollLayout = scrollLayout.data(items);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Inventory createInventory(Player player) {
|
|
||||||
return Bukkit.createInventory(null, 9 * 6, "Test Inventory");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Message getMessages() {
|
|
||||||
return Core.MESSAGE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 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.inventory.ui.util;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.With;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
@With
|
|
||||||
public class ComponentRender {
|
|
||||||
private final List<RenderItem> items;
|
|
||||||
private final Size size;
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 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.inventory.ui.util;
|
|
||||||
|
|
||||||
import de.steamwar.inventory.ui.UIInventory;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.With;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
@With
|
|
||||||
public class RenderContext {
|
|
||||||
private final Size inventorySize;
|
|
||||||
private final Size containerSize;
|
|
||||||
private final UIInventory inventory;
|
|
||||||
|
|
||||||
public <T> T useMemo(Supplier<T> supplier, List<Object> dependencies) {
|
|
||||||
return inventory.useMemo(supplier, dependencies);
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T> T useMemo(Supplier<T> supplier) {
|
|
||||||
return inventory.useMemo(supplier);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 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.inventory.ui.util;
|
|
||||||
|
|
||||||
import de.steamwar.inventory.ui.item.ItemBuilder;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.With;
|
|
||||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
|
||||||
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
@With
|
|
||||||
@AllArgsConstructor
|
|
||||||
public class RenderItem {
|
|
||||||
private int x;
|
|
||||||
private int y;
|
|
||||||
private ItemBuilder itemStack;
|
|
||||||
private Function<InventoryClickEvent, Boolean> clickEvent;
|
|
||||||
|
|
||||||
public RenderItem shift(int deltaX, int deltaY) {
|
|
||||||
return withX(x + deltaX).withY(y + deltaY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 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.inventory.ui.util;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.With;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
@With
|
|
||||||
public class Size {
|
|
||||||
private final int width;
|
|
||||||
private final int height;
|
|
||||||
|
|
||||||
public Size shrink(int width, int height) {
|
|
||||||
return new Size(this.width - width, this.height - height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 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.inventory.ui.util;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class UpdateStream<T> {
|
|
||||||
|
|
||||||
private T current;
|
|
||||||
|
|
||||||
private final List<Subscriber<T>> subscribers = new ArrayList<>();
|
|
||||||
|
|
||||||
public UpdateStream(T current) {
|
|
||||||
this.current = current;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Unsubscriber subscribe(Subscriber<T> subscriber) {
|
|
||||||
subscribers.add(subscriber);
|
|
||||||
subscriber.onUpdate(current);
|
|
||||||
return () -> subscribers.remove(subscriber);
|
|
||||||
}
|
|
||||||
|
|
||||||
public T get() {
|
|
||||||
return current;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void emit(T newCurrent) {
|
|
||||||
current = newCurrent;
|
|
||||||
subscribers.forEach(subscriber -> subscriber.onUpdate(newCurrent));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update(Updater<T> updater) {
|
|
||||||
current = updater.update(current);
|
|
||||||
subscribers.forEach(subscriber -> subscriber.onUpdate(current));
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface Subscriber<T> {
|
|
||||||
void onUpdate(T current);
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface Unsubscriber {
|
|
||||||
void unsubscribe();
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface Updater<T> {
|
|
||||||
T update(T current);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -67,3 +67,11 @@ dependencies {
|
|||||||
|
|
||||||
implementation(libs.nbt)
|
implementation(libs.nbt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks.register<DevServer>("DevVelocity") {
|
||||||
|
group = "run"
|
||||||
|
description = "Run a Dev Velocity"
|
||||||
|
dependsOn(":VelocityCore:shadowJar")
|
||||||
|
dependsOn(":VelocityCore:Persistent:jar")
|
||||||
|
template = "DevVelocity"
|
||||||
|
}
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ public enum ServerVersion {
|
|||||||
PAPER_18("paper-1.18.2.jar", 15, ProtocolVersion.MINECRAFT_1_18_2),
|
PAPER_18("paper-1.18.2.jar", 15, ProtocolVersion.MINECRAFT_1_18_2),
|
||||||
PAPER_19("paper-1.19.3.jar", 19, ProtocolVersion.MINECRAFT_1_19_3),
|
PAPER_19("paper-1.19.3.jar", 19, ProtocolVersion.MINECRAFT_1_19_3),
|
||||||
PAPER_20("paper-1.20.1.jar", 20, ProtocolVersion.MINECRAFT_1_20),
|
PAPER_20("paper-1.20.1.jar", 20, ProtocolVersion.MINECRAFT_1_20),
|
||||||
|
DEVEL_21("paper-1.21.5.jar", 21, ProtocolVersion.MINECRAFT_1_21_5),
|
||||||
PAPER_21("paper-1.21.3.jar", 21, ProtocolVersion.MINECRAFT_1_21_2);
|
PAPER_21("paper-1.21.3.jar", 21, ProtocolVersion.MINECRAFT_1_21_2);
|
||||||
|
|
||||||
private static final Map<String, ServerVersion> chatMap = new HashMap<>();
|
private static final Map<String, ServerVersion> chatMap = new HashMap<>();
|
||||||
@@ -94,6 +95,10 @@ public enum ServerVersion {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static ServerVersion get(int version) {
|
public static ServerVersion get(int version) {
|
||||||
|
if (version == 21) {
|
||||||
|
return DEVEL_21;
|
||||||
|
}
|
||||||
|
|
||||||
return versionMap.get(version);
|
return versionMap.get(version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -149,6 +149,23 @@ fun Route.configureSchematic() {
|
|||||||
return@let SchematicFormat.SPONGE_V2
|
return@let SchematicFormat.SPONGE_V2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (version == SchematicFormat.SPONGE_V3) {
|
||||||
|
try {
|
||||||
|
val fawe = schem.getCompound("Metadata")
|
||||||
|
.getCompound("WorldEdit")
|
||||||
|
.getString("Version")
|
||||||
|
.value
|
||||||
|
|
||||||
|
if (fawe.equals("2.12.3-SNAPSHOT")) {
|
||||||
|
SWException.log("Schematic with Bugged Version Uploaded", """
|
||||||
|
Schematic=$schemName
|
||||||
|
User=${user.userName}
|
||||||
|
Id=${user.id}
|
||||||
|
""".trimIndent())
|
||||||
|
}
|
||||||
|
} catch (_: Exception) {}
|
||||||
|
}
|
||||||
|
|
||||||
val data = NodeData(node.id, version)
|
val data = NodeData(node.id, version)
|
||||||
data.saveFromStream(content.inputStream(), version)
|
data.saveFromStream(content.inputStream(), version)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,214 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020 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/>.
|
||||||
|
*/
|
||||||
|
plugins {
|
||||||
|
}
|
||||||
|
|
||||||
|
class DevServer extends DefaultTask {
|
||||||
|
|
||||||
|
@Input
|
||||||
|
@Optional
|
||||||
|
String worldName = null
|
||||||
|
|
||||||
|
@Input
|
||||||
|
String template = null
|
||||||
|
|
||||||
|
@Input
|
||||||
|
@Optional
|
||||||
|
String plugins = null
|
||||||
|
|
||||||
|
@Input
|
||||||
|
@Optional
|
||||||
|
Integer port = null
|
||||||
|
|
||||||
|
@Input
|
||||||
|
@Optional
|
||||||
|
String jar = null
|
||||||
|
|
||||||
|
@Input
|
||||||
|
@Optional
|
||||||
|
Map<String, String> dParams = new HashMap<>()
|
||||||
|
|
||||||
|
DevServer() {
|
||||||
|
super()
|
||||||
|
doFirst {
|
||||||
|
List<Project> projects = []
|
||||||
|
projects.add(project)
|
||||||
|
while (projects.first.parent != null) {
|
||||||
|
projects.add(0, projects.first.parent)
|
||||||
|
}
|
||||||
|
|
||||||
|
def properties = new Properties()
|
||||||
|
projects.forEach {
|
||||||
|
def file = new File(it.projectDir, "steamwar.properties")
|
||||||
|
if (file.exists()) {
|
||||||
|
properties.load(new FileInputStream(file))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (worldName == null) worldName = properties.get("worldName")
|
||||||
|
host = properties.get("host")
|
||||||
|
|
||||||
|
if (host == null) {
|
||||||
|
throw new GradleException("Please supply the 'host' in a 'steamwar.properties' files either in this project dir or any parent project!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
doLast {
|
||||||
|
checkHasTemplate()
|
||||||
|
uploadDependencies()
|
||||||
|
startDevServer()
|
||||||
|
}
|
||||||
|
finalizedBy(new Finalizer())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Internal
|
||||||
|
BufferedWriter processInput
|
||||||
|
|
||||||
|
@Internal
|
||||||
|
String host
|
||||||
|
|
||||||
|
@Internal
|
||||||
|
Boolean running = true
|
||||||
|
|
||||||
|
class Finalizer extends DefaultTask {
|
||||||
|
|
||||||
|
Finalizer() {
|
||||||
|
super()
|
||||||
|
doLast {
|
||||||
|
running = false
|
||||||
|
if (processInput != null) {
|
||||||
|
processInput.write(template.endsWith("Velocity") ? "end\n" : "stop\n")
|
||||||
|
processInput.flush()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkHasTemplate() {
|
||||||
|
def process = new ProcessBuilder("ssh", host, "-T", "ls $template").start()
|
||||||
|
process.waitFor()
|
||||||
|
if (new BufferedReader(new InputStreamReader(process.inputStream)).lines().count() < 4) {
|
||||||
|
throw new GradleException("Used template is not in your user.home directory of the given host $host")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void uploadDependencies() {
|
||||||
|
def base = plugins == null ? "$template/plugins" : plugins
|
||||||
|
println("Uploading to ~/$base")
|
||||||
|
this.dependsOn.forEach {
|
||||||
|
Project resolved
|
||||||
|
AbstractArchiveTask archiveTask
|
||||||
|
if (it instanceof String) {
|
||||||
|
resolved = project.findProject(it.substring(0, it.lastIndexOf(':')))
|
||||||
|
archiveTask = (AbstractArchiveTask) resolved.tasks.findByName(it.substring(it.lastIndexOf(':') + 1))
|
||||||
|
} else {
|
||||||
|
throw new GradleException("Illegal argument for uploading dependencies")
|
||||||
|
}
|
||||||
|
|
||||||
|
def archive = archiveTask.archiveFile.get().asFile
|
||||||
|
println("Uploading $archive")
|
||||||
|
new ProcessBuilder("ssh", host, "-T", "rm $base/${archive.name.replace("-all", "")}").start().waitFor()
|
||||||
|
new ProcessBuilder("scp", archive.absolutePath, "$host:~/$base/${archive.name.replace("-all", "")}").start().waitFor()
|
||||||
|
println("Uploaded $archive")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void startDevServer() {
|
||||||
|
def devPy = new StringBuilder().append("dev.py")
|
||||||
|
if (port != null) devPy.append(" --port $port")
|
||||||
|
if (worldName != null) devPy.append(" -w $template/$worldName")
|
||||||
|
if (plugins != null) devPy.append(" -p $plugins")
|
||||||
|
if (jar != null) devPy.append(" --jar $jar")
|
||||||
|
for (Map.Entry<String, String> dParam : dParams.entrySet()) {
|
||||||
|
devPy.append(" -D${dParam.key}=${dParam.value}")
|
||||||
|
}
|
||||||
|
devPy.append(" $template")
|
||||||
|
println("Starting $template with command ${devPy.toString()}")
|
||||||
|
|
||||||
|
def process = new ProcessBuilder("ssh", host, "-T", devPy.toString()).start()
|
||||||
|
def processOutput = new BufferedReader(new InputStreamReader(process.inputStream))
|
||||||
|
new Thread({
|
||||||
|
while (running) {
|
||||||
|
if (processOutput.ready()) {
|
||||||
|
println(processOutput.readLine())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).start()
|
||||||
|
|
||||||
|
processInput = new BufferedWriter(new OutputStreamWriter(process.outputStream))
|
||||||
|
def input = new BufferedReader(new InputStreamReader(System.in))
|
||||||
|
new Thread({
|
||||||
|
while (running) {
|
||||||
|
def text = input.readLine()
|
||||||
|
if (text == null) break
|
||||||
|
processInput.write(text)
|
||||||
|
processInput.newLine()
|
||||||
|
processInput.flush()
|
||||||
|
}
|
||||||
|
}).start()
|
||||||
|
|
||||||
|
process.waitFor()
|
||||||
|
processInput = null
|
||||||
|
running = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FightServer extends DevServer {
|
||||||
|
|
||||||
|
@Input
|
||||||
|
@Optional
|
||||||
|
Integer checkSchemID = 0
|
||||||
|
|
||||||
|
@Input
|
||||||
|
@Optional
|
||||||
|
Integer prepareSchemID = 0
|
||||||
|
|
||||||
|
@Input
|
||||||
|
@Optional
|
||||||
|
Integer replay = 0
|
||||||
|
|
||||||
|
@Input
|
||||||
|
@Optional
|
||||||
|
String config = null
|
||||||
|
|
||||||
|
@Input
|
||||||
|
@Optional
|
||||||
|
// Property: fightID
|
||||||
|
Integer eventKampfID = 0
|
||||||
|
|
||||||
|
@Input
|
||||||
|
@Optional
|
||||||
|
UUID blueLeader = null
|
||||||
|
|
||||||
|
@Input
|
||||||
|
@Optional
|
||||||
|
UUID redLeader = null
|
||||||
|
|
||||||
|
FightServer() {
|
||||||
|
super()
|
||||||
|
doFirst {
|
||||||
|
if (checkSchemID != 0) dParams.put("checkSchemID", "$checkSchemID")
|
||||||
|
if (prepareSchemID != 0) dParams.put("prepareSchemID", "$prepareSchemID")
|
||||||
|
if (replay != 0) dParams.put("replay", "$replay")
|
||||||
|
if (eventKampfID != 0) dParams.put("fightID", "$eventKampfID")
|
||||||
|
if (blueLeader != null) dParams.put("blueLeader", blueLeader.toString())
|
||||||
|
if (redLeader != null) dParams.put("redLeader", redLeader.toString())
|
||||||
|
if (config != null) dParams.put("config", config)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user