Merge branch 'main' into VelocityCore/NoEvent

This commit is contained in:
2025-12-03 14:07:02 +01:00
75 changed files with 675 additions and 917 deletions
@@ -59,7 +59,7 @@ public class BackupCommand extends SWCommand {
if (checkGlobalRegion(region, p)) {
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);
return;
}
@@ -56,8 +56,8 @@ public class BauInfoBauGuiItem extends BauGuiItem {
Region region = Region.getRegion(player.getLocation());
List<String> stringList = new ArrayList<>();
for (Flag flag : Flag.getFlags()) {
if (!region.getFlags().has(flag).isApplicable()) continue;
FlagOptional<?> value = region.getFlags().get(flag);
if (!region.getRegionData().has(flag).isApplicable()) continue;
FlagOptional<?> value = region.getRegionData().get(flag);
if (value.isPresent()) {
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());
Region region = Region.getRegion(p.getLocation());
for (Flag flag : Flag.getFlags()) {
if (!region.getFlags().has(flag).isApplicable()) continue;
FlagOptional<?> value = region.getFlags().get(flag);
if (!region.getRegionData().has(flag).isApplicable()) continue;
FlagOptional<?> value = region.getRegionData().get(flag);
if (value.isPresent()) {
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) {
if (colorizationType == ColorizationType.GLOBAL) {
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));
return;
}
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);
return;
}
region.getFlags().set(Flag.COLOR, color);
region.getRegionData().set(Flag.COLOR, color);
try {
PasteBuilder pasteBuilder = new PasteBuilder(new PasteBuilder.FileProvider(region.getArea().getResetFile()))
.ignoreAir(true)
@@ -53,11 +53,11 @@ public class FireCommand extends SWCommand {
}
private boolean toggle(Region region) {
if (region.getFlags().get(Flag.FIRE).isWithDefault(FireMode.ALLOW)) {
region.getFlags().set(Flag.FIRE, FireMode.DENY);
if (region.getRegionData().get(Flag.FIRE).isWithDefault(FireMode.ALLOW)) {
region.getRegionData().set(Flag.FIRE, FireMode.DENY);
return true;
} else {
region.getFlags().set(Flag.FIRE, FireMode.ALLOW);
region.getRegionData().set(Flag.FIRE, FireMode.ALLOW);
return false;
}
}
@@ -36,12 +36,12 @@ public class FireListener implements Listener, ScoreboardElement {
@EventHandler
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
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
@@ -56,7 +56,7 @@ public class FireListener implements Listener, ScoreboardElement {
@Override
public String get(Region region, Player p) {
if (region.getFlags().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);
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.getRegionData().get(Flag.FIRE).getWithDefault().getChatValue(), p);
}
}
@@ -53,11 +53,11 @@ public class FreezeCommand extends SWCommand {
}
private boolean toggle(Region region) {
if (region.getFlags().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) {
region.getFlags().set(Flag.FREEZE, FreezeMode.INACTIVE);
if (region.getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) {
region.getRegionData().set(Flag.FREEZE, FreezeMode.INACTIVE);
return false;
} else {
region.getFlags().set(Flag.FREEZE, FreezeMode.ACTIVE);
region.getRegionData().set(Flag.FREEZE, FreezeMode.ACTIVE);
return true;
}
}
@@ -48,7 +48,7 @@ public class FreezeListener implements Listener, ScoreboardElement {
@EventHandler
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);
if (e.getEntityType() == TrickyTrialsWrapper.impl.getTntEntityType()) {
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
@@ -60,7 +60,7 @@ public class FreezeListener implements Listener, ScoreboardElement {
@EventHandler
public void onBlockCanBuild(BlockCanBuildEvent e) {
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) {
e.setBuildable(false);
e.getBlock().setType(Material.TNT, false);
@@ -69,14 +69,14 @@ public class FreezeListener implements Listener, ScoreboardElement {
@EventHandler
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);
}
}
@EventHandler
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) {
BlockState state = e.getSourceBlock().getState();
NoteBlock noteBlock = (NoteBlock) state.getBlockData();
@@ -101,44 +101,44 @@ public class FreezeListener implements Listener, ScoreboardElement {
@EventHandler
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);
}
}
@EventHandler
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);
}
}
@EventHandler
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);
}
}
@EventHandler
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());
}
}
@EventHandler
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);
}
}
@EventHandler
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);
} 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);
}
}
@@ -147,7 +147,7 @@ public class FreezeListener implements Listener, ScoreboardElement {
public void onBlockBreak(BlockBreakEvent e) {
if (Core.getVersion() < 19) 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.getBlock().setType(Material.BARRIER, false);
e.getBlock().setType(Material.AIR, false);
@@ -170,35 +170,35 @@ public class FreezeListener implements Listener, ScoreboardElement {
@EventHandler
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);
}
}
@EventHandler
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);
}
}
@EventHandler
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);
}
}
@EventHandler
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);
}
}
@EventHandler
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);
}
}
@@ -206,7 +206,7 @@ public class FreezeListener implements Listener, ScoreboardElement {
@EventHandler
public void onPlayerInteract(PlayerInteractEvent e) {
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();
if (block.getType() == Material.LEVER) {
Switch data = ((Switch) block.getBlockData());
@@ -218,7 +218,7 @@ public class FreezeListener implements Listener, ScoreboardElement {
@EventHandler
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);
}
}
@@ -235,7 +235,7 @@ public class FreezeListener implements Listener, ScoreboardElement {
@Override
public String get(Region region, Player p) {
if (region.getFlags().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);
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.getRegionData().get(Flag.FREEZE).getWithDefault().getChatValue(), p);
}
}
@@ -55,11 +55,11 @@ public class ItemsCommand extends SWCommand {
}
private boolean toggle(Region region) {
if (region.getFlags().get(Flag.ITEMS).isWithDefault(ItemMode.ACTIVE)) {
region.getFlags().set(Flag.ITEMS, ItemMode.INACTIVE);
if (region.getRegionData().get(Flag.ITEMS).isWithDefault(ItemMode.ACTIVE)) {
region.getRegionData().set(Flag.ITEMS, ItemMode.INACTIVE);
return false;
} else {
region.getFlags().set(Flag.ITEMS, ItemMode.ACTIVE);
region.getRegionData().set(Flag.ITEMS, ItemMode.ACTIVE);
return true;
}
}
@@ -37,7 +37,7 @@ public class ItemsListener implements Listener, ScoreboardElement {
@EventHandler
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);
}
}
@@ -54,7 +54,7 @@ public class ItemsListener implements Listener, ScoreboardElement {
@Override
public String get(Region region, Player p) {
if (region.getFlags().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);
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.getRegionData().get(Flag.ITEMS).getWithDefault().getChatValue(), p);
}
}
@@ -53,11 +53,11 @@ public class NoGravityCommand extends SWCommand {
}
private boolean toggle(Region region) {
if (region.getFlags().get(Flag.NO_GRAVITY).isWithDefault(NoGravityMode.ACTIVE)) {
region.getFlags().set(Flag.NO_GRAVITY, NoGravityMode.INACTIVE);
if (region.getRegionData().get(Flag.NO_GRAVITY).isWithDefault(NoGravityMode.ACTIVE)) {
region.getRegionData().set(Flag.NO_GRAVITY, NoGravityMode.INACTIVE);
return false;
} else {
region.getFlags().set(Flag.NO_GRAVITY, NoGravityMode.ACTIVE);
region.getRegionData().set(Flag.NO_GRAVITY, NoGravityMode.ACTIVE);
return true;
}
}
@@ -37,7 +37,7 @@ public class NoGravityListener implements Listener, ScoreboardElement {
@EventHandler
public void onEntitySpawn(EntitySpawnEvent event) {
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);
}
}
@@ -54,7 +54,7 @@ public class NoGravityListener implements Listener, ScoreboardElement {
@Override
public String get(Region region, Player p) {
if (region.getFlags().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);
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.getRegionData().get(Flag.NO_GRAVITY).getWithDefault().getChatValue(), p);
}
}
@@ -39,18 +39,18 @@ public class ProtectCommand extends SWCommand {
public void genericProtectCommand(@Validator Player p) {
Region region = regionCheck(p);
if (region == null) return;
if (region.getFlags().get(Flag.PROTECT).isWithDefault(ProtectMode.ACTIVE)) {
region.getFlags().set(Flag.PROTECT, ProtectMode.INACTIVE);
if (region.getRegionData().get(Flag.PROTECT).isWithDefault(ProtectMode.ACTIVE)) {
region.getRegionData().set(Flag.PROTECT, ProtectMode.INACTIVE);
RegionUtils.actionBar(region, "REGION_PROTECT_DISABLE");
} else {
region.getFlags().set(Flag.PROTECT, ProtectMode.ACTIVE);
region.getRegionData().set(Flag.PROTECT, ProtectMode.ACTIVE);
RegionUtils.actionBar(region, "REGION_PROTECT_ENABLE");
}
}
private Region regionCheck(Player player) {
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);
return null;
}
@@ -41,7 +41,7 @@ public class ProtectListener implements Listener, ScoreboardElement {
private void explode(List<Block> blockList, Location 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 p2 = region.getTestblockArea().getMinPoint(true);
int floorLevel = Math.min(p1.getY(), p2.getY());
@@ -70,7 +70,7 @@ public class ProtectListener implements Listener, ScoreboardElement {
@Override
public String get(Region region, Player p) {
if (region.getFlags().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);
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.getRegionData().get(Flag.PROTECT).getWithDefault().getChatValue(), p);
}
}
@@ -102,7 +102,7 @@ public class RegionCommand extends SWCommand {
try {
PasteBuilder pasteBuilder = new PasteBuilder(new PasteBuilder.FileProvider(region.getArea().getResetFile()))
.ignoreAir(true)
.color(region.getFlags().get(Flag.COLOR).getWithDefault());
.color(region.getRegionData().get(Flag.COLOR).getWithDefault());
region.getArea().reset(pasteBuilder, false);
RegionUtils.message(region, "REGION_REGION_RESTORED");
} catch (SecurityException e) {
@@ -124,7 +124,7 @@ public class RegionCommand extends SWCommand {
try {
PasteBuilder pasteBuilder = new PasteBuilder(new PasteBuilder.SchematicProvider(node))
.ignoreAir(true)
.color(region.getFlags().get(Flag.COLOR).getWithDefault());
.color(region.getRegionData().get(Flag.COLOR).getWithDefault());
region.getArea().reset(pasteBuilder, false);
RegionUtils.message(region, "REGION_REGION_RESTORED");
} catch (SecurityException e) {
@@ -182,6 +182,6 @@ public class RegionListener implements Listener {
}
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;
try {
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.getFlags().clear();
region.getRegionData().clear();
RegionUtils.message(region, "REGION_RESET_RESETED");
} catch (SecurityException e) {
@@ -84,7 +83,7 @@ public class ResetCommand extends SWCommand {
}
try {
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);
RegionUtils.message(region, "REGION_RESET_RESETED");
} catch (SecurityException e) {
@@ -92,7 +92,7 @@ public class TNTCommand extends SWCommand {
@Override
public List<String> tabCompletes(CommandSender sender, PreviousArguments previousArguments, String s) {
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());
} else {
return new ArrayList<>(tntModeMapReduced.keySet());
@@ -102,7 +102,7 @@ public class TNTCommand extends SWCommand {
@Override
public TNTMode map(CommandSender sender, PreviousArguments previousArguments, String s) {
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);
} else {
return tntModeMapReduced.getOrDefault(s, null);
@@ -124,23 +124,23 @@ public class TNTCommand extends SWCommand {
}
private void tntToggle(Region region, TNTMode requestedMode, String requestedMessage) {
if (requestedMode != null && region.getFlags().get(Flag.TESTBLOCK).isNotWithDefault(TestblockMode.NO_VALUE)) {
region.getFlags().set(Flag.TNT, requestedMode);
if (requestedMode != null && region.getRegionData().get(Flag.TESTBLOCK).isNotWithDefault(TestblockMode.NO_VALUE)) {
region.getRegionData().set(Flag.TNT, requestedMode);
RegionUtils.actionBar(region, requestedMessage);
return;
}
switch (region.getFlags().get(Flag.TNT).getWithDefault()) {
switch (region.getRegionData().get(Flag.TNT).getWithDefault()) {
case ALLOW:
case ONLY_TB:
region.getFlags().set(Flag.TNT, TNTMode.DENY);
region.getRegionData().set(Flag.TNT, TNTMode.DENY);
RegionUtils.actionBar(region, getDisableMessage());
break;
case DENY:
if (region.getFlags().get(Flag.TESTBLOCK).isNotWithDefault(TestblockMode.NO_VALUE)) {
region.getFlags().set(Flag.TNT, TNTMode.ONLY_TB);
if (region.getRegionData().get(Flag.TESTBLOCK).isNotWithDefault(TestblockMode.NO_VALUE)) {
region.getRegionData().set(Flag.TNT, TNTMode.ONLY_TB);
RegionUtils.actionBar(region, getTestblockEnableMessage());
} else {
region.getFlags().set(Flag.TNT, TNTMode.ALLOW);
region.getRegionData().set(Flag.TNT, TNTMode.ALLOW);
RegionUtils.actionBar(region, getEnableMessage());
}
break;
@@ -44,7 +44,7 @@ public class TNTListener implements Listener, ScoreboardElement {
private void explode(List<Block> blockList, boolean destroy) {
blockList.removeIf(block -> {
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 (destroy && block.getType() != Material.TNT) {
block.setType(Material.AIR);
@@ -86,7 +86,7 @@ public class TNTListener implements Listener, ScoreboardElement {
@Override
public String get(Region region, Player p) {
if (region.getFlags().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);
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.getRegionData().get(Flag.TNT).getWithDefault().getChatValue(), p);
}
}
@@ -119,7 +119,7 @@ public class TestblockCommand extends SWCommand {
.onlyColors(onlyColors)
.removeTNT(removeTNT)
.removeWater(removeWater)
.color(region.getFlags().get(Flag.COLOR).getWithDefault());
.color(region.getRegionData().get(Flag.COLOR).getWithDefault());
region.getTestblockArea().reset(pasteBuilder, regionExtensionType == RegionExtensionType.EXTENSION);
RegionUtils.message(region, "REGION_TB_DONE");
} catch (SecurityException e) {
@@ -84,14 +84,14 @@ public class ColorBauGuiItem extends BauGuiItem {
@Override
public ItemStack getItem(Player player) {
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();
}
@Override
public boolean click(ClickType click, Player p) {
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<>();
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 -> {
@@ -42,10 +42,10 @@ public class FireBauGuiItem extends BauGuiItem {
@Override
public ItemStack getItem(Player player) {
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();
}
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();
} else {
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
public ItemStack getItem(Player player) {
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();
}
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();
} else {
return new SWItem(Material.REDSTONE, BauSystem.MESSAGE.parse("REGION_ITEM_FREEZE_DISALLOW", player)).getItemStack();
@@ -43,10 +43,10 @@ public class ProtectBauGuiItem extends BauGuiItem {
@Override
public ItemStack getItem(Player player) {
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();
}
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();
} else {
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
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:
return new SWItem(Material.MINECART, BauSystem.MESSAGE.parse("REGION_ITEM_TNT_OFF", player)).getItemStack();
case ONLY_TB:
@@ -55,7 +55,7 @@ public class TntBauGuiItem extends BauGuiItem {
@Override
public boolean click(ClickType click, Player p) {
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:
updateTntMode(TNTMode.ALLOW, p);
break;
@@ -59,14 +59,14 @@ public class RegionLib implements LuaLib {
}));
LuaValue tntLib = LuaValue.tableOf();
tntLib.set("mode", getter(() -> region.get().getFlags().get(Flag.TNT).nameWithDefault()));
tntLib.set("enabled", getter(() -> region.get().getFlags().get(Flag.TNT).orElse(null) != TNTMode.DENY));
tntLib.set("onlyTb", getter(() -> region.get().getFlags().get(Flag.TNT).orElse(null) == TNTMode.ONLY_TB));
tntLib.set("mode", getter(() -> region.get().getRegionData().get(Flag.TNT).nameWithDefault()));
tntLib.set("enabled", getter(() -> region.get().getRegionData().get(Flag.TNT).orElse(null) != TNTMode.DENY));
tntLib.set("onlyTb", getter(() -> region.get().getRegionData().get(Flag.TNT).orElse(null) == TNTMode.ONLY_TB));
table.set("tnt", tntLib);
table.set("fire", getter(() -> region.get().getFlags().get(Flag.FIRE).orElse(null) == FireMode.ALLOW));
table.set("freeze", getter(() -> region.get().getFlags().get(Flag.FREEZE).orElse(null) == FreezeMode.ACTIVE));
table.set("protect", getter(() -> region.get().getFlags().get(Flag.PROTECT).orElse(null) == ProtectMode.ACTIVE));
table.set("fire", getter(() -> region.get().getRegionData().get(Flag.FIRE).orElse(null) == FireMode.ALLOW));
table.set("freeze", getter(() -> region.get().getRegionData().get(Flag.FREEZE).orElse(null) == FreezeMode.ACTIVE));
table.set("protect", getter(() -> region.get().getRegionData().get(Flag.PROTECT).orElse(null) == ProtectMode.ACTIVE));
//LuaValue traceLib = LuaValue.tableOf();
//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
public void accept(World 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);
if (!xJump) tnt.setVelocity(tnt.getVelocity().setX(0));
if (!yJump) tnt.setVelocity(tnt.getVelocity().setY(0));
@@ -35,8 +35,8 @@ public class StabFinalizer extends StabStep {
try {
PasteBuilder.ClipboardProvider clipboardProvider = new PasteBuilder.ClipboardProviderImpl(data.clipboard);
PasteBuilder pasteBuilder = new PasteBuilder(clipboardProvider);
if (data.region.getFlags().has(Flag.COLOR).isReadable()) {
pasteBuilder.color(data.region.getFlags().get(Flag.COLOR).getWithDefault());
if (data.region.getRegionData().has(Flag.COLOR).isReadable()) {
pasteBuilder.color(data.region.getRegionData().get(Flag.COLOR).getWithDefault());
}
data.region.getTestblockArea().reset(pasteBuilder, true);
} catch (SecurityException e) {
@@ -73,8 +73,8 @@ public class StabGenerator extends StabStep implements Listener {
try {
PasteBuilder.ClipboardProvider clipboardProvider = new PasteBuilder.ClipboardProviderImpl(data.clipboard);
PasteBuilder pasteBuilder = new PasteBuilder(clipboardProvider);
if (data.region.getFlags().has(Flag.COLOR).isReadable()) {
pasteBuilder.color(data.region.getFlags().get(Flag.COLOR).getWithDefault());
if (data.region.getRegionData().has(Flag.COLOR).isReadable()) {
pasteBuilder.color(data.region.getRegionData().get(Flag.COLOR).getWithDefault());
}
data.region.getTestblockArea().reset(pasteBuilder, true);
} catch (SecurityException e) {
@@ -121,8 +121,8 @@ public class BauScoreboard implements Listener {
Region region = Region.getRegion(player.getLocation());
if (region.getType().isGlobal()) return "§eSteam§8War";
String colorCode = "§e";
if (region.getFlags().has(Flag.COLOR).isReadable()) {
colorCode = "§" + region.getFlags().get(Flag.COLOR).orElse(ColorMode.PINK).getColorCode();
if (region.getRegionData().has(Flag.COLOR).isReadable()) {
colorCode = "§" + region.getRegionData().get(Flag.COLOR).orElse(ColorMode.PINK).getColorCode();
}
return colorCode + "■ §eSteam§8War " + colorCode + ""; // ■
}
@@ -41,8 +41,8 @@ public class BackupScheduler implements Enable {
@Override
public void run() {
Iterator<Region> regionsToBackup = RegionSystem.INSTANCE.getRegions()
.filter(region -> region.getFlags().has(Flag.CHANGED).isReadable())
.filter(region -> region.getFlags().get(Flag.CHANGED).getWithDefault() == ChangedMode.HAS_CHANGE)
.filter(region -> region.getRegionData().has(Flag.CHANGED).isReadable())
.filter(region -> region.getRegionData().get(Flag.CHANGED).isWithDefault(ChangedMode.HAS_CHANGE))
.iterator();
if (!regionsToBackup.hasNext()) return;
doBackup(regionsToBackup);
@@ -63,7 +63,7 @@ public class BackupScheduler implements Enable {
Optional<RegionBackups.Backup> backup = region.getBackups()
.create(RegionBackups.BackupType.AUTOMATIC);
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);
@@ -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.PasteBuilder;
import de.steamwar.sql.GameModeConfig;
import de.steamwar.sql.SchematicType;
import lombok.NonNull;
import org.bukkit.Location;
import org.bukkit.Material;
@@ -55,7 +54,7 @@ public interface Region {
RegionType getType();
@NonNull
FlagStorage getFlags();
RegionData getRegionData();
@NonNull
Area getArea();
@@ -75,9 +74,6 @@ public interface Region {
@NonNull
RegionBackups getBackups();
@NonNull
RegionData getRegionData();
interface Area {
Area EMPTY = new Area() {
@@ -49,7 +49,7 @@ public interface RegionBackups {
private final String name;
@NonNull
private final FlagStorage flags;
private final RegionData data;
@CheckReturnValue
public abstract boolean load();
@@ -19,75 +19,134 @@
package de.steamwar.bausystem.region;
import de.steamwar.bausystem.region.flags.Flag;
import de.steamwar.sql.SchematicNode;
import lombok.NonNull;
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 void clear() {
public Property(String field, Function<K, T> loader, Function<T, K> writer) {
this.field = field;
this.loader = loader;
this.writer = writer;
properties.add(this);
}
@Override
public SchematicNode getTestblockSchematic() {
return null;
}
@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");
public void load() {
if (flagData.containsKey(field)) {
value = loader.apply(flagData.getPlainValue(field));
} 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);
@Setter
private static FlagStorage FLAG_STORAGE;
private static RegionData FLAG_STORAGE;
private static final UUID GLOBAL_REGION_ID = new UUID(0, 0);
@@ -106,7 +106,7 @@ public final class FixedGlobalRegion implements Region {
}
@Override
public @NonNull FlagStorage getFlags() {
public @NonNull RegionData getRegionData() {
return FLAG_STORAGE;
}
@@ -139,9 +139,4 @@ public final class FixedGlobalRegion implements Region {
public @NonNull RegionBackups getBackups() {
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.utils.FlatteningWrapper;
import de.steamwar.bausystem.utils.PasteBuilder;
import de.steamwar.bausystem.worlddata.WorldData;
import de.steamwar.core.Core;
import de.steamwar.sql.GameModeConfig;
import de.steamwar.sql.SchematicType;
@@ -50,7 +49,7 @@ public class FixedRegion implements Region {
private final String name;
private final UUID uuid;
private final FixedFlagStorage flagStorage;
private final FixedRegionData flagStorage;
private final Prototype prototype;
private final String skin;
@@ -60,7 +59,6 @@ public class FixedRegion implements Region {
private final int floorLevel;
private final int waterLevel;
private final GameModeConfig<Material, String> gameModeConfig;
private final RegionData regionData;
private final RegionHistory regionHistory = new RegionHistory.Impl(20);
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;
uuid = UUID.nameUUIDFromBytes(name.getBytes(StandardCharsets.UTF_8));
this.flagStorage = flagStorage;
@@ -343,7 +341,6 @@ public class FixedRegion implements Region {
} else {
this.gameModeConfig = GameModeConfig.getByFileName(found);
}
this.regionData = new RegionData.RegionDataImpl(regionData, WorldData::write);
}
@Override
@@ -357,7 +354,7 @@ public class FixedRegion implements Region {
}
@Override
public @NonNull FlagStorage getFlags() {
public @NonNull RegionData getRegionData() {
return flagStorage;
}
@@ -390,9 +387,4 @@ public class FixedRegion implements Region {
public @NonNull RegionBackups getBackups() {
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;
import de.steamwar.bausystem.region.FixedRegionSystem;
import de.steamwar.bausystem.worlddata.WorldData;
import lombok.AllArgsConstructor;
import lombok.Getter;
import yapion.hierarchy.types.YAPIONObject;
@@ -216,7 +217,7 @@ public class Prototype {
} else {
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));
}
}
@@ -19,7 +19,7 @@
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.Prototype;
import de.steamwar.bausystem.worlddata.WorldData;
@@ -80,6 +80,6 @@ public class RegionLoader {
globalOptions = new YAPIONObject();
optionsYapionObject.add("global", globalOptions);
}
FixedGlobalRegion.setFLAG_STORAGE(new FixedGlobalFlagStorage(globalOptions.getObjectOrSetDefault("flagStorage", new YAPIONObject())));
FixedGlobalRegion.setFLAG_STORAGE(new FixedGlobalRegionData(globalOptions, WorldData::write));
}
}
@@ -44,6 +44,10 @@ object LeaderboardTable : CompositeIdTable("Leaderboard") {
val bestTime = bool("BestTime")
override val primaryKey = PrimaryKey(userId, name)
init {
addIdColumn(userId)
}
}
class Leaderboard(id: EntityID<CompositeID>) : CompositeEntity(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
}
+1 -1
View File
@@ -33,7 +33,7 @@ object TeamTable : IntIdTable("Team", "TeamID") {
val name = varchar("TeamName", 16)
val deleted = bool("TeamDeleted").default(false)
val address = text("Address").nullable()
val port = ushort("Port")
val port = ushort("Port").default(25565u)
}
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.extent.clipboard.BlockArrayClipboard;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.extent.clipboard.io.BuiltInClipboardFormat;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter;
import com.sk89q.worldedit.extent.clipboard.io.SpongeSchematicReader;
import com.sk89q.worldedit.extent.clipboard.io.*;
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.math.BlockVector3;
@@ -120,7 +118,12 @@ public class WorldeditWrapper14 implements WorldeditWrapper {
@Override
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
@@ -203,13 +203,23 @@ public class FightSchematic extends StateDependent {
for(int i = 0; i < chars.length; i++){
Clipboard character;
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) {
Bukkit.getLogger().log(Level.WARNING, "Could not display character {} due to missing file!", chars[i]);
try {
character = WorldeditWrapper.impl.loadChar("");
}catch (IOException ex) {
throw new SecurityException("Could not load text", ex);
character = WorldeditWrapper.impl.loadChar(chars[i] == '/' ? "slash" : String.valueOf(chars[i]));
} catch (IOException 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"
}
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") {
group = "run"
description = "Run a WarGear 1.21 Fight Server"
@@ -300,10 +300,10 @@ public class FlatteningWrapper14 implements FlatteningWrapper.IFlatteningWrapper
return head;
}
private static final Class<?> entityPose = Reflection.getClass("net.minecraft.world.entity.Pose");
private static final Object standing = entityPose.getEnumConstants()[0];
private static final Object swimming = entityPose.getEnumConstants()[3];
private static final Object sneaking = entityPose.getEnumConstants()[5];
protected static final Class<?> entityPose = Reflection.getClass("net.minecraft.world.entity.Pose");
protected static final Object standing = entityPose.getEnumConstants()[0];
protected static final Object swimming = entityPose.getEnumConstants()[3];
protected static final Object sneaking = entityPose.getEnumConstants()[5];
@Override
public Object getPose(FlatteningWrapper.EntityPose pose) {
switch (pose) {
@@ -37,6 +37,7 @@ dependencies {
compileOnly(libs.paperapi21)
compileOnly(libs.nms21)
compileOnly(libs.authlib2)
compileOnly(libs.datafixer)
compileOnly(libs.netty)
compileOnly(libs.authlib)
@@ -43,4 +43,11 @@ public class FlatteningWrapper21 extends FlatteningWrapper14 implements Flatteni
});
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.datafixers.util.Pair;
import de.steamwar.Reflection;
import net.minecraft.Util;
import net.minecraft.network.protocol.game.ClientboundPlayerInfoRemovePacket;
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 org.bukkit.GameMode;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.function.LongSupplier;
public class ProtocolWrapper21 implements ProtocolWrapper {
private static final Reflection.Field<List> equipmentStack = Reflection.getField(equipmentPacket, List.class, 0);
@Override
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
@SuppressWarnings("deprecation")
public Object playerInfoPacketConstructor(PlayerInfoAction action, GameProfile profile, GameMode mode) {
if(action == PlayerInfoAction.REMOVE)
return removePacketConstructor.invoke(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;
};
}
return new ClientboundPlayerInfoRemovePacket(Collections.singletonList(profile.getId()));
@Override
public void initTPSWarp(LongSupplier longSupplier) {
Util.timeSource = () -> System.nanoTime() + longSupplier.getAsLong();
return new ClientboundPlayerInfoUpdatePacket(action == PlayerInfoAction.ADD ?
EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER, ClientboundPlayerInfoUpdatePacket.Action.UPDATE_GAME_MODE) : EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_GAME_MODE),
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;
import com.mojang.authlib.properties.Property;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.EntityType;
@@ -40,4 +41,9 @@ public class TrickyTrialsWrapper21 implements TrickyTrialsWrapper {
public Material getTurtleScute() {
return Material.TURTLE_SCUTE;
}
@Override
public String getValue(Property property) {
return property.value();
}
}
@@ -19,7 +19,6 @@
package de.steamwar.core;
import com.fastasyncworldedit.core.extent.clipboard.io.FastSchematicReaderV2;
import com.sk89q.jnbt.NBTInputStream;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
@@ -37,7 +36,11 @@ import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
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 {
@@ -68,12 +71,58 @@ public class WorldEditWrapper21 implements WorldEditWrapper {
@Override
@SuppressWarnings("removal")
public Clipboard getClipboard(InputStream is, NodeData.SchematicFormat schemFormat) throws IOException {
return switch (schemFormat) {
case MCEDIT -> new MCEditSchematicReader(new NBTInputStream(is)).read();
case SPONGE_V2 -> new SpongeSchematicV2Reader(LinBinaryIO.read(new DataInputStream(is))).read();
case SPONGE_V3 -> new SpongeSchematicV3Reader(LinBinaryIO.read(new DataInputStream(is))).read();
};
public Clipboard getClipboard(InputStream is, NodeData.SchematicFormat ignored) throws IOException {
ResetableInputStream ris = new ResetableInputStream(is);
for (NodeData.SchematicFormat schemFormat : NodeData.SchematicFormat.values()) {
try {
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
@@ -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;
import net.minecraft.network.protocol.game.ClientboundAddEntityPacket;
import net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.PositionMoveRotation;
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);
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;
import com.mojang.authlib.properties.Property;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.EntityType;
@@ -40,4 +41,9 @@ public class TrickyTrialsWrapper8 implements TrickyTrialsWrapper {
public Material getTurtleScute() {
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 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.SWTypeMapperCreator;
import de.steamwar.command.TabCompletionCache;
@@ -110,6 +116,9 @@ public class Core extends JavaPlugin {
getServer().getMessenger().registerIncomingPluginChannel(this, "sw:bridge", new NetworkReceiver());
getServer().getMessenger().registerOutgoingPluginChannel(this, "sw:bridge");
if (Core.getVersion() != 20)
SteamwarGameProfileRepository.impl.inject();
TinyProtocol.init();
CheckpointUtils.signalHandler();
@@ -56,6 +56,8 @@ public class FlatteningWrapper {
public enum EntityPose {
NORMAL,
SNEAKING,
SWIMMING;
SWIMMING,
SHOOTING,
;
}
}
@@ -19,11 +19,10 @@
package de.steamwar.core;
import com.mojang.authlib.properties.Property;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.EntityType;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView;
public interface TrickyTrialsWrapper {
TrickyTrialsWrapper impl = VersionDependent.getVersionImpl(Core.getInstance());
@@ -33,4 +32,6 @@ public interface TrickyTrialsWrapper {
Enchantment getUnbreakingEnchantment();
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;
import com.mojang.authlib.Agent;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.GameProfileRepository;
import com.mojang.authlib.ProfileLookupCallback;
import com.mojang.authlib.yggdrasil.YggdrasilGameProfileRepository;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.core.Core;
import de.steamwar.core.VersionDependent;
import java.util.ArrayList;
import java.util.List;
public abstract class SteamwarGameProfileRepository implements GameProfileRepository {
public static final SteamwarGameProfileRepository impl = VersionDependent.getVersionImpl(Core.getInstance());
public class SteamwarGameProfileRepository implements GameProfileRepository {
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);
}
}
}
public abstract void inject();
}
@@ -23,7 +23,8 @@ import de.steamwar.core.Core;
import de.steamwar.core.VersionDependent;
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 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 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 nameVisibleWatcher = BountifulWrapper.impl.getDataWatcherObject(3, Boolean.class);
@@ -58,9 +58,9 @@ public class REntity {
protected double y;
@Getter
protected double z;
private byte yaw;
private byte pitch;
private byte headYaw;
protected byte yaw;
protected byte pitch;
protected byte headYaw;
@Getter
private boolean hidden;
@@ -219,7 +219,9 @@ public class REntity {
public void setBowDrawn(boolean drawn, boolean offHand) {
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))));
}else{
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<List> equipmentSlots = Reflection.getField(ProtocolWrapper.equipmentPacket, List.class, 0);
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 Object getEquipmentPacket(Object slot, ItemStack stack){
Object packet = Reflection.newInstance(ProtocolWrapper.equipmentPacket);
equipmentEntity.set(packet, entityId);
equipmentSlots.set(packet, new ArrayList<>());
ProtocolWrapper.impl.setEquipmentPacketStack(packet, slot, asNMSCopy.invoke(null, stack));
return packet;
}
@@ -22,10 +22,7 @@ package de.steamwar.entity;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.Property;
import de.steamwar.Reflection;
import de.steamwar.core.BountifulWrapper;
import de.steamwar.core.Core;
import de.steamwar.core.FlatteningWrapper;
import de.steamwar.core.ProtocolWrapper;
import de.steamwar.core.*;
import de.steamwar.network.CoreNetworkHandler;
import de.steamwar.network.NetworkSender;
import de.steamwar.network.packets.common.PlayerSkinRequestPacket;
@@ -82,7 +79,7 @@ public class RPlayer extends REntity {
NetworkSender.sendOrQueue(new PlayerSkinRequestPacket(actualUUID));
return new Property("textures", null, null);
});
if (skinData.getValue() != null) {
if (TrickyTrialsWrapper.impl.getValue(skinData) != null) {
GameProfile gameProfile = new GameProfile(uuid, name);
gameProfile.getProperties().put("textures", skinData);
return gameProfile;
@@ -117,10 +114,21 @@ public class RPlayer extends REntity {
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 final Function<REntity, Object> namedSpawnPacketGenerator = spawnPacketGenerator(namedSpawnPacket, Core.getVersion() == 8 ? 1 : 0);
private static final Reflection.Field<UUID> namedSpawnUUID = Reflection.getField(namedSpawnPacket, UUID.class, 0);
private static Class<?> namedSpawnPacket = null;
private static Function<REntity, Object> namedSpawnPacketGenerator = null;
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() {
if (Core.getVersion() >= 21) return PacketConstructor.impl.createRPlayerSpawn(this);
Object packet = namedSpawnPacketGenerator.apply(this);
namedSpawnUUID.set(packet, uuid);
FlatteningWrapper.impl.setNamedSpawnPacketDataWatcher(packet);
@@ -226,11 +226,6 @@ IGNORE_YOURSELF=§cHow are you going to ignore yourself?
IGNORE_ALREADY=§cYou are already ignoring this player.
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
BAU_ADDMEMBER_USAGE=§8/§7build addmember §8[§eplayer§8]
BAU_ADDMEMBER_SELFADD=§cYou don't have to add yourself!
@@ -375,12 +370,6 @@ MSG_IGNORED=§cThis player has blocked you!
#PingCommand
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
R_USAGE=§8/§7r §8[§eanswer§8]
@@ -605,13 +594,6 @@ JOIN_STREAMING=§5Streaming Mode§7 is still active§8.§7 Keep in mind that you
#EventModeListener
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
TABLIST_PHASE_WEBSITE=§8Website: https://§eSteam§8War.de
TABLIST_PHASE_DISCORD=§8Discord: https://§eSteam§8War.de/discord
@@ -208,10 +208,6 @@ IGNORE_YOURSELF=§cWie willst du dich selber ignorieren?
IGNORE_ALREADY=§cDu ignorierst diesen Spieler bereits.
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
BAU_ADDMEMBER_USAGE=§8/§7bau addmember §8[§eSpieler§8]
BAU_ADDMEMBER_SELFADD=§cDu brauchst dich nicht selbst hinzufügen!
@@ -353,12 +349,6 @@ MSG_IGNORED=§cDieser Spieler hat dich geblockt!
#PingCommand
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
R_USAGE=§8/§7r §8[§eAntwort§8]
@@ -577,13 +567,6 @@ JOIN_STREAMING=§5Streaming-Modus§7 ist weiterhin aktiv§8.§7 Beachten Sie, da
#EventModeListener
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
TABLIST_FOOTER=§e{0} {1}§8ms §eSpieler§8: §7{2}
TABLIST_BAU=§7§lBau
@@ -68,18 +68,11 @@ public class Config {
private boolean eventmode = false;
private Map<String, Server> servers = Collections.emptyMap();
private List<String> broadcasts = Collections.emptyList();
private Poll poll = null;
public RegisteredServer lobbyserver() {
return VelocityCore.getProxy().getServer(lobbyserver).orElseThrow();
}
@Getter
public static class Poll {
private String question;
private List<String> answers;
}
@Getter
public static class Server {
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.DiscordConfig;
import de.steamwar.velocitycore.listeners.BasicListener;
import de.steamwar.velocitycore.listeners.PollSystem;
import lombok.Getter;
import lombok.NonNull;
@@ -135,7 +134,6 @@ public class VelocityCore implements ReloadablePlugin {
schedule(TabCompletionCache::invalidateOldEntries).repeat(1, TimeUnit.SECONDS).schedule();
initStaticServers();
PollSystem.init();
local = new Node.LocalNode();
if(MAIN_SERVER) {
@@ -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();
}
}
@@ -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);
}
}
+1
View File
@@ -113,6 +113,7 @@ dependencyResolutionManagement {
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("authlib", "com.mojang:authlib:1.5.25")
library("authlib2", "com.mojang:authlib:6.0.58")
library("datafixer", "com.mojang:datafixerupper:4.0.26")
library("brigadier", "com.mojang:brigadier:1.0.18")
library("anvilgui", "net.wesjd:anvilgui:1.10.6-SNAPSHOT")