forked from SteamWar/SteamWar
Merge branch 'main' into Schematics/1.21
# Conflicts: # VelocityCore/build.gradle.kts
This commit is contained in:
+1
-4
@@ -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");
|
||||
|
||||
@@ -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<Flag> flags;
|
||||
@Getter
|
||||
private static final Set<Flag> resetFlags;
|
||||
|
||||
static {
|
||||
flags = EnumSet.allOf(Flag.class);
|
||||
resetFlags = flags.stream().filter(flag -> flag.reset).collect(Collectors.toUnmodifiableSet());
|
||||
}
|
||||
|
||||
private final String chatValue;
|
||||
private final Class<? extends Value<?>> valueType;
|
||||
private final Flag.Value<?> defaultValue;
|
||||
private final Value<?>[] values;
|
||||
|
||||
<T extends Enum<T> & Value<T>> Flag(String chatValue, final Class<? extends Value<T>> valueType, final Flag.Value<T> 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);
|
||||
|
||||
@@ -43,7 +43,7 @@ public class EventFight implements Comparable<EventFight> {
|
||||
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);
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<Map> 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);
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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<IntVector, Map<IntVector, BitSet>> blockVisibility = new HashMap<>();
|
||||
private final Set<IntVector> uncoveredSurface = new HashSet<>();
|
||||
private final HashMap<IntVector, BitSet> visibilityDirections = new HashMap<>(); // Contains the visible directions of each occluding visible block
|
||||
private final HashSet<IntVector> uncoveredSurface = new HashSet<>();
|
||||
|
||||
private final HashSet<Player> players = new HashSet<>();
|
||||
private final Set<Entity> entities = new HashSet<>();
|
||||
private final Set<REntity> rentities = new HashSet<>();
|
||||
private final HashSet<Entity> entities = new HashSet<>();
|
||||
private final HashSet<REntity> 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<IntVector, BitSet> 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<IntVector, BitSet> 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<IntVector, BitSet> 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<IntVector> uncovered = new ArrayList<>();
|
||||
occluding.clear(id);
|
||||
for (Map.Entry<IntVector, Map<IntVector, BitSet>> direction : blockVisibility.entrySet()) {
|
||||
for (Map.Entry<IntVector, BitSet> 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<IntVector> uncoveredSet = new HashSet<>(uncovered);
|
||||
Iterator<Entity> 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<IntVector> uncovered = new ArrayList<>();
|
||||
for(Map.Entry<IntVector, BitSet> directionalVisibility : visibilityDirections.entrySet()) {
|
||||
if(directionalVisibility.getValue().get(id)) {
|
||||
directionalVisibility.getValue().clear(id);
|
||||
uncoverBlocks(uncovered, root, directionalVisibility.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
Iterator<REntity> 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<IntVector> uncovered, IntVector block, IntVector direction, IntVector quadrant, BitSet quadVisibility) {
|
||||
private void uncoverBlocks(List<IntVector> 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<IntVector> 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;
|
||||
|
||||
@@ -32,4 +32,6 @@ tasks.shadowJar {
|
||||
|
||||
dependencies {
|
||||
compileOnly(libs.paperapi21)
|
||||
compileOnly(libs.nms21)
|
||||
compileOnly(project(":SpigotCore"))
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ class KotlinCore : JavaPlugin() {
|
||||
}
|
||||
|
||||
override fun onEnable() {
|
||||
|
||||
}
|
||||
|
||||
override fun onDisable() {
|
||||
|
||||
+20
-1
@@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.kotlin.inventory
|
||||
|
||||
import org.bukkit.event.inventory.InventoryClickEvent
|
||||
import org.bukkit.event.inventory.InventoryCloseEvent
|
||||
+20
-1
@@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.kotlin.util
|
||||
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.block.Block
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
+15
-5
@@ -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());
|
||||
|
||||
@@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
plugins {
|
||||
steamwar.kotlin
|
||||
}
|
||||
|
||||
@@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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}"
|
||||
}
|
||||
|
||||
@@ -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 <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
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!
|
||||
@@ -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 <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
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!
|
||||
@@ -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=
|
||||
@@ -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!
|
||||
@@ -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<Player> {
|
||||
return TypeValidator<Player> { _, player, _ -> TNTLeagueGame.getTeam(player)?.leader == player}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.tntleague.config
|
||||
|
||||
import de.steamwar.tntleague.plugin
|
||||
|
||||
@@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<Int>()
|
||||
var target by Delegates.notNull<Int>()
|
||||
|
||||
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()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -21,5 +21,4 @@ package de.steamwar.tntleague.events
|
||||
|
||||
import org.bukkit.event.Listener
|
||||
|
||||
object DummyListener: Listener {
|
||||
}
|
||||
object DummyListener: Listener
|
||||
@@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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
|
||||
|
||||
@@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 {
|
||||
|
||||
@@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<Player>()
|
||||
|
||||
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');
|
||||
}
|
||||
}
|
||||
@@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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)
|
||||
|
||||
@@ -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)
|
||||
@@ -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<String, Int> {
|
||||
val lines = mutableListOf<Component>()
|
||||
val lines = mutableListOf<String>()
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -4,7 +4,10 @@ main: de.steamwar.tntleague.TNTLeague
|
||||
load: POSTWORLD
|
||||
api-version: '1.21'
|
||||
dependencies:
|
||||
- name: SpigotCore
|
||||
required: true
|
||||
- name: KotlinCore
|
||||
required: true
|
||||
server:
|
||||
SpigotCore:
|
||||
required: true
|
||||
load: BEFORE
|
||||
KotlinCore:
|
||||
required: true
|
||||
load: BEFORE
|
||||
@@ -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;
|
||||
|
||||
@@ -42,7 +42,7 @@ public class Bauserver extends Subserver {
|
||||
}
|
||||
|
||||
public Bauserver(String serverName, UUID owner, int port, ProcessBuilder processBuilder, Runnable shutdownCallback, Consumer<Exception> failureCallback){
|
||||
super(Servertype.BAUSERVER, serverName, port, processBuilder, shutdownCallback, failureCallback);
|
||||
super(serverName, port, processBuilder, shutdownCallback, failureCallback);
|
||||
this.owner = owner;
|
||||
|
||||
synchronized (servers) {
|
||||
|
||||
@@ -41,7 +41,7 @@ public class Builderserver extends Subserver {
|
||||
}
|
||||
|
||||
public Builderserver(String serverName, String map, int port, ProcessBuilder processBuilder, Runnable shutdownCallback, Consumer<Exception> failureCallback){
|
||||
super(Servertype.BUILDER, serverName, port, processBuilder, shutdownCallback, failureCallback);
|
||||
super(serverName, port, processBuilder, shutdownCallback, failureCallback);
|
||||
this.map = map;
|
||||
|
||||
synchronized (servers) {
|
||||
|
||||
@@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.persistent;
|
||||
|
||||
public enum Servertype {
|
||||
BAUSERVER,
|
||||
ARENA,
|
||||
BUILDER
|
||||
}
|
||||
@@ -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<Player, String> tablistNames = new HashMap<>();
|
||||
|
||||
protected Subserver(Servertype type, String serverName, int port, ProcessBuilder processBuilder, Runnable shutdownCallback, Consumer<Exception> failureCallback) {
|
||||
protected Subserver(String serverName, int port, ProcessBuilder processBuilder, Runnable shutdownCallback, Consumer<Exception> 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) {
|
||||
|
||||
@@ -62,8 +62,7 @@ dependencies {
|
||||
|
||||
implementation(libs.msgpack)
|
||||
|
||||
implementation(libs.apolloapi)
|
||||
implementation(libs.apollocommon)
|
||||
implementation(libs.apolloprotos)
|
||||
|
||||
implementation(libs.nbt)
|
||||
}
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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<Subserver> callback = subserver -> {};
|
||||
private Object responsible = new Object();
|
||||
|
||||
private final Set<Player> playersToSend = new HashSet<>();
|
||||
private final Map<String, String> 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) {
|
||||
|
||||
@@ -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<String> tabCompletes(Chatter sender, PreviousArguments previousArguments, String s) {
|
||||
List<Subserver> 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();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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<String, RegisteredServer> devServers = new HashMap<>();
|
||||
@Getter
|
||||
private static final Map<String, RegisteredServer> devServers = new HashMap<>();
|
||||
|
||||
public DevCommand() {
|
||||
super("dev");
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 ",
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)));
|
||||
|
||||
@@ -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<Mod> mods = new ArrayList<>();
|
||||
private void handle(Player player, PlayerHandshakeMessage packet) {
|
||||
List<Mod> 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 <T extends Message> void handle(Class<T> type, Any packet, Consumer<T> 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<RegisteredServer, List<Item>> 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);
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
@@ -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())))
|
||||
|
||||
|
||||
@@ -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"))
|
||||
|
||||
+3
-4
@@ -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")
|
||||
|
||||
|
||||
+6
-2
@@ -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"
|
||||
"/binarys/website-api.jar": "WebsiteBackend/build/libs/WebsiteBackend-all.jar"
|
||||
|
||||
release:
|
||||
- "sudo systemctl restart api.service"
|
||||
|
||||
Reference in New Issue
Block a user