88
99import java .net .URI ;
1010import java .time .Duration ;
11- import java .util .Map ;
12- import java .util .Optional ;
13- import java .util .UUID ;
11+ import java .util .*;
1412import java .util .concurrent .CompletableFuture ;
1513
1614public class PunishmentRedis {
17- private static final String PREFIX = "punish:" ;
15+ private static final String PREFIX = "punish:active:" ;
16+ private static final Gson GSON = new Gson ();
1817 private static JedisPool jedisPool ;
1918 private static volatile boolean initialized = false ;
2019 private static volatile boolean connecting = false ;
@@ -40,7 +39,6 @@ private static synchronized void connectSync(String redisUri) {
4039 URI uri = URI .create (redisUri );
4140 jedisPool = new JedisPool (poolConfig , uri );
4241
43- // Test connection
4442 try (Jedis jedis = jedisPool .getResource ()) {
4543 jedis .ping ();
4644 }
@@ -60,66 +58,84 @@ public static boolean isInitialized() {
6058 return initialized && jedisPool != null && !jedisPool .isClosed ();
6159 }
6260
63- public static void saveActivePunishment (UUID playerId , String type , String id , PunishmentReason reason , long expiresAt , java .util .List <PunishmentTag > tags ) {
61+ private static String key (UUID playerId , String type ) {
62+ return PREFIX + playerId + ":" + type ;
63+ }
64+
65+ public static void saveActivePunishment (UUID playerId , String type , String id ,
66+ PunishmentReason reason , long expiresAt ,
67+ List <PunishmentTag > tags ) {
68+ if (!isInitialized ()) throw new IllegalStateException ("PunishmentRedis not initialized" );
69+
6470 try (Jedis jedis = jedisPool .getResource ()) {
65- String key = PREFIX + "active:" + playerId ;
71+ String k = key ( playerId , type ) ;
6672
67- Gson gson = new Gson ();
68- java .util .HashMap <String , String > data = new java .util .HashMap <>(Map .of (
73+ HashMap <String , String > data = new HashMap <>(Map .of (
6974 "type" , type ,
7075 "banId" , id ,
71- "reason" , gson .toJson (reason ),
76+ "reason" , GSON .toJson (reason ),
7277 "expiresAt" , String .valueOf (expiresAt )
7378 ));
7479 if (tags != null && !tags .isEmpty ()) {
75- data .put ("tags" , gson .toJson (tags ));
80+ data .put ("tags" , GSON .toJson (tags ));
7681 }
7782
78- jedis .hset (key , data );
83+ jedis .hset (k , data );
7984 if (expiresAt > 0 ) {
8085 long ttlSeconds = (expiresAt - System .currentTimeMillis ()) / 1000 ;
8186 if (ttlSeconds > 0 ) {
82- jedis .expire (key , (int ) ttlSeconds );
87+ jedis .expire (k , (int ) ttlSeconds );
8388 }
89+ } else {
90+ jedis .persist (k );
8491 }
8592 }
8693 }
8794
88- public static Optional <ActivePunishment > getActive (UUID playerId ) {
95+ public static Optional <ActivePunishment > getActive (UUID playerId , String type ) {
96+ if (!isInitialized ()) return Optional .empty ();
97+
8998 try (Jedis jedis = jedisPool .getResource ()) {
90- String key = PREFIX + "active:" + playerId ;
91- Map <String , String > data = jedis .hgetAll (key );
99+ String k = key ( playerId , type ) ;
100+ Map <String , String > data = jedis .hgetAll (k );
92101
93102 if (data .isEmpty ()) return Optional .empty ();
94103
95- String type = data .get ("type" );
96104 String banId = data .get ("banId" );
97105 long expiresAt = Long .parseLong (data .getOrDefault ("expiresAt" , "-1" ));
98106
99107 if (expiresAt > 0 && System .currentTimeMillis () > expiresAt ) {
100- jedis .del (key ); // clean up expired
108+ jedis .del (k );
101109 return Optional .empty ();
102110 }
103111
104- Gson gson = new Gson ();
105- PunishmentReason reason = gson .fromJson (data .get ("reason" ), PunishmentReason .class );
112+ PunishmentReason reason = GSON .fromJson (data .get ("reason" ), PunishmentReason .class );
106113
107- java . util . List <PunishmentTag > tags = java . util . List .of ();
114+ List <PunishmentTag > tags = List .of ();
108115 String tagsJson = data .get ("tags" );
109116 if (tagsJson != null && !tagsJson .isBlank ()) {
110- tags = java . util . List .of (gson .fromJson (tagsJson , PunishmentTag [].class ));
117+ tags = List .of (GSON .fromJson (tagsJson , PunishmentTag [].class ));
111118 }
112119
113120 return Optional .of (new ActivePunishment (type , banId , reason , expiresAt , tags ));
114121 }
115122 }
116123
117- public static CompletableFuture <Long > revoke (UUID playerId ) {
118- return CompletableFuture .supplyAsync (() -> {
119- try (Jedis jedis = jedisPool .getResource ()) {
120- String key = PREFIX + "active:" + playerId ;
121- return jedis .del (key );
122- }
123- });
124+ public static List <ActivePunishment > getAllActive (UUID playerId ) {
125+ if (!isInitialized ()) return List .of ();
126+
127+ List <ActivePunishment > result = new ArrayList <>();
128+ for (PunishmentType pt : PunishmentType .values ()) {
129+ getActive (playerId , pt .name ()).ifPresent (result ::add );
130+ }
131+ return result ;
132+ }
133+
134+ public static void revoke (UUID playerId , String type ) {
135+ if (!isInitialized ()) throw new IllegalStateException ("PunishmentRedis not initialized" );
136+
137+ try (Jedis jedis = jedisPool .getResource ()) {
138+ jedis .del (key (playerId , type ));
139+ }
124140 }
125141}
0 commit comments