SteamWar/BungeeCore
Archiviert
13
2

Ban System Rework #150

Manuell gemergt
Lixfel hat 38 Commits von ban-rework nach master 2021-01-30 08:42:35 +01:00 zusammengeführt
10 geänderte Dateien mit 189 neuen und 57 gelöschten Zeilen
Nur Änderungen aus Commit 986b53fbf8 werden angezeigt - Alle Commits anzeigen

Datei anzeigen

@ -54,7 +54,7 @@ public class BungeeCore extends Plugin {
public static final String SERVER_TEAMCHAT_PREFIX = "§8STC §e";
public static final String TEAMCHAT_PREFIX = "§8TC §e";
public static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("dd.MM.yyyy");
public static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("HH:mm dd.MM.yyyy");
Veraltet
Review

Ich glaube, Datum Uhrzeit statt Uhrzeit Datum wäre grammatikalisch besser.

Ich glaube, Datum Uhrzeit statt Uhrzeit Datum wäre grammatikalisch besser.
public static String CHAT_PREFIX;
public static String WORLD_FOLDER;

Datei anzeigen

@ -22,6 +22,7 @@ package de.steamwar.bungeecore.commands;
import de.steamwar.bungeecore.BungeeCore;
import de.steamwar.bungeecore.sql.SteamwarUser;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.sql.Timestamp;
import java.text.ParseException;
@ -56,12 +57,12 @@ public class BanCommand extends BasicCommand {
}
String msg = banReason.toString();
Veraltet
Review

Wenn du das ganze Team benachrichtigst, brauchst du nicht mehr den Spieler persönlich zu benachrichtigen.

Wenn du das ganze Team benachrichtigst, brauchst du nicht mehr den Spieler persönlich zu benachrichtigen.
BungeeCore.send(sender, BungeeCore.CHAT_PREFIX + "Du hast " + target.getUserName() + " gebannt. Grund: §c" + msg);
Veraltet
Review

In internen Messages musst du nicht die Person colorcoden.

In internen Messages musst du nicht die Person colorcoden.
Veraltet
Review

Ok, das gefällt mir doch nicht so ganz mit dem IntArray etc. Evtl. wäre es eleganter, man macht da etwas a la new Message(...equals() ? "BAN_PERMA": "BAN_UNTIL") und wenn das object eine Message ist, (welche sich einfach nur zu merken Braucht, welchen String sie hat, ggf. auch noch parameter) und dann diese Message parst und den String entsprechend einfügt.

Ok, das gefällt mir doch nicht so ganz mit dem IntArray etc. Evtl. wäre es eleganter, man macht da etwas a la new Message(...equals() ? "BAN_PERMA": "BAN_UNTIL") und wenn das object eine Message ist, (welche sich einfach nur zu merken Braucht, welchen String sie hat, ggf. auch noch parameter) und dann diese Message parst und den String entsprechend einfügt.
target.ban(banTime, msg);
target.ban(banTime, msg, SteamwarUser.get(sender.getName()).getId(), args[1].equalsIgnoreCase("perma"));
Veraltet
Review

Bitte erst die Aktion ausführen, dann die Aktion verkünden (im Fehlerfall kein Fehlannouncement).

Bitte erst die Aktion ausführen, dann die Aktion verkünden (im Fehlerfall kein Fehlannouncement).
}
public static Timestamp parseTime(CommandSender sender, String arg){
if(arg.equalsIgnoreCase("perma")) {
return Timestamp.from(Instant.ofEpochSecond(946674800));
return Timestamp.from(Instant.ofEpochSecond(946684800));
}else{
SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy_HH:mm");
try{

Datei anzeigen

@ -24,6 +24,7 @@ import de.steamwar.bungeecore.sql.SteamwarUser;
import net.md_5.bungee.api.CommandSender;
import java.sql.Timestamp;
import java.time.Instant;
public class MuteCommand extends BasicCommand {
@ -52,6 +53,6 @@ public class MuteCommand extends BasicCommand {
}
String msg = muteReason.toString();
BungeeCore.send(sender, BungeeCore.CHAT_PREFIX + "Du hast " + target.getUserName() + " gemuted. Grund: §c" + msg);
Veraltet
Review

Hier genauso.

Hier genauso.
target.mute(muteTime, msg);
target.mute(muteTime, msg, SteamwarUser.get(sender.getName()).getId(), args[1].equalsIgnoreCase("perma"));
Veraltet
Review

Hier genauso.

Hier genauso.
}
}

Datei anzeigen

@ -22,6 +22,7 @@ package de.steamwar.bungeecore.commands;
import de.steamwar.bungeecore.BungeeCore;
import de.steamwar.bungeecore.sql.SteamwarUser;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.sql.Timestamp;
import java.util.Date;
@ -44,6 +45,6 @@ public class UnbanCommand extends BasicCommand {
return;
BungeeCore.send(sender, BungeeCore.CHAT_PREFIX + "Du hast " + target.getUserName() + " entbannt.");
target.ban(Timestamp.from(new Date().toInstant()), "");
target.ban(Timestamp.from(new Date().toInstant()), "Unban", SteamwarUser.get(sender.getName()).getId(), false);
}
}

Datei anzeigen

@ -20,6 +20,7 @@
package de.steamwar.bungeecore.commands;
import de.steamwar.bungeecore.BungeeCore;
import de.steamwar.bungeecore.sql.Punishment;
import de.steamwar.bungeecore.sql.SteamwarUser;
import de.steamwar.bungeecore.sql.Team;
import net.md_5.bungee.api.CommandSender;
@ -70,11 +71,10 @@ public class WhoisCommand extends BasicCommand {
Team team = Team.get(user.getTeam());
BungeeCore.send(player, "§7Team§8: §e" + team.getTeamName());
if(user.isBanned()){
player.sendMessage(user.banMessage());
}
if(user.isMuted()){
player.sendMessage(user.muteMessage());
BungeeCore.send(player, "§7Bestrafungen: ");
Veraltet
Review

Strafen

Strafen
for (Punishment punishment : Punishment.getAllPunishmentsByPlayer(user.getId())) {
BungeeCore.send(player, "§7" + SteamwarUser.get(punishment.getPunisher()).getUserName() + "§8» §f§l" + punishment.getType().name() + ": §e"
+ punishment.getStartTime().toLocalDateTime().format(BungeeCore.DATE_FORMAT) + " - " + (punishment.isPerma()?"Perma":punishment.getEndTime().toLocalDateTime().format(BungeeCore.DATE_FORMAT)) + " §c" + punishment.getReason());
Veraltet
Review

Wenn wir die Mute & Bannsachen schon Multilingual haben, sollten wir auch das Multilingual machen. Um das Timestamp-Formatting müsste sich dann glaube ich auch das ML-Framework kümmern.

Wenn wir die Mute & Bannsachen schon Multilingual haben, sollten wir auch das Multilingual machen. Um das Timestamp-Formatting müsste sich dann glaube ich auch das ML-Framework kümmern.
Veraltet
Review

Dafür wurden wir dann ein Cache wo wir die Sprache speichern könnten, weil sonst müsste man dies von dem gemacht, der den Spieler bannt

Dafür wurden wir dann ein Cache wo wir die Sprache speichern könnten, weil sonst müsste man dies von dem gemacht, der den Spieler bannt
Veraltet
Review

Hier in dem Fall ist das Ziel klar player. Und player hat eine Sprache. Den Cache bräuchten wir wenn für den BanListener, aber nicht hier. Daher kann das schon mit umgezogen werden.

Hier in dem Fall ist das Ziel klar player. Und player hat eine Sprache. Den Cache bräuchten wir wenn für den BanListener, aber nicht hier. Daher kann das schon mit umgezogen werden.
}
Veraltet
Review

Da kannste aber auch mal aufs Multilinguale-System zurückgreifen

Da kannste aber auch mal aufs Multilinguale-System zurückgreifen
}
}

Datei anzeigen

@ -47,6 +47,15 @@ public class BanListener extends BasicListener {
List<BannedUserIPs> ips = BannedUserIPs.get(event.getConnection().getAddress().getAddress().getHostAddress());
if(!ips.isEmpty()){
if(ips.stream().anyMatch(bannedUserIPs -> bannedUserIPs.getUserID() == user.getId())) {
ips.forEach(bannedUserIPs -> {
if(bannedUserIPs.getUserID() == user.getId())
bannedUserIPs.remove();
});
ips.removeIf(bannedUserIPs -> bannedUserIPs.getUserID() == user.getId());
if(ips.isEmpty())
return;
}
Veraltet
Review

Was soll der Schmarrn und das Rausentfernen der ganzen immer noch gültigen Werte?

Was soll der Schmarrn und das Rausentfernen der ganzen immer noch gültigen Werte?
Veraltet
Review

Die Einträge die da Entfernt werden sind, wenn der Joinende Spieler, welcher nicht gebannt ist, dieselbe IP hat wie einer der Einträge. Dann ist dieser Eintrag für mich ungültig, weil der Spieler kommt ja drauf, wieso sollte er dann noch IPBanned sein?

Die Einträge die da Entfernt werden sind, wenn der Joinende Spieler, welcher nicht gebannt ist, dieselbe IP hat wie einer der Einträge. Dann ist dieser Eintrag für mich ungültig, weil der Spieler kommt ja drauf, wieso sollte er dann noch IPBanned sein?
Veraltet
Review

Weil ggf. gerade kein Teammitglied online ist, was die Situation bewerten kann? Wenn er entbannt wird/der Bann ausgelaufen ist), dann werden die IPs gelöscht, vorher nicht (VPNs etc.).

Weil ggf. gerade kein Teammitglied online ist, was die Situation bewerten kann? Wenn er entbannt wird/der Bann ausgelaufen ist), dann werden die IPs gelöscht, vorher nicht (VPNs etc.).
Veraltet
Review

Sofern in der ips Liste sich ein Spieler mit der ID vom grade beigetretener Spieler befindet wird dieser aus der Liste entfernt, weil dieser kann ja wieder darauf spielen, warum sollte man den dann noch einen nicht gebannten Spieler in der List lassen?

Sofern in der ips Liste sich ein Spieler mit der ID vom grade beigetretener Spieler befindet wird dieser aus der Liste entfernt, weil dieser kann ja wieder darauf spielen, warum sollte man den dann noch einen nicht gebannten Spieler in der List lassen?
Veraltet
Review

Das macht bereits ein anderes Codestück, die IPs nach einer Entbannung zu entfernen.

Das macht bereits ein anderes Codestück, die IPs nach einer Entbannung zu entfernen.
StringBuilder potentialBan = new StringBuilder();
potentialBan.append(BungeeCore.CHAT_PREFIX);
potentialBan.append("§cMögliche Bannumgehung durch §r");

Datei anzeigen

@ -74,7 +74,7 @@ class Utils {
if(max == ModType.YELLOW)
player.disconnect(BungeeCore.stringToText("§7Deaktiviere den Mod §e" + mods.get(0).getModName() + "§7, um weiter auf §eSteam§8War §7spielen zu können."));
else{
user.ban(Timestamp.from(Instant.now().plus(7, ChronoUnit.DAYS)), "Versuchte Benutzung des Mods " + mods.get(0).getModName());
user.ban(Timestamp.from(Instant.now().plus(7, ChronoUnit.DAYS)), "Versuchte Benutzung des Mods " + mods.get(0).getModName(), 0, false);
Veraltet
Review

Bitte ML

Bitte ML
BungeeCore.log(Level.SEVERE, user.getUserName() + " " + user.getId() + " wurde automatisch wegen des Mods " + mods.get(0).getModName() + " gebannt.");
}
}else{
@ -84,7 +84,7 @@ class Utils {
if(max == ModType.YELLOW)
player.disconnect(BungeeCore.stringToText("§7Deaktiviere die Mods\n§e" + sb.toString() + "§7um weiter auf §eSteam§8War §7spielen zu können."));
else{
user.ban(Timestamp.from(Instant.now().plus(7, ChronoUnit.DAYS)), "Versuchte Benutzung der Mods\n" + sb.toString());
user.ban(Timestamp.from(Instant.now().plus(7, ChronoUnit.DAYS)), "Versuchte Benutzung der Mods\n" + sb.toString(), 0, false);
Veraltet
Review

Bitte ML

Bitte ML
BungeeCore.log(Level.SEVERE, user.getUserName() + " " + user.getId() + " wurde automatisch wegen der Mods " + sb.toString() + " gebannt.");
}
}

Datei anzeigen

@ -78,4 +78,8 @@ public class BannedUserIPs {
public java.sql.Timestamp getTimestamp() {
return timestamp;
}
public void remove() {
SQL.update("DELETE FROM BannedUserIPs WHERE UserID = ?", userID);
}
}

Datei anzeigen

@ -0,0 +1,141 @@
/*
This file is a part of the SteamWar software.
Copyright (C) 2020 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.bungeecore.sql;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.*;
import java.util.stream.Collectors;
public class Punishment {
public static Punishment getPunishmentByPlayer(int user, PunishmentType type) {
ResultSet set = SQL.select("SELECT * FROM `Punishments` WHERE `PunishmentId` IN (SELECT MAX(`PunishmentId`) FROM Punishments WHERE UserId = ? AND Type = ?)", user, type.toDb());
Veraltet
Review

Rekursive SELECT-Statements sind ein Performancekiller & du bekommst ggf. ein veraltetes Punishment zurück. Nutze doch lieber WHERE EndTime < NOW() AND UserId = ? AND Type = ? LIMIT 1

Rekursive SELECT-Statements sind ein Performancekiller & du bekommst ggf. ein veraltetes Punishment zurück. Nutze doch lieber WHERE EndTime < NOW() AND UserId = ? AND Type = ? LIMIT 1
Veraltet
Review

Das Problem ist, dass man hier ggf. ein älteres bereits überschriebenes Punishment zurückbekommt.
Und es soll ja so sein, dass immer das letzte Punishment genommen wird.

Das Problem ist, dass man hier ggf. ein älteres bereits überschriebenes Punishment zurückbekommt. Und es soll ja so sein, dass immer das letzte Punishment genommen wird.
Veraltet
Review

Also: Das ändert nichts am Sachverhalt. Was für einen Sinn hat es, das Letzte zu bekommen? Nur weil dann eine weitere Strafe dazukommt, soll die alte Ungültig sein?!? (PS: Das geht einfach mit einem ORDER BY und LIMIT, du brauchst da kein recursive SELECT)

Also: Das ändert nichts am Sachverhalt. Was für einen Sinn hat es, das Letzte zu bekommen? Nur weil dann eine weitere Strafe dazukommt, soll die alte Ungültig sein?!? (PS: Das geht einfach mit einem ORDER BY und LIMIT, du brauchst da kein recursive SELECT)
Veraltet
Review

Der Sinn den Letzten zu bekommen ist, dass ich so die Alte EndTime behalten kann und somit bei einem remute oder Bann der alte überschrieben wird.

Der Sinn den Letzten zu bekommen ist, dass ich so die Alte EndTime behalten kann und somit bei einem remute oder Bann der alte überschrieben wird.
Veraltet
Review

Nein, das macht keinen Sinn, denn dann änderst du ja trotzdem den alten Mute oder Bann (indem du ihn invalidierst), nur wird das so nicht in der Datenbank vermerkt, dass die Mute/Bannzeit dann durch das Überschreiben automatisch geändert wurde. Das ist mein Problem damit. Zudem sollte meiner Meinung nach der Längere (mit weiter entfernterer EndTime) Mute/Bann Priorität über andere Mutes/Banns haben.

Nein, das macht keinen Sinn, denn dann änderst du ja trotzdem den alten Mute oder Bann (indem du ihn invalidierst), nur wird das so nicht in der Datenbank vermerkt, dass die Mute/Bannzeit dann durch das Überschreiben automatisch geändert wurde. Das ist mein Problem damit. Zudem sollte meiner Meinung nach der Längere (mit weiter entfernterer EndTime) Mute/Bann Priorität über andere Mutes/Banns haben.
Veraltet
Review

Also ich habe mir das System so überlegt: Ich mache einen Mute/Bann und dieser kann dann später von irgendjemanden mit einem erneuten Mute/Bann verkürzt oder entfernt werden, wobei als der aktuelle Mute/Bann immer der neuste genommen wird und nicht der längste, weil der Plan mit dieser Tabelle ist ja das alles auch Protokolliert wird. Und weshalb will ich immer den Aktuellsten brauch.

Also ich habe mir das System so überlegt: Ich mache einen Mute/Bann und dieser kann dann später von irgendjemanden mit einem erneuten Mute/Bann verkürzt oder entfernt werden, wobei als der aktuelle Mute/Bann immer der neuste genommen wird und nicht der längste, weil der Plan mit dieser Tabelle ist ja das alles auch Protokolliert wird. Und weshalb will ich immer den Aktuellsten brauch.
Veraltet
Review

Dann möchte ich, dass du dann die EndZeit des vorherigen Banns dann auf die StartZeit des neuen Banns setzt, damit das auch für sich so korrekt protokolliert ist, und nicht, dass dann über irgendeine ID das ganze Sortiert wird, wenn du bereits einen StartTimestamp hast (nach dem du i.ü. auch sortieren könntest).

Dann möchte ich, dass du dann die EndZeit des vorherigen Banns dann auf die StartZeit des neuen Banns setzt, damit das auch für sich so korrekt protokolliert ist, und nicht, dass dann über irgendeine ID das ganze Sortiert wird, wenn du bereits einen StartTimestamp hast (nach dem du i.ü. auch sortieren könntest).
Veraltet
Review

Nein genau das möchte ich nicht. Ich möchte gerne im nachhinein sehen, wie lange er eigentlich gemutet oder gebannt war. Mit deiner Lösung würdest du Daten, welche wichtig sind und wichtig zum entscheiden über neue Banns/Mutes verändert, womit diese eh nicht mehr aussagekräftig sind!

Nein genau das möchte ich nicht. Ich möchte gerne im nachhinein sehen, wie lange er eigentlich gemutet oder gebannt war. Mit deiner Lösung würdest du Daten, welche wichtig sind und wichtig zum entscheiden über neue Banns/Mutes verändert, womit diese eh nicht mehr aussagekräftig sind!
Veraltet
Review

Nein, weil er war ja dann nicht mehr so lange gebannt/gemutet! Die Daten sind damit faktisch verändert worden, nur steht dass dann nicht mehr in der Datenbank! Sein Bann/Mute war solange angedacht, aber dann ja verkürzt worden! Entweder also es wird der längste Bann genommen, oder der neuste Bann verändert ggf. den letzten älteren Bann.

Nein, weil er war ja dann nicht mehr so lange gebannt/gemutet! Die Daten sind damit faktisch verändert worden, nur steht dass dann nicht mehr in der Datenbank! Sein Bann/Mute war solange angedacht, aber dann ja verkürzt worden! Entweder also es wird der längste Bann genommen, oder der neuste Bann verändert ggf. den letzten älteren Bann.
Veraltet
Review

Aktuelles Problem: Der Perma Ban Timestamp ist vor allen anderen, das macht mir das Selecten des Aktiven Banns um einiger Schwieriger-.

Aktuelles Problem: Der Perma Ban Timestamp ist vor allen anderen, das macht mir das Selecten des Aktiven Banns um einiger Schwieriger-.
try {
if(!set.next())
return null;
return new Punishment(set);
} catch (SQLException throwable) {
throwable.printStackTrace();
Veraltet
Review

Nicht extra den Stacktrace "printen", das passiert automatisch bei der Fehlermeldung & ist dann auch richtig als [ERROR] markiert. S o spammst du nur die Konsole zu

Nicht extra den Stacktrace "printen", das passiert automatisch bei der Fehlermeldung & ist dann auch richtig als [ERROR] markiert. S o spammst du nur die Konsole zu
throw new SecurityException("Could not Load Punishments", throwable);
}
}
public static Map<PunishmentType, Punishment> getPunishmentsByPlayer(int user) {
ResultSet set = SQL.select("SELECT * FROM `Punishments` WHERE `PunishmentId` IN (SELECT MAX(`PunishmentId`) FROM Punishments WHERE UserId = ? GROUP BY Type)", user);
Veraltet
Review

Siehe oben.

Siehe oben.
try {
Map<PunishmentType, Punishment> punishmentMap = new HashMap<>();
while (set.next()) {
Veraltet
Review

Da das immer aufgerufen wird, wenn wir einen SW-User brauchen (brauchen wir häufig): Bitte auf einmal beide möglichen Punishments holen und nicht nacheinander die einzelnen PunishmentTypes. Die Datenbank braucht da nämlich immer ein paar ms.

Da das immer aufgerufen wird, wenn wir einen SW-User brauchen (brauchen wir häufig): Bitte auf einmal beide möglichen Punishments holen und nicht nacheinander die einzelnen PunishmentTypes. Die Datenbank braucht da nämlich immer ein paar ms.
Veraltet
Review

Immer noch zu fixen.

Immer noch zu fixen.
Punishment punishment = new Punishment(set);
punishmentMap.put(punishment.getType(), punishment);
}
Veraltet
Review

Da diese Funktion beim Laden eines jeden SWUsers aufgerufen wird: Bitte beide Punishments auf einmal laden.

Da diese Funktion beim Laden eines jeden SWUsers aufgerufen wird: Bitte beide Punishments auf einmal laden.
return punishmentMap;
} catch (SQLException throwable) {
throwable.printStackTrace();
throw new SecurityException("Could not Load Punishments", throwable);
}
}
public static Set<Punishment> getAllPunishmentsByPlayer(int user) {
ResultSet set = SQL.select("SELECT * FROM Punishments WHERE UserId = ? ORDER BY `PunishmentId` DESC", user);
try {
Set<Punishment> punishments = new HashSet<>();
while (set.next()) {
punishments.add(new Punishment(set));
}
return punishments;
} catch (SQLException throwable) {
throwable.printStackTrace();
Veraltet
Review

Warum Boolean und nicht boolean?

Warum Boolean und nicht boolean?
throw new SecurityException("Could not Load all Punishments", throwable);
}
}
public static Punishment createPunishment(int user, int executor, PunishmentType type, String reason, Timestamp endTime, Boolean perma) {
SQL.update("INSERT INTO Punishments (UserId, Punisher, Type, Reason, EndTime, Perma) VALUES (?, ?, ?, ?, ?, ?)",
user, executor, type.toDb(), reason, endTime, perma);
return getPunishmentByPlayer(user, type);
}
private final Timestamp startTime;
private final Timestamp endTime;
private final PunishmentType type;
private final int user;
private final String reason;
private final int id;
private final int punisher;
private final boolean perma;
Veraltet
Review

Gut, ist eher eine Stilfrage, ob man da ein separates Feld nimmt, oder ob man das nicht wie z.B. bisher über endTime macht.

Gut, ist eher eine Stilfrage, ob man da ein separates Feld nimmt, oder ob man das nicht wie z.B. bisher über endTime macht.
private Punishment(ResultSet set) throws SQLException {
id = set.getInt("PunishmentId");
user = set.getInt("UserId");
reason = set.getString("Reason");
type = PunishmentType.getTypeFromDB(set.getString("Type"));
startTime = set.getTimestamp("StartTime");
endTime = set.getTimestamp("EndTime");
punisher = set.getInt("Punisher");
perma = set.getBoolean("Perma");
}
public Timestamp getStartTime() {
return startTime;
}
public Timestamp getEndTime() {
return endTime;
}
public PunishmentType getType() {
return type;
}
public int getUser() {
return user;
}
public String getReason() {
return reason;
}
public int getId() {
return id;
}
public int getPunisher() {
return punisher;
}
public boolean isPerma() {
return perma;
}
public enum PunishmentType {
Veraltet
Review

Offenes TODO?

Offenes TODO?
Ban,
Mute;
public String toDb() {
return name().toLowerCase();
Veraltet
Review

Schreib doch nur name(), dann kannst du beim Type-Getten auch einfach valueOf() machen.

Schreib doch nur name(), dann kannst du beim Type-Getten auch einfach valueOf() machen.
}
public static PunishmentType getTypeFromDB(String str) {
return Arrays.stream(values()).filter(punishmentType -> punishmentType.name().equalsIgnoreCase(str)).collect(Collectors.toList()).get(0);
Veraltet
Review

Siehe toDb()

Siehe toDb()
}
}
}

Datei anzeigen

@ -32,7 +32,6 @@ import java.net.UnknownHostException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.time.Instant;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@ -43,16 +42,12 @@ public class SteamwarUser {
private final UUID uuid;
private String userName;
private UserGroup userGroup;
private Timestamp banTime;
private String banReason;
private int team;
private Timestamp muteTime;
private String muteReason;
private Map<Punishment.PunishmentType, Punishment> punishments;
private static final Map<String, SteamwarUser> usersByName = new HashMap<>();
private static final Map<UUID, SteamwarUser> usersByUUID = new HashMap<>();
private static final Map<Integer, SteamwarUser> usersById = new HashMap<>();
private static final Timestamp PERMA_BAN = Timestamp.from(Instant.ofEpochSecond(946684800));
private static final InetAddress LIXFEL_DE;
static {
@ -69,14 +64,11 @@ public class SteamwarUser {
uuid = UUID.fromString(rs.getString("UUID"));
userName = rs.getString("UserName");
userGroup = UserGroup.getUsergroup(rs.getString("UserGroup"));
banTime = rs.getTimestamp("BanTime");
banReason = rs.getString("BanReason");
team = rs.getInt("Team");
muteTime = rs.getTimestamp("MuteTime");
muteReason = rs.getString("MuteReason");
usersById.put(id, this);
usersByName.put(userName.toLowerCase(), this);
usersByUUID.put(uuid, this);
punishments = Punishment.getPunishmentsByPlayer(id);
}
public static SteamwarUser getOrCreate(PendingConnection connection){
@ -157,47 +149,32 @@ public class SteamwarUser {
}
public boolean isBanned() {
if (banTime == null) {
return false;
} else if (banTime.after(new Date()) || banTime.before(PERMA_BAN)) {
return true;
} else {
SQL.update("UPDATE UserData SET BanTime = NULL, BanReason = '' WHERE id = ?", id);
SQL.update("DELETE FROM BannedUserIPs WHERE UserID = ?", id);
banTime = null;
banReason = "";
return false;
}
return punishments.containsKey(Punishment.PunishmentType.Ban) &&
(punishments.get(Punishment.PunishmentType.Ban).getEndTime().after(new Date()) || punishments.get(Punishment.PunishmentType.Ban).isPerma());
Veraltet
Review

Nicht multiple get() auf die Map machen, wenn dann einmal .get(), dann auf null überprüfen (z.B. kein Bann vorliegend), dann Zeiten prüfen.

Nicht multiple get() auf die Map machen, wenn dann einmal .get(), dann auf null überprüfen (z.B. kein Bann vorliegend), dann Zeiten prüfen.
Veraltet
Review

Das macht das ganze dann auch übersichtlicher.

Das macht das ganze dann auch übersichtlicher.
Veraltet
Review

Und ggf. eine Methode isCurrent() in Punishment implementieren, wo angezeigt wird, ob die Strafe derzeit aktiv ist, das macht es einfacher und weniger Code duplication.

Und ggf. eine Methode isCurrent() in Punishment implementieren, wo angezeigt wird, ob die Strafe derzeit aktiv ist, das macht es einfacher und weniger Code duplication.
Veraltet
Review

Wenn schon, dann über ProxyServer.getInstance().getPlayer(), Problem: Diese Funktion kann den Anschein erwecken, immer einen ProxiedPlayer zurückgeben zu können, was nicht der Fall ist, daher würde ich diese Funktion entfernen.

Wenn schon, dann über ProxyServer.getInstance().getPlayer(), Problem: Diese Funktion kann den Anschein erwecken, immer einen ProxiedPlayer zurückgeben zu können, was nicht der Fall ist, daher würde ich diese Funktion entfernen.
Veraltet
Review

Dann wurden wir mal ein Cache von den Sprachen gebrauchen, weil wenn der Spieler nicht Online ist weiß das Programm nicht auf welcher Sprache es bannen soll.

Dann wurden wir mal ein Cache von den Sprachen gebrauchen, weil wenn der Spieler nicht Online ist weiß das Programm nicht auf welcher Sprache es bannen soll.
Veraltet
Review

Wenn der Spieler nicht online ist, kommt hier null zurück. Und ja, das brauchen wir auch.

Wenn der Spieler nicht online ist, kommt hier null zurück. Und ja, das brauchen wir auch.
Veraltet
Review

Hier besteht weiterhin das Problem: Wenn der User nicht online ist, kommt hier null zurück. Bitte diese Methode hier entfernen, das ist wenn überall woanders im Code. Und nutze eher ProxyServer.getInstance() als BungeeCore.get().getProxy()

Hier besteht weiterhin das Problem: Wenn der User nicht online ist, kommt hier null zurück. Bitte diese Methode hier entfernen, das ist wenn überall woanders im Code. Und nutze eher ProxyServer.getInstance() als BungeeCore.get().getProxy()
}
Veraltet
Review

Das funktioniert nicht so ganz, da der SteamwarUser-Cache einmal pro Stunde geleert wird. Daher kann es sein, dass der Key rausfällt, ohne dass je die BannedUserIPs geleert werden. Damit aber auch nicht ständig bei allen die BannedUserIPs gelöscht werden, brauchst du irgendwo ein Indikator, ob die Strafe abgesessen wurde.

Das funktioniert nicht so ganz, da der SteamwarUser-Cache einmal pro Stunde geleert wird. Daher kann es sein, dass der Key rausfällt, ohne dass je die BannedUserIPs geleert werden. Damit aber auch nicht ständig bei allen die BannedUserIPs gelöscht werden, brauchst du irgendwo ein Indikator, ob die Strafe abgesessen wurde.
Veraltet
Review

Das hier zu softloaden bringt kaum etwas, da bei jedem Join als allererstes der Gebannt-Status abgefragt wird.

Das hier zu softloaden bringt kaum etwas, da bei jedem Join als allererstes der Gebannt-Status abgefragt wird.
public boolean isMuted(){
if(muteTime == null){
return false;
}else if(muteTime.after(new Date()) || muteTime.before(PERMA_BAN)){
return true;
}else{
SQL.update("UPDATE UserData SET MuteTime = NULL, MuteReason = '' WHERE id = ?", id);
muteTime = null;
muteReason = "";
return false;
}
return punishments.containsKey(Punishment.PunishmentType.Mute) &&
(punishments.get(Punishment.PunishmentType.Mute).getEndTime().after(new Date()) || punishments.get(Punishment.PunishmentType.Mute).isPerma());
}
public TextComponent banMessage(){
if (banTime.before(PERMA_BAN)) {
return BungeeCore.stringToText(BungeeCore.CHAT_PREFIX + "§cDu bist permanent gebannt. §r§lGrund§r: §c" + banReason);
Punishment punishment = punishments.get(Punishment.PunishmentType.Ban);
if (punishment.isPerma()) {
return BungeeCore.stringToText(BungeeCore.CHAT_PREFIX + "§cDu bist permanent gebannt. §r§lGrund§r: §c" + punishment.getReason());
} else {
return BungeeCore.stringToText(BungeeCore.CHAT_PREFIX + " Du bist bis zum " +
banTime.toLocalDateTime().format(BungeeCore.DATE_FORMAT) + " gebannt. §r§lGrund§r: §c" + banReason);
punishment.getEndTime().toLocalDateTime().format(BungeeCore.DATE_FORMAT) + " gebannt. §r§lGrund§r: §c" + punishment.getReason());
}
}
public TextComponent muteMessage(){
if (muteTime.before(PERMA_BAN)) {
return BungeeCore.stringToText(BungeeCore.CHAT_PREFIX + "§cDu bist permanent gemuted. §r§lGrund§r: §c" + muteReason);
Punishment punishment = punishments.get(Punishment.PunishmentType.Mute);
if (punishment.isPerma()) {
Veraltet
Review

Die Methode scheint mir eher in Punishment zu passen.

Die Methode scheint mir eher in Punishment zu passen.
return BungeeCore.stringToText(BungeeCore.CHAT_PREFIX + "§cDu bist permanent gemuted. §r§lGrund§r: §c" + punishment.getReason());
} else {
return BungeeCore.stringToText(BungeeCore.CHAT_PREFIX + " Du bist bis zum " +
muteTime.toLocalDateTime().format(BungeeCore.DATE_FORMAT) + " gemuted. §r§lGrund§r: §c" + muteReason);
punishment.getEndTime().toLocalDateTime().format(BungeeCore.DATE_FORMAT) + " gemuted. §r§lGrund§r: §c" + punishment.getReason());
}
}
Veraltet
Review

Die Funktion gehört eher public in Punishment

Die Funktion gehört eher public in Punishment
@ -205,10 +182,9 @@ public class SteamwarUser {
BannedUserIPs.banIP(this, ip);
Veraltet
Review

Ich meine, das ML-Framework müsste selbst (mit Optionen, die in den {} angegeben werden können) Dates oder sogar Timestamps parsen können. Schließlich ist die Datumsnotation in verschiedenen Teilen der Welt unterschiedlich.

Ich meine, das ML-Framework müsste selbst (mit Optionen, die in den {} angegeben werden können) Dates oder sogar Timestamps parsen können. Schließlich ist die Datumsnotation in verschiedenen Teilen der Welt unterschiedlich.
}
public void ban(Timestamp time, String banReason){
SQL.update("UPDATE UserData SET BanTime = ?, BanReason = ? WHERE id = ?", time, banReason, id);
banTime = time;
this.banReason = banReason;
public void ban(Timestamp time, String banReason, int from, boolean perma){
punishments.remove(Punishment.PunishmentType.Ban);
punishments.put(Punishment.PunishmentType.Ban, Punishment.createPunishment(id, from, Punishment.PunishmentType.Ban, banReason, time, perma));
ProxiedPlayer player = ProxyServer.getInstance().getPlayer(uuid);
if(player != null){
@ -218,10 +194,9 @@ public class SteamwarUser {
updateBanIP("");
}
public void mute(Timestamp time, String muteReason){
SQL.update("UPDATE UserData SET MuteTime = ?, MuteReason = ? WHERE id = ?", time, muteReason, id);
muteTime = time;
this.muteReason = muteReason;
public void mute(Timestamp time, String muteReason, int from, boolean perma){
punishments.remove(Punishment.PunishmentType.Mute);
Veraltet
Review

Das fixt das Problem nur temporär, aber nicht in der Datenbank. Du musst entweder das alte Punishment aufräumen (Zeit entsprechend verkürzen) oder beim Selecten einer Strafe automatisch immer die am längesten noch andauernde Strafe SELECTen (dann würdest du mehrere Punishments zeitgleich handeln können).

Das fixt das Problem nur temporär, aber nicht in der Datenbank. Du musst entweder das alte Punishment aufräumen (Zeit entsprechend verkürzen) oder beim Selecten einer Strafe automatisch immer die am längesten noch andauernde Strafe SELECTen (dann würdest du mehrere Punishments zeitgleich handeln können).
punishments.put(Punishment.PunishmentType.Mute, Punishment.createPunishment(id, from, Punishment.PunishmentType.Mute, muteReason, time, perma));
}
private static SteamwarUser dbInit(ResultSet rs){