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 {
compileOnly(project(":BauSystem:BauSystem_Main"))
compileOnly(project(":SpigotCore"))
compileOnly(project(":BauSystem:BauSystem_Main", "default"))
compileOnly(project(":SpigotCore", "default"))
compileOnly(libs.nms15)
compileOnly(libs.worldedit15)
+2 -2
View File
@@ -27,8 +27,8 @@ java {
}
dependencies {
compileOnly(project(":BauSystem:BauSystem_Main"))
compileOnly(project(":SpigotCore"))
compileOnly(project(":BauSystem:BauSystem_Main", "default"))
compileOnly(project(":SpigotCore", "default"))
compileOnly(libs.spigotapi)
compileOnly(libs.nms18)
+2 -2
View File
@@ -27,8 +27,8 @@ java {
}
dependencies {
compileOnly(project(":BauSystem:BauSystem_Main"))
compileOnly(project(":SpigotCore"))
compileOnly(project(":BauSystem:BauSystem_Main", "default"))
compileOnly(project(":SpigotCore", "default"))
compileOnly(libs.spigotapi)
compileOnly(libs.paperapi)
+2 -2
View File
@@ -27,8 +27,8 @@ java {
}
dependencies {
compileOnly(project(":BauSystem:BauSystem_Main"))
compileOnly(project(":SpigotCore"))
compileOnly(project(":BauSystem:BauSystem_Main", "default"))
compileOnly(project(":SpigotCore", "default"))
compileOnly(libs.spigotapi)
+1 -1
View File
@@ -33,7 +33,7 @@ java {
dependencies {
compileOnly(libs.classindex)
annotationProcessor(libs.classindex)
compileOnly(project(":SpigotCore"))
compileOnly(project(":SpigotCore", "default"))
compileOnly(libs.spigotapi)
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_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_RENAME_HELP=§8/§esimulator rename §8[§7to-rename§8] §8[§7name§8] §8-§7 Rename the simulator
SIMULATOR_GUI_ITEM_NAME=§eTNT Simulator
SIMULATOR_NO_SIM_IN_HAND=§cNo simulator item selected
SIMULATOR_GUI_SELECT_SIM=Simulator selection
@@ -307,6 +308,7 @@ SIMULATOR_POSITION_Z=§7z-Position
SIMULATOR_BACK=§eBack
SIMULATOR_GUI_TOTAL_TNT=§7Total TNT§8: §e{0}
SIMULATOR_DELETED=§cSimulator deleted
SIMULATOR_RENAMED=§cSimulator renamed from {0} to {1}
## GUI
SIMULATOR_POSITION_EDIT=§eEdit 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_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_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_NO_SIM_IN_HAND=§cKein Simulator Item gewählt
SIMULATOR_GUI_SELECT_SIM=Simulator wählen
@@ -290,6 +291,7 @@ SIMULATOR_POSITION_Z=§7z-Position
SIMULATOR_BACK=§eZurück
SIMULATOR_GUI_TOTAL_TNT=§7Gesamt TNT§8: §e{0}
SIMULATOR_DELETED=§cSimulator gelöscht
SIMULATOR_RENAMED=§cSimulator von {0} zu {1} umbenannt
## GUI
SIMULATOR_POSITION_EDIT=§ePosition bearbeiten
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.script.lua.SteamWarLuaPlugin;
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.PanzernAlgorithm;
import de.steamwar.bausystem.features.tpslimit.TPSFreezeUtils;
@@ -184,6 +185,9 @@ public class BauSystem extends JavaPlugin {
if (any instanceof ConfigConverter) {
Config.addConfigConverter((ConfigConverter) any);
}
if (any instanceof BoundingBoxLoader) {
((BoundingBoxLoader) any).load();
}
});
instances.forEach((clazz, o) -> {
@@ -93,6 +93,7 @@ public class Loader implements Listener {
element.execute(delay -> waitTime = delay);
if (waitTime > 0) {
if (element instanceof LoaderTNT) currentElement--;
waitTime--;
return;
}
}
@@ -20,7 +20,6 @@
package de.steamwar.bausystem.features.simulator;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.Permission;
import de.steamwar.bausystem.SWUtils;
import de.steamwar.bausystem.features.simulator.data.Simulator;
import de.steamwar.bausystem.features.simulator.execute.SimulatorExecutor;
@@ -63,15 +62,7 @@ public class SimulatorCommand extends SWCommand {
}
@Register(value = "copy", description = "SIMULATOR_COPY_HELP")
public void copy(@Validator Player p, @ErrorMessage("SIMULATOR_NOT_EXISTS") Simulator simulator, 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;
}
public void copy(@Validator Player p, @ErrorMessage("SIMULATOR_NOT_EXISTS") Simulator simulator, @Validator("simulatorName") String name) {
if (!SimulatorStorage.copy(simulator, name)) {
BauSystem.MESSAGE.send("SIMULATOR_ERROR_COPY", p);
}
@@ -88,6 +79,17 @@ public class SimulatorCommand extends SWCommand {
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)
public TypeMapper<Simulator> allSimulators() {
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.IOException;
import java.util.*;
import java.util.stream.Collectors;
@Linked
@MinVersion(19)
@@ -130,7 +131,7 @@ public class SimulatorStorage implements Enable {
}
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
public String baseTitle() {
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.Cuboid;
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.region.Point;
import de.steamwar.bausystem.utils.FlatteningWrapper;
@@ -34,7 +35,6 @@ import org.bukkit.util.Vector;
import java.util.*;
import java.util.function.BiPredicate;
import java.util.stream.Collectors;
public class ProcessingTracesState implements LaufbauState {
@@ -45,8 +45,9 @@ public class ProcessingTracesState implements LaufbauState {
private final List<BlockBoundingBox> elements;
private final int factor;
private final List<TNTPoint> TNTPoints;
private final int totalTntRecords;
private final List<Trace> Traces;
private final List<TNTPoint> TNTPoints = new ArrayList<>();
private final int totalTraces;
private final Set<Point> affectedBlocks = new HashSet<>();
private final Map<Point, Set<Cuboid>> cuboidsPerChunk = new HashMap<>();
@@ -58,18 +59,13 @@ public class ProcessingTracesState implements LaufbauState {
this.elements = elements;
this.factor = factor;
// TODO: Optimize only retrieving traces inside of the affected regions!
TNTPoints = TraceManager.instance.getAll()
.stream()
.flatMap(trace -> trace.getHistories().stream())
.flatMap(Collection::stream)
.collect(Collectors.toList());
totalTntRecords = TNTPoints.size();
Traces = new ArrayList<>(TraceManager.instance.getAll());
totalTraces = Traces.size();
}
@Override
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) {
@@ -78,11 +74,17 @@ public class ProcessingTracesState implements LaufbauState {
@Override
public boolean hasNext() {
return !TNTPoints.isEmpty();
return !Traces.isEmpty() || !TNTPoints.isEmpty();
}
@Override
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);
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))))
@@ -39,12 +39,12 @@ public class SpeedCommand extends SWCommand {
@Register
public void speedCommand(Player p, float speed) {
speed = speed / 10F;
if (speed < -1F) {
if (speed < -10F) {
BauSystem.MESSAGE.send("SPEED_TOO_SMALL", p, speed);
} else if (speed > 1F) {
} else if (speed > 10F) {
BauSystem.MESSAGE.send("SPEED_TOO_HIGH", p, speed);
} else {
speed = speed / 10F;
p.setFlySpeed(speed);
p.setWalkSpeed(Math.min(speed + 0.1F, 1F));
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.math.BlockVector3;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import de.steamwar.bausystem.region.Color;
import de.steamwar.bausystem.region.Point;
@@ -34,9 +35,7 @@ import lombok.NonNull;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.BiPredicate;
@@ -106,51 +105,28 @@ public class PasteBuilder {
public PasteBuilder color(Color color) {
if (color == Color.PINK) return this;
BaseBlock WOOL = Objects.requireNonNull(BlockTypes.PINK_WOOL).getDefaultState().toBaseBlock();
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();
Map<String, BaseBlock> blockCache = new HashMap<>();
return map((clipboard, blockVector3) -> {
BaseBlock block = clipboard.getFullBlock(blockVector3);
if (block.equals(WOOL)) {
clipboard.setBlock(blockVector3, wool);
} else if (block.equals(CLAY)) {
clipboard.setBlock(blockVector3, clay);
} else if (block.equals(GLAZED)) {
clipboard.setBlock(blockVector3, glazed);
} else if (block.equals(GLASS)) {
clipboard.setBlock(blockVector3, glass);
} else if (block.equals(GLASS_PANE)) {
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);
if (block.getBlockType().getId().startsWith("minecraft:pink_")) {
BaseBlock baseBlock = blockCache.computeIfAbsent(block.getBlockType().getId(), s -> {
String replaced = s.replace("minecraft:pink_", "minecraft:" + color.name().toLowerCase() + "_");
BlockType blockType = BlockTypes.get(replaced);
if (blockType == null) return null;
return blockType.getDefaultState().toBaseBlock();
});
if (baseBlock == null) return;
clipboard.setBlock(blockVector3, baseBlock);
}
});
}
/**
* Can only be used before {@link #color(Color)}.
*/
public PasteBuilder onlyColors(boolean onlyColors) {
if (!onlyColors) return this;
return only((baseBlock, s) -> {
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");
});
return only((baseBlock, s) -> s.startsWith("minecraft:pink_"));
}
public PasteBuilder removeTNT(boolean removeTNT) {
@@ -121,11 +121,11 @@ public class Punishment {
public enum PunishmentType {
Ban(false, "BAN_TEAM", "BAN_PERMA", "BAN_UNTIL", "UNBAN_ERROR", "UNBAN"),
Mute( false, "MUTE_TEAM", "MUTE_PERMA", "MUTE_UNTIL", "UNMUTE_ERROR", "UNMUTE"),
NoSchemReceiving(false, "NOSCHEMRECEIVING_TEAM", "NOSCHEMRECEIVING_PERMA", "NOSCHEMRECEIVING_UNTIL", "UNNOSCHEMRECEIVING_ERROR", "UNNOSCHEMRECEIVING"),
NoSchemSharing(false, "NOSCHEMSHARING_TEAM", "NOSCHEMSHARING_PERMA", "NOSCHEMSHARING_UNTIL", "UNNOSCHEMSHARING_ERROR", "UNNOSCHEMSHARING"),
NoSchemSubmitting(true, "NOSCHEMSUBMITTING_TEAM", "NOSCHEMSUBMITTING_PERMA", "NOSCHEMSUBMITTING_UNTIL", "UNNOSCHEMSUBMITTING_ERROR", "UNNOSCHEMSUBMITTING"),
NoSchemReceiving(true, "NOSCHEMRECEIVING_TEAM", "NOSCHEMRECEIVING_PERMA", "NOSCHEMRECEIVING_UNTIL", "UNNOSCHEMRECEIVING_ERROR", "UNNOSCHEMRECEIVING"),
NoSchemSharing(true, "NOSCHEMSHARING_TEAM", "NOSCHEMSHARING_PERMA", "NOSCHEMSHARING_UNTIL", "UNNOSCHEMSHARING_ERROR", "UNNOSCHEMSHARING"),
NoSchemSubmitting(false, "NOSCHEMSUBMITTING_TEAM", "NOSCHEMSUBMITTING_PERMA", "NOSCHEMSUBMITTING_UNTIL", "UNNOSCHEMSUBMITTING_ERROR", "UNNOSCHEMSUBMITTING"),
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"),
Note(false, "NOTE_TEAM", null, null, null, null, true);
+2 -2
View File
@@ -22,8 +22,8 @@ plugins {
}
dependencies {
compileOnly(project(":SpigotCore"))
compileOnly(project(":FightSystem:FightSystem_Core"))
compileOnly(project(":SpigotCore", "default"))
compileOnly(project(":FightSystem:FightSystem_Core", "default"))
compileOnly(libs.nms10)
}
+3 -3
View File
@@ -22,9 +22,9 @@ plugins {
}
dependencies {
compileOnly(project(":SpigotCore"))
compileOnly(project(":FightSystem:FightSystem_Core"))
compileOnly(project(":FightSystem:FightSystem_8"))
compileOnly(project(":SpigotCore", "default"))
compileOnly(project(":FightSystem:FightSystem_Core", "default"))
compileOnly(project(":FightSystem:FightSystem_8", "default"))
compileOnly(libs.nms12)
compileOnly(libs.worldedit12)
+4 -4
View File
@@ -22,10 +22,10 @@ plugins {
}
dependencies {
compileOnly(project(":SpigotCore"))
compileOnly(project(":FightSystem:FightSystem_Core"))
compileOnly(project(":FightSystem:FightSystem_8"))
compileOnly(project(":FightSystem:FightSystem_9"))
compileOnly(project(":SpigotCore", "default"))
compileOnly(project(":FightSystem:FightSystem_Core", "default"))
compileOnly(project(":FightSystem:FightSystem_8", "default"))
compileOnly(project(":FightSystem:FightSystem_9", "default"))
compileOnly(libs.nms14)
compileOnly(libs.worldedit15)
+2 -2
View File
@@ -22,8 +22,8 @@ plugins {
}
dependencies {
compileOnly(project(":SpigotCore"))
compileOnly(project(":FightSystem:FightSystem_Core"))
compileOnly(project(":SpigotCore", "default"))
compileOnly(project(":FightSystem:FightSystem_Core", "default"))
compileOnly(libs.nms15)
compileOnly(libs.worldedit15)
+2 -2
View File
@@ -22,8 +22,8 @@ plugins {
}
dependencies {
compileOnly(project(":SpigotCore"))
compileOnly(project(":FightSystem:FightSystem_Core"))
compileOnly(project(":SpigotCore", "default"))
compileOnly(project(":FightSystem:FightSystem_Core", "default"))
compileOnly(libs.spigotapi)
+2 -2
View File
@@ -22,8 +22,8 @@ plugins {
}
dependencies {
compileOnly(project(":FightSystem:FightSystem_Core"))
compileOnly(project(":FightSystem:FightSystem_18"))
compileOnly(project(":FightSystem:FightSystem_Core", "default"))
compileOnly(project(":FightSystem:FightSystem_18", "default"))
compileOnly(libs.spigotapi)
+2 -2
View File
@@ -22,8 +22,8 @@ plugins {
}
dependencies {
compileOnly(project(":FightSystem:FightSystem_Core"))
compileOnly(project(":FightSystem:FightSystem_18"))
compileOnly(project(":FightSystem:FightSystem_Core", "default"))
compileOnly(project(":FightSystem:FightSystem_18", "default"))
compileOnly(libs.spigotapi)
+2 -2
View File
@@ -22,8 +22,8 @@ plugins {
}
dependencies {
compileOnly(project(":SpigotCore"))
compileOnly(project(":FightSystem:FightSystem_Core"))
compileOnly(project(":SpigotCore", "default"))
compileOnly(project(":FightSystem:FightSystem_Core", "default"))
compileOnly(libs.nms8)
compileOnly(libs.worldedit12)
+3 -3
View File
@@ -22,9 +22,9 @@ plugins {
}
dependencies {
compileOnly(project(":SpigotCore"))
compileOnly(project(":FightSystem:FightSystem_Core"))
compileOnly(project(":FightSystem:FightSystem_8"))
compileOnly(project(":SpigotCore", "default"))
compileOnly(project(":FightSystem:FightSystem_Core", "default"))
compileOnly(project(":FightSystem:FightSystem_8", "default"))
compileOnly(libs.nms9)
}
@@ -22,7 +22,7 @@ plugins {
}
dependencies {
compileOnly(project(":SpigotCore"))
compileOnly(project(":SpigotCore", "default"))
compileOnly(libs.spigotapi)
@@ -83,6 +83,8 @@ SCHEM_PRIVATE=§ePrivate {0}
SCHEM_NO_PRIVATE=§7No private {0} present
SCHEM_PRIVATE_FORBIDDEN=§7No private {0} allowed
ADD_AI_TITLE=Add AI
# Countdowns
COUNTDOWN_MINUTES=§e{0} §7Minutes {1}
@@ -114,6 +116,7 @@ RESPAWN=§eRespawn
REMOVE_PLAYERS=§cKick player
CHOOSE_SCHEMATIC=§eChoose {0}
SCHEMATIC_REQUIRED=§cChoose a schematic first
ADD_AI=§eAdd AI
KIT_PREVIEW_EDIT=§7Edit kit
KIT_PREVIEW_CHOOSE=§aSelect kit
@@ -77,6 +77,8 @@ SCHEM_PRIVATE=§ePrivates {0}
SCHEM_NO_PRIVATE=§7Kein privates {0} vorhanden
SCHEM_PRIVATE_FORBIDDEN=§7Kein privates {0} erlaubt
ADD_AI_TITLE=KI hinzufügen
# Countdowns
COUNTDOWN_MINUTES=§e{0} §7Minuten {1}
@@ -107,6 +109,7 @@ RESPAWN=§eRespawn
REMOVE_PLAYERS=§cSpieler rauswerfen
CHOOSE_SCHEMATIC=§e{0} wählen
SCHEMATIC_REQUIRED=§cZuerst muss eine Schematic gewählt sein
ADD_AI=§eKI hinzufügen
KIT_PREVIEW_EDIT=§7Kit bearbeiten
KIT_PREVIEW_CHOOSE=§aKit wählen
@@ -19,32 +19,38 @@
package de.steamwar.fightsystem.ai;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import de.steamwar.fightsystem.ArenaMode;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.fight.Fight;
import de.steamwar.fightsystem.fight.FightTeam;
import de.steamwar.fightsystem.fight.JoinRequest;
import de.steamwar.fightsystem.listener.Chat;
import de.steamwar.fightsystem.record.GlobalRecorder;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.OneShotStateDependent;
import de.steamwar.fightsystem.utils.Region;
import de.steamwar.sql.SchematicNode;
import de.steamwar.sql.SteamwarUser;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Note;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.Lectern;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.FaceAttachable;
import org.bukkit.block.data.Openable;
import org.bukkit.block.data.Powerable;
import org.bukkit.block.data.type.Comparator;
import org.bukkit.block.data.type.NoteBlock;
import org.bukkit.block.data.type.Repeater;
import org.bukkit.block.data.type.Switch;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Villager;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.scheduler.BukkitTask;
@@ -55,10 +61,16 @@ import java.util.logging.Level;
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<>();
public static void printPos() {
ais.values().forEach(ai -> ai.chat(ai.entity.isValid() + " " + ai.entity.isDead() + " " + ai.entity.getLocation()));
}
static {
new OneShotStateDependent(ArenaMode.All, FightState.Spectate, () -> {
new OneShotStateDependent(ArenaMode.AntiReplay, FightState.Spectate, () -> {
ais.values().forEach(AI::stop);
ais.clear();
});
@@ -68,7 +80,9 @@ public abstract class AI {
return ais.get(uuid);
}
private final FightTeam team;
@Getter
protected final FightTeam team;
@Getter
private final LivingEntity entity;
private final BukkitTask task;
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);
ais.put(entity.getUniqueId(), this);
team.addMember(entity, user);
if(FightState.Schem.contains(FightState.getFightState()))
Bukkit.getScheduler().runTask(FightSystem.getPlugin(), () -> schematic(team.getClipboard()));
}
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;
}
@@ -101,11 +119,7 @@ public abstract class AI {
task.cancel();
}
public LivingEntity getEntity() {
return entity;
}
protected void setReady() {
public void setReady() {
if(FightState.getFightState() != FightState.POST_SCHEM_SETUP)
return;
@@ -115,12 +129,12 @@ public abstract class AI {
team.setReady(true);
}
protected void chat(String message) {
public void chat(String message) {
FightSystem.getPlugin().getLogger().log(Level.INFO, () -> entity.getName() + "» " + message);
Chat.broadcastChat("PARTICIPANT_CHAT", team.getColoredName(), entity.getName(), message);
}
protected Vector getPosition() {
public Vector getPosition() {
Location location = entity.getLocation();
Region extend = team.getExtendRegion();
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));
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));
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) {
@Override
public void run() {
if(FightState.getFightState() != FightState.RUNNING)
return;
Location location = translate(pos, true);
if(interactionDistanceViolation(location))
Location location = translate(pos);
if(interactionDistanceViolation(location)) {
chat("InteractionDistanceViolation: setTNT");
return;
}
Block block = location.getBlock();
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) {
@Override
public void run() {
Location location = translate(pos, true);
if(interactionDistanceViolation(location))
Location location = translate(pos);
if(interactionDistanceViolation(location)) {
chat("InteractionDistanceViolation: interact");
return;
}
interact(location.getBlock());
}
});
}
protected void interact(Vector pos, int n) {
public void interact(Vector pos, int n) {
queue.add(new Action(1) {
@Override
public void run() {
Location location = translate(pos, true);
Location location = translate(pos);
if (interactionDistanceViolation(location))
return;
Block block = location.getBlock();
@@ -199,13 +217,18 @@ public abstract class AI {
});
}
protected void move(Vector pos) {
queue.add(new Action(2) {
public void move(Vector pos) {
queue.add(new Action(MOVEMENT_DELAY) {
@Override
public void run() {
Location location = entity.getLocation();
Location target = translate(pos, false);
if(Math.abs(location.getX() - target.getX()) > 1 || Math.abs(location.getY() - target.getY()) > 1.2 || Math.abs(location.getZ() - target.getZ()) > 1) {
if(!entity.isOnGround() && location.getBlock().getType() != Material.LADDER) {
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());
return;
}
@@ -213,13 +236,16 @@ public abstract class AI {
if(!team.getFightPlayer(entity).canEntern() && !team.getExtendRegion().inRegion(target))
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) {
return location.distance(entity.getEyeLocation()) > 5;
return location.distance(entity.getEyeLocation()) > INTERACTION_RANGE;
}
private void interact(Block block) {
@@ -249,23 +275,51 @@ public abstract class AI {
powerable.setPowered(false);
block.setBlockData(powerable);
updateButton(block);
}, type.name().endsWith("STONE_BUTTON") ? 20 : 30);
}
powerable.setPowered(!isPowered);
}
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() {
if(queue.isEmpty())
plan();
if(queue.isEmpty()) {
try {
plan();
} catch (Throwable t) {
stop();
throw t;
}
}
if(!queue.isEmpty() && --queue.peek().delay == 0)
queue.poll().run();
}
private Location translate(Vector pos, boolean blockPos) {
public Location translate(Vector pos) {
Region extend = team.getExtendRegion();
if(Fight.getUnrotated() == team)
return new Location(
@@ -277,9 +331,9 @@ public abstract class AI {
else
return new Location(
Config.world,
extend.getMaxX() - pos.getX() - (blockPos ? 1 : 0),
extend.getMaxX() - pos.getX(),
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;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import de.steamwar.fightsystem.Config;
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.SteamwarUser;
import org.bukkit.util.Vector;
import java.util.List;
import java.util.Random;
public class LixfelAI extends AI {
public class DummyAI extends AI {
private final Random random = new Random();
private LixfelPathplanner pathplanner;
private static final Random random = new Random();
public LixfelAI(FightTeam team, String user) {
super(team, SteamwarUser.get(user));
public DummyAI(FightTeam team) {
super(team, SteamwarUser.get("public"));
FightStatistics.unrank();
getEntity().setInvulnerable(true);
}
@Override
public SchematicNode chooseSchematic() {
List<SchematicNode> publics = SchematicNode.getAllSchematicsOfType(0, Config.SchematicType.toDB());
SchematicNode schem = publics.get(new Random().nextInt(publics.size()));
pathplanner = new LixfelPathplanner(schem);
return schem;
return publics.get(random.nextInt(publics.size()));
}
@Override
public void schematic(Clipboard clipboard) {
//does nothing
}
@Override
protected void plan() {
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);
}
if(FightState.getFightState() == FightState.POST_SCHEM_SETUP)
setReady();
}
}
@@ -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.Config;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.ai.AIManager;
import de.steamwar.fightsystem.fight.*;
import de.steamwar.fightsystem.listener.PersonalKitCreator;
import de.steamwar.fightsystem.states.FightState;
@@ -38,9 +39,8 @@ import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.*;
import java.util.stream.Collectors;
public class GUI {
private GUI(){}
@@ -53,7 +53,7 @@ public class GUI {
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 -> {
p.closeInventory();
new JoinRequest(p, team);
JoinRequest.forPlayer(p, team);
});
}
@@ -89,11 +89,29 @@ public class GUI {
inv.open();
}
public static void addAI(Player p) {
SWListInv<AIManager> inv = new SWListInv<>(
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();
}
);
inv.setCallback(-999, (ClickType click) -> p.closeInventory());
inv.open();
}
public static void chooseJoinRequests(Player p){
List<SWListInv.SWListEntry<Player>> players = JoinRequest.openRequests(p, Fight.getPlayerTeam(p));
SWListInv<Player> inv = new SWListInv<>(p, msg.parse("REQUESTS_TITLE", p), players, (ClickType click, Player player) -> {
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, player, click.isLeftClick() ? JoinRequest::accept : JoinRequest::decline);
RequestsCommand.onJoinRequest(p, request, click.isLeftClick() ? JoinRequest::accept : JoinRequest::decline);
});
inv.setCallback(-999, (ClickType click) -> p.closeInventory());
inv.open();
@@ -59,13 +59,7 @@ public class RequestsCommand implements CommandExecutor {
return false;
}
public static void onJoinRequest(Player player, Player target, BiConsumer<JoinRequest, FightTeam> handleJoinRequest) {
JoinRequest request = JoinRequest.get(target);
if(request == null) {
FightSystem.getMessage().send("NO_JOIN_REQUEST", player);
return;
}
public static void onJoinRequest(Player player, JoinRequest request, BiConsumer<JoinRequest, FightTeam> handleJoinRequest) {
FightTeam team = Fight.getPlayerTeam(player);
if(!request.required(team)) {
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.SchematicNode;
import de.steamwar.sql.SchematicType;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.DyeColor;
import org.bukkit.Location;
@@ -52,6 +53,7 @@ public class FightSchematic extends StateDependent {
private final Region region;
private final boolean rotate;
@Getter
private Clipboard clipboard = null;
private int schematic = 0;
@@ -137,6 +139,7 @@ public class FightSchematic extends StateDependent {
private void paste(){
FreezeWorld freezer = new FreezeWorld();
team.teleportToSpawn();
Vector dims = WorldeditWrapper.impl.getDimensions(clipboard);
WorldeditWrapper.impl.pasteClipboard(
clipboard,
@@ -149,11 +152,11 @@ public class FightSchematic extends StateDependent {
new AffineTransform().rotateY(rotate ? 180 : 0)
);
FightSystem.getHullHider().initialize(team);
team.getPlayers().forEach(fightPlayer -> fightPlayer.ifAI(ai -> ai.schematic(clipboard)));
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(), team::teleportToSpawn, 40);
}
@Override
@@ -23,6 +23,7 @@ import com.sk89q.worldedit.extent.clipboard.Clipboard;
import de.steamwar.fightsystem.ArenaMode;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.ai.AIManager;
import de.steamwar.fightsystem.commands.GUI;
import de.steamwar.fightsystem.countdown.Countdown;
import de.steamwar.fightsystem.events.TeamLeaveEvent;
@@ -70,9 +71,11 @@ public class FightTeam {
static {
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(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())
@@ -452,6 +455,10 @@ public class FightTeam {
return schematic.getId();
}
public Clipboard getClipboard() {
return schematic.getClipboard();
}
public double getCurrentHearts() {
return players.values().stream().filter(FightPlayer::isLiving).mapToDouble(fp -> fp.getEntity().getHealth()).sum();
}
@@ -20,6 +20,7 @@
package de.steamwar.fightsystem.fight;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.ai.AIManager;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.inventory.SWItem;
import de.steamwar.inventory.SWListInv;
@@ -28,44 +29,66 @@ import net.md_5.bungee.api.chat.ClickEvent;
import org.bukkit.entity.Player;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import java.util.stream.Collectors;
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) {
return activeRequests.values().stream().filter(
public static List<SWListInv.SWListEntry<JoinRequest>> openRequests(Player p, FightTeam team) {
return activeRequests.stream().filter(
request -> request.waitOnApproval.contains(team)
).map(request -> {
SWItem item = SWItem.getPlayerSkull(request.player);
item.setLore(Arrays.asList(
AtomicReference<SWItem> item = new AtomicReference<>();
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_RIGHT_CLICK", p)
));
return new SWListInv.SWListEntry<>(item, request.player);
return new SWListInv.SWListEntry<>(item.get(), request);
}).collect(Collectors.toList());
}
public static void clearRequests() {
playerRequests.clear();
activeRequests.clear();
}
public static JoinRequest get(Player player) {
return activeRequests.get(player);
public static void forPlayer(Player player, FightTeam team) {
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 Set<FightTeam> waitOnApproval;
public JoinRequest(Player player, FightTeam team) {
this.player = player;
private JoinRequest(Enquirer enquirer, FightTeam team, Collection<FightTeam> waitOnApproval) {
this.enquirer = enquirer;
this.team = team;
this.waitOnApproval = new HashSet<>(FightState.ingame() ? Fight.teams() : Collections.singleton(team));
this.waitOnApproval = new HashSet<>(waitOnApproval);
Set<FightTeam> alreadyAccepted = new HashSet<>();
activeRequests.put(player, this);
enquirer.ifPlayer(player -> playerRequests.put(player, this));
activeRequests.add(this);
for(FightTeam t : waitOnApproval) {
FightPlayer leader = t.getLeader();
if(leader == null)
@@ -74,14 +97,14 @@ public class JoinRequest {
if(leader.getEntity() == null)
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 -> {
if(ai.acceptJoinRequest(player, team))
if(ai.acceptJoinRequest(enquirer, team))
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);
}
@@ -93,18 +116,26 @@ public class JoinRequest {
waitOnApproval.remove(acceptor);
if(waitOnApproval.isEmpty()) {
team.addMember(player);
activeRequests.remove(player);
enquirer.ifPlayer(team::addMember);
enquirer.ifAI(manager -> manager.join(team));
close();
}
}
public void decline(FightTeam declinor) {
FightSystem.getMessage().sendPrefixless("REQUEST_YOUR_DECLINED", player, ChatMessageType.ACTION_BAR);
waitOnApproval.forEach(t -> t.broadcast("REQUEST_DECLINED", player.getName()));
silentDecline();
enquirer.ifPlayer(player -> FightSystem.getMessage().sendPrefixless("REQUEST_YOUR_DECLINED", player, ChatMessageType.ACTION_BAR));
waitOnApproval.forEach(t -> t.broadcast("REQUEST_DECLINED", enquirer.name()));
close();
}
public void silentDecline() {
activeRequests.remove(player);
public void close() {
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) {
JoinRequest request = JoinRequest.get(event.getPlayer());
if(request != null)
request.silentDecline();
request.close();
}
}
@@ -43,6 +43,7 @@ import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
@@ -70,7 +71,7 @@ public class Recording implements Listener {
return stack;
}
public static boolean isNotSent(Player p){
public static boolean isNotSent(LivingEntity p){
FightPlayer fp = Fight.getFightPlayer(p);
return fp == null || !fp.isLiving() || FightState.getFightState() == FightState.SPECTATE;
}
@@ -193,10 +194,10 @@ public class Recording implements Listener {
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onEntityDamage(EntityDamageEvent e) {
if(e.getEntityType() != EntityType.PLAYER)
if(!e.getEntityType().isAlive())
return;
Player p = (Player) e.getEntity();
LivingEntity p = (LivingEntity) e.getEntity();
if(isNotSent(p))
return;
@@ -208,10 +209,10 @@ public class Recording implements Listener {
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onEntityCombust(EntityCombustEvent e) {
if(e.getEntityType() != EntityType.PLAYER)
if(!e.getEntityType().isAlive())
return;
Player p = (Player) e.getEntity();
LivingEntity p = (LivingEntity) e.getEntity();
if(isNotSent(p))
return;
@@ -204,7 +204,7 @@ public interface Recorder {
write(0x0a, e.getEntityId(), start, offHand);
}
default void damageAnimation(Player p) {
default void damageAnimation(LivingEntity p) {
write(0x0b, p.getEntityId());
}
+1 -1
View File
@@ -27,7 +27,7 @@ java {
}
dependencies {
compileOnly(project(":SpigotCore"))
compileOnly(project(":SpigotCore", "default"))
compileOnly(libs.spigotapi)
@@ -4,8 +4,12 @@ DATE=........
COMMAND_HELP_HEAD=§7---=== (§e{0}§7) ===---
# ServerTeamNPC's
NPC_CHAT_1 = §fHello, I''m {0} and I''m a(n) {1}§f.
NPC_CHAT_2 = §fWelcome on §eSteam§8War§f, have fun.
NPC_CHAT_0 = §fHello, I''m {0} and I''m a(n) {1}§f.
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_LIST_HELP = §8/§7portal §elist §8- §7Lists all portals
@@ -4,8 +4,12 @@ DATE=........
COMMAND_HELP_HEAD=§7---=== (§e{0}§7) ===---
# ServerTeamNPC's
NPC_CHAT_1 = §fHallo, ich bin {0} und bin ein {1}§f.
NPC_CHAT_2 = §fWillkommen auf §eSteam§8War§f, viel Spaß dir.
NPC_CHAT_0 = §fHallo, ich bin {0} und bin ein {1}§f.
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_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":
return "Schemauswahl";
case "POST_SCHEM_SETUP":
case "generating_tower":
return "Vorbereitung";
case "PRE_RUNNING":
return "Kampfbeginn in";
case "fighting":
case "RUNNING":
case "running":
return "Kampf läuft";
case "end":
case "SPECTATE":
@@ -60,11 +60,6 @@ public class TeamPlayer extends BasicListener {
private Set<Player> players = new HashSet<>();
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) {
Location location = new Location(world, 2790.5, 69, 1311.5);
@@ -149,8 +144,9 @@ public class TeamPlayer extends BasicListener {
players.remove(event.getPlayer());
return;
}
String message = "NPC_Chat_" + random.nextInt(6);
SteamwarUser user = SteamwarUser.get(event.getRightClicked().getName());
String message = strings.get(random.nextInt(strings.size()));
UserPerm.Prefix prefix = user.prefix();
LobbySystem.getMessage().send(message, event.getPlayer(), event.getRightClicked().getName(), prefix.getColorCode() + prefix.getChatPrefix());
}
+1 -1
View File
@@ -27,7 +27,7 @@ java {
}
dependencies {
compileOnly(project(":SpigotCore"))
compileOnly(project(":SpigotCore", "default"))
compileOnly(libs.spigotapi)
@@ -22,8 +22,8 @@ plugins {
}
dependencies {
compileOnly(project(":SpigotCore"))
compileOnly(project(":SchematicSystem:SchematicSystem_Core"))
compileOnly(project(":SpigotCore", "default"))
compileOnly(project(":SchematicSystem:SchematicSystem_Core", "default"))
compileOnly(libs.nms15)
compileOnly(libs.worldedit15)
@@ -22,8 +22,8 @@ plugins {
}
dependencies {
compileOnly(project(":SpigotCore"))
compileOnly(project(":SchematicSystem:SchematicSystem_Core"))
compileOnly(project(":SpigotCore", "default"))
compileOnly(project(":SchematicSystem:SchematicSystem_Core", "default"))
compileOnly(libs.nms8)
compileOnly(libs.worldedit12)
@@ -22,7 +22,7 @@ plugins {
}
dependencies {
compileOnly(project(":SpigotCore"))
compileOnly(project(":SpigotCore", "default"))
compileOnly(libs.spigotapi)
compileOnly(libs.worldedit15)
+1 -1
View File
@@ -22,7 +22,7 @@ plugins {
}
dependencies {
compileOnly(project(":SpigotCore:SpigotCore_Main"))
compileOnly(project(":SpigotCore:SpigotCore_Main", "default"))
compileOnly(libs.nms10)
}
+2 -2
View File
@@ -22,8 +22,8 @@ plugins {
}
dependencies {
compileOnly(project(":CommonCore"))
compileOnly(project(":SpigotCore:SpigotCore_Main"))
compileOnly(project(":CommonCore", "default"))
compileOnly(project(":SpigotCore:SpigotCore_Main", "default"))
compileOnly(libs.nms12)
}
+4 -4
View File
@@ -22,10 +22,10 @@ plugins {
}
dependencies {
compileOnly(project(":CommonCore"))
compileOnly(project(":SpigotCore:SpigotCore_Main"))
compileOnly(project(":SpigotCore:SpigotCore_8"))
compileOnly(project(":SpigotCore:SpigotCore_9"))
compileOnly(project(":CommonCore", "default"))
compileOnly(project(":SpigotCore:SpigotCore_Main", "default"))
compileOnly(project(":SpigotCore:SpigotCore_8", "default"))
compileOnly(project(":SpigotCore:SpigotCore_9", "default"))
compileOnly(libs.nms14)
compileOnly(libs.worldedit15)
+1 -1
View File
@@ -22,7 +22,7 @@ plugins {
}
dependencies {
compileOnly(project(":SpigotCore:SpigotCore_Main"))
compileOnly(project(":SpigotCore:SpigotCore_Main", "default"))
compileOnly(libs.nms15)
}
+3 -3
View File
@@ -26,9 +26,9 @@ tasks.compileJava {
}
dependencies {
compileOnly(project(":CommonCore"))
compileOnly(project(":SpigotCore:SpigotCore_Main"))
compileOnly(project(":SpigotCore:SpigotCore_14"))
compileOnly(project(":CommonCore", "default"))
compileOnly(project(":SpigotCore:SpigotCore_Main", "default"))
compileOnly(project(":SpigotCore:SpigotCore_14", "default"))
compileOnly(libs.spigotapi)
compileOnly(libs.nms18)
+3 -3
View File
@@ -22,9 +22,9 @@ plugins {
}
dependencies {
compileOnly(project(":SpigotCore:SpigotCore_Main"))
compileOnly(project(":SpigotCore:SpigotCore_14"))
compileOnly(project(":SpigotCore:SpigotCore_18"))
compileOnly(project(":SpigotCore:SpigotCore_Main", "default"))
compileOnly(project(":SpigotCore:SpigotCore_14", "default"))
compileOnly(project(":SpigotCore:SpigotCore_18", "default"))
compileOnly(libs.worldedit15)
compileOnly(libs.nms19)
+1 -1
View File
@@ -22,7 +22,7 @@ plugins {
}
dependencies {
compileOnly(project(":SpigotCore:SpigotCore_Main"))
compileOnly(project(":SpigotCore:SpigotCore_Main", "default"))
compileOnly(libs.spigotapi)
+2 -2
View File
@@ -22,8 +22,8 @@ plugins {
}
dependencies {
compileOnly(project(":CommonCore"))
compileOnly(project(":SpigotCore:SpigotCore_Main"))
compileOnly(project(":CommonCore", "default"))
compileOnly(project(":SpigotCore:SpigotCore_Main", "default"))
compileOnly(libs.nms8)
compileOnly(libs.worldedit12)
+2 -2
View File
@@ -22,8 +22,8 @@ plugins {
}
dependencies {
compileOnly(project(":SpigotCore:SpigotCore_Main"))
compileOnly(project(":SpigotCore:SpigotCore_8"))
compileOnly(project(":SpigotCore:SpigotCore_Main", "default"))
compileOnly(project(":SpigotCore:SpigotCore_8", "default"))
compileOnly(libs.nms9)
+3 -3
View File
@@ -26,9 +26,9 @@ tasks.compileJava {
}
dependencies {
compileOnly(project(":CommonCore"))
compileOnly(project(":CommandFramework"))
compileOnly(project(":SpigotCore:CRIUDummy"))
compileOnly(project(":CommonCore", "default"))
compileOnly(project(":CommandFramework", "default"))
compileOnly(project(":SpigotCore:CRIUDummy", "default"))
compileOnly(libs.worldedit12)
@@ -36,6 +36,7 @@ import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.plugin.Plugin;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.BiFunction;
import java.util.logging.Level;
@@ -102,7 +103,7 @@ public class TinyProtocol implements Listener {
}
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) {
+2 -2
View File
@@ -4,6 +4,6 @@ plugins {
dependencies {
compileOnly(libs.paperapi21)
compileOnly(project(":SpigotCore"))
compileOnly(project(":KotlinCore"))
compileOnly(project(":SpigotCore", "default"))
compileOnly(project(":KotlinCore", "default"))
}
+1 -1
View File
@@ -22,7 +22,7 @@ plugins {
}
dependencies {
compileOnly(project(":SpigotCore"))
compileOnly(project(":SpigotCore", "default"))
compileOnly(libs.spigotapi)
+1 -1
View File
@@ -30,7 +30,7 @@ dependencies {
annotationProcessor(libs.spigotannotations)
compileOnly(libs.spigotannotations)
compileOnly(project(":SpigotCore"))
compileOnly(project(":SpigotCore", "default"))
compileOnly(libs.nms19)
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.NotLobbyListener;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.plugin.java.annotation.dependency.Dependency;
import org.bukkit.plugin.java.annotation.plugin.ApiVersion;
@@ -79,6 +80,8 @@ public class TowerRun extends JavaPlugin {
new StartCommand(lobbyCountdown);
gameCountdown = new GameCountdown();
Bukkit.getScheduler().runTaskTimer(this, new FightInfoPacketSender(), 20, 20);
TowerRunGame.reset();
}
}
@@ -39,6 +39,8 @@ public class Config {
public static final int GAME_TIMER;
public static final int GAME_ESCAPE_TIMER;
private static final int EVENT_KAMPF_ID;
static {
File configFile = new File(TowerRun.getInstance().getDataFolder(), "config.yml");
if (!configFile.exists()) {
@@ -53,6 +55,11 @@ public class Config {
GAME_TIMER = config.getInt("gameTimer", 20 * 60);
GAME_ESCAPE_TIMER = config.getInt("gameEscapeTimer", 60);
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;
public EndCountdown(LobbyCountdown lobbyCountdown) {
super(EnumSet.of(GameStates.ENDING));
super(EnumSet.of(GameStates.END));
this.lobbyCountdown = lobbyCountdown;
}
@@ -28,8 +28,10 @@ import java.util.EnumSet;
public class GameCountdown extends Countdown {
private long startTime = 0;
public GameCountdown() {
super(EnumSet.of(GameStates.INGAME));
super(EnumSet.of(GameStates.RUNNING));
}
@Override
@@ -59,9 +61,21 @@ public class GameCountdown extends Countdown {
TowerRun.getMessage().broadcastActionbar("GAME_TIME", String.format("%02d", timeMinutes), String.format("%02d", timeSeconds));
}
@Override
public void enable() {
super.enable();
startTime = System.currentTimeMillis();
}
@Override
public void disable() {
super.disable();
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;
public LobbyCountdown() {
super(EnumSet.of(GameStates.LOBBY));
super(EnumSet.of(GameStates.WAITING));
}
@Override
@@ -49,7 +49,7 @@ public class TowerRunGame {
}
public static void prepareTowerOrStart() {
if (GameState.getCurrentState() == GameStates.LOBBY) {
if (GameState.getCurrentState() == GameStates.WAITING) {
GameState.nextState();
if (TowerRun.getTowerGenerator() == null) {
start();
@@ -52,7 +52,7 @@ public class IngameListener extends GameStateBukkitListener {
private BukkitRunnable antiCampRunnable;
public IngameListener() {
super(EnumSet.of(GameStates.INGAME));
super(EnumSet.of(GameStates.RUNNING));
}
@Override
@@ -37,7 +37,7 @@ import java.util.EnumSet;
public class LobbyListener extends GameStateBukkitListener {
public LobbyListener() {
super(EnumSet.of(GameStates.LOBBY));
super(EnumSet.of(GameStates.WAITING));
}
@EventHandler
@@ -31,7 +31,7 @@ import java.util.EnumSet;
public class NotLobbyListener extends GameStateBukkitListener {
public NotLobbyListener() {
super(EnumSet.complementOf(EnumSet.of(GameStates.LOBBY)));
super(EnumSet.complementOf(EnumSet.of(GameStates.WAITING)));
}
@EventHandler
@@ -28,7 +28,7 @@ import java.util.List;
@UtilityClass
public class GameState {
@Getter
private static GameStates currentState = GameStates.LOBBY;
private static GameStates currentState = GameStates.WAITING;
private static final List<GameStateListener> gameStateListeners = new ArrayList<>();
public static void addGameStateListener(GameStateListener gameStateListener) {
@@ -49,7 +49,7 @@ public class GameState {
public static void reset() {
final GameStates oldState = currentState;
currentState = GameStates.LOBBY;
currentState = GameStates.WAITING;
gameStateChanges(oldState, currentState);
}
@@ -25,10 +25,10 @@ import lombok.Getter;
@AllArgsConstructor
@Getter
public enum GameStates {
ENDING(null),
INGAME(ENDING),
GENERATING_TOWER(INGAME),
LOBBY(GENERATING_TOWER);
END(null),
RUNNING(END),
GENERATING_TOWER(RUNNING),
WAITING(GENERATING_TOWER);
private final GameStates nextState;
}
@@ -34,7 +34,7 @@ public abstract class WinCondition extends GameStateBukkitListener {
private boolean active = false;
protected WinCondition(String name) {
super(EnumSet.of(GameStates.INGAME));
super(EnumSet.of(GameStates.RUNNING));
this.name = name;
}
+1 -1
View File
@@ -22,7 +22,7 @@ plugins {
}
dependencies {
compileOnly(project(":SpigotCore"))
compileOnly(project(":SpigotCore", "default"))
compileOnly(libs.nms15)
}
+1 -1
View File
@@ -48,7 +48,7 @@ dependencies {
annotationProcessor(libs.velocityapi)
compileOnly(libs.velocity)
compileOnly(project(":VelocityCore:Persistent"))
compileOnly(project(":VelocityCore:Persistent", "default"))
implementation(project(":CommonCore"))
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_QUESTION=Please ask your question. A staff member will address the question soon.
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_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_QUESTION=Bitte stelle deine Frage, ein Serverteammitglied wird sich dieser zeitnah annehmen.
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_SCHEMUPLOAD_NOPERM=Du darfst keine Schematics hochladen.
@@ -478,6 +478,7 @@ public class TeamCommand extends SWCommand {
}
@Register("color")
@Register("changecolor")
public void changeColor(@Validator("isLeader") PlayerChatter sender) {
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.util.AuthManager;
import lombok.Getter;
import net.dv8tion.jda.api.*;
import net.dv8tion.jda.api.entities.*;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.JDA;
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.interactions.commands.Command;
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.Commands;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
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.utils.MemberCachePolicy;
import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder;
import javax.security.auth.login.LoginException;
import java.awt.*;
import java.util.List;
import java.util.*;
@@ -87,15 +96,12 @@ public class DiscordBot {
public DiscordBot(DiscordConfig config) {
this.config = config;
try {
jda = JDABuilder
.createDefault(config.getToken())
.setStatus(OnlineStatus.ONLINE)
.setMemberCachePolicy(MemberCachePolicy.ONLINE)
.build();
} catch (LoginException e) {
throw new SecurityException("Could not login", e);
}
jda = JDABuilder
.createDefault(config.getToken())
.setStatus(OnlineStatus.ONLINE)
.setMemberCachePolicy(MemberCachePolicy.ONLINE)
.enableIntents(GatewayIntent.MESSAGE_CONTENT)
.build();
instance = this;
VelocityCore.schedule(this::asyncInit).schedule();
@@ -109,9 +115,9 @@ public class DiscordBot {
}
activity();
new StaticMessageChannel(config.channel("roles"), () -> new MessageBuilder()
new StaticMessageChannel(config.channel("roles"), () -> new MessageCreateBuilder()
.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();
Guild guild = event.getGuild();
Role role = guild.getRoleById(event.getComponentId());
@@ -124,33 +130,45 @@ public class DiscordBot {
reply.system("DC_ROLE_ADDED", role.getAsMention());
}
}));
new StaticMessageChannel(config.channel("rules"), () -> new MessageBuilder()
new StaticMessageChannel(config.channel("rules"), () -> new MessageCreateBuilder()
.setEmbeds(new EmbedBuilder()
.setDescription(String.join("\n", config.getRules()))
.setColor(Color.GRAY)
.setAuthor("SteamWar", "https://steamwar.de")
.setTitle("Regeln und Infos")
.build())
.setActionRows(
.setComponents(
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"))
), event -> {
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();
});
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()
.setDescription("Hier kannst du Tickets öffnen, welche nur von dir und Teammitgliedern eingesehen werden können.")
.setTitle("SteamWar Tickets")
.setColor(Color.RED)
.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);
checklistChannel = new ChecklistChannel(config.channel("checklist"));
announcementChannel = new DiscordChannel(config.channel("announcement")) {
@Override
public void received(GuildMessageReceivedEvent event) {
public void received(MessageReceivedEvent event) {
Chatter.broadcast().system("ALERT", event.getMessage().getContentDisplay());
}
};
@@ -198,7 +216,7 @@ public class DiscordBot {
.keySet().stream()
.filter(command -> !correctCommands.contains(command))
.filter(command -> command.matches("^[\\w-]+$"))
.map(command -> new CommandData(command, command).addOptions(commandArgument))
.map(command -> Commands.slash(command, command).addOptions(commandArgument))
.toArray(CommandData[]::new))
.queue();
}
@@ -23,9 +23,9 @@ import de.steamwar.velocitycore.Config;
import de.steamwar.velocitycore.VelocityCore;
import lombok.Getter;
import lombok.NoArgsConstructor;
import net.dv8tion.jda.api.entities.Emoji;
import net.dv8tion.jda.api.interactions.components.Button;
import net.dv8tion.jda.api.interactions.components.ButtonStyle;
import net.dv8tion.jda.api.entities.emoji.Emoji;
import net.dv8tion.jda.api.interactions.components.buttons.Button;
import net.dv8tion.jda.api.interactions.components.buttons.ButtonStyle;
import java.io.File;
import java.util.List;
@@ -20,9 +20,9 @@
package de.steamwar.velocitycore.discord;
import lombok.AllArgsConstructor;
import net.dv8tion.jda.api.entities.Emoji;
import net.dv8tion.jda.api.interactions.components.Button;
import net.dv8tion.jda.api.interactions.components.ButtonStyle;
import net.dv8tion.jda.api.entities.emoji.Emoji;
import net.dv8tion.jda.api.interactions.components.buttons.Button;
import net.dv8tion.jda.api.interactions.components.buttons.ButtonStyle;
@AllArgsConstructor
public enum DiscordTicketType {
@@ -30,7 +30,9 @@ public enum DiscordTicketType {
IDEA("U+1F4A1", "Feature vorschlagen", ButtonStyle.SUCCESS),
BUG("U+1F41B", "Bug melden", ButtonStyle.SECONDARY),
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 label;
@@ -26,11 +26,12 @@ import de.steamwar.messages.Message;
import de.steamwar.sql.SteamwarUser;
import lombok.AllArgsConstructor;
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.events.interaction.GenericComponentInteractionCreateEvent;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
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.serializer.plain.PlainTextComponentSerializer;
@@ -57,19 +58,19 @@ public class DiscordChannel extends Chatter.PlayerlessChatter {
}
public void send(String message) {
send(new MessageBuilder()
.append(message
send(new MessageCreateBuilder()
.setContent(message
.replace("&", "")
.replace("@everyone", "`@everyone`")
.replace("@here", "`@here`")
.replaceAll("<[@#]!?\\d+>", "`$0`")));
}
public void send(MessageBuilder builder) {
public void send(MessageCreateBuilder builder) {
channel.sendMessage(builder.build()).queue();
}
public void received(GuildMessageReceivedEvent event) {
public void received(MessageReceivedEvent event) {
event.getMessage().delete().queue();
}
@@ -24,7 +24,7 @@ import de.steamwar.messages.Chatter;
import de.steamwar.messages.ChatterGroup;
import de.steamwar.sql.Punishment;
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;
@@ -40,7 +40,7 @@ public class DiscordChatRoom extends DiscordChannel {
}
@Override
public void received(GuildMessageReceivedEvent event) {
public void received(MessageReceivedEvent event) {
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)) {
event.getMessage().delete().queue();
@@ -25,10 +25,10 @@ import de.steamwar.sql.Team;
import de.steamwar.sql.TeamTeilnahme;
import lombok.experimental.UtilityClass;
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.emoji.Emoji;
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.sql.Timestamp;
@@ -40,21 +40,21 @@ import java.util.stream.Collectors;
@UtilityClass
public class EventChannel {
public MessageBuilder get() {
public MessageCreateBuilder get() {
if (Event.get() == null)
return updateComing();
return updateCurrent();
}
private MessageBuilder updateComing() {
private MessageCreateBuilder updateComing() {
EmbedBuilder embedBuilder = new EmbedBuilder()
.setColor(Color.GRAY)
.setTitle("Zukünftige Events")
.setAuthor("SteamWar", "https://www.steamwar.de");
SelectionMenu.Builder menuBuilder = SelectionMenu.create("eventName")
StringSelectMenu.Builder menuBuilder = StringSelectMenu.create("eventName")
.setPlaceholder("Wähle ein Event aus!")
.setMinValues(1)
.setMaxValues(1);
@@ -77,16 +77,16 @@ public class EventChannel {
}
});
MessageBuilder messageBuilder = new MessageBuilder()
MessageCreateBuilder messageBuilder = new MessageCreateBuilder()
.setEmbeds(embedBuilder.build());
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;
}
private MessageBuilder updateCurrent() {
private MessageCreateBuilder updateCurrent() {
Event event = Event.get();
EmbedBuilder embedBuilder = new EmbedBuilder()
.setColor(Color.GRAY)
@@ -19,7 +19,8 @@
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.serializer.plain.PlainTextComponentSerializer;
@@ -29,18 +30,18 @@ import java.util.function.Consumer;
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);
consumer.accept(reply);
reply.submit();
}
private final Interaction interaction;
private final IReplyCallback interaction;
private boolean replied = false;
private final List<String> messages = new ArrayList<>();
private InteractionReply(Interaction interaction) {
private InteractionReply(IReplyCallback interaction) {
super(interaction.getUser());
this.interaction = interaction;
}
@@ -20,35 +20,36 @@
package de.steamwar.velocitycore.discord.channels;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.MessageBuilder;
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.Supplier;
public class StaticMessageChannel extends DiscordChannel {
public static MessageBuilder toMessageBuilder(EmbedBuilder embedBuilder) {
MessageBuilder messageBuilder = new MessageBuilder();
public static MessageCreateBuilder toMessageBuilder(EmbedBuilder embedBuilder) {
MessageCreateBuilder messageBuilder = new MessageCreateBuilder();
messageBuilder.setEmbeds(embedBuilder.build());
return messageBuilder;
}
private Message message;
private final Supplier<MessageBuilder> supplier;
private final Supplier<MessageCreateBuilder> supplier;
private final Consumer<GenericComponentInteractionCreateEvent> interaction;
public StaticMessageChannel(String channel, Supplier<MessageBuilder> supplier) {
public StaticMessageChannel(String channel, Supplier<MessageCreateBuilder> supplier) {
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);
this.supplier = supplier;
this.interaction = interaction;
if(getChannel().hasLatestMessage())
if(getChannel().getLatestMessageIdLong() != 0)
message = getChannel().getIterableHistory().complete().stream().filter(m -> m.getAuthor().isBot()).findFirst().orElse(null);
update();
@@ -58,7 +59,7 @@ public class StaticMessageChannel extends DiscordChannel {
if (message == null) {
getChannel().sendMessage(supplier.get().build()).queue(m -> message = m);
} 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.InteractionReply;
import lombok.Getter;
import net.dv8tion.jda.api.entities.ChannelType;
import net.dv8tion.jda.api.entities.MessageChannel;
import net.dv8tion.jda.api.events.interaction.GenericComponentInteractionCreateEvent;
import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
import net.dv8tion.jda.api.entities.channel.ChannelType;
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
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.interactions.InteractionType;
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<>();
@Override
public void onGuildMessageReceived(@NotNull GuildMessageReceivedEvent event) {
public void onMessageReceived(@NotNull MessageReceivedEvent event) {
if(event.getAuthor().isBot())
return;
@@ -69,7 +69,7 @@ public class ChannelListener extends ListenerAdapter {
}
@Override
public void onSlashCommand(@NotNull SlashCommandEvent event) {
public void onSlashCommandInteraction(@NotNull SlashCommandInteractionEvent event) {
InteractionReply.reply(event, sender -> {
if(sender.user().getDiscordId() == null)
return;
@@ -26,7 +26,7 @@ import de.steamwar.sql.Punishment;
import de.steamwar.sql.SchematicNode;
import de.steamwar.sql.SteamwarUser;
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 java.io.IOException;
@@ -41,7 +41,9 @@ public class DiscordSchemUpload extends ListenerAdapter {
private static final List<String> SCHEM_FILE_ENDINGS = Arrays.asList(".schem", ".schematic");
@Override
public void onPrivateMessageReceived(PrivateMessageReceivedEvent event) {
public void onMessageReceived(MessageReceivedEvent event) {
if (event.isFromGuild()) return;
Message message = event.getMessage();
if(message.getAttachments().isEmpty())
return;
@@ -76,7 +78,7 @@ public class DiscordSchemUpload extends ListenerAdapter {
if(node == 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"));
sender.system("DC_SCHEMUPLOAD_SUCCESS", name);
} catch (InterruptedException e) {
@@ -23,7 +23,7 @@ import de.steamwar.velocitycore.VelocityCore;
import de.steamwar.velocitycore.discord.DiscordBot;
import de.steamwar.velocitycore.discord.channels.InteractionReply;
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 org.jetbrains.annotations.NotNull;
@@ -32,7 +32,7 @@ public class DiscordTeamEvent extends ListenerAdapter {
private final String eventsChannel = DiscordBot.getInstance().getConfig().channel("events");
@Override
public void onSelectionMenu(@NotNull SelectionMenuEvent event) {
public void onStringSelectInteraction(@NotNull StringSelectInteractionEvent event) {
if(!event.getChannel().getId().equals(eventsChannel))
return;
@@ -29,22 +29,24 @@ import de.steamwar.velocitycore.discord.DiscordTicketType;
import de.steamwar.velocitycore.discord.channels.DiscordChannel;
import de.steamwar.velocitycore.discord.channels.InteractionReply;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.MessageBuilder;
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.events.interaction.GenericComponentInteractionCreateEvent;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
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.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 org.jetbrains.annotations.NotNull;
import java.awt.*;
import java.time.Instant;
import java.util.Collections;
import java.util.LinkedList;
import java.util.stream.Collectors;
@@ -59,24 +61,23 @@ public class DiscordTicketHandler extends ListenerAdapter {
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();
ticketChannel.createPermissionOverride(event.getMember()).setAllow(
ticketChannel.getPermissionContainer().upsertPermissionOverride(event.getMember()).setAllowed(
Permission.VIEW_CHANNEL,
Permission.MESSAGE_WRITE,
Permission.MESSAGE_SEND,
Permission.MESSAGE_ATTACH_FILES,
Permission.MESSAGE_ADD_REACTION,
Permission.MESSAGE_READ,
Permission.MESSAGE_EMBED_LINKS,
Permission.MESSAGE_HISTORY).complete();
ticketChannel.getManager().setTopic(event.getUser().getId()).complete();
DiscordChannel channel = new DiscordChannel(DiscordChannel.userOrPublic(event.getUser()), ticketChannel);
channel.send(new MessageBuilder()
channel.send(new MessageCreateBuilder()
.setEmbeds(new EmbedBuilder()
.setTitle(channel.parseToPlain("DC_TICKET_TITLE"))
.setDescription(channel.parseToPlain(ticketType.introduction()))
.setColor(Color.GREEN)
.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()));
Chatter.serverteam().prefixless("DISCORD_TICKET_NEW", ticketChannel.getName());
@@ -85,8 +86,8 @@ public class DiscordTicketHandler extends ListenerAdapter {
@Override
public void onGenericComponentInteractionCreate(@NotNull GenericComponentInteractionCreateEvent event) {
MessageChannel messageChannel = event.getChannel();
if(messageChannel instanceof TextChannel channel && channel.getParent() != null && channel.getParent().getId().equals(TICKET_CATEGORY) && event.getComponentId().startsWith("close-")) {
LinkedList<StringBuilder> messages = channel.getIterableHistory().complete().stream()
if(messageChannel instanceof TextChannel channel && channel.getParentCategoryIdLong() != 0 && channel.getParentCategoryId().equals(TICKET_CATEGORY) && event.getComponentId().startsWith("close-")) {
LinkedList<StringBuilder> messages = channel.getIterableHistory().reverse().complete().stream()
.filter(message -> !message.getAuthor().isSystem() && !message.getAuthor().isBot())
.map(message -> {
StringBuilder stringBuilder = new StringBuilder()
@@ -104,26 +105,12 @@ public class DiscordTicketHandler extends ListenerAdapter {
})
.collect(Collectors.toCollection(LinkedList::new));
messages.addFirst(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);
}
});
messages.add(new StringBuilder().append("<t:").append(Instant.now().getEpochSecond()).append("> **").append(event.getUser().getName()).append("**: Ticket closed"));
EmbedBuilder embedBuilder = new EmbedBuilder()
.setColor(Color.GREEN)
.setTimestamp(Instant.now())
.setTitle(event.getTextChannel().getName());
.setTitle(event.getChannel().getName());
if(channel.getTopic() != null && !channel.getTopic().isEmpty()) {
User user = event.getJDA().retrieveUserById(channel.getTopic()).complete();
@@ -131,7 +118,13 @@ public class DiscordTicketHandler extends ListenerAdapter {
}
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());
channel.delete().reason("Closed").queue();
@@ -139,11 +132,12 @@ public class DiscordTicketHandler extends ListenerAdapter {
}
@Override
public void onGuildMessageReceived(@NotNull GuildMessageReceivedEvent event) {
TextChannel channel = event.getChannel();
public void onMessageReceived(@NotNull MessageReceivedEvent event) {
MessageChannel channel = event.getChannel();
if(
channel.getParent() != null &&
channel.getParent().getId().equals(TICKET_CATEGORY) &&
channel instanceof TextChannel textChannel &&
textChannel.getParentCategoryIdLong() != 0 &&
textChannel.getParentCategoryId().equals(TICKET_CATEGORY) &&
!channel.getId().equals(TICKET_CHANNEL) &&
!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)));
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))
receivers = new ChatterGroup(receivers, Chatter.of(user));
} catch(NumberFormatException e) {
@@ -23,11 +23,11 @@ import de.steamwar.velocitycore.VelocityCore;
import de.steamwar.velocitycore.discord.channels.DiscordChannel;
import de.steamwar.sql.SteamwarUser;
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.emoji.Emoji;
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.HashMap;
@@ -63,9 +63,9 @@ public class AuthManager {
user.setDiscordId(dcUser.getIdLong());
DiscordChannel channel = new DiscordChannel(dcUser);
channel.send(new MessageBuilder()
channel.send(new MessageCreateBuilder()
.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;
}
@@ -25,11 +25,11 @@ import de.steamwar.velocitycore.discord.DiscordBot;
import de.steamwar.velocitycore.discord.channels.DiscordChannel;
import lombok.experimental.UtilityClass;
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.emoji.Emoji;
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.time.Instant;
@@ -47,7 +47,7 @@ public class DiscordAlert {
if(user == null)
return;
MessageBuilder builder = new MessageBuilder()
MessageCreateBuilder builder = new MessageCreateBuilder()
.setEmbeds(new EmbedBuilder()
.setAuthor("SteamWar", "https://steamwar.de", "https://cdn.discordapp.com/app-icons/869606970099904562/60c884000407c02671d91d8e7182b8a1.png")
.setColor(color)
@@ -56,7 +56,7 @@ public class DiscordAlert {
.setTimestamp(Instant.now())
.build());
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);
});
@@ -20,6 +20,7 @@
package de.steamwar.velocitycore.mods;
import com.velocitypowered.api.proxy.Player;
import de.steamwar.sql.Punishment;
import de.steamwar.velocitycore.VelocityCore;
import de.steamwar.velocitycore.commands.PunishmentCommand;
import de.steamwar.messages.Chatter;
@@ -76,12 +77,13 @@ public class ModUtils {
String message;
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 {
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) {
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);
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("junit", "junit:junit:4.13.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("classindex", "org.atteo.classindex:classindex:3.13")