1414import xyz .earthcow .networkjoinmessages .common .util .H2PlayerJoinTracker ;
1515import xyz .earthcow .networkjoinmessages .common .util .MessageType ;
1616
17+ import java .util .Map ;
18+ import java .util .UUID ;
19+ import java .util .concurrent .ConcurrentHashMap ;
20+
1721public class CorePlayerListener {
1822
1923 private final CorePlugin plugin ;
@@ -22,11 +26,15 @@ public class CorePlayerListener {
2226
2327 private H2PlayerJoinTracker firstJoinTracker ;
2428
29+ private final Map <UUID , Integer > leaveJoinBuffer ;
30+
2531 @ Nullable
2632 private final SayanVanishHook sayanVanishHook ;
2733
2834 @ Nullable
2935 private final PremiumVanish premiumVanish ;
36+
37+ private final String PVJoinVanishedPerm = "pv.joinvanished" ;
3038
3139 public CorePlayerListener (CorePlugin plugin , Storage storage , MessageHandler messageHandler , @ Nullable SayanVanishHook sayanVanishHook , @ Nullable PremiumVanish premiumVanish ) {
3240 this .plugin = plugin ;
@@ -42,6 +50,8 @@ public CorePlayerListener(CorePlugin plugin, Storage storage, MessageHandler mes
4250 plugin .getCoreLogger ().debug ("Exception: " + ex );
4351 }
4452
53+ this .leaveJoinBuffer = new ConcurrentHashMap <>();
54+
4555 }
4656
4757 /**
@@ -51,13 +61,14 @@ public CorePlayerListener(CorePlugin plugin, Storage storage, MessageHandler mes
5161 */
5262 private boolean isSilentEvent (@ NotNull CorePlayer player ) {
5363 // Event is silent if, the player has a silent message state OR
54- // premiumVanish is present, the treat vanished players as silent option is true, and the player is vanished
64+ // premiumVanish is present, the treat vanished players as silent option is true, and the player is vanished or
65+ // the TreatVanishedOnJoin option is enabled and the player has the pv.joinvanished permission
5566 plugin .getCoreLogger ().debug ("Checking if the event for player " + player .getName () + " should been silent:" );
5667 plugin .getCoreLogger ().debug (String .format (
5768 "silent message state: %s,%n" +
5869 "SayanVanish hook is NOT null: %s, SVTreatVanishedPlayersAsSilent: %s, SayanVanish player is vanished: %s,%n" +
5970 "PremiumVanish hook is NOT null: %s, PVTreatVanishedPlayersAsSilent: %s, PremiumVanish player is vanished: %s,%n" +
60- "PremiumVanish event hidden: %s"
71+ "PremiumVanish event hidden: %s, PVTreatVanishedOnJoin: %s, Player has pv.joinvanished permission: %s "
6172 ,
6273 storage .getSilentMessageState (player ),
6374 sayanVanishHook != null ,
@@ -66,12 +77,18 @@ private boolean isSilentEvent(@NotNull CorePlayer player) {
6677 premiumVanish != null ,
6778 storage .isPVTreatVanishedPlayersAsSilent (),
6879 premiumVanish != null ? premiumVanish .isVanished (player .getUniqueId ()) : "NA" ,
69- player .getPremiumVanishHidden ()
80+ player .getPremiumVanishHidden (),
81+ storage .isPVTreatVanishedOnJoin (),
82+ player .hasPermission (PVJoinVanishedPerm )
7083 ));
84+ if (storage .isPVTreatVanishedOnJoin () && player .hasPermission (PVJoinVanishedPerm )) {
85+ player .setPremiumVanishHidden (true );
86+ }
7187 return storage .getSilentMessageState (player ) ||
7288 (sayanVanishHook != null && storage .isSVTreatVanishedPlayersAsSilent () && sayanVanishHook .isVanished (player ))
7389 ||
74- (premiumVanish != null && storage .isPVTreatVanishedPlayersAsSilent () && (premiumVanish .isVanished (player .getUniqueId ()) || player .getPremiumVanishHidden ()));
90+ (premiumVanish != null && storage .isPVTreatVanishedPlayersAsSilent ()
91+ && (premiumVanish .isVanished (player .getUniqueId ()) || player .getPremiumVanishHidden ()));
7592 }
7693
7794 private boolean shouldNotBroadcast (@ NotNull CorePlayer player , @ NotNull MessageType type ) {
@@ -135,6 +152,14 @@ private boolean shouldNotBroadcast(@NotNull CorePlayer player, @NotNull MessageT
135152 " - suppress limbo join" );
136153 return true ;
137154 }
155+
156+ Integer leaveJoinBufferTaskId = leaveJoinBuffer .remove (player .getUniqueId ());
157+ if (leaveJoinBufferTaskId != null ) {
158+ plugin .cancelTask (leaveJoinBufferTaskId );
159+ plugin .getCoreLogger ().debug ("Skipping " + player .getName () +
160+ " - returned within LeaveJoinBufferDuration" );
161+ return true ;
162+ }
138163 }
139164 case LEAVE -> {
140165 if (!storage .isConnected (player ) || !storage .isLeaveNetworkMessageEnabled () || storage .isBlacklisted (player )) {
@@ -149,6 +174,17 @@ private boolean shouldNotBroadcast(@NotNull CorePlayer player, @NotNull MessageT
149174 " - suppress limbo leave" );
150175 return true ;
151176 }
177+
178+ if (storage .getLeaveJoinBufferDuration () > 0 && leaveJoinBuffer .get (player .getUniqueId ()) == null ) {
179+ leaveJoinBuffer .put (player .getUniqueId (), plugin .runTaskAsyncLater (() -> {
180+ this .broadcastLeaveMessage (player );
181+ leaveJoinBuffer .remove (player .getUniqueId ());
182+ },
183+ storage .getLeaveJoinBufferDuration ()));
184+ plugin .getCoreLogger ().debug ("Skipping " + player .getName () +
185+ " - allotting buffer time to rejoin before broadcasting leave message" );
186+ return true ;
187+ }
152188 }
153189 }
154190 return false ;
@@ -301,6 +337,14 @@ public void onDisconnect(@NotNull CorePlayer player) {
301337 return ;
302338 }
303339
340+ broadcastLeaveMessage (player );
341+
342+ plugin .getPlayerManager ().removePlayer (player .getUniqueId ());
343+ storage .setConnected (player , false );
344+ messageHandler .stopLeaveCacheTaskForPlayer (player );
345+ }
346+
347+ private void broadcastLeaveMessage (@ NotNull CorePlayer player ) {
304348 String message = player .getCachedLeaveMessage ();
305349
306350 // Silent
@@ -312,18 +356,14 @@ public void onDisconnect(@NotNull CorePlayer player) {
312356 Component formattedMessage = Formatter .deserialize (message );
313357 // Call the custom NetworkLeaveEvent
314358 NetworkLeaveEvent networkLeaveEvent = new NetworkLeaveEvent (
315- player ,
316- player .getCurrentServer ().getName (),
317- storage .getServerDisplayName (player .getCurrentServer ().getName ()),
318- isSilent ,
319- Formatter .serialize (formattedMessage ),
320- Formatter .sanitize (formattedMessage )
359+ player ,
360+ player .getCurrentServer ().getName (),
361+ storage .getServerDisplayName (player .getCurrentServer ().getName ()),
362+ isSilent ,
363+ Formatter .serialize (formattedMessage ),
364+ Formatter .sanitize (formattedMessage )
321365 );
322366 plugin .fireEvent (networkLeaveEvent );
323-
324- plugin .getPlayerManager ().removePlayer (player .getUniqueId ());
325- storage .setConnected (player , false );
326- messageHandler .stopLeaveCacheTaskForPlayer (player );
327367 }
328368
329369 public H2PlayerJoinTracker getPlayerJoinTracker () {
0 commit comments