Compare commits
116 Commits
1.21.1/rpl
...
BauSystem/
| Author | SHA1 | Date | |
|---|---|---|---|
| 254bcba0af | |||
| 5bdbf5dff4 | |||
| 1ae445319a | |||
| a426a563db | |||
|
1098c5617f
|
|||
|
c2bca83735
|
|||
| cfa1b5d0cd | |||
|
500f8978e5
|
|||
| 395e4a2167 | |||
| 1d65f2349e | |||
| c0a4413b7a | |||
| 6b71ac28fe | |||
| 880c6f5066 | |||
| e284f8f08c | |||
| 8a5c5794c0 | |||
| a9e278ccd9 | |||
| c9bfcc5c0c | |||
|
e343d044ff
|
|||
|
f923a007a7
|
|||
|
78352a3e67
|
|||
|
8d705e7a84
|
|||
|
8b4f864f99
|
|||
| f9cb712b07 | |||
|
b3b13d2950
|
|||
|
08ad5edf76
|
|||
|
afcf3a1906
|
|||
| 33efd26d48 | |||
| 2a96b3c26a | |||
| 3de4b3871d | |||
| 67223be80e | |||
|
81715736ae
|
|||
|
36691c6fea
|
|||
| 58618a3991 | |||
|
e6848b27a0
|
|||
|
93d0011b46
|
|||
| f56fedefe4 | |||
| 167bb4e266 | |||
| f6a9ce184b | |||
|
d5708c110c
|
|||
|
f23c1215b7
|
|||
| cfcaf1569c | |||
|
dc56b67ff6
|
|||
|
13c4a3ff8b
|
|||
|
7e5a13989b
|
|||
|
990a03ca6c
|
|||
| 4a608fe5b5 | |||
|
5ca15aa117
|
|||
|
9b459bd12c
|
|||
|
b20d37e252
|
|||
| a8c98594a9 | |||
|
1c076b5bbf
|
|||
|
133ddb39cc
|
|||
| ebb375d8d6 | |||
| 8ada9a6335 | |||
|
0760a5a08a
|
|||
|
852ff95757
|
|||
|
5c7d388876
|
|||
|
4f92f8132d
|
|||
|
56fb63f781
|
|||
|
273efff87d
|
|||
|
0cac6f36c1
|
|||
|
8680b9e6cf
|
|||
| 6c94efaf90 | |||
| f6261ad989 | |||
|
614e989892
|
|||
| 84e1f605bd | |||
| 0ea5a62dbe | |||
|
0eb6047139
|
|||
|
fcebecf745
|
|||
| dd14e9f518 | |||
|
6c5239c8fc
|
|||
|
fc71f47add
|
|||
|
5d36393643
|
|||
|
ebc6f50261
|
|||
|
c9d74fb656
|
|||
|
e50e52950b
|
|||
| aaccd4b095 | |||
| 14045a3366 | |||
|
e5a61226ca
|
|||
| cc3b93a8f6 | |||
|
0c35ace5e2
|
|||
|
23bcf14ca5
|
|||
| 58460416c3 | |||
| 40ac7b2139 | |||
|
63a5fcff97
|
|||
| b69adcd362 | |||
| ceb8d2c6d4 | |||
|
39b3cdb897
|
|||
| 26b4d8578a | |||
| 51411ceabe | |||
| 1ccc2c4b55 | |||
| 941a1916b7 | |||
| 6b8f791497 | |||
|
6ac0143459
|
|||
|
56bc75763b
|
|||
|
8272c73b48
|
|||
|
9acfb32ae0
|
|||
|
b2a4b05545
|
|||
| acf9325179 | |||
|
89e2df0eb2
|
|||
| ca3a7a82be | |||
| 0e5a03e139 | |||
|
73da9179bf
|
|||
|
0fbbcdacea
|
|||
|
4e6933f2fd
|
|||
|
eea1073892
|
|||
|
702aa1cfa6
|
|||
|
6ea73f4890
|
|||
|
14e82f36a5
|
|||
|
a8eaf3daa7
|
|||
|
b51ea484e4
|
|||
|
8bef19ed8b
|
|||
| 1aff7b30a6 | |||
| c8ac984ad3 | |||
| a462231bab | |||
| e6bbb76a0b |
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.bausystem.utils;
|
||||
|
||||
import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class PlayerMovementWrapper21 implements PlayerMovementWrapper {
|
||||
|
||||
@Override
|
||||
public void setPosition(Player player, Object object) {
|
||||
ServerboundMovePlayerPacket packetPlayInFlying = ((ServerboundMovePlayerPacket) object);
|
||||
ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
|
||||
if (packetPlayInFlying.hasPos) {
|
||||
serverPlayer.setPosRaw(packetPlayInFlying.x, packetPlayInFlying.y, packetPlayInFlying.z);
|
||||
}
|
||||
if (packetPlayInFlying.hasRot) {
|
||||
serverPlayer.setXRot(packetPlayInFlying.xRot);
|
||||
serverPlayer.setYRot(packetPlayInFlying.yRot);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convertToOut(Player player, Object object) {
|
||||
return object;
|
||||
}
|
||||
}
|
||||
@@ -1030,6 +1030,7 @@ SCHEMATIC_GUI_ITEM=§eSchematics
|
||||
# TNTListener
|
||||
TLS_MESSAGE_79=§7TLS§8> §7Tick §e{0} §8- §7TNT §e{1}
|
||||
TLS_MESSAGE_80=§7TLS§8> §7Tick §e{0} §8- §7TNT §e{1} §8(§e{2} §7with Fuse 80§8)
|
||||
TLS_START_HELP=§8/§etls start §8: §7Start the TNT Listener
|
||||
TLS_STOP_HELP=§8/§etls stop §8: §7Stop the TNT Listener
|
||||
TLS_SCOREBOARD_ELEMENT=§eTLS§8: §aon
|
||||
TLS_START_HELP=§8/§etls start §8- §7Start the TNT Listener
|
||||
TLS_STOP_HELP=§8/§etls stop §8- §7Stop the TNT Listener
|
||||
TLS_SCOREBOARD_ELEMENT=§eTLS§8: §aon
|
||||
TLS_TOGGLE_HELP=§8/§etls§8: §7Toggle the TNT Listener
|
||||
@@ -961,6 +961,7 @@ TYPEREPLACE_HELP=§8//§etyreplace §8[§7type§8] §8[§7type§8] §8- §7Erset
|
||||
# Schematics
|
||||
SCHEMATIC_GUI_ITEM=§eSchematics
|
||||
TLS_MESSAGE_80=§7TLS§8> §7Tick §e{0} §8- §7TNT §e{1} §8(§e{2} §7mit Fuse 80§8)
|
||||
TLS_START_HELP=§8/§etls start §8: §7Starte den TNT Listener
|
||||
TLS_STOP_HELP=§8/§etls stop §8: §7Stope den TNT Listener
|
||||
TLS_SCOREBOARD_ELEMENT=§eTLS§8: §aan
|
||||
TLS_START_HELP=§8/§etls start §8- §7Starte den TNT Listener
|
||||
TLS_STOP_HELP=§8/§etls stop §8- §7Stope den TNT Listener
|
||||
TLS_SCOREBOARD_ELEMENT=§eTLS§8: §aan
|
||||
TLS_TOGGLE_HELP=§8/§etls §8: §7Toggle den TNT Listener
|
||||
@@ -110,9 +110,6 @@ public class BauSystem extends JavaPlugin implements Listener {
|
||||
if (any instanceof ConfigConverter) {
|
||||
Config.addConfigConverter((ConfigConverter) any);
|
||||
}
|
||||
if (any instanceof BoundingBoxLoader) {
|
||||
((BoundingBoxLoader) any).load();
|
||||
}
|
||||
}
|
||||
};
|
||||
try {
|
||||
|
||||
@@ -27,8 +27,6 @@ import de.steamwar.sql.SteamwarUser;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@AllArgsConstructor
|
||||
@@ -39,13 +37,12 @@ public enum Permission {
|
||||
return bauweltMember.isSupervisor();
|
||||
}),
|
||||
BUILD(bauweltMember -> {
|
||||
if (isTempOnlySpectator(bauweltMember)) return false;
|
||||
return bauweltMember.isBuild() || SUPERVISOR.permissionPredicate.test(bauweltMember);
|
||||
}),
|
||||
/**
|
||||
* Only used for {@link BauMemberUpdate}
|
||||
*/
|
||||
REAL_SPECTATOR(bauweltMember -> {
|
||||
SPECTATOR(bauweltMember -> {
|
||||
return !bauweltMember.isBuild() && !bauweltMember.isSupervisor();
|
||||
}),
|
||||
/**
|
||||
@@ -55,28 +52,6 @@ public enum Permission {
|
||||
return true;
|
||||
});
|
||||
|
||||
private static final Set<Integer> TEMP_ONLY_SPECTATOR = new HashSet<>();
|
||||
|
||||
private static boolean isTempOnlySpectator(BauweltMember bauweltMember) {
|
||||
return TEMP_ONLY_SPECTATOR.contains(bauweltMember.getMemberID());
|
||||
}
|
||||
|
||||
public static boolean isTempOnlySpectator(Player player) {
|
||||
return TEMP_ONLY_SPECTATOR.contains(SteamwarUser.get(player.getUniqueId()).getId());
|
||||
}
|
||||
|
||||
public static void forceOnlySpectator(Player player) {
|
||||
TEMP_ONLY_SPECTATOR.add(SteamwarUser.get(player.getUniqueId()).getId());
|
||||
BauMemberUpdate.baumemberUpdate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Only used by {@link BauMemberUpdate}
|
||||
*/
|
||||
public static void removeForceOnlySpectator(Player player) {
|
||||
TEMP_ONLY_SPECTATOR.remove(SteamwarUser.get(player.getUniqueId()).getId());
|
||||
}
|
||||
|
||||
private final Predicate<BauweltMember> permissionPredicate;
|
||||
|
||||
public boolean hasPermission(BauweltMember bauweltMember) {
|
||||
@@ -86,10 +61,10 @@ public enum Permission {
|
||||
|
||||
public boolean hasPermission(Player member) {
|
||||
if (SteamwarUser.get(member.getUniqueId()).getId() == BauServer.getInstance().getOwnerID()) {
|
||||
return this != REAL_SPECTATOR;
|
||||
return this != SPECTATOR;
|
||||
}
|
||||
BauweltMember bauweltMember = BauweltMember.getBauMember(BauServer.getInstance().getOwner(), member.getUniqueId());
|
||||
if (bauweltMember == null) return this == REAL_SPECTATOR;
|
||||
if (bauweltMember == null) return this == SPECTATOR;
|
||||
return permissionPredicate.test(bauweltMember);
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,7 @@ public class BauServer {
|
||||
private Integer owner;
|
||||
|
||||
public UUID getOwner() {
|
||||
return SteamwarUser.get(getOwnerID()).getUUID();
|
||||
return SteamwarUser.byId(getOwnerID()).getUUID();
|
||||
}
|
||||
|
||||
public int getOwnerID() {
|
||||
|
||||
@@ -1,71 +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.bausystem.features.bau;
|
||||
|
||||
import de.steamwar.bausystem.Permission;
|
||||
import de.steamwar.command.PreviousArguments;
|
||||
import de.steamwar.command.SWCommand;
|
||||
import de.steamwar.command.TypeMapper;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Linked
|
||||
public class ForceSpectatorCommand extends SWCommand {
|
||||
|
||||
public ForceSpectatorCommand() {
|
||||
super("forcespectator");
|
||||
}
|
||||
|
||||
@Register
|
||||
public void forceSpectator(@Validator("supervisor") Player player, @Mapper("builder") Player other) {
|
||||
Permission.forceOnlySpectator(other);
|
||||
}
|
||||
|
||||
@Mapper("builder")
|
||||
public TypeMapper<Player> spectatorMapper() {
|
||||
return new TypeMapper<>() {
|
||||
@Override
|
||||
public Player map(CommandSender commandSender, String[] previousArguments, String s) {
|
||||
Player player = Bukkit.getPlayer(s);
|
||||
if (player == null) {
|
||||
return null;
|
||||
}
|
||||
if (Permission.BUILD.hasPermission(player) && !Permission.SUPERVISOR.hasPermission(player)) {
|
||||
return player;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> tabCompletes(CommandSender sender, PreviousArguments previousArguments, String s) {
|
||||
return Bukkit.getOnlinePlayers().stream()
|
||||
.filter(Permission.BUILD::hasPermission)
|
||||
.filter(player -> !Permission.SUPERVISOR.hasPermission(player))
|
||||
.map(Player::getName)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -47,7 +47,7 @@ public class InfoCommand extends SWCommand {
|
||||
|
||||
@Register(description = "BAU_INFO_COMMAND_HELP")
|
||||
public void genericCommand(Player p) {
|
||||
BauSystem.MESSAGE.send("BAU_INFO_COMMAND_OWNER", p, SteamwarUser.get(bauServer.getOwnerID()).getUserName());
|
||||
BauSystem.MESSAGE.send("BAU_INFO_COMMAND_OWNER", p, SteamwarUser.byId(bauServer.getOwnerID()).getUserName());
|
||||
Region region = Region.getRegion(p.getLocation());
|
||||
for (Flag flag : Flag.getFlags()) {
|
||||
if (!region.getFlags().has(flag).isApplicable()) continue;
|
||||
@@ -97,7 +97,7 @@ public class InfoCommand extends SWCommand {
|
||||
st.append("§8, ");
|
||||
}
|
||||
st.append("§7");
|
||||
st.append(SteamwarUser.get(bauweltMembers.get(i).getMemberID()).getUserName());
|
||||
st.append(SteamwarUser.byId(bauweltMembers.get(i).getMemberID()).getUserName());
|
||||
}
|
||||
return st.toString();
|
||||
}
|
||||
|
||||
@@ -21,9 +21,10 @@ package de.steamwar.bausystem.features.countingwand;
|
||||
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.bausystem.region.Point;
|
||||
import de.steamwar.bausystem.shared.Pair;
|
||||
import de.steamwar.bausystem.utils.ItemUtils;
|
||||
import de.steamwar.core.SWPlayer;
|
||||
import de.steamwar.inventory.SWItem;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -31,13 +32,32 @@ import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@UtilityClass
|
||||
public class Countingwand {
|
||||
|
||||
@Data
|
||||
public class CountingWandComponent implements SWPlayer.Component {
|
||||
private Point pos1;
|
||||
private Point pos2;
|
||||
|
||||
public boolean setPosition(boolean pos1, Point point) {
|
||||
if (this.pos1 == null || this.pos2 == null) {
|
||||
this.pos1 = point;
|
||||
this.pos2 = point;
|
||||
return true;
|
||||
}
|
||||
Point current = pos1 ? this.pos1 : this.pos2;
|
||||
if (current.equals(point)) return false;
|
||||
if (pos1) {
|
||||
this.pos1 = point;
|
||||
} else {
|
||||
this.pos2 = point;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static ItemStack getWandItem(Player player) {
|
||||
ItemStack itemStack = new SWItem(Material.STICK, BauSystem.MESSAGE.parse("COUNTINGWAND_ITEM_NAME", player), Arrays.asList(BauSystem.MESSAGE.parse("COUNTINGWAND_ITEM_LORE1", player), BauSystem.MESSAGE.parse("COUNTINGWAND_ITEM_LORE2", player)), false, null).getItemStack();
|
||||
ItemUtils.setItem(itemStack, "countingwand");
|
||||
@@ -47,61 +67,20 @@ public class Countingwand {
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
private final Map<String, Pair<Point, Point>> selections = new HashMap<>();
|
||||
public boolean isCountingwand(ItemStack itemStack) {
|
||||
return ItemUtils.isItem(itemStack, "countingwand");
|
||||
}
|
||||
|
||||
public boolean isCountingwand(ItemStack itemStack) {
|
||||
return ItemUtils.isItem(itemStack, "countingwand");
|
||||
}
|
||||
|
||||
public void checkSelection(final Point point, final boolean pos1, final Player p) {
|
||||
Pair<Point, Point> selection = selections.get(p.getUniqueId().toString());
|
||||
final boolean newPos;
|
||||
if (selection != null) {
|
||||
if (pos1) {
|
||||
newPos = !point.equals(selection.setKey(point));
|
||||
} else {
|
||||
newPos = !point.equals(selection.setValue(point));
|
||||
}
|
||||
} else {
|
||||
if (pos1) {
|
||||
selection = new Pair<>(point, null);
|
||||
} else {
|
||||
selection = new Pair<>(null, point);
|
||||
}
|
||||
selections.put(p.getUniqueId().toString(), selection);
|
||||
newPos = true;
|
||||
}
|
||||
|
||||
if (newPos) {
|
||||
String dimension = getDimensions(p, selection.getKey(), selection.getValue());
|
||||
String volume = getVolume(p, selection.getKey(), selection.getValue());
|
||||
if (pos1) {
|
||||
BauSystem.MESSAGE.send("COUNTINGWAND_MESSAGE_RCLICK", p, point.getX(), point.getY(), point.getZ(), dimension, volume);
|
||||
} else {
|
||||
BauSystem.MESSAGE.send("COUNTINGWAND_MESSAGE_LCLICK", p, point.getX(), point.getY(), point.getZ(), dimension, volume);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void removePlayer(Player p) {
|
||||
selections.remove(p.getUniqueId().toString());
|
||||
}
|
||||
|
||||
public String getVolume(Player player, final Point point1, final Point point2) {
|
||||
if (point1 == null || point2 == null) {
|
||||
return BauSystem.MESSAGE.parse("COUNTINGWAND_MESSAGE_VOLUME", player, 0);
|
||||
}
|
||||
return BauSystem.MESSAGE.parse("COUNTINGWAND_MESSAGE_VOLUME", player, getAmount(point1, point2));
|
||||
}
|
||||
|
||||
public String getDimensions(Player player, final Point point1, final Point point2) {
|
||||
if (point1 == null || point2 == null) {
|
||||
return BauSystem.MESSAGE.parse("COUNTINGWAND_MESSAGE_DIMENSION", player, 0, 0, 0);
|
||||
}
|
||||
return BauSystem.MESSAGE.parse("COUNTINGWAND_MESSAGE_DIMENSION", player, Math.abs(point1.getX() - point2.getX()) + 1, Math.abs(point1.getY() - point2.getY()) + 1, Math.abs(point1.getZ() - point2.getZ()) + 1);
|
||||
}
|
||||
|
||||
public int getAmount(final Point point1, final Point point2) {
|
||||
return (Math.abs(point1.getX() - point2.getX()) + 1) * (Math.abs(point1.getY() - point2.getY()) + 1) * (Math.abs(point1.getZ() - point2.getZ()) + 1);
|
||||
}
|
||||
public void checkSelection(final Point point, final boolean pos1, final Player p) {
|
||||
SWPlayer player = SWPlayer.of(p);
|
||||
CountingWandComponent countingWandComponent = player.getComponentOrDefault(CountingWandComponent.class, CountingWandComponent::new);
|
||||
if (countingWandComponent.setPosition(pos1, point)) {
|
||||
Point point1 = countingWandComponent.pos1;
|
||||
Point point2 = countingWandComponent.pos2;
|
||||
int amount = (Math.abs(point1.getX() - point2.getX()) + 1) * (Math.abs(point1.getY() - point2.getY()) + 1) * (Math.abs(point1.getZ() - point2.getZ()) + 1);
|
||||
String dimension = player.using(BauSystem.MESSAGE).parse("COUNTINGWAND_MESSAGE_VOLUME", amount);
|
||||
String volume = player.parse("COUNTINGWAND_MESSAGE_DIMENSION", Math.abs(point1.getX() - point2.getX()) + 1, Math.abs(point1.getY() - point2.getY()) + 1, Math.abs(point1.getZ() - point2.getZ()) + 1);
|
||||
player.sendMessage(pos1 ? "COUNTINGWAND_MESSAGE_RCLICK" : "COUNTINGWAND_MESSAGE_LCLICK", point.getX(), point.getY(), point.getZ(), dimension, volume);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,6 @@ import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.util.RayTraceResult;
|
||||
|
||||
import java.util.Objects;
|
||||
@@ -67,9 +66,4 @@ public class CountingwandListener implements Listener {
|
||||
event.setCancelled(true);
|
||||
Countingwand.checkSelection(Point.fromLocation(Objects.requireNonNull(event.getClickedBlock()).getLocation()), false, event.getPlayer());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onLeave(PlayerQuitEvent event) {
|
||||
Countingwand.removePlayer(event.getPlayer());
|
||||
}
|
||||
}
|
||||
@@ -25,8 +25,11 @@ import de.steamwar.bausystem.configplayer.Config;
|
||||
import de.steamwar.bausystem.features.autostart.AutostartListener;
|
||||
import de.steamwar.bausystem.features.detonator.storage.DetonatorStorage;
|
||||
import de.steamwar.bausystem.features.detonator.storage.ItemStorage;
|
||||
import de.steamwar.core.SWPlayer;
|
||||
import de.steamwar.entity.REntityServer;
|
||||
import de.steamwar.entity.RFallingBlockEntity;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
@@ -45,7 +48,28 @@ import java.util.*;
|
||||
@UtilityClass
|
||||
public class Detonator {
|
||||
|
||||
private static final Map<Player, REntityServer> ENTITIES_MAP = new HashMap<>();
|
||||
public class DetonatorComponent implements SWPlayer.Component {
|
||||
private final REntityServer entities = new REntityServer();
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private boolean hasUpdated = false;
|
||||
|
||||
@Override
|
||||
public void onMount(SWPlayer player) {
|
||||
entities.addPlayer(player.getPlayer());
|
||||
entities.setCallback((player1, entity, action) -> {
|
||||
Vector vector = new Vector(entity.getX(), entity.getY(), entity.getZ());
|
||||
DetonatorListener.addLocationToDetonator(vector.toLocation(player.getWorld()).getBlock().getLocation(), player1);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUnmount(SWPlayer player) {
|
||||
entities.close();
|
||||
}
|
||||
}
|
||||
|
||||
private static final Vector HALF = new Vector(0.5, 0, 0.5);
|
||||
|
||||
public static boolean isDetonator(ItemStack itemStack) {
|
||||
@@ -53,28 +77,19 @@ public class Detonator {
|
||||
}
|
||||
|
||||
public static void showDetonator(Player p, List<Location> locs) {
|
||||
if (ENTITIES_MAP.containsKey(p)) return;
|
||||
REntityServer entities = new REntityServer();
|
||||
entities.setCallback((player, rEntity, entityAction) -> {
|
||||
Vector vector = new Vector(rEntity.getX(), rEntity.getY(), rEntity.getZ());
|
||||
DetonatorListener.addLocationToDetonator(vector.toLocation(player.getWorld()).getBlock().getLocation(), player);
|
||||
DetonatorListener.HAS_UPDATED.add(player);
|
||||
});
|
||||
entities.addPlayer(p);
|
||||
ENTITIES_MAP.put(p, entities);
|
||||
|
||||
DetonatorComponent detonatorComponent = SWPlayer.of(p).getComponentOrDefault(DetonatorComponent.class, DetonatorComponent::new);
|
||||
locs.forEach(location -> {
|
||||
RFallingBlockEntity entity = new RFallingBlockEntity(entities, location.clone().add(HALF), Material.RED_STAINED_GLASS);
|
||||
RFallingBlockEntity entity = new RFallingBlockEntity(detonatorComponent.entities, location.clone().add(HALF), Material.RED_STAINED_GLASS);
|
||||
entity.setNoGravity(true);
|
||||
});
|
||||
}
|
||||
|
||||
public static void hideDetonator(Player p) {
|
||||
ENTITIES_MAP.remove(p).close();
|
||||
SWPlayer.of(p).removeComponent(DetonatorComponent.class);
|
||||
}
|
||||
|
||||
public static boolean hasActiveDetonatorShow(Player p) {
|
||||
return ENTITIES_MAP.containsKey(p);
|
||||
return SWPlayer.of(p).hasComponent(DetonatorComponent.class);
|
||||
}
|
||||
|
||||
public static void activateDetonator(DetonatorStorage detonator) {
|
||||
|
||||
@@ -24,6 +24,7 @@ import de.steamwar.bausystem.Permission;
|
||||
import de.steamwar.bausystem.SWUtils;
|
||||
import de.steamwar.bausystem.features.detonator.storage.DetonatorStorage;
|
||||
import de.steamwar.bausystem.features.detonator.storage.ItemStorage;
|
||||
import de.steamwar.core.SWPlayer;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -36,15 +37,11 @@ import org.bukkit.event.player.PlayerItemHeldEvent;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.event.player.PlayerSwapHandItemsEvent;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@Linked
|
||||
public class DetonatorListener implements Listener {
|
||||
|
||||
static final Set<Player> HAS_UPDATED = new HashSet<>();
|
||||
|
||||
static void addLocationToDetonator(Location location, Player p) {
|
||||
SWPlayer.of(p).getComponent(Detonator.DetonatorComponent.class).ifPresent(detonatorComponent -> detonatorComponent.setHasUpdated(true));
|
||||
Detoblock detoblock = Detonator.getBlock(location.getBlock());
|
||||
if (detoblock == Detoblock.INVALID) {
|
||||
SWUtils.sendToActionbar(p, BauSystem.MESSAGE.parse("DETONATOR_INVALID_BLOCK", p));
|
||||
@@ -66,64 +63,59 @@ public class DetonatorListener implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void onBlockBreak(BlockBreakEvent event) {
|
||||
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||
Player p = event.getPlayer();
|
||||
if (Detonator.isDetonator(p.getInventory().getItemInMainHand())) {
|
||||
event.setCancelled(true);
|
||||
addLocationToDetonator(event.getBlock().getLocation(), p);
|
||||
HAS_UPDATED.add(event.getPlayer());
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerInteract(PlayerInteractEvent event) {
|
||||
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||
if (!Detonator.isDetonator(event.getItem())) {
|
||||
return;
|
||||
}
|
||||
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||
if (!Detonator.isDetonator(event.getItem())) return;
|
||||
|
||||
if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) {
|
||||
event.setCancelled(true);
|
||||
DetonatorStorage detonator = new ItemStorage(event.getPlayer());
|
||||
Detonator.activateDetonator(detonator);
|
||||
HAS_UPDATED.add(event.getPlayer());
|
||||
SWPlayer.of(event.getPlayer()).getComponent(Detonator.DetonatorComponent.class).ifPresent(detonatorComponent -> detonatorComponent.setHasUpdated(true));
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onPlayerMove(PlayerMoveEvent event) {
|
||||
if (!Permission.BUILD.hasPermission(event.getPlayer()) ||!Detonator.isDetonator(event.getPlayer().getInventory().getItemInMainHand())) {
|
||||
if (!Permission.BUILD.hasPermission(event.getPlayer()) || !Detonator.isDetonator(event.getPlayer().getInventory().getItemInMainHand())) {
|
||||
if (Detonator.hasActiveDetonatorShow(event.getPlayer())) {
|
||||
Detonator.hideDetonator(event.getPlayer());
|
||||
}
|
||||
} else {
|
||||
if (!Detonator.hasActiveDetonatorShow(event.getPlayer())) {
|
||||
Detonator.showDetonator(event.getPlayer(), new ItemStorage(event.getPlayer()).getLocations());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (HAS_UPDATED.contains(event.getPlayer())) {
|
||||
HAS_UPDATED.remove(event.getPlayer());
|
||||
if (Detonator.hasActiveDetonatorShow(event.getPlayer())) {
|
||||
Detonator.hideDetonator(event.getPlayer());
|
||||
Detonator.showDetonator(event.getPlayer(), new ItemStorage(event.getPlayer()).getLocations());
|
||||
}
|
||||
if (!Detonator.hasActiveDetonatorShow(event.getPlayer())) {
|
||||
Detonator.showDetonator(event.getPlayer(), new ItemStorage(event.getPlayer()).getLocations());
|
||||
return;
|
||||
}
|
||||
Detonator.DetonatorComponent component = SWPlayer.of(event.getPlayer())
|
||||
.getComponentAndFilter(Detonator.DetonatorComponent.class, Detonator.DetonatorComponent::isHasUpdated)
|
||||
.orElse(null);
|
||||
if (component == null) return;
|
||||
component.setHasUpdated(false);
|
||||
Detonator.hideDetonator(event.getPlayer());
|
||||
Detonator.showDetonator(event.getPlayer(), new ItemStorage(event.getPlayer()).getLocations());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerItemHeld(PlayerItemHeldEvent event) {
|
||||
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||
if (Detonator.isDetonator(event.getPlayer().getInventory().getItemInMainHand())) {
|
||||
HAS_UPDATED.add(event.getPlayer());
|
||||
}
|
||||
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||
if (!Detonator.isDetonator(event.getPlayer().getInventory().getItemInMainHand())) return;
|
||||
SWPlayer.of(event.getPlayer()).getComponent(Detonator.DetonatorComponent.class).ifPresent(detonatorComponent -> detonatorComponent.setHasUpdated(true));
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerSwapHandItems(PlayerSwapHandItemsEvent event) {
|
||||
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||
if (Detonator.isDetonator(event.getMainHandItem()) || Detonator.isDetonator(event.getOffHandItem())) {
|
||||
HAS_UPDATED.add(event.getPlayer());
|
||||
}
|
||||
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||
if (!(Detonator.isDetonator(event.getMainHandItem()) || Detonator.isDetonator(event.getOffHandItem()))) return;
|
||||
SWPlayer.of(event.getPlayer()).getComponent(Detonator.DetonatorComponent.class).ifPresent(detonatorComponent -> detonatorComponent.setHasUpdated(true));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import de.steamwar.bausystem.features.loader.elements.LoaderInteractionElement;
|
||||
import de.steamwar.bausystem.features.loader.elements.impl.LoaderTNT;
|
||||
import de.steamwar.bausystem.features.loader.elements.impl.LoaderWait;
|
||||
import de.steamwar.bausystem.shared.EnumDisplay;
|
||||
import de.steamwar.core.SWPlayer;
|
||||
import de.steamwar.inventory.SWAnvilInv;
|
||||
import de.steamwar.inventory.SWItem;
|
||||
import de.steamwar.inventory.SWListInv;
|
||||
@@ -40,21 +41,17 @@ import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class Loader implements Listener {
|
||||
|
||||
private static final Map<Player, Loader> LOADER_MAP = new HashMap<>();
|
||||
public class Loader implements Listener, SWPlayer.Component {
|
||||
|
||||
public static Loader getLoader(Player player) {
|
||||
return LOADER_MAP.get(player);
|
||||
return SWPlayer.of(player).getComponent(Loader.class).orElse(null);
|
||||
}
|
||||
|
||||
public static void newLoader(Player player) {
|
||||
LOADER_MAP.put(player, new Loader(player));
|
||||
SWPlayer.of(player).setComponent(new Loader(player));
|
||||
}
|
||||
|
||||
private final Player p;
|
||||
@@ -145,7 +142,7 @@ public class Loader implements Listener {
|
||||
recorder = null;
|
||||
}
|
||||
elements.clear();
|
||||
LOADER_MAP.remove(p);
|
||||
SWPlayer.of(p).removeComponent(Loader.class);
|
||||
}
|
||||
|
||||
public boolean setTicksBetweenShots(int delay) {
|
||||
|
||||
@@ -21,6 +21,7 @@ package de.steamwar.bausystem.features.observer;
|
||||
|
||||
import de.steamwar.Reflection;
|
||||
import de.steamwar.bausystem.region.Point;
|
||||
import de.steamwar.core.SWPlayer;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Particle;
|
||||
@@ -34,7 +35,7 @@ import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class ObserverTracer {
|
||||
public class ObserverTracer implements SWPlayer.Component {
|
||||
|
||||
private static final Set<BlockFace> ALLOWED = EnumSet.of(BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST, BlockFace.UP, BlockFace.DOWN);
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ package de.steamwar.bausystem.features.observer;
|
||||
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.command.SWCommand;
|
||||
import de.steamwar.core.SWPlayer;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@@ -41,23 +42,23 @@ public class ObserverTracerCommand extends SWCommand {
|
||||
@Register(value = "disable", description = "OBSERVER_HELP_DISABLE")
|
||||
public void disable(Player p) {
|
||||
ObserverTracerListener.enabled.remove(p);
|
||||
ObserverTracerListener.observerTracerMap.remove(p);
|
||||
SWPlayer.of(p).removeComponent(ObserverTracer.class);
|
||||
BauSystem.MESSAGE.send("OBSERVER_DISABLE", p);
|
||||
}
|
||||
|
||||
@Register(value = "delete", description = "OBSERVER_HELP_DELETE")
|
||||
public void delete(@Validator Player p) {
|
||||
ObserverTracerListener.observerTracerMap.remove(p);
|
||||
SWPlayer.of(p).removeComponent(ObserverTracer.class);
|
||||
BauSystem.MESSAGE.send("OBSERVER_DELETE", p);
|
||||
}
|
||||
|
||||
@Register(value = "retrace", description = "OBSERVER_HELP_RETRACE")
|
||||
public void retrace(@Validator Player p) {
|
||||
if (ObserverTracerListener.observerTracerMap.containsKey(p)) {
|
||||
if (SWPlayer.of(p).hasComponent(ObserverTracer.class)) {
|
||||
BauSystem.MESSAGE.send("OBSERVER_RETRACE_NO_TRACE", p);
|
||||
return;
|
||||
}
|
||||
ObserverTracerListener.observerTracerMap.get(p).trace();
|
||||
SWPlayer.of(p).getComponent(ObserverTracer.class).ifPresent(ObserverTracer::trace);
|
||||
BauSystem.MESSAGE.send("OBSERVER_RETRACE_DONE", p);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ package de.steamwar.bausystem.features.observer;
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.bausystem.Permission;
|
||||
import de.steamwar.bausystem.utils.BauMemberUpdateEvent;
|
||||
import de.steamwar.core.SWPlayer;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
@@ -34,23 +35,19 @@ import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@Linked
|
||||
public class ObserverTracerListener implements Listener {
|
||||
|
||||
static Set<Player> enabled = new HashSet<>();
|
||||
static Map<Player, ObserverTracer> observerTracerMap = new HashMap<>();
|
||||
|
||||
public ObserverTracerListener() {
|
||||
Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), () -> {
|
||||
observerTracerMap.forEach((player, observerTracer) -> {
|
||||
if (player.getGameMode() == GameMode.SPECTATOR) {
|
||||
observerTracer.show();
|
||||
}
|
||||
SWPlayer.allWithSingleComponent(ObserverTracer.class).forEach(pair -> {
|
||||
if (pair.getKey().getGameMode() != GameMode.SPECTATOR) return;
|
||||
pair.getValue().show();
|
||||
});
|
||||
}, 15L, 15L);
|
||||
}
|
||||
@@ -58,20 +55,16 @@ public class ObserverTracerListener implements Listener {
|
||||
@EventHandler
|
||||
public void onPlayerInteract(PlayerInteractEvent event) {
|
||||
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||
if (!enabled.contains(event.getPlayer())) {
|
||||
return;
|
||||
}
|
||||
if (event.getClickedBlock() == null) {
|
||||
return;
|
||||
}
|
||||
if (observerTracerMap.containsKey(event.getPlayer())) {
|
||||
ObserverTracer observerTracer = observerTracerMap.get(event.getPlayer());
|
||||
if (!enabled.contains(event.getPlayer())) return;
|
||||
if (event.getClickedBlock() == null) return;
|
||||
ObserverTracer observerTracer = SWPlayer.of(event.getPlayer()).getComponent(ObserverTracer.class).orElse(null);
|
||||
if (observerTracer != null) {
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||
if (!observerTracer.trace()) {
|
||||
createNew(event);
|
||||
}
|
||||
observerTracerMap.forEach((player, o) -> {
|
||||
o.trace();
|
||||
SWPlayer.allWithSingleComponent(ObserverTracer.class).forEach(pair -> {
|
||||
pair.getValue().trace();
|
||||
});
|
||||
}, 1L);
|
||||
} else {
|
||||
@@ -86,13 +79,13 @@ public class ObserverTracerListener implements Listener {
|
||||
if (event.getClickedBlock().getType() == Material.OBSERVER) {
|
||||
ObserverTracer observerTracer = new ObserverTracer(event.getPlayer(), event.getClickedBlock());
|
||||
observerTracer.trace();
|
||||
observerTracerMap.put(event.getPlayer(), observerTracer);
|
||||
SWPlayer.of(event.getPlayer()).setComponent(observerTracer);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onBauMemberUpdate(BauMemberUpdateEvent event) {
|
||||
event.getNewSpectator().forEach(observerTracerMap::remove);
|
||||
event.getNewBuilder().forEach(player -> SWPlayer.of(player).removeComponent(ObserverTracer.class));
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@@ -103,6 +96,5 @@ public class ObserverTracerListener implements Listener {
|
||||
@EventHandler
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
enabled.remove(event.getPlayer());
|
||||
observerTracerMap.remove(event.getPlayer());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@ import de.steamwar.command.SWCommand;
|
||||
import de.steamwar.command.TypeMapper;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import de.steamwar.linkage.LinkedInstance;
|
||||
import de.steamwar.sql.BauweltMember;
|
||||
import de.steamwar.sql.Punishment;
|
||||
import de.steamwar.sql.SchematicNode;
|
||||
import de.steamwar.sql.SteamwarUser;
|
||||
@@ -73,6 +72,14 @@ public class TestblockCommand extends SWCommand {
|
||||
resetRegion(p, node, isExtension ? RegionExtensionType.EXTENSION : RegionExtensionType.NORMAL, isIgnoreAir, isOnlyColor, replaceTNT, replaceWater);
|
||||
}
|
||||
|
||||
@Register(value="default")
|
||||
public void setTestblockDefault(Player p) {
|
||||
Region region = regionCheck(p);
|
||||
if (region == null) return;
|
||||
region.getRegionData().setTestblockSchematic(null);
|
||||
resetRegion(p, null, RegionExtensionType.EXTENSION, false, false, false, false);
|
||||
}
|
||||
|
||||
private void resetRegion(Player p, SchematicNode node, RegionExtensionType regionExtensionType, boolean ignoreAir, boolean onlyColors, boolean removeTNT, boolean removeWater) {
|
||||
Region region = regionCheck(p);
|
||||
if (region == null) return;
|
||||
@@ -93,29 +100,10 @@ public class TestblockCommand extends SWCommand {
|
||||
}
|
||||
}
|
||||
|
||||
// Beta Tester enabled
|
||||
switch (BauServer.getInstance().getOwnerID()) {
|
||||
case 245:
|
||||
case 403:
|
||||
case 1898:
|
||||
case 3320:
|
||||
case 4603:
|
||||
case 5262:
|
||||
case 5399:
|
||||
case 6032:
|
||||
case 7862:
|
||||
case 11077:
|
||||
case 11888:
|
||||
case 12258:
|
||||
case 16009:
|
||||
if (node == null) {
|
||||
node = region.getRegionData().getTestblockSchematic();
|
||||
} else {
|
||||
region.getRegionData().setTestblockSchematic(node);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if (node == null) {
|
||||
node = region.getRegionData().getTestblockSchematic();
|
||||
} else {
|
||||
region.getRegionData().setTestblockSchematic(node);
|
||||
}
|
||||
|
||||
PasteBuilder.ClipboardProvider clipboardProvider;
|
||||
@@ -198,7 +186,7 @@ public class TestblockCommand extends SWCommand {
|
||||
@Override
|
||||
public List<String> tabCompletes(CommandSender commandSender, PreviousArguments previousArguments, String s) {
|
||||
List<String> stringList = new ArrayList<>(SchematicNode.getNodeTabcomplete(SteamwarUser.get(((Player) commandSender).getUniqueId()), s));
|
||||
stringList.addAll(SchematicNode.getNodeTabcomplete(SteamwarUser.get(0), s));
|
||||
stringList.addAll(SchematicNode.getNodeTabcomplete(SteamwarUser.byId(0), s));
|
||||
return stringList;
|
||||
}
|
||||
|
||||
@@ -206,7 +194,7 @@ public class TestblockCommand extends SWCommand {
|
||||
public SchematicNode map(CommandSender commandSender, PreviousArguments previousArguments, String s) {
|
||||
SchematicNode node = SchematicNode.getNodeFromPath(SteamwarUser.get(((Player) commandSender).getUniqueId()), s);
|
||||
if (node == null) {
|
||||
node = SchematicNode.getNodeFromPath(SteamwarUser.get(0), s);
|
||||
node = SchematicNode.getNodeFromPath(SteamwarUser.byId(0), s);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ public class ScriptHelper {
|
||||
BookMeta meta = (BookMeta) itemStack.getItemMeta();
|
||||
if(!writeable) {
|
||||
meta.setTitle(script.getName());
|
||||
meta.setAuthor(SteamwarUser.get(script.getUserId()).getUserName());
|
||||
meta.setAuthor(SteamwarUser.byId(script.getUserId()).getUserName());
|
||||
}
|
||||
meta.setPages(getScriptPages(script));
|
||||
itemStack.setItemMeta(meta);
|
||||
|
||||
@@ -67,7 +67,7 @@ public class ScriptListener implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
ScriptRunner.remove(event.getPlayer());
|
||||
playerSet.remove(event.getPlayer());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
||||
@@ -23,8 +23,11 @@ import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.bausystem.features.script.lua.CommandRegister;
|
||||
import de.steamwar.bausystem.features.script.lua.SteamWarGlobalLuaPlugin;
|
||||
import de.steamwar.bausystem.features.script.lua.SteamWarPlatform;
|
||||
import de.steamwar.core.SWPlayer;
|
||||
import de.steamwar.sql.Script;
|
||||
import de.steamwar.sql.SteamwarUser;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
@@ -44,12 +47,25 @@ public class ScriptRunner {
|
||||
// Key -> bau-script-<BUCH NAME>
|
||||
// Value -> <LUA Script>
|
||||
|
||||
private static final Map<Player, Map<SteamWarGlobalLuaPlugin.EventType, List<LuaFunction>>> EVENT_MAP = new HashMap<>();
|
||||
private static final Map<Player, Map<Hotkey, List<LuaFunction>>> HOTKEY_MAP = new HashMap<>();
|
||||
private static final Map<Player, Map<String, CommandRegister>> COMMAND_MAP = new HashMap<>();
|
||||
public class ScriptData implements SWPlayer.Component {
|
||||
private Map<SteamWarGlobalLuaPlugin.EventType, List<LuaFunction>> events = new EnumMap<>(SteamWarGlobalLuaPlugin.EventType.class);
|
||||
private Map<Hotkey, List<LuaFunction>> hotkeys = new HashMap<>();
|
||||
private Map<String, CommandRegister> commands = new HashMap<>();
|
||||
|
||||
@Getter
|
||||
private Set<String> calledCommands = new HashSet<>();
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private Long lastF = Long.MAX_VALUE;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private boolean ignore;
|
||||
}
|
||||
|
||||
public Set<String> getCommandsOfPlayer(Player player) {
|
||||
return COMMAND_MAP.getOrDefault(player, new HashMap<>()).keySet();
|
||||
return SWPlayer.of(player).getComponentOrDefault(ScriptData.class, ScriptData::new).commands.keySet();
|
||||
}
|
||||
|
||||
public static void runScript(String script, Player player) {
|
||||
@@ -64,10 +80,12 @@ public class ScriptRunner {
|
||||
|
||||
public static void createGlobalScript(List<String> scripts, Player player) {
|
||||
remove(player);
|
||||
SWPlayer swPlayer = SWPlayer.of(player);
|
||||
ScriptData scriptData = swPlayer.getComponentOrDefault(ScriptData.class, ScriptData::new);
|
||||
Globals globals = SteamWarPlatform.createGlobalGlobals(player,
|
||||
(s, luaFunction) -> EVENT_MAP.computeIfAbsent(player, player1 -> new EnumMap<>(SteamWarGlobalLuaPlugin.EventType.class)).computeIfAbsent(s, s1 -> new ArrayList<>()).add(luaFunction),
|
||||
(s, luaFunction) -> HOTKEY_MAP.computeIfAbsent(player, player1 -> new HashMap<>()).computeIfAbsent(Hotkey.fromString(s), s1 -> new ArrayList<>()).add(luaFunction),
|
||||
commandRegister -> COMMAND_MAP.computeIfAbsent(player, player1 -> new HashMap<>()).put(commandRegister.getName(), commandRegister));
|
||||
(s, luaFunction) -> scriptData.events.computeIfAbsent(s, s1 -> new ArrayList<>()).add(luaFunction),
|
||||
(s, luaFunction) -> scriptData.hotkeys.computeIfAbsent(Hotkey.fromString(s), s1 -> new ArrayList<>()).add(luaFunction),
|
||||
commandRegister -> scriptData.commands.put(commandRegister.getName(), commandRegister));
|
||||
|
||||
for (String script : scripts) {
|
||||
catchScript("SCRIPT_ERROR_GLOBAL", player, () -> globals.load(script).call());
|
||||
@@ -75,13 +93,14 @@ public class ScriptRunner {
|
||||
}
|
||||
|
||||
public static void remove(Player player) {
|
||||
EVENT_MAP.remove(player);
|
||||
COMMAND_MAP.remove(player);
|
||||
HOTKEY_MAP.remove(player);
|
||||
SWPlayer.of(player).removeComponent(ScriptData.class);
|
||||
}
|
||||
|
||||
public static void callEvent(Player player, SteamWarGlobalLuaPlugin.EventType event, LuaValue eventValue, Event wrappedEvent) {
|
||||
List<LuaFunction> luaFunctions = EVENT_MAP.getOrDefault(player, Collections.emptyMap()).getOrDefault(event, Collections.emptyList());
|
||||
List<LuaFunction> luaFunctions = SWPlayer.of(player).getComponent(ScriptData.class)
|
||||
.map(scriptData -> scriptData.events)
|
||||
.orElse(Collections.emptyMap())
|
||||
.getOrDefault(event, Collections.emptyList());
|
||||
if (luaFunctions.isEmpty()) {
|
||||
if(event == SteamWarGlobalLuaPlugin.EventType.DoubleSwap) {
|
||||
player.performCommand("gui");
|
||||
@@ -124,7 +143,10 @@ public class ScriptRunner {
|
||||
}
|
||||
|
||||
public static boolean callCommand(Player player, String command, String[] argsArray) {
|
||||
CommandRegister commandRegister = COMMAND_MAP.getOrDefault(player, Collections.emptyMap()).get(command);
|
||||
CommandRegister commandRegister = SWPlayer.of(player).getComponent(ScriptData.class)
|
||||
.map(scriptData -> scriptData.commands)
|
||||
.orElse(Collections.emptyMap())
|
||||
.get(command);
|
||||
if (commandRegister == null) {
|
||||
return false;
|
||||
}
|
||||
@@ -188,7 +210,11 @@ public class ScriptRunner {
|
||||
|
||||
public static void callHotkey(int mods, int key, Player player, boolean pressed) {
|
||||
Hotkey hotkey = Hotkey.fromChar(key, mods);
|
||||
catchScript("SCRIPT_ERROR_GLOBAL", player, () -> HOTKEY_MAP.getOrDefault(player, Collections.emptyMap()).getOrDefault(hotkey, Collections.emptyList()).forEach(luaFunction -> luaFunction.call(LuaValue.valueOf(pressed))));
|
||||
List<LuaFunction> hotkeys = SWPlayer.of(player).getComponent(ScriptData.class)
|
||||
.map(scriptData -> scriptData.hotkeys)
|
||||
.orElse(Collections.emptyMap())
|
||||
.getOrDefault(hotkey, Collections.emptyList());
|
||||
catchScript("SCRIPT_ERROR_GLOBAL", player, () -> hotkeys.forEach(luaFunction -> luaFunction.call(LuaValue.valueOf(pressed))));
|
||||
}
|
||||
|
||||
public static void catchScript(String errorMsg, Player player, Runnable run) {
|
||||
|
||||
@@ -21,44 +21,24 @@ package de.steamwar.bausystem.features.script.event;
|
||||
|
||||
import de.steamwar.bausystem.Permission;
|
||||
import de.steamwar.bausystem.features.script.ScriptRunner;
|
||||
import de.steamwar.core.SWPlayer;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@Linked
|
||||
public class CommandListener implements Listener {
|
||||
|
||||
private Map<Player, Set<String>> calledCommands = new HashMap<>();
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) {
|
||||
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||
String[] split = event.getMessage().split(" ");
|
||||
if (calledCommands.getOrDefault(event.getPlayer(), new HashSet<>()).contains(split[0])) {
|
||||
return;
|
||||
}
|
||||
ScriptRunner.ScriptData scriptData = SWPlayer.of(event.getPlayer()).getComponentOrDefault(ScriptRunner.ScriptData.class, ScriptRunner.ScriptData::new);
|
||||
if (scriptData.getCalledCommands().contains(split[0])) return;
|
||||
|
||||
calledCommands.getOrDefault(event.getPlayer(), new HashSet<>()).add(split[0]);
|
||||
scriptData.getCalledCommands().add(split[0]);
|
||||
event.setCancelled(ScriptRunner.callCommand(event.getPlayer(), split[0].substring(1), split));
|
||||
calledCommands.getOrDefault(event.getPlayer(), new HashSet<>()).remove(split[0]);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||
calledCommands.put(event.getPlayer(), new HashSet<>());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
calledCommands.remove(event.getPlayer());
|
||||
scriptData.getCalledCommands().remove(split[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import de.steamwar.bausystem.features.script.ScriptRunner;
|
||||
import de.steamwar.bausystem.features.script.lua.SteamWarGlobalLuaPlugin;
|
||||
import de.steamwar.bausystem.features.script.lua.libs.StorageLib;
|
||||
import de.steamwar.bausystem.region.Region;
|
||||
import de.steamwar.core.SWPlayer;
|
||||
import de.steamwar.core.TrickyTrialsWrapper;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Bukkit;
|
||||
@@ -43,32 +44,27 @@ import org.bukkit.event.player.*;
|
||||
import org.luaj.vm2.LuaTable;
|
||||
import org.luaj.vm2.LuaValue;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@Linked
|
||||
public class EventListener implements Listener {
|
||||
|
||||
private static final Map<Player, Long> LAST_FS = new HashMap<>();
|
||||
|
||||
static {
|
||||
Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), () -> {
|
||||
long millis = System.currentTimeMillis();
|
||||
LAST_FS.entrySet().removeIf(entry -> millis - entry.getValue() > 200);
|
||||
SWPlayer.allWithSingleComponent(ScriptRunner.ScriptData.class)
|
||||
.filter(pair -> millis - pair.getValue().getLastF() > 200)
|
||||
.forEach(pair -> pair.getValue().setLastF(Long.MAX_VALUE));
|
||||
}, 1, 1);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||
ScriptRunner.callEvent(event.getPlayer(), SteamWarGlobalLuaPlugin.EventType.SelfJoin, LuaValue.NIL, event);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
if(Permission.BUILD.hasPermission(event.getPlayer())) {
|
||||
if (Permission.BUILD.hasPermission(event.getPlayer())) {
|
||||
ScriptRunner.callEvent(event.getPlayer(), SteamWarGlobalLuaPlugin.EventType.SelfLeave, LuaValue.NIL, event);
|
||||
}
|
||||
StorageLib.removePlayer(event.getPlayer());
|
||||
@@ -76,19 +72,20 @@ public class EventListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onPlayerSwapHandItems(PlayerSwapHandItemsEvent event) {
|
||||
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||
if (LAST_FS.containsKey(event.getPlayer())) {
|
||||
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||
ScriptRunner.ScriptData scriptData = SWPlayer.of(event.getPlayer()).getComponentOrDefault(ScriptRunner.ScriptData.class, ScriptRunner.ScriptData::new);
|
||||
if (scriptData.getLastF() != Long.MAX_VALUE) {
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||
ScriptRunner.callEvent(event.getPlayer(), SteamWarGlobalLuaPlugin.EventType.DoubleSwap, LuaValue.NIL, event);
|
||||
}, 1);
|
||||
} else {
|
||||
LAST_FS.put(event.getPlayer(), System.currentTimeMillis());
|
||||
scriptData.setLastF(System.currentTimeMillis());
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onBlockPlace(BlockPlaceEvent event) {
|
||||
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||
LuaTable table = new LuaTable();
|
||||
table.set("x", event.getBlock().getX());
|
||||
table.set("y", event.getBlock().getY());
|
||||
@@ -99,7 +96,7 @@ public class EventListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onBlockBreak(BlockBreakEvent event) {
|
||||
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||
LuaTable table = new LuaTable();
|
||||
table.set("x", event.getBlock().getX());
|
||||
table.set("y", event.getBlock().getY());
|
||||
@@ -108,12 +105,12 @@ public class EventListener implements Listener {
|
||||
ScriptRunner.callEvent(event.getPlayer(), SteamWarGlobalLuaPlugin.EventType.BreakBlock, table, event);
|
||||
}
|
||||
|
||||
private final Set<Player> ignore = new HashSet<>();
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void onPlayerInteract(PlayerInteractEvent event) {
|
||||
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||
if (ignore.remove(event.getPlayer())) {
|
||||
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||
ScriptRunner.ScriptData scriptData = SWPlayer.of(event.getPlayer()).getComponentOrDefault(ScriptRunner.ScriptData.class, ScriptRunner.ScriptData::new);
|
||||
if (scriptData.isIgnore()) {
|
||||
scriptData.setIgnore(false);
|
||||
return;
|
||||
}
|
||||
LuaTable table = new LuaTable();
|
||||
@@ -124,7 +121,7 @@ public class EventListener implements Listener {
|
||||
table.set("hand", event.getHand().name());
|
||||
}
|
||||
table.set("block", event.getItem() == null ? Material.AIR.name() : event.getItem().getType().name());
|
||||
if(event.getAction() == Action.RIGHT_CLICK_BLOCK || event.getAction() == Action.LEFT_CLICK_BLOCK) {
|
||||
if (event.getAction() == Action.RIGHT_CLICK_BLOCK || event.getAction() == Action.LEFT_CLICK_BLOCK) {
|
||||
table.set("hasBlock", LuaValue.valueOf(true));
|
||||
table.set("blockX", event.getClickedBlock().getX());
|
||||
table.set("blockY", event.getClickedBlock().getY());
|
||||
@@ -150,7 +147,7 @@ public class EventListener implements Listener {
|
||||
Region tntRegion = Region.getRegion(event.getLocation());
|
||||
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
if(!Permission.BUILD.hasPermission(player)) continue;
|
||||
if (!Permission.BUILD.hasPermission(player)) continue;
|
||||
if (tntRegion.getArea().inRegion(player.getLocation(), false)) {
|
||||
ScriptRunner.callEvent(player, SteamWarGlobalLuaPlugin.EventType.TNTSpawn, LuaValue.NIL, event);
|
||||
}
|
||||
@@ -172,7 +169,7 @@ public class EventListener implements Listener {
|
||||
boolean inBuild = event.blockList().stream().anyMatch(block -> tntRegion.getBuildArea().inRegion(block.getLocation(), true));
|
||||
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
if(!Permission.BUILD.hasPermission(player)) continue;
|
||||
if (!Permission.BUILD.hasPermission(player)) continue;
|
||||
if (tntRegion.getArea().inRegion(player.getLocation(), false)) {
|
||||
ScriptRunner.callEvent(player, SteamWarGlobalLuaPlugin.EventType.TNTExplode, table, event);
|
||||
if (inBuild) {
|
||||
@@ -184,8 +181,9 @@ public class EventListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onPlayerDropItem(PlayerDropItemEvent event) {
|
||||
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||
ignore.add(event.getPlayer());
|
||||
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||
ScriptRunner.ScriptData scriptData = SWPlayer.of(event.getPlayer()).getComponentOrDefault(ScriptRunner.ScriptData.class, ScriptRunner.ScriptData::new);
|
||||
scriptData.setIgnore(true);
|
||||
LuaTable table = new LuaTable();
|
||||
table.set("type", event.getItemDrop().getItemStack().getType().name());
|
||||
ScriptRunner.callEvent(event.getPlayer(), SteamWarGlobalLuaPlugin.EventType.DropItem, table, event);
|
||||
@@ -194,7 +192,7 @@ public class EventListener implements Listener {
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onEntityDeath(EntityDeathEvent event) {
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
if(!Permission.BUILD.hasPermission(player)) continue;
|
||||
if (!Permission.BUILD.hasPermission(player)) continue;
|
||||
LuaTable table = new LuaTable();
|
||||
table.set("type", event.getEntityType().name());
|
||||
ScriptRunner.callEvent(player, SteamWarGlobalLuaPlugin.EventType.EntityDeath, table, event);
|
||||
|
||||
@@ -48,6 +48,7 @@ import java.util.logging.Level;
|
||||
public class SteamWarLuaPlugin extends TwoArgFunction {
|
||||
|
||||
private static final boolean hasFAWE = Bukkit.getPluginManager().getPlugin("FastAsyncWorldEdit") != null;
|
||||
private static final Set<String> ignoreCommandFromWorldEdit = Set.of("select", "schem", "/schem", "schematic", "/schematic");
|
||||
|
||||
protected static final Map<Class<?>, List<LuaLib>> LUA_LIBS = new HashMap<>();
|
||||
|
||||
@@ -116,7 +117,7 @@ public class SteamWarLuaPlugin extends TwoArgFunction {
|
||||
command = preprocessEvent.getMessage().substring(1);
|
||||
Bukkit.getLogger().log(Level.INFO, player.getName() + " dispatched command: " + command);
|
||||
String[] commandSplit = command.split(" ");
|
||||
if (!commandSplit[0].equals("select") && hasFAWE && WorldEditListener.isWorldEditCommand("/" + commandSplit[0])) {
|
||||
if (!ignoreCommandFromWorldEdit.contains(commandSplit[0]) && hasFAWE && WorldEditListener.isWorldEditCommand("/" + commandSplit[0])) {
|
||||
EditSession editSession = WorldEditUtils.getEditSession(player);
|
||||
Actor actor = BukkitAdapter.adapt(player);
|
||||
WorldEdit.getInstance().getPlatformManager().getPlatformCommandManager().handleCommandOnCurrentThread(new CommandEvent(actor, command, editSession));
|
||||
|
||||
@@ -89,7 +89,7 @@ public class StorageLib implements LuaLib, Enable, Disable {
|
||||
jsonObject.keySet().forEach(key -> {
|
||||
map.put(key, fromJson(jsonObject.get(key)));
|
||||
});
|
||||
SteamwarUser steamwarUser = SteamwarUser.get(Integer.parseInt(playerStorage.getName().substring(0, playerStorage.getName().length() - ".json".length())));
|
||||
SteamwarUser steamwarUser = SteamwarUser.byId(Integer.parseInt(playerStorage.getName().substring(0, playerStorage.getName().length() - ".json".length())));
|
||||
PLAYER_STORAGE.put(steamwarUser.getUUID(), map);
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ public class YAPIONFormatSimulatorLoader implements SimulatorLoader {
|
||||
}
|
||||
|
||||
String name = file.getName().substring(0, file.getName().length() - 7);
|
||||
SteamwarUser steamwarUser = SteamwarUser.get(Integer.parseInt(name));
|
||||
SteamwarUser steamwarUser = SteamwarUser.byId(Integer.parseInt(name));
|
||||
|
||||
List<Simulator> simulators = new ArrayList<>();
|
||||
for (String s : yapionObject.getKeys()) {
|
||||
|
||||
@@ -21,28 +21,16 @@ package de.steamwar.bausystem.features.slaves.laufbau;
|
||||
|
||||
import com.sk89q.worldedit.blocks.SkullBlock;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import de.steamwar.bausystem.utils.NMSWrapper;
|
||||
import de.steamwar.core.Core;
|
||||
import de.steamwar.inventory.SWItem;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.Bisected;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.block.data.Directional;
|
||||
import org.bukkit.block.data.Waterlogged;
|
||||
import org.bukkit.block.data.type.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
|
||||
|
||||
@ToString
|
||||
@Getter
|
||||
public class BlockBoundingBox {
|
||||
@@ -95,193 +83,6 @@ public class BlockBoundingBox {
|
||||
return volume;
|
||||
}
|
||||
|
||||
static {
|
||||
addPixel(Material.AIR.createBlockData(), 0, 0, 0, 0, 0, 0, null);
|
||||
// addPixel(Material.COBWEB.createBlockData(), 0, 0, 0, 0, 0, 0, createItem("LAUFBAU_BLOCK_COBWEB", Material.COBWEB));
|
||||
addPixel(Material.END_STONE.createBlockData(), 0, 0, 0, 16, 16, 16, null);
|
||||
|
||||
addPixel(NMSWrapper.impl.pathMaterial().createBlockData(), 0, 0, 0, 16, 15, 16, createItem("LAUFBAU_BLOCK_GRASS_PATH", NMSWrapper.impl.pathMaterial()));
|
||||
addPixel(Material.SOUL_SAND.createBlockData(), 0, 0, 0, 16, 14, 16, createItem("LAUFBAU_BLOCK_SOUL_SAND", Material.SOUL_SAND));
|
||||
|
||||
Cocoa cocoaNorth = (Cocoa) Material.COCOA.createBlockData();
|
||||
cocoaNorth.setAge(2);
|
||||
cocoaNorth.setFacing(BlockFace.NORTH);
|
||||
addPixel(cocoaNorth, 4, 3, 1, 8, 9, 8, createItem("LAUFBAU_BLOCK_COCOA", Material.COCOA_BEANS, "LAUFBAU_FACING_NORTH"));
|
||||
|
||||
Cocoa cocoaSouth = (Cocoa) Material.COCOA.createBlockData();
|
||||
cocoaSouth.setAge(2);
|
||||
cocoaSouth.setFacing(BlockFace.SOUTH);
|
||||
addPixel(cocoaSouth, 4, 3, 7, 8, 9, 8, createItem("LAUFBAU_BLOCK_COCOA", Material.COCOA_BEANS, "LAUFBAU_FACING_SOUTH"));
|
||||
|
||||
Cocoa cocoaWest = (Cocoa) Material.COCOA.createBlockData();
|
||||
cocoaWest.setAge(2);
|
||||
cocoaWest.setFacing(BlockFace.WEST);
|
||||
addPixel(cocoaWest, 1, 3, 4, 8, 9, 8, createItem("LAUFBAU_BLOCK_COCOA", Material.COCOA_BEANS, "LAUFBAU_FACING_WEST"));
|
||||
|
||||
Cocoa cocoaEast = (Cocoa) Material.COCOA.createBlockData();
|
||||
cocoaEast.setAge(2);
|
||||
cocoaEast.setFacing(BlockFace.EAST);
|
||||
addPixel(cocoaEast, 7, 3, 4, 8, 9, 8, createItem("LAUFBAU_BLOCK_COCOA", Material.COCOA_BEANS, "LAUFBAU_FACING_EAST"));
|
||||
|
||||
TurtleEgg singleTurtleEgg = (TurtleEgg) Material.TURTLE_EGG.createBlockData();
|
||||
singleTurtleEgg.setEggs(1);
|
||||
singleTurtleEgg.setHatch(0);
|
||||
addPixel(singleTurtleEgg, 4, 0, 3, 9, 7, 9, createItem("LAUFBAU_BLOCK_TURTLE_EGG", Material.TURTLE_EGG, "LAUFBAU_COUNT_1"));
|
||||
|
||||
TurtleEgg doubleTurtleEgg = (TurtleEgg) Material.TURTLE_EGG.createBlockData();
|
||||
doubleTurtleEgg.setEggs(2);
|
||||
doubleTurtleEgg.setHatch(0);
|
||||
addPixel(doubleTurtleEgg, 1, 0, 1, 14, 7, 14, createItem("LAUFBAU_BLOCK_TURTLE_EGG", Material.TURTLE_EGG, "LAUFBAU_COUNT_2"));
|
||||
|
||||
addPixel(Material.CHEST.createBlockData(), 1, 0, 1, 14, 14, 14, createItem("LAUFBAU_BLOCK_CHEST", Material.CHEST));
|
||||
|
||||
Snow snowLayers8 = (Snow) Material.SNOW.createBlockData();
|
||||
snowLayers8.setLayers(8);
|
||||
addPixel(snowLayers8, 0, 0, 0, 16, 14, 16, createItem("LAUFBAU_BLOCK_SNOW", Material.SNOW, "LAUFBAU_LAYERS_8"));
|
||||
|
||||
Directional headNorth = (Directional) Material.PLAYER_WALL_HEAD.createBlockData();
|
||||
headNorth.setFacing(BlockFace.NORTH);
|
||||
addPixel(headNorth, 4, 4, 8, 8, 8, 8, createItem("LAUFBAU_BLOCK_PLAYER_WALL_HEAD", Material.PLAYER_HEAD, "LAUFBAU_FACING_NORTH"), BlockBoundingBox::randomPlayerHead);
|
||||
|
||||
Directional headSouth = (Directional) Material.PLAYER_WALL_HEAD.createBlockData();
|
||||
headSouth.setFacing(BlockFace.SOUTH);
|
||||
addPixel(headSouth, 4, 4, 0, 8, 8, 8, createItem("LAUFBAU_BLOCK_PLAYER_WALL_HEAD", Material.PLAYER_HEAD, "LAUFBAU_FACING_SOUTH"), BlockBoundingBox::randomPlayerHead);
|
||||
|
||||
Directional headWest = (Directional) Material.PLAYER_WALL_HEAD.createBlockData();
|
||||
headWest.setFacing(BlockFace.WEST);
|
||||
addPixel(headWest, 8, 4, 4, 8, 8, 8, createItem("LAUFBAU_BLOCK_PLAYER_WALL_HEAD", Material.PLAYER_HEAD, "LAUFBAU_FACING_WEST"), BlockBoundingBox::randomPlayerHead);
|
||||
|
||||
Directional headEast = (Directional) Material.PLAYER_WALL_HEAD.createBlockData();
|
||||
headEast.setFacing(BlockFace.EAST);
|
||||
addPixel(headEast, 0, 4, 4, 8, 8, 8, createItem("LAUFBAU_BLOCK_PLAYER_WALL_HEAD", Material.PLAYER_HEAD, "LAUFBAU_FACING_EAST"), BlockBoundingBox::randomPlayerHead);
|
||||
|
||||
Snow snowLayers7 = (Snow) Material.SNOW.createBlockData();
|
||||
snowLayers7.setLayers(7);
|
||||
addPixel(snowLayers7, 0, 0, 0, 16, 12, 16, createItem("LAUFBAU_BLOCK_SNOW", Material.SNOW, "LAUFBAU_LAYERS_7"));
|
||||
|
||||
Snow snowLayers6 = (Snow) Material.SNOW.createBlockData();
|
||||
snowLayers6.setLayers(6);
|
||||
addPixel(snowLayers6, 0, 0, 0, 16, 10, 16, createItem("LAUFBAU_BLOCK_SNOW", Material.SNOW, "LAUFBAU_LAYERS_6"));
|
||||
|
||||
addPixel(Material.STONECUTTER.createBlockData(), 0, 0, 0, 16, 9, 16, createItem("LAUFBAU_BLOCK_STONECUTTER", Material.STONECUTTER));
|
||||
|
||||
addPixel(Material.PLAYER_HEAD.createBlockData(), 4, 0, 4, 8, 8, 8, createItem("LAUFBAU_BLOCK_PLAYER_HEAD", Material.PLAYER_HEAD), BlockBoundingBox::randomPlayerHead);
|
||||
|
||||
addPixel(Material.CAKE.createBlockData(), 1, 0, 1, 14, 8, 14, createItem("LAUFBAU_BLOCK_CAKE", Material.CAKE));
|
||||
|
||||
Slab bottomSlab = (Slab) Material.END_STONE_BRICK_SLAB.createBlockData();
|
||||
bottomSlab.setType(Slab.Type.BOTTOM);
|
||||
addPixel(bottomSlab, 0, 0, 0, 16, 8, 16, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_SLAB", Material.END_STONE_BRICK_SLAB, "LAUFBAU_TYPE_BOTTOM"));
|
||||
|
||||
Slab topSlab = (Slab) Material.END_STONE_BRICK_SLAB.createBlockData();
|
||||
topSlab.setType(Slab.Type.TOP);
|
||||
addPixel(topSlab, 0, 8, 0, 16, 8, 16, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_SLAB", Material.END_STONE_BRICK_SLAB, "LAUFBAU_TYPE_TOP"));
|
||||
|
||||
SeaPickle quadSeaPickle = (SeaPickle) Material.SEA_PICKLE.createBlockData();
|
||||
quadSeaPickle.setWaterlogged(false);
|
||||
quadSeaPickle.setPickles(4);
|
||||
addPixel(quadSeaPickle, 2, 0, 2, 12, 7, 12, createItem("LAUFBAU_BLOCK_SEA_PICKLE", Material.SEA_PICKLE, "LAUFBAU_COUNT_4"));
|
||||
|
||||
Campfire campfire = (Campfire) Material.CAMPFIRE.createBlockData();
|
||||
campfire.setSignalFire(false);
|
||||
campfire.setLit(false);
|
||||
addPixel(campfire, 0, 0, 0, 16, 7, 16, createItem("LAUFBAU_BLOCK_CAMPFIRE", Material.CAMPFIRE));
|
||||
|
||||
SeaPickle trippleSeaPickle = (SeaPickle) Material.SEA_PICKLE.createBlockData();
|
||||
trippleSeaPickle.setWaterlogged(false);
|
||||
trippleSeaPickle.setPickles(3);
|
||||
addPixel(trippleSeaPickle, 2, 0, 2, 12, 6, 12, createItem("LAUFBAU_BLOCK_SEA_PICKLE", Material.SEA_PICKLE, "LAUFBAU_COUNT_3"));
|
||||
|
||||
SeaPickle doubleSeaPickle = (SeaPickle) Material.SEA_PICKLE.createBlockData();
|
||||
doubleSeaPickle.setWaterlogged(false);
|
||||
doubleSeaPickle.setPickles(2);
|
||||
addPixel(doubleSeaPickle, 3, 0, 3, 10, 6, 10, createItem("LAUFBAU_BLOCK_SEA_PICKLE", Material.SEA_PICKLE, "LAUFBAU_COUNT_2"));
|
||||
|
||||
SeaPickle singleSeaPickle = (SeaPickle) Material.SEA_PICKLE.createBlockData();
|
||||
singleSeaPickle.setWaterlogged(false);
|
||||
singleSeaPickle.setPickles(1);
|
||||
addPixel(singleSeaPickle, 6, 0, 6, 4, 6, 4, createItem("LAUFBAU_BLOCK_SEA_PICKLE", Material.SEA_PICKLE, "LAUFBAU_COUNT_1"));
|
||||
|
||||
addPixel(Material.FLOWER_POT.createBlockData(), 5, 0, 5, 6, 6, 6, createItem("LAUFBAU_BLOCK_FLOWER_POT", Material.FLOWER_POT));
|
||||
|
||||
Snow snowLayers3 = (Snow) Material.SNOW.createBlockData();
|
||||
snowLayers3.setLayers(3);
|
||||
addPixel(snowLayers3, 0, 0, 0, 16, 4, 16, createItem("LAUFBAU_BLOCK_SNOW", Material.SNOW, "LAUFBAU_LAYERS_3"));
|
||||
|
||||
TrapDoor bottomTrapDoor = (TrapDoor) Material.IRON_TRAPDOOR.createBlockData();
|
||||
bottomTrapDoor.setHalf(Bisected.Half.BOTTOM);
|
||||
addPixel(bottomTrapDoor, 0, 0, 0, 16, 3, 16, createItem("LAUFBAU_BLOCK_IRON_TRAPDOOR", Material.IRON_TRAPDOOR, "LAUFBAU_HALF_BOTTOM"));
|
||||
|
||||
TrapDoor topTrapDoor = (TrapDoor) Material.IRON_TRAPDOOR.createBlockData();
|
||||
topTrapDoor.setHalf(Bisected.Half.TOP);
|
||||
addPixel(topTrapDoor, 0, 13, 0, 16, 3, 16, createItem("LAUFBAU_BLOCK_IRON_TRAPDOOR", Material.IRON_TRAPDOOR, "LAUFBAU_HALF_TOP"));
|
||||
|
||||
Snow snowLayers2 = (Snow) Material.SNOW.createBlockData();
|
||||
snowLayers2.setLayers(2);
|
||||
addPixel(snowLayers2, 0, 0, 0, 16, 2, 16, createItem("LAUFBAU_BLOCK_SNOW", Material.SNOW, "LAUFBAU_LAYERS_2"));
|
||||
|
||||
addPixel(Material.LILY_PAD.createBlockData(), 1, 0, 1, 14, 1.5, 14, createItem("LAUFBAU_BLOCK_LILY_PAD", Material.LILY_PAD));
|
||||
addPixel(Material.WHITE_CARPET.createBlockData(), 0, 0, 0, 16, 1, 16, createItem("LAUFBAU_BLOCK_WHITE_CARPET", Material.WHITE_CARPET));
|
||||
|
||||
Directional endRodBottomTop = (Directional) Material.END_ROD.createBlockData();
|
||||
endRodBottomTop.setFacing(BlockFace.UP);
|
||||
addPixel(endRodBottomTop, 6, 0, 6, 4, 16, 4, createItem("LAUFBAU_BLOCK_END_ROD", Material.END_ROD, "LAUFBAU_FACING_UP", "LAUFBAU_FACING_DOWN"));
|
||||
|
||||
Directional endRodNorthSouth = (Directional) Material.END_ROD.createBlockData();
|
||||
endRodNorthSouth.setFacing(BlockFace.NORTH);
|
||||
addPixel(endRodNorthSouth, 6, 6, 0, 4, 4, 16, createItem("LAUFBAU_BLOCK_END_ROD", Material.END_ROD, "LAUFBAU_FACING_NORTH", "LAUFBAU_FACING_SOUTH"));
|
||||
|
||||
Directional endRodEastWest = (Directional) Material.END_ROD.createBlockData();
|
||||
endRodEastWest.setFacing(BlockFace.EAST);
|
||||
addPixel(endRodEastWest, 0, 6, 6, 16, 4, 4, createItem("LAUFBAU_BLOCK_END_ROD", Material.END_ROD, "LAUFBAU_FACING_EAST", "LAUFBAU_FACING_WEST"));
|
||||
|
||||
if (Core.getVersion() >= 19) {
|
||||
Directional lightningRodBottomTop = (Directional) Material.LIGHTNING_ROD.createBlockData();
|
||||
lightningRodBottomTop.setFacing(BlockFace.UP);
|
||||
addPixel(lightningRodBottomTop, 6, 0, 6, 4, 16, 4, createItem("LAUFBAU_BLOCK_LIGHTNING_ROD", Material.LIGHTNING_ROD, "LAUFBAU_FACING_UP", "LAUFBAU_FACING_DOWN"));
|
||||
|
||||
Directional lightningRodNorthSouth = (Directional) Material.LIGHTNING_ROD.createBlockData();
|
||||
lightningRodNorthSouth.setFacing(BlockFace.NORTH);
|
||||
addPixel(lightningRodNorthSouth, 6, 6, 0, 4, 4, 16, createItem("LAUFBAU_BLOCK_LIGHTNING_ROD", Material.LIGHTNING_ROD, "LAUFBAU_FACING_NORTH", "LAUFBAU_FACING_SOUTH"));
|
||||
|
||||
Directional lightningRodEastWest = (Directional) Material.LIGHTNING_ROD.createBlockData();
|
||||
lightningRodEastWest.setFacing(BlockFace.EAST);
|
||||
addPixel(lightningRodEastWest, 0, 6, 6, 16, 4, 4, createItem("LAUFBAU_BLOCK_LIGHTNING_ROD", Material.LIGHTNING_ROD, "LAUFBAU_FACING_EAST", "LAUFBAU_FACING_WEST"));
|
||||
}
|
||||
|
||||
Waterlogged conduit = (Waterlogged) Material.CONDUIT.createBlockData();
|
||||
conduit.setWaterlogged(false);
|
||||
addPixel(conduit, 5, 5, 5, 6, 6, 6, createItem("LAUFBAU_BLOCK_CONDUIT", Material.CONDUIT));
|
||||
|
||||
TrapDoor northTrapDoor = (TrapDoor) Material.IRON_TRAPDOOR.createBlockData();
|
||||
northTrapDoor.setFacing(BlockFace.NORTH);
|
||||
northTrapDoor.setOpen(true);
|
||||
addPixel(northTrapDoor, 0, 0, 13, 16, 16, 3, createItem("LAUFBAU_BLOCK_IRON_TRAPDOOR", Material.IRON_TRAPDOOR, "LAUFBAU_FACING_NORTH", "LAUFBAU_OPEN"));
|
||||
|
||||
TrapDoor southTrapDoor = (TrapDoor) Material.IRON_TRAPDOOR.createBlockData();
|
||||
southTrapDoor.setFacing(BlockFace.SOUTH);
|
||||
southTrapDoor.setOpen(true);
|
||||
addPixel(southTrapDoor, 0, 0, 0, 16, 16, 3, createItem("LAUFBAU_BLOCK_IRON_TRAPDOOR", Material.IRON_TRAPDOOR, "LAUFBAU_FACING_SOUTH", "LAUFBAU_OPEN"));
|
||||
|
||||
TrapDoor westTrapDoor = (TrapDoor) Material.IRON_TRAPDOOR.createBlockData();
|
||||
westTrapDoor.setFacing(BlockFace.WEST);
|
||||
westTrapDoor.setOpen(true);
|
||||
addPixel(westTrapDoor, 13, 0, 0, 3, 16, 16, createItem("LAUFBAU_BLOCK_IRON_TRAPDOOR", Material.IRON_TRAPDOOR, "LAUFBAU_FACING_WEST", "LAUFBAU_OPEN"));
|
||||
|
||||
TrapDoor eastTrapDoor = (TrapDoor) Material.IRON_TRAPDOOR.createBlockData();
|
||||
eastTrapDoor.setFacing(BlockFace.EAST);
|
||||
eastTrapDoor.setOpen(true);
|
||||
addPixel(eastTrapDoor, 0, 0, 0, 3, 16, 16, createItem("LAUFBAU_BLOCK_IRON_TRAPDOOR", Material.IRON_TRAPDOOR, "LAUFBAU_FACING_EAST", "LAUFBAU_OPEN"));
|
||||
}
|
||||
|
||||
private static void addPixel(BlockData blockData, double xPixel, double yPixel, double zPixel, double dxPixel, double dyPixel, double dzPixel, SWItem swItem) {
|
||||
new BlockBoundingBox(blockData, Arrays.asList(pixelCuboid(xPixel, yPixel, zPixel, dxPixel, dyPixel, dzPixel)), swItem);
|
||||
}
|
||||
|
||||
private static void addPixel(BlockData blockData, double xPixel, double yPixel, double zPixel, double dxPixel, double dyPixel, double dzPixel, SWItem swItem, Consumer<BaseBlock> blockConsumer) {
|
||||
new BlockBoundingBox(blockData, Arrays.asList(pixelCuboid(xPixel, yPixel, zPixel, dxPixel, dyPixel, dzPixel)), swItem, blockConsumer);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private static void randomPlayerHead(BaseBlock block) {
|
||||
if (block instanceof SkullBlock) {
|
||||
|
||||
@@ -19,7 +19,243 @@
|
||||
|
||||
package de.steamwar.bausystem.features.slaves.laufbau;
|
||||
|
||||
public interface BoundingBoxLoader {
|
||||
import de.steamwar.core.Core;
|
||||
import de.steamwar.inventory.SWItem;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import de.steamwar.linkage.MinVersion;
|
||||
import de.steamwar.linkage.api.Enable;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.block.data.type.*;
|
||||
import org.bukkit.util.BoundingBox;
|
||||
import org.bukkit.util.VoxelShape;
|
||||
|
||||
void load();
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.util.*;
|
||||
import java.util.Comparator;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@MinVersion(20)
|
||||
@Linked
|
||||
public class BoundingBoxLoader implements Enable {
|
||||
|
||||
private static final World world = Bukkit.getWorlds().get(0);
|
||||
|
||||
@Override
|
||||
public void enable() {
|
||||
Block block = world.getBlockAt(0, 0, 0);
|
||||
BlockState blockState = block.getState();
|
||||
List<Material> materials = Arrays.stream(Material.values())
|
||||
.filter(material -> !material.isLegacy())
|
||||
.filter(material -> material.isBlock())
|
||||
.filter(material -> material.getBlastResistance() <= 9)
|
||||
.filter(material -> !(material.createBlockData() instanceof Door))
|
||||
.sorted(Comparator.comparingDouble(material -> -material.getBlastResistance()))
|
||||
.collect(Collectors.toList());
|
||||
materials.remove(Material.PITCHER_PLANT);
|
||||
materials.remove(Material.PITCHER_CROP);
|
||||
materials.remove(Material.PITCHER_POD);
|
||||
materials.remove(Material.SCAFFOLDING);
|
||||
materials.remove(Material.CAULDRON);
|
||||
if (Core.getVersion() > 20) {
|
||||
materials.remove(Material.CHISELED_BOOKSHELF);
|
||||
}
|
||||
|
||||
Map<Collection<BoundingBox>, BlockData> uniqueBoundinxBoxes = new HashMap<>();
|
||||
Sink last = new Sink() {
|
||||
@Override
|
||||
protected void sink(BlockData current) {
|
||||
try {
|
||||
if (current instanceof Cocoa) {
|
||||
if (((Cocoa) current).getAge() != ((Cocoa) current).getMaximumAge()) return;
|
||||
}
|
||||
if (current instanceof Snow) {
|
||||
if (((Snow) current).getLayers() == 2) return;
|
||||
}
|
||||
if (current instanceof Cake) {
|
||||
if (((Cake) current).getBites() != 0) return;
|
||||
}
|
||||
if (current instanceof Wall) {
|
||||
((Wall) current).setUp(true);
|
||||
}
|
||||
block.setType(Material.AIR);
|
||||
block.setBlockData(current, false);
|
||||
} catch (NullPointerException e) {
|
||||
return;
|
||||
}
|
||||
VoxelShape voxelShape = block.getCollisionShape();
|
||||
if (voxelShape.getBoundingBoxes().isEmpty()) return;
|
||||
uniqueBoundinxBoxes.putIfAbsent(voxelShape.getBoundingBoxes(), current);
|
||||
}
|
||||
};
|
||||
|
||||
for (Material material : materials) {
|
||||
BlockData blockData = material.createBlockData();
|
||||
Set<Class<? extends BlockData>> interfaces = getInterfaces(blockData.getClass());
|
||||
interfaces.remove(BlockData.class);
|
||||
|
||||
List<Sink> sinks = interfaces.stream()
|
||||
.map(this::getSetters)
|
||||
.flatMap(Set::stream)
|
||||
.map(method -> {
|
||||
try {
|
||||
return getSink(method);
|
||||
} catch (UnsupportedOperationException e) {
|
||||
return null;
|
||||
}
|
||||
})
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
for (int i = 1; i < sinks.size(); i++) {
|
||||
sinks.get(i - 1).next = sinks.get(i);
|
||||
}
|
||||
|
||||
if (!sinks.isEmpty()) {
|
||||
sinks.get(sinks.size() - 1).next = last;
|
||||
sinks.get(0).sink(blockData);
|
||||
} else {
|
||||
last.sink(blockData);
|
||||
}
|
||||
}
|
||||
uniqueBoundinxBoxes.forEach((boundingBoxes, blockData) -> {
|
||||
List<Cuboid> cuboidList = boundingBoxes.stream()
|
||||
.map(boundingBox -> {
|
||||
return new Cuboid(boundingBox.getMinX(), boundingBox.getMinY(), boundingBox.getMinZ(), boundingBox.getWidthX(), boundingBox.getHeight(), boundingBox.getWidthZ());
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
Material material = blockData.getMaterial();
|
||||
if (!material.isItem()) {
|
||||
material = blockData.getPlacementMaterial();
|
||||
}
|
||||
if (material.isAir() || !material.isItem()) {
|
||||
material = Material.BARRIER;
|
||||
}
|
||||
new BlockBoundingBox(blockData, cuboidList, new SWItem(material, blockData.getMaterial().name()));
|
||||
});
|
||||
blockState.update(true, false);
|
||||
}
|
||||
|
||||
private Set<Class<? extends BlockData>> getInterfaces(Class<?> clazz) {
|
||||
if (clazz == null) return Collections.emptySet();
|
||||
Set<Class<? extends BlockData>> interfaces = Arrays.stream(clazz.getInterfaces())
|
||||
.filter(BlockData.class::isAssignableFrom)
|
||||
.map(aClass -> (Class<? extends BlockData>) aClass)
|
||||
.collect(Collectors.toSet());
|
||||
interfaces.addAll(getInterfaces(clazz.getSuperclass()));
|
||||
interfaces.addAll(interfaces.stream()
|
||||
.map(this::getInterfaces)
|
||||
.flatMap(Set::stream)
|
||||
.collect(Collectors.toSet()));
|
||||
return interfaces;
|
||||
}
|
||||
|
||||
private Set<Method> getSetters(Class<? extends BlockData> clazz) {
|
||||
Method[] methods = clazz.getDeclaredMethods();
|
||||
Set<Method> setters = new HashSet<>();
|
||||
for (Method method : methods) {
|
||||
if (method.getName().startsWith("set")) {
|
||||
setters.add(method);
|
||||
}
|
||||
}
|
||||
return setters;
|
||||
}
|
||||
|
||||
private abstract class Sink {
|
||||
protected Sink next = null;
|
||||
|
||||
protected abstract void sink(BlockData current);
|
||||
}
|
||||
|
||||
private Sink getSink(Method method) {
|
||||
if (method.getParameterCount() == 1) {
|
||||
Parameter parameter = method.getParameters()[0];
|
||||
Object[] values = getValues(parameter);
|
||||
return new Sink() {
|
||||
@Override
|
||||
protected void sink(BlockData current) {
|
||||
for (Object o : values) {
|
||||
BlockData cloned = current.clone();
|
||||
try {
|
||||
method.invoke(cloned, o);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
next.sink(cloned);
|
||||
}
|
||||
}
|
||||
};
|
||||
} else if (method.getParameterCount() == 2) {
|
||||
Parameter firstParameter = method.getParameters()[0];
|
||||
Parameter secondParameter = method.getParameters()[1];
|
||||
Object[] firstValues = getValues(firstParameter);
|
||||
Object[] secondValues = getValues(secondParameter);
|
||||
return new Sink() {
|
||||
|
||||
private Sink outerThis = this;
|
||||
private List<Sink> sinks = new ArrayList<>();
|
||||
|
||||
{
|
||||
for (int i = 0; i < firstValues.length; i++) {
|
||||
Object first = firstValues[i];
|
||||
boolean last = i == firstValues.length - 1;
|
||||
Sink current = new Sink() {
|
||||
@Override
|
||||
protected void sink(BlockData current) {
|
||||
for (Object second : secondValues) {
|
||||
BlockData cloned = current.clone();
|
||||
try {
|
||||
method.invoke(cloned, first, second);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
if (last) {
|
||||
outerThis.next.sink(cloned);
|
||||
} else {
|
||||
next.sink(cloned);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
if (!sinks.isEmpty()) {
|
||||
sinks.get(sinks.size() - 1).next = current;
|
||||
}
|
||||
sinks.add(current);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void sink(BlockData current) {
|
||||
sinks.get(0).sink(current);
|
||||
}
|
||||
};
|
||||
} else {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
private Object[] getValues(Parameter parameter) {
|
||||
if (parameter.getType().isEnum()) {
|
||||
if (BlockFace.class.isAssignableFrom(parameter.getType())) {
|
||||
return new BlockFace[]{
|
||||
BlockFace.NORTH,
|
||||
BlockFace.SOUTH,
|
||||
BlockFace.EAST,
|
||||
BlockFace.WEST,
|
||||
BlockFace.UP,
|
||||
BlockFace.DOWN
|
||||
};
|
||||
}
|
||||
return parameter.getType().getEnumConstants();
|
||||
} else if (parameter.getType() == boolean.class || parameter.getType() == Boolean.class) {
|
||||
return new Object[]{false, true};
|
||||
} else if (parameter.getType() == int.class || parameter.getType() == Integer.class) {
|
||||
return new Object[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
|
||||
} else {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,12 +115,12 @@ public class LaufbauSettings {
|
||||
} else {
|
||||
long count = blockBoundingBoxes.stream().filter(bb -> LaufbauUtils.isDeactivated(p, bb)).count();
|
||||
if (count == 0) {
|
||||
return new SWItem(material, BauSystem.MESSAGE.parse(group, p), Arrays.asList("", BauSystem.MESSAGE.parse("LAUFBAU_SETTINGS_ACTIVE", p), "", BauSystem.MESSAGE.parse("LAUFBAU_SETTINGS_ADVANCED", p), BauSystem.MESSAGE.parse("LAUFBAU_SETTINGS_TOGGLE", p)), false, clickType -> {});
|
||||
return new SWItem(material, group/*BauSystem.MESSAGE.parse(group, p)*/, Arrays.asList("", BauSystem.MESSAGE.parse("LAUFBAU_SETTINGS_ACTIVE", p), "", BauSystem.MESSAGE.parse("LAUFBAU_SETTINGS_ADVANCED", p), BauSystem.MESSAGE.parse("LAUFBAU_SETTINGS_TOGGLE", p)), false, clickType -> {});
|
||||
}
|
||||
if (count == blockBoundingBoxes.size()) {
|
||||
return new SWItem(material, BauSystem.MESSAGE.parse(group, p), Arrays.asList("", BauSystem.MESSAGE.parse("LAUFBAU_SETTINGS_INACTIVE", p), "", BauSystem.MESSAGE.parse("LAUFBAU_SETTINGS_ADVANCED", p), BauSystem.MESSAGE.parse("LAUFBAU_SETTINGS_TOGGLE", p)), false, clickType -> {});
|
||||
return new SWItem(material, group/*BauSystem.MESSAGE.parse(group, p)*/, Arrays.asList("", BauSystem.MESSAGE.parse("LAUFBAU_SETTINGS_INACTIVE", p), "", BauSystem.MESSAGE.parse("LAUFBAU_SETTINGS_ADVANCED", p), BauSystem.MESSAGE.parse("LAUFBAU_SETTINGS_TOGGLE", p)), false, clickType -> {});
|
||||
}
|
||||
return new SWItem(material, BauSystem.MESSAGE.parse(group, p), Arrays.asList("", BauSystem.MESSAGE.parse("LAUFBAU_SETTINGS_MIXED", p, blockBoundingBoxes.size() - count, blockBoundingBoxes.size()), "", BauSystem.MESSAGE.parse("LAUFBAU_SETTINGS_ADVANCED", p), BauSystem.MESSAGE.parse("LAUFBAU_SETTINGS_TOGGLE", p)), false, clickType -> {});
|
||||
return new SWItem(material, group/*BauSystem.MESSAGE.parse(group, p)*/, Arrays.asList("", BauSystem.MESSAGE.parse("LAUFBAU_SETTINGS_MIXED", p, blockBoundingBoxes.size() - count, blockBoundingBoxes.size()), "", BauSystem.MESSAGE.parse("LAUFBAU_SETTINGS_ADVANCED", p), BauSystem.MESSAGE.parse("LAUFBAU_SETTINGS_TOGGLE", p)), false, clickType -> {});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,17 +20,14 @@
|
||||
package de.steamwar.bausystem.features.slaves.laufbau;
|
||||
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.core.SWPlayer;
|
||||
import de.steamwar.inventory.SWItem;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import de.steamwar.sql.UserConfig;
|
||||
import lombok.Cleanup;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import yapion.hierarchy.output.StreamOutput;
|
||||
import yapion.hierarchy.types.YAPIONObject;
|
||||
@@ -39,44 +36,45 @@ import yapion.parser.options.StreamOptions;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
@Linked
|
||||
public class LaufbauUtils implements Listener {
|
||||
@UtilityClass
|
||||
public class LaufbauUtils {
|
||||
|
||||
private static Map<Player, YAPIONObject> yapionObjectMap = new HashMap<>();
|
||||
public static class LaufbauComponent implements SWPlayer.Component {
|
||||
|
||||
@EventHandler
|
||||
@SneakyThrows
|
||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||
String config = UserConfig.getConfig(event.getPlayer().getUniqueId(), "bausystem-laufbau");
|
||||
if (config == null) {
|
||||
return;
|
||||
}
|
||||
byte[] bytes = Base64.getDecoder().decode(config);
|
||||
@Cleanup GZIPInputStream gzipInputStream = new GZIPInputStream(new ByteArrayInputStream(bytes));
|
||||
YAPIONObject yapionObject = new YAPIONParser(gzipInputStream, new StreamOptions().stopOnStreamEnd(true)).parse().result();
|
||||
yapionObjectMap.put(event.getPlayer(), yapionObject);
|
||||
}
|
||||
private YAPIONObject yapionObject = new YAPIONObject();
|
||||
|
||||
@EventHandler
|
||||
@SneakyThrows
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
YAPIONObject yapionObject = yapionObjectMap.get(event.getPlayer());
|
||||
if (yapionObject == null) {
|
||||
return;
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public void onMount(SWPlayer player) {
|
||||
String config = UserConfig.getConfig(player.getPlayer().getUniqueId(), "bausystem-laufbau");
|
||||
if (config == null) {
|
||||
return;
|
||||
}
|
||||
byte[] bytes = Base64.getDecoder().decode(config);
|
||||
@Cleanup GZIPInputStream gzipInputStream = new GZIPInputStream(new ByteArrayInputStream(bytes));
|
||||
yapionObject = new YAPIONParser(gzipInputStream, new StreamOptions().stopOnStreamEnd(true)).parse().result();
|
||||
}
|
||||
if (yapionObject.isEmpty()) {
|
||||
UserConfig.removePlayerConfig(event.getPlayer().getUniqueId(), "bausystem-laufbau");
|
||||
return;
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public void onUnmount(SWPlayer player) {
|
||||
if (yapionObject.isEmpty()) {
|
||||
UserConfig.removePlayerConfig(player.getPlayer().getUniqueId(), "bausystem-laufbau");
|
||||
return;
|
||||
}
|
||||
@Cleanup ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
@Cleanup GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream);
|
||||
yapionObject.toYAPION(new StreamOutput(gzipOutputStream)).close();
|
||||
UserConfig.updatePlayerConfig(player.getPlayer().getUniqueId(), "bausystem-laufbau", Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray()));
|
||||
}
|
||||
@Cleanup ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
@Cleanup GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream);
|
||||
yapionObject.toYAPION(new StreamOutput(gzipOutputStream)).close();
|
||||
UserConfig.updatePlayerConfig(event.getPlayer().getUniqueId(), "bausystem-laufbau", Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray()));
|
||||
}
|
||||
|
||||
public static Cuboid pixelCuboid(double pixelX, double pixelY, double pixelZ, double pixelDX, double pixelDY, double pixelDZ) {
|
||||
@@ -93,6 +91,7 @@ public class LaufbauUtils implements Listener {
|
||||
}
|
||||
|
||||
public static SWItem translateItem(SWItem item, Player p) {
|
||||
if (true) return item;
|
||||
ItemMeta itemMeta = item.getItemMeta();
|
||||
List<String> lore = new ArrayList<>();
|
||||
if (itemMeta.getLore() != null) {
|
||||
@@ -121,28 +120,22 @@ public class LaufbauUtils implements Listener {
|
||||
|
||||
@SneakyThrows
|
||||
public static boolean isDeactivated(Player p, BlockBoundingBox bb) {
|
||||
if (true) return false;
|
||||
if (bb.getSwItem() == null) {
|
||||
return false;
|
||||
}
|
||||
String identifier = identifier(bb);
|
||||
YAPIONObject yapionObject = yapionObjectMap.get(p);
|
||||
if (yapionObject == null) {
|
||||
return false;
|
||||
}
|
||||
return yapionObject.containsKey(identifier);
|
||||
return SWPlayer.of(p).getComponentOrDefault(LaufbauComponent.class, LaufbauComponent::new).yapionObject.containsKey(identifier);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static void toggle(Player p, BlockBoundingBox bb) {
|
||||
if (true) return;
|
||||
if (bb.getSwItem() == null) {
|
||||
return;
|
||||
}
|
||||
String identifier = identifier(bb);
|
||||
YAPIONObject yapionObject = yapionObjectMap.get(p);
|
||||
if (yapionObject == null) {
|
||||
yapionObject = new YAPIONObject();
|
||||
yapionObjectMap.put(p, yapionObject);
|
||||
}
|
||||
YAPIONObject yapionObject = SWPlayer.of(p).getComponentOrDefault(LaufbauComponent.class, LaufbauComponent::new).yapionObject;
|
||||
if (yapionObject.containsKey(identifier)) {
|
||||
yapionObject.remove(identifier);
|
||||
} else {
|
||||
|
||||
@@ -1,263 +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.bausystem.features.slaves.laufbau.boundingboxes;
|
||||
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import de.steamwar.linkage.MinVersion;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.type.AmethystCluster;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
|
||||
|
||||
@Linked
|
||||
@MinVersion(19)
|
||||
public class AmethystBoundingBox implements BoundingBoxLoader {
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
floorSmallAmethystBud();
|
||||
ceilingSmallAmethystBud();
|
||||
northSmallAmethystBud();
|
||||
southSmallAmethystBud();
|
||||
eastSmallAmethystBud();
|
||||
westSmallAmethystBud();
|
||||
|
||||
floorMediumAmethystBud();
|
||||
ceilingMediumAmethystBud();
|
||||
northMediumAmethystBud();
|
||||
southMediumAmethystBud();
|
||||
eastMediumAmethystBud();
|
||||
westMediumAmethystBud();
|
||||
|
||||
floorLargeAmethystBud();
|
||||
ceilingLargeAmethystBud();
|
||||
northLargeAmethystBud();
|
||||
southLargeAmethystBud();
|
||||
eastLargeAmethystBud();
|
||||
westLargeAmethystBud();
|
||||
|
||||
floorAmethystCluster();
|
||||
ceilingAmethystCluster();
|
||||
northAmethystCluster();
|
||||
southAmethystCluster();
|
||||
eastAmethystCluster();
|
||||
westAmethystCluster();
|
||||
}
|
||||
|
||||
private void floorSmallAmethystBud() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.SMALL_AMETHYST_BUD.createBlockData();
|
||||
cluster.setFacing(BlockFace.UP);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(4, 0, 4, 8, 3, 8));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_SMALL_AMETHYST_BUD", Material.SMALL_AMETHYST_BUD, "LAUFBAU_FACING_UP"));
|
||||
}
|
||||
|
||||
private void ceilingSmallAmethystBud() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.SMALL_AMETHYST_BUD.createBlockData();
|
||||
cluster.setFacing(BlockFace.DOWN);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(4, 13, 4, 8, 3, 8));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_SMALL_AMETHYST_BUD", Material.SMALL_AMETHYST_BUD, "LAUFBAU_FACING_DOWN"));
|
||||
}
|
||||
|
||||
private void northSmallAmethystBud() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.SMALL_AMETHYST_BUD.createBlockData();
|
||||
cluster.setFacing(BlockFace.NORTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(4, 4, 13, 8, 8, 3));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_SMALL_AMETHYST_BUD", Material.SMALL_AMETHYST_BUD, "LAUFBAU_FACING_NORTH"));
|
||||
}
|
||||
|
||||
private void southSmallAmethystBud() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.SMALL_AMETHYST_BUD.createBlockData();
|
||||
cluster.setFacing(BlockFace.SOUTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(4, 4, 0, 8, 8, 3));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_SMALL_AMETHYST_BUD", Material.SMALL_AMETHYST_BUD, "LAUFBAU_FACING_SOUTH"));
|
||||
}
|
||||
|
||||
private void eastSmallAmethystBud() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.SMALL_AMETHYST_BUD.createBlockData();
|
||||
cluster.setFacing(BlockFace.EAST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 4, 4, 3, 8, 8));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_SMALL_AMETHYST_BUD", Material.SMALL_AMETHYST_BUD, "LAUFBAU_FACING_EAST"));
|
||||
}
|
||||
|
||||
private void westSmallAmethystBud() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.SMALL_AMETHYST_BUD.createBlockData();
|
||||
cluster.setFacing(BlockFace.WEST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(13, 4, 4, 3, 8, 8));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_SMALL_AMETHYST_BUD", Material.SMALL_AMETHYST_BUD, "LAUFBAU_FACING_WEST"));
|
||||
}
|
||||
|
||||
private void floorMediumAmethystBud() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.MEDIUM_AMETHYST_BUD.createBlockData();
|
||||
cluster.setFacing(BlockFace.UP);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(3, 0, 3, 10, 4, 10));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_MEDIUM_AMETHYST_BUD", Material.MEDIUM_AMETHYST_BUD, "LAUFBAU_FACING_UP"));
|
||||
}
|
||||
|
||||
private void ceilingMediumAmethystBud() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.MEDIUM_AMETHYST_BUD.createBlockData();
|
||||
cluster.setFacing(BlockFace.DOWN);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(3, 12, 3, 10, 4, 10));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_MEDIUM_AMETHYST_BUD", Material.MEDIUM_AMETHYST_BUD, "LAUFBAU_FACING_DOWN"));
|
||||
}
|
||||
|
||||
private void northMediumAmethystBud() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.MEDIUM_AMETHYST_BUD.createBlockData();
|
||||
cluster.setFacing(BlockFace.NORTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(3, 3, 12, 10, 10, 4));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_MEDIUM_AMETHYST_BUD", Material.MEDIUM_AMETHYST_BUD, "LAUFBAU_FACING_NORTH"));
|
||||
}
|
||||
|
||||
private void southMediumAmethystBud() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.MEDIUM_AMETHYST_BUD.createBlockData();
|
||||
cluster.setFacing(BlockFace.SOUTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(3, 3, 0, 10, 10, 4));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_MEDIUM_AMETHYST_BUD", Material.MEDIUM_AMETHYST_BUD, "LAUFBAU_FACING_SOUTH"));
|
||||
}
|
||||
|
||||
private void eastMediumAmethystBud() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.MEDIUM_AMETHYST_BUD.createBlockData();
|
||||
cluster.setFacing(BlockFace.EAST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 3, 3, 4, 10, 10));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_MEDIUM_AMETHYST_BUD", Material.MEDIUM_AMETHYST_BUD, "LAUFBAU_FACING_EAST"));
|
||||
}
|
||||
|
||||
private void westMediumAmethystBud() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.MEDIUM_AMETHYST_BUD.createBlockData();
|
||||
cluster.setFacing(BlockFace.WEST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(12, 3, 3, 4, 10, 10));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_MEDIUM_AMETHYST_BUD", Material.MEDIUM_AMETHYST_BUD, "LAUFBAU_FACING_WEST"));
|
||||
}
|
||||
|
||||
private void floorLargeAmethystBud() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.LARGE_AMETHYST_BUD.createBlockData();
|
||||
cluster.setFacing(BlockFace.UP);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(3, 0, 3, 10, 5, 10));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_LARGE_AMETHYST_BUD", Material.LARGE_AMETHYST_BUD, "LAUFBAU_FACING_UP"));
|
||||
}
|
||||
|
||||
private void ceilingLargeAmethystBud() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.LARGE_AMETHYST_BUD.createBlockData();
|
||||
cluster.setFacing(BlockFace.DOWN);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(3, 11, 3, 10, 5, 10));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_LARGE_AMETHYST_BUD", Material.LARGE_AMETHYST_BUD, "LAUFBAU_FACING_DOWN"));
|
||||
}
|
||||
|
||||
private void northLargeAmethystBud() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.LARGE_AMETHYST_BUD.createBlockData();
|
||||
cluster.setFacing(BlockFace.NORTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(3, 3, 11, 10, 10, 5));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_LARGE_AMETHYST_BUD", Material.LARGE_AMETHYST_BUD, "LAUFBAU_FACING_NORTH"));
|
||||
}
|
||||
|
||||
private void southLargeAmethystBud() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.LARGE_AMETHYST_BUD.createBlockData();
|
||||
cluster.setFacing(BlockFace.SOUTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(3, 3, 0, 10, 10, 5));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_LARGE_AMETHYST_BUD", Material.LARGE_AMETHYST_BUD, "LAUFBAU_FACING_SOUTH"));
|
||||
}
|
||||
|
||||
private void eastLargeAmethystBud() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.LARGE_AMETHYST_BUD.createBlockData();
|
||||
cluster.setFacing(BlockFace.EAST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 3, 3, 5, 10, 10));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_LARGE_AMETHYST_BUD", Material.LARGE_AMETHYST_BUD, "LAUFBAU_FACING_EAST"));
|
||||
}
|
||||
|
||||
private void westLargeAmethystBud() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.LARGE_AMETHYST_BUD.createBlockData();
|
||||
cluster.setFacing(BlockFace.WEST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(11, 3, 3, 5, 10, 10));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_LARGE_AMETHYST_BUD", Material.LARGE_AMETHYST_BUD, "LAUFBAU_FACING_WEST"));
|
||||
}
|
||||
|
||||
private void floorAmethystCluster() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.AMETHYST_CLUSTER.createBlockData();
|
||||
cluster.setFacing(BlockFace.UP);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(3, 0, 3, 10, 7, 10));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_AMETHYST_CLUSTER", Material.AMETHYST_CLUSTER, "LAUFBAU_FACING_UP"));
|
||||
}
|
||||
|
||||
private void ceilingAmethystCluster() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.AMETHYST_CLUSTER.createBlockData();
|
||||
cluster.setFacing(BlockFace.DOWN);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(3, 9, 3, 10, 7, 10));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_AMETHYST_CLUSTER", Material.AMETHYST_CLUSTER, "LAUFBAU_FACING_DOWN"));
|
||||
}
|
||||
|
||||
private void northAmethystCluster() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.AMETHYST_CLUSTER.createBlockData();
|
||||
cluster.setFacing(BlockFace.NORTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(3, 3, 9, 10, 10, 7));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_AMETHYST_CLUSTER", Material.AMETHYST_CLUSTER, "LAUFBAU_FACING_NORTH"));
|
||||
}
|
||||
|
||||
private void southAmethystCluster() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.AMETHYST_CLUSTER.createBlockData();
|
||||
cluster.setFacing(BlockFace.SOUTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(3, 3, 0, 10, 10, 7));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_AMETHYST_CLUSTER", Material.AMETHYST_CLUSTER, "LAUFBAU_FACING_SOUTH"));
|
||||
}
|
||||
|
||||
private void eastAmethystCluster() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.AMETHYST_CLUSTER.createBlockData();
|
||||
cluster.setFacing(BlockFace.EAST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 3, 3, 7, 10, 10));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_AMETHYST_CLUSTER", Material.AMETHYST_CLUSTER, "LAUFBAU_FACING_EAST"));
|
||||
}
|
||||
|
||||
private void westAmethystCluster() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.AMETHYST_CLUSTER.createBlockData();
|
||||
cluster.setFacing(BlockFace.WEST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(9, 3, 3, 7, 10, 10));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_AMETHYST_CLUSTER", Material.AMETHYST_CLUSTER, "LAUFBAU_FACING_WEST"));
|
||||
}
|
||||
}
|
||||
@@ -1,48 +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.bausystem.features.slaves.laufbau.boundingboxes;
|
||||
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import de.steamwar.linkage.MinVersion;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
|
||||
|
||||
@Linked
|
||||
@MinVersion(19)
|
||||
public class AzaleaBoundingBox implements BoundingBoxLoader {
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
BlockData blockData = Material.FLOWERING_AZALEA.createBlockData();
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(6, 0, 6, 4, 8, 4));
|
||||
new BlockBoundingBox(blockData, cuboidList, createItem("LAUFBAU_BLOCK_AZALEA", Material.FLOWERING_AZALEA));
|
||||
}
|
||||
}
|
||||
@@ -1,149 +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.bausystem.features.slaves.laufbau.boundingboxes;
|
||||
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.type.Bell;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
|
||||
|
||||
@Linked
|
||||
public class BellBoundingBox implements BoundingBoxLoader {
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
ceilingBell();
|
||||
|
||||
floorNorthBell();
|
||||
floorEastBell();
|
||||
|
||||
doubleWallNorthBell();
|
||||
doubleWallEastBell();
|
||||
|
||||
singleWallNorthBell();
|
||||
singleWallSouthBell();
|
||||
singleWallEastBell();
|
||||
singleWallWestBell();
|
||||
}
|
||||
|
||||
public void ceilingBell() {
|
||||
Bell bell = (Bell) Material.BELL.createBlockData();
|
||||
bell.setAttachment(Bell.Attachment.CEILING);
|
||||
bell.setFacing(BlockFace.NORTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(4, 4, 4, 8, 2, 8));
|
||||
cuboidList.add(pixelCuboid(5, 6, 5, 6, 8, 6));
|
||||
cuboidList.add(pixelCuboid(7, 13, 7, 2, 3, 2));
|
||||
new BlockBoundingBox(bell, cuboidList, createItem("LAUFBAU_BLOCK_BELL", Material.BELL, "LAUFBAU_ATTACHMENT_CEILING"));
|
||||
}
|
||||
|
||||
public void floorNorthBell() {
|
||||
Bell bell = (Bell) Material.BELL.createBlockData();
|
||||
bell.setAttachment(Bell.Attachment.FLOOR);
|
||||
bell.setFacing(BlockFace.NORTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 0, 4, 16, 16, 8));
|
||||
new BlockBoundingBox(bell, cuboidList, createItem("LAUFBAU_BLOCK_BELL", Material.BELL, "LAUFBAU_ATTACHMENT_FLOOR", "LAUFBAU_FACING_NORTH", "LAUFBAU_FACING_SOUTH"));
|
||||
}
|
||||
|
||||
public void floorEastBell() {
|
||||
Bell bell = (Bell) Material.BELL.createBlockData();
|
||||
bell.setAttachment(Bell.Attachment.FLOOR);
|
||||
bell.setFacing(BlockFace.EAST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(4, 0, 0, 8, 16, 16));
|
||||
new BlockBoundingBox(bell, cuboidList, createItem("LAUFBAU_BLOCK_BELL", Material.BELL, "LAUFBAU_ATTACHMENT_FLOOR", "LAUFBAU_FACING_EAST", "LAUFBAU_FACING_WEST"));
|
||||
}
|
||||
|
||||
public void doubleWallNorthBell() {
|
||||
Bell bell = (Bell) Material.BELL.createBlockData();
|
||||
bell.setAttachment(Bell.Attachment.DOUBLE_WALL);
|
||||
bell.setFacing(BlockFace.NORTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(4, 4, 4, 8, 2, 8));
|
||||
cuboidList.add(pixelCuboid(5, 6, 5, 6, 8, 6));
|
||||
cuboidList.add(pixelCuboid(7, 13, 0, 2, 2, 16));
|
||||
new BlockBoundingBox(bell, cuboidList, createItem("LAUFBAU_BLOCK_BELL", Material.BELL, "LAUFBAU_ATTACHMENT_DOUBLE_WALL", "LAUFBAU_FACING_NORTH"));
|
||||
}
|
||||
|
||||
public void doubleWallEastBell() {
|
||||
Bell bell = (Bell) Material.BELL.createBlockData();
|
||||
bell.setAttachment(Bell.Attachment.DOUBLE_WALL);
|
||||
bell.setFacing(BlockFace.EAST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(4, 4, 4, 8, 2, 8));
|
||||
cuboidList.add(pixelCuboid(5, 6, 5, 6, 8, 6));
|
||||
cuboidList.add(pixelCuboid(0, 13, 7, 16, 2, 2));
|
||||
new BlockBoundingBox(bell, cuboidList, createItem("LAUFBAU_BLOCK_BELL", Material.BELL, "LAUFBAU_ATTACHMENT_DOUBLE_WALL", "LAUFBAU_FACING_EAST"));
|
||||
}
|
||||
|
||||
public void singleWallNorthBell() {
|
||||
Bell bell = (Bell) Material.BELL.createBlockData();
|
||||
bell.setAttachment(Bell.Attachment.SINGLE_WALL);
|
||||
bell.setFacing(BlockFace.NORTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(4, 4, 4, 8, 2, 8));
|
||||
cuboidList.add(pixelCuboid(5, 6, 5, 6, 8, 6));
|
||||
cuboidList.add(pixelCuboid(7, 13, 0, 2, 2, 13));
|
||||
new BlockBoundingBox(bell, cuboidList, createItem("LAUFBAU_BLOCK_BELL", Material.BELL, "LAUFBAU_ATTACHMENT_SINGLE_WALL", "LAUFBAU_FACING_NORTH"));
|
||||
}
|
||||
|
||||
public void singleWallSouthBell() {
|
||||
Bell bell = (Bell) Material.BELL.createBlockData();
|
||||
bell.setAttachment(Bell.Attachment.SINGLE_WALL);
|
||||
bell.setFacing(BlockFace.SOUTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(4, 4, 4, 8, 2, 8));
|
||||
cuboidList.add(pixelCuboid(5, 6, 5, 6, 8, 6));
|
||||
cuboidList.add(pixelCuboid(7, 13, 3, 2, 2, 13));
|
||||
new BlockBoundingBox(bell, cuboidList, createItem("LAUFBAU_BLOCK_BELL", Material.BELL, "LAUFBAU_ATTACHMENT_SINGLE_WALL", "LAUFBAU_FACING_SOUTH"));
|
||||
}
|
||||
|
||||
public void singleWallEastBell() {
|
||||
Bell bell = (Bell) Material.BELL.createBlockData();
|
||||
bell.setAttachment(Bell.Attachment.SINGLE_WALL);
|
||||
bell.setFacing(BlockFace.EAST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(4, 4, 4, 8, 2, 8));
|
||||
cuboidList.add(pixelCuboid(5, 6, 5, 6, 8, 6));
|
||||
cuboidList.add(pixelCuboid(3, 13, 7, 13, 2, 2));
|
||||
new BlockBoundingBox(bell, cuboidList, createItem("LAUFBAU_BLOCK_BELL", Material.BELL, "LAUFBAU_ATTACHMENT_SINGLE_WALL", "LAUFBAU_FACING_EAST"));
|
||||
}
|
||||
|
||||
public void singleWallWestBell() {
|
||||
Bell bell = (Bell) Material.BELL.createBlockData();
|
||||
bell.setAttachment(Bell.Attachment.SINGLE_WALL);
|
||||
bell.setFacing(BlockFace.WEST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(4, 4, 4, 8, 2, 8));
|
||||
cuboidList.add(pixelCuboid(5, 6, 5, 6, 8, 6));
|
||||
cuboidList.add(pixelCuboid(0, 13, 7, 13, 2, 2));
|
||||
new BlockBoundingBox(bell, cuboidList, createItem("LAUFBAU_BLOCK_BELL", Material.BELL, "LAUFBAU_ATTACHMENT_SINGLE_WALL", "LAUFBAU_FACING_WEST"));
|
||||
}
|
||||
}
|
||||
@@ -1,46 +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.bausystem.features.slaves.laufbau.boundingboxes;
|
||||
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.data.type.BrewingStand;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
|
||||
|
||||
@Linked
|
||||
public class BrewingStandBoundingBox implements BoundingBoxLoader {
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
BrewingStand brewingStand = (BrewingStand) Material.BREWING_STAND.createBlockData();
|
||||
List<Cuboid> cuboids = new ArrayList<>();
|
||||
cuboids.add(pixelCuboid(1, 0, 1, 14, 2, 14));
|
||||
cuboids.add(pixelCuboid(7, 2, 7, 2, 12, 2));
|
||||
new BlockBoundingBox(brewingStand, cuboids, createItem("LAUFBAU_BLOCK_BREWING_STAND", Material.BREWING_STAND));
|
||||
}
|
||||
}
|
||||
@@ -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.bausystem.features.slaves.laufbau.boundingboxes;
|
||||
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import de.steamwar.linkage.MinVersion;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.data.Lightable;
|
||||
import org.bukkit.block.data.type.Candle;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
|
||||
|
||||
@Linked
|
||||
@MinVersion(19)
|
||||
public class CandleBoundingBox implements BoundingBoxLoader {
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
caked();
|
||||
|
||||
single();
|
||||
}
|
||||
|
||||
private void caked() {
|
||||
Lightable candleCake = (Lightable) Material.CYAN_CANDLE_CAKE.createBlockData();
|
||||
candleCake.setLit(true);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(7, 8, 7, 2, 6, 2));
|
||||
new BlockBoundingBox(candleCake, cuboidList, createItem("LAUFBAU_BLOCK_CANDLE_CAKE", Material.CAKE));
|
||||
}
|
||||
|
||||
private void single() {
|
||||
Candle candle = (Candle) Material.CYAN_CANDLE.createBlockData();
|
||||
candle.setCandles(1);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(7, 0,7, 2, 6, 2));
|
||||
new BlockBoundingBox(candle, cuboidList, createItem("LAUFBAU_BLOCK_CANDLE", Material.CYAN_CANDLE, "LAUFBAU_COUNT_1"));
|
||||
}
|
||||
}
|
||||
@@ -1,71 +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.bausystem.features.slaves.laufbau.boundingboxes;
|
||||
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import de.steamwar.linkage.MinVersion;
|
||||
import org.bukkit.Axis;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.data.Orientable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
|
||||
|
||||
@Linked
|
||||
@MinVersion(19)
|
||||
public class ChainBoundingBox implements BoundingBoxLoader {
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
bottomTopChain();
|
||||
northSouthChain();
|
||||
eastWestChain();
|
||||
}
|
||||
|
||||
private void bottomTopChain() {
|
||||
Orientable chainBottomTop = (Orientable) Material.CHAIN.createBlockData();
|
||||
chainBottomTop.setAxis(Axis.Y);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(6.5, 0, 6.5, 3, 16, 3));
|
||||
new BlockBoundingBox(chainBottomTop, cuboidList, createItem("LAUFBAU_BLOCK_CHAIN", Material.CHAIN, "LAUFBAU_FACING_UP", "LAUFBAU_FACING_DOWN"));
|
||||
}
|
||||
|
||||
private void northSouthChain() {
|
||||
Orientable chainBottomTop = (Orientable) Material.CHAIN.createBlockData();
|
||||
chainBottomTop.setAxis(Axis.Z);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(6.5, 6.5, 0, 3, 3, 16));
|
||||
new BlockBoundingBox(chainBottomTop, cuboidList, createItem("LAUFBAU_BLOCK_CHAIN", Material.CHAIN, "LAUFBAU_FACING_NORTH", "LAUFBAU_FACING_SOUTH"));
|
||||
}
|
||||
|
||||
private void eastWestChain() {
|
||||
Orientable chainBottomTop = (Orientable) Material.CHAIN.createBlockData();
|
||||
chainBottomTop.setAxis(Axis.X);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 6.5, 6.5, 16, 3, 3));
|
||||
new BlockBoundingBox(chainBottomTop, cuboidList, createItem("LAUFBAU_BLOCK_CHAIN", Material.CHAIN, "LAUFBAU_FACING_EAST", "LAUFBAU_FACING_WEST"));
|
||||
}
|
||||
}
|
||||
@@ -1,89 +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.bausystem.features.slaves.laufbau.boundingboxes;
|
||||
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.MultipleFacing;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
|
||||
|
||||
@Linked
|
||||
public class ChorusPlantBoundingBox implements BoundingBoxLoader {
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
for (int nx = 0; nx < 2; nx++) {
|
||||
for (int ny = 0; ny < 2; ny++) {
|
||||
for (int nz = 0; nz < 2; nz++) {
|
||||
for (int px = 0; px < 2; px++) {
|
||||
for (int py = 0; py < 2; py++) {
|
||||
for (int pz = 0; pz < 2; pz++) {
|
||||
MultipleFacing chorusPlant = (MultipleFacing) Material.CHORUS_PLANT.createBlockData();
|
||||
List<String> lore = new ArrayList<>();
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(3, 3, 3, 10, 10, 10));
|
||||
if (nx == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_WEST");
|
||||
chorusPlant.setFace(BlockFace.WEST, true);
|
||||
cuboidList.add(pixelCuboid(0, 3, 3, 3, 10, 10));
|
||||
}
|
||||
if (ny == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_DOWN");
|
||||
chorusPlant.setFace(BlockFace.DOWN, true);
|
||||
cuboidList.add(pixelCuboid(3, 0, 3, 10, 3, 10));
|
||||
}
|
||||
if (nz == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_NORTH");
|
||||
chorusPlant.setFace(BlockFace.NORTH, true);
|
||||
cuboidList.add(pixelCuboid(3, 3, 0, 10, 10, 3));
|
||||
}
|
||||
if (px == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_EAST");
|
||||
chorusPlant.setFace(BlockFace.EAST, true);
|
||||
cuboidList.add(pixelCuboid(13, 3, 3, 3, 10, 10));
|
||||
}
|
||||
if (py == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_UP");
|
||||
chorusPlant.setFace(BlockFace.UP, true);
|
||||
cuboidList.add(pixelCuboid(3, 13, 3, 10, 3, 10));
|
||||
}
|
||||
if (pz == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_SOUTH");
|
||||
chorusPlant.setFace(BlockFace.SOUTH, true);
|
||||
cuboidList.add(pixelCuboid(3, 3, 13, 10, 10, 3));
|
||||
}
|
||||
new BlockBoundingBox(chorusPlant, cuboidList, createItem("LAUFBAU_BLOCK_CHORUS_PLANT", Material.CHORUS_PLANT, lore.toArray(new String[0])));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,47 +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.bausystem.features.slaves.laufbau.boundingboxes;
|
||||
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import de.steamwar.linkage.MinVersion;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
|
||||
|
||||
@Linked
|
||||
@MinVersion(19)
|
||||
public class DragonEggBoundingBox implements BoundingBoxLoader {
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
BlockData blockData = Material.DRAGON_EGG.createBlockData();
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(1, 0, 1, 14, 16, 14));
|
||||
new BlockBoundingBox(blockData, cuboidList, createItem("LAUFBAU_BLOCK_DRAGON_EGG", Material.DRAGON_EGG));
|
||||
}
|
||||
}
|
||||
@@ -1,61 +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.bausystem.features.slaves.laufbau.boundingboxes;
|
||||
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import de.steamwar.linkage.MinVersion;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.data.type.BigDripleaf;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
|
||||
|
||||
@Linked
|
||||
@MinVersion(19)
|
||||
public class DripLeafBoundingBox implements BoundingBoxLoader {
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
tiltNone();
|
||||
tiltPartial();
|
||||
}
|
||||
|
||||
private void tiltNone() {
|
||||
BigDripleaf bigDripleaf = (BigDripleaf) Material.BIG_DRIPLEAF.createBlockData();
|
||||
bigDripleaf.setTilt(BigDripleaf.Tilt.NONE);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 11, 0, 16, 4, 16));
|
||||
new BlockBoundingBox(bigDripleaf, cuboidList, createItem("LAUFBAU_BLOCK_BIG_DRIP_LEAF", Material.BIG_DRIPLEAF, "LAUFBAU_TILT_NONE"));
|
||||
}
|
||||
|
||||
private void tiltPartial() {
|
||||
BigDripleaf bigDripleaf = (BigDripleaf) Material.BIG_DRIPLEAF.createBlockData();
|
||||
bigDripleaf.setTilt(BigDripleaf.Tilt.PARTIAL);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 11, 0, 16, 2, 16));
|
||||
new BlockBoundingBox(bigDripleaf, cuboidList, createItem("LAUFBAU_BLOCK_BIG_DRIP_LEAF", Material.BIG_DRIPLEAF, "LAUFBAU_TILT_PARTIAL"));
|
||||
}
|
||||
}
|
||||
@@ -1,75 +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.bausystem.features.slaves.laufbau.boundingboxes;
|
||||
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.type.Fence;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
|
||||
|
||||
@Linked
|
||||
public class FencesBoundingBox implements BoundingBoxLoader {
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
for (int nx = 0; nx < 2; nx++) {
|
||||
for (int nz = 0; nz < 2; nz++) {
|
||||
for (int px = 0; px < 2; px++) {
|
||||
for (int pz = 0; pz < 2; pz++) {
|
||||
Fence fence = (Fence) Material.NETHER_BRICK_FENCE.createBlockData();
|
||||
List<String> lore = new ArrayList<>();
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(6, 0, 6, 4, 24, 4));
|
||||
if (nz == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_NORTH");
|
||||
fence.setFace(BlockFace.NORTH, true);
|
||||
cuboidList.add(pixelCuboid(6, 0, 0, 4, 24, 6));
|
||||
}
|
||||
if (pz == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_SOUTH");
|
||||
fence.setFace(BlockFace.SOUTH, true);
|
||||
cuboidList.add(pixelCuboid(6, 0, 10, 4, 24, 6));
|
||||
}
|
||||
if (nx == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_WEST");
|
||||
fence.setFace(BlockFace.WEST, true);
|
||||
cuboidList.add(pixelCuboid(0, 0, 6, 6, 24, 4));
|
||||
}
|
||||
if (px == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_EAST");
|
||||
fence.setFace(BlockFace.EAST, true);
|
||||
cuboidList.add(pixelCuboid(10, 0, 6, 6, 24, 4));
|
||||
}
|
||||
new BlockBoundingBox(fence, cuboidList, createItem("LAUFBAU_BLOCK_NETHER_BRICK_FENCE", Material.NETHER_BRICK_FENCE, lore.toArray(new String[0])));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,157 +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.bausystem.features.slaves.laufbau.boundingboxes;
|
||||
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.FaceAttachable;
|
||||
import org.bukkit.block.data.type.Grindstone;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
|
||||
|
||||
@Linked
|
||||
public class GrindstoneBoundingBox implements BoundingBoxLoader {
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
floorNorthGrindstone();
|
||||
floorEastGrindstone();
|
||||
|
||||
ceilingNorthGrindstone();
|
||||
ceilingEastGrindstone();
|
||||
|
||||
wallNorthGrindstone();
|
||||
wallSouthGrindstone();
|
||||
wallEastGrindstone();
|
||||
wallWestGrindstone();
|
||||
}
|
||||
|
||||
public void floorNorthGrindstone() {
|
||||
Grindstone grindstone = (Grindstone) Material.GRINDSTONE.createBlockData();
|
||||
grindstone.setAttachedFace(FaceAttachable.AttachedFace.FLOOR);
|
||||
grindstone.setFacing(BlockFace.NORTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(4, 4, 2, 8, 12, 12));
|
||||
cuboidList.add(pixelCuboid(2, 0, 6, 2, 7, 4));
|
||||
cuboidList.add(pixelCuboid(12, 0, 6, 2, 7, 4));
|
||||
cuboidList.add(pixelCuboid(2, 7, 5, 2, 6, 6));
|
||||
cuboidList.add(pixelCuboid(12, 7, 5, 2, 6, 6));
|
||||
new BlockBoundingBox(grindstone, cuboidList, createItem("LAUFBAU_BLOCK_GRINDSTONE", Material.GRINDSTONE, "LAUFBAU_ATTACHMENT_FLOOR", "LAUFBAU_FACING_NORTH", "LAUFBAU_FACING_SOUTH"));
|
||||
}
|
||||
|
||||
public void floorEastGrindstone() {
|
||||
Grindstone grindstone = (Grindstone) Material.GRINDSTONE.createBlockData();
|
||||
grindstone.setAttachedFace(FaceAttachable.AttachedFace.FLOOR);
|
||||
grindstone.setFacing(BlockFace.EAST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(2, 4, 4, 12, 12, 8));
|
||||
cuboidList.add(pixelCuboid(6, 0, 2, 4, 7, 2));
|
||||
cuboidList.add(pixelCuboid(6, 0, 12, 4, 7, 2));
|
||||
cuboidList.add(pixelCuboid(5, 7, 2, 6, 6, 2));
|
||||
cuboidList.add(pixelCuboid(5, 7, 12, 6, 6, 2));
|
||||
new BlockBoundingBox(grindstone, cuboidList, createItem("LAUFBAU_BLOCK_GRINDSTONE", Material.GRINDSTONE, "LAUFBAU_ATTACHMENT_FLOOR", "LAUFBAU_FACING_EAST", "LAUFBAU_FACING_WEST"));
|
||||
}
|
||||
|
||||
public void ceilingNorthGrindstone() {
|
||||
Grindstone grindstone = (Grindstone) Material.GRINDSTONE.createBlockData();
|
||||
grindstone.setAttachedFace(FaceAttachable.AttachedFace.CEILING);
|
||||
grindstone.setFacing(BlockFace.NORTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(4, 0, 2, 8, 12, 12));
|
||||
cuboidList.add(pixelCuboid(2, 9, 6, 2, 7, 4));
|
||||
cuboidList.add(pixelCuboid(12, 9, 6, 2, 7, 4));
|
||||
cuboidList.add(pixelCuboid(2, 3, 5, 2, 6, 6));
|
||||
cuboidList.add(pixelCuboid(12, 3, 5, 2, 6, 6));
|
||||
new BlockBoundingBox(grindstone, cuboidList, createItem("LAUFBAU_BLOCK_GRINDSTONE", Material.GRINDSTONE, "LAUFBAU_ATTACHMENT_CEILING", "LAUFBAU_FACING_NORTH", "LAUFBAU_FACING_SOUTH"));
|
||||
}
|
||||
|
||||
public void ceilingEastGrindstone() {
|
||||
Grindstone grindstone = (Grindstone) Material.GRINDSTONE.createBlockData();
|
||||
grindstone.setAttachedFace(FaceAttachable.AttachedFace.CEILING);
|
||||
grindstone.setFacing(BlockFace.EAST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(2, 0, 4, 12, 12, 8));
|
||||
cuboidList.add(pixelCuboid(6, 9, 2, 4, 7, 2));
|
||||
cuboidList.add(pixelCuboid(6, 9, 12, 4, 7, 2));
|
||||
cuboidList.add(pixelCuboid(5, 3, 2, 6, 6, 2));
|
||||
cuboidList.add(pixelCuboid(5, 3, 12, 6, 6, 2));
|
||||
new BlockBoundingBox(grindstone, cuboidList, createItem("LAUFBAU_BLOCK_GRINDSTONE", Material.GRINDSTONE, "LAUFBAU_ATTACHMENT_CEILING", "LAUFBAU_FACING_EAST", "LAUFBAU_FACING_WEST"));
|
||||
}
|
||||
|
||||
public void wallNorthGrindstone() {
|
||||
Grindstone grindstone = (Grindstone) Material.GRINDSTONE.createBlockData();
|
||||
grindstone.setAttachedFace(FaceAttachable.AttachedFace.WALL);
|
||||
grindstone.setFacing(BlockFace.NORTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(4, 2, 0, 8, 12, 12));
|
||||
cuboidList.add(pixelCuboid(2, 6, 9, 2, 4, 7));
|
||||
cuboidList.add(pixelCuboid(12, 6, 9, 2, 4, 7));
|
||||
cuboidList.add(pixelCuboid(2, 5, 3, 2, 6, 6));
|
||||
cuboidList.add(pixelCuboid(12, 5, 3, 2, 6, 6));
|
||||
new BlockBoundingBox(grindstone, cuboidList, createItem("LAUFBAU_BLOCK_GRINDSTONE", Material.GRINDSTONE, "LAUFBAU_ATTACHMENT_WALL", "LAUFBAU_FACING_NORTH"));
|
||||
}
|
||||
|
||||
public void wallSouthGrindstone() {
|
||||
Grindstone grindstone = (Grindstone) Material.GRINDSTONE.createBlockData();
|
||||
grindstone.setAttachedFace(FaceAttachable.AttachedFace.WALL);
|
||||
grindstone.setFacing(BlockFace.SOUTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(4, 2, 4, 8, 12, 12));
|
||||
cuboidList.add(pixelCuboid(2, 6, 0, 2, 4, 7));
|
||||
cuboidList.add(pixelCuboid(12, 6, 0, 2, 4, 7));
|
||||
cuboidList.add(pixelCuboid(2, 5, 7, 2, 6, 6));
|
||||
cuboidList.add(pixelCuboid(12, 5, 7, 2, 6, 6));
|
||||
new BlockBoundingBox(grindstone, cuboidList, createItem("LAUFBAU_BLOCK_GRINDSTONE", Material.GRINDSTONE, "LAUFBAU_ATTACHMENT_WALL", "LAUFBAU_FACING_SOUTH"));
|
||||
}
|
||||
|
||||
public void wallEastGrindstone() {
|
||||
Grindstone grindstone = (Grindstone) Material.GRINDSTONE.createBlockData();
|
||||
grindstone.setAttachedFace(FaceAttachable.AttachedFace.WALL);
|
||||
grindstone.setFacing(BlockFace.EAST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(4, 2, 4, 12, 12, 8));
|
||||
cuboidList.add(pixelCuboid(0, 6, 2, 7, 4, 2));
|
||||
cuboidList.add(pixelCuboid(0, 6, 12, 7, 4, 2));
|
||||
cuboidList.add(pixelCuboid(7, 5, 2, 6, 6, 2));
|
||||
cuboidList.add(pixelCuboid(7, 5, 12, 6, 6, 2));
|
||||
new BlockBoundingBox(grindstone, cuboidList, createItem("LAUFBAU_BLOCK_GRINDSTONE", Material.GRINDSTONE, "LAUFBAU_ATTACHMENT_WALL", "LAUFBAU_FACING_EAST"));
|
||||
}
|
||||
|
||||
public void wallWestGrindstone() {
|
||||
Grindstone grindstone = (Grindstone) Material.GRINDSTONE.createBlockData();
|
||||
grindstone.setAttachedFace(FaceAttachable.AttachedFace.WALL);
|
||||
grindstone.setFacing(BlockFace.WEST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 2, 4, 12, 12, 8));
|
||||
cuboidList.add(pixelCuboid(9, 6, 2, 7, 4, 2));
|
||||
cuboidList.add(pixelCuboid(9, 6, 12, 7, 4, 2));
|
||||
cuboidList.add(pixelCuboid(3, 5, 2, 6, 6, 2));
|
||||
cuboidList.add(pixelCuboid(3, 5, 12, 6, 6, 2));
|
||||
new BlockBoundingBox(grindstone, cuboidList, createItem("LAUFBAU_BLOCK_GRINDSTONE", Material.GRINDSTONE, "LAUFBAU_ATTACHMENT_WALL", "LAUFBAU_FACING_WEST"));
|
||||
}
|
||||
}
|
||||
@@ -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.bausystem.features.slaves.laufbau.boundingboxes;
|
||||
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.type.Hopper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
|
||||
|
||||
@Linked
|
||||
public class HopperBoundingBox implements BoundingBoxLoader {
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
downHopper();
|
||||
northHopper();
|
||||
southHopper();
|
||||
eastHopper();
|
||||
westHopper();
|
||||
}
|
||||
|
||||
public void downHopper() {
|
||||
Hopper hopper = (Hopper) Material.HOPPER.createBlockData();
|
||||
hopper.setFacing(BlockFace.DOWN);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 10, 0, 16, 6, 16));
|
||||
cuboidList.add(pixelCuboid(4, 4, 4, 8, 6, 8));
|
||||
cuboidList.add(pixelCuboid(6, 0, 6, 4, 4, 4));
|
||||
new BlockBoundingBox(hopper, cuboidList, createItem("LAUFBAU_BLOCK_HOPPER", Material.HOPPER, "LAUFBAU_CONNECTION_FLOOR"));
|
||||
}
|
||||
|
||||
public void northHopper() {
|
||||
Hopper hopper = (Hopper) Material.HOPPER.createBlockData();
|
||||
hopper.setFacing(BlockFace.NORTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 10, 0, 16, 6, 16));
|
||||
cuboidList.add(pixelCuboid(4, 4, 4, 8, 6, 8));
|
||||
cuboidList.add(pixelCuboid(6, 4, 0, 4, 4, 4));
|
||||
new BlockBoundingBox(hopper, cuboidList, createItem("LAUFBAU_BLOCK_HOPPER", Material.HOPPER, "LAUFBAU_CONNECTION_NORTH"));
|
||||
}
|
||||
|
||||
public void southHopper() {
|
||||
Hopper hopper = (Hopper) Material.HOPPER.createBlockData();
|
||||
hopper.setFacing(BlockFace.SOUTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 10, 0, 16, 6, 16));
|
||||
cuboidList.add(pixelCuboid(4, 4, 4, 8, 6, 8));
|
||||
cuboidList.add(pixelCuboid(6, 4, 12, 4, 4, 4));
|
||||
new BlockBoundingBox(hopper, cuboidList, createItem("LAUFBAU_BLOCK_HOPPER", Material.HOPPER, "LAUFBAU_CONNECTION_SOUTH"));
|
||||
}
|
||||
|
||||
public void eastHopper() {
|
||||
Hopper hopper = (Hopper) Material.HOPPER.createBlockData();
|
||||
hopper.setFacing(BlockFace.EAST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 10, 0, 16, 6, 16));
|
||||
cuboidList.add(pixelCuboid(4, 4, 4, 8, 6, 8));
|
||||
cuboidList.add(pixelCuboid(12, 4, 6, 4, 4, 4));
|
||||
new BlockBoundingBox(hopper, cuboidList, createItem("LAUFBAU_BLOCK_HOPPER", Material.HOPPER, "LAUFBAU_CONNECTION_EAST"));
|
||||
}
|
||||
|
||||
public void westHopper() {
|
||||
Hopper hopper = (Hopper) Material.HOPPER.createBlockData();
|
||||
hopper.setFacing(BlockFace.WEST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 10, 0, 16, 6, 16));
|
||||
cuboidList.add(pixelCuboid(4, 4, 4, 8, 6, 8));
|
||||
cuboidList.add(pixelCuboid(0, 4, 6, 4, 4, 4));
|
||||
new BlockBoundingBox(hopper, cuboidList, createItem("LAUFBAU_BLOCK_HOPPER", Material.HOPPER, "LAUFBAU_CONNECTION_WEST"));
|
||||
}
|
||||
}
|
||||
@@ -1,75 +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.bausystem.features.slaves.laufbau.boundingboxes;
|
||||
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.type.Fence;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
|
||||
|
||||
@Linked
|
||||
public class IronBarBoundingBox implements BoundingBoxLoader {
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
for (int nx = 0; nx < 2; nx++) {
|
||||
for (int nz = 0; nz < 2; nz++) {
|
||||
for (int px = 0; px < 2; px++) {
|
||||
for (int pz = 0; pz < 2; pz++) {
|
||||
Fence fence = (Fence) Material.IRON_BARS.createBlockData();
|
||||
List<String> lore = new ArrayList<>();
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(7, 0, 7, 2, 16, 2));
|
||||
if (nz == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_NORTH");
|
||||
fence.setFace(BlockFace.NORTH, true);
|
||||
cuboidList.add(pixelCuboid(7, 0, 0, 2, 16, 7));
|
||||
}
|
||||
if (pz == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_SOUTH");
|
||||
fence.setFace(BlockFace.SOUTH, true);
|
||||
cuboidList.add(pixelCuboid(7, 0, 9, 2, 16, 7));
|
||||
}
|
||||
if (nx == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_WEST");
|
||||
fence.setFace(BlockFace.WEST, true);
|
||||
cuboidList.add(pixelCuboid(0, 0, 7, 7, 16, 2));
|
||||
}
|
||||
if (px == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_EAST");
|
||||
fence.setFace(BlockFace.EAST, true);
|
||||
cuboidList.add(pixelCuboid(9, 0, 7, 7, 16, 2));
|
||||
}
|
||||
new BlockBoundingBox(fence, cuboidList, createItem("LAUFBAU_BLOCK_IRON_BARS", Material.IRON_BARS, lore.toArray(new String[0])));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,61 +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.bausystem.features.slaves.laufbau.boundingboxes;
|
||||
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.data.type.Lantern;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
|
||||
|
||||
@Linked
|
||||
public class LanternBoundingBox implements BoundingBoxLoader {
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
lantern();
|
||||
hangingLantern();
|
||||
}
|
||||
|
||||
public void lantern() {
|
||||
Lantern lantern = (Lantern) Material.LANTERN.createBlockData();
|
||||
lantern.setHanging(false);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(5, 0, 5, 6, 7, 6));
|
||||
cuboidList.add(pixelCuboid(6, 7, 6, 4, 2, 4));
|
||||
new BlockBoundingBox(lantern, cuboidList, createItem("LAUFBAU_BLOCK_LANTERN", Material.LANTERN));
|
||||
}
|
||||
|
||||
public void hangingLantern() {
|
||||
Lantern lantern = (Lantern) Material.LANTERN.createBlockData();
|
||||
lantern.setHanging(true);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(5, 1, 5, 6, 7, 6));
|
||||
cuboidList.add(pixelCuboid(6, 8, 6, 4, 2, 4));
|
||||
new BlockBoundingBox(lantern, cuboidList, createItem("LAUFBAU_BLOCK_LANTERN", Material.LANTERN, "LAUFBAU_HANGING"));
|
||||
}
|
||||
}
|
||||
@@ -1,46 +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.bausystem.features.slaves.laufbau.boundingboxes;
|
||||
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
|
||||
|
||||
@Linked
|
||||
public class LecternBoundingBox implements BoundingBoxLoader {
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
BlockData blockData = Material.LECTERN.createBlockData();
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 16, 2, 16));
|
||||
cuboidList.add(pixelCuboid(4, 2, 4, 8, 12, 8));
|
||||
new BlockBoundingBox(blockData, cuboidList, createItem("LAUFBAU_BLOCK_LECTERN", Material.LECTERN));
|
||||
}
|
||||
}
|
||||
@@ -1,343 +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.bausystem.features.slaves.laufbau.boundingboxes;
|
||||
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.type.Stairs;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
|
||||
|
||||
@Linked
|
||||
public class StairBoundingBox implements BoundingBoxLoader {
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
straightBottomNorthStair();
|
||||
straightBottomSouthStair();
|
||||
straightBottomEastStair();
|
||||
straightBottomWestStair();
|
||||
|
||||
straightTopNorthStair();
|
||||
straightTopSouthStair();
|
||||
straightTopEastStair();
|
||||
straightTopWestStair();
|
||||
|
||||
outerLeftBottomNorthStair();
|
||||
outerLeftBottomSouthStair();
|
||||
outerLeftBottomEastStair();
|
||||
outerLeftBottomWestStair();
|
||||
|
||||
outerLeftTopNorthStair();
|
||||
outerLeftTopSouthStair();
|
||||
outerLeftTopEastStair();
|
||||
outerLeftTopWestStair();
|
||||
|
||||
innerLeftBottomNorthStair();
|
||||
innerLeftBottomSouthStair();
|
||||
innerLeftBottomEastStair();
|
||||
innerLeftBottomWestStair();
|
||||
|
||||
innerLeftTopNorthStair();
|
||||
innerLeftTopSouthStair();
|
||||
innerLeftTopEastStair();
|
||||
innerLeftTopWestStair();
|
||||
}
|
||||
|
||||
public void straightBottomNorthStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.STRAIGHT);
|
||||
stairs.setHalf(Stairs.Half.BOTTOM);
|
||||
stairs.setFacing(BlockFace.NORTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_STRAIGHT", "LAUFBAU_HALF_BOTTOM", "LAUFBAU_FACING_NORTH"));
|
||||
}
|
||||
|
||||
public void straightBottomSouthStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.STRAIGHT);
|
||||
stairs.setHalf(Stairs.Half.BOTTOM);
|
||||
stairs.setFacing(BlockFace.SOUTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(0, 8, 8, 16, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_STRAIGHT", "LAUFBAU_HALF_BOTTOM", "LAUFBAU_FACING_SOUTH"));
|
||||
}
|
||||
|
||||
public void straightBottomEastStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.STRAIGHT);
|
||||
stairs.setHalf(Stairs.Half.BOTTOM);
|
||||
stairs.setFacing(BlockFace.EAST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(8, 8, 0, 8, 8, 16));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_STRAIGHT", "LAUFBAU_HALF_BOTTOM", "LAUFBAU_FACING_EAST"));
|
||||
}
|
||||
|
||||
public void straightBottomWestStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.STRAIGHT);
|
||||
stairs.setHalf(Stairs.Half.BOTTOM);
|
||||
stairs.setFacing(BlockFace.WEST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(0, 8, 0, 8, 8, 16));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_STRAIGHT", "LAUFBAU_HALF_BOTTOM", "LAUFBAU_FACING_WEST"));
|
||||
}
|
||||
|
||||
public void straightTopNorthStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.STRAIGHT);
|
||||
stairs.setHalf(Stairs.Half.TOP);
|
||||
stairs.setFacing(BlockFace.NORTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_STRAIGHT", "LAUFBAU_HALF_TOP", "LAUFBAU_FACING_NORTH"));
|
||||
}
|
||||
|
||||
public void straightTopSouthStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.STRAIGHT);
|
||||
stairs.setHalf(Stairs.Half.TOP);
|
||||
stairs.setFacing(BlockFace.SOUTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(0, 0, 8, 16, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_STRAIGHT", "LAUFBAU_HALF_TOP", "LAUFBAU_FACING_SOUTH"));
|
||||
}
|
||||
|
||||
public void straightTopEastStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.STRAIGHT);
|
||||
stairs.setHalf(Stairs.Half.TOP);
|
||||
stairs.setFacing(BlockFace.EAST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(8, 0, 0, 8, 8, 16));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_STRAIGHT", "LAUFBAU_HALF_TOP", "LAUFBAU_FACING_EAST"));
|
||||
}
|
||||
|
||||
public void straightTopWestStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.STRAIGHT);
|
||||
stairs.setHalf(Stairs.Half.TOP);
|
||||
stairs.setFacing(BlockFace.WEST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 8, 8, 16));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_STRAIGHT", "LAUFBAU_HALF_TOP", "LAUFBAU_FACING_WEST"));
|
||||
}
|
||||
|
||||
public void outerLeftBottomNorthStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.OUTER_LEFT);
|
||||
stairs.setHalf(Stairs.Half.BOTTOM);
|
||||
stairs.setFacing(BlockFace.NORTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(0, 8, 0, 8, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_OUTER_LEFT", "LAUFBAU_HALF_BOTTOM", "LAUFBAU_FACING_NORTH"));
|
||||
}
|
||||
|
||||
public void outerLeftBottomSouthStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.OUTER_LEFT);
|
||||
stairs.setHalf(Stairs.Half.BOTTOM);
|
||||
stairs.setFacing(BlockFace.SOUTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(8, 8, 8, 8, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_OUTER_LEFT", "LAUFBAU_HALF_BOTTOM", "LAUFBAU_FACING_SOUTH"));
|
||||
}
|
||||
|
||||
public void outerLeftBottomEastStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.OUTER_LEFT);
|
||||
stairs.setHalf(Stairs.Half.BOTTOM);
|
||||
stairs.setFacing(BlockFace.EAST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(8, 8, 0, 8, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_OUTER_LEFT", "LAUFBAU_HALF_BOTTOM", "LAUFBAU_FACING_EAST"));
|
||||
}
|
||||
|
||||
public void outerLeftBottomWestStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.OUTER_LEFT);
|
||||
stairs.setHalf(Stairs.Half.BOTTOM);
|
||||
stairs.setFacing(BlockFace.WEST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(0, 8, 8, 8, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_OUTER_LEFT", "LAUFBAU_HALF_BOTTOM", "LAUFBAU_FACING_WEST"));
|
||||
}
|
||||
|
||||
public void outerLeftTopNorthStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.OUTER_LEFT);
|
||||
stairs.setHalf(Stairs.Half.TOP);
|
||||
stairs.setFacing(BlockFace.NORTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 8, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_OUTER_LEFT", "LAUFBAU_HALF_TOP", "LAUFBAU_FACING_NORTH"));
|
||||
}
|
||||
|
||||
public void outerLeftTopSouthStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.OUTER_LEFT);
|
||||
stairs.setHalf(Stairs.Half.TOP);
|
||||
stairs.setFacing(BlockFace.SOUTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(8, 0, 8, 8, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_OUTER_LEFT", "LAUFBAU_HALF_TOP", "LAUFBAU_FACING_SOUTH"));
|
||||
}
|
||||
|
||||
public void outerLeftTopEastStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.OUTER_LEFT);
|
||||
stairs.setHalf(Stairs.Half.TOP);
|
||||
stairs.setFacing(BlockFace.EAST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(8, 0, 0, 8, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_OUTER_LEFT", "LAUFBAU_HALF_TOP", "LAUFBAU_FACING_EAST"));
|
||||
}
|
||||
|
||||
public void outerLeftTopWestStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.OUTER_LEFT);
|
||||
stairs.setHalf(Stairs.Half.TOP);
|
||||
stairs.setFacing(BlockFace.WEST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(0, 0, 8, 8, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_OUTER_LEFT", "LAUFBAU_HALF_TOP", "LAUFBAU_FACING_WEST"));
|
||||
}
|
||||
|
||||
public void innerLeftBottomNorthStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.INNER_LEFT);
|
||||
stairs.setHalf(Stairs.Half.BOTTOM);
|
||||
stairs.setFacing(BlockFace.NORTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 8));
|
||||
cuboidList.add(pixelCuboid(0, 8, 8, 8, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_INNER_LEFT", "LAUFBAU_HALF_BOTTOM", "LAUFBAU_FACING_NORTH"));
|
||||
}
|
||||
|
||||
public void innerLeftBottomSouthStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.INNER_LEFT);
|
||||
stairs.setHalf(Stairs.Half.BOTTOM);
|
||||
stairs.setFacing(BlockFace.SOUTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(0, 8, 8, 16, 8, 8));
|
||||
cuboidList.add(pixelCuboid(8, 8, 0, 8, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_INNER_LEFT", "LAUFBAU_HALF_BOTTOM", "LAUFBAU_FACING_SOUTH"));
|
||||
}
|
||||
|
||||
public void innerLeftBottomEastStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.INNER_LEFT);
|
||||
stairs.setHalf(Stairs.Half.BOTTOM);
|
||||
stairs.setFacing(BlockFace.EAST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 8));
|
||||
cuboidList.add(pixelCuboid(8, 8, 8, 8, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_INNER_LEFT", "LAUFBAU_HALF_BOTTOM", "LAUFBAU_FACING_EAST"));
|
||||
}
|
||||
|
||||
public void innerLeftBottomWestStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.INNER_LEFT);
|
||||
stairs.setHalf(Stairs.Half.BOTTOM);
|
||||
stairs.setFacing(BlockFace.WEST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(0, 8, 8, 16, 8, 8));
|
||||
cuboidList.add(pixelCuboid(0, 8, 0, 8, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_INNER_LEFT", "LAUFBAU_HALF_BOTTOM", "LAUFBAU_FACING_WEST"));
|
||||
}
|
||||
|
||||
public void innerLeftTopNorthStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.INNER_LEFT);
|
||||
stairs.setHalf(Stairs.Half.TOP);
|
||||
stairs.setFacing(BlockFace.NORTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 8));
|
||||
cuboidList.add(pixelCuboid(0, 0, 8, 8, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_INNER_LEFT", "LAUFBAU_HALF_TOP", "LAUFBAU_FACING_NORTH"));
|
||||
}
|
||||
|
||||
public void innerLeftTopSouthStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.INNER_LEFT);
|
||||
stairs.setHalf(Stairs.Half.TOP);
|
||||
stairs.setFacing(BlockFace.SOUTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(0, 0, 8, 16, 8, 8));
|
||||
cuboidList.add(pixelCuboid(8, 0, 0, 8, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_INNER_LEFT", "LAUFBAU_HALF_TOP", "LAUFBAU_FACING_SOUTH"));
|
||||
}
|
||||
|
||||
public void innerLeftTopEastStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.INNER_LEFT);
|
||||
stairs.setHalf(Stairs.Half.TOP);
|
||||
stairs.setFacing(BlockFace.EAST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 8));
|
||||
cuboidList.add(pixelCuboid(8, 0, 8, 8, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_INNER_LEFT", "LAUFBAU_HALF_TOP", "LAUFBAU_FACING_EAST"));
|
||||
}
|
||||
|
||||
public void innerLeftTopWestStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.INNER_LEFT);
|
||||
stairs.setHalf(Stairs.Half.TOP);
|
||||
stairs.setFacing(BlockFace.WEST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(0, 0, 8, 16, 8, 8));
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 8, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_INNER_LEFT", "LAUFBAU_HALF_TOP", "LAUFBAU_FACING_WEST"));
|
||||
}
|
||||
}
|
||||
@@ -1,121 +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.bausystem.features.slaves.laufbau.boundingboxes;
|
||||
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
|
||||
import de.steamwar.core.Core;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.type.Fence;
|
||||
import org.bukkit.block.data.type.Wall;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
|
||||
|
||||
@Linked
|
||||
public class WallBoundingBox implements BoundingBoxLoader {
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
if (Core.getVersion() > 15) {
|
||||
v18();
|
||||
} else {
|
||||
v15();
|
||||
}
|
||||
}
|
||||
|
||||
private void v18() {
|
||||
for (int nx = 0; nx < 2; nx++) {
|
||||
for (int nz = 0; nz < 2; nz++) {
|
||||
for (int px = 0; px < 2; px++) {
|
||||
for (int pz = 0; pz < 2; pz++) {
|
||||
Wall fence = (Wall) Material.END_STONE_BRICK_WALL.createBlockData();
|
||||
List<String> lore = new ArrayList<>();
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(4, 0, 4, 8, 24, 8));
|
||||
if (nz == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_NORTH");
|
||||
fence.setHeight(BlockFace.NORTH, Wall.Height.LOW);
|
||||
cuboidList.add(pixelCuboid(5, 0, 0, 6, 24, 4));
|
||||
}
|
||||
if (pz == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_SOUTH");
|
||||
fence.setHeight(BlockFace.SOUTH, Wall.Height.LOW);
|
||||
cuboidList.add(pixelCuboid(5, 0, 12, 6, 24, 4));
|
||||
}
|
||||
if (nx == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_WEST");
|
||||
fence.setHeight(BlockFace.WEST, Wall.Height.LOW);
|
||||
cuboidList.add(pixelCuboid(0, 0, 5, 4, 24, 6));
|
||||
}
|
||||
if (px == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_EAST");
|
||||
fence.setHeight(BlockFace.EAST, Wall.Height.LOW);
|
||||
cuboidList.add(pixelCuboid(12, 0, 5, 4, 24, 6));
|
||||
}
|
||||
new BlockBoundingBox(fence, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_WALL", Material.END_STONE_BRICK_WALL, lore.toArray(new String[0])));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void v15() {
|
||||
for (int nx = 0; nx < 2; nx++) {
|
||||
for (int nz = 0; nz < 2; nz++) {
|
||||
for (int px = 0; px < 2; px++) {
|
||||
for (int pz = 0; pz < 2; pz++) {
|
||||
Fence fence = (Fence) Material.END_STONE_BRICK_WALL.createBlockData();
|
||||
List<String> lore = new ArrayList<>();
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(4, 0, 4, 8, 24, 8));
|
||||
if (nz == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_NORTH");
|
||||
fence.setFace(BlockFace.NORTH, true);
|
||||
cuboidList.add(pixelCuboid(5, 0, 0, 6, 24, 4));
|
||||
}
|
||||
if (pz == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_SOUTH");
|
||||
fence.setFace(BlockFace.SOUTH, true);
|
||||
cuboidList.add(pixelCuboid(5, 0, 12, 6, 24, 4));
|
||||
}
|
||||
if (nx == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_WEST");
|
||||
fence.setFace(BlockFace.WEST, true);
|
||||
cuboidList.add(pixelCuboid(0, 0, 5, 4, 24, 6));
|
||||
}
|
||||
if (px == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_EAST");
|
||||
fence.setFace(BlockFace.EAST, true);
|
||||
cuboidList.add(pixelCuboid(12, 0, 5, 4, 24, 6));
|
||||
}
|
||||
new BlockBoundingBox(fence, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_WALL", Material.END_STONE_BRICK_WALL, lore.toArray(new String[0])));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -107,7 +107,7 @@ public class TechHiderCommand extends SWCommand implements Listener, ScoreboardE
|
||||
@Override
|
||||
public Player map(CommandSender commandSender, String[] previousArguments, String s) {
|
||||
Player player = Bukkit.getPlayer(s);
|
||||
if (player != null && Permission.REAL_SPECTATOR.hasPermission(player)) {
|
||||
if (player != null && Permission.SPECTATOR.hasPermission(player)) {
|
||||
return player;
|
||||
}
|
||||
return null;
|
||||
@@ -116,7 +116,7 @@ public class TechHiderCommand extends SWCommand implements Listener, ScoreboardE
|
||||
@Override
|
||||
public Collection<String> tabCompletes(CommandSender sender, PreviousArguments previousArguments, String s) {
|
||||
return Bukkit.getOnlinePlayers().stream()
|
||||
.filter(Permission.REAL_SPECTATOR::hasPermission)
|
||||
.filter(Permission.SPECTATOR::hasPermission)
|
||||
.map(Player::getName)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bausystem.features.tntlistener;
|
||||
package de.steamwar.bausystem.features.tls;
|
||||
|
||||
import de.steamwar.command.SWCommand;
|
||||
import de.steamwar.linkage.Linked;
|
||||
@@ -43,4 +43,13 @@ public class TLSCommand extends SWCommand {
|
||||
public void stop(@Validator Player player) {
|
||||
listener.stopListening(player);
|
||||
}
|
||||
|
||||
@Register(description = "TLS_TOGGLE_HELP")
|
||||
public void toggle(@Validator Player player) {
|
||||
if (listener.isActiveFor(player)) {
|
||||
listener.stopListening(player);
|
||||
} else {
|
||||
listener.startListening(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bausystem.features.tntlistener;
|
||||
package de.steamwar.bausystem.features.tls;
|
||||
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.bausystem.features.tpslimit.TPSUtils;
|
||||
@@ -17,7 +17,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bausystem.features.tntlistener;
|
||||
package de.steamwar.bausystem.features.tls;
|
||||
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.bausystem.Permission;
|
||||
@@ -20,6 +20,7 @@ package de.steamwar.bausystem.features.util;
|
||||
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.command.SWCommand;
|
||||
import de.steamwar.core.SWPlayer;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -39,10 +40,11 @@ public class GamemodeCommand extends SWCommand {
|
||||
|
||||
@Register
|
||||
public void genericCommand(final Player p) {
|
||||
if (NoClipCommand.getNOCLIPS().contains(p)) {
|
||||
p.performCommand("noclip");
|
||||
return;
|
||||
}
|
||||
SWPlayer swPlayer = SWPlayer.of(p);
|
||||
if (swPlayer.hasComponent(NoClipCommand.NoClipData.class)) {
|
||||
swPlayer.removeComponent(NoClipCommand.NoClipData.class);
|
||||
return;
|
||||
}
|
||||
if (p.getGameMode() == GameMode.CREATIVE) {
|
||||
p.setGameMode(GameMode.SPECTATOR);
|
||||
} else {
|
||||
@@ -52,9 +54,7 @@ public class GamemodeCommand extends SWCommand {
|
||||
|
||||
@Register
|
||||
public void gamemodeCommand(final Player p, final GameMode gameMode) {
|
||||
if (NoClipCommand.getNOCLIPS().contains(p)) {
|
||||
p.performCommand("noclip");
|
||||
}
|
||||
SWPlayer.of(p).removeComponent(NoClipCommand.NoClipData.class);
|
||||
p.setGameMode(gameMode);
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,7 @@ import de.steamwar.bausystem.shared.EnumDisplay;
|
||||
import de.steamwar.command.PreviousArguments;
|
||||
import de.steamwar.command.SWCommand;
|
||||
import de.steamwar.command.TypeMapper;
|
||||
import de.steamwar.core.SWPlayer;
|
||||
import de.steamwar.data.CMDs;
|
||||
import de.steamwar.inventory.SWAnvilInv;
|
||||
import de.steamwar.inventory.SWInventory;
|
||||
@@ -56,11 +57,9 @@ public class MaterialCommand extends SWCommand implements Listener {
|
||||
WorldEditListener.addCommandExclusion("material");
|
||||
}
|
||||
|
||||
private Map<Player, Search> searchMap = new HashMap<>();
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
static class Search {
|
||||
public class SearchParameter implements SWPlayer.Component {
|
||||
SearchType transparent = SearchType.IGNORE;
|
||||
SearchType solid = SearchType.IGNORE;
|
||||
SearchType gravity = SearchType.IGNORE;
|
||||
@@ -104,10 +103,10 @@ public class MaterialCommand extends SWCommand implements Listener {
|
||||
|
||||
@Register
|
||||
public void materialGUI(Player p) {
|
||||
materialGUI(p, searchMap.get(p));
|
||||
materialGUI(p, SWPlayer.of(p).getComponentOrDefault(SearchParameter.class, SearchParameter::new));
|
||||
}
|
||||
|
||||
private static final Map<String, BiConsumer<Search, SearchType>> elements = new HashMap<>();
|
||||
private static final Map<String, BiConsumer<SearchParameter, SearchType>> elements = new HashMap<>();
|
||||
static {
|
||||
elements.put("-transparent", (search, searchType) -> search.transparent = searchType);
|
||||
elements.put("-solid", (search, searchType) -> search.solid = searchType);
|
||||
@@ -122,15 +121,15 @@ public class MaterialCommand extends SWCommand implements Listener {
|
||||
|
||||
@Register
|
||||
public void search(Player p, @Mapper("search") String... searches) {
|
||||
Search search = new Search();
|
||||
SearchParameter searchParameter = SWPlayer.of(p).getComponentOrDefault(SearchParameter.class, SearchParameter::new);
|
||||
for (String s : searches) {
|
||||
boolean has = false;
|
||||
for (Map.Entry<String, BiConsumer<Search, SearchType>> element: elements.entrySet()) {
|
||||
for (Map.Entry<String, BiConsumer<SearchParameter, SearchType>> element: elements.entrySet()) {
|
||||
if (s.startsWith(element.getKey() + ":")) {
|
||||
element.getValue().accept(search, SearchType.valueOf(s.substring(element.getKey().length() + 1).toUpperCase()));
|
||||
element.getValue().accept(searchParameter, SearchType.valueOf(s.substring(element.getKey().length() + 1).toUpperCase()));
|
||||
has = true;
|
||||
} else if (s.startsWith(element.getKey().substring(0, 2) + ":")) {
|
||||
element.getValue().accept(search, SearchType.valueOf(s.substring(element.getKey().substring(0, 2).length() + 1).toUpperCase()));
|
||||
element.getValue().accept(searchParameter, SearchType.valueOf(s.substring(element.getKey().substring(0, 2).length() + 1).toUpperCase()));
|
||||
has = true;
|
||||
}
|
||||
if (has) break;
|
||||
@@ -141,15 +140,15 @@ public class MaterialCommand extends SWCommand implements Listener {
|
||||
case "-blastresistance:":
|
||||
s = s.substring(s.indexOf(':') + 1).replace('_', ' ');
|
||||
if (s.isEmpty() || s.matches("((([><]=?)|!|=)\\d+(\\.|,\\d+)?)( ((([><]=?)|!|=)\\d+(\\.|,\\d+)?))*")) {
|
||||
search.blastResistance = s;
|
||||
searchParameter.blastResistance = s;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
search.name = s;
|
||||
searchParameter.name = s;
|
||||
break;
|
||||
}
|
||||
}
|
||||
materialGUI(p, search);
|
||||
materialGUI(p, searchParameter);
|
||||
}
|
||||
|
||||
@Mapper(value = "search", local = true)
|
||||
@@ -182,7 +181,7 @@ public class MaterialCommand extends SWCommand implements Listener {
|
||||
};
|
||||
}
|
||||
|
||||
public void materialGUI(Player p, Search search) {
|
||||
public void materialGUI(Player p, SearchParameter search) {
|
||||
List<SWListInv.SWListEntry<Material>> swListEntries = new ArrayList<>();
|
||||
MaterialLazyInit.materialData.forEach(data -> {
|
||||
if (data.is(search)) {
|
||||
@@ -202,59 +201,59 @@ public class MaterialCommand extends SWCommand implements Listener {
|
||||
|
||||
private void searchGUI(Player p) {
|
||||
SWInventory swInventory = new SWInventory(p, 54, BauSystem.MESSAGE.parse("MATERIAL_SEARCH", p));
|
||||
Search search = searchMap.get(p);
|
||||
SearchParameter searchParameter = SWPlayer.of(p).getComponentOrDefault(SearchParameter.class, SearchParameter::new);
|
||||
swInventory.setItem(0, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("MATERIAL_BACK", p), clickType -> {
|
||||
materialGUI(p);
|
||||
}).setCustomModelData(CMDs.BACK));
|
||||
swInventory.setItem(10, new SWItem(Material.NAME_TAG, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_NAME", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, search.name), clickType -> {
|
||||
SWAnvilInv swAnvilInv = new SWAnvilInv(p, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_NAME", p), search.name);
|
||||
swInventory.setItem(10, new SWItem(Material.NAME_TAG, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_NAME", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, searchParameter.name), clickType -> {
|
||||
SWAnvilInv swAnvilInv = new SWAnvilInv(p, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_NAME", p), searchParameter.name);
|
||||
swAnvilInv.setCallback(s -> {
|
||||
search.name = s;
|
||||
searchParameter.name = s;
|
||||
searchGUI(p);
|
||||
});
|
||||
swAnvilInv.open();
|
||||
}));
|
||||
swInventory.setItem(19, new SWItem(Material.GLASS, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_TRANSPARENT", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, BauSystem.MESSAGE.parse(search.transparent.getChatValue(), p)), clickType -> {
|
||||
search.transparent = search.transparent.next();
|
||||
swInventory.setItem(19, new SWItem(Material.GLASS, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_TRANSPARENT", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, BauSystem.MESSAGE.parse(searchParameter.transparent.getChatValue(), p)), clickType -> {
|
||||
searchParameter.transparent = searchParameter.transparent.next();
|
||||
searchGUI(p);
|
||||
}));
|
||||
swInventory.setItem(20, new SWItem(Material.BRICK, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_SOLID", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, BauSystem.MESSAGE.parse(search.solid.getChatValue(), p)), clickType -> {
|
||||
search.solid = search.solid.next();
|
||||
swInventory.setItem(20, new SWItem(Material.BRICK, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_SOLID", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, BauSystem.MESSAGE.parse(searchParameter.solid.getChatValue(), p)), clickType -> {
|
||||
searchParameter.solid = searchParameter.solid.next();
|
||||
searchGUI(p);
|
||||
}));
|
||||
swInventory.setItem(21, new SWItem(Material.BLACK_CONCRETE_POWDER, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_GRAVITY", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, BauSystem.MESSAGE.parse(search.gravity.getChatValue(), p)), clickType -> {
|
||||
search.gravity = search.gravity.next();
|
||||
swInventory.setItem(21, new SWItem(Material.BLACK_CONCRETE_POWDER, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_GRAVITY", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, BauSystem.MESSAGE.parse(searchParameter.gravity.getChatValue(), p)), clickType -> {
|
||||
searchParameter.gravity = searchParameter.gravity.next();
|
||||
searchGUI(p);
|
||||
}));
|
||||
swInventory.setItem(22, new SWItem(Material.BIRCH_LOG, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_OCCLUDING", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, BauSystem.MESSAGE.parse(search.occluding.getChatValue(), p)), clickType -> {
|
||||
search.occluding = search.occluding.next();
|
||||
swInventory.setItem(22, new SWItem(Material.BIRCH_LOG, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_OCCLUDING", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, BauSystem.MESSAGE.parse(searchParameter.occluding.getChatValue(), p)), clickType -> {
|
||||
searchParameter.occluding = searchParameter.occluding.next();
|
||||
searchGUI(p);
|
||||
}));
|
||||
swInventory.setItem(23, new SWItem(Material.OAK_BUTTON, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_INTERACTEABLE", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, BauSystem.MESSAGE.parse(search.interacteable.getChatValue(), p)), clickType -> {
|
||||
search.interacteable = search.interacteable.next();
|
||||
swInventory.setItem(23, new SWItem(Material.OAK_BUTTON, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_INTERACTEABLE", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, BauSystem.MESSAGE.parse(searchParameter.interacteable.getChatValue(), p)), clickType -> {
|
||||
searchParameter.interacteable = searchParameter.interacteable.next();
|
||||
searchGUI(p);
|
||||
}));
|
||||
swInventory.setItem(24, new SWItem(Material.FLINT_AND_STEEL, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_FLAMMABLE", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, BauSystem.MESSAGE.parse(search.flammable.getChatValue(), p)), clickType -> {
|
||||
search.flammable = search.flammable.next();
|
||||
swInventory.setItem(24, new SWItem(Material.FLINT_AND_STEEL, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_FLAMMABLE", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, BauSystem.MESSAGE.parse(searchParameter.flammable.getChatValue(), p)), clickType -> {
|
||||
searchParameter.flammable = searchParameter.flammable.next();
|
||||
searchGUI(p);
|
||||
}));
|
||||
swInventory.setItem(25, new SWItem(Material.LAVA_BUCKET, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_BURNABLE", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, BauSystem.MESSAGE.parse(search.burnable.getChatValue(), p)), clickType -> {
|
||||
search.burnable = search.burnable.next();
|
||||
swInventory.setItem(25, new SWItem(Material.LAVA_BUCKET, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_BURNABLE", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, BauSystem.MESSAGE.parse(searchParameter.burnable.getChatValue(), p)), clickType -> {
|
||||
searchParameter.burnable = searchParameter.burnable.next();
|
||||
searchGUI(p);
|
||||
}));
|
||||
swInventory.setItem(28, new SWItem(Material.WATER_BUCKET, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_WATERLOGGABLE", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, BauSystem.MESSAGE.parse(search.waterloggable.getChatValue(), p)), clickType -> {
|
||||
search.waterloggable = search.waterloggable.next();
|
||||
swInventory.setItem(28, new SWItem(Material.WATER_BUCKET, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_WATERLOGGABLE", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, BauSystem.MESSAGE.parse(searchParameter.waterloggable.getChatValue(), p)), clickType -> {
|
||||
searchParameter.waterloggable = searchParameter.waterloggable.next();
|
||||
searchGUI(p);
|
||||
}));
|
||||
swInventory.setItem(29, new SWItem(Material.PISTON, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_UNMOVEABLE", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, BauSystem.MESSAGE.parse(search.unmoveable.getChatValue(), p)), clickType -> {
|
||||
search.unmoveable = search.unmoveable.next();
|
||||
swInventory.setItem(29, new SWItem(Material.PISTON, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_UNMOVEABLE", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, BauSystem.MESSAGE.parse(searchParameter.unmoveable.getChatValue(), p)), clickType -> {
|
||||
searchParameter.unmoveable = searchParameter.unmoveable.next();
|
||||
searchGUI(p);
|
||||
}));
|
||||
swInventory.setItem(34, new SWItem(Material.NETHER_BRICK, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_BLASTRESISTANCE", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, search.blastResistance), clickType -> {
|
||||
SWAnvilInv swAnvilInv = new SWAnvilInv(p, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_BLASTRESISTANCE", p), search.blastResistance);
|
||||
swInventory.setItem(34, new SWItem(Material.NETHER_BRICK, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_BLASTRESISTANCE", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, searchParameter.blastResistance), clickType -> {
|
||||
SWAnvilInv swAnvilInv = new SWAnvilInv(p, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_BLASTRESISTANCE", p), searchParameter.blastResistance);
|
||||
swAnvilInv.setCallback(s -> {
|
||||
if (s.isEmpty() || s.matches("((([><]=?)|!|=)\\d+(\\.|,\\d+)?)( ((([><]=?)|!|=)\\d+(\\.|,\\d+)?))*")) {
|
||||
search.blastResistance = s;
|
||||
searchParameter.blastResistance = s;
|
||||
}
|
||||
searchGUI(p);
|
||||
});
|
||||
@@ -262,14 +261,4 @@ public class MaterialCommand extends SWCommand implements Listener {
|
||||
}));
|
||||
swInventory.open();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||
searchMap.put(event.getPlayer(), new Search());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
searchMap.remove(event.getPlayer());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,7 +133,7 @@ public class MaterialLazyInit {
|
||||
}), originalMaterial);
|
||||
}
|
||||
|
||||
public boolean is(MaterialCommand.Search search) {
|
||||
public boolean is(MaterialCommand.SearchParameter search) {
|
||||
boolean result = true;
|
||||
result &= search.transparent.test(transparent);
|
||||
result &= search.solid.test(solid);
|
||||
|
||||
@@ -19,17 +19,17 @@
|
||||
|
||||
package de.steamwar.bausystem.features.util;
|
||||
|
||||
import de.steamwar.Reflection;
|
||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import de.steamwar.Reflection;
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.bausystem.features.tpslimit.TPSUtils;
|
||||
import de.steamwar.bausystem.utils.BauMemberUpdateEvent;
|
||||
import de.steamwar.bausystem.utils.NMSWrapper;
|
||||
import de.steamwar.command.SWCommand;
|
||||
import de.steamwar.core.ProtocolWrapper;
|
||||
import de.steamwar.core.SWPlayer;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -40,10 +40,6 @@ import org.bukkit.event.player.PlayerGameModeChangeEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
import org.bukkit.event.player.PlayerToggleFlightEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
@Linked
|
||||
@@ -59,29 +55,34 @@ public class NoClipCommand extends SWCommand implements Listener {
|
||||
private static final Class<?> windowClick = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundContainerClickPacket");
|
||||
private static final Class<?> setSlotStack = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundSetCreativeModeSlotPacket");
|
||||
|
||||
@Getter
|
||||
private static final List<Player> NOCLIPS = new ArrayList<>();
|
||||
private static final Map<Player, Long> LAST_TICKS = new HashMap<>();
|
||||
public static class NoClipData implements SWPlayer.Component {
|
||||
private long lastTick = -1;
|
||||
|
||||
@Override
|
||||
public void onUnmount(SWPlayer player) {
|
||||
player.setGameMode(GameMode.CREATIVE);
|
||||
}
|
||||
}
|
||||
|
||||
public NoClipCommand() {
|
||||
super("noclip", "nc");
|
||||
|
||||
BiFunction<Player, Object, Object> first = (player, o) -> {
|
||||
if (NOCLIPS.contains(player)) {
|
||||
if (LAST_TICKS.getOrDefault(player, -1L).equals(TPSUtils.currentTick.get())) return o;
|
||||
NMSWrapper.impl.setInternalGameMode(player, GameMode.SPECTATOR);
|
||||
LAST_TICKS.put(player, TPSUtils.currentTick.get());
|
||||
}
|
||||
NoClipData noClipData = SWPlayer.of(player).getComponent(NoClipData.class).orElse(null);
|
||||
if (noClipData == null) return o;
|
||||
if (noClipData.lastTick == TPSUtils.currentTick.get()) return o;
|
||||
NMSWrapper.impl.setInternalGameMode(player, GameMode.SPECTATOR);
|
||||
noClipData.lastTick = TPSUtils.currentTick.get();
|
||||
return o;
|
||||
};
|
||||
TinyProtocol.instance.addFilter(position, first);
|
||||
TinyProtocol.instance.addFilter(positionLook, first);
|
||||
|
||||
BiFunction<Player, Object, Object> second = (player, o) -> {
|
||||
if (NOCLIPS.contains(player)) {
|
||||
NMSWrapper.impl.setInternalGameMode(player, GameMode.CREATIVE);
|
||||
LAST_TICKS.put(player, TPSUtils.currentTick.get());
|
||||
}
|
||||
NoClipData noClipData = SWPlayer.of(player).getComponent(NoClipData.class).orElse(null);
|
||||
if (noClipData == null) return o;
|
||||
NMSWrapper.impl.setInternalGameMode(player, GameMode.CREATIVE);
|
||||
noClipData.lastTick = TPSUtils.currentTick.get();
|
||||
return o;
|
||||
};
|
||||
TinyProtocol.instance.addFilter(useItem, second);
|
||||
@@ -89,7 +90,7 @@ public class NoClipCommand extends SWCommand implements Listener {
|
||||
TinyProtocol.instance.addFilter(windowClick, second);
|
||||
|
||||
BiFunction<Player, Object, Object> third = (player, o) -> {
|
||||
if (NOCLIPS.contains(player)) {
|
||||
if (SWPlayer.of(player).hasComponent(NoClipData.class)) {
|
||||
NMSWrapper.impl.setSlotToItemStack(player, o);
|
||||
}
|
||||
return o;
|
||||
@@ -99,9 +100,9 @@ public class NoClipCommand extends SWCommand implements Listener {
|
||||
|
||||
@Register(help = true)
|
||||
public void genericCommand(@Validator Player player) {
|
||||
if (NOCLIPS.contains(player)) {
|
||||
NOCLIPS.remove(player);
|
||||
player.setGameMode(GameMode.CREATIVE);
|
||||
SWPlayer swPlayer = SWPlayer.of(player);
|
||||
if (swPlayer.hasComponent(NoClipData.class)) {
|
||||
swPlayer.removeComponent(NoClipData.class);
|
||||
} else {
|
||||
player.setGameMode(GameMode.SPECTATOR);
|
||||
NMSWrapper.impl.setPlayerBuildAbilities(player);
|
||||
@@ -109,8 +110,8 @@ public class NoClipCommand extends SWCommand implements Listener {
|
||||
Object gameStateChangeObject = Reflection.newInstance(gameStateChange);
|
||||
NMSWrapper.impl.setGameStateChangeReason(gameStateChangeObject);
|
||||
floatFieldAccessor.set(gameStateChangeObject, 1F);
|
||||
|
||||
NOCLIPS.add(player);
|
||||
|
||||
swPlayer.setComponent(new NoClipData());
|
||||
BauSystem.MESSAGE.send("OTHER_NOCLIP_SLOT_INFO", player);
|
||||
TinyProtocol.instance.sendPacket(player, gameStateChangeObject);
|
||||
pseudoGameMode(player, GameMode.SPECTATOR);
|
||||
@@ -120,30 +121,27 @@ public class NoClipCommand extends SWCommand implements Listener {
|
||||
@EventHandler
|
||||
public void onBauMemberUpdate(BauMemberUpdateEvent event) {
|
||||
event.getNewSpectator().forEach(player -> {
|
||||
if (NOCLIPS.contains(player)) {
|
||||
NOCLIPS.remove(player);
|
||||
player.setGameMode(GameMode.CREATIVE);
|
||||
}
|
||||
SWPlayer.of(player).removeComponent(NoClipData.class);
|
||||
});
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onPlayerGameModeChange(PlayerGameModeChangeEvent event) {
|
||||
if (NOCLIPS.contains(event.getPlayer())) {
|
||||
if (SWPlayer.of(event.getPlayer()).hasComponent(NoClipData.class)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onBlock(BlockCanBuildEvent event) {
|
||||
if (NOCLIPS.contains(event.getPlayer())) {
|
||||
if (SWPlayer.of(event.getPlayer()).hasComponent(NoClipData.class)) {
|
||||
event.setBuildable(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onPlayerToggleFlight(PlayerToggleFlightEvent event) {
|
||||
if (NOCLIPS.contains(event.getPlayer())) {
|
||||
if (SWPlayer.of(event.getPlayer()).hasComponent(NoClipData.class)) {
|
||||
event.setCancelled(true);
|
||||
event.getPlayer().setFlying(true);
|
||||
}
|
||||
@@ -154,7 +152,7 @@ public class NoClipCommand extends SWCommand implements Listener {
|
||||
if (event.getCause() != PlayerTeleportEvent.TeleportCause.SPECTATE) {
|
||||
return;
|
||||
}
|
||||
if (NOCLIPS.contains(event.getPlayer())) {
|
||||
if (SWPlayer.of(event.getPlayer()).hasComponent(NoClipData.class)) {
|
||||
event.setCancelled(true);
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||
event.getPlayer().setSpectatorTarget(null);
|
||||
|
||||
@@ -24,6 +24,7 @@ import de.steamwar.bausystem.Permission;
|
||||
import de.steamwar.bausystem.linkage.BauGuiItem;
|
||||
import de.steamwar.bausystem.region.utils.RegionExtensionType;
|
||||
import de.steamwar.bausystem.region.utils.RegionType;
|
||||
import de.steamwar.core.SWPlayer;
|
||||
import de.steamwar.inventory.SWInventory;
|
||||
import de.steamwar.inventory.SWItem;
|
||||
import de.steamwar.linkage.Linked;
|
||||
@@ -35,15 +36,11 @@ import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
@Linked
|
||||
public class SelectBauGuiItem extends BauGuiItem {
|
||||
|
||||
private static final Map<Player, LastSelect> LAST_SELECT_MAP = new HashMap<>();
|
||||
|
||||
public SelectBauGuiItem() {
|
||||
super(13);
|
||||
}
|
||||
@@ -58,13 +55,13 @@ public class SelectBauGuiItem extends BauGuiItem {
|
||||
|
||||
private static void selectFinish(Player p, RegionType type, RegionExtensionType extensionType) {
|
||||
p.closeInventory();
|
||||
LAST_SELECT_MAP.put(p, new LastSelect(type, extensionType));
|
||||
SWPlayer.of(p).setComponent(new LastSelect(type, extensionType));
|
||||
p.performCommand("select " + type.name() + " " + extensionType.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItem(Player player) {
|
||||
LastSelect last = LAST_SELECT_MAP.getOrDefault(player, new LastSelect(RegionType.BUILD, RegionExtensionType.NORMAL));
|
||||
LastSelect last = SWPlayer.of(player).getComponentOrDefault(LastSelect.class, () -> new LastSelect(RegionType.BUILD, RegionExtensionType.NORMAL));
|
||||
return new SWItem(Material.SCAFFOLDING, BauSystem.MESSAGE.parse("SELECT_ITEM_SELECT", player), Arrays.asList(BauSystem.MESSAGE.parse("SELECT_ITEM_AUSWAHL", player, BauSystem.MESSAGE.parse(last.type.getChatValue(), player), last.extensionType.name()), BauSystem.MESSAGE.parse("SELECT_ITEM_RIGHT_CLICK", player)), false, clickType -> {
|
||||
}).getItemStack();
|
||||
}
|
||||
@@ -80,7 +77,7 @@ public class SelectBauGuiItem extends BauGuiItem {
|
||||
inv.open();
|
||||
} else {
|
||||
p.closeInventory();
|
||||
LastSelect last = LAST_SELECT_MAP.getOrDefault(p, new LastSelect(RegionType.BUILD, RegionExtensionType.NORMAL));
|
||||
LastSelect last = SWPlayer.of(p).getComponentOrDefault(LastSelect.class, () -> new LastSelect(RegionType.BUILD, RegionExtensionType.NORMAL));
|
||||
p.performCommand("select " + last.getType().name() + " " + last.getExtensionType().toString());
|
||||
}
|
||||
return false;
|
||||
@@ -92,7 +89,7 @@ public class SelectBauGuiItem extends BauGuiItem {
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
private static class LastSelect {
|
||||
private static class LastSelect implements SWPlayer.Component {
|
||||
@Getter
|
||||
private final RegionType type;
|
||||
@Getter
|
||||
|
||||
@@ -21,6 +21,7 @@ package de.steamwar.bausystem.features.warp;
|
||||
|
||||
import de.steamwar.bausystem.region.Region;
|
||||
import de.steamwar.core.Core;
|
||||
import de.steamwar.core.SWPlayer;
|
||||
import de.steamwar.entity.RArmorStand;
|
||||
import de.steamwar.entity.REntityServer;
|
||||
import de.steamwar.linkage.Linked;
|
||||
@@ -30,7 +31,10 @@ import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.player.*;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerItemHeldEvent;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.event.player.PlayerToggleSneakEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
@@ -42,8 +46,21 @@ import java.util.Map;
|
||||
@Linked
|
||||
public class WarpListener implements Listener {
|
||||
|
||||
private Map<Player, REntityServer> warpEntityServer = new HashMap<>();
|
||||
private Map<Player, List<Location>> selected = new HashMap<>();
|
||||
public static class WarpComponent implements SWPlayer.Component {
|
||||
private REntityServer server;
|
||||
private List<Location> selected = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void onMount(SWPlayer player) {
|
||||
server = new REntityServer();
|
||||
server.addPlayer(player.getPlayer());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUnmount(SWPlayer player) {
|
||||
server.close();
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerItemHeld(PlayerItemHeldEvent e) {
|
||||
@@ -65,20 +82,11 @@ public class WarpListener implements Listener {
|
||||
}
|
||||
|
||||
private void reshow(Player p, Material material, boolean sneaking) {
|
||||
REntityServer entityServer = warpEntityServer.get(p);
|
||||
if (entityServer != null) {
|
||||
entityServer.close();
|
||||
}
|
||||
if (material != Material.COMPASS) {
|
||||
warpEntityServer.remove(p);
|
||||
return;
|
||||
}
|
||||
|
||||
selected.remove(p);
|
||||
entityServer = new REntityServer();
|
||||
entityServer.addPlayer(p);
|
||||
warpEntityServer.put(p, entityServer);
|
||||
SWPlayer swPlayer = SWPlayer.of(p);
|
||||
swPlayer.removeComponent(WarpComponent.class);
|
||||
if (material != Material.COMPASS) return;
|
||||
|
||||
WarpComponent warpComponent = swPlayer.getComponentOrDefault(WarpComponent.class, WarpComponent::new);
|
||||
Vector current = p.getLocation().clone().add(p.getLocation().getDirection().multiply(5)).toVector();
|
||||
|
||||
Map<String, Location> locations = new HashMap<>();
|
||||
@@ -99,12 +107,9 @@ public class WarpListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
REntityServer finalEntityServer = entityServer;
|
||||
locations.forEach((name, location) -> {
|
||||
Vector vector = location.toVector().subtract(p.getLocation().toVector());
|
||||
if (vector.getX() * vector.getX() + vector.getZ() * vector.getZ() < 25) {
|
||||
return;
|
||||
}
|
||||
if (vector.getX() * vector.getX() + vector.getZ() * vector.getZ() < 25) return;
|
||||
vector.setY(0);
|
||||
|
||||
Vector position = p.getLocation().toVector().clone().add(vector.normalize().multiply(5));
|
||||
@@ -112,9 +117,9 @@ public class WarpListener implements Listener {
|
||||
|
||||
if ((position.getX() - current.getX()) * (position.getX() - current.getX()) + (position.getZ() - current.getZ()) * (position.getZ() - current.getZ()) < 0.1) {
|
||||
name = "§a§l" + name;
|
||||
selected.computeIfAbsent(p, player -> new ArrayList<>()).add(location);
|
||||
warpComponent.selected.add(location);
|
||||
}
|
||||
RArmorStand armorStand = new RArmorStand(finalEntityServer, position.toLocation(p.getWorld()), RArmorStand.Size.MARKER);
|
||||
RArmorStand armorStand = new RArmorStand(warpComponent.server, position.toLocation(p.getWorld()), RArmorStand.Size.MARKER);
|
||||
armorStand.setDisplayName(name);
|
||||
armorStand.setNoGravity(true);
|
||||
armorStand.setInvisible(true);
|
||||
@@ -123,28 +128,13 @@ public class WarpListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPlayerInteract(PlayerInteractEvent event) {
|
||||
if (event.getPlayer().getInventory().getItemInMainHand().getType() != Material.COMPASS) {
|
||||
return;
|
||||
}
|
||||
if (event.getAction() != Action.RIGHT_CLICK_AIR) {
|
||||
return;
|
||||
}
|
||||
List<Location> locations = selected.getOrDefault(event.getPlayer(), new ArrayList<>());
|
||||
if (locations.size() != 1) {
|
||||
return;
|
||||
}
|
||||
Location location = locations.get(0);
|
||||
if (event.getPlayer().getInventory().getItemInMainHand().getType() != Material.COMPASS) return;
|
||||
if (event.getAction() != Action.RIGHT_CLICK_AIR) return;
|
||||
WarpComponent warpComponent = SWPlayer.of(event.getPlayer()).getComponent(WarpComponent.class).orElse(null);
|
||||
if (warpComponent == null || warpComponent.selected.size() != 1) return;
|
||||
Location location = warpComponent.selected.get(0);
|
||||
event.getPlayer().teleport(location);
|
||||
event.getPlayer().playSound(location, Sound.ENTITY_ENDERMAN_TELEPORT, SoundCategory.PLAYERS, 1, 1);
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
warpEntityServer.computeIfPresent(event.getPlayer(), (player, rEntityServer) -> {
|
||||
rEntityServer.close();
|
||||
return null;
|
||||
});
|
||||
selected.remove(event.getPlayer());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ public class AntiBauAddMemberFix implements Listener {
|
||||
}
|
||||
if (BauweltMember.getBauMember(BauServer.getInstance().getOwner(), event.getPlayer().getUniqueId()) == null) {
|
||||
event.getPlayer().kickPlayer("");
|
||||
throw new SecurityException("The player " + event.getPlayer().getName() + " joined on the server of " + SteamwarUser.get(BauServer.getInstance().getOwnerID()).getUserName() + " without being added!");
|
||||
throw new SecurityException("The player " + event.getPlayer().getName() + " joined on the server of " + SteamwarUser.byId(BauServer.getInstance().getOwnerID()).getUserName() + " without being added!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -59,18 +59,14 @@ public class BauMemberUpdate extends PacketHandler implements Listener {
|
||||
Set<Player> newSpectator = new HashSet<>();
|
||||
Set<Player> newBuilder = new HashSet<>();
|
||||
Bukkit.getOnlinePlayers().forEach(player -> {
|
||||
if (Permission.REAL_SPECTATOR.hasPermission(player)) {
|
||||
if (Permission.SPECTATOR.hasPermission(player)) {
|
||||
if (!SPECTATORS.contains(player)) {
|
||||
SPECTATORS.add(player);
|
||||
Permission.removeForceOnlySpectator(player);
|
||||
newSpectator.add(player);
|
||||
player.addPotionEffect(new PotionEffect(PotionEffectType.GLOWING, -1, 1, false,false, false));
|
||||
showSpectatorNotice(player);
|
||||
}
|
||||
} else {
|
||||
if (Permission.SUPERVISOR.hasPermission(player)) {
|
||||
Permission.removeForceOnlySpectator(player);
|
||||
}
|
||||
if (SPECTATORS.contains(player)) {
|
||||
SPECTATORS.remove(player);
|
||||
newBuilder.add(player);
|
||||
|
||||
@@ -21,6 +21,7 @@ package de.steamwar.bausystem.features.world;
|
||||
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.TNTPrimed;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
@@ -31,6 +32,7 @@ public class OtherTNTListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onExplosion(EntityExplodeEvent e) {
|
||||
if (!(e instanceof TNTPrimed)) return;
|
||||
e.blockList().removeIf(block -> {
|
||||
if(block.getType() == Material.TNT) {
|
||||
return false;
|
||||
|
||||
@@ -49,6 +49,7 @@ import java.util.Set;
|
||||
@Linked
|
||||
public class SpectatorListener implements Listener {
|
||||
|
||||
private static final TechHider techHider;
|
||||
private static final Set<Player> NO_TECHHIDER = new HashSet<>();
|
||||
|
||||
static {
|
||||
@@ -100,10 +101,20 @@ public class SpectatorListener implements Listener {
|
||||
materials.add(Material.WATER);
|
||||
materials.remove(Material.BARRIER);
|
||||
materials.remove(Material.STONE);
|
||||
TechHider techHider = new TechHider((TechHider.LocationEvaluator) (player, i, i1) -> {
|
||||
return Permission.BUILD.hasPermission(player) || Permission.isTempOnlySpectator(player) || NO_TECHHIDER.contains(player);
|
||||
techHider = new TechHider((TechHider.LocationEvaluator) (player, i, i1) -> {
|
||||
return Permission.BUILD.hasPermission(player) || NO_TECHHIDER.contains(player);
|
||||
}, Material.END_STONE, materials, new HashSet<>());
|
||||
techHider.enable();
|
||||
}
|
||||
|
||||
private static void enableOrDisableTechhider() {
|
||||
boolean enable = Bukkit.getOnlinePlayers()
|
||||
.stream()
|
||||
.anyMatch(player -> !(Permission.BUILD.hasPermission(player) || NO_TECHHIDER.contains(player)));
|
||||
if (enable) {
|
||||
techHider.enable();
|
||||
} else {
|
||||
techHider.disable();
|
||||
}
|
||||
}
|
||||
|
||||
public static void toggleNoTechHider(Player player) {
|
||||
@@ -113,6 +124,7 @@ public class SpectatorListener implements Listener {
|
||||
NO_TECHHIDER.add(player);
|
||||
}
|
||||
resendChunks(player);
|
||||
enableOrDisableTechhider();
|
||||
}
|
||||
|
||||
private static void resendChunks(Player player) {
|
||||
@@ -131,6 +143,7 @@ public class SpectatorListener implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||
enableOrDisableTechhider();
|
||||
if (BauSystem.DEV_SERVER) return;
|
||||
if (event.getPlayer().getUniqueId().equals(BauServer.getInstance().getOwner())) {
|
||||
return;
|
||||
@@ -152,6 +165,7 @@ public class SpectatorListener implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void onBauMemberUpdate(BauMemberUpdateEvent event) {
|
||||
enableOrDisableTechhider();
|
||||
if (!anySupervisorOnline(null) && !BauSystem.DEV_SERVER) {
|
||||
Bukkit.getOnlinePlayers().forEach(player -> {
|
||||
player.kickPlayer("");
|
||||
@@ -161,7 +175,6 @@ public class SpectatorListener implements Listener {
|
||||
|
||||
event.getChanged().forEach(player -> {
|
||||
NO_TECHHIDER.remove(player);
|
||||
if (Permission.isTempOnlySpectator(player)) return;
|
||||
resendChunks(player);
|
||||
});
|
||||
}
|
||||
@@ -169,6 +182,7 @@ public class SpectatorListener implements Listener {
|
||||
@EventHandler
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
NO_TECHHIDER.remove(event.getPlayer());
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), SpectatorListener::enableOrDisableTechhider, 1);
|
||||
if (BauSystem.DEV_SERVER) return;
|
||||
if (!anySupervisorOnline(event.getPlayer())) {
|
||||
Bukkit.getOnlinePlayers().forEach(player -> {
|
||||
|
||||
@@ -23,6 +23,7 @@ import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.bausystem.region.Point;
|
||||
import de.steamwar.bausystem.region.Region;
|
||||
import de.steamwar.bausystem.utils.FlatteningWrapper;
|
||||
import de.steamwar.core.SWPlayer;
|
||||
import de.steamwar.core.WorldEditRenderer;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import de.steamwar.linkage.MinVersion;
|
||||
@@ -35,13 +36,10 @@ import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@@ -71,32 +69,23 @@ public class SelectAdjacent implements Listener {
|
||||
new Vector(0, -1, -1),
|
||||
};
|
||||
|
||||
private Map<Player, Selector> selectors = new HashMap<>();
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerInteract(PlayerInteractEvent event) {
|
||||
if (!event.hasItem()) return;
|
||||
if (event.getItem().getType() != Material.WOODEN_AXE) return;
|
||||
Selector selector = selectors.get(event.getPlayer());
|
||||
if (selector != null) selector.cancel();
|
||||
if (!event.getPlayer().isSneaking()) return;
|
||||
if (event.getAction() != Action.LEFT_CLICK_BLOCK) return;
|
||||
Material material = event.getPlayer().getInventory().getItemInOffHand().getType();
|
||||
Selector selector;
|
||||
if (material.isAir()) {
|
||||
selector = new Selector(event.getClickedBlock(), event.getPlayer(), __ -> true);
|
||||
} else {
|
||||
selector = new Selector(event.getClickedBlock(), event.getPlayer(), type -> type == material);
|
||||
}
|
||||
selectors.put(event.getPlayer(), selector);
|
||||
SWPlayer.of(event.getPlayer()).setComponent(selector);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
Selector selector = selectors.remove(event.getPlayer());
|
||||
if (selector != null) selector.cancel();
|
||||
}
|
||||
|
||||
private class Selector {
|
||||
private class Selector implements SWPlayer.Component {
|
||||
|
||||
private static final int MAX_BLOCKS = 500_000;
|
||||
|
||||
@@ -154,6 +143,7 @@ public class SelectAdjacent implements Listener {
|
||||
if (toCalc.isEmpty() || seen.size() > MAX_BLOCKS) {
|
||||
bukkitTask.cancel();
|
||||
player.sendTitle("§aDone", "§e" + volume + " §7Blocks", 0, 20, 5);
|
||||
SWPlayer.of(player).removeComponent(Selector.class);
|
||||
}
|
||||
}, 1, 1);
|
||||
}
|
||||
@@ -190,5 +180,10 @@ public class SelectAdjacent implements Listener {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUnmount(SWPlayer player) {
|
||||
cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ public class XrayCommand extends SWCommand implements Listener, ScoreboardElemen
|
||||
if (hidden.containsKey(region) && hidden.get(region).contains(player)) {
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||
PlayerMovementWrapper.impl.setPosition(player, o);
|
||||
}, 1L);
|
||||
}, 0);
|
||||
return null;
|
||||
}
|
||||
return o;
|
||||
|
||||
@@ -50,5 +50,6 @@ tasks.register<DevServer>("DevBau21") {
|
||||
description = "Run a 1.21 Dev Bau"
|
||||
dependsOn(":SpigotCore:shadowJar")
|
||||
dependsOn(":BauSystem:shadowJar")
|
||||
dependsOn(":SchematicSystem:shadowJar")
|
||||
template = "Bau21"
|
||||
}
|
||||
|
||||
@@ -18,11 +18,26 @@
|
||||
*/
|
||||
|
||||
plugins {
|
||||
steamwar.java
|
||||
steamwar.kotlin
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(8)
|
||||
}
|
||||
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly(libs.sqlite)
|
||||
|
||||
implementation("org.yaml:snakeyaml:2.2")
|
||||
}
|
||||
|
||||
compileOnlyApi("org.jetbrains.kotlin:kotlin-stdlib:2.2.21")
|
||||
compileOnlyApi(libs.exposedCore)
|
||||
compileOnlyApi(libs.exposedDao)
|
||||
compileOnlyApi(libs.exposedJdbc)
|
||||
compileOnlyApi(libs.exposedTime)
|
||||
}
|
||||
|
||||
@@ -1,125 +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.sql;
|
||||
|
||||
import de.steamwar.sql.internal.Field;
|
||||
import de.steamwar.sql.internal.SqlTypeMapper;
|
||||
import de.steamwar.sql.internal.Statement;
|
||||
import de.steamwar.sql.internal.Table;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.time.Instant;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class AuditLog {
|
||||
|
||||
static {
|
||||
SqlTypeMapper.nameEnumMapper(AuditLog.Type.class);
|
||||
}
|
||||
|
||||
public static final String SERVER_NAME_VELOCITY = "Velocity";
|
||||
|
||||
private static final Table<AuditLog> table = new Table<>(AuditLog.class);
|
||||
|
||||
private static final Statement create = table.insertFields(true, "time", "serverName", "serverOwner", "actor", "actionType", "actionText");
|
||||
|
||||
@Getter
|
||||
@Field
|
||||
private final Timestamp time;
|
||||
|
||||
@Getter
|
||||
@Field
|
||||
private final String serverName;
|
||||
|
||||
@Field(nullable = true)
|
||||
private final int serverOwner;
|
||||
|
||||
@Field
|
||||
private final int actor;
|
||||
|
||||
@Getter
|
||||
@Field
|
||||
private final Type actionType;
|
||||
|
||||
@Getter
|
||||
@Field
|
||||
private final String actionText;
|
||||
|
||||
public enum Type {
|
||||
JOIN,
|
||||
LEAVE,
|
||||
COMMAND,
|
||||
SENSITIVE_COMMAND,
|
||||
|
||||
CHAT,
|
||||
GUI_OPEN,
|
||||
GUI_CLOSE,
|
||||
GUI_CLICK,
|
||||
}
|
||||
|
||||
private static void create(String serverName, SteamwarUser serverOwner, SteamwarUser actor, Type actionType, String text) {
|
||||
create.insertGetKey(Timestamp.from(Instant.now()), serverName, serverOwner, actor, actionType, text);
|
||||
}
|
||||
|
||||
public static void createJoin(@NonNull String jointServerName, SteamwarUser serverOwner, @NonNull SteamwarUser joinedPlayer) {
|
||||
create(jointServerName, serverOwner, joinedPlayer, Type.JOIN, "");
|
||||
}
|
||||
|
||||
public static void createLeave(@NonNull String leftServerName, SteamwarUser serverOwner, @NonNull SteamwarUser joinedPlayer) {
|
||||
create(leftServerName, serverOwner, joinedPlayer, Type.LEAVE, "");
|
||||
}
|
||||
|
||||
public static void createCommand(@NonNull String serverName, SteamwarUser serverOwner, SteamwarUser player, @NonNull String command) {
|
||||
if (player == null) return;
|
||||
create(serverName, serverOwner, player, Type.COMMAND, command);
|
||||
}
|
||||
|
||||
public static void createSensitiveCommand(@NonNull String serverName, SteamwarUser serverOwner, SteamwarUser player, @NonNull String command) {
|
||||
if (player == null) return;
|
||||
create(serverName, serverOwner, player, Type.SENSITIVE_COMMAND, command);
|
||||
}
|
||||
|
||||
public static void createChat(@NonNull String serverName, SteamwarUser serverOwner, @NonNull SteamwarUser chatter, @NonNull String chat) {
|
||||
create(serverName, serverOwner, chatter, Type.CHAT, chat);
|
||||
}
|
||||
|
||||
public static void createGuiOpen(@NonNull String serverName, SteamwarUser serverOwner, @NonNull SteamwarUser player, @NonNull String guiName) {
|
||||
create(serverName, serverOwner, player, Type.GUI_OPEN, guiName);
|
||||
}
|
||||
|
||||
public static void createGuiClick(@NonNull String serverName, SteamwarUser serverOwner, @NonNull SteamwarUser player, @NonNull String guiName, @NonNull String clickType, int slot, @NonNull String itemName) {
|
||||
create(serverName, serverOwner, player, Type.GUI_CLICK, "Gui: " + guiName + "\nSlot: " + slot + "\nClickType: " + clickType + "\nItemName: " + itemName);
|
||||
}
|
||||
|
||||
public static void createGuiClose(@NonNull String serverName, SteamwarUser serverOwner, @NonNull SteamwarUser player, @NonNull String guiName) {
|
||||
create(serverName, serverOwner, player, Type.GUI_CLOSE, guiName);
|
||||
}
|
||||
|
||||
public SteamwarUser getServerOwner() {
|
||||
return SteamwarUser.get(serverOwner);
|
||||
}
|
||||
|
||||
public SteamwarUser getActor() {
|
||||
return SteamwarUser.get(actor);
|
||||
}
|
||||
}
|
||||
121
CommonCore/SQL/src/de/steamwar/sql/AuditLog.kt
Normal file
121
CommonCore/SQL/src/de/steamwar/sql/AuditLog.kt
Normal file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* 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.sql
|
||||
|
||||
import de.steamwar.sql.internal.useDb
|
||||
import org.jetbrains.exposed.v1.core.dao.id.EntityID
|
||||
import org.jetbrains.exposed.v1.core.dao.id.IntIdTable
|
||||
import org.jetbrains.exposed.v1.dao.IntEntity
|
||||
import org.jetbrains.exposed.v1.dao.IntEntityClass
|
||||
import org.jetbrains.exposed.v1.javatime.timestamp
|
||||
import java.time.Instant
|
||||
|
||||
object AuditLogTable: IntIdTable("AuditLog", "AuditLogId") {
|
||||
val time = timestamp("Time")
|
||||
val server = varchar("ServerName", 255)
|
||||
val serverOwner = reference("ServerOwner", SteamwarUserTable).nullable()
|
||||
val actor = reference("Actor", SteamwarUserTable)
|
||||
val action = enumerationByName("ActionType", 255, AuditLog.Type::class)
|
||||
val actionText = text("ActionText")
|
||||
}
|
||||
|
||||
class AuditLog(id: EntityID<Int>): IntEntity(id) {
|
||||
companion object: IntEntityClass<AuditLog>(AuditLogTable) {
|
||||
const val SERVER_NAME_VELOCITY: String = "Velocity"
|
||||
|
||||
private fun create(
|
||||
serverName: String,
|
||||
serverOwner: SteamwarUser?,
|
||||
actor: SteamwarUser,
|
||||
actionType: Type,
|
||||
text: String = ""
|
||||
) = useDb {
|
||||
new {
|
||||
this.time = Instant.now()
|
||||
this.server = serverName
|
||||
this.serverOwner = serverOwner?.id
|
||||
this.actor = actor.id
|
||||
this.action = actionType
|
||||
this.actionText = text
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun createJoin(jointServerName: String, serverOwner: SteamwarUser?, joinedPlayer: SteamwarUser) = create(jointServerName, serverOwner, joinedPlayer, Type.JOIN)
|
||||
|
||||
@JvmStatic
|
||||
fun createLeave(leftServerName: String, serverOwner: SteamwarUser?, joinedPlayer: SteamwarUser) = create(leftServerName, serverOwner, joinedPlayer, Type.LEAVE)
|
||||
|
||||
@JvmStatic
|
||||
fun createCommand(serverName: String, serverOwner: SteamwarUser?, player: SteamwarUser?, command: String) = player?.let { create(serverName, serverOwner, it, Type.COMMAND, command) }
|
||||
|
||||
@JvmStatic
|
||||
fun createSensitiveCommand(
|
||||
serverName: String,
|
||||
serverOwner: SteamwarUser?,
|
||||
player: SteamwarUser?,
|
||||
command: String
|
||||
) = player?.let { create(serverName, serverOwner, it, Type.SENSITIVE_COMMAND, command) }
|
||||
|
||||
@JvmStatic
|
||||
fun createChat(serverName: String, serverOwner: SteamwarUser?, chatter: SteamwarUser, chat: String) = create(serverName, serverOwner, chatter, Type.CHAT, chat)
|
||||
|
||||
@JvmStatic
|
||||
fun createGuiOpen(serverName: String, serverOwner: SteamwarUser?, player: SteamwarUser, guiName: String) = create(serverName, serverOwner, player, Type.GUI_OPEN, guiName)
|
||||
|
||||
@JvmStatic
|
||||
fun createGuiClick(
|
||||
serverName: String,
|
||||
serverOwner: SteamwarUser?,
|
||||
player: SteamwarUser,
|
||||
guiName: String,
|
||||
clickType: String,
|
||||
slot: Int,
|
||||
itemName: String
|
||||
) = create(
|
||||
serverName,
|
||||
serverOwner,
|
||||
player,
|
||||
Type.GUI_CLICK,
|
||||
"Gui: $guiName\nSlot: $slot\nClickType: $clickType\nItemName: $itemName"
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
fun createGuiClose(serverName: String, serverOwner: SteamwarUser?, player: SteamwarUser, guiName: String) = create(serverName, serverOwner, player, Type.GUI_CLOSE, guiName)
|
||||
}
|
||||
|
||||
var time by AuditLogTable.time
|
||||
var server by AuditLogTable.server
|
||||
var serverOwner by AuditLogTable.serverOwner
|
||||
var actor by AuditLogTable.actor
|
||||
var action by AuditLogTable.action
|
||||
var actionText by AuditLogTable.actionText
|
||||
|
||||
enum class Type {
|
||||
JOIN,
|
||||
LEAVE,
|
||||
COMMAND,
|
||||
SENSITIVE_COMMAND,
|
||||
CHAT,
|
||||
GUI_OPEN,
|
||||
GUI_CLOSE,
|
||||
GUI_CLICK,
|
||||
}
|
||||
}
|
||||
@@ -1,67 +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.sql;
|
||||
|
||||
import de.steamwar.sql.internal.Field;
|
||||
import de.steamwar.sql.internal.SelectStatement;
|
||||
import de.steamwar.sql.internal.Statement;
|
||||
import de.steamwar.sql.internal.Table;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class BannedUserIPs {
|
||||
|
||||
private static final Table<BannedUserIPs> table = new Table<>(BannedUserIPs.class);
|
||||
|
||||
private static final SelectStatement<BannedUserIPs> getByID = table.selectFields("UserID");
|
||||
private static final SelectStatement<BannedUserIPs> getByIP = new SelectStatement<>(table, "SELECT * FROM BannedUserIPs WHERE IP = ? ORDER BY Timestamp DESC");
|
||||
private static final Statement banIP = table.insertAll();
|
||||
private static final Statement unbanIPs = table.deleteFields("UserID");
|
||||
|
||||
@Getter
|
||||
@Field(keys = {Table.PRIMARY})
|
||||
private final int userID;
|
||||
@Getter
|
||||
@Field(def = "CURRENT_TIMESTAMP")
|
||||
private final Timestamp timestamp;
|
||||
@Field(keys = {Table.PRIMARY})
|
||||
private final String ip;
|
||||
|
||||
public static List<BannedUserIPs> get(int userID) {
|
||||
return getByID.listSelect(userID);
|
||||
}
|
||||
|
||||
public static List<BannedUserIPs> get(String ip) {
|
||||
return getByIP.listSelect(ip);
|
||||
}
|
||||
|
||||
public static void banIP(int userID, String ip){
|
||||
banIP.update(userID, Timestamp.from(Instant.now()), ip);
|
||||
}
|
||||
|
||||
public static void unbanIPs(int userID) {
|
||||
unbanIPs.update(userID);
|
||||
}
|
||||
}
|
||||
78
CommonCore/SQL/src/de/steamwar/sql/BannedUserIPs.kt
Normal file
78
CommonCore/SQL/src/de/steamwar/sql/BannedUserIPs.kt
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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.sql
|
||||
|
||||
import de.steamwar.sql.internal.useDb
|
||||
import org.jetbrains.exposed.v1.core.dao.id.CompositeID
|
||||
import org.jetbrains.exposed.v1.core.dao.id.CompositeIdTable
|
||||
import org.jetbrains.exposed.v1.core.dao.id.EntityID
|
||||
import org.jetbrains.exposed.v1.core.eq
|
||||
import org.jetbrains.exposed.v1.dao.CompositeEntity
|
||||
import org.jetbrains.exposed.v1.dao.CompositeEntityClass
|
||||
import org.jetbrains.exposed.v1.javatime.timestamp
|
||||
import org.jetbrains.exposed.v1.jdbc.deleteWhere
|
||||
import org.jetbrains.exposed.v1.jdbc.insertIgnore
|
||||
import java.sql.Timestamp
|
||||
import java.time.Instant
|
||||
|
||||
object BannedUserIPsTable: CompositeIdTable("BannedUserIPs") {
|
||||
val userId = reference("UserID", SteamwarUserTable)
|
||||
val timestamp = timestamp("Timestamp")
|
||||
val ip = varchar("IP", 45)
|
||||
|
||||
override val primaryKey = PrimaryKey(userId, ip)
|
||||
}
|
||||
|
||||
class BannedUserIPs(id: EntityID<CompositeID>): CompositeEntity(id) {
|
||||
companion object: CompositeEntityClass<BannedUserIPs>(BannedUserIPsTable) {
|
||||
|
||||
@JvmStatic
|
||||
fun get(userId: Int) = useDb {
|
||||
find { BannedUserIPsTable.userId eq userId }.toList()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun get(ip: String) = useDb {
|
||||
find { BannedUserIPsTable.ip eq ip }.toList()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun banIP(userId: Int, ip: String) = useDb {
|
||||
BannedUserIPsTable.insertIgnore {
|
||||
it[BannedUserIPsTable.userId] = userId
|
||||
it[BannedUserIPsTable.ip] = ip
|
||||
it[BannedUserIPsTable.timestamp] = Instant.now()
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun unbanIPs(userId: Int) = useDb {
|
||||
BannedUserIPsTable.deleteWhere { BannedUserIPsTable.userId eq userId }
|
||||
}
|
||||
}
|
||||
|
||||
val userID by BannedUserIPsTable.userId.transform({ EntityID(it, SteamwarUserTable) }, { it.value })
|
||||
val timestamp: Timestamp by BannedUserIPsTable.timestamp.transform({ it.toInstant() }, { Timestamp.from(it) })
|
||||
val ip by BannedUserIPsTable.ip
|
||||
|
||||
fun remove() = useDb {
|
||||
delete()
|
||||
}
|
||||
}
|
||||
@@ -1,123 +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.sql;
|
||||
|
||||
import de.steamwar.sql.internal.Field;
|
||||
import de.steamwar.sql.internal.SelectStatement;
|
||||
import de.steamwar.sql.internal.Statement;
|
||||
import de.steamwar.sql.internal.Table;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class BauweltMember {
|
||||
private static final Map<Integer, BauweltMember> memberCache = new HashMap<>();
|
||||
|
||||
public static void clear() {
|
||||
memberCache.clear();
|
||||
}
|
||||
|
||||
private static final Table<BauweltMember> table = new Table<>(BauweltMember.class);
|
||||
private static final SelectStatement<BauweltMember> getMember = table.select(Table.PRIMARY);
|
||||
private static final SelectStatement<BauweltMember> getMembers = table.selectFields("BauweltID");
|
||||
private static final Statement update = table.insertAll();
|
||||
private static final Statement delete = table.delete(Table.PRIMARY);
|
||||
|
||||
public static void addMember(UUID ownerID, UUID memberID) {
|
||||
new BauweltMember(SteamwarUser.get(ownerID).getId(), SteamwarUser.get(memberID).getId(), false, false).updateDB();
|
||||
}
|
||||
|
||||
public static BauweltMember getBauMember(UUID ownerID, UUID memberID){
|
||||
return getBauMember(SteamwarUser.get(ownerID).getId(), SteamwarUser.get(memberID).getId());
|
||||
}
|
||||
|
||||
public static BauweltMember getBauMember(int ownerID, int memberID){
|
||||
BauweltMember member = memberCache.get(memberID);
|
||||
if(member != null && member.bauweltID == ownerID)
|
||||
return member;
|
||||
return getMember.select(ownerID, memberID);
|
||||
}
|
||||
|
||||
public static List<BauweltMember> getMembers(UUID bauweltID){
|
||||
return getMembers(SteamwarUser.get(bauweltID).getId());
|
||||
}
|
||||
|
||||
public static List<BauweltMember> getMembers(int bauweltID){
|
||||
return getMembers.listSelect(bauweltID);
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Field(keys = {Table.PRIMARY})
|
||||
private final int bauweltID;
|
||||
@Getter
|
||||
@Field(keys = {Table.PRIMARY})
|
||||
private final int memberID;
|
||||
@Getter
|
||||
@Field(def = "0")
|
||||
private boolean worldEdit;
|
||||
@Getter
|
||||
@Field(def = "0")
|
||||
private boolean world;
|
||||
|
||||
public BauweltMember(int bauweltID, int memberID, boolean worldEdit, boolean world) {
|
||||
this.bauweltID = bauweltID;
|
||||
this.memberID = memberID;
|
||||
this.worldEdit = worldEdit;
|
||||
this.world = world;
|
||||
memberCache.put(memberID, this);
|
||||
}
|
||||
|
||||
public void setWorldEdit(boolean worldEdit) {
|
||||
this.worldEdit = worldEdit;
|
||||
updateDB();
|
||||
}
|
||||
|
||||
public void setWorld(boolean world) {
|
||||
this.world = world;
|
||||
updateDB();
|
||||
}
|
||||
|
||||
private void updateDB(){
|
||||
update.update(bauweltID, memberID, worldEdit, world);
|
||||
}
|
||||
|
||||
public void remove(){
|
||||
delete.update(bauweltID, memberID);
|
||||
memberCache.remove(memberID);
|
||||
}
|
||||
|
||||
public boolean isBuild() {
|
||||
return worldEdit;
|
||||
}
|
||||
|
||||
public boolean isSupervisor() {
|
||||
return world;
|
||||
}
|
||||
|
||||
public void setBuild(boolean build) {
|
||||
this.worldEdit = build;
|
||||
updateDB();
|
||||
}
|
||||
|
||||
public void setSupervisor(boolean supervisor) {
|
||||
this.world = supervisor;
|
||||
updateDB();
|
||||
}
|
||||
}
|
||||
130
CommonCore/SQL/src/de/steamwar/sql/BauweltMember.kt
Normal file
130
CommonCore/SQL/src/de/steamwar/sql/BauweltMember.kt
Normal file
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* 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.sql
|
||||
|
||||
import de.steamwar.sql.BauweltMemberTable.bauweltId
|
||||
import de.steamwar.sql.internal.useDb
|
||||
import org.jetbrains.exposed.v1.core.and
|
||||
import org.jetbrains.exposed.v1.core.dao.id.CompositeID
|
||||
import org.jetbrains.exposed.v1.core.dao.id.CompositeIdTable
|
||||
import org.jetbrains.exposed.v1.core.dao.id.EntityID
|
||||
import org.jetbrains.exposed.v1.core.eq
|
||||
import org.jetbrains.exposed.v1.dao.CompositeEntity
|
||||
import org.jetbrains.exposed.v1.dao.CompositeEntityClass
|
||||
import org.jetbrains.exposed.v1.jdbc.insertIgnore
|
||||
import java.util.*
|
||||
|
||||
object BauweltMemberTable: CompositeIdTable("BauweltMember") {
|
||||
val bauweltId = reference("BauweltID", SteamwarUserTable)
|
||||
val memberId = reference("MemberID", SteamwarUserTable)
|
||||
val build = bool("Build")
|
||||
val worldEdit = bool("WorldEdit")
|
||||
val world = bool("World")
|
||||
|
||||
override val primaryKey = PrimaryKey(bauweltId, memberId)
|
||||
|
||||
init {
|
||||
addIdColumn(bauweltId)
|
||||
addIdColumn(memberId)
|
||||
}
|
||||
}
|
||||
|
||||
class BauweltMember(id: EntityID<CompositeID>): CompositeEntity(id) {
|
||||
companion object: CompositeEntityClass<BauweltMember>(BauweltMemberTable) {
|
||||
private val cache = mutableMapOf<Int, BauweltMember>()
|
||||
|
||||
private fun cache(member: BauweltMember) = cache.put(member.memberID, member)
|
||||
|
||||
@JvmStatic
|
||||
fun clear() = cache.clear()
|
||||
|
||||
@JvmStatic
|
||||
@Deprecated("Use addMember(ownerId: Int, newMemberId: Int)")
|
||||
fun addMember(ownerId: UUID, newMemberId: UUID) = addMember(SteamwarUser.get(ownerId)!!.id, SteamwarUser.get(newMemberId)!!.id)
|
||||
|
||||
@JvmStatic
|
||||
fun addMember(ownerId: Int, newMemberId: Int) = addMember(EntityID(ownerId, SteamwarUserTable), EntityID(newMemberId, SteamwarUserTable))
|
||||
|
||||
fun addMember(ownerId: EntityID<Int>, newMemberId: EntityID<Int>) = useDb {
|
||||
BauweltMemberTable.insertIgnore {
|
||||
it[bauweltId] = ownerId
|
||||
it[memberId] = newMemberId
|
||||
it[build] = false
|
||||
it[worldEdit] = false
|
||||
it[world] = false
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@Deprecated("Use getBauMember(bauwelt: Int, member: Int)")
|
||||
fun getBauMember(bauwelt: UUID, member: UUID) = useDb {
|
||||
find { (bauweltId eq SteamwarUser.get(bauwelt)!!.id) and (BauweltMemberTable.memberId eq SteamwarUser.get(member)!!.id) }.firstOrNull()?.also { cache(it) }
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getBauMember(bauwelt: Int, member: Int) = useDb {
|
||||
find { (bauweltId eq bauwelt) and (BauweltMemberTable.memberId eq member) }.firstOrNull()?.also { cache(it) }
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@Deprecated("Use getMembers(bauwelt: Int)")
|
||||
fun getMembers(bauwelt: UUID) = getMembers(SteamwarUser.get(bauwelt)!!.id.value)
|
||||
|
||||
@JvmStatic
|
||||
fun getMembers(bauwelt: Int) = useDb {
|
||||
find { bauweltId eq bauwelt }.toList().also { it.forEach { cache(it) } }
|
||||
}
|
||||
}
|
||||
|
||||
val bauweltID by BauweltMemberTable.bauweltId.transform({ EntityID(it, SteamwarUserTable) }, { it.value })
|
||||
val memberID by BauweltMemberTable.memberId.transform({ EntityID(it, SteamwarUserTable) }, { it.value })
|
||||
private var worldEditInternal by BauweltMemberTable.worldEdit
|
||||
var worldEdit: Boolean
|
||||
get() = worldEditInternal
|
||||
set(value) = useDb {
|
||||
worldEditInternal = value
|
||||
}
|
||||
private var buildInternal by BauweltMemberTable.build
|
||||
var build: Boolean
|
||||
get() = buildInternal
|
||||
set(value) = useDb {
|
||||
buildInternal = value
|
||||
}
|
||||
private var worldInternal by BauweltMemberTable.world
|
||||
var world: Boolean
|
||||
get() = worldInternal
|
||||
set(value) = useDb {
|
||||
worldInternal = value
|
||||
}
|
||||
var supervisor: Boolean
|
||||
get() = world
|
||||
set(value) = useDb {
|
||||
world = value
|
||||
}
|
||||
|
||||
fun isBuild() = build
|
||||
fun isSupervisor() = world
|
||||
fun isWorldEdit() = build
|
||||
fun isWorld() = world
|
||||
|
||||
fun remove() = useDb {
|
||||
delete()
|
||||
}
|
||||
}
|
||||
@@ -1,101 +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.sql;
|
||||
|
||||
import de.steamwar.sql.internal.Field;
|
||||
import de.steamwar.sql.internal.SelectStatement;
|
||||
import de.steamwar.sql.internal.Statement;
|
||||
import de.steamwar.sql.internal.Table;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class CheckedSchematic {
|
||||
|
||||
private static final Table<CheckedSchematic> table = new Table<>(CheckedSchematic.class);
|
||||
private static final SelectStatement<CheckedSchematic> statusOfNode = new SelectStatement<>(table, "SELECT * FROM CheckedSchematic WHERE NodeId = ? AND DeclineReason != 'Prüfvorgang abgebrochen' ORDER BY EndTime DESC");
|
||||
private static final SelectStatement<CheckedSchematic> nodeHistory = new SelectStatement<>(table, "SELECT * FROM CheckedSchematic WHERE NodeId = ? AND DeclineReason != '' AND DeclineReason != 'Prüfvorgang abgebrochen' ORDER BY EndTime DESC");
|
||||
private static final Statement insert = table.insertAll();
|
||||
|
||||
private static final SelectStatement<CheckedSchematic> getUnseen = new SelectStatement<>(table, "SELECT * FROM CheckedSchematic WHERE Seen = 0 AND NodeOwner = ? ORDER BY StartTime DESC");
|
||||
private static final Statement updateSeen = new Statement("UPDATE CheckedSchematic SET Seen = ? WHERE StartTime = ? AND EndTime = ? AND NodeName = ?");
|
||||
|
||||
public static void create(SchematicNode node, int validator, Timestamp startTime, Timestamp endTime, String reason, boolean seen) {
|
||||
insert.update(node.getId(), node.getOwner(), node.getName(), validator, startTime, endTime, reason, seen, node.getSchemtype().toDB().substring(1));
|
||||
}
|
||||
|
||||
public static List<CheckedSchematic> getLastDeclinedOfNode(int node) {
|
||||
return statusOfNode.listSelect(node);
|
||||
}
|
||||
|
||||
public static List<CheckedSchematic> previousChecks(SchematicNode node) {
|
||||
return nodeHistory.listSelect(node.getId());
|
||||
}
|
||||
|
||||
public static List<CheckedSchematic> getUnseen(SteamwarUser owner) {
|
||||
return getUnseen.listSelect(owner);
|
||||
}
|
||||
|
||||
@Field(nullable = true)
|
||||
private final Integer nodeId;
|
||||
@Field
|
||||
private final int nodeOwner;
|
||||
@Field
|
||||
private final String nodeName;
|
||||
@Getter
|
||||
@Field
|
||||
private final int validator;
|
||||
@Getter
|
||||
@Field
|
||||
private final Timestamp startTime;
|
||||
@Getter
|
||||
@Field
|
||||
private final Timestamp endTime;
|
||||
@Getter
|
||||
@Field
|
||||
private final String declineReason;
|
||||
@Getter
|
||||
@Field
|
||||
private boolean seen;
|
||||
@Getter
|
||||
@Field
|
||||
private final String nodeType;
|
||||
|
||||
public int getNode() {
|
||||
return nodeId;
|
||||
}
|
||||
|
||||
public String getSchemName() {
|
||||
return nodeName;
|
||||
}
|
||||
|
||||
public int getSchemOwner() {
|
||||
return nodeOwner;
|
||||
}
|
||||
|
||||
public void setSeen(boolean seen) {
|
||||
this.seen = seen;
|
||||
updateSeen.update(seen, startTime, endTime, nodeName);
|
||||
}
|
||||
}
|
||||
100
CommonCore/SQL/src/de/steamwar/sql/CheckedSchematic.kt
Normal file
100
CommonCore/SQL/src/de/steamwar/sql/CheckedSchematic.kt
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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.sql
|
||||
|
||||
import de.steamwar.sql.internal.useDb
|
||||
import org.jetbrains.exposed.v1.core.SortOrder
|
||||
import org.jetbrains.exposed.v1.core.and
|
||||
import org.jetbrains.exposed.v1.core.dao.id.CompositeID
|
||||
import org.jetbrains.exposed.v1.core.dao.id.CompositeIdTable
|
||||
import org.jetbrains.exposed.v1.core.dao.id.EntityID
|
||||
import org.jetbrains.exposed.v1.core.eq
|
||||
import org.jetbrains.exposed.v1.core.neq
|
||||
import org.jetbrains.exposed.v1.dao.CompositeEntity
|
||||
import org.jetbrains.exposed.v1.dao.CompositeEntityClass
|
||||
import org.jetbrains.exposed.v1.javatime.timestamp
|
||||
import org.jetbrains.exposed.v1.jdbc.insertIgnore
|
||||
import java.sql.Timestamp
|
||||
|
||||
object CheckedSchematicTable: CompositeIdTable("CheckedSchematic") {
|
||||
val nodeId = optReference("NodeId", SchematicNodeTable)
|
||||
val nodeOwner = reference("NodeOwner", SteamwarUserTable)
|
||||
val nodeName = varchar("NodeName", 64).entityId()
|
||||
val validator = reference("Validator", SteamwarUserTable)
|
||||
val startTime = timestamp("StartTime").entityId()
|
||||
val endTime = timestamp("EndTime")
|
||||
val declineReason = text("DeclineReason")
|
||||
val seen = bool("Seen")
|
||||
val nodeType = varchar("NodeType", 16)
|
||||
|
||||
init {
|
||||
addIdColumn(nodeOwner)
|
||||
addIdColumn(nodeName)
|
||||
}
|
||||
}
|
||||
|
||||
class CheckedSchematic(id: EntityID<CompositeID>): CompositeEntity(id) {
|
||||
companion object: CompositeEntityClass<CheckedSchematic>(CheckedSchematicTable) {
|
||||
@JvmStatic
|
||||
fun create(node: SchematicNode, validator: Int, startTime: Timestamp, endTime: Timestamp, reason: String, seen: Boolean) = useDb {
|
||||
CheckedSchematicTable.insertIgnore {
|
||||
it[this.nodeId] = node.id
|
||||
it[this.nodeOwner] = EntityID(node.owner, SteamwarUserTable)
|
||||
it[this.nodeName] = node.name
|
||||
it[this.validator] = EntityID(validator, SteamwarUserTable)
|
||||
it[this.startTime] = startTime.toInstant()
|
||||
it[this.endTime] = endTime.toInstant()
|
||||
it[this.declineReason] = reason
|
||||
it[this.seen] = seen
|
||||
it[this.nodeType] = node.schemtype.toDB().substring(1)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getLastDeclinedOfNode(node: Int) = useDb {
|
||||
find { (CheckedSchematicTable.nodeId eq node) and (CheckedSchematicTable.declineReason neq "Prüfvorgang abgebrochen") }.orderBy(CheckedSchematicTable.endTime to SortOrder.DESC).toList()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun previousChecks(node: SchematicNode) = useDb {
|
||||
find { (CheckedSchematicTable.nodeId eq node.id) and (CheckedSchematicTable.declineReason neq "") and (CheckedSchematicTable.declineReason neq "Prüfvorgang abgebrochen") }.orderBy(CheckedSchematicTable.endTime to SortOrder.DESC).toList()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getUnseen(owner: SteamwarUser) = useDb {
|
||||
find { (CheckedSchematicTable.nodeOwner eq owner.id) and (CheckedSchematicTable.seen eq false) }.orderBy(CheckedSchematicTable.endTime to SortOrder.DESC).toList()
|
||||
}
|
||||
}
|
||||
|
||||
val node by CheckedSchematicTable.nodeId.transform({ it?.let { EntityID(it, SchematicNodeTable) } }, { it?.value })
|
||||
val schemOwner by CheckedSchematicTable.nodeOwner.transform({ EntityID(it, SteamwarUserTable) }, { it.value })
|
||||
val nodeName by CheckedSchematicTable.nodeName
|
||||
val schemName get() = nodeName.value
|
||||
val validator by CheckedSchematicTable.validator.transform({ EntityID(it, SteamwarUserTable) }, { it.value })
|
||||
val startTimeId by CheckedSchematicTable.startTime
|
||||
val startTime get() = Timestamp.from(startTimeId.value)
|
||||
val endTime by CheckedSchematicTable.endTime.transform({ it.toInstant() }, { Timestamp.from(it) })
|
||||
val declineReason by CheckedSchematicTable.declineReason
|
||||
private var wasSeen by CheckedSchematicTable.seen
|
||||
var seen: Boolean
|
||||
get() = wasSeen
|
||||
set(value) = useDb { wasSeen = value }
|
||||
val nodeType by CheckedSchematicTable.nodeType
|
||||
}
|
||||
@@ -1,125 +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.sql;
|
||||
|
||||
import de.steamwar.sql.internal.Field;
|
||||
import de.steamwar.sql.internal.SelectStatement;
|
||||
import de.steamwar.sql.internal.Statement;
|
||||
import de.steamwar.sql.internal.Table;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class Event {
|
||||
|
||||
static {
|
||||
SchematicType.Normal.name(); // Ensure SchematicType is loaded.
|
||||
}
|
||||
|
||||
private static final Table<Event> table = new Table<>(Event.class);
|
||||
|
||||
private static final SelectStatement<Event> byCurrent = new SelectStatement<>(table, "SELECT * FROM Event WHERE Start < now() AND End > now()");
|
||||
private static final SelectStatement<Event> byId = table.select(Table.PRIMARY);
|
||||
private static final SelectStatement<Event> byName = table.select("eventName");
|
||||
private static final SelectStatement<Event> byComing = new SelectStatement<>(table, "SELECT * FROM Event WHERE Start > now()");
|
||||
private static final SelectStatement<Event> all = new SelectStatement<>(table, "SELECT * FROM Event");
|
||||
|
||||
private static final Statement create = table.insertFields(true, "eventName", "deadline", "start", "end", "maximumTeamMembers", "publicSchemsOnly");
|
||||
private static final Statement update = table.update(Table.PRIMARY, "eventName", "deadline", "start", "end", "schemType", "maximumTeamMembers", "publicSchemsOnly");
|
||||
private static final Statement delete = table.delete(Table.PRIMARY);
|
||||
|
||||
private static Event current = null;
|
||||
|
||||
public static Event get(){
|
||||
if(current != null && current.now())
|
||||
return current;
|
||||
|
||||
current = byCurrent.select();
|
||||
return current;
|
||||
}
|
||||
|
||||
public static List<Event> getAll(){
|
||||
return all.listSelect();
|
||||
}
|
||||
|
||||
public static Event create(String eventName, Timestamp start, Timestamp end){
|
||||
return get(create.insertGetKey(eventName, start, start, end, 5, false));
|
||||
}
|
||||
|
||||
public static Event get(int eventID){
|
||||
return byId.select(eventID);
|
||||
}
|
||||
|
||||
public static Event get(String eventName) {
|
||||
return byName.select(eventName);
|
||||
}
|
||||
|
||||
public static List<Event> getComing() {
|
||||
return byComing.listSelect();
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Field(keys = {Table.PRIMARY}, autoincrement = true)
|
||||
private final int eventID;
|
||||
@Getter
|
||||
@Field(keys = {"eventName"})
|
||||
private final String eventName;
|
||||
@Getter
|
||||
@Field
|
||||
private final Timestamp deadline;
|
||||
@Getter
|
||||
@Field
|
||||
private final Timestamp start;
|
||||
@Getter
|
||||
@Field
|
||||
private final Timestamp end;
|
||||
@Getter
|
||||
@Field
|
||||
private final int maximumTeamMembers;
|
||||
@Field(nullable = true)
|
||||
private final SchematicType schemType;
|
||||
@Field
|
||||
private final boolean publicSchemsOnly;
|
||||
|
||||
public boolean publicSchemsOnly() {
|
||||
return publicSchemsOnly;
|
||||
}
|
||||
|
||||
public SchematicType getSchematicType() {
|
||||
return schemType;
|
||||
}
|
||||
|
||||
private boolean now() {
|
||||
Instant now = Instant.now();
|
||||
return now.isAfter(start.toInstant()) && now.isBefore(end.toInstant());
|
||||
}
|
||||
|
||||
public void update(String eventName, Timestamp deadline, Timestamp start, Timestamp end, SchematicType schemType, int maximumTeamMembers, boolean publicSchemsOnly) {
|
||||
update.update(eventName, deadline, start, end, schemType, maximumTeamMembers, publicSchemsOnly, eventID);
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
delete.update(eventID);
|
||||
}
|
||||
}
|
||||
121
CommonCore/SQL/src/de/steamwar/sql/Event.kt
Normal file
121
CommonCore/SQL/src/de/steamwar/sql/Event.kt
Normal file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* 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.sql
|
||||
|
||||
import de.steamwar.sql.internal.useDb
|
||||
import org.jetbrains.exposed.v1.core.and
|
||||
import org.jetbrains.exposed.v1.core.dao.id.EntityID
|
||||
import org.jetbrains.exposed.v1.core.dao.id.IntIdTable
|
||||
import org.jetbrains.exposed.v1.core.eq
|
||||
import org.jetbrains.exposed.v1.core.greater
|
||||
import org.jetbrains.exposed.v1.core.lessEq
|
||||
import org.jetbrains.exposed.v1.dao.IntEntity
|
||||
import org.jetbrains.exposed.v1.dao.IntEntityClass
|
||||
import org.jetbrains.exposed.v1.javatime.timestamp
|
||||
import org.jetbrains.exposed.v1.jdbc.insertAndGetId
|
||||
import java.sql.Timestamp
|
||||
import java.time.Instant
|
||||
|
||||
object EventTable : IntIdTable("Event", "EventId") {
|
||||
val name = varchar("EventName", 100).uniqueIndex()
|
||||
val deadline = timestamp("Deadline")
|
||||
val start = timestamp("Start")
|
||||
val end = timestamp("End")
|
||||
val maxPlayers = integer("MaximumTeamMembers")
|
||||
val schemType = varchar("SchemType", 16).nullable()
|
||||
val publicsOnly = bool("PublicSchemsOnly")
|
||||
}
|
||||
|
||||
class Event(id: EntityID<Int>) : IntEntity(id) {
|
||||
companion object : IntEntityClass<Event>(EventTable) {
|
||||
private var current: Event? = null
|
||||
|
||||
@JvmStatic
|
||||
fun get(): Event? = if (current?.now() == true) {
|
||||
current
|
||||
} else useDb {
|
||||
find { EventTable.start.lessEq(Instant.now()) and EventTable.end.greater(Instant.now()) }.firstOrNull()
|
||||
?.also { current == it }
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getAll() = useDb { all().toList() }
|
||||
|
||||
@JvmStatic
|
||||
fun create(name: String, start: Timestamp, end: Timestamp) = useDb {
|
||||
EventTable.insertAndGetId {
|
||||
it[this.name] = name
|
||||
it[this.deadline] = start.toInstant()
|
||||
it[this.start] = start.toInstant()
|
||||
it[this.end] = end.toInstant()
|
||||
it[this.maxPlayers] = 5
|
||||
it[this.publicsOnly] = false
|
||||
}.let { get(it) }
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun byId(id: Int) = useDb { findById(id) }
|
||||
|
||||
@JvmStatic
|
||||
fun get(name: String) = useDb { find { EventTable.name eq name }.firstOrNull() }
|
||||
|
||||
@JvmStatic
|
||||
fun getComing() = useDb { find { EventTable.start greater Instant.now() }.toList() }
|
||||
}
|
||||
|
||||
val eventID by EventTable.id.transform({ EntityID(it, EventTable) }, { it.value })
|
||||
var eventName by EventTable.name
|
||||
private set
|
||||
var deadline: Timestamp by EventTable.deadline.transform({ it.toInstant() }, { Timestamp.from(it) })
|
||||
private set
|
||||
var start: Timestamp by EventTable.start.transform({ it.toInstant() }, { Timestamp.from(it) })
|
||||
private set
|
||||
var end: Timestamp by EventTable.end.transform({ it.toInstant() }, { Timestamp.from(it) })
|
||||
private set
|
||||
var maximumTeamMembers by EventTable.maxPlayers
|
||||
private set
|
||||
var schematicType by EventTable.schemType.transform({ it?.toDB() }, { it?.let { SchematicType.fromDB(it) } })
|
||||
private set
|
||||
var publicSchemsOnly by EventTable.publicsOnly
|
||||
private set
|
||||
|
||||
fun publicSchemsOnly() = publicSchemsOnly
|
||||
fun now() = Instant.now().let { it.isAfter(start.toInstant()) && it.isBefore(end.toInstant()) }
|
||||
|
||||
fun update(
|
||||
name: String,
|
||||
deadline: Timestamp,
|
||||
start: Timestamp,
|
||||
end: Timestamp,
|
||||
schematicType: SchematicType?,
|
||||
maxPlayers: Int,
|
||||
publicSchemsOnly: Boolean
|
||||
) = useDb {
|
||||
this@Event.eventName = name
|
||||
this@Event.deadline = deadline
|
||||
this@Event.start = start
|
||||
this@Event.end = end
|
||||
this@Event.maximumTeamMembers = maxPlayers
|
||||
this@Event.schematicType = schematicType
|
||||
this@Event.publicSchemsOnly = publicSchemsOnly
|
||||
}
|
||||
|
||||
override fun delete() = useDb { super.delete() }
|
||||
}
|
||||
@@ -1,216 +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.sql;
|
||||
|
||||
import de.steamwar.sql.internal.Field;
|
||||
import de.steamwar.sql.internal.SelectStatement;
|
||||
import de.steamwar.sql.internal.Statement;
|
||||
import de.steamwar.sql.internal.Table;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.util.*;
|
||||
|
||||
import static java.time.temporal.ChronoUnit.SECONDS;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class EventFight implements Comparable<EventFight> {
|
||||
|
||||
private static final Table<EventFight> table = new Table<>(EventFight.class);
|
||||
private static final SelectStatement<EventFight> byId = table.select(Table.PRIMARY);
|
||||
private static final SelectStatement<EventFight> byGroup = new SelectStatement<EventFight>(table, "SELECT * FROM EventFight WHERE GroupID = ? ORDER BY StartTime ASC");
|
||||
private static final SelectStatement<EventFight> byGroupLast = new SelectStatement<EventFight>(table, "SELECT * FROM EventFight WHERE GroupID = ? ORDER BY StartTime DESC LIMIT 1");
|
||||
private static final SelectStatement<EventFight> allComing = new SelectStatement<>(table, "SELECT * FROM EventFight WHERE StartTime > now() ORDER BY StartTime ASC");
|
||||
private static final SelectStatement<EventFight> event = new SelectStatement<>(table, "SELECT * FROM EventFight WHERE EventID = ? ORDER BY StartTime ASC");
|
||||
private static final SelectStatement<EventFight> activeFights = new SelectStatement<>(table, "SELECT * FROM EventFight WHERE EventID IN (SELECT EventID FROM Event WHERE Start < now() and End > now()) AND Fight IS NULL AND StartTime < now()");
|
||||
private static final Statement reschedule = table.update(Table.PRIMARY, "StartTime");
|
||||
private static final Statement setResult = table.update(Table.PRIMARY, "Ergebnis");
|
||||
private static final Statement setFight = table.update(Table.PRIMARY, "Fight");
|
||||
|
||||
private static final Statement create = table.insertFields(true, "eventID", "startTime", "spielmodus", "map", "teamBlue", "teamRed", "spectatePort");
|
||||
private static final Statement update = table.update(Table.PRIMARY, "startTime", "spielModus", "map", "teamBlue", "teamRed", "spectatePort");
|
||||
private static final Statement setGroup = table.update(Table.PRIMARY, "GroupID");
|
||||
private static final Statement delete = table.delete(Table.PRIMARY);
|
||||
|
||||
@Getter
|
||||
private static final Queue<EventFight> fights = new PriorityQueue<>();
|
||||
|
||||
public static EventFight get(int fightID) {
|
||||
return byId.select(fightID);
|
||||
}
|
||||
|
||||
public static List<EventFight> get(EventGroup group) {
|
||||
return byGroup.listSelect(group.getId());
|
||||
}
|
||||
|
||||
public static Optional<EventFight> getLast(EventGroup group) {
|
||||
return Optional.ofNullable(byGroupLast.select(group.getId()));
|
||||
}
|
||||
|
||||
public static void loadAllComingFights() {
|
||||
fights.clear();
|
||||
fights.addAll(allComing.listSelect());
|
||||
}
|
||||
|
||||
public static List<EventFight> getEvent(int eventID) {
|
||||
return event.listSelect(eventID);
|
||||
}
|
||||
|
||||
private static List<EventFight> activeFightsCache = null;
|
||||
|
||||
public static void clearActiveFightsCache() {
|
||||
activeFightsCache = null;
|
||||
}
|
||||
|
||||
public static List<EventFight> getActiveFights() {
|
||||
if (activeFightsCache == null) {
|
||||
activeFightsCache = activeFights.listSelect();
|
||||
}
|
||||
return activeFightsCache;
|
||||
}
|
||||
|
||||
public static EventFight create(int event, Timestamp from, String spielmodus, String map, int blueTeam, int redTeam, Integer spectatePort) {
|
||||
return get(create.insertGetKey(event, from, spielmodus, map, blueTeam, redTeam, spectatePort));
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Field
|
||||
private final int eventID;
|
||||
@Getter
|
||||
@Field(keys = {Table.PRIMARY}, autoincrement = true)
|
||||
private final int fightID;
|
||||
@Getter
|
||||
@Setter
|
||||
@Field(nullable = true, def = "null")
|
||||
private Integer groupId;
|
||||
@Getter
|
||||
@Setter
|
||||
@Field
|
||||
private Timestamp startTime;
|
||||
@Getter
|
||||
@Setter
|
||||
@Field
|
||||
private String spielmodus;
|
||||
@Getter
|
||||
@Setter
|
||||
@Field
|
||||
private String map;
|
||||
@Getter
|
||||
@Setter
|
||||
@Field
|
||||
private int teamBlue;
|
||||
@Getter
|
||||
@Setter
|
||||
@Field
|
||||
private int teamRed;
|
||||
@Getter
|
||||
@Setter
|
||||
@Field(nullable = true)
|
||||
private Integer spectatePort;
|
||||
@Getter
|
||||
@Setter
|
||||
@Field(def = "1")
|
||||
private int bestOf;
|
||||
@Getter
|
||||
@Field(def = "0")
|
||||
private int ergebnis;
|
||||
@Field(nullable = true)
|
||||
private int fight;
|
||||
|
||||
public Optional<EventGroup> getGroup() {
|
||||
return Optional.ofNullable(groupId).flatMap(EventGroup::get);
|
||||
}
|
||||
|
||||
public Optional<Team> getWinner() {
|
||||
if(ergebnis == 0)
|
||||
return Optional.empty();
|
||||
return Optional.ofNullable(ergebnis == 1 ? Team.get(teamBlue) : Team.get(teamRed));
|
||||
}
|
||||
|
||||
public Optional<Team> getLosser() {
|
||||
if(ergebnis == 0)
|
||||
return Optional.empty();
|
||||
return Optional.ofNullable(ergebnis == 1 ? Team.get(teamRed) : Team.get(teamBlue));
|
||||
}
|
||||
|
||||
public List<EventRelation> getDependents() {
|
||||
return EventRelation.getFightRelations(this);
|
||||
}
|
||||
|
||||
public void setErgebnis(int winner) {
|
||||
this.ergebnis = winner;
|
||||
setResult.update(winner, fightID);
|
||||
}
|
||||
|
||||
public void setFight(int fight) {
|
||||
//Fight.FightID, not EventFight.FightID
|
||||
this.fight = fight;
|
||||
setFight.update(fight, fightID);
|
||||
}
|
||||
|
||||
public void setGroup(Integer group) {
|
||||
setGroup.update(group, fightID);
|
||||
this.groupId = group;
|
||||
}
|
||||
|
||||
public boolean hasFinished() {
|
||||
return fight != 0 || ergebnis != 0;
|
||||
}
|
||||
|
||||
public void reschedule() {
|
||||
startTime = Timestamp.from(new Date().toInstant().plus(30, SECONDS));
|
||||
reschedule.update(startTime, fightID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode(){
|
||||
return fightID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o){
|
||||
if(o == null)
|
||||
return false;
|
||||
if(!(o instanceof EventFight))
|
||||
return false;
|
||||
return fightID == ((EventFight) o).fightID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(EventFight o) {
|
||||
return startTime.compareTo(o.startTime);
|
||||
}
|
||||
|
||||
public void update(Timestamp startTime, String spielmodus, String map, int teamBlue, int teamRed, Integer spectatePort) {
|
||||
update.update(startTime, spielmodus, map, teamBlue, teamRed, spectatePort, fightID);
|
||||
this.startTime = startTime;
|
||||
this.spielmodus = spielmodus;
|
||||
this.map = map;
|
||||
this.teamBlue = teamBlue;
|
||||
this.teamRed = teamRed;
|
||||
this.spectatePort = spectatePort;
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
delete.update(fightID);
|
||||
}
|
||||
}
|
||||
188
CommonCore/SQL/src/de/steamwar/sql/EventFight.kt
Normal file
188
CommonCore/SQL/src/de/steamwar/sql/EventFight.kt
Normal file
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* 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.sql
|
||||
|
||||
import de.steamwar.sql.internal.useDb
|
||||
import org.jetbrains.exposed.v1.core.*
|
||||
import org.jetbrains.exposed.v1.core.dao.id.EntityID
|
||||
import org.jetbrains.exposed.v1.core.dao.id.IntIdTable
|
||||
import org.jetbrains.exposed.v1.dao.IntEntity
|
||||
import org.jetbrains.exposed.v1.dao.IntEntityClass
|
||||
import org.jetbrains.exposed.v1.javatime.timestamp
|
||||
import org.jetbrains.exposed.v1.jdbc.insertAndGetId
|
||||
import org.jetbrains.exposed.v1.jdbc.select
|
||||
import java.sql.Timestamp
|
||||
import java.time.Instant
|
||||
import java.util.*
|
||||
|
||||
object EventFightTable : IntIdTable("EventFight", "FightID") {
|
||||
val eventId = reference("EventID", EventTable)
|
||||
val startTime = timestamp("StartTime")
|
||||
val gamemode = text("Spielmodus")
|
||||
val map = text("Map")
|
||||
val groupId = optReference("GroupId", EventGroupTable)
|
||||
val teamBlue = reference("TeamBlue", TeamTable)
|
||||
val teamRed = reference("TeamRed", TeamTable)
|
||||
val spectatePort = integer("SpectatePort").nullable()
|
||||
val bestOf = integer("BestOf")
|
||||
val ergebnis = integer("Ergebnis")
|
||||
val fight = optReference("Fight", FightTable)
|
||||
}
|
||||
|
||||
class EventFight(id: EntityID<Int>) : IntEntity(id), Comparable<EventFight> {
|
||||
companion object : IntEntityClass<EventFight>(EventFightTable) {
|
||||
val fights: Queue<EventFight> = PriorityQueue()
|
||||
@JvmStatic get
|
||||
|
||||
@JvmStatic
|
||||
fun byId(fightId: Int) = useDb { findById(fightId) }
|
||||
|
||||
@JvmStatic
|
||||
fun byId(group: EventGroup) = useDb {
|
||||
find { EventFightTable.groupId eq group.id }.orderBy(EventFightTable.startTime to SortOrder.DESC).toList()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getLast(group: EventGroup) = useDb {
|
||||
Optional.ofNullable(
|
||||
find { EventFightTable.groupId eq group.id }.orderBy(EventFightTable.startTime to SortOrder.DESC)
|
||||
.firstOrNull()
|
||||
)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun loadAllComingFights() = useDb {
|
||||
fights.clear()
|
||||
fights.addAll(find { EventFightTable.startTime greaterEq Instant.now() }.orderBy(EventFightTable.startTime to SortOrder.ASC))
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getEvent(eventId: Int) = useDb {
|
||||
find { EventFightTable.eventId eq eventId }.orderBy(EventFightTable.startTime to SortOrder.ASC).toList()
|
||||
}
|
||||
|
||||
private var activeFightsCache: List<EventFight>? = null
|
||||
|
||||
@JvmStatic
|
||||
fun clearActiveFightsCache() {
|
||||
activeFightsCache = null
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getActiveFights(): List<EventFight> {
|
||||
if (activeFightsCache == null) {
|
||||
activeFightsCache = useDb {
|
||||
find {
|
||||
EventFightTable.fight.isNull() and (EventFightTable.startTime less Instant.now()) and (EventFightTable.eventId.inSubQuery(
|
||||
EventTable.select(
|
||||
EventTable.id
|
||||
)
|
||||
.where { (EventTable.start less Instant.now()) and (EventTable.end greater Instant.now()) }))
|
||||
}.orderBy(EventFightTable.startTime to SortOrder.ASC).toList()
|
||||
}
|
||||
}
|
||||
|
||||
return activeFightsCache!!
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun create(
|
||||
event: Int,
|
||||
from: Timestamp,
|
||||
spielmodus: String,
|
||||
map: String,
|
||||
blueTeam: Int,
|
||||
redTeam: Int,
|
||||
spectatePort: Int?
|
||||
) = useDb {
|
||||
get(
|
||||
EventFightTable.insertAndGetId {
|
||||
it[eventId] = EntityID(event, EventTable)
|
||||
it[startTime] = from.toInstant()
|
||||
it[gamemode] = spielmodus
|
||||
it[EventFightTable.map] = map
|
||||
it[teamBlue] = EntityID(blueTeam, TeamTable)
|
||||
it[teamRed] = EntityID(redTeam, TeamTable)
|
||||
it[EventFightTable.spectatePort] = spectatePort
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val fightID by EventFightTable.id.transform({ EntityID(it, EventFightTable) }, { it.value })
|
||||
var teamBlue by EventFightTable.teamBlue.transform({ EntityID(it, TeamTable) }, { it.value })
|
||||
var teamRed by EventFightTable.teamRed.transform({ EntityID(it, TeamTable) }, { it.value })
|
||||
private var fightErgebnis by EventFightTable.ergebnis
|
||||
var ergebnis: Int
|
||||
get() = fightErgebnis
|
||||
set(value) = useDb {
|
||||
fightErgebnis = value
|
||||
}
|
||||
var eventID by EventFightTable.eventId.transform({ EntityID(it, EventTable) }, { it.value })
|
||||
var startTime by EventFightTable.startTime.transform({ it.toInstant() }, { Timestamp.from(it) })
|
||||
var spielmodus by EventFightTable.gamemode
|
||||
var map by EventFightTable.map
|
||||
var groupId by EventFightTable.groupId
|
||||
val group by lazy { useDb { Optional.ofNullable(groupId).map { EventGroup[it] } } }
|
||||
var spectatePort by EventFightTable.spectatePort
|
||||
private var fightStat by EventFightTable.fight.transform({ it?.let { EntityID(it, EventFightTable) } }, { it?.value })
|
||||
var fight: Int?
|
||||
get() = fightStat
|
||||
set(value) = useDb {
|
||||
fightStat = value
|
||||
}
|
||||
val dependents by lazy { useDb { EventRelation.getFightRelations(this@EventFight) } }
|
||||
|
||||
val winner: Team?
|
||||
get() = if (ergebnis == 1) Team[teamBlue] else if (ergebnis == 2) Team[teamRed] else null
|
||||
val losser: Team?
|
||||
get() = if (ergebnis == 1) Team[teamRed] else if (ergebnis == 2) Team[teamBlue] else null
|
||||
|
||||
fun setGroup(group: Int?) = useDb { groupId = group?.let { EntityID(it, EventGroupTable) } }
|
||||
fun hasFinished() = fight != null || ergebnis != 0
|
||||
|
||||
fun reschedule() = useDb {
|
||||
startTime = Timestamp.from(Instant.now().plusSeconds(30))
|
||||
}
|
||||
|
||||
override fun hashCode() = fightID
|
||||
override fun equals(other: Any?) = other is EventFight && other.fightID == fightID
|
||||
override fun compareTo(other: EventFight): Int = startTime.compareTo(other.startTime)
|
||||
|
||||
fun update(
|
||||
startTime: Timestamp,
|
||||
spielmodus: String,
|
||||
map: String,
|
||||
teamBlue: Int,
|
||||
teamRed: Int,
|
||||
spectatePort: Int?
|
||||
) = useDb {
|
||||
this@EventFight.startTime = startTime
|
||||
this@EventFight.spielmodus = spielmodus
|
||||
this@EventFight.map = map
|
||||
this@EventFight.teamBlue = teamBlue
|
||||
this@EventFight.teamRed = teamRed
|
||||
this@EventFight.spectatePort = spectatePort
|
||||
}
|
||||
|
||||
override fun delete() = useDb {
|
||||
super.delete()
|
||||
}
|
||||
}
|
||||
@@ -1,173 +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.sql;
|
||||
|
||||
import de.steamwar.sql.internal.*;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class EventGroup {
|
||||
static {
|
||||
SqlTypeMapper.ordinalEnumMapper(EventGroupType.class);
|
||||
}
|
||||
|
||||
private static final Table<EventGroup> table = new Table<>(EventGroup.class);
|
||||
|
||||
private static final SelectStatement<EventGroup> get = table.select(Table.PRIMARY);
|
||||
private static final SelectStatement<EventGroup> byEvent = new SelectStatement<>(table, "SELECT * FROM EventGroup WHERE EventID = ?");
|
||||
|
||||
private static final Statement insert = table.insertFields(true, "EventID", "Name", "Type");
|
||||
private static final Statement update = table.update(Table.PRIMARY, "Name", "Type", "PointsPerWin", "PointsPerLoss", "PointsPerDraw");
|
||||
private static final Statement delete = table.delete(Table.PRIMARY);
|
||||
|
||||
public static List<EventGroup> get(Event eventID) {
|
||||
return byEvent.listSelect(eventID.getEventID());
|
||||
}
|
||||
|
||||
public static EventGroup create(Event event, String name, EventGroupType type) {
|
||||
int key = insert.insertGetKey(event.getEventID(), name, type);
|
||||
return EventGroup.get(key).get();
|
||||
}
|
||||
|
||||
public static Optional<EventGroup> get(int id) {
|
||||
return Optional.ofNullable(get.select(id));
|
||||
}
|
||||
|
||||
@Field(keys = Table.PRIMARY)
|
||||
private final int id;
|
||||
|
||||
@Field(keys = "EVENT_NAME")
|
||||
private int eventID;
|
||||
|
||||
@Field(keys = "EVENT_NAME")
|
||||
private String name;
|
||||
|
||||
@Field
|
||||
private EventGroupType type;
|
||||
|
||||
@Field
|
||||
private int pointsPerWin;
|
||||
|
||||
@Field
|
||||
private int pointsPerLoss;
|
||||
|
||||
@Field
|
||||
private int pointsPerDraw;
|
||||
|
||||
public EventGroup(int id, int eventID, String name, EventGroupType type, int pointsPerWin, int pointsPerLoss, int pointsPerDraw) {
|
||||
this.id = id;
|
||||
this.eventID = eventID;
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.pointsPerWin = pointsPerWin;
|
||||
this.pointsPerLoss = pointsPerLoss;
|
||||
this.pointsPerDraw = pointsPerDraw;
|
||||
}
|
||||
|
||||
private Map<Team, Integer> points;
|
||||
|
||||
public List<EventFight> getFights() {
|
||||
return EventFight.get(this);
|
||||
}
|
||||
|
||||
public Set<Integer> getTeamsId() {
|
||||
return getFights().stream().flatMap(fight -> Stream.of(fight.getTeamBlue(), fight.getTeamRed()))
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public Set<Team> getTeams() {
|
||||
return getTeamsId().stream().map(Team::get).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public Optional<EventFight> getLastFight() {
|
||||
return EventFight.getLast(this);
|
||||
}
|
||||
|
||||
public List<EventRelation> getDependents() {
|
||||
return EventRelation.getGroupRelations(this);
|
||||
}
|
||||
|
||||
public Map<Team, Integer> calculatePoints() {
|
||||
if (points == null) {
|
||||
Map<Integer, Integer> p = getTeamsId().stream().collect(Collectors.toMap(team -> team, team -> 0));
|
||||
|
||||
for (EventFight fight : getFights()) {
|
||||
int blueTeamAdd = 0;
|
||||
int redTeamAdd = 0;
|
||||
|
||||
if (!fight.hasFinished()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (fight.getErgebnis()) {
|
||||
case 1:
|
||||
blueTeamAdd += pointsPerWin;
|
||||
redTeamAdd += pointsPerLoss;
|
||||
break;
|
||||
case 2:
|
||||
blueTeamAdd += pointsPerLoss;
|
||||
redTeamAdd += pointsPerWin;
|
||||
break;
|
||||
case 0:
|
||||
if (fight.getFightID() != 0) {
|
||||
blueTeamAdd += pointsPerDraw;
|
||||
redTeamAdd += pointsPerDraw;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
p.put(fight.getTeamBlue(), p.get(fight.getTeamBlue()) + blueTeamAdd);
|
||||
p.put(fight.getTeamRed(), p.get(fight.getTeamRed()) + redTeamAdd);
|
||||
}
|
||||
|
||||
points = p.entrySet().stream().collect(Collectors.toMap(integerIntegerEntry -> Team.get(integerIntegerEntry.getKey()), Map.Entry::getValue));
|
||||
}
|
||||
|
||||
return points;
|
||||
}
|
||||
|
||||
public void update(String name, EventGroupType type, int pointsPerWin, int pointsPerLoss, int pointsPerDraw) {
|
||||
update.update(name, type, pointsPerWin, pointsPerLoss, pointsPerDraw, id);
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.pointsPerWin = pointsPerWin;
|
||||
this.pointsPerLoss = pointsPerLoss;
|
||||
this.pointsPerDraw = pointsPerDraw;
|
||||
}
|
||||
|
||||
public boolean needsTieBreak() {
|
||||
return calculatePoints().values().stream().sorted().limit(2).distinct().count() < 2;
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
delete.update(id);
|
||||
}
|
||||
|
||||
public static enum EventGroupType {
|
||||
GROUP_STAGE,
|
||||
ELIMINATION_STAGE
|
||||
}
|
||||
}
|
||||
153
CommonCore/SQL/src/de/steamwar/sql/EventGroup.kt
Normal file
153
CommonCore/SQL/src/de/steamwar/sql/EventGroup.kt
Normal file
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* 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.sql
|
||||
|
||||
import de.steamwar.sql.internal.useDb
|
||||
import org.jetbrains.exposed.v1.core.dao.id.EntityID
|
||||
import org.jetbrains.exposed.v1.core.dao.id.IntIdTable
|
||||
import org.jetbrains.exposed.v1.core.eq
|
||||
import org.jetbrains.exposed.v1.dao.IntEntity
|
||||
import org.jetbrains.exposed.v1.dao.IntEntityClass
|
||||
import java.util.*
|
||||
|
||||
object EventGroupTable : IntIdTable("EventGroup", "Id") {
|
||||
val event = reference("EventID", EventTable)
|
||||
val name = varchar("Name", 64)
|
||||
val type = enumeration("Type", EventGroup.EventGroupType::class)
|
||||
val pointsPerWin = integer("PointsPerWin").default(3)
|
||||
val pointsPerLoss = integer("PointsPerLoss").default(0)
|
||||
val pointsPerDraw = integer("PointsPerDraw").default(1)
|
||||
}
|
||||
|
||||
class EventGroup(id: EntityID<Int>) : IntEntity(id) {
|
||||
companion object : IntEntityClass<EventGroup>(EventGroupTable) {
|
||||
|
||||
@JvmStatic
|
||||
fun get(event: Event) = useDb { find { EventGroupTable.event eq event.id }.toList() }
|
||||
|
||||
@JvmStatic
|
||||
fun byId(groupId: Int) = useDb { Optional.ofNullable(findById(groupId)) }
|
||||
|
||||
@JvmStatic
|
||||
fun create(event: Event, name: String, type: EventGroupType) = useDb {
|
||||
new {
|
||||
this.eventID = event.id.value
|
||||
this.groupName = name
|
||||
this.groupType = type
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var eventID by EventGroupTable.event.transform({ EntityID(it, EventTable) }, { it.value })
|
||||
private set
|
||||
private var groupName by EventGroupTable.name
|
||||
private var groupType by EventGroupTable.type
|
||||
private var groupPointsPerWin by EventGroupTable.pointsPerWin
|
||||
private var groupPointsPerLoss by EventGroupTable.pointsPerLoss
|
||||
private var groupPointsPerDraw by EventGroupTable.pointsPerDraw
|
||||
val fights by lazy { useDb { EventFight.find { EventFightTable.groupId eq id }.toList() } }
|
||||
val teamsId by lazy { fights.flatMap { listOf(it.teamBlue, it.teamRed) }.toSet() }
|
||||
|
||||
var name: String
|
||||
get() = groupName
|
||||
set(value) {
|
||||
groupName = value
|
||||
}
|
||||
var type: EventGroupType
|
||||
get() = groupType
|
||||
set(value) {
|
||||
groupType = value
|
||||
}
|
||||
var pointsPerWin: Int
|
||||
get() = groupPointsPerWin
|
||||
set(value) {
|
||||
groupPointsPerWin = value
|
||||
}
|
||||
var pointsPerLoss: Int
|
||||
get() = groupPointsPerLoss
|
||||
set(value) {
|
||||
groupPointsPerLoss = value
|
||||
}
|
||||
var pointsPerDraw: Int
|
||||
get() = groupPointsPerDraw
|
||||
set(value) {
|
||||
groupPointsPerDraw = value
|
||||
}
|
||||
val dependents by lazy { EventRelation.getGroupRelations(this) }
|
||||
val lastFight by lazy { Optional.ofNullable(fights.maxByOrNull { it.startTime }) }
|
||||
|
||||
fun getId() = id.value
|
||||
|
||||
private var points: Map<Team, Int>? = null
|
||||
|
||||
fun calculatePoints(): Map<Team, Int> {
|
||||
if (points == null) {
|
||||
val p: MutableMap<Int, Int> = teamsId.associateWith { 0 }.toMutableMap()
|
||||
|
||||
for (fight in fights) {
|
||||
var blueTeamAdd = 0
|
||||
var redTeamAdd = 0
|
||||
|
||||
if (!fight.hasFinished()) {
|
||||
continue
|
||||
}
|
||||
|
||||
when (fight.ergebnis) {
|
||||
1 -> {
|
||||
blueTeamAdd += pointsPerWin
|
||||
redTeamAdd += pointsPerLoss
|
||||
}
|
||||
2 -> {
|
||||
blueTeamAdd += pointsPerLoss
|
||||
redTeamAdd += pointsPerWin
|
||||
}
|
||||
0 -> if (fight.fight != null) {
|
||||
blueTeamAdd += pointsPerDraw
|
||||
redTeamAdd += pointsPerDraw
|
||||
}
|
||||
}
|
||||
|
||||
p[fight.teamBlue] = p[fight.teamBlue]?.plus(blueTeamAdd) ?: blueTeamAdd
|
||||
p[fight.teamRed] = p[fight.teamRed]?.plus(redTeamAdd) ?: redTeamAdd
|
||||
}
|
||||
|
||||
return p.mapKeys { Team.byId(it.key) }.also { points = it }
|
||||
} else {
|
||||
return points!!
|
||||
}
|
||||
}
|
||||
|
||||
fun needsTieBreak() = calculatePoints().values.let { it.size == it.toSet().size }
|
||||
|
||||
fun update(name: String, type: EventGroupType, pointsPerWin: Int, pointsPerLoss: Int, pointsPerDraw: Int) = useDb {
|
||||
this@EventGroup.name = name
|
||||
this@EventGroup.type = type
|
||||
this@EventGroup.pointsPerWin = pointsPerWin
|
||||
this@EventGroup.pointsPerLoss = pointsPerLoss
|
||||
this@EventGroup.pointsPerDraw = pointsPerDraw
|
||||
}
|
||||
|
||||
override fun delete() = useDb { super.delete() }
|
||||
|
||||
enum class EventGroupType {
|
||||
GROUP_STAGE,
|
||||
ELIMINATION_STAGE
|
||||
}
|
||||
}
|
||||
@@ -1,192 +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.sql;
|
||||
|
||||
import de.steamwar.sql.internal.*;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
@Setter
|
||||
public class EventRelation {
|
||||
|
||||
static {
|
||||
SqlTypeMapper.ordinalEnumMapper(FightTeam.class);
|
||||
SqlTypeMapper.ordinalEnumMapper(FromType.class);
|
||||
}
|
||||
|
||||
private static final Table<EventRelation> table = new Table<>(EventRelation.class);
|
||||
|
||||
private static final SelectStatement<EventRelation> get = new SelectStatement<>(table, "SELECT * FROM EventRelation WHERE FromType = ? AND FromId = ?");
|
||||
private static final SelectStatement<EventRelation> byId = new SelectStatement<>(table, "SELECT * FROM EventRelation WHERE id = ?");
|
||||
private static final SelectStatement<EventRelation> byEvent = new SelectStatement<>(table, "SELECT ER.* FROM EventRelation ER JOIN EventFight EF ON EF.fightId = ER.fightId WHERE EF.EventID = ?");
|
||||
private static final Statement insert = table.insertFields(true, "fightId", "fightTeam", "fromType", "fromId", "fromPlace");
|
||||
private static final Statement update = table.update(Table.PRIMARY, "fromType", "fromId", "fromPlace");
|
||||
private static final Statement updateTeam = table.update(Table.PRIMARY, "fightTeam");
|
||||
private static final Statement delete = table.delete(Table.PRIMARY);
|
||||
|
||||
public static List<EventRelation> get(Event event) {
|
||||
return byEvent.listSelect(event.getEventID());
|
||||
}
|
||||
|
||||
public static EventRelation get(int id) {
|
||||
return byId.select(id);
|
||||
}
|
||||
|
||||
public static List<EventRelation> getFightRelations(EventFight fight) {
|
||||
return get.listSelect(FromType.FIGHT, fight.getFightID());
|
||||
}
|
||||
|
||||
public static List<EventRelation> getGroupRelations(EventGroup group) {
|
||||
return get.listSelect(FromType.GROUP, group.getId());
|
||||
}
|
||||
|
||||
public static EventRelation create(EventFight fight, FightTeam fightTeam, FromType fromType, int fromId, int fromPlace) {
|
||||
int id = insert.insertGetKey(fight.getFightID(), fightTeam, fromType, fromId, fromPlace);
|
||||
return get(id);
|
||||
}
|
||||
|
||||
@Field(keys = Table.PRIMARY)
|
||||
private final int id;
|
||||
|
||||
@Field
|
||||
private int fightId;
|
||||
|
||||
@Field
|
||||
private FightTeam fightTeam;
|
||||
|
||||
@Field
|
||||
private FromType fromType;
|
||||
|
||||
@Field
|
||||
private int fromId;
|
||||
|
||||
@Field
|
||||
private int fromPlace;
|
||||
|
||||
public EventFight getFight() {
|
||||
return EventFight.get(fightId);
|
||||
}
|
||||
|
||||
public Optional<EventFight> getFromFight() {
|
||||
if(fromType == FromType.FIGHT) {
|
||||
return Optional.of(EventFight.get(fromId));
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<EventGroup> getFromGroup() {
|
||||
if(fromType == FromType.GROUP) {
|
||||
return EventGroup.get(fromId);
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
delete.update(id);
|
||||
}
|
||||
|
||||
public void setUpdateTeam(FightTeam team) {
|
||||
updateTeam.update(id, team);
|
||||
this.fightTeam = team;
|
||||
}
|
||||
|
||||
public void setFromFight(EventFight fight, int place) {
|
||||
setFrom(fight.getFightID(), place, FromType.FIGHT);
|
||||
}
|
||||
|
||||
public void setFromGroup(EventGroup group, int place) {
|
||||
setFrom(group.getId(), place, FromType.GROUP);
|
||||
}
|
||||
|
||||
private void setFrom(int fightId, int place, FromType type) {
|
||||
update.update(type, fightId, place, id);
|
||||
this.fromType = type;
|
||||
this.fromId = fightId;
|
||||
this.fromPlace = place;
|
||||
}
|
||||
|
||||
public Optional<Team> getAdvancingTeam() {
|
||||
if (fromType == FromType.FIGHT) {
|
||||
if (fromPlace == 0) {
|
||||
return getFromFight().flatMap(EventFight::getWinner);
|
||||
} else {
|
||||
return getFromFight().flatMap(EventFight::getLosser);
|
||||
}
|
||||
} else if (fromType == FromType.GROUP) {
|
||||
return getFromGroup().map(EventGroup::calculatePoints)
|
||||
.flatMap(points -> points.entrySet().stream()
|
||||
.sorted(Map.Entry.<Team, Integer>comparingByValue().reversed())
|
||||
.skip(fromPlace)
|
||||
.findFirst()
|
||||
.map(Map.Entry::getKey));
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean apply() {
|
||||
Optional<Integer> team = getAdvancingTeam().map(Team::getTeamId);
|
||||
if(!team.isPresent())
|
||||
return false;
|
||||
|
||||
EventFight fight = getFight();
|
||||
if(fightTeam == FightTeam.RED) {
|
||||
fight.update(
|
||||
fight.getStartTime(),
|
||||
fight.getSpielmodus(),
|
||||
fight.getMap(),
|
||||
fight.getTeamBlue(),
|
||||
team.get(),
|
||||
fight.getSpectatePort()
|
||||
);
|
||||
} else {
|
||||
fight.update(
|
||||
fight.getStartTime(),
|
||||
fight.getSpielmodus(),
|
||||
fight.getMap(),
|
||||
team.get(),
|
||||
fight.getTeamRed(),
|
||||
fight.getSpectatePort()
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static enum FightTeam {
|
||||
BLUE,
|
||||
RED
|
||||
}
|
||||
|
||||
public static enum FromType {
|
||||
FIGHT,
|
||||
GROUP
|
||||
}
|
||||
}
|
||||
149
CommonCore/SQL/src/de/steamwar/sql/EventRelation.kt
Normal file
149
CommonCore/SQL/src/de/steamwar/sql/EventRelation.kt
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* 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.sql
|
||||
|
||||
import de.steamwar.sql.internal.useDb
|
||||
import org.jetbrains.exposed.v1.core.and
|
||||
import org.jetbrains.exposed.v1.core.dao.id.EntityID
|
||||
import org.jetbrains.exposed.v1.core.dao.id.IntIdTable
|
||||
import org.jetbrains.exposed.v1.core.eq
|
||||
import org.jetbrains.exposed.v1.dao.IntEntity
|
||||
import org.jetbrains.exposed.v1.dao.IntEntityClass
|
||||
import org.jetbrains.exposed.v1.jdbc.select
|
||||
|
||||
object EventRelationTable : IntIdTable("EventRelation") {
|
||||
val fightId = reference("FightId", EventFightTable)
|
||||
val fightTeam = enumeration("FightTeam", EventRelation.FightTeam::class)
|
||||
val fromType = enumeration("FromType", EventRelation.FromType::class)
|
||||
val fromId = integer("FromId")
|
||||
val fromPlace = integer("FromPlace")
|
||||
}
|
||||
|
||||
class EventRelation(id: EntityID<Int>) : IntEntity(id) {
|
||||
companion object : IntEntityClass<EventRelation>(EventRelationTable) {
|
||||
@JvmStatic
|
||||
fun get(event: Event) = useDb {
|
||||
EventRelationTable.innerJoin(EventFightTable)
|
||||
.select(EventRelationTable.columns)
|
||||
.where { EventFightTable.eventId eq event.id }
|
||||
.map { wrapRow(it) }
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun byId(id: Int) = useDb { findById(id) }
|
||||
|
||||
@JvmStatic
|
||||
fun getFightRelations(fight: EventFight) =
|
||||
useDb { find { (EventRelationTable.fromId eq fight.id.value) and (EventRelationTable.fromType eq FromType.FIGHT) } }
|
||||
|
||||
@JvmStatic
|
||||
fun getGroupRelations(group: EventGroup) =
|
||||
useDb { find { (EventRelationTable.fromId eq group.id.value) and (EventRelationTable.fromType eq FromType.GROUP) } }
|
||||
|
||||
@JvmStatic
|
||||
fun create(fight: EventFight, fightTeam: FightTeam, fromType: FromType, fromId: Int, fromPlace: Int) = useDb {
|
||||
new {
|
||||
this.fightEntityId = fight.id
|
||||
this.fightTeam = fightTeam
|
||||
this.fromType = fromType
|
||||
this.fromId = fromId
|
||||
this.fromPlace = fromPlace
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var fightEntityId by EventRelationTable.fightId
|
||||
var fightId: Int
|
||||
get() = fightEntityId.value
|
||||
set(value) = useDb { fightEntityId = EntityID(value, EventFightTable) }
|
||||
val fight by lazy { useDb { EventFight[fightEntityId] } }
|
||||
var fightTeam by EventRelationTable.fightTeam
|
||||
private set
|
||||
var fromType by EventRelationTable.fromType
|
||||
private set
|
||||
var fromId by EventRelationTable.fromId
|
||||
private set
|
||||
|
||||
var fromFightId: Int?
|
||||
get() = if (fromType == FromType.FIGHT) fromId else null
|
||||
set(value) = useDb {
|
||||
fromType = FromType.FIGHT
|
||||
fromId = value!!
|
||||
}
|
||||
val fromFight: EventFight?
|
||||
get() = fromFightId?.let { useDb { EventFight[it] } }
|
||||
var fromGroupId: Int?
|
||||
get() = if (fromType == FromType.GROUP) fromId else null
|
||||
set(value) = useDb {
|
||||
fromType = FromType.GROUP
|
||||
fromId = value!!
|
||||
}
|
||||
val fromGroup: EventGroup?
|
||||
get() = fromGroupId?.let { useDb { EventGroup[it] } }
|
||||
var fromPlace by EventRelationTable.fromPlace
|
||||
private set
|
||||
|
||||
fun getId() = id.value
|
||||
fun setUpdateTeam(team: FightTeam) = useDb {
|
||||
fightTeam = team
|
||||
}
|
||||
|
||||
fun setFromFight(fight: EventFight, place: Int) = useDb {
|
||||
fromType = FromType.FIGHT
|
||||
fromId = fight.id.value
|
||||
fromPlace = place
|
||||
}
|
||||
|
||||
fun setFromGroup(group: EventGroup, place: Int) = useDb {
|
||||
fromType = FromType.GROUP
|
||||
fromId = group.id.value
|
||||
fromPlace = place
|
||||
}
|
||||
|
||||
fun getAdvancingTeam(): Team? = when(fromType) {
|
||||
FromType.FIGHT -> if (fromPlace == 0) fromFight?.winner else fromFight?.losser
|
||||
FromType.GROUP -> fromGroup?.calculatePoints()?.toList()?.sortedBy { (_, v) -> v }?.reversed()?.elementAt(fromPlace)?.first
|
||||
}
|
||||
|
||||
fun apply(): Boolean {
|
||||
val team = getAdvancingTeam() ?: return false
|
||||
|
||||
useDb {
|
||||
when(fightTeam) {
|
||||
FightTeam.BLUE -> fight.teamBlue = team.teamId
|
||||
FightTeam.RED -> fight.teamRed = team.teamId
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun delete() = useDb {
|
||||
super.delete()
|
||||
}
|
||||
|
||||
enum class FightTeam {
|
||||
BLUE, RED
|
||||
}
|
||||
|
||||
enum class FromType {
|
||||
FIGHT, GROUP
|
||||
}
|
||||
}
|
||||
@@ -1,134 +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.sql;
|
||||
|
||||
import de.steamwar.sql.internal.Field;
|
||||
import de.steamwar.sql.internal.SelectStatement;
|
||||
import de.steamwar.sql.internal.Statement;
|
||||
import de.steamwar.sql.internal.Table;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class Fight {
|
||||
|
||||
private static final Table<Fight> table = new Table<>(Fight.class);
|
||||
private static final SelectStatement<Fight> getPage = new SelectStatement<>(table, "SELECT f.*, (b.NodeId IS NULL OR b.Config & 2) AND (r.NodeId IS NULL OR r.Config & 2) AS ReplayAllowed FROM Fight f LEFT OUTER JOIN SchematicNode b ON f.BlueSchem = b.NodeId LEFT OUTER JOIN SchematicNode r ON f.RedSchem = r.NodeId ORDER BY FightID DESC LIMIT ?, ?");
|
||||
private static final SelectStatement<Fight> getById = new SelectStatement<>(table, "SELECT f.*, (b.NodeId IS NULL OR b.Config & 2) AND (r.NodeId IS NULL OR r.Config & 2) AS ReplayAllowed FROM Fight f LEFT OUTER JOIN SchematicNode b ON f.BlueSchem = b.NodeId LEFT OUTER JOIN SchematicNode r ON f.RedSchem = r.NodeId WHERE FightId = ?");
|
||||
private static final Statement insert = table.insertFields(true, "GameMode", "Server", "StartTime", "Duration", "BlueLeader", "RedLeader", "BlueSchem", "RedSchem", "Win", "WinCondition");
|
||||
private static final Statement updateReplayAvailable = table.update(Table.PRIMARY, "ReplayAvailable");
|
||||
|
||||
public static List<Fight> getPage(int page, int elementsPerPage) {
|
||||
List<Fight> fights = getPage.listSelect(page * elementsPerPage, elementsPerPage);
|
||||
|
||||
List<FightPlayer> fightPlayers = FightPlayer.batchGet(fights.stream().map(f -> f.fightID));
|
||||
for(Fight fight : fights) {
|
||||
fight.initPlayers(fightPlayers);
|
||||
}
|
||||
|
||||
SteamwarUser.batchCache(fightPlayers.stream().map(FightPlayer::getUserID).collect(Collectors.toSet()));
|
||||
return fights;
|
||||
}
|
||||
|
||||
public static Fight getById(int fightID) {
|
||||
return getById.select(fightID);
|
||||
}
|
||||
|
||||
public static int create(String gamemode, String server, Timestamp starttime, int duration, int blueleader, int redleader, Integer blueschem, Integer redschem, int win, String wincondition){
|
||||
return insert.insertGetKey(gamemode, server, starttime, duration, blueleader, redleader, blueschem, redschem, win, wincondition);
|
||||
}
|
||||
|
||||
public static void markReplayAvailable(int fightID) {
|
||||
updateReplayAvailable.update(true, fightID);
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Field(keys = {Table.PRIMARY}, autoincrement = true)
|
||||
private final int fightID;
|
||||
@Field
|
||||
private final String gameMode;
|
||||
@Getter
|
||||
@Field
|
||||
private final String server;
|
||||
@Getter
|
||||
@Field
|
||||
private final Timestamp startTime;
|
||||
@Field
|
||||
private final int duration;
|
||||
@Field
|
||||
private final int blueLeader;
|
||||
@Field
|
||||
private final int redLeader;
|
||||
@Field(nullable = true)
|
||||
private final Integer blueSchem;
|
||||
@Field(nullable = true)
|
||||
private final Integer redSchem;
|
||||
@Getter
|
||||
@Field
|
||||
private final int win;
|
||||
@Field
|
||||
private final String wincondition;
|
||||
@Field
|
||||
private final boolean replayAvailable;
|
||||
@Field // Virtual field for easy select
|
||||
private final boolean replayAllowed;
|
||||
|
||||
@Getter
|
||||
private final List<FightPlayer> bluePlayers = new ArrayList<>();
|
||||
@Getter
|
||||
private final List<FightPlayer> redPlayers = new ArrayList<>();
|
||||
|
||||
public SchematicType getSchemType() {
|
||||
return SchematicType.fromDB(gameMode);
|
||||
}
|
||||
|
||||
public SteamwarUser getBlueLeader() {
|
||||
return SteamwarUser.get(blueLeader);
|
||||
}
|
||||
|
||||
public SteamwarUser getRedLeader() {
|
||||
return SteamwarUser.get(redLeader);
|
||||
}
|
||||
|
||||
public boolean replayAllowed() {
|
||||
return replayExists() && replayAllowed;
|
||||
}
|
||||
|
||||
public boolean replayExists() {
|
||||
return getSchemType() != null && replayAvailable;
|
||||
}
|
||||
|
||||
private void initPlayers(List<FightPlayer> fightPlayers) {
|
||||
for(FightPlayer fp : fightPlayers) {
|
||||
if(fp.getFightID() != fightID)
|
||||
continue;
|
||||
|
||||
if(fp.getTeam() == 1)
|
||||
bluePlayers.add(fp);
|
||||
else
|
||||
redPlayers.add(fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
162
CommonCore/SQL/src/de/steamwar/sql/Fight.kt
Normal file
162
CommonCore/SQL/src/de/steamwar/sql/Fight.kt
Normal file
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* 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.sql
|
||||
|
||||
import de.steamwar.sql.internal.useDb
|
||||
import org.jetbrains.exposed.v1.core.IntegerColumnType
|
||||
import org.jetbrains.exposed.v1.core.ReferenceOption
|
||||
import org.jetbrains.exposed.v1.core.SortOrder
|
||||
import org.jetbrains.exposed.v1.core.dao.id.EntityID
|
||||
import org.jetbrains.exposed.v1.core.dao.id.IntIdTable
|
||||
import org.jetbrains.exposed.v1.core.eq
|
||||
import org.jetbrains.exposed.v1.dao.IntEntity
|
||||
import org.jetbrains.exposed.v1.dao.IntEntityClass
|
||||
import org.jetbrains.exposed.v1.javatime.timestamp
|
||||
import org.jetbrains.exposed.v1.jdbc.insertAndGetId
|
||||
import org.jetbrains.exposed.v1.jdbc.update
|
||||
import java.sql.Timestamp
|
||||
|
||||
object FightTable : IntIdTable("Fight", "FightId") {
|
||||
val gamemode = varchar("Gamemode", 30)
|
||||
val server = text("Server")
|
||||
val startTime = timestamp("StartTime")
|
||||
val duration = integer("Duration")
|
||||
val blueLeader = reference("BlueLeader", SteamwarUserTable)
|
||||
val redLeader = reference("RedLeader", SteamwarUserTable)
|
||||
val blueSchem = optReference("BlueSchem", SchematicNodeTable, onDelete = ReferenceOption.SET_NULL)
|
||||
val redSchem = optReference("RedSchem", SchematicNodeTable, onDelete = ReferenceOption.SET_NULL)
|
||||
val win = enumeration("Win", Fight.WinningTeam::class)
|
||||
val winCondition = varchar("WinCondition", 100)
|
||||
val replayAvailable = bool("ReplayAvailable")
|
||||
}
|
||||
|
||||
class Fight(id: EntityID<Int>) : IntEntity(id) {
|
||||
companion object : IntEntityClass<Fight>(FightTable) {
|
||||
@JvmStatic
|
||||
fun getById(id: Int) = useDb { get(id) }
|
||||
|
||||
@JvmStatic
|
||||
fun create(
|
||||
gamemode: String,
|
||||
server: String,
|
||||
starttime: Timestamp,
|
||||
duration: Int,
|
||||
blueleader: Int,
|
||||
redleader: Int,
|
||||
blueschem: Int?,
|
||||
redschem: Int?,
|
||||
win: Int,
|
||||
wincondition: String
|
||||
): Int = useDb {
|
||||
FightTable.insertAndGetId {
|
||||
it[FightTable.gamemode] = gamemode
|
||||
it[FightTable.server] = server
|
||||
it[FightTable.startTime] = starttime.toInstant()
|
||||
it[FightTable.duration] = duration
|
||||
it[FightTable.blueLeader] = EntityID(blueleader, SteamwarUserTable)
|
||||
it[FightTable.redLeader] = EntityID(redleader, SteamwarUserTable)
|
||||
it[FightTable.blueSchem] = blueschem?.let { EntityID(it, SchematicNodeTable) }
|
||||
it[FightTable.redSchem] = redschem?.let { EntityID(it, SchematicNodeTable) }
|
||||
it[FightTable.win] = WinningTeam.entries[win]
|
||||
it[FightTable.winCondition] = wincondition
|
||||
}.value
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getPage(page: Int, pageSize: Int): List<Fight> = useDb {
|
||||
val fights = all().orderBy(FightTable.startTime to SortOrder.DESC).limit(pageSize).offset((pageSize * page).toLong())
|
||||
|
||||
val fightPlayer = FightPlayer.batchGet(fights.map { it.id.value })
|
||||
for (fight in fights) {
|
||||
fight.initPlayers(fightPlayer)
|
||||
}
|
||||
|
||||
SteamwarUser.batchCache(fightPlayer.map { it.userID }.toMutableSet())
|
||||
fights.toList()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun markReplayAvailable(id: Int) = useDb {
|
||||
FightTable.update({ FightTable.id eq id }) {
|
||||
it[replayAvailable] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val fightID by FightTable.id.transform({ EntityID(it, FightTable) }, { it.value })
|
||||
val gameMode by FightTable.gamemode
|
||||
val server by FightTable.server
|
||||
val startTime by FightTable.startTime.transform({ it.toInstant() }, { Timestamp.from(it) })
|
||||
val duration by FightTable.duration
|
||||
val blueLeaderId by FightTable.blueLeader
|
||||
val blueLeader by lazy { useDb { SteamwarUser[blueLeaderId] } }
|
||||
val redLeaderId by FightTable.redLeader
|
||||
val redLeader by lazy { useDb { SteamwarUser[redLeaderId] } }
|
||||
val blueSchem by FightTable.blueSchem
|
||||
val redSchem by FightTable.redSchem
|
||||
val winner by FightTable.win
|
||||
val win: Int
|
||||
get() = winner.ordinal
|
||||
val winCondition by FightTable.winCondition
|
||||
val replayAvailable by FightTable.replayAvailable
|
||||
|
||||
val schemType: SchematicType?
|
||||
get() = SchematicType.fromDB(gameMode)
|
||||
|
||||
val replayAllowed by lazy {
|
||||
replayExists() && useDb {
|
||||
exec(
|
||||
"SELECT (b.NodeId IS NULL OR b.Config & 2) AND (r.NodeId IS NULL OR r.Config & 2) AS ReplayAllowed FROM Fight f LEFT OUTER JOIN SchematicNode b ON f.BlueSchem = b.NodeId LEFT OUTER JOIN SchematicNode r ON f.RedSchem = r.NodeId WHERE FightId = ?",
|
||||
args = listOf(IntegerColumnType() to this@Fight.id.value)
|
||||
) {
|
||||
if (it.next()) {
|
||||
it.getBoolean("ReplayAllowed")
|
||||
} else {
|
||||
false
|
||||
}
|
||||
} ?: false
|
||||
}
|
||||
}
|
||||
|
||||
fun replayExists() = schemType != null && replayAvailable
|
||||
fun replayAllowed() = replayAllowed
|
||||
|
||||
lateinit var bluePlayers: List<FightPlayer>
|
||||
lateinit var redPlayers: List<FightPlayer>
|
||||
|
||||
private fun initPlayers(fightPlayers: List<FightPlayer>) {
|
||||
val blue = mutableListOf<FightPlayer>()
|
||||
val red = mutableListOf<FightPlayer>()
|
||||
|
||||
for (player in fightPlayers.filter { it.fightID == id.value }) {
|
||||
if (player.team == 1)
|
||||
blue.add(player)
|
||||
else
|
||||
red.add(player)
|
||||
}
|
||||
|
||||
bluePlayers = blue
|
||||
redPlayers = red
|
||||
}
|
||||
|
||||
enum class WinningTeam {
|
||||
NONE, BLUE, RED;
|
||||
}
|
||||
}
|
||||
@@ -1,65 +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.sql;
|
||||
|
||||
import de.steamwar.sql.internal.Field;
|
||||
import de.steamwar.sql.internal.SelectStatement;
|
||||
import de.steamwar.sql.internal.Statement;
|
||||
import de.steamwar.sql.internal.Table;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class FightPlayer {
|
||||
|
||||
private static final Table<FightPlayer> table = new Table<>(FightPlayer.class);
|
||||
private static final Statement create = table.insertAll();
|
||||
private static final SelectStatement<FightPlayer> batchGet = new SelectStatement<>(table, "SELECT * FROM FightPlayer WHERE FightID IN ?");
|
||||
|
||||
@Getter
|
||||
@Field(keys = {Table.PRIMARY})
|
||||
private final int fightID;
|
||||
@Getter
|
||||
@Field(keys = {Table.PRIMARY})
|
||||
private final int userID;
|
||||
@Getter
|
||||
@Field
|
||||
private final int team;
|
||||
@Field
|
||||
private final String kit;
|
||||
@Field
|
||||
private final int kills;
|
||||
@Field
|
||||
private final boolean isOut;
|
||||
|
||||
public static void create(int fightID, int userID, boolean blue, String kit, int kills, boolean isOut) {
|
||||
create.update(fightID, userID, blue ? 1 : 2, kit, kills, isOut);
|
||||
}
|
||||
|
||||
public static List<FightPlayer> batchGet(Stream<Integer> fightIds) {
|
||||
try (SelectStatement<FightPlayer> batch = new SelectStatement<>(table, "SELECT * FROM FightPlayer WHERE FightID IN (" + fightIds.map(Object::toString).collect(Collectors.joining(", ")) + ")")) {
|
||||
return batch.listSelect();
|
||||
}
|
||||
}
|
||||
}
|
||||
80
CommonCore/SQL/src/de/steamwar/sql/FightPlayer.kt
Normal file
80
CommonCore/SQL/src/de/steamwar/sql/FightPlayer.kt
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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.sql
|
||||
|
||||
import de.steamwar.sql.internal.useDb
|
||||
import org.jetbrains.exposed.v1.core.dao.id.CompositeID
|
||||
import org.jetbrains.exposed.v1.core.dao.id.CompositeIdTable
|
||||
import org.jetbrains.exposed.v1.core.dao.id.EntityID
|
||||
import org.jetbrains.exposed.v1.core.inList
|
||||
import org.jetbrains.exposed.v1.dao.CompositeEntity
|
||||
import org.jetbrains.exposed.v1.dao.CompositeEntityClass
|
||||
import org.jetbrains.exposed.v1.jdbc.insertIgnore
|
||||
|
||||
object FightPlayerTable : CompositeIdTable("FightPlayer") {
|
||||
val fightId = reference("FightId", FightTable)
|
||||
val userId = reference("UserId", SteamwarUserTable)
|
||||
val team = integer("Team")
|
||||
val kit = varchar("Kit", 64)
|
||||
val kills = integer("Kills")
|
||||
val out = bool("IsOut")
|
||||
|
||||
init {
|
||||
addIdColumn(fightId)
|
||||
addIdColumn(userId)
|
||||
}
|
||||
}
|
||||
|
||||
class FightPlayer(id: EntityID<CompositeID>) : CompositeEntity(id) {
|
||||
companion object : CompositeEntityClass<FightPlayer>(FightPlayerTable) {
|
||||
@JvmStatic
|
||||
fun create(
|
||||
fightId: Int,
|
||||
userId: Int,
|
||||
blue: Boolean,
|
||||
kit: String,
|
||||
kills: Int,
|
||||
out: Boolean
|
||||
) = useDb {
|
||||
FightPlayerTable.insertIgnore {
|
||||
it[this.fightId] = fightId
|
||||
it[this.userId] = userId
|
||||
it[this.team] = if (blue) 1 else 2
|
||||
it[this.kit] = kit
|
||||
it[this.kills] = kills
|
||||
it[this.out] = out
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun batchGet(fightIds: List<Int>) = useDb {
|
||||
find { FightPlayerTable.fightId inList fightIds.toList() }.toList()
|
||||
}
|
||||
}
|
||||
|
||||
val fightID by FightPlayerTable.fightId.transform({ EntityID(it, FightTable) }, { it.value })
|
||||
val userID by FightPlayerTable.userId.transform({ EntityID(it, SteamwarUserTable) }, { it.value })
|
||||
val team by FightPlayerTable.team
|
||||
val kit by FightPlayerTable.kit
|
||||
val kills by FightPlayerTable.kills
|
||||
val out by FightPlayerTable.out
|
||||
|
||||
fun isOut() = out
|
||||
}
|
||||
@@ -35,11 +35,19 @@ import java.util.stream.Collectors;
|
||||
public final class GameModeConfig<M, W> {
|
||||
|
||||
public static final Function<String, String> ToString = Function.identity();
|
||||
public static final Function<File, String> ToStaticWarGear = __ -> "WarGear";
|
||||
public static final Function<File, String> ToInternalName = file -> file != null ? file.getName().replace(".yml", "") : "WarGear";
|
||||
public static final Function<File, String> ToStaticWarGear = GameModeConfig::constWarGear;
|
||||
public static final Function<File, String> ToInternalName = GameModeConfig::internalName;
|
||||
public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd.MM.yyyy HH:mm");
|
||||
private static final Random random = new Random();
|
||||
|
||||
private static String constWarGear(File f) {
|
||||
return "WarGear";
|
||||
}
|
||||
|
||||
private static String internalName(File f) {
|
||||
return f != null ? f.getName().replace(".yml", "") : constWarGear(null);
|
||||
}
|
||||
|
||||
private static final Map<String, GameModeConfig<?, String>> byFileName;
|
||||
private static final Map<String, GameModeConfig<?, String>> byGameName;
|
||||
private static final Map<SchematicType, GameModeConfig<?, String>> bySchematicType;
|
||||
@@ -63,11 +71,15 @@ public final class GameModeConfig<M, W> {
|
||||
}
|
||||
|
||||
private static final Field Schematic_TypeField;
|
||||
private static final Field Schematic_SubTypesField;
|
||||
|
||||
static {
|
||||
try {
|
||||
Schematic_TypeField = SchematicConfig.class.getDeclaredField("Type");
|
||||
Schematic_TypeField.setAccessible(true);
|
||||
|
||||
Schematic_SubTypesField = SchematicConfig.class.getDeclaredField("SubTypes");
|
||||
Schematic_SubTypesField.setAccessible(true);
|
||||
} catch (NoSuchFieldException e) {
|
||||
throw new SecurityException(e.getMessage(), e);
|
||||
}
|
||||
@@ -77,6 +89,18 @@ public final class GameModeConfig<M, W> {
|
||||
bySchematicType = new HashMap<>();
|
||||
SchematicType.values();
|
||||
DEFAULTS = SQLWrapper.impl.loadGameModeConfig(null);
|
||||
|
||||
byFileName.values().forEach(gameModeConfig -> {
|
||||
List<SchematicType> subTypes = Collections.unmodifiableList(gameModeConfig.Schematic.SubTypesStrings.stream()
|
||||
.map(SchematicType::fromDB)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList()));
|
||||
try {
|
||||
Schematic_SubTypesField.set(gameModeConfig.Schematic, subTypes);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new SecurityException(e.getMessage(), e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public final boolean loaded;
|
||||
@@ -516,6 +540,8 @@ public final class GameModeConfig<M, W> {
|
||||
*/
|
||||
public final SchematicType Type;
|
||||
|
||||
private final List<String> SubTypesStrings;
|
||||
|
||||
/**
|
||||
* The schematic types that are also allowed to be chosen in this arena
|
||||
*/
|
||||
@@ -605,6 +631,13 @@ public final class GameModeConfig<M, W> {
|
||||
*/
|
||||
public final int MaxDispenserItems;
|
||||
|
||||
/**
|
||||
* Maximal blast resistance for the blocks
|
||||
*
|
||||
* @implSpec {@code Double.MAX_VALUE} by default
|
||||
*/
|
||||
public final double MaxBlastResistance;
|
||||
|
||||
/**
|
||||
* Maximal blast resistance for the design blocks
|
||||
*
|
||||
@@ -623,6 +656,7 @@ public final class GameModeConfig<M, W> {
|
||||
Size = new SizeConfig(loader.with("Size"));
|
||||
Inset = new InsetConfig(loader.with("Inset"));
|
||||
Type = loader.getSchematicType("Type", "Normal");
|
||||
SubTypesStrings = loader.getStringList("SubTypes");
|
||||
SubTypes = loader.getSchematicTypeList("SubTypes");
|
||||
Shortcut = loader.getString("Shortcut", "");
|
||||
Material = loader.getMaterial("Material", "STONE_BUTTON");
|
||||
@@ -636,6 +670,7 @@ public final class GameModeConfig<M, W> {
|
||||
UnlimitedPrepare = loader.getBoolean("UnlimitedPrepare", false);
|
||||
MaxBlocks = loader.getInt("MaxBlocks", 0);
|
||||
MaxDispenserItems = loader.getInt("MaxDispenserItems", 128);
|
||||
MaxBlastResistance = loader.getDouble("MaxBlastResistance", Double.MAX_VALUE);
|
||||
MaxDesignBlastResistance = loader.getDouble("MaxDesignBlastResistance", Double.MAX_VALUE);
|
||||
|
||||
Map<Set<M>, Integer> Limited = new HashMap<>();
|
||||
@@ -650,6 +685,10 @@ public final class GameModeConfig<M, W> {
|
||||
Limited.put(Collections.unmodifiableSet(materials.stream().map(String::toUpperCase).map(loader.materialMapper).collect(Collectors.toSet())), amount);
|
||||
}
|
||||
}
|
||||
SQLWrapper.impl.getMaterialWithGreaterBlastResistance(MaxBlastResistance).forEach(material -> {
|
||||
if (Limited.entrySet().stream().anyMatch(entry -> entry.getKey().contains(material))) return;
|
||||
Limited.put(Collections.singleton((M) material), 0);
|
||||
});
|
||||
this.Limited = Collections.unmodifiableMap(Limited);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,59 +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.sql;
|
||||
|
||||
import de.steamwar.sql.internal.Field;
|
||||
import de.steamwar.sql.internal.SelectStatement;
|
||||
import de.steamwar.sql.internal.Statement;
|
||||
import de.steamwar.sql.internal.Table;
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.util.UUID;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class IgnoreSystem {
|
||||
|
||||
private static final Table<IgnoreSystem> table = new Table<>(IgnoreSystem.class, "IgnoredPlayers");
|
||||
private static final SelectStatement<IgnoreSystem> select = table.select(Table.PRIMARY);
|
||||
private static final Statement insert = table.insertAll();
|
||||
private static final Statement delete = table.delete(Table.PRIMARY);
|
||||
|
||||
@Field(keys = {Table.PRIMARY})
|
||||
private final int ignorer;
|
||||
@Field(keys = {Table.PRIMARY})
|
||||
private final int ignored;
|
||||
|
||||
public static boolean isIgnored(UUID ignorer, UUID ignored){
|
||||
return isIgnored(SteamwarUser.get(ignorer), SteamwarUser.get(ignored));
|
||||
}
|
||||
|
||||
public static boolean isIgnored(SteamwarUser ignorer, SteamwarUser ignored) {
|
||||
return select.select(ResultSet::next, ignorer.getId(), ignored.getId());
|
||||
}
|
||||
|
||||
public static void ignore(SteamwarUser ignorer, SteamwarUser ignored) {
|
||||
insert.update(ignorer.getId(), ignored.getId());
|
||||
}
|
||||
|
||||
public static void unIgnore(SteamwarUser ignorer, SteamwarUser ignored) {
|
||||
delete.update(ignorer.getId(), ignored.getId());
|
||||
}
|
||||
}
|
||||
74
CommonCore/SQL/src/de/steamwar/sql/IgnoreSystem.kt
Normal file
74
CommonCore/SQL/src/de/steamwar/sql/IgnoreSystem.kt
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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.sql
|
||||
|
||||
import de.steamwar.sql.internal.useDb
|
||||
import org.jetbrains.exposed.v1.core.and
|
||||
import org.jetbrains.exposed.v1.core.dao.id.CompositeID
|
||||
import org.jetbrains.exposed.v1.core.dao.id.CompositeIdTable
|
||||
import org.jetbrains.exposed.v1.core.dao.id.EntityID
|
||||
import org.jetbrains.exposed.v1.core.eq
|
||||
import org.jetbrains.exposed.v1.dao.CompositeEntity
|
||||
import org.jetbrains.exposed.v1.dao.CompositeEntityClass
|
||||
import java.util.*
|
||||
|
||||
object IgnoreSystemTable: CompositeIdTable("IgnoredPlayers") {
|
||||
val ignorer = reference("Ignorer", SteamwarUserTable)
|
||||
val ignored = reference("Ignored", SteamwarUserTable)
|
||||
|
||||
override val primaryKey = PrimaryKey(ignorer, ignored)
|
||||
|
||||
init {
|
||||
addIdColumn(ignorer)
|
||||
addIdColumn(ignored)
|
||||
}
|
||||
}
|
||||
|
||||
class IgnoreSystem(id: EntityID<CompositeID>) : CompositeEntity(id) {
|
||||
var ignorer by IgnoreSystemTable.ignorer
|
||||
var ignored by IgnoreSystemTable.ignored
|
||||
|
||||
companion object : CompositeEntityClass<IgnoreSystem>(IgnoreSystemTable) {
|
||||
@JvmStatic
|
||||
fun isIgnored(ignorer: UUID, ignored: UUID) = useDb { isIgnored(SteamwarUser.get(ignorer)!!, SteamwarUser.get(ignored)!!) }
|
||||
|
||||
@JvmStatic
|
||||
fun isIgnored(ignorer: SteamwarUser, ignored: SteamwarUser) = useDb {
|
||||
find {
|
||||
(IgnoreSystemTable.ignorer eq ignorer.id) and (IgnoreSystemTable.ignored eq ignored.id)
|
||||
}.firstOrNull() != null
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun ignore(ignorer: SteamwarUser, ignored: SteamwarUser) = useDb {
|
||||
new {
|
||||
this.ignorer = ignorer.id
|
||||
this.ignored = ignored.id
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun unIgnore(ignorer: SteamwarUser, ignored: SteamwarUser) = useDb {
|
||||
find {
|
||||
(IgnoreSystemTable.ignorer eq ignorer.id) and (IgnoreSystemTable.ignored eq ignored.id)
|
||||
}.firstOrNull()?.delete()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,101 +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.sql;
|
||||
|
||||
import de.steamwar.sql.internal.*;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class Mod {
|
||||
|
||||
static {
|
||||
SqlTypeMapper.ordinalEnumMapper(Platform.class);
|
||||
SqlTypeMapper.ordinalEnumMapper(ModType.class);
|
||||
}
|
||||
|
||||
private static final Table<Mod> table = new Table<>(Mod.class, "Mods");
|
||||
private static final SelectStatement<Mod> get = table.select(Table.PRIMARY);
|
||||
private static final SelectStatement<Mod> findFirst = new SelectStatement<>(table, "SELECT * FROM Mods WHERE ModType = 0 LIMIT 1");
|
||||
private static final SelectStatement<Mod> getPageOfType = new SelectStatement<>(table, "SELECT * FROM Mods WHERE ModType = ? ORDER BY ModName DESC LIMIT ?, ?");
|
||||
private static final Statement insert = table.insert(Table.PRIMARY);
|
||||
private static final Statement set = table.update(Table.PRIMARY, "ModType");
|
||||
|
||||
public static Mod get(String name, Platform platform) {
|
||||
return get.select(platform, name);
|
||||
}
|
||||
|
||||
public static Mod getOrCreate(String name, Platform platform) {
|
||||
Mod mod = get(name, platform);
|
||||
if(mod != null)
|
||||
return mod;
|
||||
|
||||
insert.update(platform, name);
|
||||
return new Mod(platform, name, ModType.UNKLASSIFIED);
|
||||
}
|
||||
|
||||
public static List<Mod> getAllModsFiltered(int page, int elementsPerPage, ModType filter) {
|
||||
return Mod.getPageOfType.listSelect(filter, page * elementsPerPage, elementsPerPage);
|
||||
}
|
||||
|
||||
public static Mod findFirstMod() {
|
||||
return findFirst.select();
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Field(keys = {Table.PRIMARY})
|
||||
private final Platform platform;
|
||||
@Getter
|
||||
@Field(keys = {Table.PRIMARY})
|
||||
private final String modName;
|
||||
@Getter
|
||||
@Field(def = "0")
|
||||
private ModType modType;
|
||||
|
||||
public void setModType(ModType modType) {
|
||||
set.update(modType, platform, modName);
|
||||
this.modType = modType;
|
||||
}
|
||||
|
||||
public enum Platform {
|
||||
FORGE,
|
||||
LABYMOD,
|
||||
FABRIC
|
||||
}
|
||||
|
||||
public enum ModType {
|
||||
UNKLASSIFIED("7"),
|
||||
GREEN("a"),
|
||||
YELLOW("e"),
|
||||
RED("c"),
|
||||
YOUTUBER_ONLY("6");
|
||||
|
||||
ModType(String colorcode) {
|
||||
this.colorcode = colorcode;
|
||||
}
|
||||
private final String colorcode;
|
||||
|
||||
public String getColorCode() {
|
||||
return colorcode;
|
||||
}
|
||||
}
|
||||
}
|
||||
88
CommonCore/SQL/src/de/steamwar/sql/Mod.kt
Normal file
88
CommonCore/SQL/src/de/steamwar/sql/Mod.kt
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* 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.sql
|
||||
|
||||
import de.steamwar.sql.internal.useDb
|
||||
import org.jetbrains.exposed.v1.core.SortOrder
|
||||
import org.jetbrains.exposed.v1.core.and
|
||||
import org.jetbrains.exposed.v1.core.dao.id.CompositeID
|
||||
import org.jetbrains.exposed.v1.core.dao.id.CompositeIdTable
|
||||
import org.jetbrains.exposed.v1.core.dao.id.EntityID
|
||||
import org.jetbrains.exposed.v1.core.eq
|
||||
import org.jetbrains.exposed.v1.dao.CompositeEntity
|
||||
import org.jetbrains.exposed.v1.dao.CompositeEntityClass
|
||||
|
||||
object ModTable : CompositeIdTable("Mods") {
|
||||
val platform = enumeration("Platform", Mod.Platform::class)
|
||||
val modName = varchar("ModName", 100)
|
||||
val modeType = enumerationByName("ModType", 10, Mod.ModType::class)
|
||||
}
|
||||
|
||||
class Mod(id: EntityID<CompositeID>) : CompositeEntity(id) {
|
||||
companion object : CompositeEntityClass<Mod>(ModTable) {
|
||||
@JvmStatic
|
||||
fun get(modName: String, platform: Platform) = useDb {
|
||||
find { ModTable.platform eq platform and (ModTable.modName eq modName) }.firstOrNull()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getOrCreate(modName: String, platform: Platform) = useDb {
|
||||
get(modName, platform) ?: new {
|
||||
this.platform = platform
|
||||
this.modName = modName
|
||||
this.type = ModType.UNKLASSIFIED
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getAllModsFiltered(page: Int, elementsPerPage: Int, filter: ModType) = useDb {
|
||||
find { ModTable.modeType eq filter }.limit(elementsPerPage).offset((elementsPerPage * page).toLong())
|
||||
.orderBy(
|
||||
ModTable.modName to SortOrder.DESC
|
||||
).toList()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun findFirstMod() = useDb {
|
||||
find { ModTable.modeType eq ModType.UNKLASSIFIED }.limit(1).firstOrNull()
|
||||
}
|
||||
}
|
||||
|
||||
var platform by ModTable.platform
|
||||
var modName by ModTable.modName
|
||||
private var type by ModTable.modeType
|
||||
var modType: ModType
|
||||
get() = type
|
||||
set(value) = useDb { type = value }
|
||||
|
||||
enum class Platform {
|
||||
FORGE,
|
||||
LABYMOD,
|
||||
FABRIC
|
||||
}
|
||||
|
||||
enum class ModType(val colorCode: String) {
|
||||
UNKLASSIFIED("7"),
|
||||
GREEN("a"),
|
||||
YELLOW("e"),
|
||||
RED("c"),
|
||||
YOUTUBER_ONLY("6");
|
||||
}
|
||||
}
|
||||
@@ -1,137 +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.sql;
|
||||
|
||||
import de.steamwar.sql.internal.*;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import javax.swing.plaf.nimbus.State;
|
||||
import java.io.*;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.Timestamp;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public class NodeData {
|
||||
static {
|
||||
new SqlTypeMapper<>(PipedInputStream.class, "BLOB", (rs, identifier) -> { throw new SecurityException("PipedInputStream is write only datatype"); }, PreparedStatement::setBinaryStream);
|
||||
new SqlTypeMapper<>(ByteArrayInputStream.class, "BLOB", (rs, identifier) -> { throw new SecurityException("ByteArrayInputStream is write only datatype"); }, PreparedStatement::setBinaryStream);
|
||||
new SqlTypeMapper<>(BufferedInputStream.class, "BLOB", (rs, identifier) -> { throw new SecurityException("BufferedInputStream is write only datatype"); }, PreparedStatement::setBinaryStream);
|
||||
|
||||
SqlTypeMapper.ordinalEnumMapper(SchematicFormat.class);
|
||||
}
|
||||
|
||||
private static final Table<NodeData> table = new Table<>(NodeData.class);
|
||||
|
||||
private static final Statement updateDatabase = new Statement("INSERT INTO NodeData(NodeId, NodeFormat, SchemData) VALUES (?, ?, ?)", true);
|
||||
private static final Statement selSchemData = new Statement("SELECT SchemData FROM NodeData WHERE NodeId = ? AND CreatedAt = ?");
|
||||
private static final Statement delete = table.delete(Table.PRIMARY);
|
||||
|
||||
private static final SelectStatement<NodeData> get = new SelectStatement<>(table, "SELECT NodeId, CreatedAt, NodeFormat FROM NodeData WHERE NodeId = ? ORDER BY CreatedAt ");
|
||||
private static final Statement getRevisions = new Statement("SELECT COUNT(DISTINCT CreatedAt) as CNT FROM NodeData WHERE NodeId = ?");
|
||||
private static final SelectStatement<NodeData> getLatest = new SelectStatement<>(table, "SELECT NodeId, CreatedAt, NodeFormat FROM NodeData WHERE NodeId = ? ORDER BY CreatedAt DESC LIMIT 1");
|
||||
|
||||
public static NodeData getLatest(SchematicNode node) {
|
||||
if (node.isDir()) throw new IllegalArgumentException("Node is dir");
|
||||
return Optional.ofNullable(getLatest.select(node)).orElseGet(() -> new NodeData(node.getId(), Timestamp.from(Instant.now()), SchematicFormat.MCEDIT));
|
||||
}
|
||||
|
||||
public static List<NodeData> get(SchematicNode node) {
|
||||
return get.listSelect(node);
|
||||
}
|
||||
|
||||
public static NodeData get(SchematicNode node, int revision) {
|
||||
return get.listSelect(node).get(revision - 1);
|
||||
}
|
||||
|
||||
public static int getRevisions(SchematicNode node) {
|
||||
return getRevisions.select(rs -> {
|
||||
if (rs.next()) {
|
||||
return rs.getInt("CNT");
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}, node);
|
||||
}
|
||||
|
||||
public static void saveFromStream(SchematicNode node, InputStream blob, SchematicFormat format) {
|
||||
updateDatabase.update(node.getId(), format, blob);
|
||||
}
|
||||
|
||||
@Field(keys = {Table.PRIMARY})
|
||||
private final int nodeId;
|
||||
|
||||
@Field(keys = {Table.PRIMARY})
|
||||
private Timestamp createdAt;
|
||||
|
||||
@Field
|
||||
private SchematicFormat nodeFormat;
|
||||
|
||||
public InputStream schemData() throws IOException {
|
||||
return schemData(true);
|
||||
}
|
||||
|
||||
public InputStream schemData(boolean decompress) throws IOException {
|
||||
try {
|
||||
return selSchemData.select(rs -> {
|
||||
rs.next();
|
||||
InputStream schemData = rs.getBinaryStream("SchemData");
|
||||
try {
|
||||
if(rs.wasNull() || schemData.available() == 0) {
|
||||
throw new SecurityException("SchemData is null");
|
||||
}
|
||||
if (decompress) {
|
||||
return new GZIPInputStream(schemData);
|
||||
} else {
|
||||
return schemData;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new SecurityException("SchemData is wrong", e);
|
||||
}
|
||||
}, nodeId, createdAt);
|
||||
} catch (Exception e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void saveFromStream(InputStream blob, SchematicFormat newFormat) {
|
||||
saveFromStream(SchematicNode.getSchematicNode(nodeId), blob, newFormat);
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
delete.update(nodeId, createdAt);
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum SchematicFormat {
|
||||
MCEDIT(".schematic"),
|
||||
SPONGE_V2(".schem"),
|
||||
SPONGE_V3(".schem");
|
||||
|
||||
private final String fileEnding;
|
||||
}
|
||||
}
|
||||
100
CommonCore/SQL/src/de/steamwar/sql/NodeData.kt
Normal file
100
CommonCore/SQL/src/de/steamwar/sql/NodeData.kt
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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.sql
|
||||
|
||||
import de.steamwar.sql.internal.useDb
|
||||
import org.jetbrains.exposed.v1.core.SortOrder
|
||||
import org.jetbrains.exposed.v1.core.dao.id.CompositeID
|
||||
import org.jetbrains.exposed.v1.core.dao.id.CompositeIdTable
|
||||
import org.jetbrains.exposed.v1.core.dao.id.EntityID
|
||||
import org.jetbrains.exposed.v1.core.eq
|
||||
import org.jetbrains.exposed.v1.core.statements.api.ExposedBlob
|
||||
import org.jetbrains.exposed.v1.dao.CompositeEntity
|
||||
import org.jetbrains.exposed.v1.dao.CompositeEntityClass
|
||||
import org.jetbrains.exposed.v1.javatime.CurrentTimestamp
|
||||
import org.jetbrains.exposed.v1.javatime.timestamp
|
||||
import org.jetbrains.exposed.v1.jdbc.insert
|
||||
import java.io.InputStream
|
||||
import java.util.zip.GZIPInputStream
|
||||
|
||||
object NodeDataTable: CompositeIdTable("NodeData") {
|
||||
val nodeId = reference("NodeId", SchematicNodeTable)
|
||||
val createdAt = timestamp("CreatedAt").defaultExpression(CurrentTimestamp).entityId()
|
||||
val nodeFormat = enumeration("NodeFormat", NodeData.SchematicFormat::class)
|
||||
val schemData = blob("SchemData")
|
||||
|
||||
override val primaryKey = PrimaryKey(nodeId, createdAt)
|
||||
|
||||
init {
|
||||
addIdColumn(nodeId)
|
||||
}
|
||||
}
|
||||
|
||||
class NodeData(id: EntityID<CompositeID>): CompositeEntity(id) {
|
||||
val nodeId by NodeDataTable.nodeId
|
||||
val createdAt by NodeDataTable.createdAt
|
||||
val nodeFormat by NodeDataTable.nodeFormat
|
||||
val schemData by NodeDataTable.schemData
|
||||
|
||||
companion object: CompositeEntityClass<NodeData>(NodeDataTable) {
|
||||
@JvmStatic
|
||||
fun getLatest(node: SchematicNode) = useDb {
|
||||
find { (NodeDataTable.nodeId eq node.nodeId) }.orderBy(NodeDataTable.createdAt to SortOrder.DESC).firstOrNull()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun get(node: SchematicNode) = useDb {
|
||||
find { (NodeDataTable.nodeId eq node.nodeId) }.orderBy(NodeDataTable.createdAt to SortOrder.ASC).toList()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun get(node: SchematicNode, revision: Int) = useDb {
|
||||
find { NodeDataTable.nodeId eq node.nodeId }.orderBy(NodeDataTable.createdAt to SortOrder.ASC).toList().get(revision - 1)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getRevisions(node: SchematicNode) = useDb {
|
||||
count(NodeDataTable.nodeId eq node.nodeId).toInt()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun saveFromStream(node: SchematicNode, blob: InputStream, format: SchematicFormat) = useDb {
|
||||
NodeDataTable.insert {
|
||||
it[NodeDataTable.nodeId] = EntityID(node.getId(), SchematicNodeTable)
|
||||
it[NodeDataTable.nodeFormat] = format
|
||||
it[NodeDataTable.schemData] = ExposedBlob(blob.readBytes())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun schemData(decompress: Boolean) = useDb {
|
||||
schemData.inputStream.let { if(decompress) GZIPInputStream(it) else it }
|
||||
}
|
||||
|
||||
fun schemData() = schemData(true)
|
||||
|
||||
override fun delete() = useDb { super.delete() }
|
||||
|
||||
enum class SchematicFormat(val fileEnding: String) {
|
||||
MCEDIT(".schematic"),
|
||||
SPONGE_V2(".schem"),
|
||||
SPONGE_V3(".schem");
|
||||
}
|
||||
}
|
||||
@@ -1,86 +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.sql;
|
||||
|
||||
import de.steamwar.sql.internal.Field;
|
||||
import de.steamwar.sql.internal.SelectStatement;
|
||||
import de.steamwar.sql.internal.Statement;
|
||||
import de.steamwar.sql.internal.Table;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.sql.Timestamp;
|
||||
import java.time.Instant;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class NodeDownload {
|
||||
|
||||
private static final char[] HEX = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
|
||||
private static final String LINK_BASE = "https://api.steamwar.de/download/";
|
||||
|
||||
private static final Table<NodeDownload> table = new Table<>(NodeDownload.class);
|
||||
private static final Statement insert = table.insertFields("NodeId", "Link");
|
||||
|
||||
private static final SelectStatement<NodeDownload> select = table.selectFields("link");
|
||||
|
||||
private static final Statement delete = table.delete(Table.PRIMARY);
|
||||
|
||||
public static NodeDownload get(String link) {
|
||||
return select.select(link);
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Field(keys = {Table.PRIMARY})
|
||||
private final int nodeId;
|
||||
@Field
|
||||
private final String link;
|
||||
@Field(def = "CURRENT_TIMESTAMP")
|
||||
@Getter
|
||||
private final Timestamp timestamp;
|
||||
|
||||
public static String getLink(SchematicNode schem){
|
||||
if(schem.isDir())
|
||||
throw new SecurityException("Can not Download Directorys");
|
||||
MessageDigest digest;
|
||||
try {
|
||||
digest = MessageDigest.getInstance("SHA-1");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new SecurityException(e);
|
||||
}
|
||||
digest.reset();
|
||||
digest.update((Instant.now().toString() + schem.getOwner() + schem.getId()).getBytes());
|
||||
String hash = base16encode(digest.digest());
|
||||
insert.update(schem.getId(), hash);
|
||||
return LINK_BASE + hash;
|
||||
}
|
||||
|
||||
public static String base16encode(byte[] byteArray) {
|
||||
StringBuilder hexBuffer = new StringBuilder(byteArray.length * 2);
|
||||
for (byte b : byteArray)
|
||||
hexBuffer.append(HEX[(b >>> 4) & 0xF]).append(HEX[b & 0xF]);
|
||||
return hexBuffer.toString();
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
delete.update(nodeId);
|
||||
}
|
||||
}
|
||||
76
CommonCore/SQL/src/de/steamwar/sql/NodeDownload.kt
Normal file
76
CommonCore/SQL/src/de/steamwar/sql/NodeDownload.kt
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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.sql
|
||||
|
||||
import de.steamwar.sql.internal.useDb
|
||||
import org.jetbrains.exposed.v1.core.dao.id.EntityID
|
||||
import org.jetbrains.exposed.v1.core.dao.id.IdTable
|
||||
import org.jetbrains.exposed.v1.core.eq
|
||||
import org.jetbrains.exposed.v1.dao.IntEntity
|
||||
import org.jetbrains.exposed.v1.dao.IntEntityClass
|
||||
import org.jetbrains.exposed.v1.javatime.CurrentTimestamp
|
||||
import org.jetbrains.exposed.v1.javatime.timestamp
|
||||
import java.security.MessageDigest
|
||||
import java.sql.Timestamp
|
||||
import java.time.Instant
|
||||
|
||||
object NodeDownloadTable: IdTable<Int>("NodeDownload") {
|
||||
override val id = reference("NodeId", SchematicNodeTable).uniqueIndex()
|
||||
val link = varchar("Link", 255)
|
||||
val timestamp = timestamp("Timestamp").defaultExpression(CurrentTimestamp)
|
||||
}
|
||||
|
||||
class NodeDownload(id: EntityID<Int>) : IntEntity(id) {
|
||||
companion object : IntEntityClass<NodeDownload>(NodeDownloadTable) {
|
||||
const val LINK_BASE = "https://api.steamwar.de/download/"
|
||||
|
||||
@JvmStatic
|
||||
fun getLink(schem: SchematicNode): String {
|
||||
if (schem.isDir())
|
||||
throw IllegalArgumentException("Cannot get link for directory")
|
||||
|
||||
val digest = MessageDigest.getInstance("SHA-1")
|
||||
digest.update("${Instant.now()}${schem.owner}${schem.nodeId}".toByteArray())
|
||||
val hash = digest.digest().joinToString("") { "%02x".format(it) }
|
||||
useDb {
|
||||
findByIdAndUpdate(schem.id.value) {
|
||||
it.link = hash
|
||||
} ?: new {
|
||||
nodeId = schem.id.value
|
||||
link = hash
|
||||
}
|
||||
}
|
||||
return "${LINK_BASE}${hash}"
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun get(link: String) = useDb {
|
||||
find { NodeDownloadTable.link eq link }.firstOrNull()
|
||||
}
|
||||
}
|
||||
|
||||
var nodeId by NodeDownloadTable.id.transform({ EntityID(it, SchematicNodeTable) }, { it.value })
|
||||
var link by NodeDownloadTable.link
|
||||
var timestamp by NodeDownloadTable.timestamp.transform({ it.toInstant() }, { Timestamp.from(it) })
|
||||
|
||||
override fun delete() = useDb {
|
||||
super.delete()
|
||||
}
|
||||
}
|
||||
@@ -1,95 +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.sql;
|
||||
|
||||
import de.steamwar.sql.internal.Field;
|
||||
import de.steamwar.sql.internal.SelectStatement;
|
||||
import de.steamwar.sql.internal.Statement;
|
||||
import de.steamwar.sql.internal.Table;
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class NodeMember {
|
||||
|
||||
public static void init() {
|
||||
// enforce class initialization
|
||||
}
|
||||
|
||||
private static final Table<NodeMember> table = new Table<>(NodeMember.class);
|
||||
private static final SelectStatement<NodeMember> getNodeMember = table.select(Table.PRIMARY);
|
||||
private static final SelectStatement<NodeMember> getNodeMembers = table.selectFields("NodeId");
|
||||
private static final SelectStatement<NodeMember> getSchematics = table.selectFields("UserId");
|
||||
private static final Statement create = table.insert(Table.PRIMARY);
|
||||
private static final Statement delete = table.delete(Table.PRIMARY);
|
||||
private static final Statement updateParent = table.update(Table.PRIMARY, "ParentId");
|
||||
|
||||
@Field(keys = {Table.PRIMARY})
|
||||
private final int nodeId;
|
||||
@Field(keys = {Table.PRIMARY})
|
||||
private final int userId;
|
||||
@Field(nullable = true, def = "null")
|
||||
private Integer parentId;
|
||||
|
||||
public int getNode() {
|
||||
return nodeId;
|
||||
}
|
||||
|
||||
public int getMember() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public Optional<Integer> getParent() {
|
||||
return Optional.ofNullable(parentId);
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
delete.update(nodeId, userId);
|
||||
}
|
||||
|
||||
public static NodeMember createNodeMember(int node, int member) {
|
||||
create.update(node, member);
|
||||
return new NodeMember(node, member, null);
|
||||
}
|
||||
|
||||
public static NodeMember getNodeMember(int node, SteamwarUser member) {
|
||||
return getNodeMember(node, member.getId());
|
||||
}
|
||||
|
||||
public static NodeMember getNodeMember(int node, int member) {
|
||||
return getNodeMember.select(node, member);
|
||||
}
|
||||
|
||||
public static Set<NodeMember> getNodeMembers(int node) {
|
||||
return new HashSet<>(getNodeMembers.listSelect(node));
|
||||
}
|
||||
|
||||
public static Set<NodeMember> getSchematics(int member) {
|
||||
return new HashSet<>(getSchematics.listSelect(member));
|
||||
}
|
||||
|
||||
public void setParentId(Integer parentId) {
|
||||
this.parentId = parentId;
|
||||
updateParent.update(this.parentId, nodeId, userId);
|
||||
}
|
||||
}
|
||||
92
CommonCore/SQL/src/de/steamwar/sql/NodeMember.kt
Normal file
92
CommonCore/SQL/src/de/steamwar/sql/NodeMember.kt
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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.sql
|
||||
|
||||
import de.steamwar.sql.internal.useDb
|
||||
import org.jetbrains.exposed.v1.core.and
|
||||
import org.jetbrains.exposed.v1.core.dao.id.CompositeID
|
||||
import org.jetbrains.exposed.v1.core.dao.id.CompositeIdTable
|
||||
import org.jetbrains.exposed.v1.core.dao.id.EntityID
|
||||
import org.jetbrains.exposed.v1.core.eq
|
||||
import org.jetbrains.exposed.v1.dao.CompositeEntity
|
||||
import org.jetbrains.exposed.v1.dao.CompositeEntityClass
|
||||
import org.jetbrains.exposed.v1.jdbc.insertIgnore
|
||||
import java.util.*
|
||||
import kotlin.jvm.optionals.getOrNull
|
||||
|
||||
object NodeMemberTable : CompositeIdTable("NodeMember") {
|
||||
val node = reference("NodeId", SchematicNodeTable)
|
||||
val userId = reference("UserId", SteamwarUserTable)
|
||||
val parentNode = optReference("ParentId", SchematicNodeTable)
|
||||
|
||||
override val primaryKey = PrimaryKey(node, userId)
|
||||
|
||||
init {
|
||||
addIdColumn(node)
|
||||
addIdColumn(userId)
|
||||
}
|
||||
}
|
||||
|
||||
class NodeMember(id: EntityID<CompositeID>) : CompositeEntity(id) {
|
||||
companion object : CompositeEntityClass<NodeMember>(NodeMemberTable) {
|
||||
@JvmStatic
|
||||
fun createNodeMember(node: Int, member: Int): NodeMember = useDb {
|
||||
NodeMemberTable.insertIgnore {
|
||||
it[this.node] = EntityID(node, SchematicNodeTable)
|
||||
it[this.userId] = EntityID(member, SteamwarUserTable)
|
||||
}
|
||||
getNodeMember(node, member) ?: throw IllegalStateException("NodeMember not created")
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun createNodeMember(node: Int, member: SteamwarUser) = createNodeMember(node, member.id.value)
|
||||
|
||||
@JvmStatic
|
||||
fun getNodeMember(node: Int, member: Int) = useDb {
|
||||
find { (NodeMemberTable.node eq node) and (NodeMemberTable.userId eq member) }.firstOrNull()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getNodeMember(node: Int, member: SteamwarUser) = getNodeMember(node, member.id.value)
|
||||
|
||||
@JvmStatic
|
||||
fun getNodeMembers(node: Int) = useDb { find { NodeMemberTable.node eq node }.toSet() }
|
||||
|
||||
@JvmStatic
|
||||
fun getSchematics(member: Int) = useDb { find { NodeMemberTable.userId eq member }.toSet() }
|
||||
|
||||
@JvmStatic
|
||||
fun init() = Unit
|
||||
}
|
||||
|
||||
val node by NodeMemberTable.node.transform({ EntityID(it, SchematicNodeTable) }, { it.value })
|
||||
val member by NodeMemberTable.userId.transform({ EntityID(it, SteamwarUserTable) }, { it.value })
|
||||
var parent by NodeMemberTable.parentNode.transform(
|
||||
{ it.map { EntityID(it, SchematicNodeTable) }.getOrNull() },
|
||||
{ Optional.ofNullable(it?.value) })
|
||||
|
||||
fun setParentId(id: Int?) {
|
||||
parent = Optional.ofNullable(id)
|
||||
}
|
||||
|
||||
override fun delete() = useDb {
|
||||
super.delete()
|
||||
}
|
||||
}
|
||||
117
CommonCore/SQL/src/de/steamwar/sql/PersonalKit.kt
Normal file
117
CommonCore/SQL/src/de/steamwar/sql/PersonalKit.kt
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* 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.sql
|
||||
|
||||
import de.steamwar.sql.internal.useDb
|
||||
import org.jetbrains.exposed.v1.core.and
|
||||
import org.jetbrains.exposed.v1.core.dao.id.CompositeID
|
||||
import org.jetbrains.exposed.v1.core.dao.id.CompositeIdTable
|
||||
import org.jetbrains.exposed.v1.core.dao.id.EntityID
|
||||
import org.jetbrains.exposed.v1.core.eq
|
||||
import org.jetbrains.exposed.v1.dao.CompositeEntity
|
||||
import org.jetbrains.exposed.v1.dao.CompositeEntityClass
|
||||
import org.jetbrains.exposed.v1.jdbc.insert
|
||||
|
||||
object PersonalKitTable: CompositeIdTable("PersonalKit") {
|
||||
val userId = reference("UserId", SteamwarUserTable)
|
||||
val gamemode = varchar("Gamemode", 64).entityId()
|
||||
val kitName = varchar("Name", 64).entityId()
|
||||
val inventory = text("Inventory")
|
||||
val armor = text("Armor")
|
||||
val inUse = bool("InUse")
|
||||
|
||||
override val primaryKey = PrimaryKey(userId, gamemode, kitName)
|
||||
|
||||
init {
|
||||
addIdColumn(userId)
|
||||
}
|
||||
}
|
||||
|
||||
class InternalKit(id: EntityID<CompositeID>): CompositeEntity(id) {
|
||||
companion object: CompositeEntityClass<InternalKit>(PersonalKitTable) {
|
||||
@JvmStatic
|
||||
fun get(userId: Int, gamemode: String) = useDb {
|
||||
find { PersonalKitTable.userId eq userId and (PersonalKitTable.gamemode eq gamemode) and (PersonalKitTable.inUse eq true) }
|
||||
.toList()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun get(userId: Int, gamemode: String, kitName: String) = useDb {
|
||||
find { PersonalKitTable.userId eq userId and (PersonalKitTable.gamemode eq gamemode) and (PersonalKitTable.kitName eq kitName) and (PersonalKitTable.inUse eq true) }
|
||||
.firstOrNull()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun create(userId: Int, gamemode: String, kitName: String, rawInventory: String, rawArmor: String) = useDb {
|
||||
new(
|
||||
CompositeID {
|
||||
it[PersonalKitTable.userId] = EntityID(userId, SteamwarUserTable)
|
||||
it[PersonalKitTable.gamemode] = gamemode
|
||||
it[PersonalKitTable.kitName] = kitName
|
||||
}
|
||||
) {
|
||||
this.inventory = rawInventory
|
||||
this.armor = rawArmor
|
||||
this.inUse = true
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getKitInUse(userId: Int, gamemode: String) = useDb {
|
||||
find { PersonalKitTable.userId eq userId and (PersonalKitTable.gamemode eq gamemode) and (PersonalKitTable.inUse eq true) }
|
||||
.firstOrNull()
|
||||
}
|
||||
}
|
||||
|
||||
var userID by PersonalKitTable.userId.transform({ EntityID(it, SteamwarUserTable) }, { it.value })
|
||||
private set
|
||||
private var gameMode by PersonalKitTable.gamemode
|
||||
val gamemode: String
|
||||
get() = gameMode.value
|
||||
|
||||
var kitName by PersonalKitTable.kitName
|
||||
private set
|
||||
val name: String
|
||||
get() = kitName.value
|
||||
|
||||
var rawInventory by PersonalKitTable.inventory
|
||||
private set
|
||||
var rawArmor by PersonalKitTable.armor
|
||||
private set
|
||||
var inUse by PersonalKitTable.inUse
|
||||
private set
|
||||
|
||||
var inventory: String
|
||||
get() = rawInventory
|
||||
set(value) = useDb { rawInventory = value }
|
||||
var armor: String
|
||||
get() = rawArmor
|
||||
set(value) = useDb { rawArmor = value }
|
||||
|
||||
fun setDefault() = useDb {
|
||||
find { PersonalKitTable.userId eq userID and (PersonalKitTable.gamemode eq gameMode) and (PersonalKitTable.inUse eq true) }
|
||||
.forEach { it.inUse = false }
|
||||
inUse = true
|
||||
}
|
||||
|
||||
override fun delete() = useDb {
|
||||
super.delete()
|
||||
}
|
||||
}
|
||||
@@ -1,77 +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.sql;
|
||||
|
||||
import de.steamwar.sql.internal.Field;
|
||||
import de.steamwar.sql.internal.SelectStatement;
|
||||
import de.steamwar.sql.internal.Statement;
|
||||
import de.steamwar.sql.internal.Table;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class PollAnswer {
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private static String currentPoll;
|
||||
|
||||
private static final Table<PollAnswer> table = new Table<>(PollAnswer.class);
|
||||
|
||||
private static final SelectStatement<PollAnswer> get = table.select(Table.PRIMARY);
|
||||
private static final Statement getResults = new Statement("SELECT Count(UserID) AS Times, Answer FROM PollAnswer WHERE Question = ? GROUP BY Answer ORDER BY Times ASC");
|
||||
private static final Statement insert = table.insertAll();
|
||||
|
||||
@Field(keys = {Table.PRIMARY})
|
||||
private final int userID;
|
||||
@Field(keys = {Table.PRIMARY})
|
||||
private final String question;
|
||||
@Field(def = "0")
|
||||
private int answer;
|
||||
|
||||
public static PollAnswer get(int userID) {
|
||||
PollAnswer answer = get.select(userID, currentPoll);
|
||||
if(answer == null)
|
||||
return new PollAnswer(userID, currentPoll, 0);
|
||||
return answer;
|
||||
}
|
||||
|
||||
public static Map<Integer, Integer> getCurrentResults() {
|
||||
return getResults.select(rs -> {
|
||||
Map<Integer, Integer> retMap = new HashMap<>();
|
||||
while (rs.next())
|
||||
retMap.put(rs.getInt("Answer")-1, rs.getInt("Times"));
|
||||
return retMap;
|
||||
}, currentPoll);
|
||||
}
|
||||
|
||||
public boolean hasAnswered(){
|
||||
return answer != 0;
|
||||
}
|
||||
|
||||
public void setAnswer(int answer){
|
||||
this.answer = answer;
|
||||
insert.update(userID, question, answer);
|
||||
}
|
||||
}
|
||||
78
CommonCore/SQL/src/de/steamwar/sql/PollAnswer.kt
Normal file
78
CommonCore/SQL/src/de/steamwar/sql/PollAnswer.kt
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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.sql
|
||||
|
||||
import de.steamwar.sql.internal.useDb
|
||||
import org.jetbrains.exposed.v1.core.VarCharColumnType
|
||||
import org.jetbrains.exposed.v1.core.and
|
||||
import org.jetbrains.exposed.v1.core.dao.id.CompositeID
|
||||
import org.jetbrains.exposed.v1.core.dao.id.CompositeIdTable
|
||||
import org.jetbrains.exposed.v1.core.dao.id.EntityID
|
||||
import org.jetbrains.exposed.v1.core.eq
|
||||
import org.jetbrains.exposed.v1.dao.CompositeEntity
|
||||
import org.jetbrains.exposed.v1.dao.CompositeEntityClass
|
||||
|
||||
object PollAnswerTable: CompositeIdTable("PollAnswer") {
|
||||
val userId = reference("UserID", SteamwarUserTable)
|
||||
val question = varchar("Question", 150)
|
||||
val answer = integer("Answer")
|
||||
}
|
||||
|
||||
class PollAnswer(id: EntityID<CompositeID>): CompositeEntity(id) {
|
||||
var userId by PollAnswerTable.userId
|
||||
private set
|
||||
var question by PollAnswerTable.question
|
||||
private set
|
||||
private var answerId by PollAnswerTable.answer
|
||||
var answer: Int
|
||||
get() = answerId
|
||||
set(value) = useDb {
|
||||
answerId = value
|
||||
}
|
||||
|
||||
companion object: CompositeEntityClass<PollAnswer>(PollAnswerTable) {
|
||||
@JvmStatic
|
||||
var currentPoll: String? = null
|
||||
|
||||
@JvmStatic
|
||||
fun get(userId: Int) = useDb {
|
||||
find { (PollAnswerTable.userId eq userId) and (PollAnswerTable.question eq currentPoll!!) }.firstOrNull()
|
||||
?: new {
|
||||
this.userId = EntityID(userId, SteamwarUserTable)
|
||||
this.question = currentPoll!!
|
||||
this.answerId = 0
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getCurrentResults(): Map<Int, Int> = useDb {
|
||||
exec("SELECT Count(UserID) AS Times, Answer FROM PollAnswer WHERE Question = ? GROUP BY Answer ORDER BY Times ASC",
|
||||
args = listOf(VarCharColumnType() to currentPoll!!)) {
|
||||
val result = mutableMapOf<Int, Int>()
|
||||
while (it.next()) {
|
||||
result[it.getInt("Answer")] = it.getInt("Times")
|
||||
}
|
||||
result
|
||||
} ?: emptyMap()
|
||||
}
|
||||
}
|
||||
|
||||
fun hasAnswered() = answerId != 0
|
||||
}
|
||||
@@ -1,140 +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.sql;
|
||||
|
||||
import de.steamwar.sql.internal.*;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.time.Instant;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class Punishment {
|
||||
|
||||
static {
|
||||
SqlTypeMapper.nameEnumMapper(PunishmentType.class);
|
||||
}
|
||||
|
||||
public static final Timestamp PERMA_TIME = Timestamp.from(Instant.ofEpochSecond(946674800));
|
||||
|
||||
private static final Table<Punishment> table = new Table<>(Punishment.class, "Punishments");
|
||||
private static final SelectStatement<Punishment> getPunishments = new SelectStatement<>(table, "SELECT * FROM Punishments WHERE PunishmentId IN (SELECT MAX(PunishmentId) FROM Punishments WHERE UserId = ? GROUP BY Type)");
|
||||
private static final SelectStatement<Punishment> getPunishment = new SelectStatement<>(table, "SELECT * FROM Punishments WHERE UserId = ? AND Type = ? ORDER BY PunishmentId DESC LIMIT 1");
|
||||
private static final SelectStatement<Punishment> getAllPunishments = new SelectStatement<>(table, "SELECT * FROM Punishments WHERE UserId = ? ORDER BY `PunishmentId` DESC");
|
||||
private static final Statement insert = table.insertFields(true, "UserId", "Punisher", "Type", "EndTime", "Perma", "Reason");
|
||||
|
||||
public static Punishment getPunishmentOfPlayer(int user, PunishmentType type) {
|
||||
return getPunishment.select(user, type);
|
||||
}
|
||||
|
||||
public static Map<PunishmentType, Punishment> getPunishmentsOfPlayer(int user) {
|
||||
return getPunishments.listSelect(user).stream().collect(Collectors.toMap(Punishment::getType, punishment -> punishment));
|
||||
}
|
||||
|
||||
public static List<Punishment> getAllPunishmentsOfPlayer(int user) {
|
||||
return getAllPunishments.listSelect(user);
|
||||
}
|
||||
|
||||
public static boolean isPunished(SteamwarUser user, PunishmentType type, Consumer<Punishment> callback) {
|
||||
Punishment punishment = Punishment.getPunishmentOfPlayer(user.getId(), type);
|
||||
if(punishment == null || !punishment.isCurrent()) {
|
||||
return false;
|
||||
} else {
|
||||
callback.accept(punishment);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static Punishment createPunishment(int user, int executor, PunishmentType type, String reason, Timestamp endTime, boolean perma) {
|
||||
if(perma && !endTime.equals(PERMA_TIME)) {
|
||||
throw new IllegalArgumentException("Permanent punishments must have an end time of `Punishment.PERMA_TIME`");
|
||||
}
|
||||
int punishmentId = insert.insertGetKey(user, executor, type.name(), endTime, perma, reason);
|
||||
return new Punishment(punishmentId, user, executor, type, Timestamp.from(Instant.now()), endTime, perma, reason);
|
||||
}
|
||||
|
||||
@Field(keys = {Table.PRIMARY}, autoincrement = true)
|
||||
private final int punishmentId;
|
||||
@Field
|
||||
@Getter
|
||||
private final int userId;
|
||||
@Field
|
||||
@Getter
|
||||
private final int punisher;
|
||||
@Field
|
||||
@Getter
|
||||
private final PunishmentType type;
|
||||
@Field
|
||||
@Getter
|
||||
private final Timestamp startTime;
|
||||
@Field
|
||||
@Getter
|
||||
private final Timestamp endTime;
|
||||
@Field
|
||||
@Getter
|
||||
private final boolean perma;
|
||||
@Field
|
||||
@Getter
|
||||
private final String reason;
|
||||
|
||||
@Deprecated // Not multiling, misleading title
|
||||
public String getBantime(Timestamp endTime, boolean perma) {
|
||||
if (perma) {
|
||||
return "permanent";
|
||||
} else {
|
||||
return endTime.toLocalDateTime().format(DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm"));
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isCurrent() {
|
||||
return isPerma() || getEndTime().after(new Date());
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
@RequiredArgsConstructor
|
||||
@Getter
|
||||
public enum PunishmentType {
|
||||
Ban(UserPerm.TEAM, "BAN_TEAM", "BAN_PERMA", "BAN_UNTIL", "UNBAN_ERROR", "UNBAN"),
|
||||
Mute( UserPerm.TEAM, "MUTE_TEAM", "MUTE_PERMA", "MUTE_UNTIL", "UNMUTE_ERROR", "UNMUTE"),
|
||||
NoSchemReceiving(UserPerm.MODERATION, "NOSCHEMRECEIVING_TEAM", "NOSCHEMRECEIVING_PERMA", "NOSCHEMRECEIVING_UNTIL", "UNNOSCHEMRECEIVING_ERROR", "UNNOSCHEMRECEIVING"),
|
||||
NoSchemSharing(UserPerm.MODERATION, "NOSCHEMSHARING_TEAM", "NOSCHEMSHARING_PERMA", "NOSCHEMSHARING_UNTIL", "UNNOSCHEMSHARING_ERROR", "UNNOSCHEMSHARING"),
|
||||
NoSchemSubmitting(UserPerm.TEAM, "NOSCHEMSUBMITTING_TEAM", "NOSCHEMSUBMITTING_PERMA", "NOSCHEMSUBMITTING_UNTIL", "UNNOSCHEMSUBMITTING_ERROR", "UNNOSCHEMSUBMITTING"),
|
||||
NoDevServer(UserPerm.PREFIX_DEVELOPER, "NODEVSERVER_TEAM", "NODEVSERVER_PERMA", "NODEVSERVER_UNTIL", "UNNODEVSERVER_ERROR", "UNNODEVSERVER"),
|
||||
NoFightServer(UserPerm.MODERATION, "NOFIGHTSERVER_TEAM", "NOFIGHTSERVER_PERMA", "NOFIGHTSERVER_UNTIL", "UNNOFIGHTSERVER_ERROR", "UNNOFIGHTSERVER"),
|
||||
NoTeamServer(UserPerm.MODERATION, "NOTEAMSERVER_TEAM", "NOTEAMSERVER_PERMA", "NOTEAMSERVER_UNTIL", "UNNOTEAMSERVER_ERROR", "UNNOTEAMSERVER"),
|
||||
Note(UserPerm.TEAM, "NOTE_TEAM", null, null, null, null, true);
|
||||
|
||||
private final UserPerm userPerm;
|
||||
private final String teamMessage;
|
||||
private final String playerMessagePerma;
|
||||
private final String playerMessageUntil;
|
||||
private final String usageNotPunished;
|
||||
private final String unpunishmentMessage;
|
||||
private boolean multi = false;
|
||||
}
|
||||
}
|
||||
186
CommonCore/SQL/src/de/steamwar/sql/Punishment.kt
Normal file
186
CommonCore/SQL/src/de/steamwar/sql/Punishment.kt
Normal file
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* 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.sql
|
||||
|
||||
import de.steamwar.sql.internal.useDb
|
||||
import org.jetbrains.exposed.v1.core.*
|
||||
import org.jetbrains.exposed.v1.core.dao.id.EntityID
|
||||
import org.jetbrains.exposed.v1.core.dao.id.IntIdTable
|
||||
import org.jetbrains.exposed.v1.dao.IntEntity
|
||||
import org.jetbrains.exposed.v1.dao.IntEntityClass
|
||||
import org.jetbrains.exposed.v1.javatime.timestamp
|
||||
import org.jetbrains.exposed.v1.jdbc.select
|
||||
import java.sql.Timestamp
|
||||
import java.time.Instant
|
||||
import java.util.*
|
||||
import java.util.function.Consumer
|
||||
|
||||
object PunishmentTable : IntIdTable("Punishments", "PunishmentId") {
|
||||
val userId = reference("UserId", SteamwarUserTable)
|
||||
val punisher = reference("Punisher", SteamwarUserTable)
|
||||
val type = enumerationByName("Type", 32, Punishment.PunishmentType::class)
|
||||
val startTime = timestamp("StartTime")
|
||||
val endTime = timestamp("EndTime")
|
||||
val perma = bool("Perma")
|
||||
val reason = text("Reason")
|
||||
}
|
||||
|
||||
class Punishment(id: EntityID<Int>) : IntEntity(id) {
|
||||
companion object : IntEntityClass<Punishment>(PunishmentTable) {
|
||||
@JvmField
|
||||
val PERMA_TIME: Timestamp = Timestamp.from(Instant.ofEpochSecond(946674800))
|
||||
|
||||
@JvmStatic
|
||||
fun getPunsihmentOfPlayer(user: Int, type: PunishmentType) = useDb {
|
||||
find { (PunishmentTable.userId eq user) and (PunishmentTable.type eq type) }.orderBy(PunishmentTable.id to SortOrder.DESC)
|
||||
.firstOrNull()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getPunishmentsOfPlayer(user: Int) = useDb {
|
||||
find {
|
||||
PunishmentTable.id inSubQuery PunishmentTable.select(PunishmentTable.id.max())
|
||||
.where { PunishmentTable.userId eq user }.groupBy(
|
||||
PunishmentTable.type
|
||||
)
|
||||
}.associateBy { it.type }.toMutableMap()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getAllPunishmentsOfPlayer(user: Int) = useDb {
|
||||
find { PunishmentTable.userId eq user }.orderBy(PunishmentTable.id to SortOrder.DESC).toList()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun isPunished(user: SteamwarUser, type: PunishmentType, callback: Consumer<Punishment>): Boolean = useDb {
|
||||
val punishment = getPunsihmentOfPlayer(user.id.value, type) ?: return@useDb false
|
||||
|
||||
if (punishment.isCurrent()) {
|
||||
callback.accept(punishment)
|
||||
return@useDb true
|
||||
}
|
||||
|
||||
return@useDb false
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun createPunishment(
|
||||
user: Int,
|
||||
executor: Int,
|
||||
type: PunishmentType,
|
||||
reason: String,
|
||||
endTime: Timestamp,
|
||||
perma: Boolean
|
||||
) = useDb {
|
||||
new {
|
||||
this.userId = user
|
||||
this.punisher = executor
|
||||
this.type = type
|
||||
this.startTime = Timestamp.from(Instant.now())
|
||||
this.endTime = endTime
|
||||
this.perma = perma
|
||||
this.reason = reason
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var userId by PunishmentTable.userId.transform({ EntityID(it, SteamwarUserTable) }, { it.value })
|
||||
private set
|
||||
var punisher by PunishmentTable.punisher.transform({ EntityID(it, SteamwarUserTable) }, { it.value })
|
||||
private set
|
||||
var type by PunishmentTable.type
|
||||
private set
|
||||
var startTime by PunishmentTable.startTime.transform({ it.toInstant() }, { Timestamp.from(it) })
|
||||
private set
|
||||
var endTime by PunishmentTable.endTime.transform({ it.toInstant() }, { Timestamp.from(it) })
|
||||
private set
|
||||
var perma by PunishmentTable.perma
|
||||
private set
|
||||
var reason by PunishmentTable.reason
|
||||
private set
|
||||
|
||||
fun isPerma() = perma
|
||||
|
||||
fun isCurrent() = perma || endTime.after(Date())
|
||||
|
||||
enum class PunishmentType(
|
||||
val teamMessage: String?,
|
||||
val playerMessagePerma: String?,
|
||||
val playerMessageUntil: String?,
|
||||
val usageNotPunished: String?,
|
||||
val unpunishmentMessage: String?,
|
||||
val userPerm: UserPerm,
|
||||
val multi: Boolean = false
|
||||
) {
|
||||
Ban("BAN_TEAM", "BAN_PERMA", "BAN_UNTIL", "UNBAN_ERROR", "UNBAN", UserPerm.TEAM),
|
||||
Mute("MUTE_TEAM", "MUTE_PERMA", "MUTE_UNTIL", "UNMUTE_ERROR", "UNMUTE", UserPerm.TEAM),
|
||||
NoSchemReceiving(
|
||||
"NOSCHEMRECEIVING_TEAM",
|
||||
"NOSCHEMRECEIVING_PERMA",
|
||||
"NOSCHEMRECEIVING_UNTIL",
|
||||
"UNNOSCHEMRECEIVING_ERROR",
|
||||
"UNNOSCHEMRECEIVING",
|
||||
UserPerm.MODERATION
|
||||
),
|
||||
NoSchemSharing(
|
||||
"NOSCHEMSHARING_TEAM",
|
||||
"NOSCHEMSHARING_PERMA",
|
||||
"NOSCHEMSHARING_UNTIL",
|
||||
"UNNOSCHEMSHARING_ERROR",
|
||||
"UNNOSCHEMSHARING",
|
||||
UserPerm.MODERATION
|
||||
),
|
||||
NoSchemSubmitting(
|
||||
"NOSCHEMSUBMITTING_TEAM",
|
||||
"NOSCHEMSUBMITTING_PERMA",
|
||||
"NOSCHEMSUBMITTING_UNTIL",
|
||||
"UNNOSCHEMSUBMITTING_ERROR",
|
||||
"UNNOSCHEMSUBMITTING",
|
||||
UserPerm.TEAM
|
||||
),
|
||||
NoDevServer(
|
||||
"NODEVSERVER_TEAM",
|
||||
"NODEVSERVER_PERMA",
|
||||
"NODEVSERVER_UNTIL",
|
||||
"UNNODEVSERVER_ERROR",
|
||||
"UNNODEVSERVER",
|
||||
UserPerm.PREFIX_DEVELOPER
|
||||
),
|
||||
NoFightServer(
|
||||
"NOFIGHTSERVER_TEAM",
|
||||
"NOFIGHTSERVER_PERMA",
|
||||
"NOFIGHTSERVER_UNTIL",
|
||||
"UNNOFIGHTSERVER_ERROR",
|
||||
"UNNOFIGHTSERVER",
|
||||
UserPerm.MODERATION
|
||||
),
|
||||
NoTeamServer(
|
||||
"NOTEAMSERVER_TEAM",
|
||||
"NOTEAMSERVER_PERMA",
|
||||
"NOTEAMSERVER_UNTIL",
|
||||
"UNNOTEAMSERVER_ERROR",
|
||||
"UNNOTEAMSERVER",
|
||||
UserPerm.MODERATION
|
||||
),
|
||||
Note("NOTE_TEAM", null, null, null, null, UserPerm.TEAM, true);
|
||||
|
||||
fun isMulti() = multi
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user