1
+ package fr .rxokas .entitypurge .neoforge ;
2
+
3
+ import dev .architectury .event .events .common .TickEvent ;
4
+ import fr .rxokas .entitypurge .util .Command ;
5
+ import net .minecraft .core .registries .BuiltInRegistries ;
6
+ import net .minecraft .resources .ResourceLocation ;
7
+ import net .minecraft .server .MinecraftServer ;
8
+ import net .minecraft .server .level .ServerLevel ;
9
+ import net .minecraft .world .entity .Entity ;
10
+ import net .minecraft .world .entity .EntityType ;
11
+ import org .slf4j .Logger ;
12
+ import org .slf4j .LoggerFactory ;
13
+
14
+ import java .util .HashMap ;
15
+ import java .util .Map ;
16
+
17
+ import static fr .rxokas .entitypurge .util .BroadcastMessage .broadcastToAllPlayers ;
18
+
19
+ public class TickHandler {
20
+ private static final Logger LOGGER = LoggerFactory .getLogger (TickHandler .class );
21
+ private static final Accumulator accumulator = new Accumulator (ModConfig .minutesBetweenEachPurge );
22
+ private static final Map <String , EntityType <?>> entityTypeCache = new HashMap <>();
23
+
24
+ private static boolean alreadyWarn10s = false ;
25
+
26
+ public static void init () {
27
+ TickEvent .SERVER_POST .register (TickHandler ::onServerTick );
28
+ cacheEntityTypes ();
29
+ }
30
+
31
+ private static void cacheEntityTypes () {
32
+ for (String entityId : ModConfig .entitiesToClear ) {
33
+ ResourceLocation entityResource = ResourceLocation .parse (entityId );
34
+ BuiltInRegistries .ENTITY_TYPE .getOptional (entityResource ).ifPresent (entityType ->
35
+ entityTypeCache .put (entityId , entityType )
36
+ );
37
+ }
38
+ }
39
+
40
+ private static void onServerTick (MinecraftServer server ) {
41
+ accumulator .add ();
42
+
43
+ if (accumulator .canProcess ()) {
44
+ LOGGER .debug ("Starting entity purge..." );
45
+ accumulator .reduce ();
46
+ alreadyWarn10s = false ;
47
+
48
+ if (ModConfig .clearItem ) Command .execute (server , "kill @e[type=item]" );
49
+
50
+ if (!ModConfig .entitiesToClear .isEmpty ()) {
51
+ for (ServerLevel serverLevel : server .getAllLevels ()) {
52
+ for (String entityId : ModConfig .entitiesToClear ) {
53
+ EntityType <?> entityType = entityTypeCache .get (entityId );
54
+ if (entityType == null ) continue ;
55
+
56
+ serverLevel .getEntities (entityType , Entity ::isAlive ).forEach (entity -> entity .remove (Entity .RemovalReason .DISCARDED ));
57
+ }
58
+ }
59
+ }
60
+ if (ModConfig .warninghappend ) broadcastToAllPlayers (server , ModConfig .warninghappendMessage + "§r" );
61
+
62
+ LOGGER .debug ("Entity purge Done" );
63
+ } else if (ModConfig .warning10s && accumulator .lessThan10SecRemaining () && !alreadyWarn10s ) {
64
+ broadcastToAllPlayers (server , ModConfig .warning10sMessage + "§r" );
65
+ alreadyWarn10s = true ;
66
+ }
67
+ }
68
+
69
+ private static class Accumulator {
70
+ private static final float TEN_SECONDS_IN_TICKS = 200 ; // 10 seconds in ticks (20 ticks per second)
71
+ float total ;
72
+ float threshold ;
73
+ private final float tenSecondThreshold ;
74
+
75
+ public Accumulator (float threshold ) {
76
+ this .threshold = threshold * 1200 ; // Convert minutes to ticks
77
+ this .tenSecondThreshold = this .threshold - TEN_SECONDS_IN_TICKS ;
78
+ }
79
+
80
+ public boolean canProcess () {
81
+ return total >= threshold ;
82
+ }
83
+
84
+ public void reduce () {
85
+ total -= threshold ;
86
+ }
87
+
88
+ public void add () {
89
+ total += 1 ;
90
+ }
91
+
92
+ public boolean lessThan10SecRemaining () {
93
+ return total >= tenSecondThreshold ;
94
+ }
95
+ }
96
+ }
0 commit comments