5
5
import java .util .Iterator ;
6
6
import java .util .List ;
7
7
import java .util .Set ;
8
+ import java .util .UUID ;
9
+ import java .util .concurrent .CompletableFuture ;
8
10
9
11
import org .bukkit .Bukkit ;
10
12
import org .bukkit .event .EventHandler ;
21
23
22
24
public class AdminPurgeCommand extends CompositeCommand implements Listener {
23
25
26
+ private static final Long YEAR2000 = 946713600L ;
24
27
private int count ;
25
28
private boolean inPurge ;
29
+ private boolean scanning ;
26
30
private boolean toBeConfirmed ;
27
31
private Iterator <String > it ;
28
32
private User user ;
@@ -47,6 +51,10 @@ public void setup() {
47
51
48
52
@ Override
49
53
public boolean canExecute (User user , String label , List <String > args ) {
54
+ if (scanning ) {
55
+ user .sendMessage ("commands.admin.purge.scanning-in-progress" );
56
+ return false ;
57
+ }
50
58
if (inPurge ) {
51
59
user .sendMessage ("commands.admin.purge.purge-in-progress" , TextVariables .LABEL , this .getTopLabel ());
52
60
return false ;
@@ -75,13 +83,21 @@ public boolean execute(User user, String label, List<String> args) {
75
83
user .sendMessage ("commands.admin.purge.days-one-or-more" );
76
84
return false ;
77
85
}
78
- islands = getOldIslands (days );
79
- user .sendMessage ("commands.admin.purge.purgable-islands" , TextVariables .NUMBER , String .valueOf (islands .size ()));
80
- if (!islands .isEmpty ()) {
81
- toBeConfirmed = true ;
82
- user .sendMessage ("commands.admin.purge.confirm" , TextVariables .LABEL , this .getTopLabel ());
83
- return false ;
84
- }
86
+ user .sendMessage ("commands.admin.purge.scanning" );
87
+ scanning = true ;
88
+ getOldIslands (days ).thenAccept (islandSet -> {
89
+ user .sendMessage ("commands.admin.purge.purgable-islands" , TextVariables .NUMBER ,
90
+ String .valueOf (islandSet .size ()));
91
+ if (!islandSet .isEmpty ()) {
92
+ toBeConfirmed = true ;
93
+ user .sendMessage ("commands.admin.purge.confirm" , TextVariables .LABEL , this .getTopLabel ());
94
+ islands = islandSet ;
95
+ } else {
96
+ user .sendMessage ("commands.admin.purge.none-found" );
97
+ }
98
+ scanning = false ;
99
+ });
100
+
85
101
} catch (NumberFormatException e ) {
86
102
user .sendMessage ("commands.admin.purge.number-error" );
87
103
return false ;
@@ -125,40 +141,61 @@ void onIslandDeleted(IslandDeletedEvent e) {
125
141
* @param days days
126
142
* @return set of islands
127
143
*/
128
- Set <String > getOldIslands (int days ) {
129
- long currentTimeMillis = System .currentTimeMillis ();
130
- long daysInMilliseconds = (long ) days * 1000 * 3600 * 24 ;
131
- Set <String > oldIslands = new HashSet <>();
132
-
144
+ CompletableFuture <Set <String >> getOldIslands (int days ) {
145
+ CompletableFuture <Set <String >> result = new CompletableFuture <>();
133
146
// Process islands in one pass, logging and adding to the set if applicable
134
- getPlugin ().getIslands ().getIslands ().stream ()
147
+ getPlugin ().getIslands ().getIslandsASync ().thenAccept (list -> {
148
+ user .sendMessage ("commands.admin.purge.total-islands" , TextVariables .NUMBER , String .valueOf (list .size ()));
149
+ Set <String > oldIslands = new HashSet <>();
150
+ list .stream ()
135
151
.filter (i -> !i .isSpawn ()).filter (i -> !i .getPurgeProtected ())
136
152
.filter (i -> i .getWorld () != null ) // to handle currently unloaded world islands
137
- .filter (i -> i .getWorld ().equals (this .getWorld ())).filter (Island ::isOwned ).filter (
138
- i -> i .getMemberSet ().stream ()
139
- .allMatch (member -> (currentTimeMillis
140
- - Bukkit .getOfflinePlayer (member ).getLastPlayed ()) > daysInMilliseconds ))
153
+ .filter (i -> i .getWorld ().equals (this .getWorld ())) // Island needs to be in this world
154
+ .filter (Island ::isOwned ) // The island needs to be owned
155
+ .filter (i -> i .getMemberSet ().stream ().allMatch (member -> checkLastLoginTimestamp (days , member )))
141
156
.forEach (i -> {
142
157
// Add the unique island ID to the set
143
158
oldIslands .add (i .getUniqueId ());
144
- BentoBox . getInstance ().log ("Will purge island at " + Util .xyz (i .getCenter ().toVector ()) + " in "
159
+ getPlugin ().log ("Will purge island at " + Util .xyz (i .getCenter ().toVector ()) + " in "
145
160
+ i .getWorld ().getName ());
146
161
// Log each member's last login information
147
162
i .getMemberSet ().forEach (member -> {
148
- Date lastLogin = new Date (Bukkit .getOfflinePlayer (member ).getLastPlayed ());
163
+ Long timestamp = getPlayers ().getLastLoginTimestamp (member );
164
+ Date lastLogin = new Date (timestamp );
149
165
BentoBox .getInstance ()
150
166
.log ("Player " + BentoBox .getInstance ().getPlayers ().getName (member )
151
167
+ " last logged in "
152
- + (int ) ((currentTimeMillis - Bukkit .getOfflinePlayer (member ).getLastPlayed ())
153
- / 1000 / 3600 / 24 )
168
+ + (int ) ((System .currentTimeMillis () - timestamp ) / 1000 / 3600 / 24 )
154
169
+ " days ago. " + lastLogin );
155
170
});
156
171
BentoBox .getInstance ().log ("+-----------------------------------------+" );
157
172
});
173
+ result .complete (oldIslands );
174
+ });
175
+ return result ;
176
+ }
158
177
159
- return oldIslands ;
178
+ private boolean checkLastLoginTimestamp (int days , UUID member ) {
179
+ long daysInMilliseconds = days * 24L * 3600 * 1000 ; // Calculate days in milliseconds
180
+ Long lastLoginTimestamp = getPlayers ().getLastLoginTimestamp (member );
181
+ // If no valid last login time is found or it's before the year 2000, try to fetch from Bukkit
182
+ if (lastLoginTimestamp == null || lastLoginTimestamp < YEAR2000 ) {
183
+ lastLoginTimestamp = Bukkit .getOfflinePlayer (member ).getLastPlayed ();
184
+
185
+ // If still invalid, set the current timestamp to mark the user for eventual purging
186
+ if (lastLoginTimestamp < YEAR2000 ) {
187
+ getPlayers ().setLoginTimeStamp (member , System .currentTimeMillis ());
188
+ return false ; // User will be purged in the future
189
+ } else {
190
+ // Otherwise, update the last login timestamp with the valid value from Bukkit
191
+ getPlayers ().setLoginTimeStamp (member , lastLoginTimestamp );
192
+ }
193
+ }
194
+ // Check if the difference between now and the last login is greater than the allowed days
195
+ return System .currentTimeMillis () - lastLoginTimestamp > daysInMilliseconds ;
160
196
}
161
197
198
+
162
199
/**
163
200
* @return the inPurge
164
201
*/
0 commit comments