Merge branch 'main' into Backend/init

This commit is contained in:
2024-11-23 13:28:00 +01:00
96 changed files with 680 additions and 524 deletions
+2 -2
View File
@@ -27,8 +27,8 @@ java {
} }
dependencies { dependencies {
compileOnly(project(":BauSystem:BauSystem_Main")) compileOnly(project(":BauSystem:BauSystem_Main", "default"))
compileOnly(project(":SpigotCore")) compileOnly(project(":SpigotCore", "default"))
compileOnly(libs.nms15) compileOnly(libs.nms15)
compileOnly(libs.worldedit15) compileOnly(libs.worldedit15)
+2 -2
View File
@@ -27,8 +27,8 @@ java {
} }
dependencies { dependencies {
compileOnly(project(":BauSystem:BauSystem_Main")) compileOnly(project(":BauSystem:BauSystem_Main", "default"))
compileOnly(project(":SpigotCore")) compileOnly(project(":SpigotCore", "default"))
compileOnly(libs.spigotapi) compileOnly(libs.spigotapi)
compileOnly(libs.nms18) compileOnly(libs.nms18)
+2 -2
View File
@@ -27,8 +27,8 @@ java {
} }
dependencies { dependencies {
compileOnly(project(":BauSystem:BauSystem_Main")) compileOnly(project(":BauSystem:BauSystem_Main", "default"))
compileOnly(project(":SpigotCore")) compileOnly(project(":SpigotCore", "default"))
compileOnly(libs.spigotapi) compileOnly(libs.spigotapi)
compileOnly(libs.paperapi) compileOnly(libs.paperapi)
+2 -2
View File
@@ -27,8 +27,8 @@ java {
} }
dependencies { dependencies {
compileOnly(project(":BauSystem:BauSystem_Main")) compileOnly(project(":BauSystem:BauSystem_Main", "default"))
compileOnly(project(":SpigotCore")) compileOnly(project(":SpigotCore", "default"))
compileOnly(libs.spigotapi) compileOnly(libs.spigotapi)
+1 -1
View File
@@ -33,7 +33,7 @@ java {
dependencies { dependencies {
compileOnly(libs.classindex) compileOnly(libs.classindex)
annotationProcessor(libs.classindex) annotationProcessor(libs.classindex)
compileOnly(project(":SpigotCore")) compileOnly(project(":SpigotCore", "default"))
compileOnly(libs.spigotapi) compileOnly(libs.spigotapi)
compileOnly(libs.axiom) compileOnly(libs.axiom)
@@ -271,6 +271,7 @@ SIMULATOR_CHANGE_HELP=§8/§esimulator change §8-§7 Change your simulator wand
SIMULATOR_DELETE_HELP=§8/§esimulator delete §8[§7name§8] §8-§7 Deletes the simulator SIMULATOR_DELETE_HELP=§8/§esimulator delete §8[§7name§8] §8-§7 Deletes the simulator
SIMULATOR_START_HELP=§8/§esimulator start §8[§7name§8] §8-§7 Starts the simulator SIMULATOR_START_HELP=§8/§esimulator start §8[§7name§8] §8-§7 Starts the simulator
SIMULATOR_COPY_HELP=§8/§esimulator copy §8[§7to-copy§8] §8[§7name§8] §8-§7 Copy the simulator SIMULATOR_COPY_HELP=§8/§esimulator copy §8[§7to-copy§8] §8[§7name§8] §8-§7 Copy the simulator
SIMULATOR_RENAME_HELP=§8/§esimulator rename §8[§7to-rename§8] §8[§7name§8] §8-§7 Rename the simulator
SIMULATOR_GUI_ITEM_NAME=§eTNT Simulator SIMULATOR_GUI_ITEM_NAME=§eTNT Simulator
SIMULATOR_NO_SIM_IN_HAND=§cNo simulator item selected SIMULATOR_NO_SIM_IN_HAND=§cNo simulator item selected
SIMULATOR_GUI_SELECT_SIM=Simulator selection SIMULATOR_GUI_SELECT_SIM=Simulator selection
@@ -307,6 +308,7 @@ SIMULATOR_POSITION_Z=§7z-Position
SIMULATOR_BACK=§eBack SIMULATOR_BACK=§eBack
SIMULATOR_GUI_TOTAL_TNT=§7Total TNT§8: §e{0} SIMULATOR_GUI_TOTAL_TNT=§7Total TNT§8: §e{0}
SIMULATOR_DELETED=§cSimulator deleted SIMULATOR_DELETED=§cSimulator deleted
SIMULATOR_RENAMED=§cSimulator renamed from {0} to {1}
## GUI ## GUI
SIMULATOR_POSITION_EDIT=§eEdit position SIMULATOR_POSITION_EDIT=§eEdit position
SIMULATOR_POSITION_ADD=§eSet position SIMULATOR_POSITION_ADD=§eSet position
@@ -254,6 +254,7 @@ SIMULATOR_CHANGE_HELP=§8/§esimulator change §8-§7 Wechsel zu einem anderen S
SIMULATOR_DELETE_HELP=§8/§esimulator delete §8[§7name§8] §8-§7 Löscht den Simulator SIMULATOR_DELETE_HELP=§8/§esimulator delete §8[§7name§8] §8-§7 Löscht den Simulator
SIMULATOR_START_HELP=§8/§esimulator start §8[§7name§8] §8-§7 Startet die Simulation SIMULATOR_START_HELP=§8/§esimulator start §8[§7name§8] §8-§7 Startet die Simulation
SIMULATOR_COPY_HELP=§8/§esimulator copy §8[§7to-copy§8] §8[§7name§8] §8-§7 Kopiert einen Simulator SIMULATOR_COPY_HELP=§8/§esimulator copy §8[§7to-copy§8] §8[§7name§8] §8-§7 Kopiert einen Simulator
SIMULATOR_RENAME_HELP=§8/§esimulator rename §8[§7to-rename§8] §8[§7name§8] §8-§7 Benennt einen Simulator um
SIMULATOR_GUI_ITEM_NAME=§eTNT Simulator SIMULATOR_GUI_ITEM_NAME=§eTNT Simulator
SIMULATOR_NO_SIM_IN_HAND=§cKein Simulator Item gewählt SIMULATOR_NO_SIM_IN_HAND=§cKein Simulator Item gewählt
SIMULATOR_GUI_SELECT_SIM=Simulator wählen SIMULATOR_GUI_SELECT_SIM=Simulator wählen
@@ -290,6 +291,7 @@ SIMULATOR_POSITION_Z=§7z-Position
SIMULATOR_BACK=§eZurück SIMULATOR_BACK=§eZurück
SIMULATOR_GUI_TOTAL_TNT=§7Gesamt TNT§8: §e{0} SIMULATOR_GUI_TOTAL_TNT=§7Gesamt TNT§8: §e{0}
SIMULATOR_DELETED=§cSimulator gelöscht SIMULATOR_DELETED=§cSimulator gelöscht
SIMULATOR_RENAMED=§cSimulator von {0} zu {1} umbenannt
## GUI ## GUI
SIMULATOR_POSITION_EDIT=§ePosition bearbeiten SIMULATOR_POSITION_EDIT=§ePosition bearbeiten
SIMULATOR_POSITION_ADD=§ePosition setzen SIMULATOR_POSITION_ADD=§ePosition setzen
@@ -25,6 +25,7 @@ import de.steamwar.bausystem.configplayer.ConfigConverter;
import de.steamwar.bausystem.features.gui.BauGUI; import de.steamwar.bausystem.features.gui.BauGUI;
import de.steamwar.bausystem.features.script.lua.SteamWarLuaPlugin; import de.steamwar.bausystem.features.script.lua.SteamWarLuaPlugin;
import de.steamwar.bausystem.features.script.lua.libs.LuaLib; import de.steamwar.bausystem.features.script.lua.libs.LuaLib;
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
import de.steamwar.bausystem.features.slaves.panzern.Panzern; import de.steamwar.bausystem.features.slaves.panzern.Panzern;
import de.steamwar.bausystem.features.slaves.panzern.PanzernAlgorithm; import de.steamwar.bausystem.features.slaves.panzern.PanzernAlgorithm;
import de.steamwar.bausystem.features.tpslimit.TPSFreezeUtils; import de.steamwar.bausystem.features.tpslimit.TPSFreezeUtils;
@@ -184,6 +185,9 @@ public class BauSystem extends JavaPlugin {
if (any instanceof ConfigConverter) { if (any instanceof ConfigConverter) {
Config.addConfigConverter((ConfigConverter) any); Config.addConfigConverter((ConfigConverter) any);
} }
if (any instanceof BoundingBoxLoader) {
((BoundingBoxLoader) any).load();
}
}); });
instances.forEach((clazz, o) -> { instances.forEach((clazz, o) -> {
@@ -93,6 +93,7 @@ public class Loader implements Listener {
element.execute(delay -> waitTime = delay); element.execute(delay -> waitTime = delay);
if (waitTime > 0) { if (waitTime > 0) {
if (element instanceof LoaderTNT) currentElement--; if (element instanceof LoaderTNT) currentElement--;
waitTime--;
return; return;
} }
} }
@@ -20,7 +20,6 @@
package de.steamwar.bausystem.features.simulator; package de.steamwar.bausystem.features.simulator;
import de.steamwar.bausystem.BauSystem; import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.Permission;
import de.steamwar.bausystem.SWUtils; import de.steamwar.bausystem.SWUtils;
import de.steamwar.bausystem.features.simulator.data.Simulator; import de.steamwar.bausystem.features.simulator.data.Simulator;
import de.steamwar.bausystem.features.simulator.execute.SimulatorExecutor; import de.steamwar.bausystem.features.simulator.execute.SimulatorExecutor;
@@ -63,15 +62,7 @@ public class SimulatorCommand extends SWCommand {
} }
@Register(value = "copy", description = "SIMULATOR_COPY_HELP") @Register(value = "copy", description = "SIMULATOR_COPY_HELP")
public void copy(@Validator Player p, @ErrorMessage("SIMULATOR_NOT_EXISTS") Simulator simulator, String name) { public void copy(@Validator Player p, @ErrorMessage("SIMULATOR_NOT_EXISTS") Simulator simulator, @Validator("simulatorName") String name) {
if (SimulatorStorage.getSimulator(name) != null) {
BauSystem.MESSAGE.send("SIMULATOR_NAME_ALREADY_EXISTS", p);
return;
}
if (!name.matches("[a-zA-Z_0-9-]+")) {
BauSystem.MESSAGE.send("SIMULATOR_NAME_INVALID", p);
return;
}
if (!SimulatorStorage.copy(simulator, name)) { if (!SimulatorStorage.copy(simulator, name)) {
BauSystem.MESSAGE.send("SIMULATOR_ERROR_COPY", p); BauSystem.MESSAGE.send("SIMULATOR_ERROR_COPY", p);
} }
@@ -88,6 +79,17 @@ public class SimulatorCommand extends SWCommand {
SimulatorExecutor.run(simulator); SimulatorExecutor.run(simulator);
} }
@Register(value = "rename", description = "SIMULATOR_RENAME_HELP")
public void rename(@Validator Player p, @ErrorMessage("SIMULATOR_NOT_EXISTS") Simulator simulator, @Validator("simulatorName") String name) {
String oldName = simulator.getName();
if (SimulatorStorage.copy(simulator, name)) {
SimulatorStorage.delete(simulator);
BauSystem.MESSAGE.send("SIMULATOR_RENAMED", p, oldName, name);
} else {
BauSystem.MESSAGE.send("SIMULATOR_ERROR_COPY", p);
}
}
@ClassMapper(value = Simulator.class, local = true) @ClassMapper(value = Simulator.class, local = true)
public TypeMapper<Simulator> allSimulators() { public TypeMapper<Simulator> allSimulators() {
return new TypeMapper<>() { return new TypeMapper<>() {
@@ -102,4 +104,19 @@ public class SimulatorCommand extends SWCommand {
} }
}; };
} }
@Validator(value = "simulatorName", local = true)
public TypeValidator<String> simulatorName() {
return (commandSender, name, messageSender) -> {
if (SimulatorStorage.getSimulator(name) != null) {
messageSender.send("SIMULATOR_NAME_ALREADY_EXISTS");
return false;
}
if (!name.matches("[a-zA-Z_0-9-]+")) {
messageSender.send("SIMULATOR_NAME_INVALID");
return false;
}
return true;
};
}
} }
@@ -44,6 +44,7 @@ import org.bukkit.inventory.meta.ItemMeta;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
@Linked @Linked
@MinVersion(19) @MinVersion(19)
@@ -130,7 +131,7 @@ public class SimulatorStorage implements Enable {
} }
public static void openSimulatorSelector(Player player) { public static void openSimulatorSelector(Player player) {
SimulatorPageGui<Simulator> simulatorPageGui = new SimulatorPageGui<Simulator>(player, null, 6 * 9, new ArrayList<>(simulatorMap.values())) { SimulatorPageGui<Simulator> simulatorPageGui = new SimulatorPageGui<Simulator>(player, null, 6 * 9, simulatorMap.values().stream().sorted(Comparator.comparing(Simulator::getName)).collect(Collectors.toList())) {
@Override @Override
public String baseTitle() { public String baseTitle() {
return "Simulators"; return "Simulators";
@@ -24,6 +24,7 @@ import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox; import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid; import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
import de.steamwar.bausystem.features.tracer.TNTPoint; import de.steamwar.bausystem.features.tracer.TNTPoint;
import de.steamwar.bausystem.features.tracer.Trace;
import de.steamwar.bausystem.features.tracer.TraceManager; import de.steamwar.bausystem.features.tracer.TraceManager;
import de.steamwar.bausystem.region.Point; import de.steamwar.bausystem.region.Point;
import de.steamwar.bausystem.utils.FlatteningWrapper; import de.steamwar.bausystem.utils.FlatteningWrapper;
@@ -34,7 +35,6 @@ import org.bukkit.util.Vector;
import java.util.*; import java.util.*;
import java.util.function.BiPredicate; import java.util.function.BiPredicate;
import java.util.stream.Collectors;
public class ProcessingTracesState implements LaufbauState { public class ProcessingTracesState implements LaufbauState {
@@ -45,8 +45,9 @@ public class ProcessingTracesState implements LaufbauState {
private final List<BlockBoundingBox> elements; private final List<BlockBoundingBox> elements;
private final int factor; private final int factor;
private final List<TNTPoint> TNTPoints; private final List<Trace> Traces;
private final int totalTntRecords; private final List<TNTPoint> TNTPoints = new ArrayList<>();
private final int totalTraces;
private final Set<Point> affectedBlocks = new HashSet<>(); private final Set<Point> affectedBlocks = new HashSet<>();
private final Map<Point, Set<Cuboid>> cuboidsPerChunk = new HashMap<>(); private final Map<Point, Set<Cuboid>> cuboidsPerChunk = new HashMap<>();
@@ -58,18 +59,13 @@ public class ProcessingTracesState implements LaufbauState {
this.elements = elements; this.elements = elements;
this.factor = factor; this.factor = factor;
// TODO: Optimize only retrieving traces inside of the affected regions! Traces = new ArrayList<>(TraceManager.instance.getAll());
TNTPoints = TraceManager.instance.getAll() totalTraces = Traces.size();
.stream()
.flatMap(trace -> trace.getHistories().stream())
.flatMap(Collection::stream)
.collect(Collectors.toList());
totalTntRecords = TNTPoints.size();
} }
@Override @Override
public String actionBarMessage(Player p) { public String actionBarMessage(Player p) {
return BauSystem.MESSAGE.parse("LAUFBAU_SIMPLE_PROGRESS", p, BauSystem.MESSAGE.parse("LAUFBAU_STATE_PROCESSING_TRACES", p), totalTntRecords - TNTPoints.size(), totalTntRecords, eta(p, start, totalTntRecords - TNTPoints.size(), totalTntRecords)); return BauSystem.MESSAGE.parse("LAUFBAU_SIMPLE_PROGRESS", p, BauSystem.MESSAGE.parse("LAUFBAU_STATE_PROCESSING_TRACES", p), totalTraces - Traces.size(), totalTraces, eta(p, start, totalTraces - Traces.size(), totalTraces));
} }
private boolean inRegion(Vector location, int expansion) { private boolean inRegion(Vector location, int expansion) {
@@ -78,11 +74,17 @@ public class ProcessingTracesState implements LaufbauState {
@Override @Override
public boolean hasNext() { public boolean hasNext() {
return !TNTPoints.isEmpty(); return !Traces.isEmpty() || !TNTPoints.isEmpty();
} }
@Override @Override
public void next() { public void next() {
if (TNTPoints.isEmpty()) {
Trace trace = Traces.remove(0);
trace.getHistories().stream().flatMap(Collection::stream).forEach(TNTPoints::add);
return;
}
TNTPoint current = TNTPoints.remove(0); TNTPoint current = TNTPoints.remove(0);
if (FlatteningWrapper.impl.inWater(world, current.getLocation().toVector())) return; if (FlatteningWrapper.impl.inWater(world, current.getLocation().toVector())) return;
if (!(inRegion(current.getLocation().toVector(), 1) || (current.getPrevious().isPresent() && inRegion(current.getPrevious().get().getLocation().toVector(), 1)))) if (!(inRegion(current.getLocation().toVector(), 1) || (current.getPrevious().isPresent() && inRegion(current.getPrevious().get().getLocation().toVector(), 1))))
@@ -39,12 +39,12 @@ public class SpeedCommand extends SWCommand {
@Register @Register
public void speedCommand(Player p, float speed) { public void speedCommand(Player p, float speed) {
speed = speed / 10F; if (speed < -10F) {
if (speed < -1F) {
BauSystem.MESSAGE.send("SPEED_TOO_SMALL", p, speed); BauSystem.MESSAGE.send("SPEED_TOO_SMALL", p, speed);
} else if (speed > 1F) { } else if (speed > 10F) {
BauSystem.MESSAGE.send("SPEED_TOO_HIGH", p, speed); BauSystem.MESSAGE.send("SPEED_TOO_HIGH", p, speed);
} else { } else {
speed = speed / 10F;
p.setFlySpeed(speed); p.setFlySpeed(speed);
p.setWalkSpeed(Math.min(speed + 0.1F, 1F)); p.setWalkSpeed(Math.min(speed + 0.1F, 1F));
BauSystem.MESSAGE.send("SPEED_CURRENT", p, (p.getFlySpeed() * 10F)); BauSystem.MESSAGE.send("SPEED_CURRENT", p, (p.getFlySpeed() * 10F));
@@ -24,6 +24,7 @@ import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.function.pattern.WaterloggedRemover; import com.sk89q.worldedit.function.pattern.WaterloggedRemover;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypes;
import de.steamwar.bausystem.region.Color; import de.steamwar.bausystem.region.Color;
import de.steamwar.bausystem.region.Point; import de.steamwar.bausystem.region.Point;
@@ -34,9 +35,7 @@ import lombok.NonNull;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.*;
import java.util.List;
import java.util.Objects;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.BiPredicate; import java.util.function.BiPredicate;
@@ -106,51 +105,28 @@ public class PasteBuilder {
public PasteBuilder color(Color color) { public PasteBuilder color(Color color) {
if (color == Color.PINK) return this; if (color == Color.PINK) return this;
BaseBlock WOOL = Objects.requireNonNull(BlockTypes.PINK_WOOL).getDefaultState().toBaseBlock(); Map<String, BaseBlock> blockCache = new HashMap<>();
BaseBlock CLAY = Objects.requireNonNull(BlockTypes.PINK_TERRACOTTA).getDefaultState().toBaseBlock();
BaseBlock GLAZED = Objects.requireNonNull(BlockTypes.PINK_GLAZED_TERRACOTTA).getDefaultState().toBaseBlock();
BaseBlock GLASS = Objects.requireNonNull(BlockTypes.PINK_STAINED_GLASS).getDefaultState().toBaseBlock();
BaseBlock GLASS_PANE = Objects.requireNonNull(BlockTypes.PINK_STAINED_GLASS_PANE).getDefaultState().toBaseBlock();
BaseBlock CONCRETE = Objects.requireNonNull(BlockTypes.PINK_CONCRETE).getDefaultState().toBaseBlock();
BaseBlock CONCRETE_POWDER = Objects.requireNonNull(BlockTypes.PINK_CONCRETE_POWDER).getDefaultState().toBaseBlock();
BaseBlock CARPET = Objects.requireNonNull(BlockTypes.PINK_CARPET).getDefaultState().toBaseBlock();
BaseBlock wool = Objects.requireNonNull(BlockTypes.get(color.name().toLowerCase() + "_wool")).getDefaultState().toBaseBlock();
BaseBlock clay = Objects.requireNonNull(BlockTypes.get(color.name().toLowerCase() + "_terracotta")).getDefaultState().toBaseBlock();
BaseBlock glazed = Objects.requireNonNull(BlockTypes.get(color.name().toLowerCase() + "_glazed_terracotta")).getDefaultState().toBaseBlock();
BaseBlock glass = Objects.requireNonNull(BlockTypes.get(color.name().toLowerCase() + "_stained_glass")).getDefaultState().toBaseBlock();
BaseBlock glassPane = Objects.requireNonNull(BlockTypes.get(color.name().toLowerCase() + "_stained_glass_pane")).getDefaultState().toBaseBlock();
BaseBlock carpet = Objects.requireNonNull(BlockTypes.get(color.name().toLowerCase() + "_carpet")).getDefaultState().toBaseBlock();
BaseBlock concrete = Objects.requireNonNull(BlockTypes.get(color.name().toLowerCase() + "_concrete")).getDefaultState().toBaseBlock();
BaseBlock concretePowder = Objects.requireNonNull(BlockTypes.get(color.name().toLowerCase() + "_concrete_powder")).getDefaultState().toBaseBlock();
return map((clipboard, blockVector3) -> { return map((clipboard, blockVector3) -> {
BaseBlock block = clipboard.getFullBlock(blockVector3); BaseBlock block = clipboard.getFullBlock(blockVector3);
if (block.equals(WOOL)) { if (block.getBlockType().getId().startsWith("minecraft:pink_")) {
clipboard.setBlock(blockVector3, wool); BaseBlock baseBlock = blockCache.computeIfAbsent(block.getBlockType().getId(), s -> {
} else if (block.equals(CLAY)) { String replaced = s.replace("minecraft:pink_", "minecraft:" + color.name().toLowerCase() + "_");
clipboard.setBlock(blockVector3, clay); BlockType blockType = BlockTypes.get(replaced);
} else if (block.equals(GLAZED)) { if (blockType == null) return null;
clipboard.setBlock(blockVector3, glazed); return blockType.getDefaultState().toBaseBlock();
} else if (block.equals(GLASS)) { });
clipboard.setBlock(blockVector3, glass); if (baseBlock == null) return;
} else if (block.equals(GLASS_PANE)) { clipboard.setBlock(blockVector3, baseBlock);
clipboard.setBlock(blockVector3, glassPane);
} else if (block.equals(CARPET)) {
clipboard.setBlock(blockVector3, carpet);
} else if (block.equals(CONCRETE)) {
clipboard.setBlock(blockVector3, concrete);
} else if (block.equals(CONCRETE_POWDER)) {
clipboard.setBlock(blockVector3, concretePowder);
} }
}); });
} }
/**
* Can only be used before {@link #color(Color)}.
*/
public PasteBuilder onlyColors(boolean onlyColors) { public PasteBuilder onlyColors(boolean onlyColors) {
if (!onlyColors) return this; if (!onlyColors) return this;
return only((baseBlock, s) -> { return only((baseBlock, s) -> s.startsWith("minecraft:pink_"));
return s.endsWith("_wool") || s.endsWith("_terracotta") || s.endsWith("_glazed_terracotta") || s.endsWith("_stained_glass") || s.endsWith("_stained_glass_pane") || s.endsWith("_carpet") || s.endsWith("_concrete") || s.endsWith("_concrete_powder");
});
} }
public PasteBuilder removeTNT(boolean removeTNT) { public PasteBuilder removeTNT(boolean removeTNT) {
@@ -121,11 +121,11 @@ public class Punishment {
public enum PunishmentType { public enum PunishmentType {
Ban(false, "BAN_TEAM", "BAN_PERMA", "BAN_UNTIL", "UNBAN_ERROR", "UNBAN"), Ban(false, "BAN_TEAM", "BAN_PERMA", "BAN_UNTIL", "UNBAN_ERROR", "UNBAN"),
Mute( false, "MUTE_TEAM", "MUTE_PERMA", "MUTE_UNTIL", "UNMUTE_ERROR", "UNMUTE"), Mute( false, "MUTE_TEAM", "MUTE_PERMA", "MUTE_UNTIL", "UNMUTE_ERROR", "UNMUTE"),
NoSchemReceiving(false, "NOSCHEMRECEIVING_TEAM", "NOSCHEMRECEIVING_PERMA", "NOSCHEMRECEIVING_UNTIL", "UNNOSCHEMRECEIVING_ERROR", "UNNOSCHEMRECEIVING"), NoSchemReceiving(true, "NOSCHEMRECEIVING_TEAM", "NOSCHEMRECEIVING_PERMA", "NOSCHEMRECEIVING_UNTIL", "UNNOSCHEMRECEIVING_ERROR", "UNNOSCHEMRECEIVING"),
NoSchemSharing(false, "NOSCHEMSHARING_TEAM", "NOSCHEMSHARING_PERMA", "NOSCHEMSHARING_UNTIL", "UNNOSCHEMSHARING_ERROR", "UNNOSCHEMSHARING"), NoSchemSharing(true, "NOSCHEMSHARING_TEAM", "NOSCHEMSHARING_PERMA", "NOSCHEMSHARING_UNTIL", "UNNOSCHEMSHARING_ERROR", "UNNOSCHEMSHARING"),
NoSchemSubmitting(true, "NOSCHEMSUBMITTING_TEAM", "NOSCHEMSUBMITTING_PERMA", "NOSCHEMSUBMITTING_UNTIL", "UNNOSCHEMSUBMITTING_ERROR", "UNNOSCHEMSUBMITTING"), NoSchemSubmitting(false, "NOSCHEMSUBMITTING_TEAM", "NOSCHEMSUBMITTING_PERMA", "NOSCHEMSUBMITTING_UNTIL", "UNNOSCHEMSUBMITTING_ERROR", "UNNOSCHEMSUBMITTING"),
NoDevServer(true, "NODEVSERVER_TEAM", "NODEVSERVER_PERMA", "NODEVSERVER_UNTIL", "UNNODEVSERVER_ERROR", "UNNODEVSERVER"), NoDevServer(true, "NODEVSERVER_TEAM", "NODEVSERVER_PERMA", "NODEVSERVER_UNTIL", "UNNODEVSERVER_ERROR", "UNNODEVSERVER"),
NoFightServer(false, "NOFIGHTSERVER_TEAM", "NOFIGHTSERVER_PERMA", "NOFIGHTSERVER_UNTIL", "UNNOFIGHTSERVER_ERROR", "UNNOFIGHTSERVER"), NoFightServer(true, "NOFIGHTSERVER_TEAM", "NOFIGHTSERVER_PERMA", "NOFIGHTSERVER_UNTIL", "UNNOFIGHTSERVER_ERROR", "UNNOFIGHTSERVER"),
NoTeamServer(true, "NOTEAMSERVER_TEAM", "NOTEAMSERVER_PERMA", "NOTEAMSERVER_UNTIL", "UNNOTEAMSERVER_ERROR", "UNNOTEAMSERVER"), NoTeamServer(true, "NOTEAMSERVER_TEAM", "NOTEAMSERVER_PERMA", "NOTEAMSERVER_UNTIL", "UNNOTEAMSERVER_ERROR", "UNNOTEAMSERVER"),
Note(false, "NOTE_TEAM", null, null, null, null, true); Note(false, "NOTE_TEAM", null, null, null, null, true);
+2 -2
View File
@@ -22,8 +22,8 @@ plugins {
} }
dependencies { dependencies {
compileOnly(project(":SpigotCore")) compileOnly(project(":SpigotCore", "default"))
compileOnly(project(":FightSystem:FightSystem_Core")) compileOnly(project(":FightSystem:FightSystem_Core", "default"))
compileOnly(libs.nms10) compileOnly(libs.nms10)
} }
+3 -3
View File
@@ -22,9 +22,9 @@ plugins {
} }
dependencies { dependencies {
compileOnly(project(":SpigotCore")) compileOnly(project(":SpigotCore", "default"))
compileOnly(project(":FightSystem:FightSystem_Core")) compileOnly(project(":FightSystem:FightSystem_Core", "default"))
compileOnly(project(":FightSystem:FightSystem_8")) compileOnly(project(":FightSystem:FightSystem_8", "default"))
compileOnly(libs.nms12) compileOnly(libs.nms12)
compileOnly(libs.worldedit12) compileOnly(libs.worldedit12)
+4 -4
View File
@@ -22,10 +22,10 @@ plugins {
} }
dependencies { dependencies {
compileOnly(project(":SpigotCore")) compileOnly(project(":SpigotCore", "default"))
compileOnly(project(":FightSystem:FightSystem_Core")) compileOnly(project(":FightSystem:FightSystem_Core", "default"))
compileOnly(project(":FightSystem:FightSystem_8")) compileOnly(project(":FightSystem:FightSystem_8", "default"))
compileOnly(project(":FightSystem:FightSystem_9")) compileOnly(project(":FightSystem:FightSystem_9", "default"))
compileOnly(libs.nms14) compileOnly(libs.nms14)
compileOnly(libs.worldedit15) compileOnly(libs.worldedit15)
+2 -2
View File
@@ -22,8 +22,8 @@ plugins {
} }
dependencies { dependencies {
compileOnly(project(":SpigotCore")) compileOnly(project(":SpigotCore", "default"))
compileOnly(project(":FightSystem:FightSystem_Core")) compileOnly(project(":FightSystem:FightSystem_Core", "default"))
compileOnly(libs.nms15) compileOnly(libs.nms15)
compileOnly(libs.worldedit15) compileOnly(libs.worldedit15)
+2 -2
View File
@@ -22,8 +22,8 @@ plugins {
} }
dependencies { dependencies {
compileOnly(project(":SpigotCore")) compileOnly(project(":SpigotCore", "default"))
compileOnly(project(":FightSystem:FightSystem_Core")) compileOnly(project(":FightSystem:FightSystem_Core", "default"))
compileOnly(libs.spigotapi) compileOnly(libs.spigotapi)
+2 -2
View File
@@ -22,8 +22,8 @@ plugins {
} }
dependencies { dependencies {
compileOnly(project(":FightSystem:FightSystem_Core")) compileOnly(project(":FightSystem:FightSystem_Core", "default"))
compileOnly(project(":FightSystem:FightSystem_18")) compileOnly(project(":FightSystem:FightSystem_18", "default"))
compileOnly(libs.spigotapi) compileOnly(libs.spigotapi)
+2 -2
View File
@@ -22,8 +22,8 @@ plugins {
} }
dependencies { dependencies {
compileOnly(project(":FightSystem:FightSystem_Core")) compileOnly(project(":FightSystem:FightSystem_Core", "default"))
compileOnly(project(":FightSystem:FightSystem_18")) compileOnly(project(":FightSystem:FightSystem_18", "default"))
compileOnly(libs.spigotapi) compileOnly(libs.spigotapi)
+2 -2
View File
@@ -22,8 +22,8 @@ plugins {
} }
dependencies { dependencies {
compileOnly(project(":SpigotCore")) compileOnly(project(":SpigotCore", "default"))
compileOnly(project(":FightSystem:FightSystem_Core")) compileOnly(project(":FightSystem:FightSystem_Core", "default"))
compileOnly(libs.nms8) compileOnly(libs.nms8)
compileOnly(libs.worldedit12) compileOnly(libs.worldedit12)
+3 -3
View File
@@ -22,9 +22,9 @@ plugins {
} }
dependencies { dependencies {
compileOnly(project(":SpigotCore")) compileOnly(project(":SpigotCore", "default"))
compileOnly(project(":FightSystem:FightSystem_Core")) compileOnly(project(":FightSystem:FightSystem_Core", "default"))
compileOnly(project(":FightSystem:FightSystem_8")) compileOnly(project(":FightSystem:FightSystem_8", "default"))
compileOnly(libs.nms9) compileOnly(libs.nms9)
} }
@@ -22,7 +22,7 @@ plugins {
} }
dependencies { dependencies {
compileOnly(project(":SpigotCore")) compileOnly(project(":SpigotCore", "default"))
compileOnly(libs.spigotapi) compileOnly(libs.spigotapi)
@@ -83,6 +83,8 @@ SCHEM_PRIVATE=§ePrivate {0}
SCHEM_NO_PRIVATE=§7No private {0} present SCHEM_NO_PRIVATE=§7No private {0} present
SCHEM_PRIVATE_FORBIDDEN=§7No private {0} allowed SCHEM_PRIVATE_FORBIDDEN=§7No private {0} allowed
ADD_AI_TITLE=Add AI
# Countdowns # Countdowns
COUNTDOWN_MINUTES=§e{0} §7Minutes {1} COUNTDOWN_MINUTES=§e{0} §7Minutes {1}
@@ -114,6 +116,7 @@ RESPAWN=§eRespawn
REMOVE_PLAYERS=§cKick player REMOVE_PLAYERS=§cKick player
CHOOSE_SCHEMATIC=§eChoose {0} CHOOSE_SCHEMATIC=§eChoose {0}
SCHEMATIC_REQUIRED=§cChoose a schematic first SCHEMATIC_REQUIRED=§cChoose a schematic first
ADD_AI=§eAdd AI
KIT_PREVIEW_EDIT=§7Edit kit KIT_PREVIEW_EDIT=§7Edit kit
KIT_PREVIEW_CHOOSE=§aSelect kit KIT_PREVIEW_CHOOSE=§aSelect kit
@@ -77,6 +77,8 @@ SCHEM_PRIVATE=§ePrivates {0}
SCHEM_NO_PRIVATE=§7Kein privates {0} vorhanden SCHEM_NO_PRIVATE=§7Kein privates {0} vorhanden
SCHEM_PRIVATE_FORBIDDEN=§7Kein privates {0} erlaubt SCHEM_PRIVATE_FORBIDDEN=§7Kein privates {0} erlaubt
ADD_AI_TITLE=KI hinzufügen
# Countdowns # Countdowns
COUNTDOWN_MINUTES=§e{0} §7Minuten {1} COUNTDOWN_MINUTES=§e{0} §7Minuten {1}
@@ -107,6 +109,7 @@ RESPAWN=§eRespawn
REMOVE_PLAYERS=§cSpieler rauswerfen REMOVE_PLAYERS=§cSpieler rauswerfen
CHOOSE_SCHEMATIC=§e{0} wählen CHOOSE_SCHEMATIC=§e{0} wählen
SCHEMATIC_REQUIRED=§cZuerst muss eine Schematic gewählt sein SCHEMATIC_REQUIRED=§cZuerst muss eine Schematic gewählt sein
ADD_AI=§eKI hinzufügen
KIT_PREVIEW_EDIT=§7Kit bearbeiten KIT_PREVIEW_EDIT=§7Kit bearbeiten
KIT_PREVIEW_CHOOSE=§aKit wählen KIT_PREVIEW_CHOOSE=§aKit wählen
@@ -19,32 +19,38 @@
package de.steamwar.fightsystem.ai; package de.steamwar.fightsystem.ai;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import de.steamwar.fightsystem.ArenaMode; import de.steamwar.fightsystem.ArenaMode;
import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.FightSystem; import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.fight.Fight; import de.steamwar.fightsystem.fight.Fight;
import de.steamwar.fightsystem.fight.FightTeam; import de.steamwar.fightsystem.fight.FightTeam;
import de.steamwar.fightsystem.fight.JoinRequest;
import de.steamwar.fightsystem.listener.Chat; import de.steamwar.fightsystem.listener.Chat;
import de.steamwar.fightsystem.record.GlobalRecorder;
import de.steamwar.fightsystem.states.FightState; import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.OneShotStateDependent; import de.steamwar.fightsystem.states.OneShotStateDependent;
import de.steamwar.fightsystem.utils.Region; import de.steamwar.fightsystem.utils.Region;
import de.steamwar.sql.SchematicNode; import de.steamwar.sql.SchematicNode;
import de.steamwar.sql.SteamwarUser; import de.steamwar.sql.SteamwarUser;
import lombok.Getter;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Note; import org.bukkit.Note;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.Lectern; import org.bukkit.block.Lectern;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.FaceAttachable;
import org.bukkit.block.data.Openable; import org.bukkit.block.data.Openable;
import org.bukkit.block.data.Powerable; import org.bukkit.block.data.Powerable;
import org.bukkit.block.data.type.Comparator; import org.bukkit.block.data.type.Comparator;
import org.bukkit.block.data.type.NoteBlock; import org.bukkit.block.data.type.NoteBlock;
import org.bukkit.block.data.type.Repeater; import org.bukkit.block.data.type.Repeater;
import org.bukkit.block.data.type.Switch;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity; import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Villager; import org.bukkit.entity.Villager;
import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.scheduler.BukkitTask; import org.bukkit.scheduler.BukkitTask;
@@ -55,10 +61,16 @@ import java.util.logging.Level;
public abstract class AI { public abstract class AI {
public static final int MOVEMENT_DELAY = 4;
public static final double INTERACTION_RANGE = 5.0;
private static final Map<UUID, AI> ais = new HashMap<>(); private static final Map<UUID, AI> ais = new HashMap<>();
public static void printPos() {
ais.values().forEach(ai -> ai.chat(ai.entity.isValid() + " " + ai.entity.isDead() + " " + ai.entity.getLocation()));
}
static { static {
new OneShotStateDependent(ArenaMode.All, FightState.Spectate, () -> { new OneShotStateDependent(ArenaMode.AntiReplay, FightState.Spectate, () -> {
ais.values().forEach(AI::stop); ais.values().forEach(AI::stop);
ais.clear(); ais.clear();
}); });
@@ -68,7 +80,9 @@ public abstract class AI {
return ais.get(uuid); return ais.get(uuid);
} }
private final FightTeam team; @Getter
protected final FightTeam team;
@Getter
private final LivingEntity entity; private final LivingEntity entity;
private final BukkitTask task; private final BukkitTask task;
private final Queue<Action> queue = new ArrayDeque<>(); private final Queue<Action> queue = new ArrayDeque<>();
@@ -83,11 +97,15 @@ public abstract class AI {
task = Bukkit.getScheduler().runTaskTimer(FightSystem.getPlugin(), this::run, 1, 1); task = Bukkit.getScheduler().runTaskTimer(FightSystem.getPlugin(), this::run, 1, 1);
ais.put(entity.getUniqueId(), this); ais.put(entity.getUniqueId(), this);
team.addMember(entity, user); team.addMember(entity, user);
if(FightState.Schem.contains(FightState.getFightState()))
Bukkit.getScheduler().runTask(FightSystem.getPlugin(), () -> schematic(team.getClipboard()));
} }
public abstract SchematicNode chooseSchematic(); public abstract SchematicNode chooseSchematic();
public abstract void schematic(Clipboard clipboard);
public boolean acceptJoinRequest(Player player, FightTeam team) { public boolean acceptJoinRequest(JoinRequest.Enquirer enquirer, FightTeam team) {
return true; return true;
} }
@@ -101,11 +119,7 @@ public abstract class AI {
task.cancel(); task.cancel();
} }
public LivingEntity getEntity() { public void setReady() {
return entity;
}
protected void setReady() {
if(FightState.getFightState() != FightState.POST_SCHEM_SETUP) if(FightState.getFightState() != FightState.POST_SCHEM_SETUP)
return; return;
@@ -115,12 +129,12 @@ public abstract class AI {
team.setReady(true); team.setReady(true);
} }
protected void chat(String message) { public void chat(String message) {
FightSystem.getPlugin().getLogger().log(Level.INFO, () -> entity.getName() + "» " + message); FightSystem.getPlugin().getLogger().log(Level.INFO, () -> entity.getName() + "» " + message);
Chat.broadcastChat("PARTICIPANT_CHAT", team.getColoredName(), entity.getName(), message); Chat.broadcastChat("PARTICIPANT_CHAT", team.getColoredName(), entity.getName(), message);
} }
protected Vector getPosition() { public Vector getPosition() {
Location location = entity.getLocation(); Location location = entity.getLocation();
Region extend = team.getExtendRegion(); Region extend = team.getExtendRegion();
if(Fight.getUnrotated() == team) if(Fight.getUnrotated() == team)
@@ -137,26 +151,28 @@ public abstract class AI {
); );
} }
protected Material getBlock(Vector pos) { public Material getBlock(Vector pos) {
queue.add(new Action(1)); queue.add(new Action(1));
return translate(pos, true).getBlock().getType(); return translate(pos).getBlock().getType();
} }
protected boolean isPowered(Vector pos) { public BlockData getBlockData(Vector pos) {
queue.add(new Action(1)); queue.add(new Action(1));
return translate(pos, true).getBlock().isBlockPowered(); return translate(pos).getBlock().getBlockData();
} }
protected void setTNT(Vector pos) { public void setTNT(Vector pos) {
queue.add(new Action(1) { queue.add(new Action(1) {
@Override @Override
public void run() { public void run() {
if(FightState.getFightState() != FightState.RUNNING) if(FightState.getFightState() != FightState.RUNNING)
return; return;
Location location = translate(pos, true); Location location = translate(pos);
if(interactionDistanceViolation(location)) if(interactionDistanceViolation(location)) {
chat("InteractionDistanceViolation: setTNT");
return; return;
}
Block block = location.getBlock(); Block block = location.getBlock();
if(block.getType() == Material.AIR) if(block.getType() == Material.AIR)
@@ -165,24 +181,26 @@ public abstract class AI {
}); });
} }
protected void interact(Vector pos) { public void interact(Vector pos) {
queue.add(new Action(1) { queue.add(new Action(1) {
@Override @Override
public void run() { public void run() {
Location location = translate(pos, true); Location location = translate(pos);
if(interactionDistanceViolation(location)) if(interactionDistanceViolation(location)) {
chat("InteractionDistanceViolation: interact");
return; return;
}
interact(location.getBlock()); interact(location.getBlock());
} }
}); });
} }
protected void interact(Vector pos, int n) { public void interact(Vector pos, int n) {
queue.add(new Action(1) { queue.add(new Action(1) {
@Override @Override
public void run() { public void run() {
Location location = translate(pos, true); Location location = translate(pos);
if (interactionDistanceViolation(location)) if (interactionDistanceViolation(location))
return; return;
Block block = location.getBlock(); Block block = location.getBlock();
@@ -199,13 +217,18 @@ public abstract class AI {
}); });
} }
protected void move(Vector pos) { public void move(Vector pos) {
queue.add(new Action(2) { queue.add(new Action(MOVEMENT_DELAY) {
@Override @Override
public void run() { public void run() {
Location location = entity.getLocation(); Location location = entity.getLocation();
Location target = translate(pos, false); if(!entity.isOnGround() && location.getBlock().getType() != Material.LADDER) {
if(Math.abs(location.getX() - target.getX()) > 1 || Math.abs(location.getY() - target.getY()) > 1.2 || Math.abs(location.getZ() - target.getZ()) > 1) { FightSystem.getPlugin().getLogger().log(Level.INFO, "Entity falling");
return;
}
Location target = translate(pos);
if(Math.abs(location.getX() - target.getX()) > 1.0 || Math.abs(location.getY() - target.getY()) > 1.5 || Math.abs(location.getZ() - target.getZ()) > 1.0) {
FightSystem.getPlugin().getLogger().log(Level.INFO, () -> entity.getName() + ": Overdistance movement " + location.toVector() + " " + target.toVector()); FightSystem.getPlugin().getLogger().log(Level.INFO, () -> entity.getName() + ": Overdistance movement " + location.toVector() + " " + target.toVector());
return; return;
} }
@@ -213,13 +236,16 @@ public abstract class AI {
if(!team.getFightPlayer(entity).canEntern() && !team.getExtendRegion().inRegion(target)) if(!team.getFightPlayer(entity).canEntern() && !team.getExtendRegion().inRegion(target))
return; return;
entity.teleport(target, PlayerTeleportEvent.TeleportCause.COMMAND); if(!entity.teleport(target, PlayerTeleportEvent.TeleportCause.PLUGIN))
FightSystem.getPlugin().getLogger().log(Level.INFO, "Entity not teleported: " + entity.isValid());
GlobalRecorder.getInstance().entityMoves(entity);
} }
}); });
} }
private boolean interactionDistanceViolation(Location location) { private boolean interactionDistanceViolation(Location location) {
return location.distance(entity.getEyeLocation()) > 5; return location.distance(entity.getEyeLocation()) > INTERACTION_RANGE;
} }
private void interact(Block block) { private void interact(Block block) {
@@ -249,23 +275,51 @@ public abstract class AI {
powerable.setPowered(false); powerable.setPowered(false);
block.setBlockData(powerable); block.setBlockData(powerable);
updateButton(block);
}, type.name().endsWith("STONE_BUTTON") ? 20 : 30); }, type.name().endsWith("STONE_BUTTON") ? 20 : 30);
} }
powerable.setPowered(!isPowered); powerable.setPowered(!isPowered);
} }
block.setBlockData(data); block.setBlockData(data);
if(data instanceof Switch) {
updateButton(block);
}
}
private void updateButton(Block block) {
Switch sw = (Switch) block.getBlockData();
FaceAttachable.AttachedFace face = sw.getAttachedFace();
if (face == FaceAttachable.AttachedFace.FLOOR) {
update(block.getRelative(BlockFace.DOWN));
} else if (face == FaceAttachable.AttachedFace.CEILING) {
update(block.getRelative(BlockFace.UP));
} else {
update(block.getRelative(sw.getFacing().getOppositeFace()));
}
}
private void update(Block block) {
BlockData data = block.getBlockData();
block.setType(Material.BARRIER);
block.setBlockData(data);
} }
private void run() { private void run() {
if(queue.isEmpty()) if(queue.isEmpty()) {
try {
plan(); plan();
} catch (Throwable t) {
stop();
throw t;
}
}
if(!queue.isEmpty() && --queue.peek().delay == 0) if(!queue.isEmpty() && --queue.peek().delay == 0)
queue.poll().run(); queue.poll().run();
} }
private Location translate(Vector pos, boolean blockPos) { public Location translate(Vector pos) {
Region extend = team.getExtendRegion(); Region extend = team.getExtendRegion();
if(Fight.getUnrotated() == team) if(Fight.getUnrotated() == team)
return new Location( return new Location(
@@ -277,9 +331,9 @@ public abstract class AI {
else else
return new Location( return new Location(
Config.world, Config.world,
extend.getMaxX() - pos.getX() - (blockPos ? 1 : 0), extend.getMaxX() - pos.getX(),
pos.getY() + team.getSchemRegion().getMinY(), pos.getY() + team.getSchemRegion().getMinY(),
extend.getMaxZ() - pos.getZ() - (blockPos ? 1 : 0) extend.getMaxZ() - pos.getZ()
); );
} }
@@ -0,0 +1,57 @@
/*
* 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.ai;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.fightsystem.ArenaMode;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.fight.FightTeam;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.bukkit.Material;
import java.util.Arrays;
import java.util.List;
import java.util.function.BooleanSupplier;
import java.util.stream.Collectors;
@AllArgsConstructor
public class AIManager {
private static final List<AIManager> AIs = Arrays.asList(
new AIManager(DummyAI.class, Material.STONE, () -> ArenaMode.Test.contains(Config.mode))
);
public static List<AIManager> availableAIs() {
return AIs.stream().filter(manager -> manager.available.getAsBoolean()).collect(Collectors.toList());
}
private final Class<? extends AI> aiClass;
@Getter
private final Material icon;
private final BooleanSupplier available;
public String name() {
return aiClass.getSimpleName();
}
public void join(FightTeam team) {
Reflection.getConstructor(aiClass, FightTeam.class).invoke(team);
}
}
@@ -19,42 +19,42 @@
package de.steamwar.fightsystem.ai; package de.steamwar.fightsystem.ai;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.fight.FightTeam; import de.steamwar.fightsystem.fight.FightTeam;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.utils.FightStatistics;
import de.steamwar.sql.SchematicNode; import de.steamwar.sql.SchematicNode;
import de.steamwar.sql.SteamwarUser; import de.steamwar.sql.SteamwarUser;
import org.bukkit.util.Vector;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
public class LixfelAI extends AI { public class DummyAI extends AI {
private final Random random = new Random(); private static final Random random = new Random();
private LixfelPathplanner pathplanner;
public LixfelAI(FightTeam team, String user) { public DummyAI(FightTeam team) {
super(team, SteamwarUser.get(user)); super(team, SteamwarUser.get("public"));
FightStatistics.unrank();
getEntity().setInvulnerable(true);
} }
@Override @Override
public SchematicNode chooseSchematic() { public SchematicNode chooseSchematic() {
List<SchematicNode> publics = SchematicNode.getAllSchematicsOfType(0, Config.SchematicType.toDB()); List<SchematicNode> publics = SchematicNode.getAllSchematicsOfType(0, Config.SchematicType.toDB());
SchematicNode schem = publics.get(new Random().nextInt(publics.size())); return publics.get(random.nextInt(publics.size()));
pathplanner = new LixfelPathplanner(schem); }
return schem;
@Override
public void schematic(Clipboard clipboard) {
//does nothing
} }
@Override @Override
protected void plan() { protected void plan() {
if(FightState.getFightState() == FightState.POST_SCHEM_SETUP)
setReady(); setReady();
Vector destination = pathplanner.getWalkable().get(random.nextInt(pathplanner.getWalkable().size()));
List<Vector> path = pathplanner.plan(getPosition(), destination);
if(!path.isEmpty())
chat("Path size: " + path.size());
for(Vector p : path) {
move(p);
}
} }
} }
@@ -1,141 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2023 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.ai;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.world.block.BlockType;
import de.steamwar.fightsystem.Config;
import de.steamwar.sql.SchematicData;
import de.steamwar.sql.SchematicNode;
import org.bukkit.util.Vector;
import java.io.IOException;
import java.util.*;
public class LixfelPathplanner {
private static BlockType getBlockType(Clipboard clipboard, BlockVector3 vector) {
return clipboard.getBlock(vector).getBlockType();
}
private static boolean nonsolid(Clipboard clipboard, BlockVector3 vector) {
return !getBlockType(clipboard, vector).getMaterial().isSolid();
}
private static Vector toBukkit(BlockVector3 vector) {
return new Vector(vector.getX() + 0.5, vector.getY(), vector.getZ() + 0.5);
}
private final List<Vector> walkable = new ArrayList<>();
private final Map<Vector, Vector[]> neighbours = new HashMap<>();
public LixfelPathplanner(SchematicNode schem) {
try {
fillWalkable(new SchematicData(schem).load());
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
public List<Vector> getWalkable() {
return walkable;
}
private void fillWalkable(Clipboard clipboard) {
BlockVector3 min = clipboard.getRegion().getMinimumPoint().subtract(Config.PreperationArea, 0, Config.PreperationArea); //TODO assumes nonextended Schematic with maximal size
Region region = clipboard.getRegion();
clipboard.getRegion().forEach(vector -> {
BlockVector3 below = vector.subtract(0, 1, 0);
if(!region.contains(below))
return;
BlockType belowMaterial = getBlockType(clipboard, below);
BlockVector3 above = vector.add(0, 1, 0);
if(nonsolid(clipboard, vector)) {
if(
(belowMaterial.getMaterial().isSolid() || belowMaterial.getId().equals("minecraft:ladder")) &&
(!region.contains(above) || nonsolid(clipboard, above))
)
walkable.add(toBukkit(vector.subtract(min)));
} else {
if(!region.contains(above))
walkable.add(toBukkit(above.subtract(min)));
}
});
for(Vector vector : walkable) {
neighbours.put(vector, walkable.stream().filter(neighbour -> neighbouring(neighbour, vector)).filter(neighbour -> neighbour != vector).toArray(Vector[]::new));
}
}
public List<Vector> planToAnywhere(Vector start, Vector destination) {
Vector intermediate = walkable.stream().filter(vector -> neighbouring(vector, destination)).findAny().orElse(null);
if(intermediate == null)
return Collections.emptyList();
List<Vector> plan = plan(start, intermediate);
plan.add(destination);
return plan;
}
public List<Vector> plan(Vector start, Vector destination) {
if(neighbouring(start, destination))
return Collections.singletonList(destination);
Map<Vector, Vector> approach = new HashMap<>();
Set<Vector> checking = Collections.singleton(destination);
while(!checking.isEmpty()) {
Set<Vector> toCheck = new HashSet<>();
for(Vector current : checking) {
Vector firstStep = Arrays.stream(neighbours.get(current))
.filter(vector -> !approach.containsKey(vector))
.filter(next -> {
approach.put(next, current);
toCheck.add(next);
return neighbouring(next, start);
})
.findAny().orElse(null);
if(firstStep != null) {
List<Vector> path = new ArrayList<>();
path.add(firstStep);
while(path.get(path.size()-1) != destination) {
path.add(approach.get(path.get(path.size()-1)));
}
return path;
}
}
checking = toCheck;
}
return Collections.emptyList();
}
private boolean neighbouring(Vector a, Vector b) {
return Math.abs(a.getX() - b.getX()) <= 1 && Math.abs(a.getY() - b.getY()) <= 1 && Math.abs(a.getZ() - b.getZ()) <= 1;
}
}
@@ -22,6 +22,7 @@ package de.steamwar.fightsystem.commands;
import de.steamwar.fightsystem.ArenaMode; import de.steamwar.fightsystem.ArenaMode;
import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.FightSystem; import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.ai.AIManager;
import de.steamwar.fightsystem.fight.*; import de.steamwar.fightsystem.fight.*;
import de.steamwar.fightsystem.listener.PersonalKitCreator; import de.steamwar.fightsystem.listener.PersonalKitCreator;
import de.steamwar.fightsystem.states.FightState; import de.steamwar.fightsystem.states.FightState;
@@ -38,9 +39,8 @@ import org.bukkit.Material;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.ClickType;
import java.util.ArrayList; import java.util.*;
import java.util.List; import java.util.stream.Collectors;
import java.util.UUID;
public class GUI { public class GUI {
private GUI(){} private GUI(){}
@@ -53,7 +53,7 @@ public class GUI {
String name = team.getLeader() != null ? team.getLeader().getEntity().getName() : team.getName(); String name = team.getLeader() != null ? team.getLeader().getEntity().getName() : team.getName();
inv.setItem(pos, SWItem.getDye(colorCode), colorCode, msg.parse("JOIN_REQUEST_TEAM", p, team.getColor() + name), click -> { inv.setItem(pos, SWItem.getDye(colorCode), colorCode, msg.parse("JOIN_REQUEST_TEAM", p, team.getColor() + name), click -> {
p.closeInventory(); p.closeInventory();
new JoinRequest(p, team); JoinRequest.forPlayer(p, team);
}); });
} }
@@ -89,11 +89,29 @@ public class GUI {
inv.open(); inv.open();
} }
public static void chooseJoinRequests(Player p){ public static void addAI(Player p) {
List<SWListInv.SWListEntry<Player>> players = JoinRequest.openRequests(p, Fight.getPlayerTeam(p)); SWListInv<AIManager> inv = new SWListInv<>(
SWListInv<Player> inv = new SWListInv<>(p, msg.parse("REQUESTS_TITLE", p), players, (ClickType click, Player player) -> { p, msg.parse("ADD_AI_TITLE", p),
AIManager.availableAIs().stream().map(manager -> new SWListInv.SWListEntry<>(new SWItem(manager.getIcon(), manager.name()), manager)).collect(Collectors.toList()),
(click, manager) -> {
FightTeam team = Fight.getPlayerTeam(p);
if(FightState.PreLeaderSetup.contains(FightState.getFightState())) {
manager.join(Fight.getOpposite(team));
} else {
JoinRequest.forAI(manager, team);
}
p.closeInventory(); p.closeInventory();
RequestsCommand.onJoinRequest(p, player, click.isLeftClick() ? JoinRequest::accept : JoinRequest::decline); }
);
inv.setCallback(-999, (ClickType click) -> p.closeInventory());
inv.open();
}
public static void chooseJoinRequests(Player p){
List<SWListInv.SWListEntry<JoinRequest>> players = JoinRequest.openRequests(p, Fight.getPlayerTeam(p));
SWListInv<JoinRequest> inv = new SWListInv<>(p, msg.parse("REQUESTS_TITLE", p), players, (ClickType click, JoinRequest request) -> {
p.closeInventory();
RequestsCommand.onJoinRequest(p, request, click.isLeftClick() ? JoinRequest::accept : JoinRequest::decline);
}); });
inv.setCallback(-999, (ClickType click) -> p.closeInventory()); inv.setCallback(-999, (ClickType click) -> p.closeInventory());
inv.open(); inv.open();
@@ -59,13 +59,7 @@ public class RequestsCommand implements CommandExecutor {
return false; return false;
} }
public static void onJoinRequest(Player player, Player target, BiConsumer<JoinRequest, FightTeam> handleJoinRequest) { public static void onJoinRequest(Player player, JoinRequest request, BiConsumer<JoinRequest, FightTeam> handleJoinRequest) {
JoinRequest request = JoinRequest.get(target);
if(request == null) {
FightSystem.getMessage().send("NO_JOIN_REQUEST", player);
return;
}
FightTeam team = Fight.getPlayerTeam(player); FightTeam team = Fight.getPlayerTeam(player);
if(!request.required(team)) { if(!request.required(team)) {
FightSystem.getMessage().send("NO_CONFIRMATION", player); FightSystem.getMessage().send("NO_CONFIRMATION", player);
@@ -34,6 +34,7 @@ import de.steamwar.fightsystem.utils.WorldeditWrapper;
import de.steamwar.sql.SchematicData; import de.steamwar.sql.SchematicData;
import de.steamwar.sql.SchematicNode; import de.steamwar.sql.SchematicNode;
import de.steamwar.sql.SchematicType; import de.steamwar.sql.SchematicType;
import lombok.Getter;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.DyeColor; import org.bukkit.DyeColor;
import org.bukkit.Location; import org.bukkit.Location;
@@ -52,6 +53,7 @@ public class FightSchematic extends StateDependent {
private final Region region; private final Region region;
private final boolean rotate; private final boolean rotate;
@Getter
private Clipboard clipboard = null; private Clipboard clipboard = null;
private int schematic = 0; private int schematic = 0;
@@ -137,6 +139,7 @@ public class FightSchematic extends StateDependent {
private void paste(){ private void paste(){
FreezeWorld freezer = new FreezeWorld(); FreezeWorld freezer = new FreezeWorld();
team.teleportToSpawn();
Vector dims = WorldeditWrapper.impl.getDimensions(clipboard); Vector dims = WorldeditWrapper.impl.getDimensions(clipboard);
WorldeditWrapper.impl.pasteClipboard( WorldeditWrapper.impl.pasteClipboard(
clipboard, clipboard,
@@ -149,11 +152,11 @@ public class FightSchematic extends StateDependent {
new AffineTransform().rotateY(rotate ? 180 : 0) new AffineTransform().rotateY(rotate ? 180 : 0)
); );
FightSystem.getHullHider().initialize(team); FightSystem.getHullHider().initialize(team);
team.getPlayers().forEach(fightPlayer -> fightPlayer.ifAI(ai -> ai.schematic(clipboard)));
if(ArenaMode.Check.contains(Config.mode) && !team.isBlue()) if(ArenaMode.Check.contains(Config.mode) && !team.isBlue())
replaceSync(Material.TNT, Material.OBSIDIAN); replaceSync(Material.TNT, Material.RED_WOOL);
Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), freezer::disable, 3); Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), freezer::disable, 3);
Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), team::teleportToSpawn, 40);
} }
@Override @Override
@@ -23,6 +23,7 @@ import com.sk89q.worldedit.extent.clipboard.Clipboard;
import de.steamwar.fightsystem.ArenaMode; import de.steamwar.fightsystem.ArenaMode;
import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.FightSystem; import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.ai.AIManager;
import de.steamwar.fightsystem.commands.GUI; import de.steamwar.fightsystem.commands.GUI;
import de.steamwar.fightsystem.countdown.Countdown; import de.steamwar.fightsystem.countdown.Countdown;
import de.steamwar.fightsystem.events.TeamLeaveEvent; import de.steamwar.fightsystem.events.TeamLeaveEvent;
@@ -70,9 +71,11 @@ public class FightTeam {
static { static {
setKitButton(notReadyKit, true); setKitButton(notReadyKit, true);
if(!ArenaMode.RankedEvent.contains(Config.mode)){ if(ArenaMode.VariableTeams.contains(Config.mode)){
notReadyKit.setItem(2, "REQUESTS", new ItemBuilder(Material.PAPER).build(), GUI::chooseJoinRequests); notReadyKit.setItem(2, "REQUESTS", new ItemBuilder(Material.PAPER).build(), GUI::chooseJoinRequests);
notReadyKit.setItem(3, "REMOVE_PLAYERS", new ItemBuilder(SWItem.getMaterial("FIREWORK_CHARGE")).build(), GUI::chooseRemove); notReadyKit.setItem(3, "REMOVE_PLAYERS", new ItemBuilder(SWItem.getMaterial("FIREWORK_CHARGE")).build(), GUI::chooseRemove);
if(!AIManager.availableAIs().isEmpty())
notReadyKit.setItem(6, "ADD_AI", new ItemBuilder(Material.REDSTONE).build(), GUI::addAI);
} }
if(Config.test()) if(Config.test())
@@ -452,6 +455,10 @@ public class FightTeam {
return schematic.getId(); return schematic.getId();
} }
public Clipboard getClipboard() {
return schematic.getClipboard();
}
public double getCurrentHearts() { public double getCurrentHearts() {
return players.values().stream().filter(FightPlayer::isLiving).mapToDouble(fp -> fp.getEntity().getHealth()).sum(); return players.values().stream().filter(FightPlayer::isLiving).mapToDouble(fp -> fp.getEntity().getHealth()).sum();
} }
@@ -20,6 +20,7 @@
package de.steamwar.fightsystem.fight; package de.steamwar.fightsystem.fight;
import de.steamwar.fightsystem.FightSystem; import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.ai.AIManager;
import de.steamwar.fightsystem.states.FightState; import de.steamwar.fightsystem.states.FightState;
import de.steamwar.inventory.SWItem; import de.steamwar.inventory.SWItem;
import de.steamwar.inventory.SWListInv; import de.steamwar.inventory.SWListInv;
@@ -28,44 +29,66 @@ import net.md_5.bungee.api.chat.ClickEvent;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.*; import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class JoinRequest { public class JoinRequest {
private static final Map<Player, JoinRequest> activeRequests = new HashMap<>(); private static final Map<Player, JoinRequest> playerRequests = new HashMap<>();
private static final List<JoinRequest> activeRequests = new ArrayList<>();
public static JoinRequest get(Player player) {
return playerRequests.get(player);
}
public static List<SWListInv.SWListEntry<Player>> openRequests(Player p, FightTeam team) { public static List<SWListInv.SWListEntry<JoinRequest>> openRequests(Player p, FightTeam team) {
return activeRequests.values().stream().filter( return activeRequests.stream().filter(
request -> request.waitOnApproval.contains(team) request -> request.waitOnApproval.contains(team)
).map(request -> { ).map(request -> {
SWItem item = SWItem.getPlayerSkull(request.player); AtomicReference<SWItem> item = new AtomicReference<>();
item.setLore(Arrays.asList( request.enquirer.ifPlayer(player -> item.set(SWItem.getPlayerSkull(player)));
request.enquirer.ifAI(manager -> item.set(new SWItem(manager.getIcon(), manager.name())));
item.get().setLore(Arrays.asList(
FightSystem.getMessage().parse("REQUESTS_LEFT_CLICK", p), FightSystem.getMessage().parse("REQUESTS_LEFT_CLICK", p),
FightSystem.getMessage().parse("REQUESTS_RIGHT_CLICK", p) FightSystem.getMessage().parse("REQUESTS_RIGHT_CLICK", p)
)); ));
return new SWListInv.SWListEntry<>(item, request.player); return new SWListInv.SWListEntry<>(item.get(), request);
}).collect(Collectors.toList()); }).collect(Collectors.toList());
} }
public static void clearRequests() { public static void clearRequests() {
playerRequests.clear();
activeRequests.clear(); activeRequests.clear();
} }
public static JoinRequest get(Player player) { public static void forPlayer(Player player, FightTeam team) {
return activeRequests.get(player); new JoinRequest(new Enquirer() {
@Override public String name() { return player.getName(); }
@Override public void ifPlayer(Consumer<Player> function) { function.accept(player); }
@Override public void ifAI(Consumer<AIManager> function) {}
}, team, FightState.ingame() ? Fight.teams() : Collections.singleton(team));
} }
private final Player player; public static void forAI(AIManager manager, FightTeam team) {
new JoinRequest(new Enquirer() {
@Override public String name() { return manager.name(); }
@Override public void ifPlayer(Consumer<Player> function) {}
@Override public void ifAI(Consumer<AIManager> function) { function.accept(manager); }
}, team, Collections.singleton(Fight.getOpposite(team)));
}
private final Enquirer enquirer;
private final FightTeam team; private final FightTeam team;
private final Set<FightTeam> waitOnApproval; private final Set<FightTeam> waitOnApproval;
public JoinRequest(Player player, FightTeam team) { private JoinRequest(Enquirer enquirer, FightTeam team, Collection<FightTeam> waitOnApproval) {
this.player = player; this.enquirer = enquirer;
this.team = team; this.team = team;
this.waitOnApproval = new HashSet<>(FightState.ingame() ? Fight.teams() : Collections.singleton(team)); this.waitOnApproval = new HashSet<>(waitOnApproval);
Set<FightTeam> alreadyAccepted = new HashSet<>(); Set<FightTeam> alreadyAccepted = new HashSet<>();
activeRequests.put(player, this); enquirer.ifPlayer(player -> playerRequests.put(player, this));
activeRequests.add(this);
for(FightTeam t : waitOnApproval) { for(FightTeam t : waitOnApproval) {
FightPlayer leader = t.getLeader(); FightPlayer leader = t.getLeader();
if(leader == null) if(leader == null)
@@ -74,14 +97,14 @@ public class JoinRequest {
if(leader.getEntity() == null) if(leader.getEntity() == null)
continue; continue;
leader.ifPlayer(leaderPlayer -> FightSystem.getMessage().sendPrefixless("JOIN_REQUEST_NOTIFICATION", leaderPlayer, "REQUESTS", new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/requests"), player.getName(), team.getColoredName())); leader.ifPlayer(leaderPlayer -> FightSystem.getMessage().sendPrefixless("JOIN_REQUEST_NOTIFICATION", leaderPlayer, "REQUESTS", new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/requests"), enquirer.name(), team.getColoredName()));
leader.ifAI(ai -> { leader.ifAI(ai -> {
if(ai.acceptJoinRequest(player, team)) if(ai.acceptJoinRequest(enquirer, team))
alreadyAccepted.add(t); alreadyAccepted.add(t);
}); });
} }
FightSystem.getMessage().sendPrefixless("JOIN_REQUEST_CONFIRMATION", player, ChatMessageType.ACTION_BAR); enquirer.ifPlayer(player -> FightSystem.getMessage().sendPrefixless("JOIN_REQUEST_CONFIRMATION", player, ChatMessageType.ACTION_BAR));
alreadyAccepted.forEach(this::accept); alreadyAccepted.forEach(this::accept);
} }
@@ -93,18 +116,26 @@ public class JoinRequest {
waitOnApproval.remove(acceptor); waitOnApproval.remove(acceptor);
if(waitOnApproval.isEmpty()) { if(waitOnApproval.isEmpty()) {
team.addMember(player); enquirer.ifPlayer(team::addMember);
activeRequests.remove(player); enquirer.ifAI(manager -> manager.join(team));
close();
} }
} }
public void decline(FightTeam declinor) { public void decline(FightTeam declinor) {
FightSystem.getMessage().sendPrefixless("REQUEST_YOUR_DECLINED", player, ChatMessageType.ACTION_BAR); enquirer.ifPlayer(player -> FightSystem.getMessage().sendPrefixless("REQUEST_YOUR_DECLINED", player, ChatMessageType.ACTION_BAR));
waitOnApproval.forEach(t -> t.broadcast("REQUEST_DECLINED", player.getName())); waitOnApproval.forEach(t -> t.broadcast("REQUEST_DECLINED", enquirer.name()));
silentDecline(); close();
} }
public void silentDecline() { public void close() {
activeRequests.remove(player); enquirer.ifPlayer(playerRequests::remove);
activeRequests.remove(this);
}
public interface Enquirer {
String name();
void ifPlayer(Consumer<Player> function);
void ifAI(Consumer<AIManager> function);
} }
} }
@@ -69,6 +69,6 @@ public class JoinRequestListener implements Listener {
public void onLeave(PlayerQuitEvent event) { public void onLeave(PlayerQuitEvent event) {
JoinRequest request = JoinRequest.get(event.getPlayer()); JoinRequest request = JoinRequest.get(event.getPlayer());
if(request != null) if(request != null)
request.silentDecline(); request.close();
} }
} }
@@ -43,6 +43,7 @@ import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
@@ -70,7 +71,7 @@ public class Recording implements Listener {
return stack; return stack;
} }
public static boolean isNotSent(Player p){ public static boolean isNotSent(LivingEntity p){
FightPlayer fp = Fight.getFightPlayer(p); FightPlayer fp = Fight.getFightPlayer(p);
return fp == null || !fp.isLiving() || FightState.getFightState() == FightState.SPECTATE; return fp == null || !fp.isLiving() || FightState.getFightState() == FightState.SPECTATE;
} }
@@ -193,10 +194,10 @@ public class Recording implements Listener {
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onEntityDamage(EntityDamageEvent e) { public void onEntityDamage(EntityDamageEvent e) {
if(e.getEntityType() != EntityType.PLAYER) if(!e.getEntityType().isAlive())
return; return;
Player p = (Player) e.getEntity(); LivingEntity p = (LivingEntity) e.getEntity();
if(isNotSent(p)) if(isNotSent(p))
return; return;
@@ -208,10 +209,10 @@ public class Recording implements Listener {
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onEntityCombust(EntityCombustEvent e) { public void onEntityCombust(EntityCombustEvent e) {
if(e.getEntityType() != EntityType.PLAYER) if(!e.getEntityType().isAlive())
return; return;
Player p = (Player) e.getEntity(); LivingEntity p = (LivingEntity) e.getEntity();
if(isNotSent(p)) if(isNotSent(p))
return; return;
@@ -204,7 +204,7 @@ public interface Recorder {
write(0x0a, e.getEntityId(), start, offHand); write(0x0a, e.getEntityId(), start, offHand);
} }
default void damageAnimation(Player p) { default void damageAnimation(LivingEntity p) {
write(0x0b, p.getEntityId()); write(0x0b, p.getEntityId());
} }
+1 -1
View File
@@ -27,7 +27,7 @@ java {
} }
dependencies { dependencies {
compileOnly(project(":SpigotCore")) compileOnly(project(":SpigotCore", "default"))
compileOnly(libs.spigotapi) compileOnly(libs.spigotapi)
@@ -4,8 +4,12 @@ DATE=........
COMMAND_HELP_HEAD=§7---=== (§e{0}§7) ===--- COMMAND_HELP_HEAD=§7---=== (§e{0}§7) ===---
# ServerTeamNPC's # ServerTeamNPC's
NPC_CHAT_1 = §fHello, I''m {0} and I''m a(n) {1}§f. NPC_CHAT_0 = §fHello, I''m {0} and I''m a(n) {1}§f.
NPC_CHAT_2 = §fWelcome on §eSteam§8War§f, have fun. NPC_CHAT_1 = §fWelcome on §eSteam§8War§f, have fun.
NPC_CHAT_2 = §eSteam§8War§f was established in 2019.
NPC_CHAT_3 = &fBecome a part of our team by applying via our Discord server (https://steamwar.de/discord).
NPC_CHAT_4 = &fYou can develop your own buildserver features with our Lua script system.
NPC_CHAT_5 = &fThere are many secrets to discover in this lobby.
# Portal Command # Portal Command
PORTAL_COMMAND_LIST_HELP = §8/§7portal §elist §8- §7Lists all portals PORTAL_COMMAND_LIST_HELP = §8/§7portal §elist §8- §7Lists all portals
@@ -4,8 +4,12 @@ DATE=........
COMMAND_HELP_HEAD=§7---=== (§e{0}§7) ===--- COMMAND_HELP_HEAD=§7---=== (§e{0}§7) ===---
# ServerTeamNPC's # ServerTeamNPC's
NPC_CHAT_1 = §fHallo, ich bin {0} und bin ein {1}§f. NPC_CHAT_0 = §fHallo, ich bin {0} und bin ein {1}§f.
NPC_CHAT_2 = §fWillkommen auf §eSteam§8War§f, viel Spaß dir. NPC_CHAT_1 = §fWillkommen auf §eSteam§8War§f, viel Spaß dir.
NPC_CHAT_2 = §eSteam§8War§f gibt es seit 2019.
NPC_CHAT_3 = &fBewerbe dich gerne für unser Team über unseren Discord-Server (https://steamwar.de/discord).
NPC_CHAT_4 = &fDu kannst mit unserm Lua Script-System deine eigenen Bau Features programmieren.
NPC_CHAT_5 = &fAuf dieser Lobby sind so einige secrets versteckt.
# Portal Command # Portal Command
PORTAL_COMMAND_LIST_HELP = §8/§7portal §elist §8- §7Listet alle Portale auf PORTAL_COMMAND_LIST_HELP = §8/§7portal §elist §8- §7Listet alle Portale auf
@@ -222,11 +222,13 @@ public class FightserverPortal implements PortalHandler, Comparable<FightserverP
case "PRE_SCHEM_SETUP": case "PRE_SCHEM_SETUP":
return "Schemauswahl"; return "Schemauswahl";
case "POST_SCHEM_SETUP": case "POST_SCHEM_SETUP":
case "generating_tower":
return "Vorbereitung"; return "Vorbereitung";
case "PRE_RUNNING": case "PRE_RUNNING":
return "Kampfbeginn in"; return "Kampfbeginn in";
case "fighting": case "fighting":
case "RUNNING": case "RUNNING":
case "running":
return "Kampf läuft"; return "Kampf läuft";
case "end": case "end":
case "SPECTATE": case "SPECTATE":
@@ -60,11 +60,6 @@ public class TeamPlayer extends BasicListener {
private Set<Player> players = new HashSet<>(); private Set<Player> players = new HashSet<>();
private Random random = new Random(); private Random random = new Random();
private List<String> strings = new ArrayList<>();
{
strings.add("NPC_CHAT_1");
strings.add("NPC_CHAT_2");
}
public static void spawnTeamPlayer(World world, SteamwarUser steamwarUser) { public static void spawnTeamPlayer(World world, SteamwarUser steamwarUser) {
Location location = new Location(world, 2790.5, 69, 1311.5); Location location = new Location(world, 2790.5, 69, 1311.5);
@@ -149,8 +144,9 @@ public class TeamPlayer extends BasicListener {
players.remove(event.getPlayer()); players.remove(event.getPlayer());
return; return;
} }
String message = "NPC_Chat_" + random.nextInt(6);
SteamwarUser user = SteamwarUser.get(event.getRightClicked().getName()); SteamwarUser user = SteamwarUser.get(event.getRightClicked().getName());
String message = strings.get(random.nextInt(strings.size()));
UserPerm.Prefix prefix = user.prefix(); UserPerm.Prefix prefix = user.prefix();
LobbySystem.getMessage().send(message, event.getPlayer(), event.getRightClicked().getName(), prefix.getColorCode() + prefix.getChatPrefix()); LobbySystem.getMessage().send(message, event.getPlayer(), event.getRightClicked().getName(), prefix.getColorCode() + prefix.getChatPrefix());
} }
+1 -1
View File
@@ -27,7 +27,7 @@ java {
} }
dependencies { dependencies {
compileOnly(project(":SpigotCore")) compileOnly(project(":SpigotCore", "default"))
compileOnly(libs.spigotapi) compileOnly(libs.spigotapi)
@@ -22,8 +22,8 @@ plugins {
} }
dependencies { dependencies {
compileOnly(project(":SpigotCore")) compileOnly(project(":SpigotCore", "default"))
compileOnly(project(":SchematicSystem:SchematicSystem_Core")) compileOnly(project(":SchematicSystem:SchematicSystem_Core", "default"))
compileOnly(libs.nms15) compileOnly(libs.nms15)
compileOnly(libs.worldedit15) compileOnly(libs.worldedit15)
@@ -22,8 +22,8 @@ plugins {
} }
dependencies { dependencies {
compileOnly(project(":SpigotCore")) compileOnly(project(":SpigotCore", "default"))
compileOnly(project(":SchematicSystem:SchematicSystem_Core")) compileOnly(project(":SchematicSystem:SchematicSystem_Core", "default"))
compileOnly(libs.nms8) compileOnly(libs.nms8)
compileOnly(libs.worldedit12) compileOnly(libs.worldedit12)
@@ -22,7 +22,7 @@ plugins {
} }
dependencies { dependencies {
compileOnly(project(":SpigotCore")) compileOnly(project(":SpigotCore", "default"))
compileOnly(libs.spigotapi) compileOnly(libs.spigotapi)
compileOnly(libs.worldedit15) compileOnly(libs.worldedit15)
+1 -1
View File
@@ -22,7 +22,7 @@ plugins {
} }
dependencies { dependencies {
compileOnly(project(":SpigotCore:SpigotCore_Main")) compileOnly(project(":SpigotCore:SpigotCore_Main", "default"))
compileOnly(libs.nms10) compileOnly(libs.nms10)
} }
+2 -2
View File
@@ -22,8 +22,8 @@ plugins {
} }
dependencies { dependencies {
compileOnly(project(":CommonCore")) compileOnly(project(":CommonCore", "default"))
compileOnly(project(":SpigotCore:SpigotCore_Main")) compileOnly(project(":SpigotCore:SpigotCore_Main", "default"))
compileOnly(libs.nms12) compileOnly(libs.nms12)
} }
+4 -4
View File
@@ -22,10 +22,10 @@ plugins {
} }
dependencies { dependencies {
compileOnly(project(":CommonCore")) compileOnly(project(":CommonCore", "default"))
compileOnly(project(":SpigotCore:SpigotCore_Main")) compileOnly(project(":SpigotCore:SpigotCore_Main", "default"))
compileOnly(project(":SpigotCore:SpigotCore_8")) compileOnly(project(":SpigotCore:SpigotCore_8", "default"))
compileOnly(project(":SpigotCore:SpigotCore_9")) compileOnly(project(":SpigotCore:SpigotCore_9", "default"))
compileOnly(libs.nms14) compileOnly(libs.nms14)
compileOnly(libs.worldedit15) compileOnly(libs.worldedit15)
+1 -1
View File
@@ -22,7 +22,7 @@ plugins {
} }
dependencies { dependencies {
compileOnly(project(":SpigotCore:SpigotCore_Main")) compileOnly(project(":SpigotCore:SpigotCore_Main", "default"))
compileOnly(libs.nms15) compileOnly(libs.nms15)
} }
+3 -3
View File
@@ -26,9 +26,9 @@ tasks.compileJava {
} }
dependencies { dependencies {
compileOnly(project(":CommonCore")) compileOnly(project(":CommonCore", "default"))
compileOnly(project(":SpigotCore:SpigotCore_Main")) compileOnly(project(":SpigotCore:SpigotCore_Main", "default"))
compileOnly(project(":SpigotCore:SpigotCore_14")) compileOnly(project(":SpigotCore:SpigotCore_14", "default"))
compileOnly(libs.spigotapi) compileOnly(libs.spigotapi)
compileOnly(libs.nms18) compileOnly(libs.nms18)
+3 -3
View File
@@ -22,9 +22,9 @@ plugins {
} }
dependencies { dependencies {
compileOnly(project(":SpigotCore:SpigotCore_Main")) compileOnly(project(":SpigotCore:SpigotCore_Main", "default"))
compileOnly(project(":SpigotCore:SpigotCore_14")) compileOnly(project(":SpigotCore:SpigotCore_14", "default"))
compileOnly(project(":SpigotCore:SpigotCore_18")) compileOnly(project(":SpigotCore:SpigotCore_18", "default"))
compileOnly(libs.worldedit15) compileOnly(libs.worldedit15)
compileOnly(libs.nms19) compileOnly(libs.nms19)
+1 -1
View File
@@ -22,7 +22,7 @@ plugins {
} }
dependencies { dependencies {
compileOnly(project(":SpigotCore:SpigotCore_Main")) compileOnly(project(":SpigotCore:SpigotCore_Main", "default"))
compileOnly(libs.spigotapi) compileOnly(libs.spigotapi)
+2 -2
View File
@@ -22,8 +22,8 @@ plugins {
} }
dependencies { dependencies {
compileOnly(project(":CommonCore")) compileOnly(project(":CommonCore", "default"))
compileOnly(project(":SpigotCore:SpigotCore_Main")) compileOnly(project(":SpigotCore:SpigotCore_Main", "default"))
compileOnly(libs.nms8) compileOnly(libs.nms8)
compileOnly(libs.worldedit12) compileOnly(libs.worldedit12)
+2 -2
View File
@@ -22,8 +22,8 @@ plugins {
} }
dependencies { dependencies {
compileOnly(project(":SpigotCore:SpigotCore_Main")) compileOnly(project(":SpigotCore:SpigotCore_Main", "default"))
compileOnly(project(":SpigotCore:SpigotCore_8")) compileOnly(project(":SpigotCore:SpigotCore_8", "default"))
compileOnly(libs.nms9) compileOnly(libs.nms9)
+3 -3
View File
@@ -26,9 +26,9 @@ tasks.compileJava {
} }
dependencies { dependencies {
compileOnly(project(":CommonCore")) compileOnly(project(":CommonCore", "default"))
compileOnly(project(":CommandFramework")) compileOnly(project(":CommandFramework", "default"))
compileOnly(project(":SpigotCore:CRIUDummy")) compileOnly(project(":SpigotCore:CRIUDummy", "default"))
compileOnly(libs.worldedit12) compileOnly(libs.worldedit12)
@@ -36,6 +36,7 @@ import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import java.util.*; import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.logging.Level; import java.util.logging.Level;
@@ -102,7 +103,7 @@ public class TinyProtocol implements Listener {
} }
public void addFilter(Class<?> packetType, BiFunction<Player, Object, Object> filter) { public void addFilter(Class<?> packetType, BiFunction<Player, Object, Object> filter) {
packetFilters.computeIfAbsent(packetType, c -> Collections.synchronizedList(new ArrayList<>(1))).add(filter); packetFilters.computeIfAbsent(packetType, c -> new CopyOnWriteArrayList<>()).add(filter);
} }
public void removeFilter(Class<?> packetType, BiFunction<Player, Object, Object> filter) { public void removeFilter(Class<?> packetType, BiFunction<Player, Object, Object> filter) {
+2 -2
View File
@@ -4,6 +4,6 @@ plugins {
dependencies { dependencies {
compileOnly(libs.paperapi21) compileOnly(libs.paperapi21)
compileOnly(project(":SpigotCore")) compileOnly(project(":SpigotCore", "default"))
compileOnly(project(":KotlinCore")) compileOnly(project(":KotlinCore", "default"))
} }
+1 -1
View File
@@ -22,7 +22,7 @@ plugins {
} }
dependencies { dependencies {
compileOnly(project(":SpigotCore")) compileOnly(project(":SpigotCore", "default"))
compileOnly(libs.spigotapi) compileOnly(libs.spigotapi)
+1 -1
View File
@@ -30,7 +30,7 @@ dependencies {
annotationProcessor(libs.spigotannotations) annotationProcessor(libs.spigotannotations)
compileOnly(libs.spigotannotations) compileOnly(libs.spigotannotations)
compileOnly(project(":SpigotCore")) compileOnly(project(":SpigotCore", "default"))
compileOnly(libs.nms19) compileOnly(libs.nms19)
compileOnly(libs.worldedit15) compileOnly(libs.worldedit15)
@@ -0,0 +1,66 @@
/*
*
* 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.towerrun;
import de.steamwar.network.NetworkSender;
import de.steamwar.network.packets.common.FightInfoPacket;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.towerrun.config.Config;
import de.steamwar.towerrun.game.TowerRunGame;
import de.steamwar.towerrun.state.GameState;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class FightInfoPacketSender implements Runnable {
private final World world = Bukkit.getWorlds().get(0);
private final String serverName = Bukkit.getServer().getName();
private final String gameMode = "towerrun";
private final String worldName = world.getName();
private final String blueName = "§3Escaped";
private final String redName = "§cAlive";
@Override
public void run() {
if (Config.test()) {
return;
}
List<Integer> alivePlayers = TowerRunGame.PLAYERS_ALIVE.stream().map(player -> SteamwarUser.get(player.player().getUniqueId()).getId()).collect(Collectors.toList());
List<Integer> escapedPlayers = TowerRunGame.PLAYERS_ESCAPED.stream().map(player -> SteamwarUser.get(player.player().getUniqueId()).getId()).collect(Collectors.toList());
List<Integer> spectatorPlayers = new ArrayList<>();
for (Player player : Bukkit.getOnlinePlayers()) {
int id = SteamwarUser.get(player.getUniqueId()).getId();
if (!alivePlayers.contains(id) && !escapedPlayers.contains(id)) {
spectatorPlayers.add(id);
}
}
NetworkSender.send(new FightInfoPacket(serverName, gameMode, worldName, blueName, redName, GameState.getCurrentState().name().toLowerCase(), TowerRun.getGameCountdown().getPlayTimeInSeconds(), 0, 0, 0, 0, escapedPlayers, alivePlayers, spectatorPlayers));
}
}
@@ -32,6 +32,7 @@ import de.steamwar.towerrun.listener.IngameListener;
import de.steamwar.towerrun.listener.LobbyListener; import de.steamwar.towerrun.listener.LobbyListener;
import de.steamwar.towerrun.listener.NotLobbyListener; import de.steamwar.towerrun.listener.NotLobbyListener;
import lombok.Getter; import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.plugin.java.annotation.dependency.Dependency; import org.bukkit.plugin.java.annotation.dependency.Dependency;
import org.bukkit.plugin.java.annotation.plugin.ApiVersion; import org.bukkit.plugin.java.annotation.plugin.ApiVersion;
@@ -79,6 +80,8 @@ public class TowerRun extends JavaPlugin {
new StartCommand(lobbyCountdown); new StartCommand(lobbyCountdown);
gameCountdown = new GameCountdown(); gameCountdown = new GameCountdown();
Bukkit.getScheduler().runTaskTimer(this, new FightInfoPacketSender(), 20, 20);
TowerRunGame.reset(); TowerRunGame.reset();
} }
} }
@@ -39,6 +39,8 @@ public class Config {
public static final int GAME_TIMER; public static final int GAME_TIMER;
public static final int GAME_ESCAPE_TIMER; public static final int GAME_ESCAPE_TIMER;
private static final int EVENT_KAMPF_ID;
static { static {
File configFile = new File(TowerRun.getInstance().getDataFolder(), "config.yml"); File configFile = new File(TowerRun.getInstance().getDataFolder(), "config.yml");
if (!configFile.exists()) { if (!configFile.exists()) {
@@ -53,6 +55,11 @@ public class Config {
GAME_TIMER = config.getInt("gameTimer", 20 * 60); GAME_TIMER = config.getInt("gameTimer", 20 * 60);
GAME_ESCAPE_TIMER = config.getInt("gameEscapeTimer", 60); GAME_ESCAPE_TIMER = config.getInt("gameEscapeTimer", 60);
DESTROYABLE_BLOCKS = EnumSet.copyOf(config.getStringList("destroyable").stream().map(Material::valueOf).collect(Collectors.toSet())); DESTROYABLE_BLOCKS = EnumSet.copyOf(config.getStringList("destroyable").stream().map(Material::valueOf).collect(Collectors.toSet()));
EVENT_KAMPF_ID = Integer.parseInt(System.getProperty("fightID", "0"));
} }
public static boolean test() {
return EVENT_KAMPF_ID == -1;
}
} }
@@ -35,7 +35,7 @@ public class EndCountdown extends Countdown {
private static final boolean RESETS = Objects.requireNonNull(Bukkit.getWorlds().get(0).getWorldFolder().list((dir, name) -> name.equals("backup"))).length > 0; private static final boolean RESETS = Objects.requireNonNull(Bukkit.getWorlds().get(0).getWorldFolder().list((dir, name) -> name.equals("backup"))).length > 0;
public EndCountdown(LobbyCountdown lobbyCountdown) { public EndCountdown(LobbyCountdown lobbyCountdown) {
super(EnumSet.of(GameStates.ENDING)); super(EnumSet.of(GameStates.END));
this.lobbyCountdown = lobbyCountdown; this.lobbyCountdown = lobbyCountdown;
} }
@@ -28,8 +28,10 @@ import java.util.EnumSet;
public class GameCountdown extends Countdown { public class GameCountdown extends Countdown {
private long startTime = 0;
public GameCountdown() { public GameCountdown() {
super(EnumSet.of(GameStates.INGAME)); super(EnumSet.of(GameStates.RUNNING));
} }
@Override @Override
@@ -59,9 +61,21 @@ public class GameCountdown extends Countdown {
TowerRun.getMessage().broadcastActionbar("GAME_TIME", String.format("%02d", timeMinutes), String.format("%02d", timeSeconds)); TowerRun.getMessage().broadcastActionbar("GAME_TIME", String.format("%02d", timeMinutes), String.format("%02d", timeSeconds));
} }
@Override
public void enable() {
super.enable();
startTime = System.currentTimeMillis();
}
@Override @Override
public void disable() { public void disable() {
super.disable(); super.disable();
setTime(defaultTime()); setTime(defaultTime());
startTime = 0;
}
public int getPlayTimeInSeconds() {
if (startTime == 0) return 0;
return (int) ((System.currentTimeMillis() - startTime) / 1000);
} }
} }
@@ -37,7 +37,7 @@ public class LobbyCountdown extends Countdown {
private boolean override = false; private boolean override = false;
public LobbyCountdown() { public LobbyCountdown() {
super(EnumSet.of(GameStates.LOBBY)); super(EnumSet.of(GameStates.WAITING));
} }
@Override @Override
@@ -49,7 +49,7 @@ public class TowerRunGame {
} }
public static void prepareTowerOrStart() { public static void prepareTowerOrStart() {
if (GameState.getCurrentState() == GameStates.LOBBY) { if (GameState.getCurrentState() == GameStates.WAITING) {
GameState.nextState(); GameState.nextState();
if (TowerRun.getTowerGenerator() == null) { if (TowerRun.getTowerGenerator() == null) {
start(); start();
@@ -52,7 +52,7 @@ public class IngameListener extends GameStateBukkitListener {
private BukkitRunnable antiCampRunnable; private BukkitRunnable antiCampRunnable;
public IngameListener() { public IngameListener() {
super(EnumSet.of(GameStates.INGAME)); super(EnumSet.of(GameStates.RUNNING));
} }
@Override @Override
@@ -37,7 +37,7 @@ import java.util.EnumSet;
public class LobbyListener extends GameStateBukkitListener { public class LobbyListener extends GameStateBukkitListener {
public LobbyListener() { public LobbyListener() {
super(EnumSet.of(GameStates.LOBBY)); super(EnumSet.of(GameStates.WAITING));
} }
@EventHandler @EventHandler
@@ -31,7 +31,7 @@ import java.util.EnumSet;
public class NotLobbyListener extends GameStateBukkitListener { public class NotLobbyListener extends GameStateBukkitListener {
public NotLobbyListener() { public NotLobbyListener() {
super(EnumSet.complementOf(EnumSet.of(GameStates.LOBBY))); super(EnumSet.complementOf(EnumSet.of(GameStates.WAITING)));
} }
@EventHandler @EventHandler
@@ -28,7 +28,7 @@ import java.util.List;
@UtilityClass @UtilityClass
public class GameState { public class GameState {
@Getter @Getter
private static GameStates currentState = GameStates.LOBBY; private static GameStates currentState = GameStates.WAITING;
private static final List<GameStateListener> gameStateListeners = new ArrayList<>(); private static final List<GameStateListener> gameStateListeners = new ArrayList<>();
public static void addGameStateListener(GameStateListener gameStateListener) { public static void addGameStateListener(GameStateListener gameStateListener) {
@@ -49,7 +49,7 @@ public class GameState {
public static void reset() { public static void reset() {
final GameStates oldState = currentState; final GameStates oldState = currentState;
currentState = GameStates.LOBBY; currentState = GameStates.WAITING;
gameStateChanges(oldState, currentState); gameStateChanges(oldState, currentState);
} }
@@ -25,10 +25,10 @@ import lombok.Getter;
@AllArgsConstructor @AllArgsConstructor
@Getter @Getter
public enum GameStates { public enum GameStates {
ENDING(null), END(null),
INGAME(ENDING), RUNNING(END),
GENERATING_TOWER(INGAME), GENERATING_TOWER(RUNNING),
LOBBY(GENERATING_TOWER); WAITING(GENERATING_TOWER);
private final GameStates nextState; private final GameStates nextState;
} }
@@ -34,7 +34,7 @@ public abstract class WinCondition extends GameStateBukkitListener {
private boolean active = false; private boolean active = false;
protected WinCondition(String name) { protected WinCondition(String name) {
super(EnumSet.of(GameStates.INGAME)); super(EnumSet.of(GameStates.RUNNING));
this.name = name; this.name = name;
} }
+1 -1
View File
@@ -22,7 +22,7 @@ plugins {
} }
dependencies { dependencies {
compileOnly(project(":SpigotCore")) compileOnly(project(":SpigotCore", "default"))
compileOnly(libs.nms15) compileOnly(libs.nms15)
} }
+1 -1
View File
@@ -48,7 +48,7 @@ dependencies {
annotationProcessor(libs.velocityapi) annotationProcessor(libs.velocityapi)
compileOnly(libs.velocity) compileOnly(libs.velocity)
compileOnly(project(":VelocityCore:Persistent")) compileOnly(project(":VelocityCore:Persistent", "default"))
implementation(project(":CommonCore")) implementation(project(":CommonCore"))
implementation(project(":CommandFramework")) implementation(project(":CommandFramework"))
@@ -739,6 +739,7 @@ DC_TICKETINTRO_IDEA=Describe your idea as detailed as possible. Hereto belongs:
DC_TICKETINTRO_BUG=Please describe the observed unexpected or incorrect behaviour of our software. If necessary describe steps to reproduce the error. DC_TICKETINTRO_BUG=Please describe the observed unexpected or incorrect behaviour of our software. If necessary describe steps to reproduce the error.
DC_TICKETINTRO_QUESTION=Please ask your question. A staff member will address the question soon. DC_TICKETINTRO_QUESTION=Please ask your question. A staff member will address the question soon.
DC_TICKETINTRO_APPEAL=Asking creates wonders. DC_TICKETINTRO_APPEAL=Asking creates wonders.
DC_TICKETINTRO_SCHEMATIC=Please answer the following questions as precisely as possible for the locking of the Schematic and, if possible, add evidence:\n - Which player(s)?\n - On which Arena Server\n - At what time?\n - Rules which the Schematic violates (rules/code of conduct)
DC_TICKET_CLOSE=Close DC_TICKET_CLOSE=Close
DC_SCHEMUPLOAD_NOPERM=You\'re not allowed to upload schematics. DC_SCHEMUPLOAD_NOPERM=You\'re not allowed to upload schematics.
@@ -692,6 +692,7 @@ DC_TICKETINTRO_IDEA=Beschreibe deine Idee möglichst detailiert. Hierzu gehört:
DC_TICKETINTRO_BUG=Bitte beschreibe das beobachtete unerwartete bzw. inkorrekte Verhalten der Serversoftware. Falls notwendig, beschreibe die Schritte, mit denen der Fehler reproduziert werden kann. DC_TICKETINTRO_BUG=Bitte beschreibe das beobachtete unerwartete bzw. inkorrekte Verhalten der Serversoftware. Falls notwendig, beschreibe die Schritte, mit denen der Fehler reproduziert werden kann.
DC_TICKETINTRO_QUESTION=Bitte stelle deine Frage, ein Serverteammitglied wird sich dieser zeitnah annehmen. DC_TICKETINTRO_QUESTION=Bitte stelle deine Frage, ein Serverteammitglied wird sich dieser zeitnah annehmen.
DC_TICKETINTRO_APPEAL=Fragen wirkt Wunder! DC_TICKETINTRO_APPEAL=Fragen wirkt Wunder!
DC_TICKETINTRO_SCHEMATIC=Bitte beantworte für die sperrung der Schematic möglichst genau folgende Fragen und füge nach Möglichkeit Beweismaterial hinzu:\n - Welche(r) Spieler?\n - Auf welchem Arena Server\n - Zu welchem Zeitpunkt?\n - Regeln, gegen welche die Schematic verstößt (Regelwerk/ Verhaltensrichtlinien)
DC_TICKET_CLOSE=Schließen DC_TICKET_CLOSE=Schließen
DC_SCHEMUPLOAD_NOPERM=Du darfst keine Schematics hochladen. DC_SCHEMUPLOAD_NOPERM=Du darfst keine Schematics hochladen.
@@ -478,6 +478,7 @@ public class TeamCommand extends SWCommand {
} }
@Register("color") @Register("color")
@Register("changecolor")
public void changeColor(@Validator("isLeader") PlayerChatter sender) { public void changeColor(@Validator("isLeader") PlayerChatter sender) {
Team team = Team.get(sender.user().getTeam()); Team team = Team.get(sender.user().getTeam());
@@ -30,20 +30,29 @@ import de.steamwar.velocitycore.discord.listeners.DiscordTeamEvent;
import de.steamwar.velocitycore.discord.listeners.DiscordTicketHandler; import de.steamwar.velocitycore.discord.listeners.DiscordTicketHandler;
import de.steamwar.velocitycore.discord.util.AuthManager; import de.steamwar.velocitycore.discord.util.AuthManager;
import lombok.Getter; import lombok.Getter;
import net.dv8tion.jda.api.*; import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.*; import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent; import net.dv8tion.jda.api.JDABuilder;
import net.dv8tion.jda.api.OnlineStatus;
import net.dv8tion.jda.api.entities.Activity;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.api.entities.emoji.Emoji;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.dv8tion.jda.api.exceptions.ErrorResponseException; import net.dv8tion.jda.api.exceptions.ErrorResponseException;
import net.dv8tion.jda.api.interactions.commands.Command; import net.dv8tion.jda.api.interactions.commands.Command;
import net.dv8tion.jda.api.interactions.commands.OptionType; import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.build.CommandData; import net.dv8tion.jda.api.interactions.commands.build.CommandData;
import net.dv8tion.jda.api.interactions.commands.build.Commands;
import net.dv8tion.jda.api.interactions.commands.build.OptionData; import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import net.dv8tion.jda.api.interactions.components.ActionRow; import net.dv8tion.jda.api.interactions.components.ActionRow;
import net.dv8tion.jda.api.interactions.components.Button; import net.dv8tion.jda.api.interactions.components.buttons.Button;
import net.dv8tion.jda.api.requests.GatewayIntent;
import net.dv8tion.jda.api.requests.restaction.CommandListUpdateAction; import net.dv8tion.jda.api.requests.restaction.CommandListUpdateAction;
import net.dv8tion.jda.api.utils.MemberCachePolicy; import net.dv8tion.jda.api.utils.MemberCachePolicy;
import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder;
import javax.security.auth.login.LoginException;
import java.awt.*; import java.awt.*;
import java.util.List; import java.util.List;
import java.util.*; import java.util.*;
@@ -87,15 +96,12 @@ public class DiscordBot {
public DiscordBot(DiscordConfig config) { public DiscordBot(DiscordConfig config) {
this.config = config; this.config = config;
try {
jda = JDABuilder jda = JDABuilder
.createDefault(config.getToken()) .createDefault(config.getToken())
.setStatus(OnlineStatus.ONLINE) .setStatus(OnlineStatus.ONLINE)
.setMemberCachePolicy(MemberCachePolicy.ONLINE) .setMemberCachePolicy(MemberCachePolicy.ONLINE)
.enableIntents(GatewayIntent.MESSAGE_CONTENT)
.build(); .build();
} catch (LoginException e) {
throw new SecurityException("Could not login", e);
}
instance = this; instance = this;
VelocityCore.schedule(this::asyncInit).schedule(); VelocityCore.schedule(this::asyncInit).schedule();
@@ -109,9 +115,9 @@ public class DiscordBot {
} }
activity(); activity();
new StaticMessageChannel(config.channel("roles"), () -> new MessageBuilder() new StaticMessageChannel(config.channel("roles"), () -> new MessageCreateBuilder()
.setContent("**Rollenvergabe**\nKlicke um eine Rolle zu bekommen:") .setContent("**Rollenvergabe**\nKlicke um eine Rolle zu bekommen:")
.setActionRows(ActionRow.of(config.getRoles().values().stream().map(DiscordConfig.DiscordRole::toButton).toArray(Button[]::new))), event -> InteractionReply.reply(event, reply -> { .setComponents(ActionRow.of(config.getRoles().values().stream().map(DiscordConfig.DiscordRole::toButton).toArray(Button[]::new))), event -> InteractionReply.reply(event, reply -> {
Member member = event.getMember(); Member member = event.getMember();
Guild guild = event.getGuild(); Guild guild = event.getGuild();
Role role = guild.getRoleById(event.getComponentId()); Role role = guild.getRoleById(event.getComponentId());
@@ -124,33 +130,45 @@ public class DiscordBot {
reply.system("DC_ROLE_ADDED", role.getAsMention()); reply.system("DC_ROLE_ADDED", role.getAsMention());
} }
})); }));
new StaticMessageChannel(config.channel("rules"), () -> new MessageBuilder() new StaticMessageChannel(config.channel("rules"), () -> new MessageCreateBuilder()
.setEmbeds(new EmbedBuilder() .setEmbeds(new EmbedBuilder()
.setDescription(String.join("\n", config.getRules())) .setDescription(String.join("\n", config.getRules()))
.setColor(Color.GRAY) .setColor(Color.GRAY)
.setAuthor("SteamWar", "https://steamwar.de") .setAuthor("SteamWar", "https://steamwar.de")
.setTitle("Regeln und Infos") .setTitle("Regeln und Infos")
.build()) .build())
.setActionRows( .setComponents(
ActionRow.of(Button.link("https://steamwar.de", "Website"), Button.link("https://steamwar.de/youtube", "YouTube")), ActionRow.of(Button.link("https://steamwar.de", "Website"), Button.link("https://steamwar.de/youtube", "YouTube")),
ActionRow.of(Button.primary("auth", Emoji.fromUnicode("U+2705")).withLabel("Minecraft verknüpfen")) ActionRow.of(Button.primary("auth", Emoji.fromUnicode("U+2705")).withLabel("Minecraft verknüpfen"))
), event -> { ), event -> {
if(event.getComponentId().equals("auth")) if(event.getComponentId().equals("auth"))
event.reply("Gebe innerhalb der nächsten 10 Minuten ``/verify " + AuthManager.createDiscordAuthToken(event.getUser()) + "`` auf dem Minecraft Server ein").setEphemeral(true).queue(); event.reply("Gebe innerhalb der nächsten 10 Minuten ``/verify " + AuthManager.createDiscordAuthToken(event.getUser()) + "`` auf dem Minecraft Server ein").setEphemeral(true).queue();
}); });
new StaticMessageChannel(config.channel("ticket"), () -> new MessageBuilder() List<ActionRow> actionRows = new ArrayList<>();
List<Button> list = new ArrayList<>();
for (DiscordTicketType type : DiscordTicketType.values()) {
list.add(type.toButton());
if (list.size() > 3) {
actionRows.add(ActionRow.of(list.toArray(Button[]::new)));
list.clear();
}
}
if (!list.isEmpty()) {
actionRows.add(ActionRow.of(list.toArray(Button[]::new)));
}
new StaticMessageChannel(config.channel("ticket"), () -> new MessageCreateBuilder()
.setEmbeds(new EmbedBuilder() .setEmbeds(new EmbedBuilder()
.setDescription("Hier kannst du Tickets öffnen, welche nur von dir und Teammitgliedern eingesehen werden können.") .setDescription("Hier kannst du Tickets öffnen, welche nur von dir und Teammitgliedern eingesehen werden können.")
.setTitle("SteamWar Tickets") .setTitle("SteamWar Tickets")
.setColor(Color.RED) .setColor(Color.RED)
.build()) .build())
.setActionRows(ActionRow.of(Arrays.stream(DiscordTicketType.values()).map(DiscordTicketType::toButton).toArray(Button[]::new))), DiscordTicketHandler::openTicket); .setComponents(actionRows), DiscordTicketHandler::openTicket);
eventChannel = new StaticMessageChannel(config.channel("events"), EventChannel::get); eventChannel = new StaticMessageChannel(config.channel("events"), EventChannel::get);
checklistChannel = new ChecklistChannel(config.channel("checklist")); checklistChannel = new ChecklistChannel(config.channel("checklist"));
announcementChannel = new DiscordChannel(config.channel("announcement")) { announcementChannel = new DiscordChannel(config.channel("announcement")) {
@Override @Override
public void received(GuildMessageReceivedEvent event) { public void received(MessageReceivedEvent event) {
Chatter.broadcast().system("ALERT", event.getMessage().getContentDisplay()); Chatter.broadcast().system("ALERT", event.getMessage().getContentDisplay());
} }
}; };
@@ -198,7 +216,7 @@ public class DiscordBot {
.keySet().stream() .keySet().stream()
.filter(command -> !correctCommands.contains(command)) .filter(command -> !correctCommands.contains(command))
.filter(command -> command.matches("^[\\w-]+$")) .filter(command -> command.matches("^[\\w-]+$"))
.map(command -> new CommandData(command, command).addOptions(commandArgument)) .map(command -> Commands.slash(command, command).addOptions(commandArgument))
.toArray(CommandData[]::new)) .toArray(CommandData[]::new))
.queue(); .queue();
} }
@@ -23,9 +23,9 @@ import de.steamwar.velocitycore.Config;
import de.steamwar.velocitycore.VelocityCore; import de.steamwar.velocitycore.VelocityCore;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import net.dv8tion.jda.api.entities.Emoji; import net.dv8tion.jda.api.entities.emoji.Emoji;
import net.dv8tion.jda.api.interactions.components.Button; import net.dv8tion.jda.api.interactions.components.buttons.Button;
import net.dv8tion.jda.api.interactions.components.ButtonStyle; import net.dv8tion.jda.api.interactions.components.buttons.ButtonStyle;
import java.io.File; import java.io.File;
import java.util.List; import java.util.List;
@@ -20,9 +20,9 @@
package de.steamwar.velocitycore.discord; package de.steamwar.velocitycore.discord;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import net.dv8tion.jda.api.entities.Emoji; import net.dv8tion.jda.api.entities.emoji.Emoji;
import net.dv8tion.jda.api.interactions.components.Button; import net.dv8tion.jda.api.interactions.components.buttons.Button;
import net.dv8tion.jda.api.interactions.components.ButtonStyle; import net.dv8tion.jda.api.interactions.components.buttons.ButtonStyle;
@AllArgsConstructor @AllArgsConstructor
public enum DiscordTicketType { public enum DiscordTicketType {
@@ -30,7 +30,9 @@ public enum DiscordTicketType {
IDEA("U+1F4A1", "Feature vorschlagen", ButtonStyle.SUCCESS), IDEA("U+1F4A1", "Feature vorschlagen", ButtonStyle.SUCCESS),
BUG("U+1F41B", "Bug melden", ButtonStyle.SECONDARY), BUG("U+1F41B", "Bug melden", ButtonStyle.SECONDARY),
QUESTION("U+2753", "Fragen", ButtonStyle.PRIMARY), QUESTION("U+2753", "Fragen", ButtonStyle.PRIMARY),
APPEAL("U+1F528", "Entbannungsantrag", ButtonStyle.SECONDARY); APPEAL("U+1F528", "Entbannungsantrag", ButtonStyle.SECONDARY),
SCHEMATIC("U+1F4BE", "Schematic melden", ButtonStyle.DANGER);
private final String emoji; private final String emoji;
private final String label; private final String label;
@@ -26,11 +26,12 @@ import de.steamwar.messages.Message;
import de.steamwar.sql.SteamwarUser; import de.steamwar.sql.SteamwarUser;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import net.dv8tion.jda.api.MessageBuilder;
import net.dv8tion.jda.api.entities.MessageChannel;
import net.dv8tion.jda.api.entities.User; import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.events.interaction.GenericComponentInteractionCreateEvent; import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent; import net.dv8tion.jda.api.events.interaction.component.GenericComponentInteractionCreateEvent;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder;
import net.dv8tion.jda.api.utils.messages.MessageCreateData;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
@@ -57,19 +58,19 @@ public class DiscordChannel extends Chatter.PlayerlessChatter {
} }
public void send(String message) { public void send(String message) {
send(new MessageBuilder() send(new MessageCreateBuilder()
.append(message .setContent(message
.replace("&", "") .replace("&", "")
.replace("@everyone", "`@everyone`") .replace("@everyone", "`@everyone`")
.replace("@here", "`@here`") .replace("@here", "`@here`")
.replaceAll("<[@#]!?\\d+>", "`$0`"))); .replaceAll("<[@#]!?\\d+>", "`$0`")));
} }
public void send(MessageBuilder builder) { public void send(MessageCreateBuilder builder) {
channel.sendMessage(builder.build()).queue(); channel.sendMessage(builder.build()).queue();
} }
public void received(GuildMessageReceivedEvent event) { public void received(MessageReceivedEvent event) {
event.getMessage().delete().queue(); event.getMessage().delete().queue();
} }
@@ -24,7 +24,7 @@ import de.steamwar.messages.Chatter;
import de.steamwar.messages.ChatterGroup; import de.steamwar.messages.ChatterGroup;
import de.steamwar.sql.Punishment; import de.steamwar.sql.Punishment;
import de.steamwar.sql.SteamwarUser; import de.steamwar.sql.SteamwarUser;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent; import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import java.util.function.Supplier; import java.util.function.Supplier;
@@ -40,7 +40,7 @@ public class DiscordChatRoom extends DiscordChannel {
} }
@Override @Override
public void received(GuildMessageReceivedEvent event) { public void received(MessageReceivedEvent event) {
SteamwarUser user = SteamwarUser.get(event.getAuthor().getIdLong()); SteamwarUser user = SteamwarUser.get(event.getAuthor().getIdLong());
if (user == null || event.getMessage().getContentRaw().length() > 250 || user.isPunished(Punishment.PunishmentType.Ban) || user.isPunished(Punishment.PunishmentType.Mute)) { if (user == null || event.getMessage().getContentRaw().length() > 250 || user.isPunished(Punishment.PunishmentType.Ban) || user.isPunished(Punishment.PunishmentType.Mute)) {
event.getMessage().delete().queue(); event.getMessage().delete().queue();
@@ -25,10 +25,10 @@ import de.steamwar.sql.Team;
import de.steamwar.sql.TeamTeilnahme; import de.steamwar.sql.TeamTeilnahme;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.MessageBuilder; import net.dv8tion.jda.api.entities.emoji.Emoji;
import net.dv8tion.jda.api.entities.Emoji;
import net.dv8tion.jda.api.interactions.components.ActionRow; import net.dv8tion.jda.api.interactions.components.ActionRow;
import net.dv8tion.jda.api.interactions.components.selections.SelectionMenu; import net.dv8tion.jda.api.interactions.components.selections.StringSelectMenu;
import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder;
import java.awt.*; import java.awt.*;
import java.sql.Timestamp; import java.sql.Timestamp;
@@ -40,21 +40,21 @@ import java.util.stream.Collectors;
@UtilityClass @UtilityClass
public class EventChannel { public class EventChannel {
public MessageBuilder get() { public MessageCreateBuilder get() {
if (Event.get() == null) if (Event.get() == null)
return updateComing(); return updateComing();
return updateCurrent(); return updateCurrent();
} }
private MessageBuilder updateComing() { private MessageCreateBuilder updateComing() {
EmbedBuilder embedBuilder = new EmbedBuilder() EmbedBuilder embedBuilder = new EmbedBuilder()
.setColor(Color.GRAY) .setColor(Color.GRAY)
.setTitle("Zukünftige Events") .setTitle("Zukünftige Events")
.setAuthor("SteamWar", "https://www.steamwar.de"); .setAuthor("SteamWar", "https://www.steamwar.de");
SelectionMenu.Builder menuBuilder = SelectionMenu.create("eventName") StringSelectMenu.Builder menuBuilder = StringSelectMenu.create("eventName")
.setPlaceholder("Wähle ein Event aus!") .setPlaceholder("Wähle ein Event aus!")
.setMinValues(1) .setMinValues(1)
.setMaxValues(1); .setMaxValues(1);
@@ -77,16 +77,16 @@ public class EventChannel {
} }
}); });
MessageBuilder messageBuilder = new MessageBuilder() MessageCreateBuilder messageBuilder = new MessageCreateBuilder()
.setEmbeds(embedBuilder.build()); .setEmbeds(embedBuilder.build());
if(events.stream().anyMatch(event -> event.getDeadline().after(Timestamp.from(Instant.now())))) { if(events.stream().anyMatch(event -> event.getDeadline().after(Timestamp.from(Instant.now())))) {
messageBuilder.setActionRows(ActionRow.of(menuBuilder.build())); messageBuilder.setComponents(ActionRow.of(menuBuilder.build()));
} }
return messageBuilder; return messageBuilder;
} }
private MessageBuilder updateCurrent() { private MessageCreateBuilder updateCurrent() {
Event event = Event.get(); Event event = Event.get();
EmbedBuilder embedBuilder = new EmbedBuilder() EmbedBuilder embedBuilder = new EmbedBuilder()
.setColor(Color.GRAY) .setColor(Color.GRAY)
@@ -19,7 +19,8 @@
package de.steamwar.velocitycore.discord.channels; package de.steamwar.velocitycore.discord.channels;
import net.dv8tion.jda.api.interactions.Interaction; 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.Component;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
@@ -29,18 +30,18 @@ import java.util.function.Consumer;
public class InteractionReply extends DiscordChannel { public class InteractionReply extends DiscordChannel {
public static void reply(Interaction interaction, Consumer<InteractionReply> consumer) { public static void reply(IReplyCallback interaction, Consumer<InteractionReply> consumer) {
InteractionReply reply = new InteractionReply(interaction); InteractionReply reply = new InteractionReply(interaction);
consumer.accept(reply); consumer.accept(reply);
reply.submit(); reply.submit();
} }
private final Interaction interaction; private final IReplyCallback interaction;
private boolean replied = false; private boolean replied = false;
private final List<String> messages = new ArrayList<>(); private final List<String> messages = new ArrayList<>();
private InteractionReply(Interaction interaction) { private InteractionReply(IReplyCallback interaction) {
super(interaction.getUser()); super(interaction.getUser());
this.interaction = interaction; this.interaction = interaction;
} }
@@ -20,35 +20,36 @@
package de.steamwar.velocitycore.discord.channels; package de.steamwar.velocitycore.discord.channels;
import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.MessageBuilder;
import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.events.interaction.GenericComponentInteractionCreateEvent; import net.dv8tion.jda.api.events.interaction.component.GenericComponentInteractionCreateEvent;
import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder;
import net.dv8tion.jda.api.utils.messages.MessageEditData;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Supplier; import java.util.function.Supplier;
public class StaticMessageChannel extends DiscordChannel { public class StaticMessageChannel extends DiscordChannel {
public static MessageBuilder toMessageBuilder(EmbedBuilder embedBuilder) { public static MessageCreateBuilder toMessageBuilder(EmbedBuilder embedBuilder) {
MessageBuilder messageBuilder = new MessageBuilder(); MessageCreateBuilder messageBuilder = new MessageCreateBuilder();
messageBuilder.setEmbeds(embedBuilder.build()); messageBuilder.setEmbeds(embedBuilder.build());
return messageBuilder; return messageBuilder;
} }
private Message message; private Message message;
private final Supplier<MessageBuilder> supplier; private final Supplier<MessageCreateBuilder> supplier;
private final Consumer<GenericComponentInteractionCreateEvent> interaction; private final Consumer<GenericComponentInteractionCreateEvent> interaction;
public StaticMessageChannel(String channel, Supplier<MessageBuilder> supplier) { public StaticMessageChannel(String channel, Supplier<MessageCreateBuilder> supplier) {
this(channel, supplier, event -> {}); this(channel, supplier, event -> {});
} }
public StaticMessageChannel(String channel, Supplier<MessageBuilder> supplier, Consumer<GenericComponentInteractionCreateEvent> interaction) { public StaticMessageChannel(String channel, Supplier<MessageCreateBuilder> supplier, Consumer<GenericComponentInteractionCreateEvent> interaction) {
super(channel); super(channel);
this.supplier = supplier; this.supplier = supplier;
this.interaction = interaction; this.interaction = interaction;
if(getChannel().hasLatestMessage()) if(getChannel().getLatestMessageIdLong() != 0)
message = getChannel().getIterableHistory().complete().stream().filter(m -> m.getAuthor().isBot()).findFirst().orElse(null); message = getChannel().getIterableHistory().complete().stream().filter(m -> m.getAuthor().isBot()).findFirst().orElse(null);
update(); update();
@@ -58,7 +59,7 @@ public class StaticMessageChannel extends DiscordChannel {
if (message == null) { if (message == null) {
getChannel().sendMessage(supplier.get().build()).queue(m -> message = m); getChannel().sendMessage(supplier.get().build()).queue(m -> message = m);
} else { } else {
message.editMessage(supplier.get().build()).queue(); message.editMessage(MessageEditData.fromCreateData(supplier.get().build())).queue();
} }
} }
@@ -25,11 +25,11 @@ import de.steamwar.velocitycore.discord.DiscordBot;
import de.steamwar.velocitycore.discord.channels.DiscordChannel; import de.steamwar.velocitycore.discord.channels.DiscordChannel;
import de.steamwar.velocitycore.discord.channels.InteractionReply; import de.steamwar.velocitycore.discord.channels.InteractionReply;
import lombok.Getter; import lombok.Getter;
import net.dv8tion.jda.api.entities.ChannelType; import net.dv8tion.jda.api.entities.channel.ChannelType;
import net.dv8tion.jda.api.entities.MessageChannel; import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.events.interaction.GenericComponentInteractionCreateEvent; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; import net.dv8tion.jda.api.events.interaction.component.GenericComponentInteractionCreateEvent;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent; import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter; import net.dv8tion.jda.api.hooks.ListenerAdapter;
import net.dv8tion.jda.api.interactions.InteractionType; import net.dv8tion.jda.api.interactions.InteractionType;
import net.dv8tion.jda.api.interactions.commands.OptionMapping; import net.dv8tion.jda.api.interactions.commands.OptionMapping;
@@ -44,7 +44,7 @@ public class ChannelListener extends ListenerAdapter {
private static final Map<MessageChannel, DiscordChannel> channels = new HashMap<>(); private static final Map<MessageChannel, DiscordChannel> channels = new HashMap<>();
@Override @Override
public void onGuildMessageReceived(@NotNull GuildMessageReceivedEvent event) { public void onMessageReceived(@NotNull MessageReceivedEvent event) {
if(event.getAuthor().isBot()) if(event.getAuthor().isBot())
return; return;
@@ -69,7 +69,7 @@ public class ChannelListener extends ListenerAdapter {
} }
@Override @Override
public void onSlashCommand(@NotNull SlashCommandEvent event) { public void onSlashCommandInteraction(@NotNull SlashCommandInteractionEvent event) {
InteractionReply.reply(event, sender -> { InteractionReply.reply(event, sender -> {
if(sender.user().getDiscordId() == null) if(sender.user().getDiscordId() == null)
return; return;
@@ -26,7 +26,7 @@ import de.steamwar.sql.Punishment;
import de.steamwar.sql.SchematicNode; import de.steamwar.sql.SchematicNode;
import de.steamwar.sql.SteamwarUser; import de.steamwar.sql.SteamwarUser;
import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.events.message.priv.PrivateMessageReceivedEvent; import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter; import net.dv8tion.jda.api.hooks.ListenerAdapter;
import java.io.IOException; import java.io.IOException;
@@ -41,7 +41,9 @@ public class DiscordSchemUpload extends ListenerAdapter {
private static final List<String> SCHEM_FILE_ENDINGS = Arrays.asList(".schem", ".schematic"); private static final List<String> SCHEM_FILE_ENDINGS = Arrays.asList(".schem", ".schematic");
@Override @Override
public void onPrivateMessageReceived(PrivateMessageReceivedEvent event) { public void onMessageReceived(MessageReceivedEvent event) {
if (event.isFromGuild()) return;
Message message = event.getMessage(); Message message = event.getMessage();
if(message.getAttachments().isEmpty()) if(message.getAttachments().isEmpty())
return; return;
@@ -76,7 +78,7 @@ public class DiscordSchemUpload extends ListenerAdapter {
if(node == null) if(node == null)
node = SchematicNode.createSchematic(user.getId(), name, null); node = SchematicNode.createSchematic(user.getId(), name, null);
try (InputStream in = attachment.retrieveInputStream().get()) { try (InputStream in = attachment.getProxy().download().get()) {
NodeData.get(node).saveFromStream(in, fileName.substring(dot).equalsIgnoreCase(".schem")); NodeData.get(node).saveFromStream(in, fileName.substring(dot).equalsIgnoreCase(".schem"));
sender.system("DC_SCHEMUPLOAD_SUCCESS", name); sender.system("DC_SCHEMUPLOAD_SUCCESS", name);
} catch (InterruptedException e) { } catch (InterruptedException e) {
@@ -23,7 +23,7 @@ import de.steamwar.velocitycore.VelocityCore;
import de.steamwar.velocitycore.discord.DiscordBot; import de.steamwar.velocitycore.discord.DiscordBot;
import de.steamwar.velocitycore.discord.channels.InteractionReply; import de.steamwar.velocitycore.discord.channels.InteractionReply;
import de.steamwar.sql.Event; import de.steamwar.sql.Event;
import net.dv8tion.jda.api.events.interaction.SelectionMenuEvent; import net.dv8tion.jda.api.events.interaction.component.StringSelectInteractionEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter; import net.dv8tion.jda.api.hooks.ListenerAdapter;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -32,7 +32,7 @@ public class DiscordTeamEvent extends ListenerAdapter {
private final String eventsChannel = DiscordBot.getInstance().getConfig().channel("events"); private final String eventsChannel = DiscordBot.getInstance().getConfig().channel("events");
@Override @Override
public void onSelectionMenu(@NotNull SelectionMenuEvent event) { public void onStringSelectInteraction(@NotNull StringSelectInteractionEvent event) {
if(!event.getChannel().getId().equals(eventsChannel)) if(!event.getChannel().getId().equals(eventsChannel))
return; return;
@@ -29,22 +29,24 @@ import de.steamwar.velocitycore.discord.DiscordTicketType;
import de.steamwar.velocitycore.discord.channels.DiscordChannel; import de.steamwar.velocitycore.discord.channels.DiscordChannel;
import de.steamwar.velocitycore.discord.channels.InteractionReply; import de.steamwar.velocitycore.discord.channels.InteractionReply;
import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.MessageBuilder;
import net.dv8tion.jda.api.Permission; import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.entities.Emoji;
import net.dv8tion.jda.api.entities.MessageChannel;
import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.entities.User; import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.events.interaction.GenericComponentInteractionCreateEvent; import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent; import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.entities.emoji.Emoji;
import net.dv8tion.jda.api.events.interaction.component.GenericComponentInteractionCreateEvent;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter; import net.dv8tion.jda.api.hooks.ListenerAdapter;
import net.dv8tion.jda.api.interactions.components.ActionRow; import net.dv8tion.jda.api.interactions.components.ActionRow;
import net.dv8tion.jda.api.interactions.components.Button; import net.dv8tion.jda.api.interactions.components.buttons.Button;
import net.dv8tion.jda.api.utils.SplitUtil;
import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder;
import net.kyori.adventure.text.event.ClickEvent; import net.kyori.adventure.text.event.ClickEvent;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.awt.*; import java.awt.*;
import java.time.Instant; import java.time.Instant;
import java.util.Collections;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -59,24 +61,23 @@ public class DiscordTicketHandler extends ListenerAdapter {
SteamwarUser user = SteamwarUser.get(event.getUser().getIdLong()); SteamwarUser user = SteamwarUser.get(event.getUser().getIdLong());
TextChannel ticketChannel = event.getGuild().getCategoryById(TICKET_CATEGORY).createTextChannel((user == null ? event.getUser().getName() : user.getUserName()) + "-" + event.getComponentId() + "-" + System.currentTimeMillis() % 1000).complete(); TextChannel ticketChannel = event.getGuild().getCategoryById(TICKET_CATEGORY).createTextChannel((user == null ? event.getUser().getName() : user.getUserName()) + "-" + event.getComponentId() + "-" + System.currentTimeMillis() % 1000).complete();
ticketChannel.createPermissionOverride(event.getMember()).setAllow( ticketChannel.getPermissionContainer().upsertPermissionOverride(event.getMember()).setAllowed(
Permission.VIEW_CHANNEL, Permission.VIEW_CHANNEL,
Permission.MESSAGE_WRITE, Permission.MESSAGE_SEND,
Permission.MESSAGE_ATTACH_FILES, Permission.MESSAGE_ATTACH_FILES,
Permission.MESSAGE_ADD_REACTION, Permission.MESSAGE_ADD_REACTION,
Permission.MESSAGE_READ,
Permission.MESSAGE_EMBED_LINKS, Permission.MESSAGE_EMBED_LINKS,
Permission.MESSAGE_HISTORY).complete(); Permission.MESSAGE_HISTORY).complete();
ticketChannel.getManager().setTopic(event.getUser().getId()).complete(); ticketChannel.getManager().setTopic(event.getUser().getId()).complete();
DiscordChannel channel = new DiscordChannel(DiscordChannel.userOrPublic(event.getUser()), ticketChannel); DiscordChannel channel = new DiscordChannel(DiscordChannel.userOrPublic(event.getUser()), ticketChannel);
channel.send(new MessageBuilder() channel.send(new MessageCreateBuilder()
.setEmbeds(new EmbedBuilder() .setEmbeds(new EmbedBuilder()
.setTitle(channel.parseToPlain("DC_TICKET_TITLE")) .setTitle(channel.parseToPlain("DC_TICKET_TITLE"))
.setDescription(channel.parseToPlain(ticketType.introduction())) .setDescription(channel.parseToPlain(ticketType.introduction()))
.setColor(Color.GREEN) .setColor(Color.GREEN)
.build()) .build())
.setActionRows(ActionRow.of(Button.danger("close-" + ticketChannel.getName(), channel.parseToPlain("DC_TICKET_CLOSE")).withEmoji(Emoji.fromUnicode("U+26A0"))))); .setComponents(ActionRow.of(Button.danger("close-" + ticketChannel.getName(), channel.parseToPlain("DC_TICKET_CLOSE")).withEmoji(Emoji.fromUnicode("U+26A0")))));
InteractionReply.reply(event, reply -> reply.system("DC_TICKET_CREATED", ticketChannel.getAsMention())); InteractionReply.reply(event, reply -> reply.system("DC_TICKET_CREATED", ticketChannel.getAsMention()));
Chatter.serverteam().prefixless("DISCORD_TICKET_NEW", ticketChannel.getName()); Chatter.serverteam().prefixless("DISCORD_TICKET_NEW", ticketChannel.getName());
@@ -85,8 +86,8 @@ public class DiscordTicketHandler extends ListenerAdapter {
@Override @Override
public void onGenericComponentInteractionCreate(@NotNull GenericComponentInteractionCreateEvent event) { public void onGenericComponentInteractionCreate(@NotNull GenericComponentInteractionCreateEvent event) {
MessageChannel messageChannel = event.getChannel(); MessageChannel messageChannel = event.getChannel();
if(messageChannel instanceof TextChannel channel && channel.getParent() != null && channel.getParent().getId().equals(TICKET_CATEGORY) && event.getComponentId().startsWith("close-")) { if(messageChannel instanceof TextChannel channel && channel.getParentCategoryIdLong() != 0 && channel.getParentCategoryId().equals(TICKET_CATEGORY) && event.getComponentId().startsWith("close-")) {
LinkedList<StringBuilder> messages = channel.getIterableHistory().complete().stream() LinkedList<StringBuilder> messages = channel.getIterableHistory().reverse().complete().stream()
.filter(message -> !message.getAuthor().isSystem() && !message.getAuthor().isBot()) .filter(message -> !message.getAuthor().isSystem() && !message.getAuthor().isBot())
.map(message -> { .map(message -> {
StringBuilder stringBuilder = new StringBuilder() StringBuilder stringBuilder = new StringBuilder()
@@ -104,26 +105,12 @@ public class DiscordTicketHandler extends ListenerAdapter {
}) })
.collect(Collectors.toCollection(LinkedList::new)); .collect(Collectors.toCollection(LinkedList::new));
messages.addFirst(new StringBuilder().append("<t:").append(Instant.now().getEpochSecond()).append("> **").append(event.getUser().getName()).append("**: Ticket closed")); messages.add(new StringBuilder().append("<t:").append(Instant.now().getEpochSecond()).append("> **").append(event.getUser().getName()).append("**: Ticket closed"));
LinkedList<StringBuilder> messageBuilders = new LinkedList<>();
messageBuilders.add(new StringBuilder());
messages.descendingIterator()
.forEachRemaining(stringBuilder -> {
if(stringBuilder.length() >= 4096) {
messageBuilders.getLast().append(stringBuilder.substring(0, 4090));
messageBuilders.add(new StringBuilder(stringBuilder.substring(4090, stringBuilder.length() - 1)));
} else if (stringBuilder.length() + messageBuilders.getLast().length() >= 4096) {
messageBuilders.add(new StringBuilder(stringBuilder.toString()));
} else {
messageBuilders.getLast().append(stringBuilder);
}
});
EmbedBuilder embedBuilder = new EmbedBuilder() EmbedBuilder embedBuilder = new EmbedBuilder()
.setColor(Color.GREEN) .setColor(Color.GREEN)
.setTimestamp(Instant.now()) .setTimestamp(Instant.now())
.setTitle(event.getTextChannel().getName()); .setTitle(event.getChannel().getName());
if(channel.getTopic() != null && !channel.getTopic().isEmpty()) { if(channel.getTopic() != null && !channel.getTopic().isEmpty()) {
User user = event.getJDA().retrieveUserById(channel.getTopic()).complete(); User user = event.getJDA().retrieveUserById(channel.getTopic()).complete();
@@ -131,7 +118,13 @@ public class DiscordTicketHandler extends ListenerAdapter {
} }
TextChannel logChannel = event.getGuild().getTextChannelById(TICKET_LOG); TextChannel logChannel = event.getGuild().getTextChannelById(TICKET_LOG);
messageBuilders.forEach(stringBuilder -> logChannel.sendMessage(new MessageBuilder().setEmbeds(embedBuilder.setDescription(stringBuilder.toString()).build()).build()).queue()); SplitUtil.split(
messages.stream()
.map(StringBuilder::toString).collect(Collectors.joining()),
2000,
SplitUtil.Strategy.NEWLINE,
SplitUtil.Strategy.ANYWHERE
).stream().map(message -> new MessageCreateBuilder().setEmbeds(embedBuilder.setDescription(message).build())).forEach(builder -> logChannel.sendMessage(builder.build()).queue());
Chatter.serverteam().prefixless("DISCORD_TICKET_CLOSED", channel.getName()); Chatter.serverteam().prefixless("DISCORD_TICKET_CLOSED", channel.getName());
channel.delete().reason("Closed").queue(); channel.delete().reason("Closed").queue();
@@ -139,11 +132,12 @@ public class DiscordTicketHandler extends ListenerAdapter {
} }
@Override @Override
public void onGuildMessageReceived(@NotNull GuildMessageReceivedEvent event) { public void onMessageReceived(@NotNull MessageReceivedEvent event) {
TextChannel channel = event.getChannel(); MessageChannel channel = event.getChannel();
if( if(
channel.getParent() != null && channel instanceof TextChannel textChannel &&
channel.getParent().getId().equals(TICKET_CATEGORY) && textChannel.getParentCategoryIdLong() != 0 &&
textChannel.getParentCategoryId().equals(TICKET_CATEGORY) &&
!channel.getId().equals(TICKET_CHANNEL) && !channel.getId().equals(TICKET_CHANNEL) &&
!channel.getId().equals(TICKET_LOG) !channel.getId().equals(TICKET_LOG)
) { ) {
@@ -152,7 +146,7 @@ public class DiscordTicketHandler extends ListenerAdapter {
ChatterGroup receivers = new ChatterGroup(Chatter.allStream().filter(player -> player.user().hasPerm(UserPerm.TICKET_LOG))); ChatterGroup receivers = new ChatterGroup(Chatter.allStream().filter(player -> player.user().hasPerm(UserPerm.TICKET_LOG)));
try { try {
SteamwarUser user = SteamwarUser.get(Long.parseLong(channel.getTopic())); SteamwarUser user = SteamwarUser.get(Long.parseLong(textChannel.getTopic()));
if(user != null && !user.perms().contains(UserPerm.TEAM)) if(user != null && !user.perms().contains(UserPerm.TEAM))
receivers = new ChatterGroup(receivers, Chatter.of(user)); receivers = new ChatterGroup(receivers, Chatter.of(user));
} catch(NumberFormatException e) { } catch(NumberFormatException e) {
@@ -23,11 +23,11 @@ import de.steamwar.velocitycore.VelocityCore;
import de.steamwar.velocitycore.discord.channels.DiscordChannel; import de.steamwar.velocitycore.discord.channels.DiscordChannel;
import de.steamwar.sql.SteamwarUser; import de.steamwar.sql.SteamwarUser;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import net.dv8tion.jda.api.MessageBuilder;
import net.dv8tion.jda.api.entities.Emoji;
import net.dv8tion.jda.api.entities.User; import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.entities.emoji.Emoji;
import net.dv8tion.jda.api.interactions.components.ActionRow; import net.dv8tion.jda.api.interactions.components.ActionRow;
import net.dv8tion.jda.api.interactions.components.Button; import net.dv8tion.jda.api.interactions.components.buttons.Button;
import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder;
import java.util.Base64; import java.util.Base64;
import java.util.HashMap; import java.util.HashMap;
@@ -63,9 +63,9 @@ public class AuthManager {
user.setDiscordId(dcUser.getIdLong()); user.setDiscordId(dcUser.getIdLong());
DiscordChannel channel = new DiscordChannel(dcUser); DiscordChannel channel = new DiscordChannel(dcUser);
channel.send(new MessageBuilder() channel.send(new MessageCreateBuilder()
.setContent(channel.parseToPlain("DC_AUTH_SUCCESS", user)) .setContent(channel.parseToPlain("DC_AUTH_SUCCESS", user))
.setActionRows(ActionRow.of(Button.success("tada", Emoji.fromUnicode("U+1F389"))))); .setComponents(ActionRow.of(Button.success("tada", Emoji.fromUnicode("U+1F389")))));
return dcUser; return dcUser;
} }
@@ -25,11 +25,11 @@ import de.steamwar.velocitycore.discord.DiscordBot;
import de.steamwar.velocitycore.discord.channels.DiscordChannel; import de.steamwar.velocitycore.discord.channels.DiscordChannel;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.MessageBuilder;
import net.dv8tion.jda.api.entities.Emoji;
import net.dv8tion.jda.api.entities.User; import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.entities.emoji.Emoji;
import net.dv8tion.jda.api.interactions.components.ActionRow; import net.dv8tion.jda.api.interactions.components.ActionRow;
import net.dv8tion.jda.api.interactions.components.Button; import net.dv8tion.jda.api.interactions.components.buttons.Button;
import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder;
import java.awt.*; import java.awt.*;
import java.time.Instant; import java.time.Instant;
@@ -47,7 +47,7 @@ public class DiscordAlert {
if(user == null) if(user == null)
return; return;
MessageBuilder builder = new MessageBuilder() MessageCreateBuilder builder = new MessageCreateBuilder()
.setEmbeds(new EmbedBuilder() .setEmbeds(new EmbedBuilder()
.setAuthor("SteamWar", "https://steamwar.de", "https://cdn.discordapp.com/app-icons/869606970099904562/60c884000407c02671d91d8e7182b8a1.png") .setAuthor("SteamWar", "https://steamwar.de", "https://cdn.discordapp.com/app-icons/869606970099904562/60c884000407c02671d91d8e7182b8a1.png")
.setColor(color) .setColor(color)
@@ -56,7 +56,7 @@ public class DiscordAlert {
.setTimestamp(Instant.now()) .setTimestamp(Instant.now())
.build()); .build());
if(success) if(success)
builder.setActionRows(ActionRow.of(Button.success("tada", Emoji.fromUnicode("U+1F389")))); builder.setComponents(ActionRow.of(Button.success("tada", Emoji.fromUnicode("U+1F389"))));
new DiscordChannel(user).send(builder); new DiscordChannel(user).send(builder);
}); });
@@ -20,6 +20,7 @@
package de.steamwar.velocitycore.mods; package de.steamwar.velocitycore.mods;
import com.velocitypowered.api.proxy.Player; import com.velocitypowered.api.proxy.Player;
import de.steamwar.sql.Punishment;
import de.steamwar.velocitycore.VelocityCore; import de.steamwar.velocitycore.VelocityCore;
import de.steamwar.velocitycore.commands.PunishmentCommand; import de.steamwar.velocitycore.commands.PunishmentCommand;
import de.steamwar.messages.Chatter; import de.steamwar.messages.Chatter;
@@ -76,12 +77,13 @@ public class ModUtils {
String message; String message;
if(mods.size() == 1) { if(mods.size() == 1) {
message = sender.parseToLegacy(max == ModType.RED ? "MOD_RED_SING" : "MOD_YELLOW_SING", locale, modList); message = sender.parseToLegacy(max == ModType.RED ? "MOD_RED_SING" : "MOD_YELLOW_SING", modList);
} else { } else {
message = sender.parseToLegacy(max == ModType.RED ? "MOD_RED_PLUR" : "MOD_YELLOW_PLUR", locale, modList); message = sender.parseToLegacy(max == ModType.RED ? "MOD_RED_PLUR" : "MOD_YELLOW_PLUR", modList);
} }
if(max == ModType.RED) { if(max == ModType.RED) {
user.punish(Punishment.PunishmentType.Ban, Timestamp.from(Instant.now().plus(7, ChronoUnit.DAYS)), message, -1, false);
PunishmentCommand.ban(user, Timestamp.from(Instant.now().plus(7, ChronoUnit.DAYS)), message, SteamwarUser.get(-1), false); PunishmentCommand.ban(user, Timestamp.from(Instant.now().plus(7, ChronoUnit.DAYS)), message, SteamwarUser.get(-1), false);
VelocityCore.getLogger().log(Level.SEVERE, "%s %s wurde automatisch wegen der Mods %s gebannt.".formatted(user.getUserName(), user.getId(), modList)); VelocityCore.getLogger().log(Level.SEVERE, "%s %s wurde automatisch wegen der Mods %s gebannt.".formatted(user.getUserName(), user.getId(), modList));
} }
+1 -1
View File
@@ -107,7 +107,7 @@ dependencyResolutionManagement {
library("netty", "io.netty:netty-all:4.1.68.Final") library("netty", "io.netty:netty-all:4.1.68.Final")
library("junit", "junit:junit:4.13.2") library("junit", "junit:junit:4.13.2")
library("hamcrest", "org.hamcrest:hamcrest:2.2") library("hamcrest", "org.hamcrest:hamcrest:2.2")
library("jda", "net.dv8tion:JDA:4.4.0_352") library("jda", "net.dv8tion:JDA:5.2.0")
library("msgpack", "org.msgpack:msgpack-core:0.9.8") library("msgpack", "org.msgpack:msgpack-core:0.9.8")
library("classindex", "org.atteo.classindex:classindex:3.13") library("classindex", "org.atteo.classindex:classindex:3.13")