11package me .xginko .aef .modules .dupepreventions ;
22
3+ import com .github .retrooper .packetevents .PacketEvents ;
34import com .github .retrooper .packetevents .event .PacketListenerPriority ;
45import com .github .retrooper .packetevents .event .PacketReceiveEvent ;
56import com .github .retrooper .packetevents .manager .server .ServerVersion ;
67import com .github .retrooper .packetevents .netty .buffer .ByteBufHelper ;
78import com .github .retrooper .packetevents .protocol .packettype .PacketType ;
89import me .xginko .aef .modules .packets .PacketModule ;
910import me .xginko .aef .utils .enums .Platform ;
11+ import me .xginko .aef .utils .models .ExpiringSet ;
1012
1113import java .nio .charset .StandardCharsets ;
14+ import java .time .Duration ;
15+ import java .util .UUID ;
1216
1317public class BookTitleDupe extends PacketModule {
1418
19+ private final long cooldownMillis ;
1520 private final int titleLimit , pageLimit , pageCharLimit ;
1621 private final boolean log , kick ;
1722
23+ private ExpiringSet <UUID > editCooldown ;
24+
1825 public BookTitleDupe () {
1926 super ("dupe-preventions.book-title-dupe" ,
20- Platform .getServerVersion ().isNewerThanOrEquals (ServerVersion .V_1_20_6 ) &&
21- Platform .getServerVersion ().isOlderThan (ServerVersion .V_1_21_2 ),
27+ Platform .getServerVersion ().isNewerThanOrEquals (ServerVersion .V_1_20_6 )
28+ && ! Platform .getServerVersion ().isOlderThan (ServerVersion .V_1_21_2 ),
2229 PacketListenerPriority .HIGHEST ,
2330 "Relevant for 1.20.6 - 1.21:\n " +
2431 "Will prevent players from sending book packets with a too large title,\n " +
@@ -27,13 +34,38 @@ public BookTitleDupe() {
2734 this .titleLimit = config .getInt (configPath + ".max-title-charlength" , modernLimits ? 15 : 120 );
2835 this .pageLimit = config .getInt (configPath + ".max-pages" , modernLimits ? 90 : 190 );
2936 this .pageCharLimit = config .getInt (configPath + ".max-page-charlength" , modernLimits ? 1000 : 8100 );
37+ this .cooldownMillis = config .getLong (configPath + ".spam-cooldown-millis" , 1000 );
3038 this .log = config .getBoolean (configPath + ".log" , false );
3139 this .kick = config .getBoolean (configPath + ".kick-player" , false );
3240 }
3341
42+ @ Override
43+ public void enable () {
44+ PacketEvents .getAPI ().getEventManager ().registerListener (asAbstract );
45+ editCooldown = new ExpiringSet <>(Duration .ofMillis (cooldownMillis ));
46+ }
47+
48+ @ Override
49+ public void disable () {
50+ PacketEvents .getAPI ().getEventManager ().unregisterListener (asAbstract );
51+ if (editCooldown != null ) {
52+ editCooldown .clear ();
53+ editCooldown .cleanUp ();
54+ editCooldown = null ;
55+ }
56+ }
57+
3458 @ Override
3559 public void onPacketReceive (PacketReceiveEvent event ) {
36- if (event .getPacketType () != PacketType .Play .Client .EDIT_BOOK ) return ;
60+ if (event .isCancelled () || event .getPacketType () != PacketType .Play .Client .EDIT_BOOK ) return ;
61+
62+ if (editCooldown .contains (event .getUser ().getUUID ())) {
63+ event .setCancelled (true );
64+ onCancel (log , kick , event .getUser ());
65+ return ;
66+ }
67+
68+ editCooldown .add (event .getUser ().getUUID ());
3769
3870 if (isIllegalBookEdit (event )) {
3971 event .setCancelled (true );
0 commit comments