forked from SteamWar/SteamWar
Compare commits
11
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eb218c33ca | ||
|
|
7b01f11b5b | ||
|
|
fd57ba43e9 | ||
|
|
03005adcd8 | ||
|
|
679d373a1e | ||
|
|
828084a3d6 | ||
|
|
2b782585b1 | ||
|
|
b43965be91 | ||
|
|
d82f306094 | ||
|
|
30cdbe072e | ||
|
|
db7e1a5fc9 |
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2025 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.data;
|
||||||
|
|
||||||
|
public class SyncCommands {
|
||||||
|
public static final String RELOAD_PLAYER = "reload_player";
|
||||||
|
public static final String RELOAD_EVENT = "reload_event";
|
||||||
|
}
|
||||||
@@ -35,7 +35,8 @@ import java.util.stream.Collectors;
|
|||||||
public class Fight {
|
public class Fight {
|
||||||
|
|
||||||
private static final Table<Fight> table = new Table<>(Fight.class);
|
private static final Table<Fight> table = new Table<>(Fight.class);
|
||||||
private static final SelectStatement<Fight> getPage = new SelectStatement<>(table, "SELECT f.*, (b.NodeId IS NULL OR b.AllowReplay) AND (r.NodeId IS NULL OR r.AllowReplay) AS ReplayAllowed FROM Fight f LEFT OUTER JOIN SchematicNode b ON f.BlueSchem = b.NodeId LEFT OUTER JOIN SchematicNode r ON f.RedSchem = r.NodeId ORDER BY FightID DESC LIMIT ?, ?");
|
private static final SelectStatement<Fight> getPage = new SelectStatement<>(table, "SELECT f.*, (b.NodeId IS NULL OR b.Config & 2) AND (r.NodeId IS NULL OR r.Config & 2) AS ReplayAllowed FROM Fight f LEFT OUTER JOIN SchematicNode b ON f.BlueSchem = b.NodeId LEFT OUTER JOIN SchematicNode r ON f.RedSchem = r.NodeId ORDER BY FightID DESC LIMIT ?, ?");
|
||||||
|
private static final SelectStatement<Fight> getById = new SelectStatement<>(table, "SELECT f.*, (b.NodeId IS NULL OR b.Config & 2) AND (r.NodeId IS NULL OR r.Config & 2) AS ReplayAllowed FROM Fight f LEFT OUTER JOIN SchematicNode b ON f.BlueSchem = b.NodeId LEFT OUTER JOIN SchematicNode r ON f.RedSchem = r.NodeId WHERE FightId = ?");
|
||||||
private static final Statement insert = table.insertFields(true, "GameMode", "Server", "StartTime", "Duration", "BlueLeader", "RedLeader", "BlueSchem", "RedSchem", "Win", "WinCondition");
|
private static final Statement insert = table.insertFields(true, "GameMode", "Server", "StartTime", "Duration", "BlueLeader", "RedLeader", "BlueSchem", "RedSchem", "Win", "WinCondition");
|
||||||
private static final Statement updateReplayAvailable = table.update(Table.PRIMARY, "ReplayAvailable");
|
private static final Statement updateReplayAvailable = table.update(Table.PRIMARY, "ReplayAvailable");
|
||||||
|
|
||||||
@@ -51,6 +52,10 @@ public class Fight {
|
|||||||
return fights;
|
return fights;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Fight getById(int fightID) {
|
||||||
|
return getById.select(fightID);
|
||||||
|
}
|
||||||
|
|
||||||
public static int create(String gamemode, String server, Timestamp starttime, int duration, int blueleader, int redleader, Integer blueschem, Integer redschem, int win, String wincondition){
|
public static int create(String gamemode, String server, Timestamp starttime, int duration, int blueleader, int redleader, Integer blueschem, Integer redschem, int win, String wincondition){
|
||||||
return insert.insertGetKey(gamemode, server, starttime, duration, blueleader, redleader, blueschem, redschem, win, wincondition);
|
return insert.insertGetKey(gamemode, server, starttime, duration, blueleader, redleader, blueschem, redschem, win, wincondition);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ public class NodeData {
|
|||||||
@Field(keys = {Table.PRIMARY})
|
@Field(keys = {Table.PRIMARY})
|
||||||
private final int nodeId;
|
private final int nodeId;
|
||||||
|
|
||||||
@Field
|
@Field(keys = {Table.PRIMARY})
|
||||||
private Timestamp createdAt;
|
private Timestamp createdAt;
|
||||||
|
|
||||||
@Field
|
@Field
|
||||||
|
|||||||
@@ -466,16 +466,6 @@ public class SchematicNode {
|
|||||||
setConfig(ConfigFlags.IS_PREPARED, prepared);
|
setConfig(ConfigFlags.IS_PREPARED, prepared);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isInvestigation() {
|
|
||||||
return getConfig(ConfigFlags.INVESTIGATION);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setInvestigation(boolean investigation) {
|
|
||||||
if (isDir())
|
|
||||||
throw new SecurityException("Is Directory");
|
|
||||||
setConfig(ConfigFlags.INVESTIGATION, investigation);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getConfig(ConfigFlags flag) {
|
public boolean getConfig(ConfigFlags flag) {
|
||||||
return (config & (1 << flag.ordinal())) != 0;
|
return (config & (1 << flag.ordinal())) != 0;
|
||||||
}
|
}
|
||||||
@@ -639,7 +629,6 @@ public class SchematicNode {
|
|||||||
public static enum ConfigFlags {
|
public static enum ConfigFlags {
|
||||||
REPLACE_COLOR,
|
REPLACE_COLOR,
|
||||||
ALLOW_REPLAY,
|
ALLOW_REPLAY,
|
||||||
IS_PREPARED,
|
IS_PREPARED
|
||||||
INVESTIGATION,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,13 +54,13 @@ public enum UserPerm {
|
|||||||
emptyPrefix = new Prefix("§7", "");
|
emptyPrefix = new Prefix("§7", "");
|
||||||
p.put(PREFIX_NONE, emptyPrefix);
|
p.put(PREFIX_NONE, emptyPrefix);
|
||||||
p.put(PREFIX_YOUTUBER, new Prefix("§7", "YT"));
|
p.put(PREFIX_YOUTUBER, new Prefix("§7", "YT"));
|
||||||
p.put(PREFIX_GUIDE, new Prefix("§x§E§5§F§F§8§4", "Guide")); // E5FF84
|
p.put(PREFIX_GUIDE, new Prefix("§x§e§7§6§2§e§d", "Guide")); // E762ED
|
||||||
|
|
||||||
p.put(PREFIX_SUPPORTER, new Prefix("§x§6§0§9§5§F§F", "Sup")); // 6095FF
|
p.put(PREFIX_SUPPORTER, new Prefix("§x§6§0§9§5§F§B", "Sup")); // 6095FB
|
||||||
p.put(PREFIX_MODERATOR, new Prefix("§x§F§F§A§2§5§0", "Mod")); // FFA250
|
p.put(PREFIX_MODERATOR, new Prefix("§x§F§F§A§2§5§C", "Mod")); // FFA25C
|
||||||
p.put(PREFIX_BUILDER, new Prefix("§x§6§0§F§F§6§9", "Arch")); // 60FF69
|
p.put(PREFIX_BUILDER, new Prefix("§x§6§0§F§F§6§A", "Arch")); // 60FF6A
|
||||||
p.put(PREFIX_DEVELOPER, new Prefix("§x§0§B§B§C§B§9", "Dev")); // 0BBCB9
|
p.put(PREFIX_DEVELOPER, new Prefix("§x§0§B§B§C§B§3", "Dev")); // 0BBCB3
|
||||||
p.put(PREFIX_ADMIN, new Prefix("§x§F§F§2§B§2§B", "Admin")); // FF2B2B
|
p.put(PREFIX_ADMIN, new Prefix("§x§F§F§2§B§2§4", "Admin")); // FF2B24
|
||||||
prefixes = Collections.unmodifiableMap(p);
|
prefixes = Collections.unmodifiableMap(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -125,7 +125,7 @@ public class GUI {
|
|||||||
}).setCustomModelData(CMDs.Schematic.BACK));
|
}).setCustomModelData(CMDs.Schematic.BACK));
|
||||||
|
|
||||||
if(node.getOwner() == user.getId()){
|
if(node.getOwner() == user.getId()){
|
||||||
if(!node.isDir() && node.getSchemtype().writeable() && !node.isInvestigation()){
|
if(!node.isDir() && node.getSchemtype().writeable()){
|
||||||
CheckedSchematic.getLastDeclinedOfNode(node.getId()).stream().findFirst().ifPresent(checkedSchematic ->
|
CheckedSchematic.getLastDeclinedOfNode(node.getId()).stream().findFirst().ifPresent(checkedSchematic ->
|
||||||
inv.setItem(1, SWItem.getDye(10), (byte) 10, SchematicSystem.MESSAGE.parse("GUI_INFO_STATUS", player, node.getSchemtype().name()), Collections.singletonList(SchematicSystem.MESSAGE.parse("GUI_INFO_STATUS_LORE", player, checkedSchematic.getDeclineReason().replaceAll("&", "§"))), false, click -> {}));
|
inv.setItem(1, SWItem.getDye(10), (byte) 10, SchematicSystem.MESSAGE.parse("GUI_INFO_STATUS", player, node.getSchemtype().name()), Collections.singletonList(SchematicSystem.MESSAGE.parse("GUI_INFO_STATUS_LORE", player, checkedSchematic.getDeclineReason().replaceAll("&", "§"))), false, click -> {}));
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-3
@@ -251,9 +251,7 @@ public class SchematicCommandUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SchematicSystem.MESSAGE.sendPrefixless("UTIL_INFO_FORMAT", player, node.getFileEnding());
|
SchematicSystem.MESSAGE.sendPrefixless("UTIL_INFO_FORMAT", player, node.getFileEnding());
|
||||||
if (!node.isInvestigation()) {
|
CheckedSchematic.getLastDeclinedOfNode(node.getId()).stream().findFirst().ifPresent(checkedSchematic -> SchematicSystem.MESSAGE.sendPrefixless("UTIL_INFO_STATUS", player, checkedSchematic.getEndTime(), checkedSchematic.getDeclineReason()));
|
||||||
CheckedSchematic.getLastDeclinedOfNode(node.getId()).stream().findFirst().ifPresent(checkedSchematic -> SchematicSystem.MESSAGE.sendPrefixless("UTIL_INFO_STATUS", player, checkedSchematic.getEndTime(), checkedSchematic.getDeclineReason()));
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
SchematicSystem.MESSAGE.sendPrefixless("UTIL_INFO_TYPE", player, SchematicSystem.MESSAGE.parse("UTIL_INFO_TYPE_DIR", player));
|
SchematicSystem.MESSAGE.sendPrefixless("UTIL_INFO_TYPE", player, SchematicSystem.MESSAGE.parse("UTIL_INFO_TYPE_DIR", player));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -319,7 +319,6 @@ CHECK_LIST_CHECKING_HOVER=§eTo the reviewer
|
|||||||
CHECK_SCHEMATIC_ALREADY_CHECKING=§cYou are already reviewing a schematic!
|
CHECK_SCHEMATIC_ALREADY_CHECKING=§cYou are already reviewing a schematic!
|
||||||
CHECK_SCHEMATIC_OWN=§cYou cannot review your own schematics.
|
CHECK_SCHEMATIC_OWN=§cYou cannot review your own schematics.
|
||||||
CHECK_SCHEMATIC_OWN_TEAM=§cYou cannot review your team schematics.
|
CHECK_SCHEMATIC_OWN_TEAM=§cYou cannot review your team schematics.
|
||||||
CHECK_SCHEMATIC_INVESTIGATION_PENDING=§cThis schematic is currently under investigation
|
|
||||||
CHECK_SCHEMATIC_PREVIOUS=§7{0} from {1}§8: §e{2}
|
CHECK_SCHEMATIC_PREVIOUS=§7{0} from {1}§8: §e{2}
|
||||||
CHECK_INVALID_RANK=§cUnknown schematic rank.
|
CHECK_INVALID_RANK=§cUnknown schematic rank.
|
||||||
CHECK_ABORT=§aThe test operation was canceled!
|
CHECK_ABORT=§aThe test operation was canceled!
|
||||||
@@ -398,7 +397,7 @@ REPLAY_WINNER=§e§l{0} §7+§e{1}
|
|||||||
REPLAY_SOLO_LOSER=§e{0}
|
REPLAY_SOLO_LOSER=§e{0}
|
||||||
REPLAY_LOSER=§e{0} §7+§e{1}
|
REPLAY_LOSER=§e{0} §7+§e{1}
|
||||||
REPLAY_TIME=§7{0}
|
REPLAY_TIME=§7{0}
|
||||||
REPLAY_SERVER=§7{0}
|
REPLAY_SERVER=§7{0} #{1}
|
||||||
|
|
||||||
#TutorialCommand
|
#TutorialCommand
|
||||||
TUTORIAL_TITLE=Tutorials
|
TUTORIAL_TITLE=Tutorials
|
||||||
|
|||||||
@@ -301,7 +301,6 @@ CHECK_LIST_CHECKING_HOVER=§eZum Prüfer
|
|||||||
CHECK_SCHEMATIC_ALREADY_CHECKING=§cDu prüfst schon eine Schematic!
|
CHECK_SCHEMATIC_ALREADY_CHECKING=§cDu prüfst schon eine Schematic!
|
||||||
CHECK_SCHEMATIC_OWN=§cDu kannst nicht deine eigenen Schematics prüfen.
|
CHECK_SCHEMATIC_OWN=§cDu kannst nicht deine eigenen Schematics prüfen.
|
||||||
CHECK_SCHEMATIC_OWN_TEAM=§cDu kannst nicht Schematics deines Teams prüfen.
|
CHECK_SCHEMATIC_OWN_TEAM=§cDu kannst nicht Schematics deines Teams prüfen.
|
||||||
CHECK_SCHEMATIC_INVESTIGATION_PENDING=§cDiese Schematic wird grade untersucht!
|
|
||||||
CHECK_SCHEMATIC_PREVIOUS=§7{0} von {1}§8: §e{2}
|
CHECK_SCHEMATIC_PREVIOUS=§7{0} von {1}§8: §e{2}
|
||||||
CHECK_INVALID_RANK=§cUnbekannter Schematicrang.
|
CHECK_INVALID_RANK=§cUnbekannter Schematicrang.
|
||||||
CHECK_ABORT=§aDer Prüfvorgang wurde abgebrochen!
|
CHECK_ABORT=§aDer Prüfvorgang wurde abgebrochen!
|
||||||
|
|||||||
@@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2025 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.velocitycore;
|
||||||
|
|
||||||
|
import de.steamwar.data.SyncCommands;
|
||||||
|
import de.steamwar.sql.Event;
|
||||||
|
import de.steamwar.sql.EventFight;
|
||||||
|
import de.steamwar.sql.SteamwarUser;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.*;
|
||||||
|
|
||||||
|
public class BackendSync implements Runnable {
|
||||||
|
private static final Path syncPath = new File("/run/sync").toPath();
|
||||||
|
private final Thread thread;
|
||||||
|
private final WatchService watchService;
|
||||||
|
|
||||||
|
public BackendSync() {
|
||||||
|
try {
|
||||||
|
watchService
|
||||||
|
= FileSystems.getDefault().newWatchService();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new SecurityException("Could not create watch service", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
thread = new Thread(this, "BackendSync");
|
||||||
|
thread.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() {
|
||||||
|
try {
|
||||||
|
watchService.close();
|
||||||
|
thread.join();
|
||||||
|
} catch (IOException | InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleCommand(String name) {
|
||||||
|
try {
|
||||||
|
String[] parts = name.split("\\.");
|
||||||
|
|
||||||
|
switch (parts[0]) {
|
||||||
|
case SyncCommands.RELOAD_EVENT -> EventFight.loadAllComingFights();
|
||||||
|
case SyncCommands.RELOAD_PLAYER -> SteamwarUser.invalidate(Integer.parseInt(parts[1]));
|
||||||
|
default -> VelocityCore.getLogger().warning("Unknown command: " + name);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
VelocityCore.getLogger().throwing(this.getClass().getName(), "handleCommand", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
syncPath.register(watchService,
|
||||||
|
java.nio.file.StandardWatchEventKinds.ENTRY_CREATE);
|
||||||
|
|
||||||
|
WatchKey key;
|
||||||
|
while ((key = watchService.take()) != null) {
|
||||||
|
for (WatchEvent<?> event : key.pollEvents()) {
|
||||||
|
String command = event.context().toString();
|
||||||
|
handleCommand(command);
|
||||||
|
|
||||||
|
if (!VelocityCore.get().getConfig().isEventmode()) {
|
||||||
|
Path path = syncPath.resolve((Path) event.context());
|
||||||
|
Files.delete(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
key.reset();
|
||||||
|
}
|
||||||
|
} catch (InterruptedException | ClosedWatchServiceException ignored) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
} catch (Exception e) {
|
||||||
|
VelocityCore.getLogger().throwing(this.getClass().getName(), "run", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -95,6 +95,7 @@ public class VelocityCore implements ReloadablePlugin {
|
|||||||
private Config config;
|
private Config config;
|
||||||
private ErrorLogger errorLogger;
|
private ErrorLogger errorLogger;
|
||||||
private TablistManager tablistManager;
|
private TablistManager tablistManager;
|
||||||
|
private BackendSync backendSync;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private TeamCommand teamCommand;
|
private TeamCommand teamCommand;
|
||||||
@@ -147,6 +148,8 @@ public class VelocityCore implements ReloadablePlugin {
|
|||||||
new ReplayMod();
|
new ReplayMod();
|
||||||
new FML2();
|
new FML2();
|
||||||
|
|
||||||
|
backendSync = new BackendSync();
|
||||||
|
|
||||||
new ConnectionListener();
|
new ConnectionListener();
|
||||||
new ChatListener();
|
new ChatListener();
|
||||||
new BanListener();
|
new BanListener();
|
||||||
@@ -268,6 +271,8 @@ public class VelocityCore implements ReloadablePlugin {
|
|||||||
logger.log(Level.SEVERE, "Could not shutdown discord bot", e);
|
logger.log(Level.SEVERE, "Could not shutdown discord bot", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
backendSync.stop();
|
||||||
|
|
||||||
if(tablistManager != null)
|
if(tablistManager != null)
|
||||||
tablistManager.disable();
|
tablistManager.disable();
|
||||||
errorLogger.unregister();
|
errorLogger.unregister();
|
||||||
|
|||||||
@@ -99,13 +99,11 @@ public class CheckCommand extends SWCommand {
|
|||||||
for (SchematicNode schematic : schematicList) {
|
for (SchematicNode schematic : schematicList) {
|
||||||
CheckSession current = currentSchems.get(schematic.getId());
|
CheckSession current = currentSchems.get(schematic.getId());
|
||||||
if (current == null) {
|
if (current == null) {
|
||||||
boolean isInvestigation = schematic.isInvestigation();
|
|
||||||
|
|
||||||
sender.prefixless("CHECK_LIST_TO_CHECK",
|
sender.prefixless("CHECK_LIST_TO_CHECK",
|
||||||
isInvestigation ? new Message("PLAIN_STRING", CheckedSchematic.getLastDeclinedOfNode(schematic.getId()).stream().map(CheckedSchematic::getDeclineReason).findFirst().orElse("")) : new Message("CHECK_LIST_TO_CHECK_HOVER"),
|
new Message("CHECK_LIST_TO_CHECK_HOVER"),
|
||||||
isInvestigation ? ClickEvent.suggestCommand("") : ClickEvent.runCommand("/check schematic " + schematic.getId()),
|
ClickEvent.runCommand("/check schematic " + schematic.getId()),
|
||||||
getWaitTime(schematic),
|
getWaitTime(schematic),
|
||||||
schematic.getSchemtype().getKuerzel(), SteamwarUser.get(schematic.getOwner()).getUserName(), (isInvestigation ? "§c" : "") + schematic.getName());
|
schematic.getSchemtype().getKuerzel(), SteamwarUser.get(schematic.getOwner()).getUserName(), schematic.getName());
|
||||||
} else {
|
} else {
|
||||||
sender.prefixless("CHECK_LIST_CHECKING",
|
sender.prefixless("CHECK_LIST_CHECKING",
|
||||||
new Message("CHECK_LIST_CHECKING_HOVER"),
|
new Message("CHECK_LIST_CHECKING_HOVER"),
|
||||||
@@ -132,10 +130,6 @@ public class CheckCommand extends SWCommand {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(schem.isInvestigation() && !sender.user().hasPerm(UserPerm.MODERATION)) {
|
|
||||||
sender.system("CHECK_SCHEMATIC_INVESTIGATION_PENDING");
|
|
||||||
}
|
|
||||||
|
|
||||||
int playerTeam = sender.user().hasPerm(UserPerm.MODERATION) ? 0 : sender.user().getTeam();
|
int playerTeam = sender.user().hasPerm(UserPerm.MODERATION) ? 0 : sender.user().getTeam();
|
||||||
if (playerTeam != 0 && SteamwarUser.get(schem.getOwner()).getTeam() == playerTeam) {
|
if (playerTeam != 0 && SteamwarUser.get(schem.getOwner()).getTeam() == playerTeam) {
|
||||||
sender.system("CHECK_SCHEMATIC_OWN_TEAM");
|
sender.system("CHECK_SCHEMATIC_OWN_TEAM");
|
||||||
@@ -187,22 +181,6 @@ public class CheckCommand extends SWCommand {
|
|||||||
currentCheckers.get(sender.getPlayer().getUniqueId()).decline(String.join(" ", message));
|
currentCheckers.get(sender.getPlayer().getUniqueId()).decline(String.join(" ", message));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register(value = "block")
|
|
||||||
public void investigate(PlayerChatter sender, String... message) {
|
|
||||||
if(notChecking(sender.getPlayer()))
|
|
||||||
return;
|
|
||||||
|
|
||||||
currentCheckers.get(sender.getPlayer().getUniqueId()).investigate(String.join(" ", message));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Register(value = "unblock")
|
|
||||||
public void uninvestigate(PlayerChatter sender) {
|
|
||||||
if(notChecking(sender.getPlayer()))
|
|
||||||
return;
|
|
||||||
|
|
||||||
currentCheckers.get(sender.getPlayer().getUniqueId()).unblock();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<SchematicNode> getSchemsToCheck(){
|
public static List<SchematicNode> getSchemsToCheck(){
|
||||||
List<SchematicNode> schematicList = new ArrayList<>();
|
List<SchematicNode> schematicList = new ArrayList<>();
|
||||||
|
|
||||||
@@ -245,7 +223,7 @@ public class CheckCommand extends SWCommand {
|
|||||||
currentCheckers.put(checker.user().getUUID(), this);
|
currentCheckers.put(checker.user().getUUID(), this);
|
||||||
currentSchems.put(schematic.getId(), this);
|
currentSchems.put(schematic.getId(), this);
|
||||||
|
|
||||||
for(CheckedSchematic previous : CheckedSchematic.getLastDeclinedOfNode(schematic.getId()))
|
for(CheckedSchematic previous : CheckedSchematic.previousChecks(schematic))
|
||||||
checker.prefixless("CHECK_SCHEMATIC_PREVIOUS", previous.getEndTime(), SteamwarUser.get(previous.getValidator()).getUserName(), previous.getDeclineReason());
|
checker.prefixless("CHECK_SCHEMATIC_PREVIOUS", previous.getEndTime(), SteamwarUser.get(previous.getValidator()).getUserName(), previous.getDeclineReason());
|
||||||
next();
|
next();
|
||||||
}).start();
|
}).start();
|
||||||
@@ -331,9 +309,7 @@ public class CheckCommand extends SWCommand {
|
|||||||
private void concludeCheckSession(String reason, SchematicType type, BooleanSupplier sendMessageIsOnline) {
|
private void concludeCheckSession(String reason, SchematicType type, BooleanSupplier sendMessageIsOnline) {
|
||||||
if(SchematicNode.getSchematicNode(schematic.getId()) != null) {
|
if(SchematicNode.getSchematicNode(schematic.getId()) != null) {
|
||||||
CheckedSchematic.create(schematic, checker.user().getId(), startTime, Timestamp.from(Instant.now()), reason, sendMessageIsOnline.getAsBoolean());
|
CheckedSchematic.create(schematic, checker.user().getId(), startTime, Timestamp.from(Instant.now()), reason, sendMessageIsOnline.getAsBoolean());
|
||||||
|
|
||||||
if(type != null) {
|
if(type != null) {
|
||||||
schematic.setInvestigation(false);
|
|
||||||
schematic.setSchemtype(type);
|
schematic.setSchemtype(type);
|
||||||
if (type == SchematicType.Normal) {
|
if (type == SchematicType.Normal) {
|
||||||
schematic.setPrepared(false);
|
schematic.setPrepared(false);
|
||||||
@@ -353,15 +329,5 @@ public class CheckCommand extends SWCommand {
|
|||||||
currentCheckers.remove(checker.user().getUUID());
|
currentCheckers.remove(checker.user().getUUID());
|
||||||
currentSchems.remove(schematic.getId());
|
currentSchems.remove(schematic.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void investigate(String reason) {
|
|
||||||
schematic.setInvestigation(true);
|
|
||||||
concludeCheckSession(reason, null, () -> true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void unblock() {
|
|
||||||
schematic.setInvestigation(false);
|
|
||||||
CheckedSchematic.create(schematic, checker.user().getId(), startTime, Timestamp.from(Instant.now()), "", true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,31 +38,51 @@ public class ReplayCommand extends SWCommand {
|
|||||||
super("replay");
|
super("replay");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Register
|
||||||
|
public void genericCommand(PlayerChatter sender, int replayId, @StaticValue(value = {"", "-a"}, allowISE=true) @OptionalValue("") boolean isAdmin, @OptionalValue("") String optionalMap) {
|
||||||
|
Fight fight = Fight.getById(replayId);
|
||||||
|
|
||||||
|
if (fight == null) {
|
||||||
|
sender.system("REPLAY_UNAVAILABLE");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
startReplay(sender, isAdmin, optionalMap, fight);
|
||||||
|
}
|
||||||
|
|
||||||
@Register
|
@Register
|
||||||
public void genericCommand(PlayerChatter sender, @OptionalValue("") String optionalMap) {
|
public void genericCommand(PlayerChatter sender, @OptionalValue("") String optionalMap) {
|
||||||
if (PunishmentCommand.isPunishedWithMessage(sender, Punishment.PunishmentType.NoFightServer))
|
if (PunishmentCommand.isPunishedWithMessage(sender, Punishment.PunishmentType.NoFightServer))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
new SWStreamInv<>(sender, new Message("REPLAY_TITLE"), (click, fight) -> {
|
new SWStreamInv<>(sender, new Message("REPLAY_TITLE"), (click, fight) -> {
|
||||||
ArenaMode mode = ArenaMode.getBySchemType(fight.getSchemType());
|
startReplay(sender, click.isShiftClick(), optionalMap, fight);
|
||||||
ServerStarter starter = new ServerStarter().replay(fight.getFightID()).blueLeader(sender.getPlayer());
|
|
||||||
|
|
||||||
String map = mode.getRandomMap();
|
|
||||||
if (!optionalMap.equals("")) {
|
|
||||||
String tMap = mode.hasMap(optionalMap);
|
|
||||||
if (tMap != null) map = tMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sender.user().hasPerm(UserPerm.MODERATION) && click.isShiftClick() && fight.replayExists()) {
|
|
||||||
starter.test(mode, map, sender.getPlayer()).start();
|
|
||||||
} else if(!fight.replayAllowed()) {
|
|
||||||
sender.system("REPLAY_UNAVAILABLE");
|
|
||||||
} else {
|
|
||||||
starter.arena(mode, map).start();
|
|
||||||
}
|
|
||||||
}, page -> Fight.getPage(page, 45).stream().map(fight -> new SWListInv.SWListEntry<>(getFightItem(fight), fight)).toList()).open();
|
}, page -> Fight.getPage(page, 45).stream().map(fight -> new SWListInv.SWListEntry<>(getFightItem(fight), fight)).toList()).open();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void startReplay(PlayerChatter sender, boolean isAdmin, String optionalMap, Fight fight) {
|
||||||
|
if (PunishmentCommand.isPunishedWithMessage(sender, Punishment.PunishmentType.NoFightServer))
|
||||||
|
return;
|
||||||
|
|
||||||
|
ArenaMode mode = ArenaMode.getBySchemType(fight.getSchemType());
|
||||||
|
ServerStarter starter = new ServerStarter().replay(fight.getFightID()).blueLeader(sender.getPlayer());
|
||||||
|
|
||||||
|
String map = mode.getRandomMap();
|
||||||
|
if (!optionalMap.isEmpty()) {
|
||||||
|
String tMap = mode.hasMap(optionalMap);
|
||||||
|
if (tMap != null) map = tMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sender.user().hasPerm(UserPerm.MODERATION) && isAdmin && fight.replayExists()) {
|
||||||
|
System.out.println("Starting admin replay");
|
||||||
|
starter.test(mode, map, sender.getPlayer()).start();
|
||||||
|
} else if(!fight.replayAllowed()) {
|
||||||
|
sender.system("REPLAY_UNAVAILABLE");
|
||||||
|
} else {
|
||||||
|
starter.arena(mode, map).start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private SWItem getFightItem(Fight fight) {
|
private SWItem getFightItem(Fight fight) {
|
||||||
SchematicType type = fight.getSchemType();
|
SchematicType type = fight.getSchemType();
|
||||||
SWItem item = new SWItem(type != null ? type.getMaterial() : "BARRIER", parseLeader(fight.getBlueLeader(), fight.getBluePlayers().size(), fight.getWin() == 1));
|
SWItem item = new SWItem(type != null ? type.getMaterial() : "BARRIER", parseLeader(fight.getBlueLeader(), fight.getBluePlayers().size(), fight.getWin() == 1));
|
||||||
@@ -71,7 +91,7 @@ public class ReplayCommand extends SWCommand {
|
|||||||
lore.add(parseLeader(fight.getRedLeader(), fight.getRedPlayers().size(), fight.getWin() == 2));
|
lore.add(parseLeader(fight.getRedLeader(), fight.getRedPlayers().size(), fight.getWin() == 2));
|
||||||
lore.add(new Message("REPLAY_TIME", fight.getStartTime()));
|
lore.add(new Message("REPLAY_TIME", fight.getStartTime()));
|
||||||
lore.add(new Message("SPACER"));
|
lore.add(new Message("SPACER"));
|
||||||
lore.add(new Message("REPLAY_SERVER", fight.getServer()));
|
lore.add(new Message("REPLAY_SERVER", fight.getServer(), Integer.toString(fight.getFightID())));
|
||||||
if(!fight.replayAllowed())
|
if(!fight.replayAllowed())
|
||||||
lore.add(new Message("REPLAY_UNAVAILABLE"));
|
lore.add(new Message("REPLAY_UNAVAILABLE"));
|
||||||
item.setLore(lore);
|
item.setLore(lore);
|
||||||
|
|||||||
@@ -333,7 +333,7 @@ public class TeamCommand extends SWCommand {
|
|||||||
Team tm = all.get(i);
|
Team tm = all.get(i);
|
||||||
|
|
||||||
sender.prefixless("TEAM_LIST_TEAM", new Message("TEAM_LIST_TEAM_HOVER"),
|
sender.prefixless("TEAM_LIST_TEAM", new Message("TEAM_LIST_TEAM_HOVER"),
|
||||||
ClickEvent.runCommand("/team info " + tm.getTeamKuerzel()), tm.getTeamColor(), tm.getTeamKuerzel(), tm.getTeamName());
|
ClickEvent.runCommand("/team info " + tm.getTeamName()), tm.getTeamColor(), tm.getTeamKuerzel(), tm.getTeamName());
|
||||||
}
|
}
|
||||||
|
|
||||||
Component beforePage = Component
|
Component beforePage = Component
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ public class WhoisCommand extends SWCommand {
|
|||||||
|
|
||||||
sender.system("WHOIS_USERNAME", user.getUserName());
|
sender.system("WHOIS_USERNAME", user.getUserName());
|
||||||
sender.system("WHOIS_PREFIX", user.prefix().getColorCode() + user.prefix().getChatPrefix());
|
sender.system("WHOIS_PREFIX", user.prefix().getColorCode() + user.prefix().getChatPrefix());
|
||||||
sender.system("WHOIS_TEAM", new Message("WHOIS_TEAM_HOVER", team.getTeamName()), ClickEvent.runCommand("/team info " + team.getTeamKuerzel()), team.getTeamColor(), team.getTeamKuerzel(), team.getTeamName());
|
sender.system("WHOIS_TEAM", new Message("WHOIS_TEAM_HOVER", team.getTeamName()), ClickEvent.runCommand("/team info " + team.getTeamName()), team.getTeamColor(), team.getTeamKuerzel(), team.getTeamName());
|
||||||
|
|
||||||
if (!sender.user().hasPerm(UserPerm.TEAM))
|
if (!sender.user().hasPerm(UserPerm.TEAM))
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -338,7 +338,8 @@ public class PluginMessage extends BasicListener {
|
|||||||
"frozenlib:moving_restriction_sound_packet", "frozenlib:remove_entity_screen_shakes_packet",
|
"frozenlib:moving_restriction_sound_packet", "frozenlib:remove_entity_screen_shakes_packet",
|
||||||
"frozenlib:remove_screen_shakes_packet", "frozenlib:screen_shake_entity_packet",
|
"frozenlib:remove_screen_shakes_packet", "frozenlib:screen_shake_entity_packet",
|
||||||
"frozenlib:screen_shake_packet", "frozenlib:spotting_icon_packet", "frozenlib:wind_disturbance_packet",
|
"frozenlib:screen_shake_packet", "frozenlib:spotting_icon_packet", "frozenlib:wind_disturbance_packet",
|
||||||
"frozenlib:spotting_icon_remove_packet", "frozenlib:starting_moving_restriction_looping_sound_packet"
|
"frozenlib:spotting_icon_remove_packet", "frozenlib:starting_moving_restriction_looping_sound_packet",
|
||||||
|
"imm_ptl:remote_cts" //https://www.curseforge.com/minecraft/mc-mods/immersive-portals-mod
|
||||||
))
|
))
|
||||||
channelRegisterHandlers.put(channel, player -> {});
|
channelRegisterHandlers.put(channel, player -> {});
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2025 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.data
|
||||||
|
|
||||||
|
import de.steamwar.sql.SteamwarUser
|
||||||
|
import java.io.File
|
||||||
|
import java.nio.file.Files
|
||||||
|
|
||||||
|
object VelocitySync {
|
||||||
|
private const val SYNC_PATH = "/run/sync"
|
||||||
|
private val SYNC_FILE = File(SYNC_PATH)
|
||||||
|
private val isWindows = System.getProperty("os.name").lowercase().contains("win")
|
||||||
|
private val lastSendMap = mutableMapOf<String, Long>()
|
||||||
|
|
||||||
|
private fun sendCommand(command: String, vararg args: String) {
|
||||||
|
if (isWindows) { return }
|
||||||
|
|
||||||
|
val name = command + if (args.isNotEmpty()) "." + args.joinToString(".") else ""
|
||||||
|
|
||||||
|
if (lastSendMap[name] != null || lastSendMap[name]!! > System.currentTimeMillis() - 1000) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
lastSendMap[name] = System.currentTimeMillis()
|
||||||
|
|
||||||
|
Files.createFile(File(SYNC_FILE, name).toPath())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun reloadEvent() = sendCommand(SyncCommands.RELOAD_EVENT)
|
||||||
|
|
||||||
|
fun reloadPlayer(user: SteamwarUser) = sendCommand(SyncCommands.RELOAD_PLAYER, user.id.toString())
|
||||||
|
}
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
package de.steamwar.routes
|
package de.steamwar.routes
|
||||||
|
|
||||||
import de.steamwar.ResponseError
|
import de.steamwar.ResponseError
|
||||||
|
import de.steamwar.data.VelocitySync
|
||||||
import de.steamwar.sql.*
|
import de.steamwar.sql.*
|
||||||
import io.ktor.http.*
|
import io.ktor.http.*
|
||||||
import io.ktor.server.application.*
|
import io.ktor.server.application.*
|
||||||
@@ -112,6 +113,7 @@ fun Route.configureEventFightRoutes() {
|
|||||||
if (fight.group != null) {
|
if (fight.group != null) {
|
||||||
eventFight.setGroup(fight.group)
|
eventFight.setGroup(fight.group)
|
||||||
}
|
}
|
||||||
|
VelocitySync.reloadEvent()
|
||||||
call.respond(HttpStatusCode.Created, ResponseEventFight(eventFight))
|
call.respond(HttpStatusCode.Created, ResponseEventFight(eventFight))
|
||||||
}
|
}
|
||||||
route("/{fight}") {
|
route("/{fight}") {
|
||||||
@@ -143,11 +145,13 @@ fun Route.configureEventFightRoutes() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fight.update(start, spielmodus, map, teamBlue, teamRed, spectatePort)
|
fight.update(start, spielmodus, map, teamBlue, teamRed, spectatePort)
|
||||||
|
VelocitySync.reloadEvent()
|
||||||
call.respond(HttpStatusCode.OK, ResponseEventFight(fight))
|
call.respond(HttpStatusCode.OK, ResponseEventFight(fight))
|
||||||
}
|
}
|
||||||
delete {
|
delete {
|
||||||
val fight = call.receiveFight() ?: return@delete
|
val fight = call.receiveFight() ?: return@delete
|
||||||
fight.delete()
|
fight.delete()
|
||||||
|
VelocitySync.reloadEvent()
|
||||||
call.respond(HttpStatusCode.OK)
|
call.respond(HttpStatusCode.OK)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
package de.steamwar.routes
|
package de.steamwar.routes
|
||||||
|
|
||||||
|
import de.steamwar.data.VelocitySync
|
||||||
import de.steamwar.plugins.SWPermissionCheck
|
import de.steamwar.plugins.SWPermissionCheck
|
||||||
import de.steamwar.plugins.getUser
|
import de.steamwar.plugins.getUser
|
||||||
import de.steamwar.sql.SteamwarUser
|
import de.steamwar.sql.SteamwarUser
|
||||||
@@ -86,6 +87,8 @@ fun Route.configureUserPerms() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
UserPerm.addPerm(user, UserPerm.entries.find { it == prefix }!!)
|
UserPerm.addPerm(user, UserPerm.entries.find { it == prefix }!!)
|
||||||
|
|
||||||
|
VelocitySync.reloadPlayer(user)
|
||||||
call.respond(HttpStatusCode.Accepted)
|
call.respond(HttpStatusCode.Accepted)
|
||||||
}
|
}
|
||||||
put("/{perm}") {
|
put("/{perm}") {
|
||||||
@@ -96,6 +99,8 @@ fun Route.configureUserPerms() {
|
|||||||
call.respond(HttpStatusCode.Accepted)
|
call.respond(HttpStatusCode.Accepted)
|
||||||
return@put
|
return@put
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VelocitySync.reloadPlayer(user)
|
||||||
call.respond(HttpStatusCode.NoContent)
|
call.respond(HttpStatusCode.NoContent)
|
||||||
}
|
}
|
||||||
delete("/{perm}") {
|
delete("/{perm}") {
|
||||||
@@ -106,6 +111,8 @@ fun Route.configureUserPerms() {
|
|||||||
call.respond(HttpStatusCode.Accepted)
|
call.respond(HttpStatusCode.Accepted)
|
||||||
return@delete
|
return@delete
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VelocitySync.reloadPlayer(user)
|
||||||
call.respond(HttpStatusCode.NoContent)
|
call.respond(HttpStatusCode.NoContent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user