diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/region/ResetCommand.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/region/ResetCommand.java index 3e3e4483..4490a146 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/region/ResetCommand.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/region/ResetCommand.java @@ -20,7 +20,6 @@ package de.steamwar.bausystem.features.region; import de.steamwar.bausystem.BauSystem; -import de.steamwar.bausystem.Permission; import de.steamwar.bausystem.config.BauServer; import de.steamwar.bausystem.region.GlobalRegion; import de.steamwar.bausystem.region.Region; @@ -31,7 +30,6 @@ import de.steamwar.bausystem.region.utils.RegionExtensionType; import de.steamwar.bausystem.region.utils.RegionType; import de.steamwar.bausystem.utils.PasteBuilder; import de.steamwar.command.SWCommand; -import de.steamwar.command.TypeValidator; import de.steamwar.linkage.Linked; import de.steamwar.linkage.LinkedInstance; import de.steamwar.sql.Punishment; @@ -40,7 +38,6 @@ import de.steamwar.sql.SteamwarUser; import org.bukkit.Bukkit; import org.bukkit.entity.Player; -import java.io.IOException; import java.util.logging.Level; @Linked @@ -61,7 +58,7 @@ public class ResetCommand extends SWCommand { PasteBuilder pasteBuilder = new PasteBuilder(new PasteBuilder.FileProvider(region.getResetFile(RegionType.NORMAL))) .color(region.getPlain(Flag.COLOR, ColorMode.class).getColor()); region.reset(pasteBuilder, RegionType.NORMAL, RegionExtensionType.NORMAL); - for (Flag value : Flag.values()) { + for (Flag value : Flag.getResetFlags()) { region.set(value, value.getDefaultValue()); } RegionUtils.message(region, "REGION_RESET_RESETED"); diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/region/flags/Flag.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/region/flags/Flag.java index d6bdf3e6..3c9f3173 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/region/flags/Flag.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/region/flags/Flag.java @@ -21,41 +21,40 @@ package de.steamwar.bausystem.region.flags; import de.steamwar.bausystem.region.flags.flagvalues.*; import de.steamwar.bausystem.shared.EnumDisplay; +import lombok.AllArgsConstructor; import lombok.Getter; import java.util.EnumSet; import java.util.Set; +import java.util.stream.Collectors; @Getter +@AllArgsConstructor public enum Flag implements EnumDisplay { - COLOR("FLAG_COLOR", ColorMode.class, ColorMode.YELLOW), - TNT("FLAG_TNT", TNTMode.class, TNTMode.ONLY_TB), - FIRE("FLAG_FIRE", FireMode.class, FireMode.ALLOW), - FREEZE("FLAG_FREEZE", FreezeMode.class, FreezeMode.INACTIVE), - PROTECT("FLAG_PROTECT", ProtectMode.class, ProtectMode.ACTIVE), - ITEMS("FLAG_ITEMS", ItemMode.class, ItemMode.INACTIVE), - NO_GRAVITY("FLAG_NO_GRAVITY", NoGravityMode.class, NoGravityMode.INACTIVE), + COLOR("FLAG_COLOR", ColorMode.class, ColorMode.YELLOW, false), + TNT("FLAG_TNT", TNTMode.class, TNTMode.ONLY_TB, true), + FIRE("FLAG_FIRE", FireMode.class, FireMode.ALLOW, true), + FREEZE("FLAG_FREEZE", FreezeMode.class, FreezeMode.INACTIVE, true), + PROTECT("FLAG_PROTECT", ProtectMode.class, ProtectMode.ACTIVE, true), + ITEMS("FLAG_ITEMS", ItemMode.class, ItemMode.INACTIVE, true), + NO_GRAVITY("FLAG_NO_GRAVITY", NoGravityMode.class, NoGravityMode.INACTIVE, true), ; @Getter private static final Set flags; + @Getter + private static final Set resetFlags; static { flags = EnumSet.allOf(Flag.class); + resetFlags = flags.stream().filter(flag -> flag.reset).collect(Collectors.toUnmodifiableSet()); } private final String chatValue; private final Class> valueType; private final Flag.Value defaultValue; - private final Value[] values; - - & Value> Flag(String chatValue, final Class> valueType, final Flag.Value defaultValue) { - this.chatValue = chatValue; - this.valueType = valueType; - this.defaultValue = defaultValue; - this.values = defaultValue.getValues(); - } + private final boolean reset; public Value getFlagValueOf(final String name) { return this.defaultValue.getValueOf(name); diff --git a/CommonCore/SQL/src/de/steamwar/sql/EventFight.java b/CommonCore/SQL/src/de/steamwar/sql/EventFight.java index 72497525..fe91e3be 100644 --- a/CommonCore/SQL/src/de/steamwar/sql/EventFight.java +++ b/CommonCore/SQL/src/de/steamwar/sql/EventFight.java @@ -43,7 +43,7 @@ public class EventFight implements Comparable { private static final Statement setResult = table.update(Table.PRIMARY, "Ergebnis"); private static final Statement setFight = table.update(Table.PRIMARY, "Fight"); - private static final Statement create = table.insertAll(true); + private static final Statement create = table.insertFields(true, "eventID", "startTime", "spielmodus", "map", "teamBlue", "teamRed", "spectatePort"); private static final Statement update = table.update(Table.PRIMARY, "startTime", "spielModus", "map", "teamBlue", "teamRed", "spectatePort"); private static final Statement delete = table.delete(Table.PRIMARY); diff --git a/FightSystem/FightSystem_14/src/de/steamwar/fightsystem/utils/BlockIdWrapper14.java b/FightSystem/FightSystem_14/src/de/steamwar/fightsystem/utils/BlockIdWrapper14.java index f2330e12..5030cb04 100644 --- a/FightSystem/FightSystem_14/src/de/steamwar/fightsystem/utils/BlockIdWrapper14.java +++ b/FightSystem/FightSystem_14/src/de/steamwar/fightsystem/utils/BlockIdWrapper14.java @@ -26,6 +26,7 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.Block; +import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import java.util.Map; @@ -72,16 +73,16 @@ public class BlockIdWrapper14 implements BlockIdWrapper { private static final Class entityTracker = Reflection.getClass("{nms.server.level}.PlayerChunkMap$EntityTracker"); private static final Reflection.MethodInvoker updatePlayer = Reflection.getMethod(entityTracker, Core.getVersion() > 15 ? "b" : "updatePlayer", entityPlayer); @Override - public void trackEntity(Player player, int entity) { - Object tracker = trackers.get(entity); + public void trackEntity(Player player, Entity entity) { + Object tracker = trackers.get(entity.getEntityId()); if(tracker != null) updatePlayer.invoke(tracker, getPlayer.invoke(player)); } private static final Reflection.MethodInvoker clearPlayer = Reflection.getMethod(entityTracker, Core.getVersion() > 15 ? "a" : "clear", entityPlayer); @Override - public void untrackEntity(Player player, int entity) { - Object tracker = trackers.get(entity); + public void untrackEntity(Player player, Entity entity) { + Object tracker = trackers.get(entity.getEntityId()); if(tracker != null) clearPlayer.invoke(tracker, getPlayer.invoke(player)); } diff --git a/FightSystem/FightSystem_18/build.gradle.kts b/FightSystem/FightSystem_18/build.gradle.kts index fa12144d..b140d148 100644 --- a/FightSystem/FightSystem_18/build.gradle.kts +++ b/FightSystem/FightSystem_18/build.gradle.kts @@ -24,6 +24,7 @@ plugins { dependencies { compileOnly(project(":SpigotCore", "default")) compileOnly(project(":FightSystem:FightSystem_Core", "default")) + compileOnly(project(":FightSystem:FightSystem_14", "default")) compileOnly(libs.spigotapi) diff --git a/FightSystem/FightSystem_18/src/de/steamwar/fightsystem/utils/BlockIdWrapper18.java b/FightSystem/FightSystem_18/src/de/steamwar/fightsystem/utils/BlockIdWrapper18.java new file mode 100644 index 00000000..c229353a --- /dev/null +++ b/FightSystem/FightSystem_18/src/de/steamwar/fightsystem/utils/BlockIdWrapper18.java @@ -0,0 +1,42 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.fightsystem.utils; + +import com.comphenix.tinyprotocol.Reflection; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +import java.util.*; + +public class BlockIdWrapper18 extends BlockIdWrapper14 { + + private static final Reflection.FieldAccessor hiddenEntities = Reflection.getField(Reflection.getClass("{obc}.entity.CraftPlayer"), Map.class, 0, UUID.class, Set.class); + @Override + public void trackEntity(Player player, Entity entity) { + hiddenEntities.get(player).remove(entity.getUniqueId()); + super.trackEntity(player, entity); + } + + @Override + public void untrackEntity(Player player, Entity entity) { + hiddenEntities.get(player).put(entity.getUniqueId(), new HashSet<>(1)); + super.untrackEntity(player, entity); + } +} diff --git a/FightSystem/FightSystem_8/src/de/steamwar/fightsystem/utils/BlockIdWrapper8.java b/FightSystem/FightSystem_8/src/de/steamwar/fightsystem/utils/BlockIdWrapper8.java index d330cfbc..402f8e60 100644 --- a/FightSystem/FightSystem_8/src/de/steamwar/fightsystem/utils/BlockIdWrapper8.java +++ b/FightSystem/FightSystem_8/src/de/steamwar/fightsystem/utils/BlockIdWrapper8.java @@ -24,6 +24,7 @@ import de.steamwar.fightsystem.Config; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.Block; +import org.bukkit.entity.Entity; import org.bukkit.entity.Player; public class BlockIdWrapper8 implements BlockIdWrapper { @@ -57,16 +58,16 @@ public class BlockIdWrapper8 implements BlockIdWrapper { private static final Reflection.MethodInvoker get = Reflection.getTypedMethod(intHashMap, "get", Object.class, int.class); private static final Reflection.MethodInvoker updatePlayer = Reflection.getMethod(entityTrackerEntry, "updatePlayer", entityPlayer); @Override - public void trackEntity(Player player, int entity) { - Object tracker = get.invoke(trackers, entity); + public void trackEntity(Player player, Entity entity) { + Object tracker = get.invoke(trackers, entity.getEntityId()); if(tracker != null) updatePlayer.invoke(tracker, getPlayer.invoke(player)); } private static final Reflection.MethodInvoker clearPlayer = Reflection.getMethod(entityTrackerEntry, "a", entityPlayer); @Override - public void untrackEntity(Player player, int entity) { - Object tracker = get.invoke(trackers, entity); + public void untrackEntity(Player player, Entity entity) { + Object tracker = get.invoke(trackers, entity.getEntityId()); if(tracker != null) clearPlayer.invoke(tracker, getPlayer.invoke(player)); } diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/Permanent.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/Permanent.java index 90342de2..2f3138ec 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/Permanent.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/Permanent.java @@ -83,7 +83,7 @@ public class Permanent implements Listener { @EventHandler public void onTpGM3(PlayerTeleportEvent e) { - if (e.getCause() == PlayerTeleportEvent.TeleportCause.SPECTATE) { + if (ArenaMode.AntiTest.contains(Config.mode) && e.getCause() == PlayerTeleportEvent.TeleportCause.SPECTATE) { e.setCancelled(true); FightSystem.getMessage().sendPrefixless("NO_TELEPORT", e.getPlayer(), ChatMessageType.ACTION_BAR); e.getPlayer().kickPlayer(null); diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/record/PacketProcessor.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/record/PacketProcessor.java index eafe4377..47efc09d 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/record/PacketProcessor.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/record/PacketProcessor.java @@ -26,6 +26,7 @@ import de.steamwar.core.WorldEditWrapper; import de.steamwar.entity.REntity; import de.steamwar.entity.REntityServer; import de.steamwar.entity.RPlayer; +import de.steamwar.fightsystem.ArenaMode; import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.FightSystem; import de.steamwar.fightsystem.countdown.Countdown; @@ -244,6 +245,9 @@ public class PacketProcessor implements Listener { SteamwarUser user = SteamwarUser.get(userId); addREntity(entityId, new RPlayer(entityServer, user.getUUID(), user.getUserName(), Config.SpecSpawn)); team.addEntry(user.getUserName()); + + if(ArenaMode.Test.contains(Config.mode)) + entities.get(entityId).setGlowing(true); }); } diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/BlockIdWrapper.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/BlockIdWrapper.java index a6b825db..354ff9fd 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/BlockIdWrapper.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/BlockIdWrapper.java @@ -25,6 +25,7 @@ import de.steamwar.fightsystem.FightSystem; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.Block; +import org.bukkit.entity.Entity; import org.bukkit.entity.Player; public interface BlockIdWrapper { @@ -41,6 +42,6 @@ public interface BlockIdWrapper { int blockToId(Block block); void setBlock(World world, int x, int y, int z, int blockState); - void trackEntity(Player player, int entity); - void untrackEntity(Player player, int entity); + void trackEntity(Player player, Entity entity); + void untrackEntity(Player player, Entity entity); } diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/Hull.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/Hull.java index 05ff3fc8..5c4bd32c 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/Hull.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/Hull.java @@ -35,24 +35,28 @@ import org.bukkit.entity.Player; import java.util.*; import java.util.function.BiConsumer; import java.util.logging.Level; +import java.util.stream.IntStream; public class Hull { + private static final IntVector[] NO_BRANCHES = new IntVector[0]; + private static boolean isOccluding(Material material) { return material.isOccluding() || Config.HiddenBlocks.contains(material); } private final Region region; private final boolean groundVisible; + private final IntVector[] directions; private final BitSet occluding; private final BitSet visibility; - private final Map> blockVisibility = new HashMap<>(); - private final Set uncoveredSurface = new HashSet<>(); + private final HashMap visibilityDirections = new HashMap<>(); // Contains the visible directions of each occluding visible block + private final HashSet uncoveredSurface = new HashSet<>(); private final HashSet players = new HashSet<>(); - private final Set entities = new HashSet<>(); - private final Set rentities = new HashSet<>(); + private final HashSet entities = new HashSet<>(); + private final HashSet rentities = new HashSet<>(); public Hull(FightTeam team) { this.region = team.getSchemRegion(); @@ -60,38 +64,14 @@ public class Hull { this.occluding = new BitSet(region.volume()); this.visibility = new BitSet(region.volume()); - IntVector[] directions; - if (groundVisible) { - directions = new IntVector[]{ - new IntVector(1, 0, 0), - new IntVector(-1, 0, 0), - new IntVector(0, 1, 0), - new IntVector(0, -1, 0), - new IntVector(0, 0, 1), - new IntVector(0, 0, -1) - }; - } else { - directions = new IntVector[]{ - new IntVector(1, 0, 0), - new IntVector(-1, 0, 0), - new IntVector(0, -1, 0), - new IntVector(0, 0, 1), - new IntVector(0, 0, -1) - }; - } + IntVector primaryDirection = new IntVector(0, 0, team.isBlue() == (Config.BlueToRedZ > 0) ? -1 : 1); + directions = IntStream.range(0, 27) + .mapToObj(v -> new IntVector(v%3 -1, (v/3)%3 -1, v/9 -1)) + .filter(v -> v.sqLength() == 1 || v.x*primaryDirection.x + v.y*primaryDirection.y + v.z*primaryDirection.z == 1) // Not pointing away from primary direction + .toArray(IntVector[]::new); - // Generate quadrants for each direction - for (IntVector direction : directions) { - Map map = new HashMap<>(); - for (int z = (direction.z == 0 ? -1 : 0); z <= 1; z += 2) { - for (int y = (direction.y == 0 ? -1 : 0); y <= 1; y += 2) { - for (int x = (direction.x == 0 ? -1 : 0); x <= 1; x += 2) { - map.put(new IntVector(x, y, z), new BitSet(region.volume())); - } - } - } - blockVisibility.put(direction, map); - } + for(IntVector direction : directions) + visibilityDirections.put(direction, new BitSet(region.volume())); } public boolean blockPrecise(Player player, int chunkX, int chunkY, int chunkZ) { @@ -109,29 +89,29 @@ public class Hull { public void addPlayer(Player player) { if(players.add(player)) { for(Entity entity : entities) - BlockIdWrapper.impl.untrackEntity(player, entity.getEntityId()); + BlockIdWrapper.impl.untrackEntity(player, entity); } } public void removePlayer(Player player, boolean activeRemoval) { if(players.remove(player) && activeRemoval) { for(Entity entity : entities) - BlockIdWrapper.impl.trackEntity(player, entity.getEntityId()); + BlockIdWrapper.impl.trackEntity(player, entity); // techhider triggers block change sending } } public void checkEntity(Entity entity) { Location location = entity.getLocation(); - if(region.inRegion(location) && !visibility.get(new IntVector(location).toId(region))) { //TODO more precise + if(region.inRegion(location) && !visibility.get(new IntVector(location).toId(region))) { if(entities.add(entity)) { for(Player player : players) - BlockIdWrapper.impl.untrackEntity(player, entity.getEntityId()); + BlockIdWrapper.impl.untrackEntity(player, entity); } } else { if(entities.remove(entity)) { for(Player player : players) - BlockIdWrapper.impl.trackEntity(player, entity.getEntityId()); + BlockIdWrapper.impl.trackEntity(player, entity); } } } @@ -142,7 +122,7 @@ public class Hull { public void checkREntity(REntity entity) { Location location = new Location(Config.world, entity.getX(), entity.getY(), entity.getZ()); - if(region.inRegion(location) && !visibility.get(new IntVector(location).toId(region))) { //TODO more precise + if(region.inRegion(location) && !visibility.get(new IntVector(location).toId(region))) { if(rentities.add(entity)) entity.hide(true); } else { @@ -159,10 +139,8 @@ public class Hull { visibility.clear(); occluding.clear(); uncoveredSurface.clear(); - for (Map direction : blockVisibility.values()) { - for (BitSet set : direction.values()) - set.clear(); - } + for(BitSet directionalVisibility : visibilityDirections.values()) + directionalVisibility.clear(); long start = System.currentTimeMillis(); region.forEach((x, y, z) -> { @@ -170,11 +148,7 @@ public class Hull { if (isOccluding(Config.world.getBlockAt(x, y, z).getType())) occluding.set(block.toId(region)); }); - forEachBorder((root, direction) -> { - for (Map.Entry quadrant : blockVisibility.get(direction).entrySet()) { - checkBlock(new NullList<>(), root, direction, quadrant.getKey(), quadrant.getValue()); - } - }); + forEachBorder((root, direction) -> uncoverBlocks(new NullList<>(), root, direction)); FightSystem.getPlugin().getLogger().log(Level.INFO, () -> "[HullHider] initialisation finished: " + (System.currentTimeMillis() - start) + " ms, visible blocks: " + visibility.cardinality()); } @@ -187,41 +161,19 @@ public class Hull { if (!occluding.get(id) || isOccluding(changedType)) return; - List uncovered = new ArrayList<>(); occluding.clear(id); - for (Map.Entry> direction : blockVisibility.entrySet()) { - for (Map.Entry quadrant : direction.getValue().entrySet()) { - if (quadrant.getValue().get(id)) { - quadrant.getValue().clear(id); - checkBlock(uncovered, root, direction.getKey(), quadrant.getKey(), quadrant.getValue()); - } - } - } - - if(uncovered.isEmpty()) + if(!visibility.get(id)) return; - Set uncoveredSet = new HashSet<>(uncovered); - Iterator it = entities.iterator(); - while(it.hasNext()) { - Entity entity = it.next(); - if(uncoveredSet.contains(new IntVector(entity.getLocation()))) { //TODO more precise - it.remove(); - for(Player player : players) - BlockIdWrapper.impl.trackEntity(player, entity.getEntityId()); + List uncovered = new ArrayList<>(); + for(Map.Entry directionalVisibility : visibilityDirections.entrySet()) { + if(directionalVisibility.getValue().get(id)) { + directionalVisibility.getValue().clear(id); + uncoverBlocks(uncovered, root, directionalVisibility.getKey()); } } - Iterator rit = rentities.iterator(); - while(rit.hasNext()) { - REntity entity = rit.next(); - if(uncoveredSet.contains(new IntVector(new Location(Config.world, entity.getX(), entity.getY(), entity.getZ())))) { //TODO more precise - rit.remove(); - entity.hide(false); - } - } - - uncoveredSurface.addAll(uncoveredSet); + uncoveredSurface.addAll(new HashSet<>(uncovered)); uncoveredSurface.remove(root); } @@ -266,15 +218,26 @@ public class Hull { } } - private void checkBlock(List uncovered, IntVector block, IntVector direction, IntVector quadrant, BitSet quadVisibility) { + private void uncoverBlocks(List uncovered, IntVector block, IntVector direction) { + uncoverBlocks( + uncovered, block, direction, visibilityDirections.get(direction), + direction.sqLength() == 1 + ? Arrays.stream(directions) + .filter(v -> v.sqLength() >= 2 && v.x*direction.x + v.y*direction.y + v.z*direction.z == 1) + .toArray(IntVector[]::new) + : NO_BRANCHES + ); + } + + private void uncoverBlocks(List uncovered, IntVector block, IntVector direction, BitSet directionalVisibility, IntVector[] branchDirections) { if (block.notInRegion(region)) return; int id = block.toId(region); - if (quadVisibility.get(id)) + if(directionalVisibility.get(id)) return; + directionalVisibility.set(id); - quadVisibility.set(id); if (!visibility.get(id)) { visibility.set(id); uncovered.add(block); @@ -283,31 +246,9 @@ public class Hull { if (occluding.get(id)) return; - IntVector neighbour = block.add(direction); - checkBlock(uncovered, neighbour, direction, quadrant, quadVisibility); - boolean neigbourTransparent = boundedNonOccluding(neighbour); - boolean diagonalReachable = false; - if (direction.x == 0 && (neigbourTransparent || boundedNonOccluding(block.add(quadrant.x, 0, 0)))) { - checkBlock(uncovered, neighbour.add(quadrant.x, 0, 0), direction, quadrant, quadVisibility); - diagonalReachable = boundedNonOccluding(neighbour.add(quadrant.x, 0, 0)); - } - - if (direction.y == 0 && (neigbourTransparent || boundedNonOccluding(block.add(0, quadrant.y, 0)))) { - checkBlock(uncovered, neighbour.add(0, quadrant.y, 0), direction, quadrant, quadVisibility); - diagonalReachable = diagonalReachable || boundedNonOccluding(neighbour.add(0, quadrant.y, 0)); - } - - if (direction.z == 0 && (neigbourTransparent || boundedNonOccluding(block.add(0, 0, quadrant.z)))) { - checkBlock(uncovered, neighbour.add(0, 0, quadrant.z), direction, quadrant, quadVisibility); - diagonalReachable = diagonalReachable || boundedNonOccluding(neighbour.add(0, 0, quadrant.z)); - } - - if (diagonalReachable) - checkBlock(uncovered, neighbour.add(quadrant), direction, quadrant, quadVisibility); - } - - private boolean boundedNonOccluding(IntVector block) { - return !(block.notInRegion(region) || occluding.get(block.toId(region))); + uncoverBlocks(uncovered, block.add(direction), direction, directionalVisibility, branchDirections); + for(IntVector branchDirection : branchDirections) + uncoverBlocks(uncovered, block.add(branchDirection), branchDirection, visibilityDirections.get(branchDirection), NO_BRANCHES); } @@ -340,6 +281,10 @@ public class Hull { return add(v.x, v.y, v.z); } + public int sqLength() { + return x*x + y*y + z*z; + } + @Override public int hashCode() { return y << 24 ^ x << 12 ^ z; diff --git a/KotlinCore/build.gradle.kts b/KotlinCore/build.gradle.kts index 5d00f0f6..0c610074 100644 --- a/KotlinCore/build.gradle.kts +++ b/KotlinCore/build.gradle.kts @@ -32,4 +32,6 @@ tasks.shadowJar { dependencies { compileOnly(libs.paperapi21) + compileOnly(libs.nms21) + compileOnly(project(":SpigotCore")) } diff --git a/KotlinCore/src/de/steamwar/kotlin/KotlinCore.kt b/KotlinCore/src/de/steamwar/kotlin/KotlinCore.kt index e821ade4..1c4bc406 100644 --- a/KotlinCore/src/de/steamwar/kotlin/KotlinCore.kt +++ b/KotlinCore/src/de/steamwar/kotlin/KotlinCore.kt @@ -32,6 +32,7 @@ class KotlinCore : JavaPlugin() { } override fun onEnable() { + } override fun onDisable() { diff --git a/TNTLeague/src/de/steamwar/tntleague/inventory/SWInventoryHolder.kt b/KotlinCore/src/de/steamwar/kotlin/inventory/SWInventoryHolder.kt similarity index 59% rename from TNTLeague/src/de/steamwar/tntleague/inventory/SWInventoryHolder.kt rename to KotlinCore/src/de/steamwar/kotlin/inventory/SWInventoryHolder.kt index 5d89e541..3afb3183 100644 --- a/TNTLeague/src/de/steamwar/tntleague/inventory/SWInventoryHolder.kt +++ b/KotlinCore/src/de/steamwar/kotlin/inventory/SWInventoryHolder.kt @@ -1,4 +1,23 @@ -package de.steamwar.tntleague.inventory +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.kotlin.inventory import org.bukkit.event.inventory.InventoryClickEvent import org.bukkit.event.inventory.InventoryCloseEvent diff --git a/TNTLeague/src/de/steamwar/tntleague/util/Area.kt b/KotlinCore/src/de/steamwar/kotlin/util/Area.kt similarity index 62% rename from TNTLeague/src/de/steamwar/tntleague/util/Area.kt rename to KotlinCore/src/de/steamwar/kotlin/util/Area.kt index 0b27d227..5b96519f 100644 --- a/TNTLeague/src/de/steamwar/tntleague/util/Area.kt +++ b/KotlinCore/src/de/steamwar/kotlin/util/Area.kt @@ -1,4 +1,23 @@ -package de.steamwar.tntleague.util +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.kotlin.util import org.bukkit.Location import org.bukkit.block.Block diff --git a/SchematicSystem/SchematicSystem_Core/src/SchematicSystem.properties b/SchematicSystem/SchematicSystem_Core/src/SchematicSystem.properties index b5e1c15f..29cb8829 100644 --- a/SchematicSystem/SchematicSystem_Core/src/SchematicSystem.properties +++ b/SchematicSystem/SchematicSystem_Core/src/SchematicSystem.properties @@ -82,7 +82,8 @@ UTIL_LOAD_ERROR=§cThe schematic could not be loaded UTIL_DOWNLOAD_PUNISHED=§cYou are not allowed to download schematics: §f§l{0} UTIL_DOWNLOAD_NOT_OWN=§cYou may download only your own schematics UTIL_DOWNLOAD_LINK=Your download link: -UTIL_TYPE_PUNISHED=§cYou are not allowed to submit schematics: §f§l{0} +UTIL_TYPE_PUNISHED=§cYou are not allowed to submit schematics until §e{1}§7: §f§l{0} +UTIL_TYPE_PUNISHED_PERMA=§cYou are permanently prohibited from submitting schematics: §f§l{0} UTIL_TYPE_NOT_OWN=§cYou can only submit your own schematics UTIL_TYPE_DIR=§cYou cannot submit folders UTIL_TYPE_NOT_ASSIGNABLE=§cSchematics cannot be changed for this type @@ -90,6 +91,7 @@ UTIL_TYPE_ALREADY=§cThe Schematic already has this type UTIL_TYPE_DONE=§aChange schematic type UTIL_TYPE_FIGHT_ALREADY=§cYou have already submitted this schematic UTIL_TYPE_AFTER_DEADLINE=§cSchematics of this type can no longer be submitted. Deadline was: {0} +UTIL_TYPE_TOO_MANY=§cYou have sent in too many Schematics UTIL_TYPE_ERROR=§cThe Schematic is not compliant with the rules UTIL_TYPE_EXTEND=§aThe preparation server is starting UTIL_SUBMIT_TITLE=Extend Schematic diff --git a/SchematicSystem/SchematicSystem_Core/src/SchematicSystem_de.properties b/SchematicSystem/SchematicSystem_Core/src/SchematicSystem_de.properties index cf370bcb..5e85d346 100644 --- a/SchematicSystem/SchematicSystem_Core/src/SchematicSystem_de.properties +++ b/SchematicSystem/SchematicSystem_Core/src/SchematicSystem_de.properties @@ -69,7 +69,8 @@ UTIL_LOAD_ERROR=§cDie Schematic konnte nicht geladen werden UTIL_DOWNLOAD_PUNISHED=§cDu darf keine Schematics Downloaden: §f§l{0} UTIL_DOWNLOAD_NOT_OWN=§cDu darfst nur deine eigenen Schematics herunterladen UTIL_DOWNLOAD_LINK=Dein Download Link: -UTIL_TYPE_PUNISHED=§cDu darf keine Schematics einsenden: §f§l{0} +UTIL_TYPE_PUNISHED=§cDu darfst bis zum §e{1} §7keine Schematics einsenden: §f§l{0} +UTIL_TYPE_PUNISHED_PERMA=§cDu darfst keine Schematics mehr einsenden: §f§l{0} UTIL_TYPE_NOT_OWN=§cDu kannst nur deine eigenen Schematics einsenden UTIL_TYPE_DIR=§cDu kannst keine Ordner einsenden UTIL_TYPE_NOT_ASSIGNABLE=§cZu diesem Typen können keine Schematics geändert werden @@ -77,6 +78,7 @@ UTIL_TYPE_ALREADY=§cDie Schematic hat schon diesen Typen UTIL_TYPE_DONE=§aSchematictyp geändert UTIL_TYPE_FIGHT_ALREADY=§cDu hast diese Schematic bereits eingesendet UTIL_TYPE_AFTER_DEADLINE=§cVon diesem Typen können keine Schematics mehr eingesendet werden. Einsendeschluss war: {0} +UTIL_TYPE_TOO_MANY=§cDu hast zu viele Schematics eingesendet UTIL_TYPE_ERROR=§cDie Schematic ist nicht regelkonform UTIL_TYPE_EXTEND=§aDer Vorbereitungsserver wird gestartet UTIL_SUBMIT_TITLE=Schematic ausfahren diff --git a/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicCommandUtils.java b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicCommandUtils.java index 14ecdabb..860435b9 100644 --- a/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicCommandUtils.java +++ b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicCommandUtils.java @@ -401,11 +401,6 @@ public class SchematicCommandUtils { public static void changeType(Player player, SchematicNode node, SchematicType type, SchematicCommand.Extend extend) { SteamwarUser user = getUser(player); - if (Punishment.isPunished(user, - Punishment.PunishmentType.NoSchemSubmitting, - punishment -> SchematicSystem.MESSAGE.send("UTIL_TYPE_PUNISHED", player, punishment.getReason()))) { - return; - } if (node.getOwner() != user.getId()) { SchematicSystem.MESSAGE.send("UTIL_TYPE_NOT_OWN", player); return; @@ -430,11 +425,26 @@ public class SchematicCommandUtils { node.setSchemtype(type); SchematicSystem.MESSAGE.send("UTIL_TYPE_DONE", player); } else if (type.fightType()) { + if (Punishment.isPunished(user, + Punishment.PunishmentType.NoSchemSubmitting, + punishment -> SchematicSystem.MESSAGE.send(punishment.isPerma() ? "UTIL_TYPE_PUNISHED_PERMA" : "UTIL_TYPE_PUNISHED", player, punishment.getReason(), punishment.getEndTime()))) { + return; + } + if (node.getSchemtype().check()) { SchematicSystem.MESSAGE.send("UTIL_TYPE_FIGHT_ALREADY", player); return; } + if (SchematicType.values().stream().filter(SchematicType::check) + .map(schematicType -> SchematicNode.getAllSchematicsOfType(user.getId(), schematicType.toDB())) + .map(List::size) + .reduce(Integer::sum) + .orElse(0) >= 3) { + SchematicSystem.MESSAGE.send("UTIL_TYPE_TOO_MANY", player); + return; + } + CheckSchemType checkSchemType = CheckSchemType.get(type); if (checkSchemType.isAfterDeadline()) { SchematicSystem.MESSAGE.send("UTIL_TYPE_AFTER_DEADLINE", player, checkSchemType.getDeadline()); diff --git a/TNTLeague/build.gradle.kts b/TNTLeague/build.gradle.kts index 0d7fc472..e8b8253a 100644 --- a/TNTLeague/build.gradle.kts +++ b/TNTLeague/build.gradle.kts @@ -1,3 +1,22 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + plugins { steamwar.kotlin } diff --git a/TNTLeague/src/de/steamwar/tntleague/TNTLeague.kt b/TNTLeague/src/de/steamwar/tntleague/TNTLeague.kt index 5479e4d7..378dbfc7 100644 --- a/TNTLeague/src/de/steamwar/tntleague/TNTLeague.kt +++ b/TNTLeague/src/de/steamwar/tntleague/TNTLeague.kt @@ -1,19 +1,36 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + package de.steamwar.tntleague +import de.steamwar.message.Message import de.steamwar.tntleague.command.AcceptCommand import de.steamwar.tntleague.command.InviteCommand import de.steamwar.tntleague.command.LeaveCommand import de.steamwar.tntleague.command.RemoveCommand import de.steamwar.tntleague.events.GlobalListener import de.steamwar.tntleague.events.LobbyListener -import net.kyori.adventure.key.Key -import net.kyori.adventure.translation.GlobalTranslator -import net.kyori.adventure.translation.TranslationRegistry -import net.kyori.adventure.util.UTF8ResourceBundleControl +import de.steamwar.tntleague.game.TNTLeagueTeam import org.bukkit.plugin.java.JavaPlugin -import java.util.* lateinit var plugin: TNTLeague +lateinit var message: Message class TNTLeague : JavaPlugin() { init { @@ -21,19 +38,7 @@ class TNTLeague : JavaPlugin() { } override fun onEnable() { - saveResource("config.yml", false) - saveDefaultConfig() - - val registry = TranslationRegistry.create(Key.key("steamwar:tntleague")) - - val bundleDe = ResourceBundle.getBundle("de.steamwar.tntleague.TNTLeague", Locale.GERMAN, UTF8ResourceBundleControl()) - val bundleEn = ResourceBundle.getBundle("de.steamwar.tntleague.TNTLeague", Locale.US, UTF8ResourceBundleControl()) - registry.defaultLocale(Locale.US) - - registry.registerAll(Locale.GERMAN, bundleDe, true) - registry.registerAll(Locale.US, bundleEn, true) - - GlobalTranslator.translator().addSource(registry) + message = Message("de.steamwar.tntleague.TNTLeague", classLoader) server.pluginManager.registerEvents(LobbyListener, this) server.pluginManager.registerEvents(GlobalListener, this) @@ -46,3 +51,8 @@ class TNTLeague : JavaPlugin() { LeaveCommand.register() } } + +fun String.colorByTeam(team: TNTLeagueTeam?) = when (team) { + null -> "§7${this}" + else -> "§${team.color}${this}" +} diff --git a/TNTLeague/src/de/steamwar/tntleague/TNTLeague.properties b/TNTLeague/src/de/steamwar/tntleague/TNTLeague.properties new file mode 100644 index 00000000..03a4e361 --- /dev/null +++ b/TNTLeague/src/de/steamwar/tntleague/TNTLeague.properties @@ -0,0 +1,49 @@ +# +# This file is a part of the SteamWar software. +# +# Copyright (C) 2024 SteamWar.de-Serverteam +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# + +PREFIX=§eTNT§7League§8» +JOIN=§e{0} §7joined the game! +JOIN_TEAM={0} §7joined the {1} §7team! +QUIT={0} §7left the game! +QUIT_TEAM={0} §7left the {1} §7team! +BLUE=Blue +RED=Red +SHUTDOWN=§7The server stops in §e{0} §7seconds! +TEAM_WIN=§aTeam {0} §awins! +NOT_ENOUGH_COINS=§cYou don't have enough coins to buy this item! +GAME_STARTING=§aThe game starts in §e{0} §aseconds! +GAME_START= +GAME_STARTED=§aThe game has started! +TIME_REMAINING=§e{0} §7minutes remaining! +GAME_ENDED=§cThe game has ended! +DRAW=§cThe game ended in a draw! +DEALER=Shopkeeper +DEALER_ITEM={0} {1} +DEALER_PRICE= +SCOREBOARD_TARGET= +SCOREBOARD_TIME=§7Time§8: §e{0}§8:§e{1} +SCOREBOARD_COINS=§7Coins§8: §e{0} +SCOREBOARD_TEAM=§7Team {0}§8: §e{1} +READY=§aReady +NOT_READY=§cNot ready +IS_READY=§aTeam {0} §ais ready! +IS_NOT_READY=§cTeam {0} §cis not ready! +INVITED={0} §ainvited you to join team {1}§7! *Click* +INVITED_HOVER=§7Click to join team {0}§7! +INVITED_PLAYER=§aInvited §e{0} §ato join your team! \ No newline at end of file diff --git a/TNTLeague/src/de/steamwar/tntleague/TNTLeague_de.properties b/TNTLeague/src/de/steamwar/tntleague/TNTLeague_de.properties new file mode 100644 index 00000000..8d3d3d06 --- /dev/null +++ b/TNTLeague/src/de/steamwar/tntleague/TNTLeague_de.properties @@ -0,0 +1,44 @@ +# +# This file is a part of the SteamWar software. +# +# Copyright (C) 2024 SteamWar.de-Serverteam +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +JOIN=§e{0} §7ist dem Spiel beigetreten! +JOIN_TEAM={0} §7ist Team {1} §7begetreten! +QUIT={0} §7hat das Spiel verlassen! +QUIT_TEAM={0} §7hat Team {1} §7verlassen! +BLUE=Blau +RED=Rot +SHUTDOWN=§7Der Server fährt in §e{0} §7Sekunden herunter! +TEAM_WIN=§aTeam {0} §agewinnt! +NOT_ENOUGH_COINS=§cDu hast nicht genug Coins, um dir das zu kaufen! +GAME_STARTING=§aDas Spiel beginnt in §e{0} §aSekunden! +GAME_STARTED=§aDas Spiel beginnt! +TIME_REMAINING=§7noch §e{0} §7Minuten! +GAME_ENDED=§cDas Spiel ist vorbei! +DRAW=§cKeiner hat gewonnen! +DEALER=Händler +DEALER_PRICE=§7Kosten: §e{0} Coins + +SCOREBOARD_TARGET=§7Ziel§8: {0} +SCOREBOARD_TIME=§7Zeit§8: §e{0}§8:§e{1} +READY=§aBereit +NOT_READY=§cNicht bereit +IS_READY=§aTeam {0} §aist bereit! +IS_NOT_READY=§cTeam {0} §cist nicht bereit! +INVITED={0} §ahat dich in Team {1} §aeingeladen! *Klick* +INVITED_HOVER=§7Team {0} §7beitreten! +INVITED_PLAYER={0} §awurde eingeladen! \ No newline at end of file diff --git a/TNTLeague/src/de/steamwar/tntleague/TNTLeague_de_DE.properties b/TNTLeague/src/de/steamwar/tntleague/TNTLeague_de_DE.properties deleted file mode 100644 index 7200a9e2..00000000 --- a/TNTLeague/src/de/steamwar/tntleague/TNTLeague_de_DE.properties +++ /dev/null @@ -1,18 +0,0 @@ -join={0} ist dem Spiel beigetreten! -joinTeam={0} ist dem {1} team begetreten! -quit={0} hat das Spiel verlassen! -blue=Blau -red=Rot -shutdown=Der Server fährt in {0} sekunden herunter! -teamWin=Team {0} gewinnt! -notEnoughCoins=Du hast nicht genug Coins um dir das zu kaufen! -gameStarting=Das Spiel beginnt in {0} Sekunden! -gameStart=Start in {0} -gameStarted=Das Spiel beginnt! -gameEnded=Das Spiel ist aus! -dealer=Händler -dealerItem= -dealerPrice=Kosten: {0} Coins -scoreboardTarget=Ziel: {0} -scoreboardTime=Zeit: {0}:{1} -scoreboardTeam= \ No newline at end of file diff --git a/TNTLeague/src/de/steamwar/tntleague/TNTLeague_en_US.properties b/TNTLeague/src/de/steamwar/tntleague/TNTLeague_en_US.properties deleted file mode 100644 index 2f7c11e2..00000000 --- a/TNTLeague/src/de/steamwar/tntleague/TNTLeague_en_US.properties +++ /dev/null @@ -1,37 +0,0 @@ -join={0} joined the game! -joinTeam={0} joined the {1} team! -quit={0} left the game! -quitTeam={0} left the {1} team! -blue=Blue -red=Red -shutdown=The server stops in {0} seconds! -teamWin=Team {0} wins! - -notEnoughCoins=You don't have enough coins to buy this item! - -gameStarting=The game starts in {0} seconds! -gameStart=Starting in {0} -gameStarted=The game has started! - -timeRemaining={0} minutes remaining! - -gameEnded=The game has ended! -draw=The game ended in a draw! -chat={0}» {1} - -dealer=Shopkeeper -dealerItem={0} {1} -dealerPrice=Price: {0} Coins - -scoreboardTarget=Target: {0} -scoreboardTime=Time: {0}:{1} -scoreboardTeam=Team {0}: {1} - -ready=Ready -notReady=Not ready -isReady=Team {0} is ready! -isNotReady=Team {0} is not ready! - -invited={0} invited you to join the {1} team! *Click* -invitedHover=Click to join the {0} team! -invitedPlayer=Invited {0} to join your team! \ No newline at end of file diff --git a/TNTLeague/src/de/steamwar/tntleague/command/InviteCommand.kt b/TNTLeague/src/de/steamwar/tntleague/command/InviteCommand.kt index fdfaf359..feec0215 100644 --- a/TNTLeague/src/de/steamwar/tntleague/command/InviteCommand.kt +++ b/TNTLeague/src/de/steamwar/tntleague/command/InviteCommand.kt @@ -21,10 +21,10 @@ package de.steamwar.tntleague.command import de.steamwar.command.SWCommand import de.steamwar.command.TypeValidator +import de.steamwar.tntleague.colorByTeam import de.steamwar.tntleague.game.TNTLeagueGame -import de.steamwar.tntleague.util.* -import net.kyori.adventure.text.event.ClickEvent -import net.kyori.adventure.text.event.HoverEvent +import de.steamwar.tntleague.message +import net.md_5.bungee.api.chat.ClickEvent import org.bukkit.entity.Player object InviteCommand: SWCommand("invite") { @@ -37,20 +37,15 @@ object InviteCommand: SWCommand("invite") { val team = TNTLeagueGame.getTeam(sender)!! team.invites.add(target) - target.sendMessage(translate("invited", sender.name.yellow(), translate(team.name).colorByTeam(team)).basic().clickEvent( - ClickEvent.callback { - if (target !in team.invites) return@callback + message + .send("INVITED", target, message.parse("INVITED_HOVER", target, team.name.colorByTeam(team)), + ClickEvent(ClickEvent.Action.RUN_COMMAND, "/accept " + sender.name), sender.name, team.name.colorByTeam(team), ) - team.invites.remove(target) - team.opposite.invites.remove(target) - team.join(target) - }) - .hoverEvent(HoverEvent.showText(translate("invitedHover", translate(team.name).colorByTeam(team)).green()))) - sender.sendMessage(translate("invitedPlayer", target.name.yellow()).basic()) + message.send("INVITED_PLAYER", sender, target.name) } @Validator("isLeader", local = false) fun isLeader(): TypeValidator { return TypeValidator { _, player, _ -> TNTLeagueGame.getTeam(player)?.leader == player} } -} \ No newline at end of file +} diff --git a/TNTLeague/src/de/steamwar/tntleague/command/LeaveCommand.kt b/TNTLeague/src/de/steamwar/tntleague/command/LeaveCommand.kt index aeb96492..196f4312 100644 --- a/TNTLeague/src/de/steamwar/tntleague/command/LeaveCommand.kt +++ b/TNTLeague/src/de/steamwar/tntleague/command/LeaveCommand.kt @@ -26,5 +26,5 @@ import org.bukkit.entity.Player object LeaveCommand: SWCommand("leave", "l") { @Register - fun leave(player: Player) = TNTLeagueGame.getTeam(player)?.remove(player) + fun leave(player: Player) = TNTLeagueGame.getTeam(player)?.remove(player) ?: Unit } \ No newline at end of file diff --git a/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueConfig.kt b/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueConfig.kt index 30fb8353..cf48afe7 100644 --- a/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueConfig.kt +++ b/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueConfig.kt @@ -1,3 +1,22 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + package de.steamwar.tntleague.config import de.steamwar.tntleague.plugin diff --git a/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueWorldConfig.kt b/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueWorldConfig.kt index faaf73aa..6be87d7e 100644 --- a/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueWorldConfig.kt +++ b/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueWorldConfig.kt @@ -1,15 +1,35 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + package de.steamwar.tntleague.config import de.steamwar.tntleague.plugin -import de.steamwar.tntleague.util.Area -import de.steamwar.tntleague.util.translate +import de.steamwar.kotlin.util.Area +import net.kyori.adventure.text.Component +import org.bukkit.Bukkit import org.bukkit.Location import org.bukkit.Material import org.bukkit.configuration.ConfigurationSection import org.bukkit.configuration.file.YamlConfiguration -import org.bukkit.entity.Villager import org.bukkit.entity.WanderingTrader import java.io.File +import kotlin.properties.Delegates val world by lazy { plugin.server.worlds.first()!! } @@ -33,12 +53,25 @@ object TNTLeagueWorldConfig { ) } - val blueTeam: TeamConfig = TeamConfig.fromConfig(config.getConfigurationSection("blueTeam")!!) - val redTeam: TeamConfig = TeamConfig.fromConfig(config.getConfigurationSection("redTeam")!!) - val lobby: Location = config.getLocation("lobby", blueTeam.spawnLocation.clone().add(redTeam.spawnLocation).multiply(0.5))!! - val targetMaterial: Material = Material.matchMaterial(config.getString("targetMaterial", "IRON_BLOCK")!!)!! - val minHeight: Int = config.getInt("minHeight", 0) - val target: Int = config.getInt("target", -1) + lateinit var blueTeam: TeamConfig + lateinit var redTeam: TeamConfig + lateinit var lobby: Location + lateinit var targetMaterial: Material + var minHeight by Delegates.notNull() + var target by Delegates.notNull() + + init { + try { + blueTeam = TeamConfig.fromConfig(config.getConfigurationSection("blueTeam")!!) + redTeam = TeamConfig.fromConfig(config.getConfigurationSection("redTeam")!!) + lobby = config.getWorldLocation("lobby", blueTeam.spawnLocation.clone().add(redTeam.spawnLocation).multiply(0.5)) + targetMaterial = Material.matchMaterial(config.getString("targetMaterial", "IRON_BLOCK")!!)!! + minHeight = config.getInt("minHeight", 0) + target = config.getInt("target", -1) + } catch (e: NullPointerException) { + Bukkit.shutdown() + } + } @JvmRecord data class TeamConfig( @@ -49,11 +82,11 @@ object TNTLeagueWorldConfig { ) { companion object { fun fromConfig(config: ConfigurationSection): TeamConfig { - val spawnLocation = config.getLocation("spawn")!! - val dealerSpawn = config.getLocation("dealerSpawn")!! - val itemSpawn = config.getLocation("itemSpawn")!! - val targetPos1 = config.getLocation("targetMin")!! - val targetPos2 = config.getLocation("targetMax")!! + val spawnLocation = config.getWorldLocation("spawn") + val dealerSpawn = config.getWorldLocation("dealerSpawn") + val itemSpawn = config.getWorldLocation("itemSpawn") + val targetPos1 = config.getWorldLocation("targetMin") + val targetPos2 = config.getWorldLocation("targetMax") spawnDealer(dealerSpawn) @@ -62,7 +95,7 @@ object TNTLeagueWorldConfig { private fun spawnDealer(loc: Location) = world.spawn(loc, WanderingTrader::class.java) .apply { - customName(translate("dealer")) + customName(Component.text("Shop")) isCustomNameVisible = false isInvulnerable = true isSilent = true @@ -73,3 +106,19 @@ object TNTLeagueWorldConfig { } } } + +fun ConfigurationSection.getWorldLocation(s: String, default: Location? = null): Location { + val section = getConfigurationSection(s) ?: return default!! + + val x = section.getDouble("x") + val y = section.getDouble("y") + val z = section.getDouble("z") + val pitch = section.getDouble("pitch") + val yaw = section.getDouble("yaw") + + return Location( + plugin.server.worlds.first(), + x, y, z, + yaw.toFloat(), pitch.toFloat() + ) +} diff --git a/TNTLeague/src/de/steamwar/tntleague/events/DummyListener.kt b/TNTLeague/src/de/steamwar/tntleague/events/DummyListener.kt index f9f616de..917ba5be 100644 --- a/TNTLeague/src/de/steamwar/tntleague/events/DummyListener.kt +++ b/TNTLeague/src/de/steamwar/tntleague/events/DummyListener.kt @@ -21,5 +21,4 @@ package de.steamwar.tntleague.events import org.bukkit.event.Listener -object DummyListener: Listener { -} \ No newline at end of file +object DummyListener: Listener \ No newline at end of file diff --git a/TNTLeague/src/de/steamwar/tntleague/events/GlobalListener.kt b/TNTLeague/src/de/steamwar/tntleague/events/GlobalListener.kt index f2930adb..e930106b 100644 --- a/TNTLeague/src/de/steamwar/tntleague/events/GlobalListener.kt +++ b/TNTLeague/src/de/steamwar/tntleague/events/GlobalListener.kt @@ -1,18 +1,39 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + package de.steamwar.tntleague.events +import de.steamwar.tntleague.colorByTeam import de.steamwar.tntleague.config.TNTLeagueWorldConfig import de.steamwar.tntleague.game.TNTLeagueGame import de.steamwar.tntleague.game.TNTLeagueTeam -import de.steamwar.tntleague.inventory.SWInventoryHolder +import de.steamwar.kotlin.inventory.SWInventoryHolder +import de.steamwar.tntleague.message import de.steamwar.tntleague.plugin -import de.steamwar.tntleague.util.* -import io.papermc.paper.event.player.AsyncChatEvent +import org.bukkit.Bukkit import org.bukkit.GameMode import org.bukkit.Material import org.bukkit.event.EventHandler import org.bukkit.event.EventPriority import org.bukkit.event.Listener import org.bukkit.event.entity.PlayerDeathEvent +import org.bukkit.event.inventory.CraftItemEvent import org.bukkit.event.inventory.InventoryClickEvent import org.bukkit.event.player.PlayerJoinEvent import org.bukkit.event.player.PlayerMoveEvent @@ -27,7 +48,7 @@ object GlobalListener: Listener { with(e.player) { teleport(TNTLeagueWorldConfig.lobby) inventory.clear() - plugin.server.broadcast(translate("join", name.bold()).basic()) + message.broadcast("JOIN", name) isOp = false gameMode = GameMode.SPECTATOR respawnLocation = TNTLeagueWorldConfig.lobby @@ -37,8 +58,17 @@ object GlobalListener: Listener { @EventHandler(priority = EventPriority.HIGHEST) fun onPlayerQuit(e: PlayerQuitEvent) { e.quitMessage(null) - plugin.server.broadcast(translate("quit", e.player.name.bold().colorByTeam(TNTLeagueGame.getTeam(e.player))).basic()) + message.broadcast("QUIT", e.player.name.colorByTeam(TNTLeagueGame.getTeam(e.player))) TNTLeagueGame.playerLeave(e.player) + + if (plugin.server.onlinePlayers.size == 1 && plugin.server.onlinePlayers.first() == e.player) { + plugin.server.shutdown() + } + } + + @EventHandler + fun onPlayerCraft(e: CraftItemEvent) { + e.isCancelled = true } @EventHandler(priority = EventPriority.LOWEST) @@ -67,6 +97,7 @@ object GlobalListener: Listener { fun onPlayerDeath(e: PlayerDeathEvent) { e.deathMessage(null) e.drops.clear() + e.keepInventory = true e.itemsToKeep.removeIf { it.type != Material.DIAMOND_PICKAXE } } @@ -78,11 +109,4 @@ object GlobalListener: Listener { null -> e.respawnLocation = TNTLeagueWorldConfig.lobby } } - - @EventHandler - fun onChat(e: AsyncChatEvent) { - e.renderer { source, sourceDisplayName, message, _ -> - translate("chat", sourceDisplayName.colorByTeam(TNTLeagueGame.getTeam(source)), message).basic() - } - } } \ No newline at end of file diff --git a/TNTLeague/src/de/steamwar/tntleague/events/IngameListener.kt b/TNTLeague/src/de/steamwar/tntleague/events/IngameListener.kt index e688dcbc..e48ea7e6 100644 --- a/TNTLeague/src/de/steamwar/tntleague/events/IngameListener.kt +++ b/TNTLeague/src/de/steamwar/tntleague/events/IngameListener.kt @@ -1,3 +1,22 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + package de.steamwar.tntleague.events import de.steamwar.scoreboard.SWScoreboard @@ -13,12 +32,11 @@ import org.bukkit.entity.EntityType import org.bukkit.event.EventHandler import org.bukkit.event.Listener import org.bukkit.event.entity.EntityExplodeEvent -import org.bukkit.event.entity.PlayerDeathEvent +import org.bukkit.event.player.PlayerAttemptPickupItemEvent import org.bukkit.event.player.PlayerDropItemEvent import org.bukkit.event.player.PlayerInteractEntityEvent import org.bukkit.event.player.PlayerJoinEvent import org.bukkit.event.player.PlayerMoveEvent -import org.bukkit.event.player.PlayerQuitEvent object IngameListener: Listener { @@ -26,7 +44,7 @@ object IngameListener: Listener { fun onEntityInteract(e: PlayerInteractEntityEvent) { if (e.player.gameMode == GameMode.SPECTATOR) return - if(e.rightClicked.type == EntityType.VILLAGER) { + if(e.rightClicked.type == EntityType.WANDERING_TRADER) { e.isCancelled = true e.player.openInventory(DealerInventory(e.player).getInventory()) } @@ -63,6 +81,17 @@ object IngameListener: Listener { } } + @EventHandler + fun onPickupCoins(e: PlayerAttemptPickupItemEvent) { + if (e.item.itemStack.isSimilar(DealerInventory.coins)) { + TNTLeagueGame.getTeam(e.player)?.coins = e.item.itemStack.amount + (TNTLeagueGame.getTeam(e.player)?.coins ?: 0) + + e.item.itemStack.amount = 0 + e.isCancelled = true + e.flyAtPlayer = true + } + } + private fun getTeamByTargetLocation(location: Location): TNTLeagueTeam? = when (location) { in TNTLeagueWorldConfig.redTeam.target -> TNTLeagueGame.redTeam diff --git a/TNTLeague/src/de/steamwar/tntleague/events/LobbyListener.kt b/TNTLeague/src/de/steamwar/tntleague/events/LobbyListener.kt index e88cfbaa..d61be80b 100644 --- a/TNTLeague/src/de/steamwar/tntleague/events/LobbyListener.kt +++ b/TNTLeague/src/de/steamwar/tntleague/events/LobbyListener.kt @@ -1,22 +1,33 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + package de.steamwar.tntleague.events import de.steamwar.tntleague.game.TNTLeagueGame -import de.steamwar.tntleague.plugin -import de.steamwar.tntleague.util.basic -import de.steamwar.tntleague.util.colorByTeam -import de.steamwar.tntleague.util.translate -import de.steamwar.tntleague.util.yellow -import io.papermc.paper.util.Tick +import org.bukkit.GameMode +import org.bukkit.entity.EntityType import org.bukkit.event.EventHandler import org.bukkit.event.EventPriority import org.bukkit.event.Listener -import org.bukkit.event.block.Action import org.bukkit.event.entity.EntityDamageEvent import org.bukkit.event.inventory.InventoryClickEvent -import org.bukkit.event.player.PlayerDropItemEvent -import org.bukkit.event.player.PlayerInteractEvent -import org.bukkit.event.player.PlayerJoinEvent -import org.bukkit.event.player.PlayerQuitEvent +import org.bukkit.event.player.* object LobbyListener: Listener { @@ -30,8 +41,7 @@ object LobbyListener: Listener { @EventHandler(priority = EventPriority.LOWEST) fun onPlayerQuit(e: PlayerQuitEvent) { - val team = TNTLeagueGame.getTeam(e.player) ?: return - team.leave(e.player) + TNTLeagueGame.playerLeave(e.player) } @EventHandler @@ -58,4 +68,13 @@ object LobbyListener: Listener { e.isCancelled = true } } + + @EventHandler + fun onEntityInteract(e: PlayerInteractEntityEvent) { + if (e.player.gameMode == GameMode.SPECTATOR) return + + if(e.rightClicked.type == EntityType.WANDERING_TRADER) { + e.isCancelled = true + } + } } \ No newline at end of file diff --git a/TNTLeague/src/de/steamwar/tntleague/game/TNTLeagueGame.kt b/TNTLeague/src/de/steamwar/tntleague/game/TNTLeagueGame.kt index 94191c4e..8c278620 100644 --- a/TNTLeague/src/de/steamwar/tntleague/game/TNTLeagueGame.kt +++ b/TNTLeague/src/de/steamwar/tntleague/game/TNTLeagueGame.kt @@ -1,9 +1,30 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + package de.steamwar.tntleague.game +import de.steamwar.kotlin.util.Area import de.steamwar.scoreboard.SWScoreboard import de.steamwar.sql.Fight import de.steamwar.sql.FightPlayer import de.steamwar.sql.SteamwarUser +import de.steamwar.tntleague.colorByTeam import de.steamwar.tntleague.config.TNTLeagueConfig import de.steamwar.tntleague.config.TNTLeagueWorldConfig import de.steamwar.tntleague.config.world @@ -11,19 +32,16 @@ import de.steamwar.tntleague.events.DummyListener import de.steamwar.tntleague.events.IngameListener import de.steamwar.tntleague.events.LobbyListener import de.steamwar.tntleague.inventory.DealerInventory +import de.steamwar.tntleague.message import de.steamwar.tntleague.plugin import de.steamwar.tntleague.util.* -import net.kyori.adventure.bossbar.BossBar -import net.kyori.adventure.sound.Sound import org.bukkit.GameMode import org.bukkit.Location import org.bukkit.Material -import org.bukkit.block.data.type.TNT -import org.bukkit.entity.Entity +import org.bukkit.Sound import org.bukkit.entity.Item import org.bukkit.entity.Player import org.bukkit.entity.TNTPrimed -import org.bukkit.entity.Villager import org.bukkit.event.HandlerList import org.bukkit.event.Listener import org.bukkit.inventory.ItemStack @@ -62,7 +80,7 @@ object TNTLeagueGame { blueTeam.start() redTeam.start() - plugin.server.broadcast(translate("gameStarted").success()) + message.broadcast("GAME_STARTED") val tnt = ItemStack(Material.TNT) @@ -82,13 +100,18 @@ object TNTLeagueGame { timerTask = plugin.server.scheduler.runTaskTimer(plugin, bukkit { gameTimeRemaining-- if (gameTimeRemaining == 0) { - draw(WinReason.TIMEOUT) + if (blueTeam.damagedBlocks > redTeam.damagedBlocks) + win(blueTeam, WinReason.TIMEOUT) + else if (redTeam.damagedBlocks > blueTeam.damagedBlocks) + win(redTeam, WinReason.TIMEOUT) + else + draw(WinReason.TIMEOUT) return@bukkit } if (gameTimeRemaining % 300 == 0) { - plugin.server.broadcast(translate("timeRemaining", (gameTimeRemaining / 60).toString().yellow()).basic()) - plugin.server.onlinePlayers.forEach { it.playSound(Sound.sound(org.bukkit.Sound.BLOCK_NOTE_BLOCK_PLING.key, Sound.Source.MASTER, 1f, 1f)) } + message.broadcast("TIME_REMAINING", (gameTimeRemaining / 60)) + plugin.server.onlinePlayers.forEach { it.playSound(it.location, Sound.BLOCK_NOTE_BLOCK_PLING, 1f, 1f) } } }, 20, 20) } @@ -102,10 +125,10 @@ object TNTLeagueGame { plugin.server.onlinePlayers.forEach { it.gameMode = GameMode.SPECTATOR SWScoreboard.impl.removeScoreboard(it) - it.playSound(Sound.sound(org.bukkit.Sound.ENTITY_ENDER_DRAGON_DEATH.key, Sound.Source.MASTER, 1f, 1f)) + it.playSound(it.location, Sound.ENTITY_ENDER_DRAGON_DEATH, 1f, 1f) } - plugin.server.broadcast(translate("gameEnded").success()) + message.broadcast("GAME_ENDED") spawnerTask.cancel() @@ -116,7 +139,7 @@ object TNTLeagueGame { plugin.server.shutdown() } - plugin.server.broadcast(translate("shutdown", shutdown.toString().yellow()).basic()) + message.broadcast("SHUTDOWN", shutdown) shutdown-- }, 20, 20) @@ -135,19 +158,15 @@ object TNTLeagueGame { state = GameState.STARTING var countdown = TNTLeagueConfig.config.startDelay - plugin.server.broadcast(translate("gameStarting", countdown.toString().yellow()).basic()) - val bar = BossBar.bossBar(translate("gameStart", countdown.toString().yellow()).gray(), (TNTLeagueConfig.config.startDelay - countdown) / TNTLeagueConfig.config.startDelay.toFloat(), BossBar.Color.GREEN, BossBar.Overlay.NOTCHED_10) - plugin.server.onlinePlayers.forEach { bar.addViewer(it) } + message.broadcast("GAME_STARTING", countdown.toString()) task = plugin.server.scheduler.scheduleSyncRepeatingTask(plugin, { - plugin.server.onlinePlayers.forEach { it.playSound(Sound.sound(org.bukkit.Sound.ENTITY_EXPERIENCE_ORB_PICKUP.key, Sound.Source.MASTER, 1f, 1f)) } - if (countdown-- == 0) { - plugin.server.onlinePlayers.forEach { it.hideBossBar(bar) } + plugin.server.onlinePlayers.forEach { it.playSound(it.location, Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1f, 1f) } + if (--countdown == 0) { + plugin.server.onlinePlayers.forEach { it.level = 0 } task = task?.also { plugin.server.scheduler.cancelTask(it) }.let { null } setup() } else { - bar.name(translate("gameStart", countdown.toString().yellow()).gray()) - bar.progress((TNTLeagueConfig.config.startDelay - countdown) / TNTLeagueConfig.config.startDelay.toFloat()) - plugin.server.onlinePlayers.filter { !it.activeBossBars().contains(bar) }.forEach { bar.addViewer(it) } + plugin.server.onlinePlayers.forEach { it.level = countdown } } }, 20, 20) @@ -161,10 +180,7 @@ object TNTLeagueGame { blueTeam.invites.remove(player) redTeam.invites.remove(player) getTeam(player)?.apply { - members.remove(player) - if (leader == player) { - win(this.opposite, WinReason.LEAVE) - } + remove(player) } } @@ -173,7 +189,6 @@ object TNTLeagueGame { if (state == GameState.STARTING) { task = task?.also { plugin.server.scheduler.cancelTask(it) }.let { null } - plugin.server.onlinePlayers.forEach { p -> p.activeBossBars().forEach { it.removeViewer(p) } } state = GameState.LOBBY } } @@ -181,16 +196,14 @@ object TNTLeagueGame { fun win(tntLeagueTeam: TNTLeagueTeam, reason: WinReason) { if (state != GameState.RUNNING) return end() - plugin.server.broadcast(translate("teamWin", translate(tntLeagueTeam.name).color(tntLeagueTeam.color)).success()) - statistic(tntLeagueTeam, reason) + plugin.server.onlinePlayers.forEach { message.send("TEAM_WIN", it, message.parse(tntLeagueTeam.name, it).colorByTeam(tntLeagueTeam)) } explode(tntLeagueTeam.opposite) } fun draw(reason: WinReason) { if (state != GameState.RUNNING) return end() - plugin.server.broadcast(translate("draw").success()) - statistic(null, reason) + message.broadcast("DRAW") } fun explode(team: TNTLeagueTeam) { @@ -204,32 +217,6 @@ object TNTLeagueGame { } } - private fun statistic(winTeam: TNTLeagueTeam?, reason: WinReason) { - val fightId = Fight.create( - "TNTLeague", - world.name, - start, - TNTLeagueConfig.config.gameTime - gameTimeRemaining, - SteamwarUser.get(blueTeam.leader!!.uniqueId).id, - SteamwarUser.get(redTeam.leader!!.uniqueId).id, - null, - null, - when (winTeam) { - blueTeam -> 1 - redTeam -> 2 - else -> 0 - }, - when (reason) { - WinReason.TIMEOUT -> "TIMEOUT" - WinReason.DESTROYED -> "DESTROYED" - WinReason.LEAVE -> "LEAVE" - } - ) - - addTeamMember(blueTeam, fightId) - addTeamMember(redTeam, fightId) - } - private fun addTeamMember(team: TNTLeagueTeam, fightId: Int) { team.members.filter { team.leader != it } .forEach { diff --git a/TNTLeague/src/de/steamwar/tntleague/game/TNTLeagueTeam.kt b/TNTLeague/src/de/steamwar/tntleague/game/TNTLeagueTeam.kt index cafa70c2..cfb23dca 100644 --- a/TNTLeague/src/de/steamwar/tntleague/game/TNTLeagueTeam.kt +++ b/TNTLeague/src/de/steamwar/tntleague/game/TNTLeagueTeam.kt @@ -1,18 +1,38 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + package de.steamwar.tntleague.game +import de.steamwar.tntleague.colorByTeam import de.steamwar.tntleague.config.TNTLeagueWorldConfig import de.steamwar.tntleague.config.targetedBlocks +import de.steamwar.tntleague.game.TNTLeagueGame.WinReason +import de.steamwar.tntleague.game.TNTLeagueGame.win +import de.steamwar.tntleague.message import de.steamwar.tntleague.plugin -import de.steamwar.tntleague.util.* -import net.kyori.adventure.sound.Sound -import net.kyori.adventure.text.format.NamedTextColor -import net.kyori.adventure.text.format.TextColor +import net.kyori.adventure.text.Component import org.bukkit.GameMode import org.bukkit.Material +import org.bukkit.Sound import org.bukkit.enchantments.Enchantment import org.bukkit.entity.Player import org.bukkit.inventory.ItemStack -import java.awt.Color.green data class TNTLeagueTeam(val config: TNTLeagueWorldConfig.TeamConfig, private val team: Team) { @@ -31,24 +51,18 @@ data class TNTLeagueTeam(val config: TNTLeagueWorldConfig.TeamConfig, private va val invites = mutableListOf() val name: String - get() = team.name.lowercase() + get() = team.name.uppercase() - val color: TextColor + val color: Char get() = team.color var isReady: Boolean = false set(value) { field = value leader?.inventory?.setItem(4, readyItem()) - leader?.playSound(Sound.sound(org.bukkit.Sound.BLOCK_NOTE_BLOCK_PLING.key, Sound.Source.MASTER, 1f, 1f)) + leader?.let { it.playSound(it.location, Sound.BLOCK_NOTE_BLOCK_PLING, 1f, 1f) } - plugin.server.onlinePlayers.forEach { it.sendActionBar(translate(if (value) "isReady" else "isNotReady", translate(this.name).colorByTeam(this)).let { cmp -> - if (value) { - cmp.green() - } else { - cmp.red() - } - }) } + message.broadcastActionbar(if (value) "IS_READY" else "IS_NOT_READY", name.colorByTeam(this)) if (value && opposite.isReady) { TNTLeagueGame.checkStart() @@ -63,6 +77,8 @@ data class TNTLeagueTeam(val config: TNTLeagueWorldConfig.TeamConfig, private va } } + var coins: Int = 0 + val opposite: TNTLeagueTeam get() = when (team) { Team.BLUE -> TNTLeagueGame.redTeam @@ -76,7 +92,7 @@ data class TNTLeagueTeam(val config: TNTLeagueWorldConfig.TeamConfig, private va teleport(config.spawnLocation) gameMode = GameMode.ADVENTURE inventory.clear() - plugin.server.broadcast(translate("joinTeam", name().colorByTeam(this@TNTLeagueTeam), translate(this@TNTLeagueTeam.name).colorByTeam(this@TNTLeagueTeam)).basic()) + message.broadcast("JOIN_TEAM", name.colorByTeam(this@TNTLeagueTeam), this@TNTLeagueTeam.name.colorByTeam(this@TNTLeagueTeam)) } if (leader == null) { @@ -89,13 +105,13 @@ data class TNTLeagueTeam(val config: TNTLeagueWorldConfig.TeamConfig, private va fun readyItem() = if (isReady) { ItemStack.of(Material.LIME_DYE).apply { itemMeta = itemMeta.apply { - displayName(translate("ready").green().translate(leader!!)) + displayName(Component.text(message.parse("READY", leader!!))) } } } else { ItemStack.of(Material.RED_DYE).apply { itemMeta = itemMeta.apply { - displayName(translate("notReady").red().translate(leader!!)) + displayName(Component.text(message.parse("NOT_READY", leader!!))) } } } @@ -113,11 +129,8 @@ data class TNTLeagueTeam(val config: TNTLeagueWorldConfig.TeamConfig, private va } fun leave(player: Player) { - if (TNTLeagueGame.state == TNTLeagueGame.GameState.RUNNING) { - TNTLeagueGame.playerLeave(player) - } else { - members.remove(player) - + members.remove(player) + if (TNTLeagueGame.state != TNTLeagueGame.GameState.RUNNING) { if (members.isEmpty()) { plugin.server.onlinePlayers.firstOrNull { it != player && TNTLeagueGame.getTeam(it) == null }?.run { members.add(this) @@ -125,6 +138,14 @@ data class TNTLeagueTeam(val config: TNTLeagueWorldConfig.TeamConfig, private va } if (leader == player) { leader = members.firstOrNull() + + if (leader == null && TNTLeagueGame.state == TNTLeagueGame.GameState.LOBBY) { + isReady = false + } + } + } else if (TNTLeagueGame.state == TNTLeagueGame.GameState.RUNNING) { + if (members.isEmpty()) { + win(this.opposite, WinReason.LEAVE) } } } @@ -135,12 +156,12 @@ data class TNTLeagueTeam(val config: TNTLeagueWorldConfig.TeamConfig, private va teleport(TNTLeagueWorldConfig.lobby) gameMode = GameMode.SPECTATOR inventory.clear() - plugin.server.broadcast(translate("quitTeam", name().colorByTeam(this@TNTLeagueTeam), translate(this@TNTLeagueTeam.name).colorByTeam(this@TNTLeagueTeam)).basic()) + message.broadcast("QUIT_TEAM", name.colorByTeam(this@TNTLeagueTeam), this@TNTLeagueTeam.name.colorByTeam(this@TNTLeagueTeam)) } } - enum class Team(val color: TextColor) { - BLUE(NamedTextColor.BLUE), - RED(NamedTextColor.RED); + enum class Team(val color: Char) { + BLUE('9'), + RED('c'); } } \ No newline at end of file diff --git a/TNTLeague/src/de/steamwar/tntleague/inventory/DealerInventory.kt b/TNTLeague/src/de/steamwar/tntleague/inventory/DealerInventory.kt index 04c1c288..dc5813b8 100644 --- a/TNTLeague/src/de/steamwar/tntleague/inventory/DealerInventory.kt +++ b/TNTLeague/src/de/steamwar/tntleague/inventory/DealerInventory.kt @@ -1,14 +1,35 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + package de.steamwar.tntleague.inventory +import de.steamwar.kotlin.inventory.SWInventoryHolder import de.steamwar.tntleague.config.TNTLeagueConfig +import de.steamwar.tntleague.game.TNTLeagueGame +import de.steamwar.tntleague.message import de.steamwar.tntleague.plugin -import de.steamwar.tntleague.util.* -import net.kyori.adventure.sound.Sound import net.kyori.adventure.text.Component -import net.kyori.adventure.text.format.Style +import net.kyori.adventure.text.format.NamedTextColor import net.kyori.adventure.text.format.TextDecoration import org.bukkit.Material import org.bukkit.NamespacedKey +import org.bukkit.Sound import org.bukkit.entity.Player import org.bukkit.inventory.Inventory import org.bukkit.inventory.ItemStack @@ -16,7 +37,7 @@ import org.bukkit.persistence.PersistentDataType import java.util.* import kotlin.math.ceil -class DealerInventory(player: Player): SWInventoryHolder() { +class DealerInventory(val player: Player): SWInventoryHolder() { init { items.forEachIndexed { index, item -> @@ -24,19 +45,21 @@ class DealerInventory(player: Player): SWInventoryHolder() { val price = item.second.price * if (it.isShiftClick) 5 else 1 val amount = item.second.amount * if (it.isShiftClick) 5 else 1 - if (!player.inventory.containsAtLeast(coins, price)) { - player.sendMessage(translate("notEnoughCoins").error()) - player.playSound(Sound.sound(org.bukkit.Sound.ENTITY_VILLAGER_HURT.key, net.kyori.adventure.sound.Sound.Source.MASTER, 1f, 1f)) + val team = TNTLeagueGame.getTeam(player) ?: return@to + + if (team.coins < price) { + message.send("NOT_ENOUGH_COINS", player) + player.playSound(player, Sound.ENTITY_VILLAGER_HURT, 1f, 1f) return@to } - player.inventory.removeItem(coins.asQuantity(price)) + team.coins -= price player.inventory.addItem(ItemStack.of(item.first.type, amount)) } } } - override fun createInventory(): Inventory = plugin.server.createInventory(this, ceil(TNTLeagueConfig.config.prices.size / 9f).toInt() * 9, translate("dealer").reset()) + override fun createInventory(): Inventory = plugin.server.createInventory(this, ceil(TNTLeagueConfig.config.prices.size / 9f).toInt() * 9, Component.text(message.parse("DEALER", player))) companion object { private val priceKey = NamespacedKey(plugin, "price") @@ -45,7 +68,7 @@ class DealerInventory(player: Player): SWInventoryHolder() { val coins = ItemStack(Material.RAW_GOLD).apply { itemMeta = itemMeta.apply { - displayName(Component.text("Coins").bold().gold()) + displayName(Component.text("Coins").color(NamedTextColor.GOLD)) persistentDataContainer.apply { set(coinKey, PersistentDataType.BOOLEAN, true) } @@ -58,11 +81,13 @@ class DealerInventory(player: Player): SWInventoryHolder() { prices.map { (material, price) -> ItemStack(material).apply { itemMeta = itemMeta.apply { - displayName(material.name.lowercase().replace("_", " ") - .replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() } - .component().gray().appendSpace().append(price.amount.toString().component().yellow())) + displayName(Component.text(material.name.lowercase().replace("_", " ") + .replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }) + .color(NamedTextColor.GRAY).appendSpace().append(Component.text(price.amount).color(NamedTextColor.YELLOW))) + + amount = price.amount - lore(listOf(price.price.toString().component().yellow().bold().appendSpace().append(Component.text("Coins").yellow()))) + lore(listOf(Component.text(price.price).color(NamedTextColor.YELLOW).decorate(TextDecoration.BOLD).appendSpace().append(Component.text("Coins").color(NamedTextColor.YELLOW)))) persistentDataContainer.apply { set(priceKey, PersistentDataType.INTEGER, price.price) set(amountKey, PersistentDataType.INTEGER, price.amount) diff --git a/TNTLeague/src/de/steamwar/tntleague/util/Style.kt b/TNTLeague/src/de/steamwar/tntleague/util/Style.kt deleted file mode 100644 index 3ef28b9a..00000000 --- a/TNTLeague/src/de/steamwar/tntleague/util/Style.kt +++ /dev/null @@ -1,73 +0,0 @@ -package de.steamwar.tntleague.util - -import de.steamwar.tntleague.game.TNTLeagueTeam -import net.kyori.adventure.text.Component -import net.kyori.adventure.text.ComponentLike -import net.kyori.adventure.text.TranslatableComponent -import net.kyori.adventure.text.format.NamedTextColor -import net.kyori.adventure.text.format.Style -import net.kyori.adventure.text.format.TextDecoration -import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer -import net.kyori.adventure.translation.GlobalTranslator -import org.bukkit.entity.Player -import java.util.Locale - -val prefix = Component.text("Steam").yellow() - .append(Component.text("War").darkGray()) - .appendSpace() - -val tntLeaguePrefix = Component.text("TNT").color(NamedTextColor.DARK_RED) - .append(Component.text("League").color(NamedTextColor.GOLD)) - -val tntLeagueChatPrefix: Component = tntLeaguePrefix - .append(Component.text("»").darkGray()) - .appendSpace() - -fun TranslatableComponent.basic(): Component = tntLeagueChatPrefix.append(this.gray()) - -fun TranslatableComponent.error(): Component = tntLeagueChatPrefix.append(this.red()) - -fun TranslatableComponent.success(): Component = tntLeagueChatPrefix.append(this.green()) - -fun String.component(): Component = Component.text(this) - -fun Component.bold(): Component = this.decorate(TextDecoration.BOLD) - -fun String.bold(): Component = this.component().bold() - -fun Component.yellow(): Component = this.color(NamedTextColor.YELLOW) - -fun String.yellow(): Component = this.component().yellow() - -fun Component.red(): Component = this.color(NamedTextColor.RED) - -fun String.red(): Component = this.component().red() - -fun Component.green(): Component = this.color(NamedTextColor.GREEN) - -fun String.green(): Component = this.component().green() - -fun Component.gray(): Component = this.color(NamedTextColor.GRAY) - -fun String.gray(): Component = this.component().gray() - -fun Component.darkGray(): Component = this.color(NamedTextColor.DARK_GRAY) - -fun String.darkGray(): Component = this.component().darkGray() - -fun Component.gold(): Component = this.color(NamedTextColor.GOLD) - -fun translate(key: String, vararg args: ComponentLike): TranslatableComponent = Component.translatable(key, *args).decoration(TextDecoration.ITALIC, false) - -fun Component.reset(): Component = this.style(Style.empty()) - -fun Component.colorByTeam(team: TNTLeagueTeam?) = when (team) { - null -> this.gray() - else -> this.color(team.color) -} - -fun Component.translate(locale: Locale): Component = GlobalTranslator.render(this, locale) - -fun Component.translate(p: Player): Component = this.translate(p.locale()) - -fun Component.toLegacy(): String = LegacyComponentSerializer.legacySection().serialize(this) diff --git a/TNTLeague/src/de/steamwar/tntleague/util/TNTLeagueScoreboard.kt b/TNTLeague/src/de/steamwar/tntleague/util/TNTLeagueScoreboard.kt index 7b8da592..27c129de 100644 --- a/TNTLeague/src/de/steamwar/tntleague/util/TNTLeagueScoreboard.kt +++ b/TNTLeague/src/de/steamwar/tntleague/util/TNTLeagueScoreboard.kt @@ -20,38 +20,46 @@ package de.steamwar.tntleague.util import de.steamwar.scoreboard.ScoreboardCallback +import de.steamwar.tntleague.colorByTeam import de.steamwar.tntleague.config.targetedBlocks import de.steamwar.tntleague.game.TNTLeagueGame -import net.kyori.adventure.text.Component +import de.steamwar.tntleague.game.TNTLeagueTeam +import de.steamwar.tntleague.message import org.bukkit.entity.Player import kotlin.collections.HashMap -private val scoreboardTitle by lazy { tntLeaguePrefix.toLegacy() } - data class TNTLeagueScoreboard(val p: Player): ScoreboardCallback { override fun getData(): HashMap { - val lines = mutableListOf() + val lines = mutableListOf() - lines.add(Component.space().green()) + lines.add("§1") val minutes = TNTLeagueGame.gameTimeRemaining.floorDiv(60) val seconds = TNTLeagueGame.gameTimeRemaining.rem(60).toString().padStart(2, '0') - lines.add(translate("scoreboardTime", minutes.toString().yellow(), seconds.yellow()).gray()) + lines.add(message.parse("SCOREBOARD_TIME", p, minutes, seconds)) - lines.add(Component.space().yellow()) + lines.add("§2") - with(TNTLeagueGame.blueTeam) { - lines.add(translate("scoreboardTeam", translate(name).colorByTeam(this), (targetedBlocks - damagedBlocks).toString().yellow()).gray()) + when (val team = TNTLeagueGame.getTeam(p)) { + is TNTLeagueTeam -> lines.add(message.parse("SCOREBOARD_COINS", p, team.coins)) + else -> lines.add(message.parse("SCOREBOARD_COINS", p, + "§${TNTLeagueGame.blueTeam.color}${TNTLeagueGame.blueTeam.coins}§8:§${TNTLeagueGame.redTeam.color}${TNTLeagueGame.redTeam.coins}")) } + + lines.add("§3") + with(TNTLeagueGame.redTeam) { - lines.add(translate("scoreboardTeam", translate(name).colorByTeam(this), (targetedBlocks - damagedBlocks).toString().yellow()).gray()) + lines.add(message.parse("SCOREBOARD_TEAM", p, message.parse(name, p).colorByTeam(this), targetedBlocks - damagedBlocks)) + } + with(TNTLeagueGame.blueTeam) { + lines.add(message.parse("SCOREBOARD_TEAM", p, message.parse(name, p).colorByTeam(this), targetedBlocks - damagedBlocks)) } - lines.add(Component.space().gray()) + lines.add("§4") return lines - .foldIndexed(HashMap()) { index, acc, component -> acc.also { it[component.translate(p).toLegacy()] = index } } + .foldIndexed(HashMap()) { index, acc, component -> acc.also { it[component] = index } } } - override fun getTitle(): String = scoreboardTitle + override fun getTitle(): String = message.parse("PREFIX", p).dropLast(1) } diff --git a/TNTLeague/src/paper-plugin.yml b/TNTLeague/src/paper-plugin.yml index 8687424a..4e740ea9 100644 --- a/TNTLeague/src/paper-plugin.yml +++ b/TNTLeague/src/paper-plugin.yml @@ -4,7 +4,10 @@ main: de.steamwar.tntleague.TNTLeague load: POSTWORLD api-version: '1.21' dependencies: - - name: SpigotCore - required: true - - name: KotlinCore - required: true \ No newline at end of file + server: + SpigotCore: + required: true + load: BEFORE + KotlinCore: + required: true + load: BEFORE \ No newline at end of file diff --git a/VelocityCore/Persistent/src/de/steamwar/persistent/Arenaserver.java b/VelocityCore/Persistent/src/de/steamwar/persistent/Arenaserver.java index c283090b..450d771a 100644 --- a/VelocityCore/Persistent/src/de/steamwar/persistent/Arenaserver.java +++ b/VelocityCore/Persistent/src/de/steamwar/persistent/Arenaserver.java @@ -29,7 +29,7 @@ public class Arenaserver extends Subserver { private final boolean allowMerge; public Arenaserver(String serverName, String mode, String map, boolean allowMerge, int port, ProcessBuilder processBuilder, Runnable shutdownCallback) { - super(Servertype.ARENA, serverName, port, processBuilder, shutdownCallback, null); + super(serverName, port, processBuilder, shutdownCallback, null); this.mode = mode; this.map = map; this.allowMerge = allowMerge; diff --git a/VelocityCore/Persistent/src/de/steamwar/persistent/Bauserver.java b/VelocityCore/Persistent/src/de/steamwar/persistent/Bauserver.java index fecd1ae1..85bf581a 100644 --- a/VelocityCore/Persistent/src/de/steamwar/persistent/Bauserver.java +++ b/VelocityCore/Persistent/src/de/steamwar/persistent/Bauserver.java @@ -42,7 +42,7 @@ public class Bauserver extends Subserver { } public Bauserver(String serverName, UUID owner, int port, ProcessBuilder processBuilder, Runnable shutdownCallback, Consumer failureCallback){ - super(Servertype.BAUSERVER, serverName, port, processBuilder, shutdownCallback, failureCallback); + super(serverName, port, processBuilder, shutdownCallback, failureCallback); this.owner = owner; synchronized (servers) { diff --git a/VelocityCore/Persistent/src/de/steamwar/persistent/Builderserver.java b/VelocityCore/Persistent/src/de/steamwar/persistent/Builderserver.java index ad90b8a2..4a01c7d4 100644 --- a/VelocityCore/Persistent/src/de/steamwar/persistent/Builderserver.java +++ b/VelocityCore/Persistent/src/de/steamwar/persistent/Builderserver.java @@ -41,7 +41,7 @@ public class Builderserver extends Subserver { } public Builderserver(String serverName, String map, int port, ProcessBuilder processBuilder, Runnable shutdownCallback, Consumer failureCallback){ - super(Servertype.BUILDER, serverName, port, processBuilder, shutdownCallback, failureCallback); + super(serverName, port, processBuilder, shutdownCallback, failureCallback); this.map = map; synchronized (servers) { diff --git a/VelocityCore/Persistent/src/de/steamwar/persistent/Servertype.java b/VelocityCore/Persistent/src/de/steamwar/persistent/Servertype.java deleted file mode 100644 index 4731a2eb..00000000 --- a/VelocityCore/Persistent/src/de/steamwar/persistent/Servertype.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * This file is a part of the SteamWar software. - * - * Copyright (C) 2024 SteamWar.de-Serverteam - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package de.steamwar.persistent; - -public enum Servertype { - BAUSERVER, - ARENA, - BUILDER -} diff --git a/VelocityCore/Persistent/src/de/steamwar/persistent/Subserver.java b/VelocityCore/Persistent/src/de/steamwar/persistent/Subserver.java index 5d262ccf..072f1467 100644 --- a/VelocityCore/Persistent/src/de/steamwar/persistent/Subserver.java +++ b/VelocityCore/Persistent/src/de/steamwar/persistent/Subserver.java @@ -38,9 +38,20 @@ import java.util.function.Predicate; import java.util.logging.Level; import java.util.logging.Logger; -@SuppressWarnings("unused") public class Subserver { + public static boolean isArena(Subserver subserver) { + return subserver instanceof Arenaserver; + } + + public static boolean isBuild(Subserver subserver) { + return subserver instanceof Bauserver; + } + + public static boolean isBuilder(Subserver subserver) { + return subserver instanceof Builderserver; + } + private static final Component PREFIX = Component .text("Steam").color(NamedTextColor.YELLOW) .append(Component.text("War» ").color(NamedTextColor.DARK_GRAY)); @@ -84,8 +95,6 @@ public class Subserver { private final ServerInfo server; @Getter private RegisteredServer registeredServer; - @Getter - private final Servertype type; private final Thread thread; @Getter private boolean started; @@ -94,13 +103,13 @@ public class Subserver { @Getter private final Map tablistNames = new HashMap<>(); - protected Subserver(Servertype type, String serverName, int port, ProcessBuilder processBuilder, Runnable shutdownCallback, Consumer failureCallback) { + protected Subserver(String serverName, int port, ProcessBuilder processBuilder, Runnable shutdownCallback, Consumer failureCallback) { this.started = false; this.serverName = serverName; - this.type = type; this.shutdownCallback = shutdownCallback; this.failureCallback = failureCallback == null ? this::fatalError : failureCallback; this.checkpoint = processBuilder.command().contains("criu"); + this.thread = new Thread(this::run, "Subserver " + serverName); try { this.process = processBuilder.start(); @@ -112,7 +121,8 @@ public class Subserver { this.server = new ServerInfo(serverName, address); this.writer = new PrintWriter(process.getOutputStream(), true); - this.thread = new Thread(this::run, "Subserver " + serverName); + register(); + this.thread.start(); } @@ -146,7 +156,8 @@ public class Subserver { process.destroyForcibly(); } - thread.join(); + if(thread.isAlive()) + thread.join(); } catch (InterruptedException e) { logger.log(Level.SEVERE, "Subserver stop interrupted!", e); Thread.currentThread().interrupt(); @@ -205,8 +216,6 @@ public class Subserver { } private void run() { - register(); - Exception ex = null; try { if (checkpoint) { diff --git a/VelocityCore/build.gradle.kts b/VelocityCore/build.gradle.kts index 166df4c4..d3480ca8 100644 --- a/VelocityCore/build.gradle.kts +++ b/VelocityCore/build.gradle.kts @@ -62,8 +62,7 @@ dependencies { implementation(libs.msgpack) - implementation(libs.apolloapi) - implementation(libs.apollocommon) + implementation(libs.apolloprotos) implementation(libs.nbt) } \ No newline at end of file diff --git a/VelocityCore/src/de/steamwar/messages/BungeeCore.properties b/VelocityCore/src/de/steamwar/messages/BungeeCore.properties index 2535aaf3..b133d99b 100644 --- a/VelocityCore/src/de/steamwar/messages/BungeeCore.properties +++ b/VelocityCore/src/de/steamwar/messages/BungeeCore.properties @@ -116,6 +116,8 @@ HELP_BAU_SET_BUILDER=§8/§ebuild setbuilder §8- §7Building, WorldEdit, BauSys HELP_BAU_SET_BUILDER_HOVER=§eSets the Role to Builder HELP_BAU_SET_SUPERVISOR=§8/§ebuild supervisor §8- §7Starting build server. Saving schematics HELP_BAU_SET_SUPERVISOR_HOVER=§eSets the Role to Supervisor +HELP_BAU_STOP=§8/§ebuild stop §8- §7Stop your build server +HELP_BAU_STOP_HOVER=§eStop build server HELP_BAU_DELETE=§8/§ebuild delete §8- §7Reset your entire build server HELP_BAU_DELETE_HOVER=§eReset build server HELP_BAU_TESTARENA=§8/§ebuild testarena §8- §7Start a test arena @@ -235,6 +237,8 @@ BAU_DELMEMBER_USAGE=§8/§7build delmember §8[§eplayer§8] BAU_DELMEMBER_SELFDEL=§cYou cannot remove yourself! BAU_DELMEMBER_DELETED=§cPlayer was removed. BAU_DELMEMBER_DELETED_TARGET=§cYou were removed from the world of §e{0}. +BAU_STOPPING=§7Stopping your build server. (May take up to a minute) +BAU_STOPPED=§aYour build server has been stopped. BAU_DELETE_DELETED=§aYour world is being reset. BAU_DELETE_GUI_NAME=§eDo you really want to delete the world? BAU_DELETE_GUI_CANCEL=§cCancel @@ -326,7 +330,7 @@ CHECK_DECLINED_TEAM=§7The schematic §e{0} §7from §e{1} §7is now declined be #HistoricCommand HISTORIC_BROADCAST=§7Historic §e{0} §7fight by §e{1}§8! -HISTORIC_BROADCAST_HOVER=§afight against §7{1} +HISTORIC_BROADCAST_HOVER=§afight against §7{0} #JoinCommand JOIN_PLAYER_BLOCK=§cYou currently cannot follow this player. diff --git a/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties b/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties index 786ad244..9299064f 100644 --- a/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties +++ b/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties @@ -101,6 +101,8 @@ HELP_BAU_SET_BUILDER=§8/§ebau setbuilder §8- §7Bauen, WorldEdit, BauSystem F HELP_BAU_SET_BUILDER_HOVER=§eSetzt die Rolle Builder HELP_BAU_SET_SUPERVISOR=§8/§ebuild setsupervisor §8- §7Starten des Baus. Schematics erstellen HELP_BAU_SET_SUPERVISOR_HOVER=§eSetzt die Rolle Supervisor +HELP_BAU_STOP=§8/§ebau stop §8- §7Stoppt deinen Bauserver +HELP_BAU_STOP_HOVER=§eStoppe Bauserver HELP_BAU_DELETE=§8/§ebau delete §8- §7Setzt deine Bauwelt zurück HELP_BAU_DELETE_HOVER=§eBauwelt zurücksetzen HELP_BAU_TESTARENA=§8/§ebau testarena §8- §7Starte eine Testarena @@ -218,6 +220,8 @@ BAU_DELMEMBER_USAGE=§8/§7bau delmember §8[§eSpieler§8] BAU_DELMEMBER_SELFDEL=§cDu kannst dich nicht selbst entfernen! BAU_DELMEMBER_DELETED=§cDer Spieler wurde entfernt. BAU_DELMEMBER_DELETED_TARGET=§cDu wurdest von der Welt von §e{0} §centfernt. +BAU_STOPPING=§7Stoppe den Bauserver. (Kann bis zu einer Minute dauern) +BAU_STOPPED=§aDein Bauserver wurde gestoppt. BAU_DELETE_DELETED=§aDeine Welt wird zurückgesetzt. BAU_DELETE_GUI_NAME=§eWirklich Welt löschen? BAU_DELETE_GUI_CANCEL=§cAbbrechen @@ -308,7 +312,7 @@ CHECK_DECLINED_TEAM=§7Die Schematic §e{0} §7von §e{1} §7wurde aufgrund von #HistoricCommand HISTORIC_BROADCAST=§7Historischer §e{0}§8-§7Kampf von §e{1}§8! -HISTORIC_BROADCAST_HOVER=§aGegen §7{1} §ekämpfen +HISTORIC_BROADCAST_HOVER=§aGegen §7{0} §ekämpfen #JoinCommand JOIN_PLAYER_BLOCK=§cDu kannst diesem Spieler derzeit nicht folgen. diff --git a/VelocityCore/src/de/steamwar/messages/Chatter.java b/VelocityCore/src/de/steamwar/messages/Chatter.java index 224b502f..2e67354c 100644 --- a/VelocityCore/src/de/steamwar/messages/Chatter.java +++ b/VelocityCore/src/de/steamwar/messages/Chatter.java @@ -24,7 +24,6 @@ import com.velocitypowered.api.event.ResultedEvent; import com.velocitypowered.api.event.connection.LoginEvent; import com.velocitypowered.api.proxy.Player; import com.velocitypowered.api.proxy.ServerConnection; -import de.steamwar.persistent.Servertype; import de.steamwar.persistent.Subserver; import de.steamwar.sql.SteamwarUser; import de.steamwar.sql.UserPerm; @@ -64,7 +63,7 @@ public interface Chatter { static ChatterGroup globalChat() { return new ChatterGroup(Stream.concat(Stream.of(Chatter.console()), allPlayers().filter(player -> { Subserver subserver = Subserver.getSubserver(player); - return subserver == null || !(subserver.getType() == Servertype.ARENA && subserver.getServer() == player.getCurrentServer().map(ServerConnection::getServerInfo).orElse(null)); + return !(Subserver.isArena(subserver) && subserver.getServer() == player.getCurrentServer().map(ServerConnection::getServerInfo).orElse(null)); }).map(Chatter::of))); } diff --git a/VelocityCore/src/de/steamwar/velocitycore/ErrorLogger.java b/VelocityCore/src/de/steamwar/velocitycore/ErrorLogger.java index 714011f2..f5b79af8 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/ErrorLogger.java +++ b/VelocityCore/src/de/steamwar/velocitycore/ErrorLogger.java @@ -53,7 +53,7 @@ public class ErrorLogger extends AbstractAppender { @Override public void append(LogEvent event) { - if(event.getLevel().isLessSpecificThan(Level.WARN)) + if(event.getLevel().intLevel() > Level.WARN.intLevel()) return; String message = event.getMessage().getFormattedMessage(); diff --git a/VelocityCore/src/de/steamwar/velocitycore/ServerStarter.java b/VelocityCore/src/de/steamwar/velocitycore/ServerStarter.java index 75edf040..1b834390 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/ServerStarter.java +++ b/VelocityCore/src/de/steamwar/velocitycore/ServerStarter.java @@ -70,6 +70,7 @@ public class ServerStarter { private boolean checkpoint = false; private ServerConstructor constructor = (serverName, port, builder, shutdownCallback, failureCallback) -> new Arenaserver(serverName, gameMode, fightMap, allowMerge, port, builder, shutdownCallback); private Consumer callback = subserver -> {}; + private Object responsible = new Object(); private final Set playersToSend = new HashSet<>(); private final Map arguments = new HashMap<>(); @@ -84,6 +85,14 @@ public class ServerStarter { directory = new File(SERVER_PATH, mode.getFolder()); arguments.put("config", mode.getConfig()); tempWorld(SERVER_PATH + mode.getFolder() + "/arenas/" + map); + startCondition = () -> { + if(playersToSend.stream().anyMatch(player -> Subserver.isArena(Subserver.getSubserver(player)))) { + playersToSend.forEach(player -> Chatter.of(player).system("FIGHT_IN_ARENA")); + return false; + } + + return true; + }; return this; } @@ -245,6 +254,10 @@ public class ServerStarter { public ServerStarter send(Player player) { playersToSend.add(player); + + if(!(responsible instanceof Player)) + responsible = player; + return this; } @@ -253,47 +266,49 @@ public class ServerStarter { return this; } - public boolean start() { - if(!startCondition.getAsBoolean()) - return false; + public void start() { + VelocityCore.schedule(() -> { + synchronized (responsible) { + if(!startCondition.getAsBoolean()) + return; - int port = portrange.freePort(); - String serverName = serverNameProvider.apply(port); + int port = portrange.freePort(); + String serverName = serverNameProvider.apply(port); - if(node == null) { - node = Node.getNode(); - if(node == null) { - for (Player p : playersToSend) - Chatter.of(p).system("SERVER_START_OVERLOAD"); + if(node == null) { + node = Node.getNode(); + if(node == null) { + for (Player p : playersToSend) + Chatter.of(p).system("SERVER_START_OVERLOAD"); - return false; + return; + } + } + if(worldName == null) + worldName = serverToWorldName(serverName); + + worldSetup.run(); + arguments.put("logPath", worldName); + + File checkpointDir = new File("/tmp/" + System.getProperty("user.name") + ".checkpoints/" + directory.getName() + "/" + worldName); + if(checkpoint) + arguments.put("checkpoint", checkpointDir.getPath()); + + if(checkpoint && checkpointDir.exists()) { + try(DataOutputStream out = new DataOutputStream(Files.newOutputStream(new File(checkpointDir, "port").toPath()))) { + out.writeInt(port); + } catch (IOException e) { + throw new SecurityException(e); + } + + postStart(constructor.construct(serverName, port, node.prepareExecution( + "criu", "restore", "-D", checkpointDir.getPath(), "--auto-dedup", "--shell-job", "-v" + ), worldCleanup, e -> regularStart(serverName, port))); + } else { + regularStart(serverName, port); + } } - } - if(worldName == null) - worldName = serverToWorldName(serverName); - - worldSetup.run(); - arguments.put("logPath", worldName); - - File checkpointDir = new File("/tmp/" + System.getProperty("user.name") + ".checkpoints/" + directory.getName() + "/" + worldName); - if(checkpoint) - arguments.put("checkpoint", checkpointDir.getPath()); - - if(checkpoint && checkpointDir.exists()) { - try(DataOutputStream out = new DataOutputStream(Files.newOutputStream(new File(checkpointDir, "port").toPath()))) { - out.writeInt(port); - } catch (IOException e) { - throw new SecurityException(e); - } - - postStart(constructor.construct(serverName, port, node.prepareExecution( - "criu", "restore", "-D", checkpointDir.getPath(), "--auto-dedup", "--shell-job", "-v" - ), worldCleanup, e -> regularStart(serverName, port))); - } else { - regularStart(serverName, port); - } - - return true; + }).schedule(); } private void regularStart(String serverName, int port) { diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/ArenaCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/ArenaCommand.java index 1fa04e0e..cee6cb04 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/ArenaCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/ArenaCommand.java @@ -20,14 +20,13 @@ package de.steamwar.velocitycore.commands; import com.velocitypowered.api.proxy.server.RegisteredServer; -import de.steamwar.persistent.Servertype; -import de.steamwar.persistent.Subserver; -import de.steamwar.velocitycore.VelocityCore; import de.steamwar.command.PreviousArguments; import de.steamwar.command.SWCommand; import de.steamwar.command.TypeMapper; import de.steamwar.messages.Chatter; import de.steamwar.messages.PlayerChatter; +import de.steamwar.persistent.Subserver; +import de.steamwar.velocitycore.VelocityCore; import java.util.Collection; import java.util.List; @@ -53,7 +52,7 @@ public class ArenaCommand extends SWCommand { @Override public boolean validate(Chatter sender, Subserver value, MessageSender messageSender) { - if (value == null || value.getType() != Servertype.ARENA) { + if (!Subserver.isArena(value)) { sender.system("ARENA_NOT_FOUND"); return false; } @@ -64,7 +63,7 @@ public class ArenaCommand extends SWCommand { public Collection tabCompletes(Chatter sender, PreviousArguments previousArguments, String s) { List subserverList = Subserver.getServerList(); synchronized (subserverList) { - return subserverList.stream().filter(subserver -> subserver.getType() == Servertype.ARENA).map(subserver -> subserver.getServer().getName()).toList(); + return subserverList.stream().filter(Subserver::isArena).map(subserver -> subserver.getServer().getName()).toList(); } } }; diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/BauCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/BauCommand.java index 3e1b5d74..150df3fd 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/BauCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/BauCommand.java @@ -197,6 +197,18 @@ public class BauCommand extends SWCommand { }; } + @Register("stop") + public void stop(PlayerChatter sender) { + VelocityCore.schedule(() -> { + sender.system("BAU_STOPPING"); + Bauserver subserver = Bauserver.get(sender.user().getUUID()); + if(subserver != null) + subserver.stop(); + + sender.system("BAU_STOPPED"); + }).schedule(); + } + @Register("resetall") @Register("delete") public void delete(PlayerChatter sender, @OptionalValue(value = "", onlyUINIG = true) ServerVersion version) { @@ -223,7 +235,7 @@ public class BauCommand extends SWCommand { @Register("testarena") public void testarena(PlayerChatter sender, @Mapper("nonHistoricArenaMode") @OptionalValue("") @AllowNull ArenaMode arenaMode, @Mapper("arenaMap") @OptionalValue("") @AllowNull String map) { FightCommand.createArena(sender, "/bau testarena ", false, arenaMode, map, false, (chatter, mode, m) -> - VelocityCore.schedule(() -> new ServerStarter().test(mode, m, sender.getPlayer()).start()).schedule() + new ServerStarter().test(mode, m, sender.getPlayer()).start() ); } diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/ChallengeCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/ChallengeCommand.java index ddc33654..78ced8d1 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/ChallengeCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/ChallengeCommand.java @@ -20,16 +20,15 @@ package de.steamwar.velocitycore.commands; import com.velocitypowered.api.proxy.Player; -import de.steamwar.velocitycore.ArenaMode; -import de.steamwar.velocitycore.ServerStarter; -import de.steamwar.persistent.Servertype; -import de.steamwar.persistent.Subserver; import de.steamwar.command.SWCommand; import de.steamwar.command.TypeValidator; import de.steamwar.messages.Chatter; import de.steamwar.messages.Message; import de.steamwar.messages.PlayerChatter; +import de.steamwar.persistent.Subserver; import de.steamwar.sql.IgnoreSystem; +import de.steamwar.velocitycore.ArenaMode; +import de.steamwar.velocitycore.ServerStarter; import net.kyori.adventure.text.event.ClickEvent; import java.util.LinkedList; @@ -84,8 +83,7 @@ public class ChallengeCommand extends SWCommand { return false; } - Subserver subserver = Subserver.getSubserver(value); - if (subserver != null && subserver.getType() == Servertype.ARENA) { + if (Subserver.isArena(Subserver.getSubserver(value))) { messageSender.send("CHALLENGE_INARENA"); return false; } diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/CheckCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/CheckCommand.java index 7fb5118a..c678fa4c 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/CheckCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/CheckCommand.java @@ -207,19 +207,15 @@ public class CheckCommand extends SWCommand { this.startTime = Timestamp.from(Instant.now()); this.checkList = checkQuestions.get(schematic.getSchemtype()).listIterator(); - VelocityCore.schedule(() -> { - ArenaMode mode = ArenaMode.getBySchemType(fightTypes.get(schematic.getSchemtype())); - if(!new ServerStarter().test(mode, mode.getRandomMap(), checker.getPlayer()).check(schematic.getId()).start()) { - remove(); - return; - } - + ArenaMode mode = ArenaMode.getBySchemType(fightTypes.get(schematic.getSchemtype())); + new ServerStarter().test(mode, mode.getRandomMap(), checker.getPlayer()).check(schematic.getId()).callback(subserver -> { currentCheckers.put(checker.user().getUUID(), this); currentSchems.put(schematic.getId(), this); + for(CheckedSchematic previous : CheckedSchematic.previousChecks(schematic)) checker.prefixless("CHECK_SCHEMATIC_PREVIOUS", previous.getEndTime(), SteamwarUser.get(previous.getValidator()).getUserName(), previous.getDeclineReason()); next(); - }).schedule(); + }).start(); } private void next() { diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/DevCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/DevCommand.java index 005e5fe8..528272fb 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/DevCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/DevCommand.java @@ -30,6 +30,7 @@ import de.steamwar.command.TypeValidator; import de.steamwar.messages.PlayerChatter; import de.steamwar.sql.Punishment; import de.steamwar.sql.SteamwarUser; +import lombok.Getter; import java.io.File; import java.net.InetSocketAddress; @@ -39,7 +40,8 @@ import java.util.Map; public class DevCommand extends SWCommand { private final File devServerDir = new File("/configs/DevServer"); - private final Map devServers = new HashMap<>(); + @Getter + private static final Map devServers = new HashMap<>(); public DevCommand() { super("dev"); diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/FightCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/FightCommand.java index 633405e8..6c320758 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/FightCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/FightCommand.java @@ -20,16 +20,16 @@ package de.steamwar.velocitycore.commands; import com.velocitypowered.api.proxy.Player; -import de.steamwar.velocitycore.*; -import de.steamwar.velocitycore.inventory.SWInventory; -import de.steamwar.velocitycore.inventory.SWItem; import de.steamwar.command.SWCommand; import de.steamwar.messages.Chatter; import de.steamwar.messages.Message; import de.steamwar.messages.PlayerChatter; import de.steamwar.persistent.Arenaserver; -import de.steamwar.persistent.Servertype; import de.steamwar.persistent.Subserver; +import de.steamwar.velocitycore.ArenaMode; +import de.steamwar.velocitycore.ServerStarter; +import de.steamwar.velocitycore.inventory.SWInventory; +import de.steamwar.velocitycore.inventory.SWItem; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.event.ClickEvent; import net.kyori.adventure.text.event.HoverEvent; @@ -60,20 +60,7 @@ public class FightCommand extends SWCommand { sender.sendMessage(start); } - private static boolean alreadyInArena(PlayerChatter sender){ - Subserver subserver = Subserver.getSubserver(sender.getPlayer()); - if(subserver != null && subserver.getType() == Servertype.ARENA){ - sender.system("FIGHT_IN_ARENA"); - return true; - } - - return false; - } - static void createArena(PlayerChatter sender, String precommand, boolean allowMerging, ArenaMode arenaMode, String map, boolean historic, FightCallback callback) { - if(alreadyInArena(sender)) - return; - if (arenaMode == null) { getModes(sender, precommand, historic); return; diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/HelpCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/HelpCommand.java index 8cb6fda4..33e595d0 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/HelpCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/HelpCommand.java @@ -92,6 +92,7 @@ public class HelpCommand extends SWCommand { "HELP_BAU_SET_SPECTATOR", "/build setSpectator ", "HELP_BAU_SET_BUILDER", "/build setBuilder ", "HELP_BAU_SET_SUPERVISOR", "/build setSupervisor ", + "HELP_BAU_STOP", "/build stop", "HELP_BAU_DELETE", "/build delete ", "HELP_BAU_TESTARENA", "/build testarena ", "HELP_BAU_LOCK", "/build lock ", diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/HistoricCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/HistoricCommand.java index 7176da84..395eff33 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/HistoricCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/HistoricCommand.java @@ -35,7 +35,7 @@ public class HistoricCommand extends SWCommand { @Register public void historic(@Validator("arenaPlayer") PlayerChatter player, @Mapper("historicArenaMode") @OptionalValue("") @AllowNull ArenaMode arenaMode, @Mapper("arenaMap") @OptionalValue("") @AllowNull String map) { FightCommand.createArena(player, "/historic ", true, arenaMode, map, true, (p, mode, m) -> new ServerStarter().arena(mode, m).blueLeader(p.getPlayer()).callback( - arena -> Chatter.broadcast().system("HISTORIC_BROADCAST", new Message("HISTORIC_BROADCAST_HOVER"), ClickEvent.runCommand("/arena " + arena.getServer().getName()), mode.getGameName(), p.getPlayer()) + arena -> Chatter.broadcast().system("HISTORIC_BROADCAST", new Message("HISTORIC_BROADCAST_HOVER", p), ClickEvent.runCommand("/arena " + arena.getServer().getName()), mode.getGameName(), p.getPlayer()) ).start()); } } diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/ListCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/ListCommand.java index d2659836..1505b438 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/ListCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/ListCommand.java @@ -21,11 +21,10 @@ package de.steamwar.velocitycore.commands; import com.velocitypowered.api.proxy.Player; import com.velocitypowered.api.proxy.ServerConnection; -import de.steamwar.persistent.Servertype; -import de.steamwar.persistent.Subserver; -import de.steamwar.velocitycore.VelocityCore; import de.steamwar.command.SWCommand; import de.steamwar.messages.Chatter; +import de.steamwar.persistent.Subserver; +import de.steamwar.velocitycore.VelocityCore; import java.util.ArrayList; import java.util.List; @@ -46,8 +45,7 @@ public class ListCommand extends SWCommand { if (pserver == null) continue; - Subserver subserver = Subserver.getSubserver(pserver.getServerInfo()); - if (subserver != null && subserver.getType() == Servertype.BAUSERVER) { + if (Subserver.isBuild(Subserver.getSubserver(pserver.getServerInfo()))) { playerMap.computeIfAbsent("Bau", s -> new ArrayList<>()).add(player); } else { playerMap.computeIfAbsent(pserver.getServerInfo().getName(), s -> new ArrayList<>()).add(player); diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/SendCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/SendCommand.java index de9a73f3..a0435983 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/SendCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/SendCommand.java @@ -55,15 +55,7 @@ public class SendCommand extends SWCommand { if (name.contains(" ")) return false; Subserver subserver = Subserver.getSubserver(serverInfo); - if (subserver == null) { - return true; - } - - return switch (subserver.getType()) { - case ARENA -> true; - case BUILDER -> user.hasPerm(UserPerm.BUILD); - default -> false; - }; + return subserver == null || Subserver.isArena(subserver) || (Subserver.isBuilder(subserver) && user.hasPerm(UserPerm.BUILD)); } @Override diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/TpCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/TpCommand.java index 031e2baa..2292c258 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/TpCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/TpCommand.java @@ -110,37 +110,31 @@ public class TpCommand extends SWCommand { return; } - switch (subserver.getType()) { - case ARENA: - if (PunishmentCommand.isPunishedWithMessage(sender, Punishment.PunishmentType.NoFightServer)) - return; - break; - - case BAUSERVER: - Bauserver bauserver = (Bauserver) subserver; - Player checker = VelocityCore.getProxy().getPlayer(bauserver.getOwner()).orElse(null); - if (checker != null && CheckCommand.isChecking(checker)) { - if (!sender.user().hasPerm(UserPerm.CHECK) && CheckCommand.getCheckingSchem(checker).getOwner() != sender.user().getId()) { - sender.system("JOIN_PLAYER_BLOCK"); - return; - } - } else if (BauLock.isLocked(SteamwarUser.get(bauserver.getOwner()), sender.user())) { - sender.system("BAU_LOCKED_NOALLOWED"); - Chatter.of(bauserver.getOwner()).system("BAU_LOCK_BLOCKED", sender); - return; - } else if (!bauserver.getOwner().equals(sender.user().getUUID()) && BauweltMember.getBauMember(bauserver.getOwner(), sender.user().getUUID()) == null) { - SubserverSystem.sendDeniedMessage(sender, bauserver.getOwner()); + if(Subserver.isArena(subserver)) { + if (PunishmentCommand.isPunishedWithMessage(sender, Punishment.PunishmentType.NoFightServer)) + return; + } else if(Subserver.isBuild(subserver)) { + Bauserver bauserver = (Bauserver) subserver; + Player checker = VelocityCore.getProxy().getPlayer(bauserver.getOwner()).orElse(null); + if (checker != null && CheckCommand.isChecking(checker)) { + if (!sender.user().hasPerm(UserPerm.CHECK) && CheckCommand.getCheckingSchem(checker).getOwner() != sender.user().getId()) { sender.system("JOIN_PLAYER_BLOCK"); return; } - break; - - case BUILDER: - if(!sender.user().hasPerm(UserPerm.BUILD)) { - sender.system("JOIN_PLAYER_BLOCK"); - return; - } - break; + } else if (BauLock.isLocked(SteamwarUser.get(bauserver.getOwner()), sender.user())) { + sender.system("BAU_LOCKED_NOALLOWED"); + Chatter.of(bauserver.getOwner()).system("BAU_LOCK_BLOCKED", sender); + return; + } else if (!bauserver.getOwner().equals(sender.user().getUUID()) && BauweltMember.getBauMember(bauserver.getOwner(), sender.user().getUUID()) == null) { + SubserverSystem.sendDeniedMessage(sender, bauserver.getOwner()); + sender.system("JOIN_PLAYER_BLOCK"); + return; + } + } else if(Subserver.isBuilder(subserver)) { + if(!sender.user().hasPerm(UserPerm.BUILD)) { + sender.system("JOIN_PLAYER_BLOCK"); + return; + } } SubserverSystem.sendPlayer(subserver, sender.getPlayer()); diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/TutorialCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/TutorialCommand.java index 5b4e01fa..877b7479 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/TutorialCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/TutorialCommand.java @@ -19,21 +19,22 @@ package de.steamwar.velocitycore.commands; -import de.steamwar.velocitycore.*; -import de.steamwar.velocitycore.inventory.SWInventory; -import de.steamwar.velocitycore.inventory.SWItem; -import de.steamwar.velocitycore.inventory.SWListInv; -import de.steamwar.velocitycore.inventory.SWStreamInv; import de.steamwar.command.SWCommand; import de.steamwar.command.TypeValidator; import de.steamwar.messages.Chatter; import de.steamwar.messages.Message; import de.steamwar.messages.PlayerChatter; -import de.steamwar.persistent.Servertype; import de.steamwar.persistent.Subserver; import de.steamwar.sql.SteamwarUser; import de.steamwar.sql.Tutorial; import de.steamwar.sql.UserPerm; +import de.steamwar.velocitycore.ServerStarter; +import de.steamwar.velocitycore.SubserverSystem; +import de.steamwar.velocitycore.VelocityCore; +import de.steamwar.velocitycore.inventory.SWInventory; +import de.steamwar.velocitycore.inventory.SWItem; +import de.steamwar.velocitycore.inventory.SWListInv; +import de.steamwar.velocitycore.inventory.SWStreamInv; import java.io.File; import java.util.Arrays; @@ -140,7 +141,7 @@ public class TutorialCommand extends SWCommand { SteamwarUser user = sender.user(); File tempWorld = new File(ServerStarter.TEMP_WORLD_PATH, ServerStarter.serverToWorldName(ServerStarter.bauServerName(user))); - if(subserver == null || !subserver.isStarted() || subserver.getType() != Servertype.BAUSERVER || !tempWorld.exists()) { + if(!Subserver.isBuild(subserver) || !subserver.isStarted() || !tempWorld.exists()) { sender.system("TUTORIAL_CREATE_MISSING"); return; } diff --git a/VelocityCore/src/de/steamwar/velocitycore/discord/channels/InteractionReply.java b/VelocityCore/src/de/steamwar/velocitycore/discord/channels/InteractionReply.java index 7366ae96..3d805f9b 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/discord/channels/InteractionReply.java +++ b/VelocityCore/src/de/steamwar/velocitycore/discord/channels/InteractionReply.java @@ -20,7 +20,6 @@ package de.steamwar.velocitycore.discord.channels; import net.dv8tion.jda.api.interactions.callbacks.IReplyCallback; -import net.dv8tion.jda.api.interactions.components.ComponentInteraction; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; @@ -44,23 +43,24 @@ public class InteractionReply extends DiscordChannel { private InteractionReply(IReplyCallback interaction) { super(interaction.getUser()); this.interaction = interaction; + interaction.deferReply(true).queue(); } @Override public void sendMessage(Component msg) { - if(replied) { - super.sendMessage(msg); + if(!replied) { + messages.add(PlainTextComponentSerializer.plainText().serialize(msg)); return; } - messages.add(PlainTextComponentSerializer.plainText().serialize(msg)); + if(interaction.getHook().isExpired()) + super.sendMessage(msg); + else + interaction.getHook().sendMessage(PlainTextComponentSerializer.plainText().serialize(msg)).queue(); } public void submit() { - (messages.isEmpty() ? - interaction.deferReply() : - interaction.reply(String.join("\n", messages)) - ).setEphemeral(true).queue(); + interaction.getHook().sendMessage(String.join("\n", messages)).queue(); replied = true; } } diff --git a/VelocityCore/src/de/steamwar/velocitycore/discord/util/DiscordAlert.java b/VelocityCore/src/de/steamwar/velocitycore/discord/util/DiscordAlert.java index 6ba23149..d5aafa5c 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/discord/util/DiscordAlert.java +++ b/VelocityCore/src/de/steamwar/velocitycore/discord/util/DiscordAlert.java @@ -43,7 +43,7 @@ public class DiscordAlert { if(discordId == null) return; - User user = DiscordBot.getInstance().getJda().getUserById(discordId); + User user = DiscordBot.getInstance().getJda().retrieveUserById(discordId).complete(); if(user == null) return; diff --git a/VelocityCore/src/de/steamwar/velocitycore/listeners/ChatListener.java b/VelocityCore/src/de/steamwar/velocitycore/listeners/ChatListener.java index 0880a0bf..0445be62 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/listeners/ChatListener.java +++ b/VelocityCore/src/de/steamwar/velocitycore/listeners/ChatListener.java @@ -32,7 +32,6 @@ import de.steamwar.messages.ChatterGroup; import de.steamwar.messages.Message; import de.steamwar.messages.PlayerChatter; import de.steamwar.network.packets.server.PingPacket; -import de.steamwar.persistent.Servertype; import de.steamwar.persistent.Subserver; import de.steamwar.sql.*; import de.steamwar.velocitycore.ArenaMode; @@ -110,7 +109,7 @@ public class ChatListener extends BasicListener { return; Subserver subserver = Subserver.getSubserver(player); - if(subserver != null && subserver.getType() == Servertype.ARENA && subserver.getServer() == player.getCurrentServer().orElseThrow().getServerInfo()) { + if(Subserver.isArena(subserver) && subserver.getServer() == player.getCurrentServer().orElseThrow().getServerInfo()) { localChat(Chatter.of(player), message); } else if (message.startsWith("+")) { localChat(Chatter.of(player), message.substring(1)); diff --git a/VelocityCore/src/de/steamwar/velocitycore/listeners/CheckListener.java b/VelocityCore/src/de/steamwar/velocitycore/listeners/CheckListener.java index 46668160..4c8ef131 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/listeners/CheckListener.java +++ b/VelocityCore/src/de/steamwar/velocitycore/listeners/CheckListener.java @@ -24,13 +24,12 @@ import com.velocitypowered.api.event.connection.DisconnectEvent; import com.velocitypowered.api.event.connection.PostLoginEvent; import com.velocitypowered.api.event.player.ServerConnectedEvent; import com.velocitypowered.api.proxy.Player; -import de.steamwar.persistent.Bauserver; -import de.steamwar.persistent.Servertype; -import de.steamwar.persistent.Subserver; -import de.steamwar.velocitycore.commands.CheckCommand; import de.steamwar.messages.Chatter; +import de.steamwar.persistent.Bauserver; +import de.steamwar.persistent.Subserver; import de.steamwar.sql.SchematicNode; import de.steamwar.sql.SchematicType; +import de.steamwar.velocitycore.commands.CheckCommand; import java.util.ArrayList; import java.util.List; @@ -56,11 +55,7 @@ public class CheckListener extends BasicListener { Player player = e.getPlayer(); if(CheckCommand.isChecking(player)){ Subserver server = Subserver.getSubserver(e.getServer().getServerInfo()); - if( - server == null || - server.getType() != Servertype.BAUSERVER || - ((Bauserver)server).getOwner() != player.getUniqueId() - ) + if(!Subserver.isBuild(server) || ((Bauserver)server).getOwner() != player.getUniqueId()) CheckCommand.abort(player); } } diff --git a/VelocityCore/src/de/steamwar/velocitycore/listeners/ConnectionListener.java b/VelocityCore/src/de/steamwar/velocitycore/listeners/ConnectionListener.java index ec8d1726..c1a4b51d 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/listeners/ConnectionListener.java +++ b/VelocityCore/src/de/steamwar/velocitycore/listeners/ConnectionListener.java @@ -27,7 +27,6 @@ import com.velocitypowered.api.permission.Tristate; import com.velocitypowered.api.proxy.Player; import de.steamwar.messages.Chatter; import de.steamwar.messages.Message; -import de.steamwar.persistent.Servertype; import de.steamwar.persistent.Subserver; import de.steamwar.sql.SteamwarUser; import de.steamwar.sql.UserPerm; @@ -77,7 +76,7 @@ public class ConnectionListener extends BasicListener { CheckCommand.sendReminder(chatter); for(Subserver subserver : Subserver.getServerList()) { - if(subserver.getType() == Servertype.ARENA) { + if(Subserver.isArena(subserver)) { chatter.system("JOIN_ARENA", new Message("JOIN_ARENA_HOVER"), ClickEvent.runCommand("/arena " + subserver.getServer().getName()), subserver.getServer().getName()); } } diff --git a/VelocityCore/src/de/steamwar/velocitycore/listeners/PluginMessage.java b/VelocityCore/src/de/steamwar/velocitycore/listeners/PluginMessage.java index bd67e805..05e91edb 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/listeners/PluginMessage.java +++ b/VelocityCore/src/de/steamwar/velocitycore/listeners/PluginMessage.java @@ -19,7 +19,6 @@ package de.steamwar.velocitycore.listeners; -import com.lunarclient.apollo.ApolloManager; import com.velocitypowered.api.event.Subscribe; import com.velocitypowered.api.event.connection.PluginMessageEvent; import com.velocitypowered.api.event.player.PlayerChannelRegisterEvent; @@ -32,12 +31,12 @@ import com.velocitypowered.api.proxy.messages.ChannelMessageSource; import com.velocitypowered.api.proxy.messages.LegacyChannelIdentifier; import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier; import com.velocitypowered.proxy.protocol.ProtocolUtils; +import de.steamwar.messages.Chatter; +import de.steamwar.network.packets.NetworkPacket; import de.steamwar.velocitycore.VelocityCore; import de.steamwar.velocitycore.commands.TeamCommand; import de.steamwar.velocitycore.mods.*; import de.steamwar.velocitycore.network.ServerMetaInfo; -import de.steamwar.messages.Chatter; -import de.steamwar.network.packets.NetworkPacket; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import net.kyori.adventure.text.Component; @@ -106,24 +105,24 @@ public class PluginMessage extends BasicListener { for(String channel : Arrays.asList( "fabric:container/open", "fabric:registry/sync/direct", "fabric:registry/sync", - "fabric-screen-handler-api-v1:open_screen", + "fabric-screen-handler-api-v1:open_screen", "fabric:attachment_sync_v1", FML.CHANNEL, "FML|MP", "FML", "FORGE", "fml:loginwrapper", "fml:handshake", "fml:play", "forge:tier_sorting", "forge:split", "forge:login", "forge:handshake", - "labymod3:main", "labymod:neo", + "labymod3:main", "labymod:neo", "labymod:voicechat", "labymod:germanminer", "feather:client/frag", Alpine.HANDSHAKE, Alpine.PLAY, + "lunarclient:pm", "transfer:channel", "apollo:json", //https://lunarclient.dev/apollo/developers/modules/transfer (Lunarclient channels) "sw:hotkeys", - "floodgate:form", "floodgate:transfer", "floodgate:packet", + "floodgate:form", "floodgate:w", "floodgate:packet", "floodgate:transfer", "erosion:msg", "Replay|Restrict", "replaymod:restrict", "WDL|CONTROL", "wdl:control", "tpshud:handshake", "tpshud:tps", //https://github.com/mooziii/tpshud-fabric/tree/main "methane_server:statepacket", //https://modrinth.com/mod/methane - "servux:structures", //https://modrinth.com/mod/servux "architectury:spawn_entity_packet", //https://modrinth.com/mod/architectury-api "jei:channel", "jei:cheat_permission", //https://modrinth.com/mod/jei "owo:local_packet", "owo:sync_screen_handler_properties", //https://modrinth.com/mod/owo-lib @@ -134,9 +133,9 @@ public class PluginMessage extends BasicListener { "plasmo:voice/v2/installed", "plasmo:voice/v2", //https://modrinth.com/plugin/plasmo-voice (Voice chat) "inventorysorter:sync_blacklist_packet", //https://github.com/cpw/inventorysorter (needs server side component to work) "emi:ping", "emi:command", "emi:chess", //https://github.com/emilyploszaj/emi/ - "fancymenu:execute_command", "fancymenu:packet_bridge", //https://github.com/Keksuccino/FancyMenu (Custom menus) + "fancymenu:execute_command", "fancymenu:packet_bridge", "minecraft:fancymenu_packet_bridge", //https://github.com/Keksuccino/FancyMenu (Custom menus) "itemswapper:enableshulker", "itemswapper:enablerefill", //https://github.com/tr7zw/ItemSwapper/tree/main (Easier inventory item swapping) - "jade:show_overlay", "jade:receive_data", "jade:server_ping", //https://github.com/Snownee/Jade (Information over block/entity under crosshair) + "jade:show_overlay", "jade:receive_data", "jade:server_ping", "jade:server_ping_v1", //https://github.com/Snownee/Jade (Information over block/entity under crosshair) "bclib:hello_client", "bclib:request_files", "bclib:send_files", "bclib:chunker", //https://github.com/quiqueck/BCLib (Library for additional dimensions) "roughlyenoughitems:ci_msg", "roughlyenoughitems:request_tags_s2c", "roughlyenoughitems:og_not_enough", //https://github.com/shedaniel/RoughlyEnoughItems (Crafting recipe helper) "essentialclient:chunkdebug", "essentialclient:clientscript", "essentialclient:gamerule", //https://github.com/senseiwells/EssentialClient (Carpet mod extension) @@ -153,17 +152,16 @@ public class PluginMessage extends BasicListener { "craftingtweaks:hello", "craftingtweaks:sync_config", //https://github.com/TwelveIterationMods/CraftingTweaks (Additional Crafting UI) "create:main", //https://github.com/Creators-of-Create/Create (Additional redstone blocks mod) "dummmmmmy:0", "dummmmmmy:1", "dummmmmmy:2", //https://github.com/MehVahdJukaar/DuMmmMmmy (Adding dummy target item) - "easyanvils:1/0", "easyanvils:1/2", //https://github.com/Fuzss/easyanvils (Anvil handling improvements) - "easymagic:1/0", "easymagic.main:0", //https://github.com/Fuzss/easymagic (Enchantment table handling improvements) + "easyanvils:1/0", "easyanvils:1/2", "easyanvils:play", //https://github.com/Fuzss/easyanvils (Anvil handling improvements) + "easymagic:1/0", "easymagic.main:0", "easymagic:play", //https://github.com/Fuzss/easymagic (Enchantment table handling improvements) "enhancedvisuals:main0", "enhancedvisuals:main1", "enhancedvisuals:main2", //https://github.com/CreativeMD/EnhancedVisuals (Visual effects) "fallingtree:configuration-packet", //https://github.com/RakambdaOrg/FallingTree (Serverside tree cutting enhancements) "forgeconfigscreens:play/0", "forgeconfigscreens:play/1", //https://github.com/Fuzss/forgeconfigscreens (Config GUI) "fwaystones:void_totem_revive", "fwaystones:sync_player", "fwaystones:waystone_packet", //https://github.com/LordDeatHunter/FabricWaystones (Adds new block - waystone) - "fzzy_config:sync_config_packet", //https://github.com/fzzyhmstrs/fconfig (Synchronizing configuation library) "graveyard:spawn_entity", //https://github.com/finallion/The-Graveyard-FORGE (Adding graveyard themed blocks, items and mobs) "immersive_weathering:0", //https://github.com/AstralOrdana/Immersive-Weathering (Adds additional random block transitions) "kiwi:sync_cosmetic", //github.com/Snownee/Kiwi (General purpose library) - "libgui:screen_messag", "libgui:screen_message_s2c", //https://github.com/cottonmc/libgui (Ingame GUI library) + "libgui:screen_messag", "libgui:screen_message", "libgui:screen_message_s2c", //https://github.com/cottonmc/libgui (Ingame GUI library) "libjf-config-network", "libjf-config-network-v0:request", "libjf-config-network-v0:response", //https://git.frohnmeyer-wds.de/JfMods/LibJF (General purpose library) "libz:set_mouse_position", "libz:sync_config", //https://github.com/Globox1997/LibZ (General purpose library) "moonlight:0", "moonlight:1", "moonlight:2", "moonlight:3", "moonlight:4", "moonlight:5", //https://github.com/MehVahdJukaar/Moonlight (General purpose library) @@ -186,6 +184,15 @@ public class PluginMessage extends BasicListener { "walkietalkie:buttonpressedresponse", //https://github.com/Flaton1/walkie-talkie-mod (Simple voice chat walkietalkie addon) "whereisit:s2c_founditem", "whereisit:found_item_s2c", //https://modrinth.com/mod/where-is-it (needs server side component to work) "wildfire_gender:hurt", "wildfire_gender:sync", //https://github.com/WildfireRomeo/WildfireFemaleGenderMod (Female player model) + "cancelblockupdate:channel", //https://github.com/Phoupraw/CancelBlockUpdate/ (Server side block update suppression) + "replayvoicechat:entity_sound", "replayvoicechat:locational_sound", "replayvoicechat:static_sound", //https://github.com/henkelmax/replay-voice-chat (Record simple voice chat with replay mod) + "adventure:registered_arg_mappings", + "better-suggestions:entity_scores_response", "better-suggestions:entity_tags_response", //https://github.com/shurik204/better-suggestions (Better command tab completion) + "farmingforblockheads:chicken_nest_effect", "farmingforblockheads:market_categories", //https://github.com/TwelveIterationMods/FarmingForBlockheads (Improved farming with new blocks) + + //https://modrinth.com/mod/servux + "servux:structures", "servux:entity_data", "servux:hud_metadata", "servux:debug_service", + "servux:tweaks", //https://github.com/ZsoltMolnarrr/SpellEngine (Magic library) "spell_engine:config_sync", "spell_engine:particle_effects", "spell_engine:spell_animation", @@ -219,6 +226,8 @@ public class PluginMessage extends BasicListener { //https://github.com/CreativeMD/CreativeCore (General purpose library) "creativecore:main0", "creativecore:main1", "creativecore:main2", "creativecore:main3", "creativecore:main4", "creativecore:main5", "creativecore:main6", "creativecore:main7", + "creativecore:0s", "creativecore:1s", "creativecore:2s", "creativecore:3s", "creativecore:4s", + "creativecore:5s", "creativecore:6s", "creativecore:7s", //https://github.com/Ladysnake/Cardinal-Components-API (General purpose library) "cardinal-components:block_entity_sync", "cardinal-components:chunk_sync", @@ -273,19 +282,21 @@ public class PluginMessage extends BasicListener { "minecells:elevator_destroyed", "minecells:spawn_rune_particles", "minecells:sync_minecells_data", //https://modrinth.com/mod/appleskin (Additional food bar information) - "appleskin:exhaustion_sync", "appleskin:saturation_sync", + "appleskin:exhaustion_sync", "appleskin:saturation_sync", "appleskin:natural_regeneration", "appleskin:saturation", "appleskin:exhaustion", //https://modrinth.com/mod/puzzles-lib (General purpose library) - "puzzleslib:1/0", "puzzleslib:1/1", "puzzleslib:1/2", + "puzzleslib:play", "puzzleslib:1/0", "puzzleslib:1/1", "puzzleslib:1/2", "puzzleslib.main:0", "puzzleslib.main:1", "puzzleslib:play/0", //https://github.com/Fuzss/puzzlesapi (General purpose library extension) "puzzlesapi:1/1", "puzzlesapi:1/2", "puzzlesapi:1/5", "puzzlesapi:2/1", "puzzlesapi:2/2", //https://github.com/bernie-g/geckolib "geckolib:block_entity_anim_trigger_sync", "geckolib:entity_anim_trigger_sync", - "geckolib:block_entity_anim_data_sync", "geckolib:anim_data_sync", - "geckolib:entity_anim_data_sync", "geckolib:anim_trigger_sync", + "geckolib:entity_data_sync", "geckolib:blockentity_anim_trigger", "geckolib:singleton_data_sync", + "geckolib:block_entity_anim_data_sync", "geckolib:anim_data_sync", "geckolib:entity_anim_trigger", + "geckolib:entity_anim_data_sync", "geckolib:anim_trigger_sync", "geckolib:singleton_anim_trigger", + "geckolib:blockentity_data_sync", //https://github.com/Noxcrew/noxesium (MC Championship helper) "noxesium:server_rules", @@ -294,25 +305,55 @@ public class PluginMessage extends BasicListener { "noxesium-v1:stop_sound", "noxesium-v1:start_sound", "noxesium-v1:modify_sound", "noxesium-v2:reset", "noxesium-v2:change_server_rules", "noxesium-v2:server_info", "noxesium-v2:mcc_server", "noxesium-v2:mcc_game_state", "noxesium-v2:reset_server_rules", - "noxesium-v2:stop_sound", "noxesium-v2:start_sound", "noxesium-v2:modify_sound" + "noxesium-v2:stop_sound", "noxesium-v2:start_sound", "noxesium-v2:modify_sound", + "noxesium-v2:change_extra_entity_data", "noxesium-v2:reset_extra_entity_data", + + //https://github.com/Up-Mods/OkZoomer (Zoom mod, deprecated dysfunctional control options) + "ok_zoomer:force_classic_mode", "ok_zoomer:acknowledge_mod", "ok_zoomer:force_spyglass_overlay", + "ok_zoomer:force_spyglass", "ok_zoomer:disable_zoom_scrolling", "ok_zoomer:disable_zoom", + "ok_zoomer:force_zoom_divisor", + + //https://github.com/fzzyhmstrs/fconfig (Synchronizing configuation library) + "fzzy_config:sync_config_packet", "fzzy_config:config_perms_s2c", "fzzy_config:config_sync_s2c", + "fzzy_config:config_update_s2c", "fzzy_config:dynamic_id_s2c", "fzzy_config:setting_forward", + + //https://github.com/TwelveIterationMods/CookingForBlockheads (Improved cooking with new blocks) + "cookingforblockheads:available_craftables_list", "cookingforblockheads:selection_recipes_list", + "cookingforblockheads:synced_effect", + + //https://github.com/tom5454/CustomPlayerModels (Custom player models) + "cpm_net:get_skin", "cpm_net:hello", "cpm_net:plugin", "cpm_net:rec_evt", "cpm_net:rec_sfy", + "cpm_net:set_scl", "cpm_net:set_skin", "cpm_net:srv_anim", + + //https://github.com/FrozenBlock/FrozenLib (General purpose library) + "frozenlib:config_sync_packet", "frozenlib:cooldown_change_packet", "frozenlib:cooldown_change_packet", + "frozenlib:fading_distance_sound_packet", "frozenlib:flyby_sound_packet", "frozenlib:wind_sync_packet", + "frozenlib:forced_cooldown_packet", "frozenlib:local_player_sound_packet", + "frozenlib:local_sound_packet", "frozenlib:moving_fading_restriction_sound_packet", + "frozenlib:moving_restriction_sound_packet", "frozenlib:remove_entity_screen_shakes_packet", + "frozenlib:remove_screen_shakes_packet", "frozenlib:screen_shake_entity_packet", + "frozenlib:screen_shake_packet", "frozenlib:spotting_icon_packet", "frozenlib:wind_disturbance_packet", + "frozenlib:spotting_icon_remove_packet", "frozenlib:starting_moving_restriction_looping_sound_packet" )) channelRegisterHandlers.put(channel, player -> {}); - channelRegisterHandlers.put(ApolloManager.PLUGIN_MESSAGE_CHANNEL, lunar::sendRestrictions); + channelRegisterHandlers.put(Lunar.CHANNEL, lunar::sendRestrictions); channelRegisterHandlers.put(Feather.CHANNEL, new Feather()::sendRestrictions); channelRegisterHandlers.put("openboatutils:settings", player -> send(player, "openboatutils:settings", new byte[] { 0, 0 })); //https://github.com/o7Moon/OpenBoatUtils/wiki/Packets (Reset packet) channelRegisterHandlers.put("itemswapper:disable", player -> send(player, "itemswapper:disable", new byte[]{ 0 })); //https://github.com/tr7zw/ItemSwapper/blob/main/src/main/java/dev/tr7zw/itemswapper/packets/DisableModPayload.java channelRegisterHandlers.put("xaerominimap:main", player -> player.sendMessage(Component.text("§n§o§m§i§n§i§m§a§p"))); //https://www.curseforge.com/minecraft/mc-mods/xaeros-minimap channelRegisterHandlers.put("litemoretica:init_easy_place", player -> Chatter.disconnect(player).prefixless("MOD_YELLOW_SING", "litematica")); //https://github.com/Earthcomputer/litemoretica/tree/master channelRegisterHandlers.put("litemoretica:init_ea", player -> Chatter.disconnect(player).prefixless("MOD_YELLOW_SING", "litematica")); //https://github.com/Earthcomputer/litemoretica/tree/master + channelRegisterHandlers.put("servux:litematics", player -> Chatter.disconnect(player).prefixless("MOD_YELLOW_SING", "litematica")); //https://github.com/maruohon/litematica/blob/pre-rewrite/fabric/1.21.1-masa/src/main/java/fi/dy/masa/litematica/network/ServuxLitematicaHandler.java channelRegisterHandlers.put("voxelmap:settings", player -> Chatter.disconnect(player).prefixless("MOD_YELLOW_SING", "voxelmap")); //https://modrinth.com/mod/voxelmap-updated undocumented + channelRegisterHandlers.put("inventoryessentials:hello", player -> Chatter.disconnect(player).prefixless("MOD_YELLOW_SING", "InventoryEssentials")); //https://github.com/TwelveIterationMods/InventoryEssentials channelRegisterHandlers.put(Controlify.CHANNEL, new Controlify()::onRegister); for(String channel : Arrays.asList( "worldinfo:world_id", // JourneyMap and VoxelMap "journeymap:version", "journeymap:admin_req", "journeymap:mp_options_req", "journeymap:waypoint", "journeymap:player_loc", "journeymap:admin_save", "journeymap:teleport_req", "journeymap:common", - "journeymap:perm_req" + "journeymap:perm_req", "journeymap:chunk_overlay", "journeymap:remove_player" )) channelRegisterHandlers.put(channel, player -> Chatter.disconnect(player).prefixless("MOD_YELLOW_SING", "minimap")); @@ -325,13 +366,14 @@ public class PluginMessage extends BasicListener { "axiom:enable", "axiom:initialize_hotbars", "axiom:response_chunk_data", "axiom:register_world_properties", "axiom:set_world_property", "axiom:ack_world_properties", "axiom:restrictions", "axiom:marker_data", "axiom:marker_nbt_response", - "axiom:custom_blocks", "axiom:editor_warning", "axiom:blueprint_manifest", "axiom:response_blueprint" + "axiom:custom_blocks", "axiom:editor_warning", "axiom:blueprint_manifest", "axiom:response_blueprint", + "axiom:annotation_update" ); registerBiDirPassthrough("axiom:handle_big_payload", "axiom:set_editor_views"); for(String channel : Arrays.asList( "axiom:hello", "axiom:set_gamemode", "axiom:set_fly_speed", "axiom:set_world_time", "axiom:set_world_property", "axiom:set_block", "axiom:set_hotbar_slot", "axiom:switch_active_hotbar", - "axiom:teleport", "axiom:request_chunk_data", "axiom:spawn_entity", + "axiom:teleport", "axiom:request_chunk_data", "axiom:spawn_entity", "axiom:response_entity_data", "axiom:manipulate_entity", "axiom:delete_entity", "axiom:marker_nbt_request", "axiom:set_buffer" )) { channelRegisterHandlers.put(channel, player -> {}); @@ -343,7 +385,8 @@ public class PluginMessage extends BasicListener { "watut:nbt", //https://github.com/Corosauce/WATUT "bclib:hello_server", "vivecraft:data", //https://github.com/Vivecraft/VivecraftMod https://github.com/jrbudda/Vivecraft_Spigot_Extensions https://github.com/Techjar/Vivecraft_BungeeCord_Extensions (VR support) - "badpackets:channel_sync" //https://github.com/badasintended/badpackets (Forge fabric translation layer) + "badpackets:channel_sync", //https://github.com/badasintended/badpackets (Forge fabric translation layer) + "hero-api:mouse-packet", "hero-api:mouse-scroll" //TODO https://github.com/NoRiskClient Mit Superhelden-Mod? )) { channelRegisterHandlers.put(channel, player -> {}); register(channel, false, directional(UNKNOWN, DROP)); @@ -372,7 +415,8 @@ public class PluginMessage extends BasicListener { "fwaystones:request_player_waystone_update", "openboatutils:settings", //https://github.com/o7Moon/OpenBoatUtils "block-event-separator:handshake", //https://github.com/SpaceWalkerRS/block-event-separator (Separating block events) - "oth3r-sit:settings_v1.1" //https://github.com/Oth3r/Sit (Sitting mod) + "oth3r-sit:settings_v1.1", //https://github.com/Oth3r/Sit (Sitting mod) + "carryon:key_pressed" //https://github.com/Tschipp/CarryOn/blob/1.21/Common/src/main/java/tschipp/carryon/networking/serverbound/ServerboundCarryKeyPressedPacket.java )) register(channel, false, directional(UNKNOWN, DROP)); @@ -390,7 +434,7 @@ public class PluginMessage extends BasicListener { register("WDL|INIT", true, directional(UNKNOWN, wdl::handlePluginMessage)); register("wdl:init", true, directional(UNKNOWN, wdl::handlePluginMessage)); - register(ApolloManager.PLUGIN_MESSAGE_CHANNEL, true, async(lunar::handlePluginMessage)); + register(Lunar.CHANNEL, true, async(lunar::handlePluginMessage)); register(Alpine.HANDSHAKE, false, directional(UNKNOWN, new Alpine()::handleHandshakeMessage)); register("LMC", true, directional(UNKNOWN, async(labyMod::handlePluginMessage))); register("labymod3:main", true, directional(UNKNOWN, async(labyMod::handlePluginMessage))); diff --git a/VelocityCore/src/de/steamwar/velocitycore/mods/Lunar.java b/VelocityCore/src/de/steamwar/velocitycore/mods/Lunar.java index de39b37c..ad823364 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/mods/Lunar.java +++ b/VelocityCore/src/de/steamwar/velocitycore/mods/Lunar.java @@ -19,112 +19,79 @@ package de.steamwar.velocitycore.mods; -import com.lunarclient.apollo.ApolloManager; -import com.lunarclient.apollo.libs.protobuf.Any; -import com.lunarclient.apollo.libs.protobuf.InvalidProtocolBufferException; -import com.lunarclient.apollo.libs.protobuf.Message; -import com.lunarclient.apollo.mods.impl.*; -import com.lunarclient.apollo.module.ApolloModuleManager; -import com.lunarclient.apollo.module.ApolloModuleManagerImpl; -import com.lunarclient.apollo.module.modsetting.ModSettingModule; -import com.lunarclient.apollo.network.NetworkOptions; -import com.lunarclient.apollo.option.Options; -import com.lunarclient.apollo.player.AbstractApolloPlayer; +import com.google.protobuf.Any; +import com.google.protobuf.InvalidProtocolBufferException; +import com.google.protobuf.Value; +import com.lunarclient.apollo.configurable.v1.ConfigurableSettings; +import com.lunarclient.apollo.configurable.v1.OverrideConfigurableSettingsMessage; import com.lunarclient.apollo.player.v1.ModMessage; import com.lunarclient.apollo.player.v1.PlayerHandshakeMessage; import com.velocitypowered.api.event.connection.PluginMessageEvent; import com.velocitypowered.api.proxy.Player; import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier; -import de.steamwar.velocitycore.VelocityCore; import de.steamwar.sql.Mod; -import lombok.AllArgsConstructor; +import de.steamwar.velocitycore.VelocityCore; import java.util.ArrayList; import java.util.List; -import java.util.UUID; -import java.util.function.Consumer; import java.util.logging.Level; public class Lunar { // https://lunarclient.dev/apollo/introduction // https://github.com/LunarClient/Apollo - private final ApolloModuleManager manager = new ApolloModuleManagerImpl().addModule(ModSettingModule.class); + public static final String CHANNEL = "lunar:apollo"; - public Lunar() { //TODO seems defunct - Options modSettings = manager.getModule(ModSettingModule.class).getOptions(); - modSettings.set(ModReplaymod.ENABLED, false); // TODO check if restrictions working - modSettings.set(ModFreelook.ENABLED, false); - modSettings.set(ModHypixelMod.ENABLED, false); - modSettings.set(ModMinimap.ENABLED, false); - modSettings.set(ModNametag.ENABLED, false); - modSettings.set(ModTeamView.ENABLED, false); - modSettings.set(ModTntCountdown.ENABLED, false); - modSettings.set(ModToggleSneak.TOGGLE_SNEAK_CONTAINER, false); + private final byte[] packet; + + public Lunar() { + ConfigurableSettings.Builder builder = ConfigurableSettings.newBuilder() + .setApolloModule("mod_setting") + .setEnable(true); + + for(String property : List.of( + "freelook.enabled", "hypixel-mod.enabled", "minimap.enabled", "nametag.enabled", "replaymod.enabled", + "team-view.enabled", "tnt-countdown.enabled", "toggle-sneak.toggle-sneak-container" + )) + builder.putProperties(property, Value.newBuilder().setBoolValue(false).build()); + + packet = Any.pack(OverrideConfigurableSettingsMessage.newBuilder().addConfigurableSettings(builder).build()).toByteArray(); } public void sendRestrictions(Player player) { - NetworkOptions.sendOptions(manager.getModules(), true, new SWApolloPlayer(player)); + player.sendPluginMessage(MinecraftChannelIdentifier.from(CHANNEL), packet); } public void handlePluginMessage(PluginMessageEvent event) { - Player player = (Player) event.getSource(); - Any packet; - try { - packet = Any.parseFrom(event.getData()); + Any packet = Any.parseFrom(event.getData()); + if(packet.is(PlayerHandshakeMessage.class)) + handle((Player) event.getSource(), packet.unpack(PlayerHandshakeMessage.class)); } catch (InvalidProtocolBufferException e) { throw new SecurityException(e); } + } - handle(PlayerHandshakeMessage.class, packet, handshake -> { - List mods = new ArrayList<>(); + private void handle(Player player, PlayerHandshakeMessage packet) { + List mods = new ArrayList<>(); - for(ModMessage mod : handshake.getInstalledModsList()) { - switch(mod.getType()) { - case TYPE_FABRIC_INTERNAL, TYPE_FORGE_INTERNAL: - // Controlled with ModSettings - break; - case TYPE_FABRIC_EXTERNAL: - mods.add(Mod.getOrCreate(mod.getName(), Mod.Platform.FABRIC)); - break; - case TYPE_FORGE_EXTERNAL: - mods.add(Mod.getOrCreate(mod.getName(), Mod.Platform.FORGE)); - break; - default: - VelocityCore.getLogger().log(Level.INFO, () -> player.getUsername() + " uses Lunar mod with unknown type " + mod); - break; - } + for(ModMessage mod : packet.getInstalledModsList()) { + switch(mod.getType()) { + case TYPE_FABRIC_INTERNAL, TYPE_FORGE_INTERNAL: + // Controlled with ModSettings + break; + case TYPE_FABRIC_EXTERNAL: + mods.add(Mod.getOrCreate(mod.getName(), Mod.Platform.FABRIC)); + break; + case TYPE_FORGE_EXTERNAL: + mods.add(Mod.getOrCreate(mod.getName(), Mod.Platform.FORGE)); + break; + default: + VelocityCore.getLogger().log(Level.INFO, () -> player.getUsername() + " uses Lunar mod with unknown type " + mod); + break; } - - ModUtils.handleMods(player, mods); - }); - } - - private void handle(Class type, Any packet, Consumer handler) { - try { - handler.accept(packet.unpack(type)); - } catch (InvalidProtocolBufferException ignored) { /*ignored*/ } - } - - @AllArgsConstructor - private static class SWApolloPlayer extends AbstractApolloPlayer { - - private final Player player; - - @Override - public void sendPacket(Message message) { - sendPacket(Any.pack(message).toByteArray()); } - @Override - public void sendPacket(byte[] bytes) { - player.sendPluginMessage(MinecraftChannelIdentifier.from(ApolloManager.PLUGIN_MESSAGE_CHANNEL), bytes); - } - - @Override public UUID getUniqueId() { return player.getUniqueId(); } - @Override public String getName() { return player.getUsername(); } - @Override public boolean hasPermission(String s) { return player.hasPermission(s); } - @Override public Object getPlayer() { return player; } + ModUtils.handleMods(player, mods); } } diff --git a/VelocityCore/src/de/steamwar/velocitycore/mods/ReplayMod.java b/VelocityCore/src/de/steamwar/velocitycore/mods/ReplayMod.java index 45ba2192..a09e7295 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/mods/ReplayMod.java +++ b/VelocityCore/src/de/steamwar/velocitycore/mods/ReplayMod.java @@ -26,6 +26,7 @@ import de.steamwar.persistent.Bauserver; import de.steamwar.persistent.Builderserver; import de.steamwar.velocitycore.VelocityCore; import de.steamwar.persistent.Subserver; +import de.steamwar.velocitycore.commands.DevCommand; import de.steamwar.velocitycore.listeners.BasicListener; import de.steamwar.velocitycore.listeners.PluginMessage; @@ -56,7 +57,7 @@ public class ReplayMod extends BasicListener { return; Subserver subserver = Subserver.getSubserver(player.getCurrentServer().orElseThrow().getServerInfo()); - if(subserver instanceof Builderserver || (subserver instanceof Bauserver bauserver && bauserver.getOwner().equals(player.getUniqueId()))) + if(subserver instanceof Builderserver || (subserver instanceof Bauserver bauserver && bauserver.getOwner().equals(player.getUniqueId())) || DevCommand.getDevServers().containsValue(player.getCurrentServer().orElseThrow().getServer())) return; PluginMessage.send(player, "Replay|Restrict", "replaymod:restrict", restrict); diff --git a/VelocityCore/src/de/steamwar/velocitycore/tablist/Tablist.java b/VelocityCore/src/de/steamwar/velocitycore/tablist/Tablist.java index 1d8a0738..1c5b74c5 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/tablist/Tablist.java +++ b/VelocityCore/src/de/steamwar/velocitycore/tablist/Tablist.java @@ -172,8 +172,10 @@ public class Tablist extends ChannelInboundHandlerAdapter { sendTabPacket(current, null); current.clear(); - if(connection != null) + if(connection != null) { connection.getConnection().getChannel().pipeline().remove(this); + connection = null; + } } @Override diff --git a/VelocityCore/src/de/steamwar/velocitycore/tablist/TablistBuild.java b/VelocityCore/src/de/steamwar/velocitycore/tablist/TablistBuild.java index 26e22837..6fdd8f4c 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/tablist/TablistBuild.java +++ b/VelocityCore/src/de/steamwar/velocitycore/tablist/TablistBuild.java @@ -22,10 +22,9 @@ package de.steamwar.velocitycore.tablist; import com.velocitypowered.api.proxy.Player; import com.velocitypowered.api.proxy.ServerConnection; import com.velocitypowered.api.proxy.server.RegisteredServer; -import de.steamwar.persistent.Servertype; +import de.steamwar.messages.Chatter; import de.steamwar.persistent.Subserver; import de.steamwar.velocitycore.VelocityCore; -import de.steamwar.messages.Chatter; import java.util.ArrayList; import java.util.HashMap; @@ -38,9 +37,8 @@ public class TablistBuild implements TablistPart { private final Map> players = new HashMap<>(); public TablistBuild() { - for (RegisteredServer server : VelocityCore.getProxy().getAllServers()){ - Subserver subserver = Subserver.getSubserver(server.getServerInfo()); - if(server.getPlayersConnected().isEmpty() || subserver == null || subserver.getType() != Servertype.BAUSERVER) + for (RegisteredServer server : VelocityCore.getProxy().getAllServers()) { + if(server.getPlayersConnected().isEmpty() || !Subserver.isBuild(Subserver.getSubserver(server.getServerInfo()))) continue; servers.add(server); diff --git a/VelocityCore/src/de/steamwar/velocitycore/tablist/TablistManager.java b/VelocityCore/src/de/steamwar/velocitycore/tablist/TablistManager.java index 06c0d725..205cf067 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/tablist/TablistManager.java +++ b/VelocityCore/src/de/steamwar/velocitycore/tablist/TablistManager.java @@ -27,7 +27,6 @@ import com.velocitypowered.api.network.ProtocolVersion; import com.velocitypowered.api.proxy.Player; import com.velocitypowered.api.proxy.server.RegisteredServer; import de.steamwar.network.packets.common.FightInfoPacket; -import de.steamwar.persistent.Servertype; import de.steamwar.persistent.Storage; import de.steamwar.persistent.Subserver; import de.steamwar.velocitycore.VelocityCore; @@ -100,7 +99,7 @@ public class TablistManager extends BasicListener { Subserver subserver = Subserver.getSubserver(server.getServerInfo()); if (fightInfos.containsKey(server)) subservers.add(new TablistServer(server, fightInfos.get(server))); - else if (subserver == null || subserver.getType() != Servertype.BAUSERVER) + else if (!Subserver.isBuild(subserver)) subservers.add(new TablistServer(server)); } subservers.add(new TablistBuild()); diff --git a/VelocityCore/src/de/steamwar/velocitycore/tablist/TablistServer.java b/VelocityCore/src/de/steamwar/velocitycore/tablist/TablistServer.java index 6601f2ca..88ba9a86 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/tablist/TablistServer.java +++ b/VelocityCore/src/de/steamwar/velocitycore/tablist/TablistServer.java @@ -23,12 +23,11 @@ import com.velocitypowered.api.proxy.Player; import com.velocitypowered.api.proxy.ServerConnection; import com.velocitypowered.api.proxy.server.RegisteredServer; import com.velocitypowered.api.util.GameProfile; -import de.steamwar.persistent.Servertype; -import de.steamwar.persistent.Subserver; -import de.steamwar.velocitycore.VelocityCore; import de.steamwar.messages.Chatter; import de.steamwar.network.packets.common.FightInfoPacket; +import de.steamwar.persistent.Subserver; import de.steamwar.sql.SteamwarUser; +import de.steamwar.velocitycore.VelocityCore; import java.util.ArrayList; import java.util.Collection; @@ -94,8 +93,7 @@ public class TablistServer implements TablistPart { return players.stream().map(item -> { Player p = VelocityCore.getProxy().getPlayer(item.getUuid()).orElse(null); if (p == null) return item; - Subserver subserver = Subserver.getSubserver(p.getCurrentServer().map(ServerConnection::getServerInfo).orElse(null)); - if (subserver != null && subserver.getType() == Servertype.ARENA) return item; + if (Subserver.isArena(Subserver.getSubserver(p.getCurrentServer().map(ServerConnection::getServerInfo).orElse(null)))) return item; if (SteamwarUser.get(p.getUniqueId()).getTeam() != team) return item; return new Item(p, true); }); diff --git a/WebsiteBackend/src/de/steamwar/data/Groups.kt b/WebsiteBackend/src/de/steamwar/data/Groups.kt index ae895bfc..2ecff054 100644 --- a/WebsiteBackend/src/de/steamwar/data/Groups.kt +++ b/WebsiteBackend/src/de/steamwar/data/Groups.kt @@ -37,6 +37,9 @@ class Groups { private var groups: GroupsData = if (kGroupsFile.exists()) { Cbor.decodeFromByteArray(kGroupsFile.readBytes()) } else { + if (!kGroupsFile.parentFile.exists()) { + kGroupsFile.parentFile.mkdirs() + } kGroupsFile.createNewFile() kGroupsFile.writeBytes(Cbor.encodeToByteArray(GroupsData(mutableListOf()))) diff --git a/WebsiteBackend/src/de/steamwar/routes/Events.kt b/WebsiteBackend/src/de/steamwar/routes/Events.kt index e351f3e4..4b4c6206 100644 --- a/WebsiteBackend/src/de/steamwar/routes/Events.kt +++ b/WebsiteBackend/src/de/steamwar/routes/Events.kt @@ -234,7 +234,7 @@ fun Route.configureEventsRoute() { } } -suspend fun ApplicationCall.receiveEvent(fieldName: String = "event"): Event? { +suspend fun ApplicationCall.receiveEvent(fieldName: String = "id"): Event? { val eventId = parameters[fieldName]?.toIntOrNull() if (eventId == null) { respond(HttpStatusCode.BadRequest, ResponseError("Invalid event ID")) diff --git a/settings.gradle.kts b/settings.gradle.kts index 670bea38..423e814e 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -107,8 +107,6 @@ dependencyResolutionManagement { library("netty", "io.netty:netty-all:4.1.68.Final") library("junit", "junit:junit:4.13.2") library("hamcrest", "org.hamcrest:hamcrest:2.2") - library("jda", "net.dv8tion:JDA:5.2.0") - library("msgpack", "org.msgpack:msgpack-core:0.9.8") library("classindex", "org.atteo.classindex:classindex:3.13") library("spigotapi", "org.spigotmc:spigot-api:1.20-R0.1-SNAPSHOT") @@ -140,8 +138,9 @@ dependencyResolutionManagement { library("velocity", "de.steamwar:velocity:RELEASE") library("velocityapi", "com.velocitypowered:velocity-api:3.3.0-SNAPSHOT") - library("apolloapi", "com.lunarclient:apollo-api:1.1.0") - library("apollocommon", "com.lunarclient:apollo-common:1.1.0") + library("jda", "net.dv8tion:JDA:5.2.0") + library("msgpack", "org.msgpack:msgpack-core:0.9.8") + library("apolloprotos", "com.lunarclient:apollo-protos:1.0-SNAPSHOT") library("logback", "ch.qos.logback:logback-classic:1.5.6") diff --git a/steamwarci.yml b/steamwarci.yml index 19b1643c..9e5f7f8e 100644 --- a/steamwarci.yml +++ b/steamwarci.yml @@ -7,7 +7,8 @@ artifacts: "/binarys/fightsystem.jar": "FightSystem/build/libs/FightSystem-all.jar" "/binarys/FightSystem_Standalone.jar": "FightSystem/FightSystem_Standalone/build/libs/FightSystem_Standalone-all.jar" - # KotlinCore !! + "/binarys/kotlincore.jar": "KotlinCore/build/libs/KotlinCore-all.jar" + "/binarys/tntleague.jar": "TNTLeague/build/libs/TNTLeague.jar" "/binarys/lobbysystem2.0.jar": "LobbySystem/build/libs/LobbySystem.jar" @@ -29,4 +30,7 @@ artifacts: "/binarys/VelocityCore.jar": "VelocityCore/build/libs/VelocityCore-all.jar" "/binarys/deployarena.py": "VelocityCore/deployarena.py" - "/binarys/website-api.jar": "WebsiteBackend/build/libs/WebsiteBackend-all.jar" \ No newline at end of file + "/binarys/website-api.jar": "WebsiteBackend/build/libs/WebsiteBackend-all.jar" + +release: + - "sudo systemctl restart api.service"