Compare commits

...
Author SHA1 Message Date
YoyoNow 026937bc7b Merge branch 'main' into VelocityCore/NoEvent 2025-12-03 14:07:02 +01:00
YoyoNow 8640d43d4b Merge pull request 'BauSystem/ImproveRegionData' (#234) from BauSystem/ImproveRegionData into main
Reviewed-on: SteamWar/SteamWar#234
Reviewed-by: D4rkr34lm <dark@steamwar.de>
2025-12-03 13:26:10 +01:00
YoyoNow fbdb0cfaf1 Merge pull request 'Fix replay in 1.21 -> RPlayer needs fixing before' (#199) from FightSystem/ReplayFix21 into main
Reviewed-on: SteamWar/SteamWar#199
2025-12-03 10:05:03 +01:00
YoyoNow 9305ab5f91 Merge pull request 'Refactor Authlib integration and adjust entity handling for 1.21 compatibility' (#106) from 1.21.1/rplayer-fix into main
Reviewed-on: SteamWar/SteamWar#106
2025-12-03 10:04:50 +01:00
YoyoNow 34ade1de19 Merge branch 'main' into 1.21.1/rplayer-fix 2025-12-03 09:59:33 +01:00
YoyoNow 87d0df8067 Merge pull request 'Remove Poll-System' (#245) from Refactor/remove-poll-system into main
Reviewed-on: SteamWar/SteamWar#245
Reviewed-by: YoyoNow <yoyonow@noreply.localhost>
2025-12-03 09:56:28 +01:00
Chaoscaot 2f8491c3f6 Fix Team Creation
Signed-off-by: Chaoscaot <max@maxsp.de>
2025-12-02 21:35:14 +01:00
Chaoscaot 4df92f7e5f Remove Poll-System
Signed-off-by: Chaoscaot <max@maxsp.de>
2025-12-02 20:43:37 +01:00
Chaoscaot 9a78b99a75 Remove Poll-System
Signed-off-by: Chaoscaot <max@maxsp.de>
2025-12-02 16:39:16 +01:00
Chaoscaot 1de1bf6571 Fix Leaderboard ID handling
Signed-off-by: Chaoscaot <max@maxsp.de>
2025-12-02 00:47:54 +01:00
YoyoNow 771c77247a Add Punishment.PunishmentType.NoEvent 2025-12-01 15:52:15 +01:00
Chaoscaot dfb71594b9 Fix Leaderboard
Signed-off-by: Chaoscaot <max@maxsp.de>
2025-12-01 14:49:23 +01:00
Chaoscaot f535e056c7 Merge remote-tracking branch 'origin/main'
# Conflicts:
#	LobbySystem/src/de/steamwar/lobby/special/advent/Present.java
2025-12-01 12:23:34 +01:00
Chaoscaot e67e340707 Fix Advent Calendar Present parent ID handling
Signed-off-by: Chaoscaot <max@maxsp.de>
2025-12-01 12:23:04 +01:00
YoyoNow a594a163f7 Fix NodeMember for Present since the setter for parent apparently does not work 2025-12-01 09:14:09 +01:00
YoyoNow 1c0146a02d Fix SchematicNode.parentNode get 2025-12-01 09:01:00 +01:00
Chaoscaot d3fecf763c Fix Lobby
Signed-off-by: Chaoscaot <max@maxsp.de>
2025-12-01 00:21:12 +01:00
Chaoscaot 3944c011b0 Fix Lobby
Signed-off-by: Chaoscaot <max@maxsp.de>
2025-11-30 21:22:21 +01:00
Chaoscaot 1f4a77e8b4 Fix Lobby
Signed-off-by: Chaoscaot <max@maxsp.de>
2025-11-30 20:59:03 +01:00
Chaoscaot 4d40e52ea6 Merge pull request 'Refactor leaderboard management' (#166) from Lobby/refactor-leaderboard into main
Reviewed-on: SteamWar/SteamWar#166
2025-11-30 20:56:10 +01:00
YoyoNow 698e411944 Fix SQLWrapperImpl.getMaterialWithGreaterBlastResistance for 1.12 or lower 2025-11-30 20:18:58 +01:00
Chaoscaot 0fd7aab86c Fix FightStatistics
Signed-off-by: Chaoscaot <max@maxsp.de>
2025-11-30 17:27:27 +01:00
YoyoNow 624fe98c47 Add some Clear tasks 2025-11-30 16:12:52 +01:00
Chaoscaot ede7df82f3 Fix FightStatistics
Signed-off-by: Chaoscaot <max@maxsp.de>
2025-11-30 16:09:40 +01:00
YoyoNow eafb469eca Remove FlagStorage and merge into RegionData 2025-11-28 12:04:36 +01:00
YoyoNow 14bd38f471 Improve FlagStorage 2025-11-28 11:59:14 +01:00
YoyoNow febf2c283d Fix REntity.bowDrawnWatcher 2025-11-28 09:56:18 +01:00
YoyoNow 5f53ebf5b3 Fix REntity.getEquipmentPacket
Fix FightSchematic.pasteTeamName
2025-11-28 09:27:04 +01:00
Chaoscaot d0c1413ea6 Refactor Leaderboard to Kotlin, leveraging Exposed library for database operations, and update LeaderboardManager for compatibility.
Signed-off-by: Chaoscaot <max@maxsp.de>
2025-11-11 17:39:39 +01:00
Chaoscaot 5f7c5f0a18 Merge remote-tracking branch 'origin/Lobby/refactor-leaderboard' into Lobby/refactor-leaderboard
# Conflicts:
#	LobbySystem/src/de/steamwar/lobby/util/LeaderboardManager.java
2025-11-11 17:28:03 +01:00
Chaoscaot 9e9f405e30 Refactor leaderboard management: replace UserConfig-based implementation with new Leaderboard SQL class, update related classes to use LeaderboardManager, and fix query/logic for best time retrieval. 2025-11-11 17:27:24 +01:00
YoyoNow fd4d15ac5a Fix replay in 1.21 -> RPlayer needs fixing before 2025-11-11 17:13:35 +01:00
Chaoscaot fa4d006dd3 Refactor Authlib integration and adjust entity handling for 1.21 compatibility 2025-11-08 20:09:02 +01:00
Chaoscaot eb63381b83 Refactor leaderboard management: replace UserConfig-based implementation with new Leaderboard SQL class, update related classes to use LeaderboardManager, and fix query/logic for best time retrieval. 2025-10-20 16:39:35 +02:00
90 changed files with 920 additions and 1017 deletions
@@ -59,7 +59,7 @@ public class BackupCommand extends SWCommand {
if (checkGlobalRegion(region, p)) { if (checkGlobalRegion(region, p)) {
return; return;
} }
if (region.getFlags().get(Flag.CHANGED).isWithDefault(ChangedMode.NO_CHANGE)) { if (region.getRegionData().get(Flag.CHANGED).isWithDefault(ChangedMode.NO_CHANGE)) {
BauSystem.MESSAGE.send("BACKUP_CREATE_NO_CHANGE", p); BauSystem.MESSAGE.send("BACKUP_CREATE_NO_CHANGE", p);
return; return;
} }
@@ -56,8 +56,8 @@ public class BauInfoBauGuiItem extends BauGuiItem {
Region region = Region.getRegion(player.getLocation()); Region region = Region.getRegion(player.getLocation());
List<String> stringList = new ArrayList<>(); List<String> stringList = new ArrayList<>();
for (Flag flag : Flag.getFlags()) { for (Flag flag : Flag.getFlags()) {
if (!region.getFlags().has(flag).isApplicable()) continue; if (!region.getRegionData().has(flag).isApplicable()) continue;
FlagOptional<?> value = region.getFlags().get(flag); FlagOptional<?> value = region.getRegionData().get(flag);
if (value.isPresent()) { if (value.isPresent()) {
stringList.add(BauSystem.MESSAGE.parse("BAU_INFO_ITEM_LORE_" + flag.name(), player, BauSystem.MESSAGE.parse(value.getWithDefault().getChatValue(), player))); stringList.add(BauSystem.MESSAGE.parse("BAU_INFO_ITEM_LORE_" + flag.name(), player, BauSystem.MESSAGE.parse(value.getWithDefault().getChatValue(), player)));
} }
@@ -50,8 +50,8 @@ public class InfoCommand extends SWCommand {
BauSystem.MESSAGE.send("BAU_INFO_COMMAND_OWNER", p, SteamwarUser.byId(bauServer.getOwnerID()).getUserName()); BauSystem.MESSAGE.send("BAU_INFO_COMMAND_OWNER", p, SteamwarUser.byId(bauServer.getOwnerID()).getUserName());
Region region = Region.getRegion(p.getLocation()); Region region = Region.getRegion(p.getLocation());
for (Flag flag : Flag.getFlags()) { for (Flag flag : Flag.getFlags()) {
if (!region.getFlags().has(flag).isApplicable()) continue; if (!region.getRegionData().has(flag).isApplicable()) continue;
FlagOptional<?> value = region.getFlags().get(flag); FlagOptional<?> value = region.getRegionData().get(flag);
if (value.isPresent()) { if (value.isPresent()) {
BauSystem.MESSAGE.send("BAU_INFO_COMMAND_FLAG", p, BauSystem.MESSAGE.parse(flag.getChatValue(), p), BauSystem.MESSAGE.parse(value.getWithDefault().getChatValue(), p)); BauSystem.MESSAGE.send("BAU_INFO_COMMAND_FLAG", p, BauSystem.MESSAGE.parse(flag.getChatValue(), p), BauSystem.MESSAGE.parse(value.getWithDefault().getChatValue(), p));
} }
@@ -51,17 +51,17 @@ public class ColorCommand extends SWCommand {
public void genericColorSet(@Validator Player p, ColorMode color, ColorizationType colorizationType) { public void genericColorSet(@Validator Player p, ColorMode color, ColorizationType colorizationType) {
if (colorizationType == ColorizationType.GLOBAL) { if (colorizationType == ColorizationType.GLOBAL) {
Region.getRegions().forEach(region -> { Region.getRegions().forEach(region -> {
region.getFlags().set(Flag.COLOR, color); region.getRegionData().set(Flag.COLOR, color);
}); });
BauSystem.MESSAGE.send("REGION_COLOR_GLOBAL", p, BauSystem.MESSAGE.parse(color.getChatValue(), p)); BauSystem.MESSAGE.send("REGION_COLOR_GLOBAL", p, BauSystem.MESSAGE.parse(color.getChatValue(), p));
return; return;
} }
Region region = Region.getRegion(p.getLocation()); Region region = Region.getRegion(p.getLocation());
if (!region.getFlags().has(Flag.COLOR).isWritable()) { if (!region.getRegionData().has(Flag.COLOR).isWritable()) {
BauSystem.MESSAGE.send("REGION_COLOR_NO_REGION", p); BauSystem.MESSAGE.send("REGION_COLOR_NO_REGION", p);
return; return;
} }
region.getFlags().set(Flag.COLOR, color); region.getRegionData().set(Flag.COLOR, color);
try { try {
PasteBuilder pasteBuilder = new PasteBuilder(new PasteBuilder.FileProvider(region.getArea().getResetFile())) PasteBuilder pasteBuilder = new PasteBuilder(new PasteBuilder.FileProvider(region.getArea().getResetFile()))
.ignoreAir(true) .ignoreAir(true)
@@ -53,11 +53,11 @@ public class FireCommand extends SWCommand {
} }
private boolean toggle(Region region) { private boolean toggle(Region region) {
if (region.getFlags().get(Flag.FIRE).isWithDefault(FireMode.ALLOW)) { if (region.getRegionData().get(Flag.FIRE).isWithDefault(FireMode.ALLOW)) {
region.getFlags().set(Flag.FIRE, FireMode.DENY); region.getRegionData().set(Flag.FIRE, FireMode.DENY);
return true; return true;
} else { } else {
region.getFlags().set(Flag.FIRE, FireMode.ALLOW); region.getRegionData().set(Flag.FIRE, FireMode.ALLOW);
return false; return false;
} }
} }
@@ -36,12 +36,12 @@ public class FireListener implements Listener, ScoreboardElement {
@EventHandler @EventHandler
public void onFireDamage(BlockBurnEvent e) { public void onFireDamage(BlockBurnEvent e) {
if (Region.getRegion(e.getBlock().getLocation()).getFlags().get(Flag.FIRE).isWithDefault(FireMode.DENY)) e.setCancelled(true); if (Region.getRegion(e.getBlock().getLocation()).getRegionData().get(Flag.FIRE).isWithDefault(FireMode.DENY)) e.setCancelled(true);
} }
@EventHandler @EventHandler
public void onFireSpread(BlockSpreadEvent e) { public void onFireSpread(BlockSpreadEvent e) {
if (Region.getRegion(e.getBlock().getLocation()).getFlags().get(Flag.FIRE).isWithDefault(FireMode.DENY)) e.setCancelled(true); if (Region.getRegion(e.getBlock().getLocation()).getRegionData().get(Flag.FIRE).isWithDefault(FireMode.DENY)) e.setCancelled(true);
} }
@Override @Override
@@ -56,7 +56,7 @@ public class FireListener implements Listener, ScoreboardElement {
@Override @Override
public String get(Region region, Player p) { public String get(Region region, Player p) {
if (region.getFlags().get(Flag.FIRE).isWithDefault(FireMode.DENY)) return null; if (region.getRegionData().get(Flag.FIRE).isWithDefault(FireMode.DENY)) return null;
return "§e" + BauSystem.MESSAGE.parse(Flag.FIRE.getChatValue(), p) + "§8: " + BauSystem.MESSAGE.parse(region.getFlags().get(Flag.FIRE).getWithDefault().getChatValue(), p); return "§e" + BauSystem.MESSAGE.parse(Flag.FIRE.getChatValue(), p) + "§8: " + BauSystem.MESSAGE.parse(region.getRegionData().get(Flag.FIRE).getWithDefault().getChatValue(), p);
} }
} }
@@ -53,11 +53,11 @@ public class FreezeCommand extends SWCommand {
} }
private boolean toggle(Region region) { private boolean toggle(Region region) {
if (region.getFlags().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) { if (region.getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) {
region.getFlags().set(Flag.FREEZE, FreezeMode.INACTIVE); region.getRegionData().set(Flag.FREEZE, FreezeMode.INACTIVE);
return false; return false;
} else { } else {
region.getFlags().set(Flag.FREEZE, FreezeMode.ACTIVE); region.getRegionData().set(Flag.FREEZE, FreezeMode.ACTIVE);
return true; return true;
} }
} }
@@ -48,7 +48,7 @@ public class FreezeListener implements Listener, ScoreboardElement {
@EventHandler @EventHandler
public void onEntitySpawn(EntitySpawnEvent e) { public void onEntitySpawn(EntitySpawnEvent e) {
if (Region.getRegion(e.getLocation()).getFlags().get(Flag.FREEZE).isWithDefault(FreezeMode.INACTIVE)) return; if (Region.getRegion(e.getLocation()).getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.INACTIVE)) return;
e.setCancelled(true); e.setCancelled(true);
if (e.getEntityType() == TrickyTrialsWrapper.impl.getTntEntityType()) { if (e.getEntityType() == TrickyTrialsWrapper.impl.getTntEntityType()) {
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
@@ -60,7 +60,7 @@ public class FreezeListener implements Listener, ScoreboardElement {
@EventHandler @EventHandler
public void onBlockCanBuild(BlockCanBuildEvent e) { public void onBlockCanBuild(BlockCanBuildEvent e) {
if (!e.isBuildable()) return; if (!e.isBuildable()) return;
if (Region.getRegion(e.getBlock().getLocation()).getFlags().get(Flag.FREEZE).isWithDefault(FreezeMode.INACTIVE)) return; if (Region.getRegion(e.getBlock().getLocation()).getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.INACTIVE)) return;
if (e.getMaterial() == Material.TNT) { if (e.getMaterial() == Material.TNT) {
e.setBuildable(false); e.setBuildable(false);
e.getBlock().setType(Material.TNT, false); e.getBlock().setType(Material.TNT, false);
@@ -69,14 +69,14 @@ public class FreezeListener implements Listener, ScoreboardElement {
@EventHandler @EventHandler
public void onEntityChangeBlock(EntityChangeBlockEvent e) { public void onEntityChangeBlock(EntityChangeBlockEvent e) {
if (Region.getRegion(e.getBlock().getLocation()).getFlags().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) { if (Region.getRegion(e.getBlock().getLocation()).getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) {
e.setCancelled(true); e.setCancelled(true);
} }
} }
@EventHandler @EventHandler
public void onPhysicsEvent(BlockPhysicsEvent e) { public void onPhysicsEvent(BlockPhysicsEvent e) {
if (Region.getRegion(e.getBlock().getLocation()).getFlags().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) { if (Region.getRegion(e.getBlock().getLocation()).getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) {
if (e.getSourceBlock().getType() == Material.NOTE_BLOCK) { if (e.getSourceBlock().getType() == Material.NOTE_BLOCK) {
BlockState state = e.getSourceBlock().getState(); BlockState state = e.getSourceBlock().getState();
NoteBlock noteBlock = (NoteBlock) state.getBlockData(); NoteBlock noteBlock = (NoteBlock) state.getBlockData();
@@ -101,44 +101,44 @@ public class FreezeListener implements Listener, ScoreboardElement {
@EventHandler @EventHandler
public void onPistonExtend(BlockPistonExtendEvent e) { public void onPistonExtend(BlockPistonExtendEvent e) {
if (Region.getRegion(e.getBlock().getLocation()).getFlags().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) { if (Region.getRegion(e.getBlock().getLocation()).getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) {
e.setCancelled(true); e.setCancelled(true);
} }
} }
@EventHandler @EventHandler
public void onPistonRetract(BlockPistonRetractEvent e) { public void onPistonRetract(BlockPistonRetractEvent e) {
if (Region.getRegion(e.getBlock().getLocation()).getFlags().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) { if (Region.getRegion(e.getBlock().getLocation()).getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) {
e.setCancelled(true); e.setCancelled(true);
} }
} }
@EventHandler @EventHandler
public void onBlockGrow(BlockGrowEvent e) { public void onBlockGrow(BlockGrowEvent e) {
if (Region.getRegion(e.getBlock().getLocation()).getFlags().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) { if (Region.getRegion(e.getBlock().getLocation()).getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) {
e.setCancelled(true); e.setCancelled(true);
} }
} }
@EventHandler @EventHandler
public void onRedstoneEvent(BlockRedstoneEvent e) { public void onRedstoneEvent(BlockRedstoneEvent e) {
if (Region.getRegion(e.getBlock().getLocation()).getFlags().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) { if (Region.getRegion(e.getBlock().getLocation()).getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) {
e.setNewCurrent(e.getOldCurrent()); e.setNewCurrent(e.getOldCurrent());
} }
} }
@EventHandler @EventHandler
public void onBlockDispense(BlockDispenseEvent e) { public void onBlockDispense(BlockDispenseEvent e) {
if (Region.getRegion(e.getBlock().getLocation()).getFlags().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) { if (Region.getRegion(e.getBlock().getLocation()).getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) {
e.setCancelled(true); e.setCancelled(true);
} }
} }
@EventHandler @EventHandler
public void onInventoryMoveEvent(InventoryMoveItemEvent e) { public void onInventoryMoveEvent(InventoryMoveItemEvent e) {
if (e.getDestination().getLocation() != null && Region.getRegion(e.getDestination().getLocation()).getFlags().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) { if (e.getDestination().getLocation() != null && Region.getRegion(e.getDestination().getLocation()).getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) {
e.setCancelled(true); e.setCancelled(true);
} else if (e.getSource().getLocation() != null && Region.getRegion(e.getSource().getLocation()).getFlags().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) { } else if (e.getSource().getLocation() != null && Region.getRegion(e.getSource().getLocation()).getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) {
e.setCancelled(true); e.setCancelled(true);
} }
} }
@@ -147,7 +147,7 @@ public class FreezeListener implements Listener, ScoreboardElement {
public void onBlockBreak(BlockBreakEvent e) { public void onBlockBreak(BlockBreakEvent e) {
if (Core.getVersion() < 19) return; if (Core.getVersion() < 19) return;
if (e.getPlayer().getInventory().getItemInMainHand().getType() == Material.DEBUG_STICK) return; if (e.getPlayer().getInventory().getItemInMainHand().getType() == Material.DEBUG_STICK) return;
if (Region.getRegion(e.getBlock().getLocation()).getFlags().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) { if (Region.getRegion(e.getBlock().getLocation()).getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) {
e.setCancelled(true); e.setCancelled(true);
e.getBlock().setType(Material.BARRIER, false); e.getBlock().setType(Material.BARRIER, false);
e.getBlock().setType(Material.AIR, false); e.getBlock().setType(Material.AIR, false);
@@ -170,35 +170,35 @@ public class FreezeListener implements Listener, ScoreboardElement {
@EventHandler @EventHandler
public void onFluidLevelChange(FluidLevelChangeEvent e) { public void onFluidLevelChange(FluidLevelChangeEvent e) {
if (Region.getRegion(e.getBlock().getLocation()).getFlags().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) { if (Region.getRegion(e.getBlock().getLocation()).getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) {
e.setCancelled(true); e.setCancelled(true);
} }
} }
@EventHandler @EventHandler
public void onBlockSpread(BlockSpreadEvent e) { public void onBlockSpread(BlockSpreadEvent e) {
if (Region.getRegion(e.getBlock().getLocation()).getFlags().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) { if (Region.getRegion(e.getBlock().getLocation()).getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) {
e.setCancelled(true); e.setCancelled(true);
} }
} }
@EventHandler @EventHandler
public void onBlockFromTo(BlockFromToEvent e) { public void onBlockFromTo(BlockFromToEvent e) {
if (Region.getRegion(e.getBlock().getLocation()).getFlags().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) { if (Region.getRegion(e.getBlock().getLocation()).getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) {
e.setCancelled(true); e.setCancelled(true);
} }
} }
@EventHandler @EventHandler
public void onSpongeAbsorb(SpongeAbsorbEvent e) { public void onSpongeAbsorb(SpongeAbsorbEvent e) {
if (Region.getRegion(e.getBlock().getLocation()).getFlags().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) { if (Region.getRegion(e.getBlock().getLocation()).getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) {
e.setCancelled(true); e.setCancelled(true);
} }
} }
@EventHandler @EventHandler
public void onBlockForm(BlockFormEvent e) { public void onBlockForm(BlockFormEvent e) {
if (Region.getRegion(e.getBlock().getLocation()).getFlags().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) { if (Region.getRegion(e.getBlock().getLocation()).getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) {
e.setCancelled(true); e.setCancelled(true);
} }
} }
@@ -206,7 +206,7 @@ public class FreezeListener implements Listener, ScoreboardElement {
@EventHandler @EventHandler
public void onPlayerInteract(PlayerInteractEvent e) { public void onPlayerInteract(PlayerInteractEvent e) {
if (e.getAction() != Action.RIGHT_CLICK_BLOCK) return; if (e.getAction() != Action.RIGHT_CLICK_BLOCK) return;
if (Region.getRegion(e.getClickedBlock().getLocation()).getFlags().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) { if (Region.getRegion(e.getClickedBlock().getLocation()).getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) {
Block block = e.getClickedBlock(); Block block = e.getClickedBlock();
if (block.getType() == Material.LEVER) { if (block.getType() == Material.LEVER) {
Switch data = ((Switch) block.getBlockData()); Switch data = ((Switch) block.getBlockData());
@@ -218,7 +218,7 @@ public class FreezeListener implements Listener, ScoreboardElement {
@EventHandler @EventHandler
public void onBlockFade(BlockFadeEvent e) { public void onBlockFade(BlockFadeEvent e) {
if (Region.getRegion(e.getBlock().getLocation()).getFlags().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) { if (Region.getRegion(e.getBlock().getLocation()).getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) {
e.setCancelled(true); e.setCancelled(true);
} }
} }
@@ -235,7 +235,7 @@ public class FreezeListener implements Listener, ScoreboardElement {
@Override @Override
public String get(Region region, Player p) { public String get(Region region, Player p) {
if (region.getFlags().get(Flag.FREEZE).isWithDefault(FreezeMode.INACTIVE)) return null; if (region.getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.INACTIVE)) return null;
return "§e" + BauSystem.MESSAGE.parse(Flag.FREEZE.getChatValue(), p) + "§8: " + BauSystem.MESSAGE.parse(region.getFlags().get(Flag.FREEZE).getWithDefault().getChatValue(), p); return "§e" + BauSystem.MESSAGE.parse(Flag.FREEZE.getChatValue(), p) + "§8: " + BauSystem.MESSAGE.parse(region.getRegionData().get(Flag.FREEZE).getWithDefault().getChatValue(), p);
} }
} }
@@ -55,11 +55,11 @@ public class ItemsCommand extends SWCommand {
} }
private boolean toggle(Region region) { private boolean toggle(Region region) {
if (region.getFlags().get(Flag.ITEMS).isWithDefault(ItemMode.ACTIVE)) { if (region.getRegionData().get(Flag.ITEMS).isWithDefault(ItemMode.ACTIVE)) {
region.getFlags().set(Flag.ITEMS, ItemMode.INACTIVE); region.getRegionData().set(Flag.ITEMS, ItemMode.INACTIVE);
return false; return false;
} else { } else {
region.getFlags().set(Flag.ITEMS, ItemMode.ACTIVE); region.getRegionData().set(Flag.ITEMS, ItemMode.ACTIVE);
return true; return true;
} }
} }
@@ -37,7 +37,7 @@ public class ItemsListener implements Listener, ScoreboardElement {
@EventHandler @EventHandler
public void onItemSpawn(ItemSpawnEvent event) { public void onItemSpawn(ItemSpawnEvent event) {
if (Region.getRegion(event.getLocation()).getFlags().get(Flag.ITEMS).isWithDefault(ItemMode.INACTIVE)) { if (Region.getRegion(event.getLocation()).getRegionData().get(Flag.ITEMS).isWithDefault(ItemMode.INACTIVE)) {
event.setCancelled(true); event.setCancelled(true);
} }
} }
@@ -54,7 +54,7 @@ public class ItemsListener implements Listener, ScoreboardElement {
@Override @Override
public String get(Region region, Player p) { public String get(Region region, Player p) {
if (region.getFlags().get(Flag.ITEMS).isWithDefault(ItemMode.INACTIVE)) return null; if (region.getRegionData().get(Flag.ITEMS).isWithDefault(ItemMode.INACTIVE)) return null;
return "§e" + BauSystem.MESSAGE.parse(Flag.ITEMS.getChatValue(), p) + "§8: " + BauSystem.MESSAGE.parse(region.getFlags().get(Flag.ITEMS).getWithDefault().getChatValue(), p); return "§e" + BauSystem.MESSAGE.parse(Flag.ITEMS.getChatValue(), p) + "§8: " + BauSystem.MESSAGE.parse(region.getRegionData().get(Flag.ITEMS).getWithDefault().getChatValue(), p);
} }
} }
@@ -53,11 +53,11 @@ public class NoGravityCommand extends SWCommand {
} }
private boolean toggle(Region region) { private boolean toggle(Region region) {
if (region.getFlags().get(Flag.NO_GRAVITY).isWithDefault(NoGravityMode.ACTIVE)) { if (region.getRegionData().get(Flag.NO_GRAVITY).isWithDefault(NoGravityMode.ACTIVE)) {
region.getFlags().set(Flag.NO_GRAVITY, NoGravityMode.INACTIVE); region.getRegionData().set(Flag.NO_GRAVITY, NoGravityMode.INACTIVE);
return false; return false;
} else { } else {
region.getFlags().set(Flag.NO_GRAVITY, NoGravityMode.ACTIVE); region.getRegionData().set(Flag.NO_GRAVITY, NoGravityMode.ACTIVE);
return true; return true;
} }
} }
@@ -37,7 +37,7 @@ public class NoGravityListener implements Listener, ScoreboardElement {
@EventHandler @EventHandler
public void onEntitySpawn(EntitySpawnEvent event) { public void onEntitySpawn(EntitySpawnEvent event) {
if (event.getEntityType() == EntityType.PLAYER) return; if (event.getEntityType() == EntityType.PLAYER) return;
if (Region.getRegion(event.getLocation()).getFlags().get(Flag.NO_GRAVITY).isWithDefault(NoGravityMode.ACTIVE)) { if (Region.getRegion(event.getLocation()).getRegionData().get(Flag.NO_GRAVITY).isWithDefault(NoGravityMode.ACTIVE)) {
event.getEntity().setGravity(false); event.getEntity().setGravity(false);
} }
} }
@@ -54,7 +54,7 @@ public class NoGravityListener implements Listener, ScoreboardElement {
@Override @Override
public String get(Region region, Player p) { public String get(Region region, Player p) {
if (region.getFlags().get(Flag.NO_GRAVITY).isWithDefault(NoGravityMode.INACTIVE)) return null; if (region.getRegionData().get(Flag.NO_GRAVITY).isWithDefault(NoGravityMode.INACTIVE)) return null;
return "§e" + BauSystem.MESSAGE.parse(Flag.NO_GRAVITY.getChatValue(), p) + "§8: " + BauSystem.MESSAGE.parse(region.getFlags().get(Flag.NO_GRAVITY).getWithDefault().getChatValue(), p); return "§e" + BauSystem.MESSAGE.parse(Flag.NO_GRAVITY.getChatValue(), p) + "§8: " + BauSystem.MESSAGE.parse(region.getRegionData().get(Flag.NO_GRAVITY).getWithDefault().getChatValue(), p);
} }
} }
@@ -39,18 +39,18 @@ public class ProtectCommand extends SWCommand {
public void genericProtectCommand(@Validator Player p) { public void genericProtectCommand(@Validator Player p) {
Region region = regionCheck(p); Region region = regionCheck(p);
if (region == null) return; if (region == null) return;
if (region.getFlags().get(Flag.PROTECT).isWithDefault(ProtectMode.ACTIVE)) { if (region.getRegionData().get(Flag.PROTECT).isWithDefault(ProtectMode.ACTIVE)) {
region.getFlags().set(Flag.PROTECT, ProtectMode.INACTIVE); region.getRegionData().set(Flag.PROTECT, ProtectMode.INACTIVE);
RegionUtils.actionBar(region, "REGION_PROTECT_DISABLE"); RegionUtils.actionBar(region, "REGION_PROTECT_DISABLE");
} else { } else {
region.getFlags().set(Flag.PROTECT, ProtectMode.ACTIVE); region.getRegionData().set(Flag.PROTECT, ProtectMode.ACTIVE);
RegionUtils.actionBar(region, "REGION_PROTECT_ENABLE"); RegionUtils.actionBar(region, "REGION_PROTECT_ENABLE");
} }
} }
private Region regionCheck(Player player) { private Region regionCheck(Player player) {
Region region = Region.getRegion(player.getLocation()); Region region = Region.getRegion(player.getLocation());
if (!region.getFlags().has(Flag.PROTECT).isApplicable()) { if (!region.getRegionData().has(Flag.PROTECT).isApplicable()) {
BauSystem.MESSAGE.send("REGION_PROTECT_FALSE_REGION", player); BauSystem.MESSAGE.send("REGION_PROTECT_FALSE_REGION", player);
return null; return null;
} }
@@ -41,7 +41,7 @@ public class ProtectListener implements Listener, ScoreboardElement {
private void explode(List<Block> blockList, Location location) { private void explode(List<Block> blockList, Location location) {
Region region = Region.getRegion(location); Region region = Region.getRegion(location);
if (region.getFlags().get(Flag.PROTECT).isWithDefault(ProtectMode.INACTIVE)) return; if (region.getRegionData().get(Flag.PROTECT).isWithDefault(ProtectMode.INACTIVE)) return;
Point p1 = region.getBuildArea().getMinPoint(true); Point p1 = region.getBuildArea().getMinPoint(true);
Point p2 = region.getTestblockArea().getMinPoint(true); Point p2 = region.getTestblockArea().getMinPoint(true);
int floorLevel = Math.min(p1.getY(), p2.getY()); int floorLevel = Math.min(p1.getY(), p2.getY());
@@ -70,7 +70,7 @@ public class ProtectListener implements Listener, ScoreboardElement {
@Override @Override
public String get(Region region, Player p) { public String get(Region region, Player p) {
if (region.getFlags().get(Flag.PROTECT).isWithDefault(ProtectMode.INACTIVE)) return null; if (region.getRegionData().get(Flag.PROTECT).isWithDefault(ProtectMode.INACTIVE)) return null;
return "§e" + BauSystem.MESSAGE.parse(Flag.PROTECT.getChatValue(), p) + "§8: " + BauSystem.MESSAGE.parse(region.getFlags().get(Flag.PROTECT).getWithDefault().getChatValue(), p); return "§e" + BauSystem.MESSAGE.parse(Flag.PROTECT.getChatValue(), p) + "§8: " + BauSystem.MESSAGE.parse(region.getRegionData().get(Flag.PROTECT).getWithDefault().getChatValue(), p);
} }
} }
@@ -102,7 +102,7 @@ public class RegionCommand extends SWCommand {
try { try {
PasteBuilder pasteBuilder = new PasteBuilder(new PasteBuilder.FileProvider(region.getArea().getResetFile())) PasteBuilder pasteBuilder = new PasteBuilder(new PasteBuilder.FileProvider(region.getArea().getResetFile()))
.ignoreAir(true) .ignoreAir(true)
.color(region.getFlags().get(Flag.COLOR).getWithDefault()); .color(region.getRegionData().get(Flag.COLOR).getWithDefault());
region.getArea().reset(pasteBuilder, false); region.getArea().reset(pasteBuilder, false);
RegionUtils.message(region, "REGION_REGION_RESTORED"); RegionUtils.message(region, "REGION_REGION_RESTORED");
} catch (SecurityException e) { } catch (SecurityException e) {
@@ -124,7 +124,7 @@ public class RegionCommand extends SWCommand {
try { try {
PasteBuilder pasteBuilder = new PasteBuilder(new PasteBuilder.SchematicProvider(node)) PasteBuilder pasteBuilder = new PasteBuilder(new PasteBuilder.SchematicProvider(node))
.ignoreAir(true) .ignoreAir(true)
.color(region.getFlags().get(Flag.COLOR).getWithDefault()); .color(region.getRegionData().get(Flag.COLOR).getWithDefault());
region.getArea().reset(pasteBuilder, false); region.getArea().reset(pasteBuilder, false);
RegionUtils.message(region, "REGION_REGION_RESTORED"); RegionUtils.message(region, "REGION_REGION_RESTORED");
} catch (SecurityException e) { } catch (SecurityException e) {
@@ -182,6 +182,6 @@ public class RegionListener implements Listener {
} }
private static void tagChangedRegion(final Location location) { private static void tagChangedRegion(final Location location) {
Region.getRegion(location).getFlags().set(Flag.CHANGED, ChangedMode.HAS_CHANGE); Region.getRegion(location).getRegionData().set(Flag.CHANGED, ChangedMode.HAS_CHANGE);
} }
} }
@@ -53,9 +53,8 @@ public class ResetCommand extends SWCommand {
if (region == null) return; if (region == null) return;
try { try {
PasteBuilder pasteBuilder = new PasteBuilder(new PasteBuilder.FileProvider(region.getArea().getResetFile())) PasteBuilder pasteBuilder = new PasteBuilder(new PasteBuilder.FileProvider(region.getArea().getResetFile()))
.color(region.getFlags().get(Flag.COLOR).getWithDefault()); .color(region.getRegionData().get(Flag.COLOR).getWithDefault());
region.getArea().reset(pasteBuilder, false); region.getArea().reset(pasteBuilder, false);
region.getFlags().clear();
region.getRegionData().clear(); region.getRegionData().clear();
RegionUtils.message(region, "REGION_RESET_RESETED"); RegionUtils.message(region, "REGION_RESET_RESETED");
} catch (SecurityException e) { } catch (SecurityException e) {
@@ -84,7 +83,7 @@ public class ResetCommand extends SWCommand {
} }
try { try {
PasteBuilder pasteBuilder = new PasteBuilder(new PasteBuilder.SchematicProvider(node)) PasteBuilder pasteBuilder = new PasteBuilder(new PasteBuilder.SchematicProvider(node))
.color(region.getFlags().get(Flag.COLOR).getWithDefault()); .color(region.getRegionData().get(Flag.COLOR).getWithDefault());
region.getArea().reset(pasteBuilder, true); region.getArea().reset(pasteBuilder, true);
RegionUtils.message(region, "REGION_RESET_RESETED"); RegionUtils.message(region, "REGION_RESET_RESETED");
} catch (SecurityException e) { } catch (SecurityException e) {
@@ -92,7 +92,7 @@ public class TNTCommand extends SWCommand {
@Override @Override
public List<String> tabCompletes(CommandSender sender, PreviousArguments previousArguments, String s) { public List<String> tabCompletes(CommandSender sender, PreviousArguments previousArguments, String s) {
Region region = Region.getRegion(((Player) sender).getLocation()); Region region = Region.getRegion(((Player) sender).getLocation());
if (region.getFlags().get(Flag.TESTBLOCK).isNotWithDefault(TestblockMode.NO_VALUE)) { if (region.getRegionData().get(Flag.TESTBLOCK).isNotWithDefault(TestblockMode.NO_VALUE)) {
return new ArrayList<>(tntModeMap.keySet()); return new ArrayList<>(tntModeMap.keySet());
} else { } else {
return new ArrayList<>(tntModeMapReduced.keySet()); return new ArrayList<>(tntModeMapReduced.keySet());
@@ -102,7 +102,7 @@ public class TNTCommand extends SWCommand {
@Override @Override
public TNTMode map(CommandSender sender, PreviousArguments previousArguments, String s) { public TNTMode map(CommandSender sender, PreviousArguments previousArguments, String s) {
Region region = Region.getRegion(((Player) sender).getLocation()); Region region = Region.getRegion(((Player) sender).getLocation());
if (region.getFlags().get(Flag.TESTBLOCK).isNotWithDefault(TestblockMode.NO_VALUE)) { if (region.getRegionData().get(Flag.TESTBLOCK).isNotWithDefault(TestblockMode.NO_VALUE)) {
return tntModeMap.getOrDefault(s, null); return tntModeMap.getOrDefault(s, null);
} else { } else {
return tntModeMapReduced.getOrDefault(s, null); return tntModeMapReduced.getOrDefault(s, null);
@@ -124,23 +124,23 @@ public class TNTCommand extends SWCommand {
} }
private void tntToggle(Region region, TNTMode requestedMode, String requestedMessage) { private void tntToggle(Region region, TNTMode requestedMode, String requestedMessage) {
if (requestedMode != null && region.getFlags().get(Flag.TESTBLOCK).isNotWithDefault(TestblockMode.NO_VALUE)) { if (requestedMode != null && region.getRegionData().get(Flag.TESTBLOCK).isNotWithDefault(TestblockMode.NO_VALUE)) {
region.getFlags().set(Flag.TNT, requestedMode); region.getRegionData().set(Flag.TNT, requestedMode);
RegionUtils.actionBar(region, requestedMessage); RegionUtils.actionBar(region, requestedMessage);
return; return;
} }
switch (region.getFlags().get(Flag.TNT).getWithDefault()) { switch (region.getRegionData().get(Flag.TNT).getWithDefault()) {
case ALLOW: case ALLOW:
case ONLY_TB: case ONLY_TB:
region.getFlags().set(Flag.TNT, TNTMode.DENY); region.getRegionData().set(Flag.TNT, TNTMode.DENY);
RegionUtils.actionBar(region, getDisableMessage()); RegionUtils.actionBar(region, getDisableMessage());
break; break;
case DENY: case DENY:
if (region.getFlags().get(Flag.TESTBLOCK).isNotWithDefault(TestblockMode.NO_VALUE)) { if (region.getRegionData().get(Flag.TESTBLOCK).isNotWithDefault(TestblockMode.NO_VALUE)) {
region.getFlags().set(Flag.TNT, TNTMode.ONLY_TB); region.getRegionData().set(Flag.TNT, TNTMode.ONLY_TB);
RegionUtils.actionBar(region, getTestblockEnableMessage()); RegionUtils.actionBar(region, getTestblockEnableMessage());
} else { } else {
region.getFlags().set(Flag.TNT, TNTMode.ALLOW); region.getRegionData().set(Flag.TNT, TNTMode.ALLOW);
RegionUtils.actionBar(region, getEnableMessage()); RegionUtils.actionBar(region, getEnableMessage());
} }
break; break;
@@ -44,7 +44,7 @@ public class TNTListener implements Listener, ScoreboardElement {
private void explode(List<Block> blockList, boolean destroy) { private void explode(List<Block> blockList, boolean destroy) {
blockList.removeIf(block -> { blockList.removeIf(block -> {
Region region = Region.getRegion(block.getLocation()); Region region = Region.getRegion(block.getLocation());
TNTMode value = region.getFlags().get(Flag.TNT).getWithDefault(); TNTMode value = region.getRegionData().get(Flag.TNT).getWithDefault();
if (value == TNTMode.ALLOW) { if (value == TNTMode.ALLOW) {
if (destroy && block.getType() != Material.TNT) { if (destroy && block.getType() != Material.TNT) {
block.setType(Material.AIR); block.setType(Material.AIR);
@@ -86,7 +86,7 @@ public class TNTListener implements Listener, ScoreboardElement {
@Override @Override
public String get(Region region, Player p) { public String get(Region region, Player p) {
if (region.getFlags().get(Flag.TNT).isWithDefault(TNTMode.ALLOW)) return null; if (region.getRegionData().get(Flag.TNT).isWithDefault(TNTMode.ALLOW)) return null;
return "§e" + BauSystem.MESSAGE.parse(Flag.TNT.getChatValue(), p) + "§8: " + BauSystem.MESSAGE.parse(region.getFlags().get(Flag.TNT).getWithDefault().getChatValue(), p); return "§e" + BauSystem.MESSAGE.parse(Flag.TNT.getChatValue(), p) + "§8: " + BauSystem.MESSAGE.parse(region.getRegionData().get(Flag.TNT).getWithDefault().getChatValue(), p);
} }
} }
@@ -119,7 +119,7 @@ public class TestblockCommand extends SWCommand {
.onlyColors(onlyColors) .onlyColors(onlyColors)
.removeTNT(removeTNT) .removeTNT(removeTNT)
.removeWater(removeWater) .removeWater(removeWater)
.color(region.getFlags().get(Flag.COLOR).getWithDefault()); .color(region.getRegionData().get(Flag.COLOR).getWithDefault());
region.getTestblockArea().reset(pasteBuilder, regionExtensionType == RegionExtensionType.EXTENSION); region.getTestblockArea().reset(pasteBuilder, regionExtensionType == RegionExtensionType.EXTENSION);
RegionUtils.message(region, "REGION_TB_DONE"); RegionUtils.message(region, "REGION_TB_DONE");
} catch (SecurityException e) { } catch (SecurityException e) {
@@ -84,14 +84,14 @@ public class ColorBauGuiItem extends BauGuiItem {
@Override @Override
public ItemStack getItem(Player player) { public ItemStack getItem(Player player) {
Region region = Region.getRegion(player.getLocation()); Region region = Region.getRegion(player.getLocation());
ColorMode mode = region.getFlags().get(Flag.COLOR).orElse(ColorMode.PINK); ColorMode mode = region.getRegionData().get(Flag.COLOR).orElse(ColorMode.PINK);
return new SWItem(mapColor(mode), BauSystem.MESSAGE.parse("REGION_ITEM_COLOR", player, BauSystem.MESSAGE.parse(mode.getChatValue(), player))).getItemStack(); return new SWItem(mapColor(mode), BauSystem.MESSAGE.parse("REGION_ITEM_COLOR", player, BauSystem.MESSAGE.parse(mode.getChatValue(), player))).getItemStack();
} }
@Override @Override
public boolean click(ClickType click, Player p) { public boolean click(ClickType click, Player p) {
p.closeInventory(); p.closeInventory();
ColorMode current = Region.getRegion(p.getLocation()).getFlags().get(Flag.COLOR).orElse(ColorMode.PINK); ColorMode current = Region.getRegion(p.getLocation()).getRegionData().get(Flag.COLOR).orElse(ColorMode.PINK);
List<SWListInv.SWListEntry<ColorMode>> items = new ArrayList<>(); List<SWListInv.SWListEntry<ColorMode>> items = new ArrayList<>();
for (ColorMode value : ColorMode.values()) { for (ColorMode value : ColorMode.values()) {
items.add(new SWListInv.SWListEntry<>(new SWItem(mapColor(value), (byte) 0, "§f" + BauSystem.MESSAGE.parse(value.getChatValue(), p), Collections.emptyList(), value == current, clickType -> { items.add(new SWListInv.SWListEntry<>(new SWItem(mapColor(value), (byte) 0, "§f" + BauSystem.MESSAGE.parse(value.getChatValue(), p), Collections.emptyList(), value == current, clickType -> {
@@ -42,10 +42,10 @@ public class FireBauGuiItem extends BauGuiItem {
@Override @Override
public ItemStack getItem(Player player) { public ItemStack getItem(Player player) {
Region region = Region.getRegion(player.getLocation()); Region region = Region.getRegion(player.getLocation());
if (!region.getFlags().has(Flag.FIRE).isApplicable()) { if (!region.getRegionData().has(Flag.FIRE).isApplicable()) {
return new SWItem(Material.BARRIER, "").getItemStack(); return new SWItem(Material.BARRIER, "").getItemStack();
} }
if (region.getFlags().get(Flag.FIRE).isWithDefault(FireMode.ALLOW)) { if (region.getRegionData().get(Flag.FIRE).isWithDefault(FireMode.ALLOW)) {
return new SWItem(Material.FIRE_CHARGE, BauSystem.MESSAGE.parse("REGION_ITEM_FIRE_ALLOW", player)).getItemStack(); return new SWItem(Material.FIRE_CHARGE, BauSystem.MESSAGE.parse("REGION_ITEM_FIRE_ALLOW", player)).getItemStack();
} else { } else {
return new SWItem(Material.FIREWORK_STAR, BauSystem.MESSAGE.parse("REGION_ITEM_FIRE_DISALLOW", player)).getItemStack(); return new SWItem(Material.FIREWORK_STAR, BauSystem.MESSAGE.parse("REGION_ITEM_FIRE_DISALLOW", player)).getItemStack();
@@ -42,10 +42,10 @@ public class FreezeBauGuiItem extends BauGuiItem {
@Override @Override
public ItemStack getItem(Player player) { public ItemStack getItem(Player player) {
Region region = Region.getRegion(player.getLocation()); Region region = Region.getRegion(player.getLocation());
if (!region.getFlags().has(Flag.FREEZE).isApplicable()) { if (!region.getRegionData().has(Flag.FREEZE).isApplicable()) {
return new SWItem(Material.BARRIER, "").getItemStack(); return new SWItem(Material.BARRIER, "").getItemStack();
} }
if (region.getFlags().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) { if (region.getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) {
return new SWItem(Material.GUNPOWDER, BauSystem.MESSAGE.parse("REGION_ITEM_FREEZE_ALLOW", player)).getItemStack(); return new SWItem(Material.GUNPOWDER, BauSystem.MESSAGE.parse("REGION_ITEM_FREEZE_ALLOW", player)).getItemStack();
} else { } else {
return new SWItem(Material.REDSTONE, BauSystem.MESSAGE.parse("REGION_ITEM_FREEZE_DISALLOW", player)).getItemStack(); return new SWItem(Material.REDSTONE, BauSystem.MESSAGE.parse("REGION_ITEM_FREEZE_DISALLOW", player)).getItemStack();
@@ -43,10 +43,10 @@ public class ProtectBauGuiItem extends BauGuiItem {
@Override @Override
public ItemStack getItem(Player player) { public ItemStack getItem(Player player) {
Region region = Region.getRegion(player.getLocation()); Region region = Region.getRegion(player.getLocation());
if (!region.getFlags().has(Flag.PROTECT).isApplicable()) { if (!region.getRegionData().has(Flag.PROTECT).isApplicable()) {
return new SWItem(Material.BARRIER, "").getItemStack(); return new SWItem(Material.BARRIER, "").getItemStack();
} }
if (region.getFlags().get(Flag.PROTECT).isWithDefault(ProtectMode.ACTIVE)) { if (region.getRegionData().get(Flag.PROTECT).isWithDefault(ProtectMode.ACTIVE)) {
return SWUtils.setCustomModelData(new SWItem(Material.OBSIDIAN, BauSystem.MESSAGE.parse("REGION_ITEM_PROTECT_ALLOW", player)), 1).getItemStack(); return SWUtils.setCustomModelData(new SWItem(Material.OBSIDIAN, BauSystem.MESSAGE.parse("REGION_ITEM_PROTECT_ALLOW", player)), 1).getItemStack();
} else { } else {
return SWUtils.setCustomModelData(new SWItem(Material.STONE, BauSystem.MESSAGE.parse("REGION_ITEM_PROTECT_DISALLOW", player)), 1).getItemStack(); return SWUtils.setCustomModelData(new SWItem(Material.STONE, BauSystem.MESSAGE.parse("REGION_ITEM_PROTECT_DISALLOW", player)), 1).getItemStack();
@@ -42,7 +42,7 @@ public class TntBauGuiItem extends BauGuiItem {
@Override @Override
public ItemStack getItem(Player player) { public ItemStack getItem(Player player) {
switch (Region.getRegion(player.getLocation()).getFlags().get(Flag.TNT).getWithDefault()) { switch (Region.getRegion(player.getLocation()).getRegionData().get(Flag.TNT).getWithDefault()) {
case DENY: case DENY:
return new SWItem(Material.MINECART, BauSystem.MESSAGE.parse("REGION_ITEM_TNT_OFF", player)).getItemStack(); return new SWItem(Material.MINECART, BauSystem.MESSAGE.parse("REGION_ITEM_TNT_OFF", player)).getItemStack();
case ONLY_TB: case ONLY_TB:
@@ -55,7 +55,7 @@ public class TntBauGuiItem extends BauGuiItem {
@Override @Override
public boolean click(ClickType click, Player p) { public boolean click(ClickType click, Player p) {
if (click == ClickType.LEFT) { if (click == ClickType.LEFT) {
switch (Region.getRegion(p.getLocation()).getFlags().get(Flag.TNT).getWithDefault()) { switch (Region.getRegion(p.getLocation()).getRegionData().get(Flag.TNT).getWithDefault()) {
case DENY: case DENY:
updateTntMode(TNTMode.ALLOW, p); updateTntMode(TNTMode.ALLOW, p);
break; break;
@@ -59,14 +59,14 @@ public class RegionLib implements LuaLib {
})); }));
LuaValue tntLib = LuaValue.tableOf(); LuaValue tntLib = LuaValue.tableOf();
tntLib.set("mode", getter(() -> region.get().getFlags().get(Flag.TNT).nameWithDefault())); tntLib.set("mode", getter(() -> region.get().getRegionData().get(Flag.TNT).nameWithDefault()));
tntLib.set("enabled", getter(() -> region.get().getFlags().get(Flag.TNT).orElse(null) != TNTMode.DENY)); tntLib.set("enabled", getter(() -> region.get().getRegionData().get(Flag.TNT).orElse(null) != TNTMode.DENY));
tntLib.set("onlyTb", getter(() -> region.get().getFlags().get(Flag.TNT).orElse(null) == TNTMode.ONLY_TB)); tntLib.set("onlyTb", getter(() -> region.get().getRegionData().get(Flag.TNT).orElse(null) == TNTMode.ONLY_TB));
table.set("tnt", tntLib); table.set("tnt", tntLib);
table.set("fire", getter(() -> region.get().getFlags().get(Flag.FIRE).orElse(null) == FireMode.ALLOW)); table.set("fire", getter(() -> region.get().getRegionData().get(Flag.FIRE).orElse(null) == FireMode.ALLOW));
table.set("freeze", getter(() -> region.get().getFlags().get(Flag.FREEZE).orElse(null) == FreezeMode.ACTIVE)); table.set("freeze", getter(() -> region.get().getRegionData().get(Flag.FREEZE).orElse(null) == FreezeMode.ACTIVE));
table.set("protect", getter(() -> region.get().getFlags().get(Flag.PROTECT).orElse(null) == ProtectMode.ACTIVE)); table.set("protect", getter(() -> region.get().getRegionData().get(Flag.PROTECT).orElse(null) == ProtectMode.ACTIVE));
//LuaValue traceLib = LuaValue.tableOf(); //LuaValue traceLib = LuaValue.tableOf();
//traceLib.set("active", getter(() -> !region.get().isGlobal() && Recorder.INSTANCE.get(region.get()) instanceof ActiveTracer)); //traceLib.set("active", getter(() -> !region.get().isGlobal() && Recorder.INSTANCE.get(region.get()) instanceof ActiveTracer));
@@ -65,7 +65,7 @@ public final class TNTPhase extends SimulatorPhase {
@Override @Override
public void accept(World world) { public void accept(World world) {
Location location = position.toLocation(world); Location location = position.toLocation(world);
if (Region.getRegion(location).getFlags().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) return; if (Region.getRegion(location).getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) return;
TNTPrimed tnt = world.spawn(location, TNTPrimed.class); TNTPrimed tnt = world.spawn(location, TNTPrimed.class);
if (!xJump) tnt.setVelocity(tnt.getVelocity().setX(0)); if (!xJump) tnt.setVelocity(tnt.getVelocity().setX(0));
if (!yJump) tnt.setVelocity(tnt.getVelocity().setY(0)); if (!yJump) tnt.setVelocity(tnt.getVelocity().setY(0));
@@ -35,8 +35,8 @@ public class StabFinalizer extends StabStep {
try { try {
PasteBuilder.ClipboardProvider clipboardProvider = new PasteBuilder.ClipboardProviderImpl(data.clipboard); PasteBuilder.ClipboardProvider clipboardProvider = new PasteBuilder.ClipboardProviderImpl(data.clipboard);
PasteBuilder pasteBuilder = new PasteBuilder(clipboardProvider); PasteBuilder pasteBuilder = new PasteBuilder(clipboardProvider);
if (data.region.getFlags().has(Flag.COLOR).isReadable()) { if (data.region.getRegionData().has(Flag.COLOR).isReadable()) {
pasteBuilder.color(data.region.getFlags().get(Flag.COLOR).getWithDefault()); pasteBuilder.color(data.region.getRegionData().get(Flag.COLOR).getWithDefault());
} }
data.region.getTestblockArea().reset(pasteBuilder, true); data.region.getTestblockArea().reset(pasteBuilder, true);
} catch (SecurityException e) { } catch (SecurityException e) {
@@ -73,8 +73,8 @@ public class StabGenerator extends StabStep implements Listener {
try { try {
PasteBuilder.ClipboardProvider clipboardProvider = new PasteBuilder.ClipboardProviderImpl(data.clipboard); PasteBuilder.ClipboardProvider clipboardProvider = new PasteBuilder.ClipboardProviderImpl(data.clipboard);
PasteBuilder pasteBuilder = new PasteBuilder(clipboardProvider); PasteBuilder pasteBuilder = new PasteBuilder(clipboardProvider);
if (data.region.getFlags().has(Flag.COLOR).isReadable()) { if (data.region.getRegionData().has(Flag.COLOR).isReadable()) {
pasteBuilder.color(data.region.getFlags().get(Flag.COLOR).getWithDefault()); pasteBuilder.color(data.region.getRegionData().get(Flag.COLOR).getWithDefault());
} }
data.region.getTestblockArea().reset(pasteBuilder, true); data.region.getTestblockArea().reset(pasteBuilder, true);
} catch (SecurityException e) { } catch (SecurityException e) {
@@ -121,8 +121,8 @@ public class BauScoreboard implements Listener {
Region region = Region.getRegion(player.getLocation()); Region region = Region.getRegion(player.getLocation());
if (region.getType().isGlobal()) return "§eSteam§8War"; if (region.getType().isGlobal()) return "§eSteam§8War";
String colorCode = "§e"; String colorCode = "§e";
if (region.getFlags().has(Flag.COLOR).isReadable()) { if (region.getRegionData().has(Flag.COLOR).isReadable()) {
colorCode = "§" + region.getFlags().get(Flag.COLOR).orElse(ColorMode.PINK).getColorCode(); colorCode = "§" + region.getRegionData().get(Flag.COLOR).orElse(ColorMode.PINK).getColorCode();
} }
return colorCode + "■ §eSteam§8War " + colorCode + "■"; // ■ return colorCode + "■ §eSteam§8War " + colorCode + "■"; // ■
} }
@@ -41,8 +41,8 @@ public class BackupScheduler implements Enable {
@Override @Override
public void run() { public void run() {
Iterator<Region> regionsToBackup = RegionSystem.INSTANCE.getRegions() Iterator<Region> regionsToBackup = RegionSystem.INSTANCE.getRegions()
.filter(region -> region.getFlags().has(Flag.CHANGED).isReadable()) .filter(region -> region.getRegionData().has(Flag.CHANGED).isReadable())
.filter(region -> region.getFlags().get(Flag.CHANGED).getWithDefault() == ChangedMode.HAS_CHANGE) .filter(region -> region.getRegionData().get(Flag.CHANGED).isWithDefault(ChangedMode.HAS_CHANGE))
.iterator(); .iterator();
if (!regionsToBackup.hasNext()) return; if (!regionsToBackup.hasNext()) return;
doBackup(regionsToBackup); doBackup(regionsToBackup);
@@ -63,7 +63,7 @@ public class BackupScheduler implements Enable {
Optional<RegionBackups.Backup> backup = region.getBackups() Optional<RegionBackups.Backup> backup = region.getBackups()
.create(RegionBackups.BackupType.AUTOMATIC); .create(RegionBackups.BackupType.AUTOMATIC);
if (backup.isPresent()) { if (backup.isPresent()) {
region.getFlags().set(Flag.CHANGED, ChangedMode.NO_CHANGE); region.getRegionData().set(Flag.CHANGED, ChangedMode.NO_CHANGE);
} }
} }
}.runTaskTimer(BauSystem.getInstance(), 0, 20 * 60); }.runTaskTimer(BauSystem.getInstance(), 0, 20 * 60);
@@ -1,43 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2025 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.region;
import de.steamwar.bausystem.region.flags.Flag;
import lombok.NonNull;
import java.util.Map;
public interface FlagStorage {
@NonNull
<T extends Enum<T> & Flag.Value<T>> RegionFlagPolicy has(@NonNull Flag<T> flag);
/**
* Returns true if the flag was changed and did not already contain the provided value
*/
<T extends Enum<T> & Flag.Value<T>> boolean set(@NonNull Flag<T> flag, @NonNull T value);
@NonNull
<T extends Enum<T> & Flag.Value<T>> FlagOptional<T> get(@NonNull Flag<T> flag);
void clear();
Map<Flag<?>, Flag.Value<?>> getBackedMap();
}
@@ -23,7 +23,6 @@ import com.sk89q.worldedit.extent.clipboard.Clipboard;
import de.steamwar.bausystem.utils.FlatteningWrapper; import de.steamwar.bausystem.utils.FlatteningWrapper;
import de.steamwar.bausystem.utils.PasteBuilder; import de.steamwar.bausystem.utils.PasteBuilder;
import de.steamwar.sql.GameModeConfig; import de.steamwar.sql.GameModeConfig;
import de.steamwar.sql.SchematicType;
import lombok.NonNull; import lombok.NonNull;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
@@ -55,7 +54,7 @@ public interface Region {
RegionType getType(); RegionType getType();
@NonNull @NonNull
FlagStorage getFlags(); RegionData getRegionData();
@NonNull @NonNull
Area getArea(); Area getArea();
@@ -75,9 +74,6 @@ public interface Region {
@NonNull @NonNull
RegionBackups getBackups(); RegionBackups getBackups();
@NonNull
RegionData getRegionData();
interface Area { interface Area {
Area EMPTY = new Area() { Area EMPTY = new Area() {
@@ -49,7 +49,7 @@ public interface RegionBackups {
private final String name; private final String name;
@NonNull @NonNull
private final FlagStorage flags; private final RegionData data;
@CheckReturnValue @CheckReturnValue
public abstract boolean load(); public abstract boolean load();
@@ -19,75 +19,134 @@
package de.steamwar.bausystem.region; package de.steamwar.bausystem.region;
import de.steamwar.bausystem.region.flags.Flag;
import de.steamwar.sql.SchematicNode; import de.steamwar.sql.SchematicNode;
import lombok.NonNull;
import yapion.hierarchy.types.YAPIONObject; import yapion.hierarchy.types.YAPIONObject;
import java.util.Objects; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
public interface RegionData { public abstract class RegionData {
void clear(); private final List<Property<?, ?>> properties = new ArrayList<>();
SchematicNode getTestblockSchematic(); protected final YAPIONObject data;
protected final YAPIONObject flagData;
protected final Runnable onChange;
protected final Map<Flag<?>, Flag.Value<?>> flagMap = new HashMap<>();
void setTestblockSchematic(SchematicNode schematic); private final class Property<T, K> {
private final String field;
private final Function<K, T> loader;
private final Function<T, K> writer;
RegionData EMPTY = new RegionData() { private T value;
@Override public Property(String field, Function<K, T> loader, Function<T, K> writer) {
public void clear() { this.field = field;
this.loader = loader;
this.writer = writer;
properties.add(this);
} }
@Override public void load() {
public SchematicNode getTestblockSchematic() { if (flagData.containsKey(field)) {
return null; value = loader.apply(flagData.getPlainValue(field));
}
@Override
public void setTestblockSchematic(SchematicNode schematic) {
}
};
class RegionDataImpl implements RegionData {
private final YAPIONObject yapionObject;
private final Runnable onChange;
public RegionDataImpl(YAPIONObject yapionObject, Runnable onChange) {
this.yapionObject = yapionObject;
this.onChange = onChange;
if (yapionObject.containsKey("testblockSchematic")) {
testblockSchematic = SchematicNode.getSchematicNode(yapionObject.getInt("testblockSchematic"));
}
}
@Override
public void clear() {
testblockSchematic = null;
yapionObject.remove("testblockSchematic");
onChange.run();
}
private SchematicNode testblockSchematic = null;
@Override
public SchematicNode getTestblockSchematic() {
return testblockSchematic;
}
@Override
public void setTestblockSchematic(SchematicNode schematic) {
if (Objects.equals(this.testblockSchematic, schematic)) {
return;
}
this.testblockSchematic = schematic;
if (schematic == null) {
yapionObject.remove("testblockSchematic");
} else { } else {
yapionObject.put("testblockSchematic", testblockSchematic.getId()); value = null;
}
}
public T get() {
return value;
}
public void set(T value) {
this.value = value;
if (value == null) {
flagData.remove(field);
} else {
flagData.put(field, writer.apply(value));
} }
onChange.run();
} }
} }
private Property<SchematicNode, Integer> testblockSchematic = new Property<>("testblockSchematic", SchematicNode::byId, SchematicNode::getId);
protected RegionData(YAPIONObject data, Runnable onChange) {
this.data = data;
this.flagData = data.getObjectOrSetDefault("flagStorage", new YAPIONObject());
this.onChange = onChange;
initialize();
for (final Flag flag : Flag.getFlags()) {
if (!has(flag).isWritable()) continue;
try {
String s = flagData.getPlainValue(flag.name());
flagMap.put(flag, flag.valueOfValue(s));
} catch (Exception e) {
flagMap.put(flag, (Flag.Value<?>) flag.getDefaultValue());
}
}
properties.forEach(Property::load);
}
protected void initialize() {
}
@NonNull
public abstract <T extends Enum<T> & Flag.Value<T>> RegionFlagPolicy has(@NonNull Flag<T> flag);
/**
* Returns true if the flag was changed and did not already contain the provided value
*/
public final <T extends Enum<T> & Flag.Value<T>> boolean set(@NonNull Flag<T> flag, @NonNull T value) {
if (has(flag).isWritable()) {
if (flagMap.put(flag, value) != value) {
flagData.put(flag.name(), value.name());
onChange.run();
return true;
}
}
return false;
}
@NonNull
public final <T extends Enum<T> & Flag.Value<T>> FlagOptional<T> get(@NonNull Flag<T> flag) {
return FlagOptional.of(flag, (T) flagMap.get(flag));
}
public final void clear() {
for (Flag flag : Flag.getFlags()) {
if (has(flag).isWritable()) {
flagMap.remove(flag);
flagData.remove(flag.name());
}
}
properties.forEach(property -> property.set(null));
onChange.run();
}
public final Map<Flag<?>, Flag.Value<?>> getBackedMap() {
return flagMap;
}
public SchematicNode getTestblockSchematic() {
return testblockSchematic.get();
}
public void setTestblockSchematic(SchematicNode schematic) {
testblockSchematic.set(schematic);
onChange.run();
}
@Override
public final String toString() {
return getClass().getSimpleName() + "{" +
"flagMap=" + flagMap +
'}';
}
} }
@@ -1,106 +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.region.fixed;
import de.steamwar.bausystem.region.FlagOptional;
import de.steamwar.bausystem.region.FlagStorage;
import de.steamwar.bausystem.region.RegionFlagPolicy;
import de.steamwar.bausystem.region.flags.Flag;
import de.steamwar.bausystem.worlddata.WorldData;
import de.steamwar.core.Core;
import lombok.NonNull;
import yapion.hierarchy.types.YAPIONObject;
import java.util.HashMap;
import java.util.Map;
public class FixedFlagStorage implements FlagStorage {
private Map<Flag<?>, Flag.Value<?>> flagMap = new HashMap<>();
private YAPIONObject data;
public FixedFlagStorage(YAPIONObject data) {
this.data = data;
for (final Flag flag : Flag.getFlags()) {
if (!has(flag).isWritable()) continue;
try {
String s = data.getPlainValue(flag.name());
flagMap.put(flag, flag.valueOfValue(s));
} catch (Exception e) {
flagMap.put(flag, (Flag.Value<?>) flag.getDefaultValue());
}
}
}
@Override
public @NonNull <T extends Enum<T> & Flag.Value<T>> RegionFlagPolicy has(@NonNull Flag<T> flag) {
if (flag.oneOf(Flag.COLOR, Flag.TNT, Flag.FIRE, Flag.FREEZE, Flag.PROTECT, Flag.NO_GRAVITY, Flag.CHANGED)) {
return RegionFlagPolicy.WRITABLE;
}
if (flag.oneOf(Flag.ITEMS) && Core.getVersion() >= 20) {
return RegionFlagPolicy.WRITABLE;
}
if (flag.oneOf(Flag.TESTBLOCK)) {
return RegionFlagPolicy.READ_ONLY;
}
return RegionFlagPolicy.NOT_APPLICABLE;
}
@Override
public <T extends Enum<T> & Flag.Value<T>> boolean set(@NonNull Flag<T> flag, @NonNull T value) {
if (has(flag).isWritable()) {
boolean hasChanged = flagMap.put(flag, value) != value;
if (hasChanged) {
data.put(flag.name(), value.name());
WorldData.write();
}
return hasChanged;
} else {
return false;
}
}
@Override
public @NonNull <T extends Enum<T> & Flag.Value<T>> FlagOptional<T> get(@NonNull Flag<T> flag) {
return FlagOptional.of(flag, (T) flagMap.get(flag));
}
@Override
public void clear() {
for (Flag flag : Flag.getFlags()) {
if (flag == Flag.TESTBLOCK) continue;
if (flag == Flag.COLOR) continue;
if (flag == Flag.CHANGED) continue;
flagMap.remove(flag);
}
}
@Override
public Map<Flag<?>, Flag.Value<?>> getBackedMap() {
return flagMap;
}
@Override
public String toString() {
return "FixedFlagStorage{" +
"flagMap=" + flagMap +
'}';
}
}
@@ -1,113 +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.region.fixed;
import de.steamwar.bausystem.region.FlagOptional;
import de.steamwar.bausystem.region.FlagStorage;
import de.steamwar.bausystem.region.RegionFlagPolicy;
import de.steamwar.bausystem.region.flags.ColorMode;
import de.steamwar.bausystem.region.flags.Flag;
import de.steamwar.bausystem.region.flags.ProtectMode;
import de.steamwar.bausystem.region.flags.TNTMode;
import de.steamwar.bausystem.worlddata.WorldData;
import de.steamwar.core.Core;
import lombok.NonNull;
import yapion.hierarchy.types.YAPIONObject;
import java.util.HashMap;
import java.util.Map;
public class FixedGlobalFlagStorage implements FlagStorage {
private Map<Flag<?>, Flag.Value<?>> flagMap = new HashMap<>();
private YAPIONObject data;
public FixedGlobalFlagStorage(YAPIONObject data) {
flagMap.put(Flag.TNT, TNTMode.DENY);
this.data = data;
for (final Flag flag : Flag.getFlags()) {
if (!has(flag).isWritable()) continue;
try {
String s = data.getPlainValue(flag.name());
flagMap.put(flag, flag.valueOfValue(s));
} catch (Exception e) {
flagMap.put(flag, (Flag.Value<?>) flag.getDefaultValue());
}
}
}
@Override
public @NonNull <T extends Enum<T> & Flag.Value<T>> RegionFlagPolicy has(@NonNull Flag<T> flag) {
if (flag.oneOf(Flag.COLOR)) {
return RegionFlagPolicy.READ_ONLY;
}
if (flag.oneOf(Flag.ITEMS) && Core.getVersion() >= 20) {
return RegionFlagPolicy.WRITABLE;
}
if (flag.oneOf(Flag.TNT, Flag.FIRE, Flag.FREEZE)) {
return RegionFlagPolicy.WRITABLE;
}
return RegionFlagPolicy.NOT_APPLICABLE;
}
@Override
public <T extends Enum<T> & Flag.Value<T>> boolean set(@NonNull Flag<T> flag, @NonNull T value) {
if (has(flag).isWritable()) {
data.put(flag.name(), value.name());
WorldData.write();
return flagMap.put(flag, value) != value;
} else {
return false;
}
}
@Override
public @NonNull <T extends Enum<T> & Flag.Value<T>> FlagOptional<T> get(@NonNull Flag<T> flag) {
if (flag.oneOf(Flag.COLOR)) {
return FlagOptional.of((Flag) flag, ColorMode.YELLOW);
}
if (flag.oneOf(Flag.PROTECT)) {
return FlagOptional.of((Flag) flag, ProtectMode.INACTIVE);
}
return FlagOptional.of(flag, (T) flagMap.get(flag));
}
@Override
public void clear() {
for (Flag flag : Flag.getFlags()) {
if (flag == Flag.TESTBLOCK) continue;
if (flag == Flag.COLOR) continue;
if (flag == Flag.CHANGED) continue;
flagMap.remove(flag);
}
}
@Override
public Map<Flag<?>, Flag.Value<?>> getBackedMap() {
return flagMap;
}
@Override
public String toString() {
return "FixedGlobalFlagStorage{" +
"flagMap=" + flagMap +
'}';
}
}
@@ -41,7 +41,7 @@ public final class FixedGlobalRegion implements Region {
private static final Point MAX_POINT = new Point(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE); private static final Point MAX_POINT = new Point(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE);
@Setter @Setter
private static FlagStorage FLAG_STORAGE; private static RegionData FLAG_STORAGE;
private static final UUID GLOBAL_REGION_ID = new UUID(0, 0); private static final UUID GLOBAL_REGION_ID = new UUID(0, 0);
@@ -106,7 +106,7 @@ public final class FixedGlobalRegion implements Region {
} }
@Override @Override
public @NonNull FlagStorage getFlags() { public @NonNull RegionData getRegionData() {
return FLAG_STORAGE; return FLAG_STORAGE;
} }
@@ -139,9 +139,4 @@ public final class FixedGlobalRegion implements Region {
public @NonNull RegionBackups getBackups() { public @NonNull RegionBackups getBackups() {
return RegionBackups.EMPTY; return RegionBackups.EMPTY;
} }
@Override
public @NonNull RegionData getRegionData() {
return RegionData.EMPTY;
}
} }
@@ -0,0 +1,58 @@
/*
* 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.region.fixed;
import de.steamwar.bausystem.region.RegionData;
import de.steamwar.bausystem.region.RegionFlagPolicy;
import de.steamwar.bausystem.region.flags.ColorMode;
import de.steamwar.bausystem.region.flags.Flag;
import de.steamwar.bausystem.region.flags.ProtectMode;
import de.steamwar.bausystem.region.flags.TNTMode;
import de.steamwar.core.Core;
import lombok.NonNull;
import yapion.hierarchy.types.YAPIONObject;
public class FixedGlobalRegionData extends RegionData {
public FixedGlobalRegionData(YAPIONObject data, Runnable onChange) {
super(data, onChange);
}
@Override
protected void initialize() {
flagMap.put(Flag.TNT, TNTMode.DENY);
flagMap.put(Flag.COLOR, ColorMode.YELLOW);
flagMap.put(Flag.PROTECT, ProtectMode.INACTIVE);
}
@Override
public @NonNull <T extends Enum<T> & Flag.Value<T>> RegionFlagPolicy has(@NonNull Flag<T> flag) {
if (flag.oneOf(Flag.COLOR, Flag.PROTECT)) {
return RegionFlagPolicy.READ_ONLY;
}
if (flag.oneOf(Flag.ITEMS) && Core.getVersion() >= 20) {
return RegionFlagPolicy.WRITABLE;
}
if (flag.oneOf(Flag.TNT, Flag.FIRE, Flag.FREEZE)) {
return RegionFlagPolicy.WRITABLE;
}
return RegionFlagPolicy.NOT_APPLICABLE;
}
}
@@ -26,7 +26,6 @@ import de.steamwar.bausystem.region.flags.Flag;
import de.steamwar.bausystem.region.flags.TestblockMode; import de.steamwar.bausystem.region.flags.TestblockMode;
import de.steamwar.bausystem.utils.FlatteningWrapper; import de.steamwar.bausystem.utils.FlatteningWrapper;
import de.steamwar.bausystem.utils.PasteBuilder; import de.steamwar.bausystem.utils.PasteBuilder;
import de.steamwar.bausystem.worlddata.WorldData;
import de.steamwar.core.Core; import de.steamwar.core.Core;
import de.steamwar.sql.GameModeConfig; import de.steamwar.sql.GameModeConfig;
import de.steamwar.sql.SchematicType; import de.steamwar.sql.SchematicType;
@@ -50,7 +49,7 @@ public class FixedRegion implements Region {
private final String name; private final String name;
private final UUID uuid; private final UUID uuid;
private final FixedFlagStorage flagStorage; private final FixedRegionData flagStorage;
private final Prototype prototype; private final Prototype prototype;
private final String skin; private final String skin;
@@ -60,7 +59,6 @@ public class FixedRegion implements Region {
private final int floorLevel; private final int floorLevel;
private final int waterLevel; private final int waterLevel;
private final GameModeConfig<Material, String> gameModeConfig; private final GameModeConfig<Material, String> gameModeConfig;
private final RegionData regionData;
private final RegionHistory regionHistory = new RegionHistory.Impl(20); private final RegionHistory regionHistory = new RegionHistory.Impl(20);
private final RegionBackups regionBackups = new RegionBackups() { private final RegionBackups regionBackups = new RegionBackups() {
@@ -141,7 +139,7 @@ public class FixedRegion implements Region {
} }
} }
public FixedRegion(String name, FixedFlagStorage flagStorage, Prototype prototype, YAPIONObject regionConfig, YAPIONObject regionData) { public FixedRegion(String name, FixedRegionData flagStorage, Prototype prototype, YAPIONObject regionConfig, YAPIONObject regionData) {
this.name = name; this.name = name;
uuid = UUID.nameUUIDFromBytes(name.getBytes(StandardCharsets.UTF_8)); uuid = UUID.nameUUIDFromBytes(name.getBytes(StandardCharsets.UTF_8));
this.flagStorage = flagStorage; this.flagStorage = flagStorage;
@@ -343,7 +341,6 @@ public class FixedRegion implements Region {
} else { } else {
this.gameModeConfig = GameModeConfig.getByFileName(found); this.gameModeConfig = GameModeConfig.getByFileName(found);
} }
this.regionData = new RegionData.RegionDataImpl(regionData, WorldData::write);
} }
@Override @Override
@@ -357,7 +354,7 @@ public class FixedRegion implements Region {
} }
@Override @Override
public @NonNull FlagStorage getFlags() { public @NonNull RegionData getRegionData() {
return flagStorage; return flagStorage;
} }
@@ -390,9 +387,4 @@ public class FixedRegion implements Region {
public @NonNull RegionBackups getBackups() { public @NonNull RegionBackups getBackups() {
return regionBackups; return regionBackups;
} }
@Override
public @NonNull RegionData getRegionData() {
return regionData;
}
} }
@@ -0,0 +1,48 @@
/*
* 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.region.fixed;
import de.steamwar.bausystem.region.RegionData;
import de.steamwar.bausystem.region.RegionFlagPolicy;
import de.steamwar.bausystem.region.flags.Flag;
import de.steamwar.core.Core;
import lombok.NonNull;
import yapion.hierarchy.types.YAPIONObject;
public class FixedRegionData extends RegionData {
public FixedRegionData(YAPIONObject data, Runnable onChange) {
super(data, onChange);
}
@Override
public @NonNull <T extends Enum<T> & Flag.Value<T>> RegionFlagPolicy has(@NonNull Flag<T> flag) {
if (flag.oneOf(Flag.COLOR, Flag.TNT, Flag.FIRE, Flag.FREEZE, Flag.PROTECT, Flag.NO_GRAVITY, Flag.CHANGED)) {
return RegionFlagPolicy.WRITABLE;
}
if (flag.oneOf(Flag.ITEMS) && Core.getVersion() >= 20) {
return RegionFlagPolicy.WRITABLE;
}
if (flag.oneOf(Flag.TESTBLOCK)) {
return RegionFlagPolicy.READ_ONLY;
}
return RegionFlagPolicy.NOT_APPLICABLE;
}
}
@@ -20,6 +20,7 @@
package de.steamwar.bausystem.region.fixed; package de.steamwar.bausystem.region.fixed;
import de.steamwar.bausystem.region.FixedRegionSystem; import de.steamwar.bausystem.region.FixedRegionSystem;
import de.steamwar.bausystem.worlddata.WorldData;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import yapion.hierarchy.types.YAPIONObject; import yapion.hierarchy.types.YAPIONObject;
@@ -216,7 +217,7 @@ public class Prototype {
} else { } else {
prototype = PROTOTYPE_MAP.get(regionConfig.getPlainValue("prototype")); prototype = PROTOTYPE_MAP.get(regionConfig.getPlainValue("prototype"));
} }
FixedFlagStorage flagStorage = new FixedFlagStorage(regionData.getObjectOrSetDefault("flagStorage", new YAPIONObject())); FixedRegionData flagStorage = new FixedRegionData(regionData, WorldData::write);
FixedRegionSystem.addRegion(new FixedRegion(name, flagStorage, prototype, regionConfig, regionData)); FixedRegionSystem.addRegion(new FixedRegion(name, flagStorage, prototype, regionConfig, regionData));
} }
} }
@@ -19,7 +19,7 @@
package de.steamwar.bausystem.region.fixed.loader; package de.steamwar.bausystem.region.fixed.loader;
import de.steamwar.bausystem.region.fixed.FixedGlobalFlagStorage; import de.steamwar.bausystem.region.fixed.FixedGlobalRegionData;
import de.steamwar.bausystem.region.fixed.FixedGlobalRegion; import de.steamwar.bausystem.region.fixed.FixedGlobalRegion;
import de.steamwar.bausystem.region.fixed.Prototype; import de.steamwar.bausystem.region.fixed.Prototype;
import de.steamwar.bausystem.worlddata.WorldData; import de.steamwar.bausystem.worlddata.WorldData;
@@ -80,6 +80,6 @@ public class RegionLoader {
globalOptions = new YAPIONObject(); globalOptions = new YAPIONObject();
optionsYapionObject.add("global", globalOptions); optionsYapionObject.add("global", globalOptions);
} }
FixedGlobalRegion.setFLAG_STORAGE(new FixedGlobalFlagStorage(globalOptions.getObjectOrSetDefault("flagStorage", new YAPIONObject()))); FixedGlobalRegion.setFLAG_STORAGE(new FixedGlobalRegionData(globalOptions, WorldData::write));
} }
} }
@@ -151,9 +151,9 @@ class EventFight(id: EntityID<Int>) : IntEntity(id), Comparable<EventFight> {
val dependents by lazy { useDb { EventRelation.getFightRelations(this@EventFight).toList() } } val dependents by lazy { useDb { EventRelation.getFightRelations(this@EventFight).toList() } }
val winner: Team? val winner: Team?
get() = if (ergebnis == 1) Team[teamBlue] else if (ergebnis == 2) Team[teamRed] else null get() = useDb { if (ergebnis == 1) Team[teamBlue] else if (ergebnis == 2) Team[teamRed] else null }
val losser: Team? val losser: Team?
get() = if (ergebnis == 1) Team[teamRed] else if (ergebnis == 2) Team[teamBlue] else null get() = useDb { 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 setGroup(group: Int?) = useDb { groupId = group?.let { EntityID(it, EventGroupTable) } }
fun hasFinished() = fight != null || ergebnis != 0 fun hasFinished() = fight != null || ergebnis != 0
@@ -90,7 +90,7 @@ class EventGroup(id: EntityID<Int>) : IntEntity(id) {
set(value) { set(value) {
groupPointsPerDraw = value groupPointsPerDraw = value
} }
val dependents by lazy { EventRelation.getGroupRelations(this) } val dependents by lazy { EventRelation.getGroupRelations(this).toList() }
val lastFight by lazy { Optional.ofNullable(fights.maxByOrNull { it.startTime }) } val lastFight by lazy { Optional.ofNullable(fights.maxByOrNull { it.startTime }) }
fun getId() = id.value fun getId() = id.value
@@ -117,10 +117,10 @@ class EventRelation(id: EntityID<Int>) : IntEntity(id) {
fromPlace = place fromPlace = place
} }
fun getAdvancingTeam(): Team? = when(fromType) { fun getAdvancingTeam(): Team? = useDb { when(fromType) {
FromType.FIGHT -> if (fromPlace == 0) fromFight?.winner else fromFight?.losser FromType.FIGHT -> if (fromPlace == 0) fromFight?.winner else fromFight?.losser
FromType.GROUP -> fromGroup?.calculatePoints()?.toList()?.sortedBy { (_, v) -> v }?.reversed()?.elementAt(fromPlace)?.first FromType.GROUP -> fromGroup?.calculatePoints()?.toList()?.sortedBy { (_, v) -> v }?.reversed()?.elementAt(fromPlace)?.first
} } }
fun apply(): Boolean { fun apply(): Boolean {
val team = getAdvancingTeam() ?: return false val team = getAdvancingTeam() ?: return false
@@ -0,0 +1,94 @@
/*
* 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.count
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.lessSubQuery
import org.jetbrains.exposed.v1.dao.CompositeEntity
import org.jetbrains.exposed.v1.dao.CompositeEntityClass
import org.jetbrains.exposed.v1.dao.flushCache
import org.jetbrains.exposed.v1.javatime.CurrentTimestamp
import org.jetbrains.exposed.v1.javatime.timestamp
import org.jetbrains.exposed.v1.jdbc.select
import org.jetbrains.exposed.v1.jdbc.upsert
object LeaderboardTable : CompositeIdTable("Leaderboard") {
val userId = reference("UserId", SteamwarUserTable)
val name = varchar("LeaderboardName", 64).entityId()
val time = long("Time")
val updatedAt = timestamp("UpdatedAt").defaultExpression(CurrentTimestamp)
val bestTime = bool("BestTime")
override val primaryKey = PrimaryKey(userId, name)
init {
addIdColumn(userId)
}
}
class Leaderboard(id: EntityID<CompositeID>) : CompositeEntity(id) {
companion object : CompositeEntityClass<Leaderboard>(LeaderboardTable) {
@JvmStatic
fun getLeaderboard(name: String) = useDb {
find { LeaderboardTable.name eq name }.orderBy(LeaderboardTable.time to SortOrder.ASC).limit(5).toList()
}
@JvmStatic
fun getPlayerTime(user: SteamwarUser, name: String) = useDb {
find { (LeaderboardTable.userId eq user.id.value) and (LeaderboardTable.name eq name) }.firstOrNull()
}
@JvmStatic
fun getPlayerPlacement(user: SteamwarUser, name: String) = useDb {
LeaderboardTable.select(LeaderboardTable.time.count())
.where {
(LeaderboardTable.name eq name) and (LeaderboardTable.time lessSubQuery LeaderboardTable.select(
LeaderboardTable.time
).where { (LeaderboardTable.userId eq user.id.value) and (LeaderboardTable.name eq name) })
}
.firstOrNull()?.get(LeaderboardTable.time.count())?.toInt() ?: Int.MAX_VALUE
}
@JvmStatic
fun upsert(userId: Int, name: String, time: Long, bestTime: Boolean) = useDb {
LeaderboardTable.upsert(
onUpdateExclude = listOf(LeaderboardTable.updatedAt, LeaderboardTable.userId, LeaderboardTable.name)
) {
it[LeaderboardTable.userId] = userId
it[LeaderboardTable.name] = name
it[LeaderboardTable.time] = time
it[LeaderboardTable.bestTime] = bestTime
}
}
}
val user by LeaderboardTable.userId.transform({ EntityID(it, SteamwarUserTable) }, { it.value })
val name by LeaderboardTable.name
var time by LeaderboardTable.time
var updatedAt by LeaderboardTable.updatedAt
var bestTime by LeaderboardTable.bestTime
}
@@ -55,6 +55,17 @@ class NodeMember(id: EntityID<CompositeID>) : CompositeEntity(id) {
getNodeMember(node, member) ?: throw IllegalStateException("NodeMember not created") getNodeMember(node, member) ?: throw IllegalStateException("NodeMember not created")
} }
@JvmStatic
fun createNodeMember(node: Int, member: Int, parent: SchematicNode): NodeMember = useDb {
if (!parent.isDir()) throw IllegalStateException("Parent must be a directory")
NodeMemberTable.insertIgnore {
it[this.node] = EntityID(node, SchematicNodeTable)
it[this.userId] = EntityID(member, SteamwarUserTable)
it[NodeMemberTable.parentNode] = parent.getId()
}
getNodeMember(node, member) ?: throw IllegalStateException("NodeMember not created")
}
@JvmStatic @JvmStatic
fun createNodeMember(node: Int, member: SteamwarUser) = createNodeMember(node, member.id.value) fun createNodeMember(node: Int, member: SteamwarUser) = createNodeMember(node, member.id.value)
@@ -81,6 +92,7 @@ class NodeMember(id: EntityID<CompositeID>) : CompositeEntity(id) {
var parent by NodeMemberTable.parentNode.transform( var parent by NodeMemberTable.parentNode.transform(
{ it.map { EntityID(it, SchematicNodeTable) }.getOrNull() }, { it.map { EntityID(it, SchematicNodeTable) }.getOrNull() },
{ Optional.ofNullable(it?.value) }) { Optional.ofNullable(it?.value) })
private set
fun setParentId(id: Int?) { fun setParentId(id: Int?) {
parent = Optional.ofNullable(id) parent = Optional.ofNullable(id)
@@ -1,78 +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.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
}
@@ -179,6 +179,14 @@ class Punishment(id: EntityID<Int>) : IntEntity(id) {
"UNNOTEAMSERVER", "UNNOTEAMSERVER",
UserPerm.MODERATION UserPerm.MODERATION
), ),
NoEvent(
"NOEVENT_TEAM",
"NOEVENT_PERMA",
"NOEVENT_UNTIL",
"NOEVENT_ERROR",
"UNNOEVENT",
UserPerm.MODERATION
),
Note("NOTE_TEAM", null, null, null, null, UserPerm.PUNISHMENTS, true); Note("NOTE_TEAM", null, null, null, null, UserPerm.PUNISHMENTS, true);
fun isMulti() = multi fun isMulti() = multi
@@ -314,7 +314,7 @@ class SchematicNode(id: EntityID<Int>) : IntEntity(id) {
parentNodeId = value?.let { EntityID(it, SchematicNodeTable) } parentNodeId = value?.let { EntityID(it, SchematicNodeTable) }
} }
val parentNode: SchematicNode? val parentNode: SchematicNode?
get() = parent?.let { findById(it) } get() = useDb { parent?.let { findById(it) } }
val optionalParent: Optional<Int> get() = Optional.ofNullable(parent) val optionalParent: Optional<Int> get() = Optional.ofNullable(parent)
var lastUpdate by SchematicNodeTable.lastUpdate.transform({ it.toInstant() }, { Timestamp.from(it) }) var lastUpdate by SchematicNodeTable.lastUpdate.transform({ it.toInstant() }, { Timestamp.from(it) })
+1 -1
View File
@@ -33,7 +33,7 @@ object TeamTable : IntIdTable("Team", "TeamID") {
val name = varchar("TeamName", 16) val name = varchar("TeamName", 16)
val deleted = bool("TeamDeleted").default(false) val deleted = bool("TeamDeleted").default(false)
val address = text("Address").nullable() val address = text("Address").nullable()
val port = ushort("Port") val port = ushort("Port").default(25565u)
} }
class Team(id: EntityID<Int>) : IntEntity(id) { class Team(id: EntityID<Int>) : IntEntity(id) {
@@ -27,9 +27,7 @@ import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.bukkit.BukkitWorld; import com.sk89q.worldedit.bukkit.BukkitWorld;
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.extent.clipboard.io.BuiltInClipboardFormat; import com.sk89q.worldedit.extent.clipboard.io.*;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter;
import com.sk89q.worldedit.extent.clipboard.io.SpongeSchematicReader;
import com.sk89q.worldedit.function.operation.ForwardExtentCopy; import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
import com.sk89q.worldedit.function.operation.Operations; import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
@@ -120,7 +118,12 @@ public class WorldeditWrapper14 implements WorldeditWrapper {
@Override @Override
public Clipboard loadChar(String charName) throws IOException { public Clipboard loadChar(String charName) throws IOException {
return new SpongeSchematicReader(new NBTInputStream(new GZIPInputStream(new FileInputStream(new File(FightSystem.getPlugin().getDataFolder(), "text/" + charName + ".schem"))))).read(); File file = new File(FightSystem.getPlugin().getDataFolder(), "text/" + charName + ".schem");
Clipboard clipboard;
try (ClipboardReader reader = Objects.requireNonNull(ClipboardFormats.findByFile(file)).getReader(new FileInputStream(file))) {
clipboard = reader.read();
}
return clipboard;
} }
@Override @Override
@@ -203,13 +203,23 @@ public class FightSchematic extends StateDependent {
for(int i = 0; i < chars.length; i++){ for(int i = 0; i < chars.length; i++){
Clipboard character; Clipboard character;
try { try {
character = WorldeditWrapper.impl.loadChar(chars[i] == '/' ? "slash" : String.valueOf(chars[i])); if (Character.isLowerCase(chars[i])) {
character = WorldeditWrapper.impl.loadChar("lower/" + chars[i]);
} else if (Character.isUpperCase(chars[i])) {
character = WorldeditWrapper.impl.loadChar("upper/" + chars[i]);
} else {
character = WorldeditWrapper.impl.loadChar(chars[i] == '/' ? "slash" : String.valueOf(chars[i]));
}
} catch (IOException e) { } catch (IOException e) {
Bukkit.getLogger().log(Level.WARNING, "Could not display character {} due to missing file!", chars[i]);
try { try {
character = WorldeditWrapper.impl.loadChar(""); character = WorldeditWrapper.impl.loadChar(chars[i] == '/' ? "slash" : String.valueOf(chars[i]));
}catch (IOException ex) { } catch (IOException ex) {
throw new SecurityException("Could not load text", ex); Bukkit.getLogger().log(Level.WARNING, "Could not display character {} due to missing file!", chars[i]);
try {
character = WorldeditWrapper.impl.loadChar("");
}catch (IOException exc) {
throw new SecurityException("Could not load text", exc);
}
} }
} }
+12
View File
@@ -50,6 +50,18 @@ tasks.register<FightServer>("WarGear20") {
config = "WarGear20.yml" config = "WarGear20.yml"
} }
tasks.register<FightServer>("HalloweenWS") {
group = "run"
description = "Run a Halloween 1.21 Fight Replay Server"
dependsOn(":SpigotCore:shadowJar")
dependsOn(":FightSystem:shadowJar")
template = "HalloweenWS"
worldName = "arenas/Lucifus"
config = "HalloweenWS.yml"
replay = 179786
jar = "/jars/paper-1.21.6.jar"
}
tasks.register<FightServer>("WarGear21") { tasks.register<FightServer>("WarGear21") {
group = "run" group = "run"
description = "Run a WarGear 1.21 Fight Server" description = "Run a WarGear 1.21 Fight Server"
@@ -22,8 +22,9 @@ package de.steamwar.lobby.boatrace;
import de.steamwar.entity.REntity; import de.steamwar.entity.REntity;
import de.steamwar.entity.REntityServer; import de.steamwar.entity.REntityServer;
import de.steamwar.lobby.LobbySystem; import de.steamwar.lobby.LobbySystem;
import de.steamwar.lobby.util.Leaderboard; import de.steamwar.lobby.util.LeaderboardManager;
import de.steamwar.sql.UserConfig; import de.steamwar.sql.Leaderboard;
import de.steamwar.sql.SteamwarUser;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Sound; import org.bukkit.Sound;
@@ -43,16 +44,18 @@ import org.bukkit.scheduler.BukkitTask;
import java.util.EventListener; import java.util.EventListener;
import static de.steamwar.lobby.util.Leaderboard.renderTime; import static de.steamwar.lobby.util.LeaderboardManager.renderTime;
public class BoatRace implements EventListener, Listener { public class BoatRace implements EventListener, Listener {
private static final String CONFIG_KEY = "lobby@boatrace";
private static final double MIN_HEIGHT = 4.3; private static final double MIN_HEIGHT = 4.3;
public static final REntityServer boatNpcServer; public static final REntityServer boatNpcServer;
private static boolean oneNotStarted = false; private static boolean oneNotStarted = false;
private static final Leaderboard leaderboard; private static final LeaderboardManager leaderboard;
static { static {
boatNpcServer = new REntityServer(); boatNpcServer = new REntityServer();
@@ -65,7 +68,7 @@ public class BoatRace implements EventListener, Listener {
new BoatRace(player); new BoatRace(player);
} }
}); });
leaderboard = new Leaderboard(boatNpcServer, "lobby@boatrace", BoatRacePositions.LEADERBOARD, 5); leaderboard = new LeaderboardManager(boatNpcServer, CONFIG_KEY, BoatRacePositions.LEADERBOARD);
} }
private final Player player; private final Player player;
@@ -123,12 +126,11 @@ public class BoatRace implements EventListener, Listener {
HandlerList.unregisterAll(this); HandlerList.unregisterAll(this);
task.cancel(); task.cancel();
LobbySystem.getMessage().send("BOAT_RACE_TIME", player, renderTime(time)); LobbySystem.getMessage().send("BOAT_RACE_TIME", player, renderTime(time));
String conf = UserConfig.getConfig(player.getUniqueId(), "lobby@boatrace"); SteamwarUser user = SteamwarUser.get(player.getUniqueId());
long best = Long.parseLong(conf == null ? String.valueOf(Long.MAX_VALUE) : conf); long best = leaderboard.getPlayerTime(user);
if (time < best) { if (time < best) {
LobbySystem.getMessage().send("BOAT_RACE_NEW_BEST", player); LobbySystem.getMessage().send("BOAT_RACE_NEW_BEST", player);
UserConfig.updatePlayerConfig(player.getUniqueId(), "lobby@boatrace", String.valueOf(time)); leaderboard.updateBestTime(user, time);
leaderboard.update();
} }
} else { } else {
player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 1); player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 1);
@@ -22,8 +22,8 @@ package de.steamwar.lobby.jumpandrun;
import de.steamwar.linkage.Linked; import de.steamwar.linkage.Linked;
import de.steamwar.lobby.LobbySystem; import de.steamwar.lobby.LobbySystem;
import de.steamwar.lobby.listener.PlayerSpawn; import de.steamwar.lobby.listener.PlayerSpawn;
import de.steamwar.lobby.util.Leaderboard; import de.steamwar.lobby.util.LeaderboardManager;
import de.steamwar.sql.UserConfig; import de.steamwar.sql.SteamwarUser;
import net.md_5.bungee.api.ChatMessageType; import net.md_5.bungee.api.ChatMessageType;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
@@ -45,7 +45,7 @@ import java.util.*;
@Linked @Linked
public class JumpAndRun implements Listener { public class JumpAndRun implements Listener {
public static final String JUMP_AND_RUN_CONFIG = "jump_and_run"; public static final String JUMP_AND_RUN_CONFIG = "jump_and_run@winter25";
private static final String BAR_EMPTY = "||||||||||||||||||||||||||||||"; private static final String BAR_EMPTY = "||||||||||||||||||||||||||||||";
@@ -58,7 +58,7 @@ public class JumpAndRun implements Listener {
private static final Map<Player, Long> CLICKED = new HashMap<>(); private static final Map<Player, Long> CLICKED = new HashMap<>();
private static final Map<Player, Integer> CLICKED_COUNT = new HashMap<>(); private static final Map<Player, Integer> CLICKED_COUNT = new HashMap<>();
private static final Leaderboard LEADERBOARD = new Leaderboard(LobbySystem.getEntityServer(false), JUMP_AND_RUN_CONFIG, new Location(Bukkit.getWorlds().get(0), 2338.5, 42.5, 1231.5), 5); private static final LeaderboardManager LEADERBOARD = new LeaderboardManager(LobbySystem.getEntityServer(false), JUMP_AND_RUN_CONFIG, new Location(Bukkit.getWorlds().get(0), 2338.5, 42.5, 1231.5));
{ {
Bukkit.getScheduler().runTaskTimer(LobbySystem.getInstance(), () -> { Bukkit.getScheduler().runTaskTimer(LobbySystem.getInstance(), () -> {
@@ -161,18 +161,14 @@ public class JumpAndRun implements Listener {
} }
private void updateJumpAndRunTime(Player player, long time) { private void updateJumpAndRunTime(Player player, long time) {
String jumpAndRunTimeConfig = UserConfig.getConfig(player.getUniqueId(), JUMP_AND_RUN_CONFIG); long best = LEADERBOARD.getPlayerTime(SteamwarUser.get(player.getUniqueId()));
if (jumpAndRunTimeConfig == null) { if (time < best) {
UserConfig.updatePlayerConfig(player.getUniqueId(), JUMP_AND_RUN_CONFIG, time + ""); if (best != Long.MAX_VALUE) {
} else {
long jumpAndRunTime = Long.parseLong(jumpAndRunTimeConfig);
if (time < jumpAndRunTime) {
SimpleDateFormat format = new SimpleDateFormat(LobbySystem.getMessage().parse("JUMP_AND_RUN_TIME", player), Locale.ROOT); SimpleDateFormat format = new SimpleDateFormat(LobbySystem.getMessage().parse("JUMP_AND_RUN_TIME", player), Locale.ROOT);
String parsed = format.format(new Date(jumpAndRunTime - time)); String parsed = format.format(new Date(best - time));
LobbySystem.getMessage().sendPrefixless("JUMP_AND_RUN_PERSONAL_BEST", player, parsed); LobbySystem.getMessage().sendPrefixless("JUMP_AND_RUN_PERSONAL_BEST", player, parsed);
UserConfig.updatePlayerConfig(player.getUniqueId(), JUMP_AND_RUN_CONFIG, time + "");
LEADERBOARD.update();
} }
LEADERBOARD.updateBestTime(SteamwarUser.get(player.getUniqueId()), time);
} }
} }
@@ -97,9 +97,10 @@ public class Present {
folder = null; folder = null;
} }
} }
NodeMember nodeMember = NodeMember.createNodeMember(schematicId, user.getId());
if (folder != null) { if (folder != null) {
nodeMember.setParent(Optional.of(folder.getId())); NodeMember.createNodeMember(schematicId, user.getId(), folder);
} else {
NodeMember.createNodeMember(schematicId, user.getId());
} }
LobbySystem.getMessage().send("ADVENT_CALENDAR_OPEN", player, node.getName()); LobbySystem.getMessage().send("ADVENT_CALENDAR_OPEN", player, node.getName());
player.playSound(location, Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 1); player.playSound(location, Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 1);
@@ -23,9 +23,8 @@ import de.steamwar.entity.RArmorStand;
import de.steamwar.entity.REntity; import de.steamwar.entity.REntity;
import de.steamwar.entity.REntityServer; import de.steamwar.entity.REntityServer;
import de.steamwar.lobby.LobbySystem; import de.steamwar.lobby.LobbySystem;
import de.steamwar.sql.Leaderboard;
import de.steamwar.sql.SteamwarUser; import de.steamwar.sql.SteamwarUser;
import de.steamwar.sql.internal.Statement;
import lombok.AllArgsConstructor;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@@ -39,25 +38,18 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
public class Leaderboard implements Listener { public class LeaderboardManager implements Listener {
private static final Statement LEADERBOARD = new Statement("SELECT User, CAST(Value as integer) AS Time from UserConfig WHERE Config = ? ORDER BY CAST(Value as integer) ASC LIMIT ?");
private static final Statement PLAYER_TIME = new Statement("SELECT CAST(Value as integer) AS Time FROM UserConfig WHERE Config = ? AND User = ?");
private static final Statement PLAYER_PLACEMENT = new Statement("SELECT COUNT(*) AS Placement FROM UserConfig WHERE Config = ? AND CAST(Value as integer) < (SELECT CAST(Value as integer) AS Time FROM UserConfig WHERE Config = ? AND User = ?)");
private final REntityServer server; private final REntityServer server;
private final String configKey; private final String configKey;
private final Location location; private final Location location;
private final int best;
private long bestTime; private long bestTime;
private final List<REntity> entities = new ArrayList<>(); private final List<REntity> entities = new ArrayList<>();
private final Map<Integer, REntityServer> playerPlacements = new HashMap<>(); private final Map<Integer, REntityServer> playerPlacements = new HashMap<>();
public Leaderboard(REntityServer server, String configKey, Location location, int best) { public LeaderboardManager(REntityServer server, String configKey, Location location) {
this.server = server; this.server = server;
this.configKey = configKey; this.configKey = configKey;
this.location = location; this.location = location;
this.best = best;
Bukkit.getPluginManager().registerEvents(this, LobbySystem.getInstance()); Bukkit.getPluginManager().registerEvents(this, LobbySystem.getInstance());
update(); update();
} }
@@ -65,20 +57,23 @@ public class Leaderboard implements Listener {
public void update() { public void update() {
entities.forEach(REntity::die); entities.forEach(REntity::die);
entities.clear(); entities.clear();
List<LeaderboardEntry> leaderboard = getLeaderboard(); List<Leaderboard> leaderboard = getLeaderboard();
if (leaderboard.isEmpty()) return; if (leaderboard.isEmpty()) {
bestTime = leaderboard.get(0).time; bestTime = Long.MAX_VALUE;
return;
}
bestTime = leaderboard.get(0).getTime();
for (int i = 0; i < leaderboard.size(); i++) { for (int i = 0; i < leaderboard.size(); i++) {
LeaderboardEntry entry = leaderboard.get(i); Leaderboard entry = leaderboard.get(i);
RArmorStand entity = new RArmorStand(server, location.clone().add(0, (leaderboard.size() - i - 1) * 0.32, 0), RArmorStand.Size.MARKER); RArmorStand entity = new RArmorStand(server, location.clone().add(0, (leaderboard.size() - i - 1) * 0.32, 0), RArmorStand.Size.MARKER);
SteamwarUser user = SteamwarUser.byId(entry.user); SteamwarUser user = SteamwarUser.byId(entry.getUser());
String color = "§7"; String color = "§7";
if (i == 0) { if (i == 0) {
color = "§6§l"; color = "§6§l";
} else if (i < 3) { } else if (i < 3) {
color = "§e"; color = "§e";
} }
entity.setDisplayName(calcName(user, color, i + 1, entry.time)); entity.setDisplayName(calcName(user, color, i + 1, entry.getTime()));
entity.setInvisible(true); entity.setInvisible(true);
entities.add(entity); entities.add(entity);
} }
@@ -135,32 +130,27 @@ public class Leaderboard implements Listener {
return st.toString(); return st.toString();
} }
private List<LeaderboardEntry> getLeaderboard() { private boolean isNewBestTime(long time) {
return LEADERBOARD.select(resultSet -> { return time < bestTime;
List<LeaderboardEntry> leaderboard = new ArrayList<>();
while (resultSet.next()) {
leaderboard.add(new LeaderboardEntry(resultSet.getInt("User"), resultSet.getLong("Time")));
}
return leaderboard;
}, configKey, best);
} }
private long getPlayerTime(SteamwarUser user) { public void updateBestTime(SteamwarUser user, long time) {
return PLAYER_TIME.select(resultSet -> { Leaderboard.upsert(user.getId(), configKey, time, isNewBestTime(time));
if (!resultSet.next()) { update();
return Long.MAX_VALUE; }
}
return resultSet.getLong("Time"); private List<Leaderboard> getLeaderboard() {
}, configKey, user.getId()); return Leaderboard.getLeaderboard(configKey);
}
public long getPlayerTime(SteamwarUser user) {
Leaderboard lb = Leaderboard.getPlayerTime(user, configKey);
if(lb != null) return lb.getTime();
return Long.MAX_VALUE;
} }
private int getPlayerPlacement(SteamwarUser user) { private int getPlayerPlacement(SteamwarUser user) {
return PLAYER_PLACEMENT.select(resultSet -> { return Leaderboard.getPlayerPlacement(user, configKey);
if (!resultSet.next()) {
return Integer.MAX_VALUE;
}
return resultSet.getInt("Placement");
}, configKey, configKey, user.getId());
} }
public static String renderTime(long time) { public static String renderTime(long time) {
@@ -178,13 +168,6 @@ public class Leaderboard implements Listener {
time % 1000); time % 1000);
} }
@AllArgsConstructor
private class LeaderboardEntry {
private final int user;
private final long time;
}
@EventHandler @EventHandler
public void onPlayerJoin(PlayerJoinEvent event) { public void onPlayerJoin(PlayerJoinEvent event) {
SteamwarUser steamwarUser = SteamwarUser.get(event.getPlayer().getUniqueId()); SteamwarUser steamwarUser = SteamwarUser.get(event.getPlayer().getUniqueId());
@@ -300,10 +300,10 @@ public class FlatteningWrapper14 implements FlatteningWrapper.IFlatteningWrapper
return head; return head;
} }
private static final Class<?> entityPose = Reflection.getClass("net.minecraft.world.entity.Pose"); protected static final Class<?> entityPose = Reflection.getClass("net.minecraft.world.entity.Pose");
private static final Object standing = entityPose.getEnumConstants()[0]; protected static final Object standing = entityPose.getEnumConstants()[0];
private static final Object swimming = entityPose.getEnumConstants()[3]; protected static final Object swimming = entityPose.getEnumConstants()[3];
private static final Object sneaking = entityPose.getEnumConstants()[5]; protected static final Object sneaking = entityPose.getEnumConstants()[5];
@Override @Override
public Object getPose(FlatteningWrapper.EntityPose pose) { public Object getPose(FlatteningWrapper.EntityPose pose) {
switch (pose) { switch (pose) {
@@ -37,6 +37,7 @@ dependencies {
compileOnly(libs.paperapi21) compileOnly(libs.paperapi21)
compileOnly(libs.nms21) compileOnly(libs.nms21)
compileOnly(libs.authlib2)
compileOnly(libs.datafixer) compileOnly(libs.datafixer)
compileOnly(libs.netty) compileOnly(libs.netty)
compileOnly(libs.authlib) compileOnly(libs.authlib)
@@ -43,4 +43,11 @@ public class FlatteningWrapper21 extends FlatteningWrapper14 implements Flatteni
}); });
return head; return head;
} }
protected static final Object shooting = entityPose.getEnumConstants()[16];
@Override
public Object getPose(FlatteningWrapper.EntityPose pose) {
if (pose == FlatteningWrapper.EntityPose.SHOOTING) return shooting;
return super.getPose(pose);
}
} }
@@ -21,46 +21,31 @@ package de.steamwar.core;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import com.mojang.datafixers.util.Pair; import com.mojang.datafixers.util.Pair;
import de.steamwar.Reflection;
import net.minecraft.Util;
import net.minecraft.network.protocol.game.ClientboundPlayerInfoRemovePacket; import net.minecraft.network.protocol.game.ClientboundPlayerInfoRemovePacket;
import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket; import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket;
import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.GameType; import net.minecraft.world.level.GameType;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import java.util.Collections; import java.util.Collections;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.List;
import java.util.function.LongSupplier;
public class ProtocolWrapper21 implements ProtocolWrapper { public class ProtocolWrapper21 implements ProtocolWrapper {
private static final Reflection.Field<List> equipmentStack = Reflection.getField(equipmentPacket, List.class, 0);
@Override @Override
public void setEquipmentPacketStack(Object packet, Object slot, Object stack) { public void setEquipmentPacketStack(Object packet, Object slot, Object stack) {
equipmentStack.set(packet, Collections.singletonList(new Pair<>(slot, stack))); ClientboundSetEquipmentPacket setEquipmentPacket = (ClientboundSetEquipmentPacket) packet;
setEquipmentPacket.getSlots().add(Pair.of((EquipmentSlot) slot, (ItemStack) stack));
} }
private static final Reflection.Constructor removePacketConstructor = Reflection.getConstructor(ClientboundPlayerInfoRemovePacket.class, List.class);
@Override @Override
@SuppressWarnings("deprecation")
public Object playerInfoPacketConstructor(PlayerInfoAction action, GameProfile profile, GameMode mode) { public Object playerInfoPacketConstructor(PlayerInfoAction action, GameProfile profile, GameMode mode) {
if(action == PlayerInfoAction.REMOVE) if(action == PlayerInfoAction.REMOVE)
return removePacketConstructor.invoke(Collections.singletonList(profile.getId())); return new ClientboundPlayerInfoRemovePacket(Collections.singletonList(profile.getId()));
return switch (action) {
case ADD -> new ClientboundPlayerInfoUpdatePacket(EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER, ClientboundPlayerInfoUpdatePacket.Action.UPDATE_GAME_MODE), new ClientboundPlayerInfoUpdatePacket.Entry(
profile.getId(), profile, true, 0, GameType.byId(mode.getValue()), null, true, 0, null
));
case GAMEMODE -> new ClientboundPlayerInfoUpdatePacket(EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_GAME_MODE), new ClientboundPlayerInfoUpdatePacket.Entry(
profile.getId(), profile, true, 0, GameType.byId(mode.getValue()), null, true, 0, null
));
default -> null;
};
}
@Override return new ClientboundPlayerInfoUpdatePacket(action == PlayerInfoAction.ADD ?
public void initTPSWarp(LongSupplier longSupplier) { EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER, ClientboundPlayerInfoUpdatePacket.Action.UPDATE_GAME_MODE) : EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_GAME_MODE),
Util.timeSource = () -> System.nanoTime() + longSupplier.getAsLong(); Collections.singletonList(new ClientboundPlayerInfoUpdatePacket.Entry(profile.getId(), profile, false, 0, GameType.byId(mode.getValue()), null, false, 0, null)));
} }
} }
@@ -19,6 +19,7 @@
package de.steamwar.core; package de.steamwar.core;
import com.mojang.authlib.properties.Property;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
@@ -40,4 +41,9 @@ public class TrickyTrialsWrapper21 implements TrickyTrialsWrapper {
public Material getTurtleScute() { public Material getTurtleScute() {
return Material.TURTLE_SCUTE; return Material.TURTLE_SCUTE;
} }
@Override
public String getValue(Property property) {
return property.value();
}
} }
@@ -19,7 +19,6 @@
package de.steamwar.core; package de.steamwar.core;
import com.fastasyncworldedit.core.extent.clipboard.io.FastSchematicReaderV2;
import com.sk89q.jnbt.NBTInputStream; import com.sk89q.jnbt.NBTInputStream;
import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.extent.clipboard.Clipboard;
@@ -37,7 +36,11 @@ import org.bukkit.entity.Player;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import org.enginehub.linbus.stream.LinBinaryIO; import org.enginehub.linbus.stream.LinBinaryIO;
import java.io.*; import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
public class WorldEditWrapper21 implements WorldEditWrapper { public class WorldEditWrapper21 implements WorldEditWrapper {
@@ -68,12 +71,58 @@ public class WorldEditWrapper21 implements WorldEditWrapper {
@Override @Override
@SuppressWarnings("removal") @SuppressWarnings("removal")
public Clipboard getClipboard(InputStream is, NodeData.SchematicFormat schemFormat) throws IOException { public Clipboard getClipboard(InputStream is, NodeData.SchematicFormat ignored) throws IOException {
return switch (schemFormat) { ResetableInputStream ris = new ResetableInputStream(is);
case MCEDIT -> new MCEditSchematicReader(new NBTInputStream(is)).read(); for (NodeData.SchematicFormat schemFormat : NodeData.SchematicFormat.values()) {
case SPONGE_V2 -> new SpongeSchematicV2Reader(LinBinaryIO.read(new DataInputStream(is))).read(); try {
case SPONGE_V3 -> new SpongeSchematicV3Reader(LinBinaryIO.read(new DataInputStream(is))).read(); Clipboard clipboard = switch (schemFormat) {
}; case MCEDIT -> new MCEditSchematicReader(new NBTInputStream(ris)).read();
case SPONGE_V2 -> new SpongeSchematicV2Reader(LinBinaryIO.read(new DataInputStream(ris))).read();
case SPONGE_V3 -> new SpongeSchematicV3Reader(LinBinaryIO.read(new DataInputStream(ris))).read();
};
ris.close();
return clipboard;
} catch (Exception e) {
// Ignore
}
ris.reset();
}
throw new IOException("No clipboard found");
}
private class ResetableInputStream extends InputStream {
private InputStream inputStream;
private int pointer = 0;
private List<Integer> list = new ArrayList<>();
public ResetableInputStream(InputStream in) {
this.inputStream = in;
}
@Override
public int read() throws IOException {
if (pointer >= list.size()) {
int data = inputStream.read();
list.add(data);
pointer++;
return data;
}
int data = list.get(pointer);
pointer++;
return data;
}
@Override
public void reset() throws IOException {
pointer = 0;
}
@Override
public void close() throws IOException {
list.clear();
pointer = -1;
}
} }
@Override @Override
@@ -0,0 +1,73 @@
/*
* 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.core.authlib;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.GameProfileRepository;
import com.mojang.authlib.ProfileLookupCallback;
import de.steamwar.Reflection;
import de.steamwar.sql.SteamwarUser;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.Services;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
public class SteamwarGameProfileRepository21 extends SteamwarGameProfileRepository {
private static final GameProfileRepository fallback;
private static final Reflection.Field<Services> field;
private static final Services current;
static {
Class<?> clazz = MinecraftServer.getServer().getClass();
field = Reflection.getField(clazz, Services.class, 0);
current = field.get(MinecraftServer.getServer());
fallback = current.profileRepository();
}
@Override
public void findProfilesByNames(String[] strings, ProfileLookupCallback profileLookupCallback) {
List<String> unknownNames = new ArrayList<>();
for (String name:strings) {
SteamwarUser user = SteamwarUser.get(name);
if(user == null) {
unknownNames.add(name);
continue;
}
profileLookupCallback.onProfileLookupSucceeded(new GameProfile(user.getUUID(), user.getUserName()));
}
if(!unknownNames.isEmpty()) {
fallback.findProfilesByNames(unknownNames.toArray(new String[0]), profileLookupCallback);
}
}
@Override
public Optional<GameProfile> findProfileByName(String s) {
return fallback.findProfileByName(s);
}
@Override
public void inject() {
Services newServices = new Services(current.sessionService(), current.servicesKeySet(), this, current.profileCache(), current.paperConfigurations());
field.set(MinecraftServer.getServer(), newServices);
}
}
@@ -19,7 +19,9 @@
package de.steamwar.entity; package de.steamwar.entity;
import net.minecraft.network.protocol.game.ClientboundAddEntityPacket;
import net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket; import net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.PositionMoveRotation; import net.minecraft.world.entity.PositionMoveRotation;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
@@ -31,4 +33,21 @@ public class PacketConstructor21 implements PacketConstructor{
PositionMoveRotation rot = new PositionMoveRotation(new Vec3(x, y, z), Vec3.ZERO, pitch, yaw); PositionMoveRotation rot = new PositionMoveRotation(new Vec3(x, y, z), Vec3.ZERO, pitch, yaw);
return new ClientboundTeleportEntityPacket(entityId, rot, Collections.emptySet(), false); return new ClientboundTeleportEntityPacket(entityId, rot, Collections.emptySet(), false);
} }
@Override
public Object createRPlayerSpawn(RPlayer player) {
return new ClientboundAddEntityPacket(
player.entityId,
player.uuid,
player.x,
player.y,
player.z,
player.yaw,
player.pitch,
EntityType.PLAYER,
0,
Vec3.ZERO,
player.headYaw
);
}
} }
@@ -19,6 +19,7 @@
package de.steamwar.core; package de.steamwar.core;
import com.mojang.authlib.properties.Property;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
@@ -40,4 +41,9 @@ public class TrickyTrialsWrapper8 implements TrickyTrialsWrapper {
public Material getTurtleScute() { public Material getTurtleScute() {
return Material.STONE; return Material.STONE;
} }
@Override
public String getValue(Property property) {
return property.getValue();
}
} }
@@ -0,0 +1,72 @@
/*
* 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.core.authlib;
import com.mojang.authlib.Agent;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.GameProfileRepository;
import com.mojang.authlib.ProfileLookupCallback;
import de.steamwar.Reflection;
import de.steamwar.sql.SteamwarUser;
import java.util.ArrayList;
import java.util.List;
public class SteamwarGameProfileRepository8 extends SteamwarGameProfileRepository {
private static final GameProfileRepository fallback;
private static final Object minecraftServer;
private static final Reflection.Field<?> gameProfile;
static {
Class<?> minecraftServerClass = Reflection.getClass("net.minecraft.server.MinecraftServer");
Class<?> gpr = Reflection.getClass("com.mojang.authlib.GameProfileRepository");
gameProfile = Reflection.getField(minecraftServerClass, gpr, 0);
minecraftServer = Reflection.getTypedMethod(minecraftServerClass, "getServer", minecraftServerClass).invoke(null);
fallback = (GameProfileRepository) gameProfile.get(minecraftServer);
}
@Override
public void inject() {
gameProfile.set(minecraftServer, this);
}
@Override
public void findProfilesByNames(String[] strings, Agent agent, ProfileLookupCallback profileLookupCallback) {
if(agent == Agent.SCROLLS) {
fallback.findProfilesByNames(strings, agent, profileLookupCallback);
} else {
List<String> unknownNames = new ArrayList<>();
for (String name:strings) {
SteamwarUser user = SteamwarUser.get(name);
if(user == null) {
unknownNames.add(name);
continue;
}
profileLookupCallback.onProfileLookupSucceeded(new GameProfile(user.getUUID(), user.getUserName()));
}
if(!unknownNames.isEmpty()) {
fallback.findProfilesByNames(unknownNames.toArray(new String[0]), agent, profileLookupCallback);
}
}
}
}
@@ -21,6 +21,12 @@ package de.steamwar.core;
import com.comphenix.tinyprotocol.TinyProtocol; import com.comphenix.tinyprotocol.TinyProtocol;
import de.steamwar.Reflection; import de.steamwar.Reflection;
import de.steamwar.command.*;
import de.steamwar.core.authlib.SteamwarGameProfileRepository;
import de.steamwar.core.events.AntiNocom;
import de.steamwar.core.events.ChattingEvent;
import de.steamwar.core.events.PlayerJoinedEvent;
import de.steamwar.core.events.WorldLoadEvent;
import de.steamwar.command.SWCommandUtils; import de.steamwar.command.SWCommandUtils;
import de.steamwar.command.SWTypeMapperCreator; import de.steamwar.command.SWTypeMapperCreator;
import de.steamwar.command.TabCompletionCache; import de.steamwar.command.TabCompletionCache;
@@ -110,6 +116,9 @@ public class Core extends JavaPlugin {
getServer().getMessenger().registerIncomingPluginChannel(this, "sw:bridge", new NetworkReceiver()); getServer().getMessenger().registerIncomingPluginChannel(this, "sw:bridge", new NetworkReceiver());
getServer().getMessenger().registerOutgoingPluginChannel(this, "sw:bridge"); getServer().getMessenger().registerOutgoingPluginChannel(this, "sw:bridge");
if (Core.getVersion() != 20)
SteamwarGameProfileRepository.impl.inject();
TinyProtocol.init(); TinyProtocol.init();
CheckpointUtils.signalHandler(); CheckpointUtils.signalHandler();
@@ -56,6 +56,8 @@ public class FlatteningWrapper {
public enum EntityPose { public enum EntityPose {
NORMAL, NORMAL,
SNEAKING, SNEAKING,
SWIMMING; SWIMMING,
SHOOTING,
;
} }
} }
@@ -19,11 +19,10 @@
package de.steamwar.core; package de.steamwar.core;
import com.mojang.authlib.properties.Property;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView;
public interface TrickyTrialsWrapper { public interface TrickyTrialsWrapper {
TrickyTrialsWrapper impl = VersionDependent.getVersionImpl(Core.getInstance()); TrickyTrialsWrapper impl = VersionDependent.getVersionImpl(Core.getInstance());
@@ -33,4 +32,6 @@ public interface TrickyTrialsWrapper {
Enchantment getUnbreakingEnchantment(); Enchantment getUnbreakingEnchantment();
Material getTurtleScute(); Material getTurtleScute();
String getValue(Property property);
} }
@@ -1,40 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2025 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.core.authlib;
import de.steamwar.Reflection;
import com.mojang.authlib.GameProfileRepository;
import com.mojang.authlib.yggdrasil.YggdrasilGameProfileRepository;
import de.steamwar.linkage.Linked;
import de.steamwar.linkage.MaxVersion;
import de.steamwar.linkage.api.Enable;
@Linked
@MaxVersion(18)
public class AuthlibInjector implements Enable {
@Override
public void enable() {
Class<?> minecraftServerClass = Reflection.getClass("net.minecraft.server.MinecraftServer");
Reflection.Field<GameProfileRepository> gameProfile = Reflection.getField(minecraftServerClass, GameProfileRepository.class, 0);
Object minecraftServer = Reflection.getTypedMethod(minecraftServerClass, "getServer", minecraftServerClass).invoke(null);
gameProfile.set(minecraftServer, new SteamwarGameProfileRepository((YggdrasilGameProfileRepository) gameProfile.get(minecraftServer)));
}
}
@@ -19,42 +19,12 @@
package de.steamwar.core.authlib; package de.steamwar.core.authlib;
import com.mojang.authlib.Agent;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.GameProfileRepository; import com.mojang.authlib.GameProfileRepository;
import com.mojang.authlib.ProfileLookupCallback; import de.steamwar.core.Core;
import com.mojang.authlib.yggdrasil.YggdrasilGameProfileRepository; import de.steamwar.core.VersionDependent;
import de.steamwar.sql.SteamwarUser;
import java.util.ArrayList; public abstract class SteamwarGameProfileRepository implements GameProfileRepository {
import java.util.List; public static final SteamwarGameProfileRepository impl = VersionDependent.getVersionImpl(Core.getInstance());
public class SteamwarGameProfileRepository implements GameProfileRepository { public abstract void inject();
private final YggdrasilGameProfileRepository fallback;
public SteamwarGameProfileRepository(YggdrasilGameProfileRepository repository) {
fallback = repository;
}
@Override
public void findProfilesByNames(String[] strings, Agent agent, ProfileLookupCallback profileLookupCallback) {
if(agent == Agent.SCROLLS) {
fallback.findProfilesByNames(strings, agent, profileLookupCallback);
} else {
List<String> unknownNames = new ArrayList<>();
for (String name:strings) {
SteamwarUser user = SteamwarUser.get(name);
if(user == null) {
unknownNames.add(name);
continue;
}
profileLookupCallback.onProfileLookupSucceeded(new GameProfile(user.getUUID(), user.getUserName()));
}
if(!unknownNames.isEmpty()) {
fallback.findProfilesByNames(unknownNames.toArray(new String[0]), agent, profileLookupCallback);
}
}
}
} }
@@ -23,7 +23,8 @@ import de.steamwar.core.Core;
import de.steamwar.core.VersionDependent; import de.steamwar.core.VersionDependent;
public interface PacketConstructor { public interface PacketConstructor {
public static final PacketConstructor impl = VersionDependent.getVersionImpl(Core.getInstance()); PacketConstructor impl = VersionDependent.getVersionImpl(Core.getInstance());
Object teleportPacket(int entityId, double x, double y, double z, float yaw, float pitch); Object teleportPacket(int entityId, double x, double y, double z, float yaw, float pitch);
Object createRPlayerSpawn(RPlayer player);
} }
@@ -36,7 +36,7 @@ public class REntity {
private static final Object entityStatusWatcher = BountifulWrapper.impl.getDataWatcherObject(0, Byte.class); private static final Object entityStatusWatcher = BountifulWrapper.impl.getDataWatcherObject(0, Byte.class);
private static final Object sneakingDataWatcher = BountifulWrapper.impl.getDataWatcherObject(Core.getVersion() > 12 ? 6 : 0, FlatteningWrapper.impl.getPose(FlatteningWrapper.EntityPose.NORMAL).getClass()); private static final Object sneakingDataWatcher = BountifulWrapper.impl.getDataWatcherObject(Core.getVersion() > 12 ? 6 : 0, FlatteningWrapper.impl.getPose(FlatteningWrapper.EntityPose.NORMAL).getClass());
private static final Object bowDrawnWatcher = BountifulWrapper.impl.getDataWatcherObject(Core.getVersion() > 12 ? 7 : 6, Byte.class); private static final Object bowDrawnWatcher = Core.getVersion() >= 21 ? BountifulWrapper.impl.getDataWatcherObject(6, FlatteningWrapper.impl.getPose(FlatteningWrapper.EntityPose.NORMAL).getClass()) : BountifulWrapper.impl.getDataWatcherObject(Core.getVersion() > 12 ? 7 : 6, Byte.class);
private static final Object nameWatcher = BountifulWrapper.impl.getDataWatcherObject(2, Core.getVersion() > 12 ? Optional.class : String.class); // Optional<IChatBaseComponent> private static final Object nameWatcher = BountifulWrapper.impl.getDataWatcherObject(2, Core.getVersion() > 12 ? Optional.class : String.class); // Optional<IChatBaseComponent>
private static final Object nameVisibleWatcher = BountifulWrapper.impl.getDataWatcherObject(3, Boolean.class); private static final Object nameVisibleWatcher = BountifulWrapper.impl.getDataWatcherObject(3, Boolean.class);
@@ -58,9 +58,9 @@ public class REntity {
protected double y; protected double y;
@Getter @Getter
protected double z; protected double z;
private byte yaw; protected byte yaw;
private byte pitch; protected byte pitch;
private byte headYaw; protected byte headYaw;
@Getter @Getter
private boolean hidden; private boolean hidden;
@@ -219,7 +219,9 @@ public class REntity {
public void setBowDrawn(boolean drawn, boolean offHand) { public void setBowDrawn(boolean drawn, boolean offHand) {
bowDrawn = drawn; bowDrawn = drawn;
if(Core.getVersion() > 8){ if (Core.getVersion() >= 21) {
server.updateEntity(this, getDataWatcherPacket(bowDrawnWatcher, FlatteningWrapper.impl.getPose(FlatteningWrapper.EntityPose.SHOOTING)));
} else if(Core.getVersion() > 8){
server.updateEntity(this, getDataWatcherPacket(bowDrawnWatcher, (byte) ((drawn ? 1 : 0) + (offHand ? 2 : 0)))); server.updateEntity(this, getDataWatcherPacket(bowDrawnWatcher, (byte) ((drawn ? 1 : 0) + (offHand ? 2 : 0))));
}else{ }else{
server.updateEntity(this, getDataWatcherPacket(entityStatusWatcher, getEntityStatus())); server.updateEntity(this, getDataWatcherPacket(entityStatusWatcher, getEntityStatus()));
@@ -443,12 +445,14 @@ public class REntity {
} }
private static final Reflection.Field<Integer> equipmentEntity = Reflection.getField(ProtocolWrapper.equipmentPacket, int.class, 0); private static final Reflection.Field<Integer> equipmentEntity = Reflection.getField(ProtocolWrapper.equipmentPacket, int.class, 0);
private static final Reflection.Field<List> equipmentSlots = Reflection.getField(ProtocolWrapper.equipmentPacket, List.class, 0);
private static final Class<?> craftItemStack = Reflection.getClass("org.bukkit.craftbukkit.inventory.CraftItemStack"); private static final Class<?> craftItemStack = Reflection.getClass("org.bukkit.craftbukkit.inventory.CraftItemStack");
protected static final Reflection.Method asNMSCopy = Reflection.getTypedMethod(REntity.craftItemStack, "asNMSCopy", ProtocolWrapper.itemStack, ItemStack.class); protected static final Reflection.Method asNMSCopy = Reflection.getTypedMethod(REntity.craftItemStack, "asNMSCopy", ProtocolWrapper.itemStack, ItemStack.class);
protected Object getEquipmentPacket(Object slot, ItemStack stack){ protected Object getEquipmentPacket(Object slot, ItemStack stack){
Object packet = Reflection.newInstance(ProtocolWrapper.equipmentPacket); Object packet = Reflection.newInstance(ProtocolWrapper.equipmentPacket);
equipmentEntity.set(packet, entityId); equipmentEntity.set(packet, entityId);
equipmentSlots.set(packet, new ArrayList<>());
ProtocolWrapper.impl.setEquipmentPacketStack(packet, slot, asNMSCopy.invoke(null, stack)); ProtocolWrapper.impl.setEquipmentPacketStack(packet, slot, asNMSCopy.invoke(null, stack));
return packet; return packet;
} }
@@ -22,10 +22,7 @@ package de.steamwar.entity;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.Property; import com.mojang.authlib.properties.Property;
import de.steamwar.Reflection; import de.steamwar.Reflection;
import de.steamwar.core.BountifulWrapper; import de.steamwar.core.*;
import de.steamwar.core.Core;
import de.steamwar.core.FlatteningWrapper;
import de.steamwar.core.ProtocolWrapper;
import de.steamwar.network.CoreNetworkHandler; import de.steamwar.network.CoreNetworkHandler;
import de.steamwar.network.NetworkSender; import de.steamwar.network.NetworkSender;
import de.steamwar.network.packets.common.PlayerSkinRequestPacket; import de.steamwar.network.packets.common.PlayerSkinRequestPacket;
@@ -82,7 +79,7 @@ public class RPlayer extends REntity {
NetworkSender.sendOrQueue(new PlayerSkinRequestPacket(actualUUID)); NetworkSender.sendOrQueue(new PlayerSkinRequestPacket(actualUUID));
return new Property("textures", null, null); return new Property("textures", null, null);
}); });
if (skinData.getValue() != null) { if (TrickyTrialsWrapper.impl.getValue(skinData) != null) {
GameProfile gameProfile = new GameProfile(uuid, name); GameProfile gameProfile = new GameProfile(uuid, name);
gameProfile.getProperties().put("textures", skinData); gameProfile.getProperties().put("textures", skinData);
return gameProfile; return gameProfile;
@@ -117,10 +114,21 @@ public class RPlayer extends REntity {
packetSink.accept(ProtocolWrapper.impl.playerInfoPacketConstructor(ProtocolWrapper.PlayerInfoAction.REMOVE, saved, GameMode.CREATIVE)); packetSink.accept(ProtocolWrapper.impl.playerInfoPacketConstructor(ProtocolWrapper.PlayerInfoAction.REMOVE, saved, GameMode.CREATIVE));
} }
private static final Class<?> namedSpawnPacket = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundAddPlayerPacket"); private static Class<?> namedSpawnPacket = null;
private static final Function<REntity, Object> namedSpawnPacketGenerator = spawnPacketGenerator(namedSpawnPacket, Core.getVersion() == 8 ? 1 : 0); private static Function<REntity, Object> namedSpawnPacketGenerator = null;
private static final Reflection.Field<UUID> namedSpawnUUID = Reflection.getField(namedSpawnPacket, UUID.class, 0); private static Reflection.Field<UUID> namedSpawnUUID = null;
static {
try {
namedSpawnPacket = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundAddPlayerPacket");
namedSpawnPacketGenerator = spawnPacketGenerator(namedSpawnPacket, Core.getVersion() == 8 ? 1 : 0);
namedSpawnUUID = Reflection.getField(namedSpawnPacket, UUID.class, 0);
} catch (IllegalArgumentException e) { }
}
private Object getNamedSpawnPacket() { private Object getNamedSpawnPacket() {
if (Core.getVersion() >= 21) return PacketConstructor.impl.createRPlayerSpawn(this);
Object packet = namedSpawnPacketGenerator.apply(this); Object packet = namedSpawnPacketGenerator.apply(this);
namedSpawnUUID.set(packet, uuid); namedSpawnUUID.set(packet, uuid);
FlatteningWrapper.impl.setNamedSpawnPacketDataWatcher(packet); FlatteningWrapper.impl.setNamedSpawnPacketDataWatcher(packet);
@@ -30,6 +30,7 @@ import java.io.File;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
public class SQLWrapperImpl implements SQLWrapper<Material> { public class SQLWrapperImpl implements SQLWrapper<Material> {
@@ -45,9 +46,11 @@ public class SQLWrapperImpl implements SQLWrapper<Material> {
@Override @Override
public List<Material> getMaterialWithGreaterBlastResistance(double maxBlastResistance) { public List<Material> getMaterialWithGreaterBlastResistance(double maxBlastResistance) {
return Arrays.stream(Material.values()) Stream<Material> stream = Arrays.stream(Material.values());
.filter(material -> !material.isLegacy()) if (Core.getVersion() > 12) {
.filter(Material::isBlock) stream = stream.filter(material -> !material.isLegacy());
}
return stream.filter(Material::isBlock)
.filter(material -> material.getBlastResistance() > maxBlastResistance) .filter(material -> material.getBlastResistance() > maxBlastResistance)
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
@@ -208,6 +208,14 @@ NOTEAMSERVER_UNTIL=§7You are excluded from §e§lteam servers§7 §euntil {0}§
UNNOTEAMSERVER_ERROR=§cThe player is not excluded from team servers. UNNOTEAMSERVER_ERROR=§cThe player is not excluded from team servers.
UNNOTEAMSERVER=§e{0} §7may now set §e§lteam servers§7 again§8. UNNOTEAMSERVER=§e{0} §7may now set §e§lteam servers§7 again§8.
NOEVENT_TEAM=§e{0} §7was excluded from §e{1} {2} §7from §e§levents§8: §f{3}
NOEVENT_PERMA=§7You are §epermanently§7 excluded from §e§levents§8: §e{0}
NOEVENT_UNTIL=§7You are excluded from §e§levents§7 §euntil {0}§8: §e{1}
NOEVENT_ERROR=§cThe player is not excluded from events.
UNNOEVENT=§e{0} §7may now participate in §e§levents§7 again§8.
NOEVENT_PLAYER_PUNISHED=§7A player in your Team is excluded from §e§levents§8.§7 Your team cannot participate§8.
NOEVENT_INVITED_PUNISHED=§cThe player you invited cannot attend §e§levents§8.§7 If they join your future Event participation will be restricted§8.
NOTE_TEAM=§e{0} §7received a §e§lnote§7 from §e{1} {2}: §f{3} NOTE_TEAM=§e{0} §7received a §e§lnote§7 from §e{1} {2}: §f{3}
#BugCommand #BugCommand
@@ -218,11 +226,6 @@ IGNORE_YOURSELF=§cHow are you going to ignore yourself?
IGNORE_ALREADY=§cYou are already ignoring this player. IGNORE_ALREADY=§cYou are already ignoring this player.
IGNORE_MESSAGE=§7You are now ignoring §e{0}§8. IGNORE_MESSAGE=§7You are now ignoring §e{0}§8.
#PollresultCommand
POLLRESULT_NOPOLL=§cThere is currently no ongoing poll.
POLLRESULT_HEADER=§e{0} players have voted on the question: §7{1}
POLLRESULT_LIST=§e{0}§8: §7{1}
#BauCommand #BauCommand
BAU_ADDMEMBER_USAGE=§8/§7build addmember §8[§eplayer§8] BAU_ADDMEMBER_USAGE=§8/§7build addmember §8[§eplayer§8]
BAU_ADDMEMBER_SELFADD=§cYou don't have to add yourself! BAU_ADDMEMBER_SELFADD=§cYou don't have to add yourself!
@@ -367,12 +370,6 @@ MSG_IGNORED=§cThis player has blocked you!
#PingCommand #PingCommand
PING_RESPONSE=§7Your ping is §c{0}§7 ms! PING_RESPONSE=§7Your ping is §c{0}§7 ms!
#PollCommand
POLL_NO_POLL=§cThere is no ongoing poll.
POLL_NO_ANSWER=§cThis is not an option
POLL_ANSWER_REFRESH=§aYour answer was updated.
POLL_ANSWER_NEW=§aYour answer was registered.
#RCommand #RCommand
R_USAGE=§8/§7r §8[§eanswer§8] R_USAGE=§8/§7r §8[§eanswer§8]
@@ -597,13 +594,6 @@ JOIN_STREAMING=§5Streaming Mode§7 is still active§8.§7 Keep in mind that you
#EventModeListener #EventModeListener
EVENTMODE_KICK=§cYou are not an event participant. EVENTMODE_KICK=§cYou are not an event participant.
#PollSystem
POLL_HEADER=§e§lPoll
POLL_HEADER2=§7Click the answer you like!
POLL_QUESTION=§e{0}
POLL_ANSWER=§7{0}
POLL_ANSWER_HOVER=§eChoose {0}
#TablistManager #TablistManager
TABLIST_PHASE_WEBSITE=§8Website: https://§eSteam§8War.de TABLIST_PHASE_WEBSITE=§8Website: https://§eSteam§8War.de
TABLIST_PHASE_DISCORD=§8Discord: https://§eSteam§8War.de/discord TABLIST_PHASE_DISCORD=§8Discord: https://§eSteam§8War.de/discord
@@ -190,6 +190,14 @@ NOTEAMSERVER_UNTIL=§7Du bist §ebis zum {0} §7vom §e§lTeamserver§7 setzen a
UNNOTEAMSERVER_ERROR=§cDer Spieler ist nicht vom Teamserver setzten ausgeschlossen. UNNOTEAMSERVER_ERROR=§cDer Spieler ist nicht vom Teamserver setzten ausgeschlossen.
UNNOTEAMSERVER=§e{0} §7darf nun wieder §e§lTeamserver§7 setzen§8. UNNOTEAMSERVER=§e{0} §7darf nun wieder §e§lTeamserver§7 setzen§8.
NOEVENT_TEAM=§e{0} §7wurde von §e{1} {2} §7aus §e§lEvents§8 ausgeschlossen: §f{3}
NOEVENT_PERMA=§7Du bist §epermanent§7 von §e§lEvents§8 ausgeschlossen: §e{0}
NOEVENT_UNTIL=§7Du bist §ebis zum {0}§7 von §e§lEvents§7 ausgeschlossen§8: §e{1}
NOEVENT_ERROR=§cDer Spieler ist nicht von Events ausgeschlossen.
UNNOEVENT=§e{0} §7kann nun wieder an §e§lEvents§7 teilnehmen§8.
NOEVENT_PLAYER_PUNISHED=§7Ein Spieler deines Teams ist von §e§lEvents§7 ausgeschlossen§8.§7 Dein Team kann nicht teilnehmen§8.
NOEVENT_INVITED_PUNISHED=§cDer von dir eingeladene Spieler kann nicht an §e§lEvents§7 teilnehmen§8.§7 Wenn er beitritt, wird deine zukünftige Teilnahme an Events eingeschränkt§8.
NOTE_TEAM=§e{0} §7erhielt von §e{1} {2} §7die §e§lNotiz§7§8: §f{3} NOTE_TEAM=§e{0} §7erhielt von §e{1} {2} §7die §e§lNotiz§7§8: §f{3}
#BugCommand #BugCommand
@@ -200,10 +208,6 @@ IGNORE_YOURSELF=§cWie willst du dich selber ignorieren?
IGNORE_ALREADY=§cDu ignorierst diesen Spieler bereits. IGNORE_ALREADY=§cDu ignorierst diesen Spieler bereits.
IGNORE_MESSAGE=§7Du ignorierst nun §e{0}§8. IGNORE_MESSAGE=§7Du ignorierst nun §e{0}§8.
#PollresultCommand
POLLRESULT_NOPOLL=§cDerzeit läuft keine Umfrage.
POLLRESULT_HEADER=§eEs haben {0} abgestimmt auf die Frage: §7{1}
#BauCommand #BauCommand
BAU_ADDMEMBER_USAGE=§8/§7bau addmember §8[§eSpieler§8] BAU_ADDMEMBER_USAGE=§8/§7bau addmember §8[§eSpieler§8]
BAU_ADDMEMBER_SELFADD=§cDu brauchst dich nicht selbst hinzufügen! BAU_ADDMEMBER_SELFADD=§cDu brauchst dich nicht selbst hinzufügen!
@@ -345,12 +349,6 @@ MSG_IGNORED=§cDieser Spieler hat dich geblockt!
#PingCommand #PingCommand
PING_RESPONSE=§7Dein Ping beträgt §c{0}§7 ms! PING_RESPONSE=§7Dein Ping beträgt §c{0}§7 ms!
#PollCommand
POLL_NO_POLL=§cDerzeit läuft keine Umfrage.
POLL_NO_ANSWER=§cDas ist keine Antwortmöglichkeit!
POLL_ANSWER_REFRESH=§aDeine Antwort wurde aktualisiert.
POLL_ANSWER_NEW=§aDeine Antwort wurde registriert.
#RCommand #RCommand
R_USAGE=§8/§7r §8[§eAntwort§8] R_USAGE=§8/§7r §8[§eAntwort§8]
@@ -569,13 +567,6 @@ JOIN_STREAMING=§5Streaming-Modus§7 ist weiterhin aktiv§8.§7 Beachten Sie, da
#EventModeListener #EventModeListener
EVENTMODE_KICK=§cDu bist kein Eventteilnehmer. EVENTMODE_KICK=§cDu bist kein Eventteilnehmer.
#PollSystem
POLL_HEADER=§e§lUmfrage
POLL_HEADER2=§7Klicke die Antwort an, die dir gefällt!
POLL_QUESTION=§e{0}
POLL_ANSWER=§7{0}
POLL_ANSWER_HOVER=§e{0} §ewählen
#TablistManager #TablistManager
TABLIST_FOOTER=§e{0} {1}§8ms §eSpieler§8: §7{2} TABLIST_FOOTER=§e{0} {1}§8ms §eSpieler§8: §7{2}
TABLIST_BAU=§7§lBau TABLIST_BAU=§7§lBau
@@ -68,18 +68,11 @@ public class Config {
private boolean eventmode = false; private boolean eventmode = false;
private Map<String, Server> servers = Collections.emptyMap(); private Map<String, Server> servers = Collections.emptyMap();
private List<String> broadcasts = Collections.emptyList(); private List<String> broadcasts = Collections.emptyList();
private Poll poll = null;
public RegisteredServer lobbyserver() { public RegisteredServer lobbyserver() {
return VelocityCore.getProxy().getServer(lobbyserver).orElseThrow(); return VelocityCore.getProxy().getServer(lobbyserver).orElseThrow();
} }
@Getter
public static class Poll {
private String question;
private List<String> answers;
}
@Getter @Getter
public static class Server { public static class Server {
private int spectatePort = 0; private int spectatePort = 0;
@@ -46,7 +46,6 @@ import de.steamwar.velocitycore.commands.TeamCommand;
import de.steamwar.velocitycore.discord.DiscordBot; import de.steamwar.velocitycore.discord.DiscordBot;
import de.steamwar.velocitycore.discord.DiscordConfig; import de.steamwar.velocitycore.discord.DiscordConfig;
import de.steamwar.velocitycore.listeners.BasicListener; import de.steamwar.velocitycore.listeners.BasicListener;
import de.steamwar.velocitycore.listeners.PollSystem;
import lombok.Getter; import lombok.Getter;
import lombok.NonNull; import lombok.NonNull;
@@ -135,7 +134,6 @@ public class VelocityCore implements ReloadablePlugin {
schedule(TabCompletionCache::invalidateOldEntries).repeat(1, TimeUnit.SECONDS).schedule(); schedule(TabCompletionCache::invalidateOldEntries).repeat(1, TimeUnit.SECONDS).schedule();
initStaticServers(); initStaticServers();
PollSystem.init();
local = new Node.LocalNode(); local = new Node.LocalNode();
if(MAIN_SERVER) { if(MAIN_SERVER) {
@@ -151,6 +149,7 @@ public class VelocityCore implements ReloadablePlugin {
new PunishmentCommand("nodev", Punishment.PunishmentType.NoDevServer); new PunishmentCommand("nodev", Punishment.PunishmentType.NoDevServer);
new PunishmentCommand("nofight", Punishment.PunishmentType.NoFightServer); new PunishmentCommand("nofight", Punishment.PunishmentType.NoFightServer);
new PunishmentCommand("noteamserver", Punishment.PunishmentType.NoTeamServer); new PunishmentCommand("noteamserver", Punishment.PunishmentType.NoTeamServer);
new PunishmentCommand("noevent", Punishment.PunishmentType.NoEvent);
new PunishmentCommand("note", Punishment.PunishmentType.Note); new PunishmentCommand("note", Punishment.PunishmentType.Note);
linker = new AbstractLinker<>(this) { linker = new AbstractLinker<>(this) {
@@ -1,66 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2025 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.velocitycore.commands;
import de.steamwar.linkage.Linked;
import de.steamwar.velocitycore.listeners.PollSystem;
import de.steamwar.command.SWCommand;
import de.steamwar.command.TypeValidator;
import de.steamwar.messages.Chatter;
import de.steamwar.sql.PollAnswer;
@Linked
public class PollCommand extends SWCommand {
public PollCommand() {
super("poll");
}
@Register
public void genericCommand(@Validator Chatter sender) {
PollSystem.sendPoll(sender);
}
@Register(noTabComplete = true)
public void answerPoll(@Validator Chatter sender, String answerString) {
int answer;
try {
answer = Integer.parseUnsignedInt(answerString);
if(answer < 1 || answer > PollSystem.answers())
throw new NumberFormatException();
}catch(NumberFormatException e){
sender.system("POLL_NO_ANSWER");
return;
}
PollAnswer pollAnswer = PollAnswer.get(sender.user().getId());
if(pollAnswer.hasAnswered())
sender.system("POLL_ANSWER_REFRESH");
else
sender.system("POLL_ANSWER_NEW");
pollAnswer.setAnswer(answer);
}
@ClassValidator(value = Chatter.class, local = true)
public TypeValidator<Chatter> noPoll() {
return PollSystem.noPoll();
}
}
@@ -1,52 +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.velocitycore.commands;
import de.steamwar.linkage.Linked;
import de.steamwar.velocitycore.listeners.PollSystem;
import de.steamwar.command.SWCommand;
import de.steamwar.command.TypeValidator;
import de.steamwar.messages.Chatter;
import de.steamwar.sql.PollAnswer;
import de.steamwar.sql.UserPerm;
import java.util.Map;
@Linked
public class PollresultCommand extends SWCommand {
public PollresultCommand() {
super("pollresult", UserPerm.MODERATION);
}
@Register
public void genericCommand(@Validator Chatter sender) {
Map<Integer, Integer> voted = PollAnswer.getCurrentResults();
sender.system("POLLRESULT_HEADER", voted.values().stream().reduce(Integer::sum).orElse(0), PollAnswer.getCurrentPoll());
for (Map.Entry<Integer, Integer> e: voted.entrySet()) {
sender.prefixless("POLLRESULT_LIST", PollSystem.getAnswer(e.getKey()), e.getValue());
}
}
@ClassValidator(value = Chatter.class, local = true)
public TypeValidator<Chatter> noPoll() {
return PollSystem.noPoll();
}
}
@@ -26,10 +26,7 @@ import de.steamwar.command.SWCommand;
import de.steamwar.command.TypeMapper; import de.steamwar.command.TypeMapper;
import de.steamwar.messages.Chatter; import de.steamwar.messages.Chatter;
import de.steamwar.messages.Message; import de.steamwar.messages.Message;
import de.steamwar.sql.BannedUserIPs; import de.steamwar.sql.*;
import de.steamwar.sql.Punishment;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.sql.UserPerm;
import de.steamwar.velocitycore.VelocityCore; import de.steamwar.velocitycore.VelocityCore;
import de.steamwar.velocitycore.listeners.IPSanitizer; import de.steamwar.velocitycore.listeners.IPSanitizer;
@@ -213,6 +210,11 @@ public class PunishmentCommand {
if(punishmentType == Punishment.PunishmentType.Ban) if(punishmentType == Punishment.PunishmentType.Ban)
ban(target, banTime, msg, punisher, isPerma); ban(target, banTime, msg, punisher, isPerma);
Chatter.serverteam().system(punishmentType.getTeamMessage(), target, sender, new Message((isPerma ? "PUNISHMENT_PERMA" : "PUNISHMENT_UNTIL"), banTime), msg); Chatter.serverteam().system(punishmentType.getTeamMessage(), target, sender, new Message((isPerma ? "PUNISHMENT_PERMA" : "PUNISHMENT_UNTIL"), banTime), msg);
if (punishmentType == Punishment.PunishmentType.NoEvent) {
int teamId = target.getTeam();
if (teamId == 0) return;
TeamTeilnahme.deleteFuture(teamId);
}
} }
@Register @Register
@@ -141,6 +141,9 @@ public class TeamCommand extends SWCommand {
user.setTeam(t); user.setTeam(t);
teamInvitations.remove(user.getId()); teamInvitations.remove(user.getId());
sender.system("TEAM_JOIN_JOINED", Team.byId(t).getTeamName()); sender.system("TEAM_JOIN_JOINED", Team.byId(t).getTeamName());
if (user.isPunished(Punishment.PunishmentType.NoEvent)) {
TeamTeilnahme.deleteFuture(t);
}
} }
@Register("stepback") @Register("stepback")
@@ -201,6 +204,9 @@ public class TeamCommand extends SWCommand {
invitations.add(team.getTeamId()); invitations.add(team.getTeamId());
sender.system("TEAM_INVITE_INVITED", target.getUserName()); sender.system("TEAM_INVITE_INVITED", target.getUserName());
if (target.isPunished(Punishment.PunishmentType.NoEvent)) {
sender.system("NOEVENT_INVITED_PUNISHED");
}
Chatter.of(target).system("TEAM_INVITE_INVITED_TARGET", team.getTeamColor(), team.getTeamName()); Chatter.of(target).system("TEAM_INVITE_INVITED_TARGET", team.getTeamColor(), team.getTeamName());
} }
@@ -422,6 +428,12 @@ public class TeamCommand extends SWCommand {
TeamTeilnahme.notTeilnehmen(team.getTeamId(), event.getEventID()); TeamTeilnahme.notTeilnehmen(team.getTeamId(), event.getEventID());
sender.system("TEAM_EVENT_LEFT"); sender.system("TEAM_EVENT_LEFT");
}else{ }else{
if (team.getMembers().stream().anyMatch(integer -> {
return SteamwarUser.get(integer).isPunished(Punishment.PunishmentType.NoEvent);
})) {
sender.system("NOEVENT_PLAYER_PUNISHED");
return;
}
TeamTeilnahme.teilnehmen(team.getTeamId(), event.getEventID()); TeamTeilnahme.teilnehmen(team.getTeamId(), event.getEventID());
sender.system("TEAM_EVENT_JOINED", event.getEventName()); sender.system("TEAM_EVENT_JOINED", event.getEventName());
sender.prefixless("TEAM_EVENT_HOW_TO_LEAVE"); sender.prefixless("TEAM_EVENT_HOW_TO_LEAVE");
@@ -25,9 +25,6 @@ import de.steamwar.sql.Team;
import de.steamwar.sql.TeamTeilnahme; import de.steamwar.sql.TeamTeilnahme;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.emoji.Emoji;
import net.dv8tion.jda.api.interactions.components.ActionRow;
import net.dv8tion.jda.api.interactions.components.selections.StringSelectMenu;
import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder; import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder;
import java.awt.*; import java.awt.*;
@@ -54,12 +51,6 @@ public class EventChannel {
.setTitle("Zukünftige Events") .setTitle("Zukünftige Events")
.setAuthor("SteamWar", "https://www.steamwar.de"); .setAuthor("SteamWar", "https://www.steamwar.de");
StringSelectMenu.Builder menuBuilder = StringSelectMenu.create("eventName")
.setPlaceholder("Wähle ein Event aus!")
.setMinValues(1)
.setMaxValues(1);
Timestamp now = Timestamp.from(Instant.now()); Timestamp now = Timestamp.from(Instant.now());
List<Event> events = Event.getComing(); List<Event> events = Event.getComing();
events.forEach(event -> { events.forEach(event -> {
@@ -73,18 +64,10 @@ public class EventChannel {
st.append("\nAngemeldete Teams: ").append(teilname); st.append("\nAngemeldete Teams: ").append(teilname);
} }
embedBuilder.addField(event.getEventName(), st.toString(), false); embedBuilder.addField(event.getEventName(), st.toString(), false);
if(event.getDeadline().after(Timestamp.from(Instant.now()))) {
menuBuilder.addOption(event.getEventName(), event.getEventID() + "", "An " + event.getEventName() + " teilnehmen", Emoji.fromUnicode("U+1F4DD"));
}
}); });
MessageCreateBuilder messageBuilder = new MessageCreateBuilder() return new MessageCreateBuilder()
.setEmbeds(embedBuilder.build()); .setEmbeds(embedBuilder.build());
if(events.stream().anyMatch(event -> event.getDeadline().after(Timestamp.from(Instant.now())))) {
messageBuilder.setComponents(ActionRow.of(menuBuilder.build()));
}
return messageBuilder;
} }
private MessageCreateBuilder updateCurrent() { private MessageCreateBuilder updateCurrent() {
@@ -1,91 +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.velocitycore.listeners;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.connection.PostLoginEvent;
import de.steamwar.velocitycore.Config;
import de.steamwar.velocitycore.VelocityCore;
import de.steamwar.command.TypeValidator;
import de.steamwar.messages.Chatter;
import de.steamwar.messages.Message;
import de.steamwar.sql.PollAnswer;
import net.kyori.adventure.text.event.ClickEvent;
public class PollSystem extends BasicListener {
public static void init() {
poll = VelocityCore.get().getConfig().getPoll();
if(poll == null)
return;
if(noCurrentPoll())
return;
PollAnswer.setCurrentPoll(poll.getQuestion());
new PollSystem();
}
private static Config.Poll poll = null;
@Subscribe
public void onPostLogin(PostLoginEvent event){
Chatter player = Chatter.of(event.getPlayer());
PollAnswer answer = PollAnswer.get(player.user().getId());
if(answer.hasAnswered())
return;
sendPoll(player);
}
public static void sendPoll(Chatter player) {
player.system("POLL_HEADER");
player.prefixless("POLL_HEADER2");
player.prefixless("POLL_QUESTION", poll.getQuestion());
for(int i = 1; i <= poll.getAnswers().size(); i++) {
player.prefixless("POLL_ANSWER", new Message("POLL_ANSWER_HOVER", poll.getAnswers().get(i-1)), ClickEvent.runCommand("/poll " + i), poll.getAnswers().get(i-1));
}
}
private static boolean noCurrentPoll(){
return poll == null;
}
public static TypeValidator<Chatter> noPoll() {
return (sender, value, messageSender) -> {
if (PollSystem.noCurrentPoll()) {
messageSender.send("POLL_NO_POLL");
return false;
}
return true;
};
}
public static int answers(){
return poll.getAnswers().size();
}
public static String getAnswer(int i) {
return poll.getAnswers().get(i);
}
}
+36
View File
@@ -25,3 +25,39 @@ allprojects {
group = "de.steamwar" group = "de.steamwar"
version = "" version = ""
} }
tasks.register("0_ClearAllGradle") {
group = "run"
description = "Clears the gradle build caches"
doLast {
File("~/.gradle/").deleteRecursively()
}
}
tasks.register("1_ClearGradleBuilds") {
group = "run"
description = "Clears the gradle build caches"
doLast {
File("~/.gradle/build-cache-1/").deleteRecursively()
}
}
tasks.register("2_ClearAllGradleDependencies") {
group = "run"
description = "Clears the dependencies in the .gradle folder"
doLast {
File("~/.gradle/modules-2/files-2.1/").deleteRecursively()
}
}
tasks.register("2_ClearSWGradleDependencies") {
group = "run"
description = "Clears the dependencies in the .gradle folder"
doLast {
File("~/.gradle/modules-2/files-2.1/de.steamwar/").deleteRecursively()
}
}
+1
View File
@@ -113,6 +113,7 @@ dependencyResolutionManagement {
library("paperapi", "io.papermc.paper:paper-api:1.19.2-R0.1-SNAPSHOT") library("paperapi", "io.papermc.paper:paper-api:1.19.2-R0.1-SNAPSHOT")
library("paperapi21", "io.papermc.paper:paper-api:1.21.6-R0.1-SNAPSHOT") library("paperapi21", "io.papermc.paper:paper-api:1.21.6-R0.1-SNAPSHOT")
library("authlib", "com.mojang:authlib:1.5.25") library("authlib", "com.mojang:authlib:1.5.25")
library("authlib2", "com.mojang:authlib:6.0.58")
library("datafixer", "com.mojang:datafixerupper:4.0.26") library("datafixer", "com.mojang:datafixerupper:4.0.26")
library("brigadier", "com.mojang:brigadier:1.0.18") library("brigadier", "com.mojang:brigadier:1.0.18")
library("anvilgui", "net.wesjd:anvilgui:1.10.6-SNAPSHOT") library("anvilgui", "net.wesjd:anvilgui:1.10.6-SNAPSHOT")