Ban System Rework #150
@ -19,6 +19,8 @@
|
||||
|
||||
package de.steamwar.bungeecore.sql;
|
||||
|
||||
import de.steamwar.bungeecore.BungeeCore;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Timestamp;
|
||||
@ -27,7 +29,7 @@ import java.util.*;
|
||||
public class Punishment {
|
||||
|
||||
public static Punishment getPunishmentOfPlayer(int user, PunishmentType type) {
|
||||
|
||||
ResultSet set = SQL.select("SELECT * FROM `Punishments` WHERE EndTime < NOW() AND UserId = ? AND Type = ? ORDER BY PunishmentId DESC LIMIT 1", user, type.name());
|
||||
ResultSet set = SQL.select("SELECT * FROM Punishments WHERE UserId = ? AND Type = ? ORDER BY PunishmentId DESC LIMIT 1", user, type.name());
|
||||
try {
|
||||
if(!set.next())
|
||||
return null;
|
||||
@ -38,17 +40,14 @@ public class Punishment {
|
||||
}
|
||||
|
||||
public static Map<PunishmentType, Punishment> getPunishmentsOfPlayer(int user) {
|
||||
ResultSet set = SQL.select("SELECT * FROM Punishments WHERE PunishmentId IN (SELECT MAX(PunishmentId) FROM Punishments WHERE UserId = ? GROUP BY Type)", user);
|
||||
try {
|
||||
Map<PunishmentType, Punishment> punishmentMap = new HashMap<>();
|
||||
while (set.next()) {
|
||||
Punishment punishment = new Punishment(set);
|
||||
punishmentMap.put(punishment.getType(), punishment);
|
||||
}
|
||||
return punishmentMap;
|
||||
} catch (SQLException e) {
|
||||
throw new SecurityException("Could not Load Punishments", e);
|
||||
Map<PunishmentType, Punishment> punishmentMap = new HashMap<>();
|
||||
Lixfel
hat
Siehe oben. Siehe oben.
|
||||
for (PunishmentType type : PunishmentType.values()) {
|
||||
Punishment punishment = getPunishmentOfPlayer(user, type);
|
||||
if(punishment == null)
|
||||
Lixfel
hat
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.
Lixfel
hat
Immer noch zu fixen. Immer noch zu fixen.
|
||||
continue;
|
||||
punishmentMap.put(type, punishment);
|
||||
}
|
||||
Lixfel
hat
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;
|
||||
}
|
||||
|
||||
public static List<Punishment> getAllPunishmentsOfPlayer(int user) {
|
||||
@ -71,12 +70,13 @@ public class Punishment {
|
||||
}
|
||||
|
||||
private final Timestamp startTime;
|
||||
private final Timestamp endTime;
|
||||
private Timestamp endTime;
|
||||
private final PunishmentType type;
|
||||
private final int user;
|
||||
private final String reason;
|
||||
private final int id;
|
||||
private String reason;
|
||||
private final int punisher;
|
||||
private final boolean perma;
|
||||
private boolean perma;
|
||||
|
||||
private Punishment(ResultSet set) throws SQLException {
|
||||
user = set.getInt("UserId");
|
||||
@ -86,6 +86,7 @@ public class Punishment {
|
||||
endTime = set.getTimestamp("EndTime");
|
||||
punisher = set.getInt("Punisher");
|
||||
perma = set.getBoolean("Perma");
|
||||
id = set.getInt("PunishmentId");
|
||||
}
|
||||
|
||||
public Timestamp getStartTime() {
|
||||
@ -116,6 +117,36 @@ public class Punishment {
|
||||
return perma;
|
||||
}
|
||||
|
||||
public void updateEndTime(int from, String reason, Timestamp newUpdate, boolean perma) {
|
||||
StringBuilder newReason = new StringBuilder(reason);
|
||||
if(newUpdate.before(endTime))
|
||||
newReason.append(" verkürtz vom ")
|
||||
.append(getBantime())
|
||||
.append(" von ")
|
||||
.append(SteamwarUser.get(from).getUserName())
|
||||
.append(" Grund: ")
|
||||
.append(reason);
|
||||
else
|
||||
Lixfel
hat
Offenes TODO? Offenes TODO?
|
||||
newReason.append(" verlängert vom ")
|
||||
.append(getBantime())
|
||||
.append(" von ")
|
||||
.append(SteamwarUser.get(from).getUserName())
|
||||
.append(" Grund: ")
|
||||
Lixfel
hat
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.
|
||||
.append(reason);
|
||||
|
||||
SQL.update("UPDATE Punishments SET EndTime = ?, Reason = ?, Perma = ? WHERE PunishmentId = ?", newUpdate, newReason.toString(), perma, id);
|
||||
this.reason = newReason.toString();
|
||||
Lixfel
hat
Siehe toDb() Siehe toDb()
|
||||
this.perma = perma;
|
||||
this.endTime = newUpdate;
|
||||
}
|
||||
|
||||
public String getBantime() {
|
||||
if(perma)
|
||||
return "Permanent";
|
||||
else
|
||||
return endTime.toLocalDateTime().format(BungeeCore.DATE_FORMAT);
|
||||
}
|
||||
|
||||
public enum PunishmentType {
|
||||
Ban,
|
||||
Mute;
|
||||
|
@ -189,6 +189,10 @@ public class SteamwarUser {
|
||||
}
|
||||
|
||||
public void ban(Timestamp time, String banReason, int from, boolean perma){
|
||||
if(isBanned()) {
|
||||
Lixfel
hat
Siehe banMessage() Siehe banMessage()
|
||||
punishments.get(Punishment.PunishmentType.Ban).updateEndTime(from, banReason, time, perma);
|
||||
return;
|
||||
}
|
||||
punishments.remove(Punishment.PunishmentType.Ban);
|
||||
punishments.put(Punishment.PunishmentType.Ban, Punishment.createPunishment(id, from, Punishment.PunishmentType.Ban, banReason, time, perma));
|
||||
|
||||
Lixfel
hat
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).
|
||||
@ -201,6 +205,10 @@ public class SteamwarUser {
|
||||
}
|
||||
|
||||
public void mute(Timestamp time, String muteReason, int from, boolean perma){
|
||||
if(isMuted()) {
|
||||
punishments.get(Punishment.PunishmentType.Ban).updateEndTime(from, muteReason, time, perma);
|
||||
return;
|
||||
}
|
||||
punishments.remove(Punishment.PunishmentType.Mute);
|
||||
punishments.put(Punishment.PunishmentType.Mute, Punishment.createPunishment(id, from, Punishment.PunishmentType.Mute, muteReason, time, perma));
|
||||
Lixfel
hat
Whoops! Mute/Ban. Whoops! Mute/Ban.
|
||||
}
|
||||
|
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
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.
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)
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.
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.
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.
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).
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, 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.
Aktuelles Problem: Der Perma Ban Timestamp ist vor allen anderen, das macht mir das Selecten des Aktiven Banns um einiger Schwieriger-.