Skip to content

Commit 85f8b4f

Browse files
refactor(punishment): extract ActivePunishment record, fix unban and mute bugs
- Extract ActivePunishment from PunishmentRedis into standalone record so proxy/game server no longer depend on Redis class (DIP) - Fix UnpunishPlayerEndpoint: verify punishment type is BAN before revoking, preventing /unban from clearing mutes - Fix permanent mute message showing "will expire in" with negative time
1 parent 87752e0 commit 85f8b4f

9 files changed

Lines changed: 31 additions & 20 deletions

File tree

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package net.swofty.commons.punishment;
2+
3+
public record ActivePunishment(String type, String banId, PunishmentReason reason, long expiresAt) {}

commons/src/main/java/net/swofty/commons/punishment/PunishmentMessages.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
public final class PunishmentMessages {
77
private PunishmentMessages() {}
88

9-
public static Component banMessage(PunishmentRedis.ActivePunishment punishment) {
9+
public static Component banMessage(ActivePunishment punishment) {
1010
long expiresAt = punishment.expiresAt();
1111
PunishmentReason reason = punishment.reason();
1212
String banId = punishment.banId();
@@ -31,22 +31,23 @@ public static Component banMessage(PunishmentRedis.ActivePunishment punishment)
3131
return Component.text(header + "\n§7Reason: §f" + reason.getReasonString() + "\n" + findOutMore + "\n§7Ban ID: §f" + banId + "\n" + footer);
3232
}
3333

34-
public static Component muteMessage(PunishmentRedis.ActivePunishment punishment) {
34+
public static Component muteMessage(ActivePunishment punishment) {
3535
long expiresAt = punishment.expiresAt();
3636
PunishmentReason reason = punishment.reason();
3737

38-
long timeLeft = expiresAt - System.currentTimeMillis();
39-
String prettyTimeLeft = StringUtility.formatTimeLeft(timeLeft);
40-
4138
String line = "\n§c§m §r\n";
4239

4340
String header;
41+
String time;
4442
if (expiresAt <= 0) {
4543
header = "§cYou are permanently muted on this server!\n";
44+
time = "";
4645
} else {
46+
long timeLeft = expiresAt - System.currentTimeMillis();
47+
String prettyTimeLeft = StringUtility.formatTimeLeft(timeLeft);
4748
header = "§cYou are currently muted for " + reason.getReasonString() + "\n";
49+
time = "§7Your mute will expire in §c" + prettyTimeLeft + "\n\n";
4850
}
49-
String time = "§7Your mute will expire in §c" + prettyTimeLeft + "\n\n";
5051

5152
String urlInfo = "§7Find out more here: §fwww.hypixel.net/mutes\n";
5253
String footer = "§7Mute ID: §f" + punishment.banId();

commons/src/main/java/net/swofty/commons/punishment/PunishmentRedis.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,6 @@ public static CompletableFuture<Long> revoke(UUID playerId) {
115115
});
116116
}
117117

118-
public record ActivePunishment(String type, String banId, PunishmentReason reason, long expiresAt) {}
119-
120118
public static Set<String> getAllBannedPlayerIds() {
121119
try (Jedis jedis = jedisPool.getResource()) {
122120
var cursor = "0";

service.punishment/src/main/java/net/swofty/service/punishment/endpoints/GetActivePunishmentEndpoint.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import net.swofty.commons.impl.ServiceProxyRequest;
44
import net.swofty.commons.protocol.ProtocolObject;
55
import net.swofty.commons.protocol.objects.punishment.GetActivePunishmentProtocolObject;
6+
import net.swofty.commons.punishment.ActivePunishment;
67
import net.swofty.commons.punishment.PunishmentRedis;
78
import net.swofty.service.generic.redis.ServiceEndpoint;
89

@@ -19,12 +20,12 @@ public ProtocolObject<GetActivePunishmentProtocolObject.GetActivePunishmentMessa
1920

2021
@Override
2122
public GetActivePunishmentProtocolObject.GetActivePunishmentResponse onMessage(ServiceProxyRequest message, GetActivePunishmentProtocolObject.GetActivePunishmentMessage messageObject) {
22-
Optional<PunishmentRedis.ActivePunishment> existing = PunishmentRedis.getActive(messageObject.target());
23+
Optional<ActivePunishment> existing = PunishmentRedis.getActive(messageObject.target());
2324
if (existing.isEmpty()) {
2425
return new GetActivePunishmentProtocolObject.GetActivePunishmentResponse(false, null, null, null, 0);
2526
}
2627

27-
PunishmentRedis.ActivePunishment punishment = existing.get();
28+
ActivePunishment punishment = existing.get();
2829
return new GetActivePunishmentProtocolObject.GetActivePunishmentResponse(
2930
true,
3031
punishment.type(),

service.punishment/src/main/java/net/swofty/service/punishment/endpoints/PunishPlayerEndpoint.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ public PunishPlayerProtocolObject.PunishPlayerResponse onMessage(ServiceProxyReq
3838

3939
boolean hasOverwriteTag = messageObject.tags() != null && messageObject.tags().contains(PunishmentTag.OVERWRITE);
4040
if (!hasOverwriteTag) {
41-
Optional<PunishmentRedis.ActivePunishment> existing = PunishmentRedis.getActive(messageObject.target());
41+
Optional<ActivePunishment> existing = PunishmentRedis.getActive(messageObject.target());
4242
if (existing.isPresent()) {
43-
PunishmentRedis.ActivePunishment active = existing.get();
43+
ActivePunishment active = existing.get();
4444
PunishmentType existingType = PunishmentType.valueOf(active.type());
4545
if (existingType == punishmentType) {
4646
return new PunishPlayerProtocolObject.PunishPlayerResponse(false, null,

service.punishment/src/main/java/net/swofty/service/punishment/endpoints/UnpunishPlayerEndpoint.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
import net.swofty.commons.impl.ServiceProxyRequest;
44
import net.swofty.commons.protocol.ProtocolObject;
55
import net.swofty.commons.protocol.objects.punishment.UnpunishPlayerProtocolObject;
6+
import net.swofty.commons.punishment.ActivePunishment;
67
import net.swofty.commons.punishment.PunishmentRedis;
8+
import net.swofty.commons.punishment.PunishmentType;
79
import net.swofty.service.generic.redis.ServiceEndpoint;
810
import org.tinylog.Logger;
911

@@ -20,13 +22,19 @@ public ProtocolObject<UnpunishPlayerProtocolObject.UnpunishPlayerMessage, Unpuni
2022

2123
@Override
2224
public UnpunishPlayerProtocolObject.UnpunishPlayerResponse onMessage(ServiceProxyRequest message, UnpunishPlayerProtocolObject.UnpunishPlayerMessage messageObject) {
23-
Optional<PunishmentRedis.ActivePunishment> existing = PunishmentRedis.getActive(messageObject.target());
25+
Optional<ActivePunishment> existing = PunishmentRedis.getActive(messageObject.target());
2426
if (existing.isEmpty()) {
2527
return new UnpunishPlayerProtocolObject.UnpunishPlayerResponse(false, "No active punishment found for this player.");
2628
}
2729

30+
ActivePunishment punishment = existing.get();
31+
PunishmentType type = PunishmentType.valueOf(punishment.type());
32+
if (type != PunishmentType.BAN) {
33+
return new UnpunishPlayerProtocolObject.UnpunishPlayerResponse(false, "Player is not banned (active punishment is " + type.name() + ").");
34+
}
35+
2836
PunishmentRedis.revoke(messageObject.target()).join();
29-
Logger.info("Revoked punishment for {} by staff {}",
37+
Logger.info("Revoked ban for {} by staff {}",
3038
messageObject.target(), messageObject.staff());
3139
return new UnpunishPlayerProtocolObject.UnpunishPlayerResponse(true, null);
3240
}

type.generic/src/main/java/net/swofty/type/generic/event/actions/ActionPlayerMute.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
import net.minestom.server.event.player.PlayerChatEvent;
55
import net.swofty.commons.ServiceType;
66
import net.swofty.commons.protocol.objects.punishment.GetActivePunishmentProtocolObject;
7+
import net.swofty.commons.punishment.ActivePunishment;
78
import net.swofty.commons.punishment.PunishmentMessages;
8-
import net.swofty.commons.punishment.PunishmentRedis;
99
import net.swofty.commons.punishment.PunishmentType;
1010
import net.swofty.proxyapi.ProxyService;
1111
import net.swofty.type.generic.event.EventNodes;
@@ -28,7 +28,7 @@ public void onPlayerChat(PlayerChatEvent event) {
2828
if (response instanceof GetActivePunishmentProtocolObject.GetActivePunishmentResponse r
2929
&& r.found() && PunishmentType.valueOf(r.type()) == PunishmentType.MUTE) {
3030
event.setCancelled(true);
31-
var punishment = new PunishmentRedis.ActivePunishment(r.type(), r.banId(), r.reason(), r.expiresAt());
31+
var punishment = new ActivePunishment(r.type(), r.banId(), r.reason(), r.expiresAt());
3232
player.sendMessage(PunishmentMessages.muteMessage(punishment));
3333
}
3434
} catch (Exception ignored) {

velocity.extension/src/main/java/net/swofty/velocity/SkyBlockVelocity.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@
3939
import net.swofty.commons.protocol.ProtocolObject;
4040
import net.swofty.commons.protocol.objects.punishment.GetActivePunishmentProtocolObject;
4141
import net.swofty.commons.proxy.FromProxyChannels;
42+
import net.swofty.commons.punishment.ActivePunishment;
4243
import net.swofty.commons.punishment.PunishmentMessages;
43-
import net.swofty.commons.punishment.PunishmentRedis;
4444
import net.swofty.commons.punishment.PunishmentType;
4545
import net.swofty.proxyapi.ProxyService;
4646
import net.swofty.proxyapi.redis.ServerOutboundMessage;
@@ -229,7 +229,7 @@ public boolean punished(Player player) {
229229
return false;
230230
}
231231

232-
PunishmentRedis.ActivePunishment punishment = new PunishmentRedis.ActivePunishment(
232+
ActivePunishment punishment = new ActivePunishment(
233233
r.type(), r.banId(), r.reason(), r.expiresAt());
234234
PunishmentType type = PunishmentType.valueOf(r.type());
235235
if (type == PunishmentType.BAN) {

velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerPlayerPunished.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
import net.swofty.commons.proxy.ToProxyChannels;
77
import net.swofty.commons.punishment.PunishmentId;
88
import net.swofty.commons.punishment.PunishmentReason;
9+
import net.swofty.commons.punishment.ActivePunishment;
910
import net.swofty.commons.punishment.PunishmentMessages;
10-
import net.swofty.commons.punishment.PunishmentRedis;
1111
import net.swofty.commons.punishment.PunishmentType;
1212
import net.swofty.commons.punishment.template.BanType;
1313
import net.swofty.commons.punishment.template.MuteType;
@@ -54,7 +54,7 @@ public JSONObject receivedMessage(JSONObject message, UUID serverUUID) {
5454
PunishmentType punishmentType = PunishmentType.valueOf(type);
5555
PunishmentReason finalReason = reason;
5656
SkyBlockVelocity.getServer().getPlayer(target).ifPresent((player) -> {
57-
PunishmentRedis.ActivePunishment activePunishment = new PunishmentRedis.ActivePunishment(type, id, finalReason, expiresAt);
57+
ActivePunishment activePunishment = new ActivePunishment(type, id, finalReason, expiresAt);
5858
switch (punishmentType) {
5959
case BAN -> {
6060
player.disconnect(PunishmentMessages.banMessage(activePunishment));

0 commit comments

Comments
 (0)