2011-09-29 01:38:56 +02:00
package com.earth2me.essentials ;
2020-04-10 21:44:45 +02:00
import com.earth2me.essentials.commands.Commandfireball ;
2022-12-24 18:58:51 +01:00
import com.earth2me.essentials.craftbukkit.Inventories ;
2011-11-18 04:18:03 +01:00
import com.earth2me.essentials.textreader.IText ;
import com.earth2me.essentials.textreader.KeywordReplacer ;
import com.earth2me.essentials.textreader.TextInput ;
import com.earth2me.essentials.textreader.TextPager ;
2024-02-04 03:13:18 +01:00
import com.earth2me.essentials.utils.AdventureUtil ;
2024-02-03 21:38:14 +01:00
import com.earth2me.essentials.utils.CommonPlaceholders ;
2016-06-28 04:40:47 +02:00
import com.earth2me.essentials.utils.DateUtil ;
2021-05-21 19:28:22 +02:00
import com.earth2me.essentials.utils.FormatUtil ;
2013-06-08 23:31:19 +02:00
import com.earth2me.essentials.utils.LocationUtil ;
2018-09-01 11:35:08 +02:00
import com.earth2me.essentials.utils.MaterialUtil ;
2020-01-14 08:50:48 +01:00
import com.earth2me.essentials.utils.VersionUtil ;
2019-02-20 13:25:05 +01:00
import io.papermc.lib.PaperLib ;
2013-10-11 04:44:41 +02:00
import net.ess3.api.IEssentials ;
2020-03-13 03:08:11 +01:00
import net.ess3.api.events.AfkStatusChangeEvent ;
2021-09-15 23:23:31 +02:00
import net.ess3.provider.CommandSendListenerProvider ;
import net.ess3.provider.providers.BukkitCommandSendListenerProvider ;
import net.ess3.provider.providers.PaperCommandSendListenerProvider ;
2021-03-06 20:22:00 +01:00
import net.essentialsx.api.v2.events.AsyncUserDataLoadEvent ;
2024-02-03 21:38:14 +01:00
import net.kyori.adventure.text.Component ;
2020-10-03 19:46:05 +02:00
import org.bukkit.BanEntry ;
import org.bukkit.BanList ;
import org.bukkit.GameMode ;
import org.bukkit.Location ;
import org.bukkit.Material ;
import org.bukkit.World ;
2021-02-20 17:30:07 +01:00
import org.bukkit.command.Command ;
import org.bukkit.command.FormattedCommandAlias ;
2016-01-13 00:53:09 +01:00
import org.bukkit.command.PluginCommand ;
2021-01-08 21:11:35 +01:00
import org.bukkit.enchantments.Enchantment ;
2012-06-03 17:34:27 +02:00
import org.bukkit.entity.HumanEntity ;
2011-09-29 01:38:56 +02:00
import org.bukkit.entity.Player ;
2012-01-20 05:20:37 +01:00
import org.bukkit.event.EventHandler ;
import org.bukkit.event.EventPriority ;
import org.bukkit.event.Listener ;
2016-11-06 11:54:49 +01:00
import org.bukkit.event.inventory.ClickType ;
2012-03-25 03:33:52 +02:00
import org.bukkit.event.inventory.InventoryClickEvent ;
import org.bukkit.event.inventory.InventoryCloseEvent ;
import org.bukkit.event.inventory.InventoryType ;
2020-10-03 19:46:05 +02:00
import org.bukkit.event.player.AsyncPlayerChatEvent ;
import org.bukkit.event.player.PlayerBucketEmptyEvent ;
import org.bukkit.event.player.PlayerChangedWorldEvent ;
import org.bukkit.event.player.PlayerCommandPreprocessEvent ;
import org.bukkit.event.player.PlayerEggThrowEvent ;
import org.bukkit.event.player.PlayerFishEvent ;
import org.bukkit.event.player.PlayerInteractEvent ;
import org.bukkit.event.player.PlayerJoinEvent ;
import org.bukkit.event.player.PlayerLoginEvent ;
2013-10-11 04:44:41 +02:00
import org.bukkit.event.player.PlayerLoginEvent.Result ;
2020-10-03 19:46:05 +02:00
import org.bukkit.event.player.PlayerMoveEvent ;
import org.bukkit.event.player.PlayerQuitEvent ;
import org.bukkit.event.player.PlayerRespawnEvent ;
import org.bukkit.event.player.PlayerTeleportEvent ;
2011-12-06 23:56:38 +01:00
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause ;
2013-01-01 19:39:23 +01:00
import org.bukkit.inventory.Inventory ;
2012-06-03 17:34:27 +02:00
import org.bukkit.inventory.InventoryHolder ;
2011-09-29 01:38:56 +02:00
import org.bukkit.inventory.ItemStack ;
2016-11-06 11:54:49 +01:00
import org.bukkit.inventory.PlayerInventory ;
2011-09-29 01:38:56 +02:00
2015-04-15 06:06:16 +02:00
import java.io.IOException ;
2020-04-01 20:37:55 +02:00
import java.lang.management.ManagementFactory ;
2016-07-12 21:36:55 +02:00
import java.text.NumberFormat ;
2020-10-03 19:46:05 +02:00
import java.util.ArrayList ;
import java.util.Date ;
import java.util.HashMap ;
import java.util.HashSet ;
import java.util.Iterator ;
import java.util.List ;
import java.util.Locale ;
2016-06-28 04:40:47 +02:00
import java.util.Map.Entry ;
2020-10-03 19:46:05 +02:00
import java.util.Set ;
2021-08-09 21:22:09 +02:00
import java.util.UUID ;
import java.util.concurrent.ConcurrentHashMap ;
2021-09-15 23:23:31 +02:00
import java.util.function.Predicate ;
2015-04-15 06:06:16 +02:00
import java.util.logging.Level ;
2016-06-28 04:40:47 +02:00
import java.util.regex.Pattern ;
2015-04-15 06:06:16 +02:00
2024-02-03 21:38:14 +01:00
import static com.earth2me.essentials.I18n.tlLiteral ;
2015-04-15 06:06:16 +02:00
2021-07-27 22:23:20 +02:00
public class EssentialsPlayerListener implements Listener , FakeAccessor {
2015-04-15 06:06:16 +02:00
private final transient IEssentials ess ;
2021-08-09 21:22:09 +02:00
private final ConcurrentHashMap < UUID , Integer > pendingMotdTasks = new ConcurrentHashMap < > ( ) ;
2015-04-15 06:06:16 +02:00
public EssentialsPlayerListener ( final IEssentials parent ) {
this . ess = parent ;
}
2020-02-22 11:02:53 +01:00
private static boolean isEntityPickupEvent ( ) {
try {
Class . forName ( " org.bukkit.event.entity.EntityPickupItemEvent " ) ;
return true ;
2020-10-03 19:46:05 +02:00
} catch ( final ClassNotFoundException ignored ) {
2020-02-22 11:02:53 +01:00
return false ;
}
}
private static boolean isCommandSendEvent ( ) {
try {
Class . forName ( " org.bukkit.event.player.PlayerCommandSendEvent " ) ;
return true ;
2020-10-03 19:46:05 +02:00
} catch ( final ClassNotFoundException ignored ) {
2020-02-22 11:02:53 +01:00
return false ;
}
}
2021-09-15 23:23:31 +02:00
private static boolean isPaperCommandSendEvent ( ) {
try {
Class . forName ( " com.destroystokyo.paper.event.brigadier.AsyncPlayerSendCommandsEvent " ) ;
return true ;
} catch ( final ClassNotFoundException ignored ) {
return false ;
}
}
2020-04-10 21:44:45 +02:00
private static boolean isArrowPickupEvent ( ) {
try {
Class . forName ( " org.bukkit.event.player.PlayerPickupArrowEvent " ) ;
return true ;
2020-10-03 19:46:05 +02:00
} catch ( final ClassNotFoundException ignored ) {
2020-04-10 21:44:45 +02:00
return false ;
}
}
2023-04-03 00:29:29 +02:00
private static boolean isGameEventEvent ( ) {
try {
Class . forName ( " org.bukkit.event.block.BlockReceiveGameEvent " ) ;
return true ;
} catch ( final ClassNotFoundException ignored ) {
return false ;
}
}
2017-07-28 21:13:59 +02:00
public void registerEvents ( ) {
ess . getServer ( ) . getPluginManager ( ) . registerEvents ( this , ess ) ;
2019-03-31 21:35:47 +02:00
2020-04-10 21:44:45 +02:00
if ( isArrowPickupEvent ( ) ) {
ess . getServer ( ) . getPluginManager ( ) . registerEvents ( new ArrowPickupListener ( ) , ess ) ;
}
2023-04-03 00:29:29 +02:00
if ( isGameEventEvent ( ) ) {
ess . getServer ( ) . getPluginManager ( ) . registerEvents ( new SculkListener1_17 ( ) , ess ) ;
}
2018-10-27 16:37:29 +02:00
if ( isEntityPickupEvent ( ) ) {
2019-03-31 21:35:47 +02:00
ess . getServer ( ) . getPluginManager ( ) . registerEvents ( new PickupListener1_12 ( ) , ess ) ;
2018-10-27 16:37:29 +02:00
} else {
2019-03-31 21:35:47 +02:00
ess . getServer ( ) . getPluginManager ( ) . registerEvents ( new PickupListenerPre1_12 ( ) , ess ) ;
}
2021-09-15 23:23:31 +02:00
if ( isPaperCommandSendEvent ( ) ) {
ess . getServer ( ) . getPluginManager ( ) . registerEvents ( new PaperCommandSendListenerProvider ( new CommandSendFilter ( ) ) , ess ) ;
} else if ( isCommandSendEvent ( ) ) {
ess . getServer ( ) . getPluginManager ( ) . registerEvents ( new BukkitCommandSendListenerProvider ( new CommandSendFilter ( ) ) , ess ) ;
2017-07-28 21:13:59 +02:00
}
}
2015-04-15 06:06:16 +02:00
@EventHandler ( priority = EventPriority . NORMAL )
public void onPlayerRespawn ( final PlayerRespawnEvent event ) {
final User user = ess . getUser ( event . getPlayer ( ) ) ;
updateCompass ( user ) ;
user . setDisplayNick ( ) ;
if ( ess . getSettings ( ) . isTeleportInvulnerability ( ) ) {
user . enableInvulnerabilityAfterTeleport ( ) ;
}
}
@EventHandler ( priority = EventPriority . LOWEST )
public void onPlayerChat ( final AsyncPlayerChatEvent event ) {
final User user = ess . getUser ( event . getPlayer ( ) ) ;
if ( user . isMuted ( ) ) {
event . setCancelled ( true ) ;
2017-09-03 23:41:32 +02:00
2020-10-03 19:46:05 +02:00
final String dateDiff = user . getMuteTimeout ( ) > 0 ? DateUtil . formatDateDiff ( user . getMuteTimeout ( ) ) : null ;
2020-07-06 20:52:51 +02:00
if ( dateDiff = = null ) {
2024-02-03 21:38:14 +01:00
if ( user . hasMuteReason ( ) ) {
user . sendTl ( " voiceSilencedReason " , user . getMuteReason ( ) ) ;
} else {
user . sendTl ( " voiceSilenced " ) ;
}
2020-07-06 20:52:51 +02:00
} else {
2024-02-03 21:38:14 +01:00
if ( user . hasMuteReason ( ) ) {
user . sendTl ( " voiceSilencedReasonTime " , dateDiff , user . getMuteReason ( ) ) ;
} else {
user . sendTl ( " voiceSilencedTime " , dateDiff ) ;
}
2020-07-06 20:52:51 +02:00
}
2017-09-03 23:41:32 +02:00
2024-02-04 03:13:18 +01:00
ess . getLogger ( ) . info ( AdventureUtil . miniToLegacy ( tlLiteral ( " mutedUserSpeaks " , user . getName ( ) , event . getMessage ( ) ) ) ) ;
2015-04-15 06:06:16 +02:00
}
try {
final Iterator < Player > it = event . getRecipients ( ) . iterator ( ) ;
while ( it . hasNext ( ) ) {
final User u = ess . getUser ( it . next ( ) ) ;
if ( u . isIgnoredPlayer ( user ) ) {
it . remove ( ) ;
}
}
2020-10-03 19:46:05 +02:00
} catch ( final UnsupportedOperationException ex ) {
2015-04-15 06:06:16 +02:00
if ( ess . getSettings ( ) . isDebug ( ) ) {
ess . getLogger ( ) . log ( Level . INFO , " Ignore could not block chat due to custom chat plugin event. " , ex ) ;
} else {
ess . getLogger ( ) . info ( " Ignore could not block chat due to custom chat plugin event. " ) ;
}
}
2021-01-01 01:20:08 +01:00
user . updateActivityOnChat ( true ) ;
2015-04-15 06:06:16 +02:00
user . setDisplayNick ( ) ;
}
@EventHandler ( priority = EventPriority . HIGH , ignoreCancelled = true )
public void onPlayerMove ( final PlayerMoveEvent event ) {
if ( event . getFrom ( ) . getBlockX ( ) = = event . getTo ( ) . getBlockX ( ) & & event . getFrom ( ) . getBlockZ ( ) = = event . getTo ( ) . getBlockZ ( ) & & event . getFrom ( ) . getBlockY ( ) = = event . getTo ( ) . getBlockY ( ) ) {
return ;
}
2022-12-25 21:59:23 +01:00
final User user = ess . getUser ( event . getPlayer ( ) ) ;
2015-04-15 06:06:16 +02:00
2022-12-25 21:59:23 +01:00
if ( user . isFreeze ( ) ) {
final Location from = event . getFrom ( ) ;
final Location to = event . getTo ( ) . clone ( ) ;
to . setX ( from . getX ( ) ) ;
to . setY ( from . getY ( ) ) ;
to . setZ ( from . getZ ( ) ) ;
try {
2022-12-25 22:14:20 +01:00
event . setTo ( LocationUtil . getSafeDestination ( ess , to ) ) ;
2022-12-25 21:59:23 +01:00
} catch ( final Exception ex ) {
event . setTo ( to ) ;
2015-04-15 06:06:16 +02:00
}
2022-12-25 21:59:23 +01:00
return ;
}
2015-04-15 06:06:16 +02:00
2022-12-25 21:59:23 +01:00
if ( ! ess . getSettings ( ) . cancelAfkOnMove ( ) & & ! ess . getSettings ( ) . getFreezeAfkPlayers ( ) ) {
2015-04-15 06:06:16 +02:00
return ;
}
if ( user . isAfk ( ) & & ess . getSettings ( ) . getFreezeAfkPlayers ( ) ) {
final Location from = event . getFrom ( ) ;
final Location origTo = event . getTo ( ) ;
final Location to = origTo . clone ( ) ;
2018-03-26 09:50:42 +02:00
if ( origTo . getY ( ) > = from . getBlockY ( ) + 1 ) {
user . updateActivityOnMove ( true ) ;
2015-04-15 06:06:16 +02:00
return ;
}
to . setX ( from . getX ( ) ) ;
to . setY ( from . getY ( ) ) ;
to . setZ ( from . getZ ( ) ) ;
try {
2022-06-15 17:43:57 +02:00
if ( event . getPlayer ( ) . getAllowFlight ( ) ) {
// Don't teleport to a safe location here, they are either a god or flying
throw new Exception ( ) ;
}
2021-11-24 05:44:08 +01:00
event . setTo ( LocationUtil . getSafeDestination ( ess , to ) ) ;
2020-10-03 19:46:05 +02:00
} catch ( final Exception ex ) {
2015-04-15 06:06:16 +02:00
event . setTo ( to ) ;
}
return ;
}
final Location afk = user . getAfkPosition ( ) ;
if ( afk = = null | | ! event . getTo ( ) . getWorld ( ) . equals ( afk . getWorld ( ) ) | | afk . distanceSquared ( event . getTo ( ) ) > 9 ) {
2018-08-26 16:17:07 +02:00
user . updateActivityOnMove ( true ) ;
2015-04-15 06:06:16 +02:00
}
}
@EventHandler ( priority = EventPriority . HIGHEST )
public void onPlayerQuit ( final PlayerQuitEvent event ) {
final User user = ess . getUser ( event . getPlayer ( ) ) ;
2021-08-09 21:22:09 +02:00
final Integer pendingId = pendingMotdTasks . remove ( user . getUUID ( ) ) ;
if ( pendingId ! = null ) {
ess . getScheduler ( ) . cancelTask ( pendingId ) ;
}
2020-07-08 00:16:20 +02:00
if ( hideJoinQuitMessages ( ) | | ( ess . getSettings ( ) . allowSilentJoinQuit ( ) & & user . isAuthorized ( " essentials.silentquit " ) ) ) {
2015-04-15 06:06:16 +02:00
event . setQuitMessage ( null ) ;
} else if ( ess . getSettings ( ) . isCustomQuitMessage ( ) & & event . getQuitMessage ( ) ! = null ) {
final Player player = event . getPlayer ( ) ;
2018-12-06 15:05:50 +01:00
final String msg = ess . getSettings ( ) . getCustomQuitMessage ( )
2020-10-03 19:46:05 +02:00
. replace ( " {PLAYER} " , player . getDisplayName ( ) )
. replace ( " {USERNAME} " , player . getName ( ) )
2023-10-29 00:29:11 +02:00
. replace ( " {ONLINE} " , NumberFormat . getInstance ( ) . format ( ess . getOnlinePlayers ( ) . size ( ) - 1 ) ) // Subtract 1 as the leaving player is still online during this time
2021-05-21 19:28:22 +02:00
. replace ( " {UPTIME} " , DateUtil . formatDateDiff ( ManagementFactory . getRuntimeMXBean ( ) . getStartTime ( ) ) )
. replace ( " {PREFIX} " , FormatUtil . replaceFormat ( ess . getPermissionsHandler ( ) . getPrefix ( player ) ) )
. replace ( " {SUFFIX} " , FormatUtil . replaceFormat ( ess . getPermissionsHandler ( ) . getSuffix ( player ) ) ) ;
2020-02-22 11:02:53 +01:00
2018-12-06 15:05:50 +01:00
event . setQuitMessage ( msg . isEmpty ( ) ? null : msg ) ;
2015-04-15 06:06:16 +02:00
}
2015-09-30 03:56:04 +02:00
user . startTransaction ( ) ;
2015-04-15 06:06:16 +02:00
if ( ess . getSettings ( ) . removeGodOnDisconnect ( ) & & user . isGodModeEnabled ( ) ) {
user . setGodModeEnabled ( false ) ;
}
if ( user . isVanished ( ) ) {
2022-07-24 00:35:14 +02:00
user . setLeavingHidden ( true ) ;
2015-04-15 06:06:16 +02:00
user . setVanished ( false ) ;
}
user . setLogoutLocation ( ) ;
if ( user . isRecipeSee ( ) ) {
user . getBase ( ) . getOpenInventory ( ) . getTopInventory ( ) . clear ( ) ;
}
2020-10-03 19:46:05 +02:00
final ArrayList < HumanEntity > viewers = new ArrayList < > ( user . getBase ( ) . getInventory ( ) . getViewers ( ) ) ;
for ( final HumanEntity viewer : viewers ) {
2015-04-15 06:06:16 +02:00
if ( viewer instanceof Player ) {
2020-10-03 19:46:05 +02:00
final User uviewer = ess . getUser ( ( Player ) viewer ) ;
2015-04-15 06:06:16 +02:00
if ( uviewer . isInvSee ( ) ) {
uviewer . getBase ( ) . closeInventory ( ) ;
}
}
}
2020-03-13 03:08:11 +01:00
user . updateActivity ( false , AfkStatusChangeEvent . Cause . QUIT ) ;
2015-09-30 03:56:04 +02:00
if ( ! user . isHidden ( ) ) {
user . setLastLogout ( System . currentTimeMillis ( ) ) ;
}
user . stopTransaction ( ) ;
2015-04-15 06:06:16 +02:00
user . dispose ( ) ;
}
@EventHandler ( priority = EventPriority . HIGHEST )
public void onPlayerJoin ( final PlayerJoinEvent event ) {
final String joinMessage = event . getJoinMessage ( ) ;
2019-12-31 14:58:09 +01:00
ess . runTaskAsynchronously ( ( ) - > delayedJoin ( event . getPlayer ( ) , joinMessage ) ) ;
2020-07-08 00:16:20 +02:00
if ( hideJoinQuitMessages ( ) | | ess . getSettings ( ) . allowSilentJoinQuit ( ) | | ess . getSettings ( ) . isCustomJoinMessage ( ) ) {
2015-04-15 06:06:16 +02:00
event . setJoinMessage ( null ) ;
}
}
2020-07-08 00:16:20 +02:00
private boolean hideJoinQuitMessages ( ) {
return ess . getSettings ( ) . hasJoinQuitMessagePlayerCount ( ) & & ess . getServer ( ) . getOnlinePlayers ( ) . size ( ) > ess . getSettings ( ) . getJoinQuitMessagePlayerCount ( ) ;
}
2015-04-15 06:06:16 +02:00
public void delayedJoin ( final Player player , final String message ) {
if ( ! player . isOnline ( ) ) {
return ;
}
ess . getBackup ( ) . onPlayerJoin ( ) ;
final User dUser = ess . getUser ( player ) ;
2022-09-04 16:42:43 +02:00
dUser . update ( player ) ;
2015-04-15 06:06:16 +02:00
2015-09-30 03:56:04 +02:00
dUser . startTransaction ( ) ;
2015-04-15 06:06:16 +02:00
if ( dUser . isNPC ( ) ) {
dUser . setNPC ( false ) ;
}
final long currentTime = System . currentTimeMillis ( ) ;
dUser . checkMuteTimeout ( currentTime ) ;
2020-03-13 03:08:11 +01:00
dUser . updateActivity ( false , AfkStatusChangeEvent . Cause . JOIN ) ;
2015-09-30 03:56:04 +02:00
dUser . stopTransaction ( ) ;
2015-04-15 06:06:16 +02:00
class DelayJoinTask implements Runnable {
@Override
public void run ( ) {
final User user = ess . getUser ( player ) ;
if ( ! user . getBase ( ) . isOnline ( ) ) {
return ;
}
user . startTransaction ( ) ;
2021-07-07 17:46:54 +02:00
final String lastAccountName = user . getLastAccountName ( ) ; // For comparison
2015-04-15 06:06:16 +02:00
user . setLastAccountName ( user . getBase ( ) . getName ( ) ) ;
user . setLastLogin ( currentTime ) ;
user . setDisplayNick ( ) ;
updateCompass ( user ) ;
2022-07-24 00:35:14 +02:00
user . setLeavingHidden ( false ) ;
2015-04-15 06:06:16 +02:00
2021-07-07 17:46:54 +02:00
// Check for new username. If they don't want the message, let's just say it's false.
final boolean newUsername = ess . getSettings ( ) . isCustomNewUsernameMessage ( ) & & lastAccountName ! = null & & ! lastAccountName . equals ( user . getBase ( ) . getName ( ) ) ;
2018-03-25 23:12:36 +02:00
if ( ! ess . getVanishedPlayersNew ( ) . isEmpty ( ) & & ! user . isAuthorized ( " essentials.vanish.see " ) ) {
2020-10-03 19:46:05 +02:00
for ( final String p : ess . getVanishedPlayersNew ( ) ) {
final Player toVanish = ess . getServer ( ) . getPlayerExact ( p ) ;
2015-04-15 06:06:16 +02:00
if ( toVanish ! = null & & toVanish . isOnline ( ) ) {
user . getBase ( ) . hidePlayer ( toVanish ) ;
2018-03-25 23:12:36 +02:00
if ( ess . getSettings ( ) . isDebug ( ) ) {
ess . getLogger ( ) . info ( " Hiding vanished player: " + p ) ;
}
2015-04-15 06:06:16 +02:00
}
}
}
if ( user . isAuthorized ( " essentials.sleepingignored " ) ) {
user . getBase ( ) . setSleepingIgnored ( true ) ;
}
2021-07-01 15:43:35 +02:00
final String effectiveMessage ;
2015-04-15 06:06:16 +02:00
if ( ess . getSettings ( ) . allowSilentJoinQuit ( ) & & ( user . isAuthorized ( " essentials.silentjoin " ) | | user . isAuthorized ( " essentials.silentjoin.vanish " ) ) ) {
if ( user . isAuthorized ( " essentials.silentjoin.vanish " ) ) {
user . setVanished ( true ) ;
}
2021-07-01 15:43:35 +02:00
effectiveMessage = null ;
2020-07-08 00:16:20 +02:00
} else if ( message = = null | | hideJoinQuitMessages ( ) ) {
2021-07-01 15:43:35 +02:00
effectiveMessage = null ;
2015-04-15 06:06:16 +02:00
} else if ( ess . getSettings ( ) . isCustomJoinMessage ( ) ) {
2021-07-07 17:46:54 +02:00
final String msg = ( newUsername ? ess . getSettings ( ) . getCustomNewUsernameMessage ( ) : ess . getSettings ( ) . getCustomJoinMessage ( ) )
2020-10-03 19:46:05 +02:00
. replace ( " {PLAYER} " , player . getDisplayName ( ) ) . replace ( " {USERNAME} " , player . getName ( ) )
2022-09-04 16:42:43 +02:00
. replace ( " {UNIQUE} " , NumberFormat . getInstance ( ) . format ( ess . getUsers ( ) . getUserCount ( ) ) )
2020-10-03 19:46:05 +02:00
. replace ( " {ONLINE} " , NumberFormat . getInstance ( ) . format ( ess . getOnlinePlayers ( ) . size ( ) ) )
2021-05-21 19:28:22 +02:00
. replace ( " {UPTIME} " , DateUtil . formatDateDiff ( ManagementFactory . getRuntimeMXBean ( ) . getStartTime ( ) ) )
. replace ( " {PREFIX} " , FormatUtil . replaceFormat ( ess . getPermissionsHandler ( ) . getPrefix ( player ) ) )
2021-07-07 17:46:54 +02:00
. replace ( " {SUFFIX} " , FormatUtil . replaceFormat ( ess . getPermissionsHandler ( ) . getSuffix ( player ) ) )
2021-07-09 18:33:44 +02:00
. replace ( " {OLDUSERNAME} " , lastAccountName = = null ? " " : lastAccountName ) ;
2018-12-06 15:05:50 +01:00
if ( ! msg . isEmpty ( ) ) {
ess . getServer ( ) . broadcastMessage ( msg ) ;
}
2021-07-01 15:43:35 +02:00
effectiveMessage = msg . isEmpty ( ) ? null : msg ;
2015-04-15 06:06:16 +02:00
} else if ( ess . getSettings ( ) . allowSilentJoinQuit ( ) ) {
ess . getServer ( ) . broadcastMessage ( message ) ;
2021-07-01 15:43:35 +02:00
effectiveMessage = message ;
} else {
effectiveMessage = message ;
2015-04-15 06:06:16 +02:00
}
2021-07-01 15:43:35 +02:00
ess . runTaskAsynchronously ( ( ) - > ess . getServer ( ) . getPluginManager ( ) . callEvent ( new AsyncUserDataLoadEvent ( user , effectiveMessage ) ) ) ;
2021-08-10 16:51:33 +02:00
if ( ess . getSettings ( ) . getMotdDelay ( ) > = 0 ) {
2021-08-09 21:22:09 +02:00
final int motdDelay = ess . getSettings ( ) . getMotdDelay ( ) / 50 ;
final DelayMotdTask motdTask = new DelayMotdTask ( user ) ;
if ( motdDelay > 0 ) {
pendingMotdTasks . put ( user . getUUID ( ) , ess . scheduleSyncDelayedTask ( motdTask , motdDelay ) ) ;
} else {
motdTask . run ( ) ;
}
2015-04-15 06:06:16 +02:00
}
if ( ! ess . getSettings ( ) . isCommandDisabled ( " mail " ) & & user . isAuthorized ( " essentials.mail " ) ) {
2021-07-01 17:23:32 +02:00
if ( user . getUnreadMailAmount ( ) = = 0 ) {
2015-04-20 17:56:45 +02:00
if ( ess . getSettings ( ) . isNotifyNoNewMail ( ) ) {
2024-02-03 21:38:14 +01:00
user . sendTl ( " noNewMail " ) ; // Only notify if they want us to.
2015-04-16 16:25:29 +02:00
}
2015-04-15 06:06:16 +02:00
} else {
2017-06-22 23:54:51 +02:00
user . notifyOfMail ( ) ;
2015-04-15 06:06:16 +02:00
}
}
2021-08-09 21:14:15 +02:00
if ( user . isAuthorized ( " essentials.updatecheck " ) ) {
ess . runTaskAsynchronously ( ( ) - > {
2024-02-03 21:38:14 +01:00
for ( final Component component : ess . getUpdateChecker ( ) . getVersionMessages ( false , false , user . getSource ( ) ) ) {
user . sendComponent ( component ) ;
2021-08-09 21:14:15 +02:00
}
} ) ;
}
2015-04-15 06:06:16 +02:00
if ( user . isAuthorized ( " essentials.fly.safelogin " ) ) {
user . getBase ( ) . setFallDistance ( 0 ) ;
2021-11-24 05:44:08 +01:00
if ( LocationUtil . shouldFly ( ess , user . getLocation ( ) ) ) {
2015-04-15 06:06:16 +02:00
user . getBase ( ) . setAllowFlight ( true ) ;
user . getBase ( ) . setFlying ( true ) ;
2016-01-19 03:21:29 +01:00
if ( ess . getSettings ( ) . isSendFlyEnableOnJoin ( ) ) {
2024-02-03 21:38:14 +01:00
user . sendTl ( " flyMode " , CommonPlaceholders . enableDisable ( user . getSource ( ) , true ) , CommonPlaceholders . displayName ( user ) ) ;
2016-01-19 03:21:29 +01:00
}
2015-04-15 06:06:16 +02:00
}
}
if ( ! user . isAuthorized ( " essentials.speed " ) ) {
user . getBase ( ) . setFlySpeed ( 0 . 1f ) ;
user . getBase ( ) . setWalkSpeed ( 0 . 2f ) ;
}
2015-12-06 21:30:40 +01:00
if ( user . isSocialSpyEnabled ( ) & & ! user . isAuthorized ( " essentials.socialspy " ) ) {
user . setSocialSpyEnabled ( false ) ;
ess . getLogger ( ) . log ( Level . INFO , " Set socialspy to false for {0} because they had it enabled without permission. " , user . getName ( ) ) ;
}
2017-08-13 17:42:59 +02:00
if ( user . isGodModeEnabled ( ) & & ! user . isAuthorized ( " essentials.god " ) ) {
user . setGodModeEnabled ( false ) ;
ess . getLogger ( ) . log ( Level . INFO , " Set god mode to false for {0} because they had it enabled without permission. " , user . getName ( ) ) ;
}
2020-02-22 11:02:53 +01:00
2018-06-15 20:09:27 +02:00
user . setConfirmingClearCommand ( null ) ;
user . getConfirmingPayments ( ) . clear ( ) ;
2017-08-13 17:42:59 +02:00
2015-04-15 06:06:16 +02:00
user . stopTransaction ( ) ;
}
2017-07-28 20:20:44 +02:00
class DelayMotdTask implements Runnable {
2020-04-25 14:08:57 +02:00
private final User user ;
2017-07-28 20:20:44 +02:00
2020-10-03 19:46:05 +02:00
DelayMotdTask ( final User user ) {
2017-07-28 20:20:44 +02:00
this . user = user ;
}
@Override
public void run ( ) {
2021-08-09 21:22:09 +02:00
pendingMotdTasks . remove ( user . getUUID ( ) ) ;
2017-07-28 20:20:44 +02:00
IText tempInput = null ;
if ( ! ess . getSettings ( ) . isCommandDisabled ( " motd " ) ) {
try {
tempInput = new TextInput ( user . getSource ( ) , " motd " , true , ess ) ;
2020-10-03 19:46:05 +02:00
} catch ( final IOException ex ) {
2017-07-28 20:20:44 +02:00
if ( ess . getSettings ( ) . isDebug ( ) ) {
2022-06-27 20:54:10 +02:00
ess . getLogger ( ) . log ( Level . WARNING , ex . getMessage ( ) , ex ) ;
2017-07-28 20:20:44 +02:00
} else {
2022-06-27 20:54:10 +02:00
ess . getLogger ( ) . log ( Level . WARNING , ex . getMessage ( ) ) ;
2017-07-28 20:20:44 +02:00
}
}
}
final IText input = tempInput ;
2018-02-01 02:01:51 +01:00
if ( input ! = null & & ! input . getLines ( ) . isEmpty ( ) & & user . isAuthorized ( " essentials.motd " ) ) {
2017-07-28 20:20:44 +02:00
final IText output = new KeywordReplacer ( input , user . getSource ( ) , ess ) ;
final TextPager pager = new TextPager ( output , true ) ;
pager . showPage ( " 1 " , null , " motd " , user . getSource ( ) ) ;
}
}
}
2015-04-15 06:06:16 +02:00
}
ess . scheduleSyncDelayedTask ( new DelayJoinTask ( ) ) ;
}
// Makes the compass item ingame always point to the first essentials home. #EasterEgg
2018-06-15 20:20:06 +02:00
// EssentialsX: This can now optionally require a permission to enable, if set in the config.
2015-04-15 06:06:16 +02:00
private void updateCompass ( final User user ) {
2018-06-15 20:20:06 +02:00
if ( ess . getSettings ( ) . isCompassTowardsHomePerm ( ) & & ! user . isAuthorized ( " essentials.home.compass " ) ) return ;
2020-10-03 19:46:05 +02:00
final Location loc = user . getHome ( user . getLocation ( ) ) ;
2015-04-15 06:06:16 +02:00
if ( loc = = null ) {
2020-06-27 21:17:35 +02:00
PaperLib . getBedSpawnLocationAsync ( user . getBase ( ) , false ) . thenAccept ( location - > {
if ( location ! = null ) {
user . getBase ( ) . setCompassTarget ( location ) ;
}
} ) ;
return ;
2015-04-15 06:06:16 +02:00
}
2020-06-27 21:17:35 +02:00
user . getBase ( ) . setCompassTarget ( loc ) ;
2015-04-15 06:06:16 +02:00
}
2017-08-12 14:46:27 +02:00
@EventHandler ( priority = EventPriority . LOW )
public void onPlayerLoginBanned ( final PlayerLoginEvent event ) {
2020-10-03 19:46:05 +02:00
if ( event . getResult ( ) = = Result . KICK_BANNED ) {
BanEntry banEntry = ess . getServer ( ) . getBanList ( BanList . Type . NAME ) . getBanEntry ( event . getPlayer ( ) . getName ( ) ) ;
if ( banEntry ! = null ) {
final Date banExpiry = banEntry . getExpiration ( ) ;
if ( banExpiry ! = null ) {
final String expiry = DateUtil . formatDateDiff ( banExpiry . getTime ( ) ) ;
2024-02-03 21:38:14 +01:00
event . setKickMessage ( tlLiteral ( " tempbanJoin " , expiry , banEntry . getReason ( ) ) ) ;
2017-08-12 14:46:27 +02:00
} else {
2024-02-03 21:38:14 +01:00
event . setKickMessage ( tlLiteral ( " banJoin " , banEntry . getReason ( ) ) ) ;
2017-08-12 14:46:27 +02:00
}
2020-10-03 19:46:05 +02:00
} else {
banEntry = ess . getServer ( ) . getBanList ( BanList . Type . IP ) . getBanEntry ( event . getAddress ( ) . getHostAddress ( ) ) ;
if ( banEntry ! = null ) {
2024-02-03 21:38:14 +01:00
event . setKickMessage ( tlLiteral ( " banIpJoin " , banEntry . getReason ( ) ) ) ;
2020-10-03 19:46:05 +02:00
}
}
2017-08-12 14:46:27 +02:00
}
}
2015-04-15 06:06:16 +02:00
@EventHandler ( priority = EventPriority . HIGH )
public void onPlayerLogin ( final PlayerLoginEvent event ) {
2020-10-03 19:46:05 +02:00
if ( event . getResult ( ) = = Result . KICK_FULL ) {
final User kfuser = ess . getUser ( event . getPlayer ( ) ) ;
2022-09-04 16:42:43 +02:00
kfuser . update ( event . getPlayer ( ) ) ;
2020-10-03 19:46:05 +02:00
if ( kfuser . isAuthorized ( " essentials.joinfullserver " ) ) {
event . allow ( ) ;
return ;
}
2021-01-11 06:10:07 +01:00
if ( ess . getSettings ( ) . isCustomServerFullMessage ( ) ) {
2024-02-03 21:38:14 +01:00
event . disallow ( Result . KICK_FULL , tlLiteral ( " serverFull " ) ) ;
2021-01-11 06:10:07 +01:00
}
2015-04-15 06:06:16 +02:00
}
}
@EventHandler ( priority = EventPriority . HIGH , ignoreCancelled = true )
public void onPlayerTeleport ( final PlayerTeleportEvent event ) {
2021-10-31 22:25:18 +01:00
final Player player = event . getPlayer ( ) ;
if ( player . hasMetadata ( " NPC " ) | | ! ( event . getCause ( ) = = TeleportCause . PLUGIN | | event . getCause ( ) = = TeleportCause . COMMAND ) ) {
return ;
}
final User user = ess . getUser ( player ) ;
2021-12-12 22:02:37 +01:00
if ( ess . getSettings ( ) . registerBackInListener ( ) & & user . isAuthorized ( " essentials.back.onteleport " ) ) {
2021-10-31 22:25:18 +01:00
user . setLastLocation ( ) ;
}
if ( ess . getSettings ( ) . isTeleportInvulnerability ( ) ) {
user . enableInvulnerabilityAfterTeleport ( ) ;
2015-04-15 06:06:16 +02:00
}
}
@EventHandler ( priority = EventPriority . HIGH , ignoreCancelled = true )
public void onPlayerEggThrow ( final PlayerEggThrowEvent event ) {
final User user = ess . getUser ( event . getPlayer ( ) ) ;
final ItemStack stack = new ItemStack ( Material . EGG , 1 ) ;
if ( user . hasUnlimited ( stack ) ) {
2022-12-24 18:58:51 +01:00
Inventories . addItem ( user . getBase ( ) , stack ) ;
2015-04-15 06:06:16 +02:00
user . getBase ( ) . updateInventory ( ) ;
}
}
@EventHandler ( priority = EventPriority . HIGH , ignoreCancelled = true )
public void onPlayerBucketEmpty ( final PlayerBucketEmptyEvent event ) {
final User user = ess . getUser ( event . getPlayer ( ) ) ;
if ( user . hasUnlimited ( new ItemStack ( event . getBucket ( ) ) ) ) {
event . getItemStack ( ) . setType ( event . getBucket ( ) ) ;
2019-12-31 14:58:09 +01:00
ess . scheduleSyncDelayedTask ( user . getBase ( ) : : updateInventory ) ;
2015-04-15 06:06:16 +02:00
}
}
@EventHandler ( priority = EventPriority . MONITOR , ignoreCancelled = true )
public void onPlayerCommandPreprocess ( final PlayerCommandPreprocessEvent event ) {
final String cmd = event . getMessage ( ) . toLowerCase ( Locale . ENGLISH ) . split ( " " ) [ 0 ] . replace ( " / " , " " ) . toLowerCase ( Locale . ENGLISH ) ;
2021-02-20 17:30:07 +01:00
final int argStartIndex = event . getMessage ( ) . indexOf ( " " ) ;
final String args = argStartIndex = = - 1 ? " " // No arguments present
: event . getMessage ( ) . substring ( argStartIndex ) ; // arguments start at argStartIndex; substring from there.
// If the plugin command does not exist, check if it is an alias from commands.yml
if ( ess . getServer ( ) . getPluginCommand ( cmd ) = = null ) {
final Command knownCommand = ess . getKnownCommandsProvider ( ) . getKnownCommands ( ) . get ( cmd ) ;
if ( knownCommand instanceof FormattedCommandAlias ) {
final FormattedCommandAlias command = ( FormattedCommandAlias ) knownCommand ;
for ( String fullCommand : ess . getFormattedCommandAliasProvider ( ) . createCommands ( command , event . getPlayer ( ) , args . split ( " " ) ) ) {
handlePlayerCommandPreprocess ( event , fullCommand ) ;
}
return ;
}
}
// Handle the command given from the event.
handlePlayerCommandPreprocess ( event , cmd + args ) ;
}
2017-08-04 01:04:42 +02:00
2021-02-20 17:30:07 +01:00
public void handlePlayerCommandPreprocess ( final PlayerCommandPreprocessEvent event , final String effectiveCommand ) {
final Player player = event . getPlayer ( ) ;
final String cmd = effectiveCommand . toLowerCase ( Locale . ENGLISH ) . split ( " " ) [ 0 ] . replace ( " / " , " " ) . toLowerCase ( Locale . ENGLISH ) ;
2020-10-03 19:46:05 +02:00
final PluginCommand pluginCommand = ess . getServer ( ) . getPluginCommand ( cmd ) ;
2017-08-04 01:04:42 +02:00
2015-04-15 06:06:16 +02:00
if ( ess . getSettings ( ) . getSocialSpyCommands ( ) . contains ( cmd ) | | ess . getSettings ( ) . getSocialSpyCommands ( ) . contains ( " * " ) ) {
2016-07-23 01:09:18 +02:00
if ( pluginCommand = = null
2020-10-03 19:46:05 +02:00
| | ( ! pluginCommand . getName ( ) . equals ( " msg " ) & & ! pluginCommand . getName ( ) . equals ( " r " ) ) ) { // /msg and /r are handled in SimpleMessageRecipient
final User user = ess . getUser ( player ) ;
2016-07-23 01:09:18 +02:00
if ( ! user . isAuthorized ( " essentials.chat.spy.exempt " ) ) {
2020-10-03 19:46:05 +02:00
for ( final User spyer : ess . getOnlineUsers ( ) ) {
2016-07-23 01:09:18 +02:00
if ( spyer . isSocialSpyEnabled ( ) & & ! player . equals ( spyer . getBase ( ) ) ) {
2017-08-04 01:04:42 +02:00
if ( user . isMuted ( ) & & ess . getSettings ( ) . getSocialSpyListenMutedPlayers ( ) ) {
2024-02-03 21:38:14 +01:00
spyer . sendMessage ( spyer . playerTl ( " socialSpyMutedPrefix " ) + player . getDisplayName ( ) + " : " + event . getMessage ( ) ) ;
2018-08-26 16:17:07 +02:00
} else {
2024-02-03 21:38:14 +01:00
spyer . sendMessage ( spyer . playerTl ( " socialSpyPrefix " ) + player . getDisplayName ( ) + " : " + event . getMessage ( ) ) ;
2017-08-04 01:04:42 +02:00
}
2016-07-23 01:09:18 +02:00
}
2015-08-08 00:05:19 +02:00
}
2015-04-15 06:06:16 +02:00
}
}
2016-01-30 15:08:11 +01:00
}
2017-08-04 01:04:42 +02:00
2020-07-06 20:52:51 +02:00
final User user = ess . getUser ( player ) ;
if ( user . isMuted ( ) & & ( ess . getSettings ( ) . getMuteCommands ( ) . contains ( cmd ) | | ess . getSettings ( ) . getMuteCommands ( ) . contains ( " * " ) ) ) {
2017-08-04 01:04:42 +02:00
event . setCancelled ( true ) ;
2020-10-03 19:46:05 +02:00
final String dateDiff = user . getMuteTimeout ( ) > 0 ? DateUtil . formatDateDiff ( user . getMuteTimeout ( ) ) : null ;
2020-07-06 20:52:51 +02:00
if ( dateDiff = = null ) {
2024-02-03 21:38:14 +01:00
if ( user . hasMuteReason ( ) ) {
user . sendTl ( " voiceSilencedReason " , user . getMuteReason ( ) ) ;
} else {
user . sendTl ( " voiceSilenced " ) ;
}
2020-07-06 20:52:51 +02:00
} else {
2024-02-03 21:38:14 +01:00
if ( user . hasMuteReason ( ) ) {
user . sendTl ( " voiceSilencedReasonTime " , dateDiff , user . getMuteReason ( ) ) ;
} else {
user . sendTl ( " voiceSilencedTime " , dateDiff ) ;
}
2020-07-06 20:52:51 +02:00
}
2024-02-04 03:13:18 +01:00
ess . getLogger ( ) . info ( AdventureUtil . miniToLegacy ( tlLiteral ( " mutedUserSpeaks " , player . getName ( ) , event . getMessage ( ) ) ) ) ;
2017-08-04 01:04:42 +02:00
return ;
}
2020-02-22 11:02:53 +01:00
2016-01-30 15:08:11 +01:00
boolean broadcast = true ; // whether to broadcast the updated activity
boolean update = true ; // Only modified when the command is afk
if ( pluginCommand ! = null ) {
// Switch case for commands that shouldn't broadcast afk activity.
switch ( pluginCommand . getName ( ) ) {
case " afk " :
update = false ;
2020-10-03 19:46:05 +02:00
// fall through
2016-01-30 15:08:11 +01:00
case " vanish " :
broadcast = false ;
2020-10-03 19:46:05 +02:00
break ;
2016-01-13 00:53:09 +01:00
}
2015-04-15 06:06:16 +02:00
}
2020-07-06 20:52:51 +02:00
2016-01-30 15:08:11 +01:00
if ( update ) {
2018-03-26 09:50:42 +02:00
user . updateActivityOnInteract ( broadcast ) ;
2016-01-30 15:08:11 +01:00
}
2016-06-28 04:40:47 +02:00
2021-02-20 17:30:07 +01:00
if ( ess . getSettings ( ) . isCommandCooldownsEnabled ( )
2023-02-14 00:19:52 +01:00
& & ! user . isAuthorized ( " essentials.commandcooldowns.bypass " )
& & ( pluginCommand = = null | | ! user . isAuthorized ( " essentials.commandcooldowns.bypass. " + pluginCommand . getName ( ) ) ) ) {
2021-02-20 17:30:07 +01:00
final int argStartIndex = effectiveCommand . indexOf ( " " ) ;
2020-10-03 19:46:05 +02:00
final String args = argStartIndex = = - 1 ? " " // No arguments present
2021-02-20 17:30:07 +01:00
: " " + effectiveCommand . substring ( argStartIndex ) ; // arguments start at argStartIndex; substring from there.
final String fullCommand = pluginCommand = = null ? effectiveCommand : pluginCommand . getName ( ) + args ;
2016-06-28 04:40:47 +02:00
// Used to determine whether a user already has an existing cooldown
// If so, no need to check for (and write) new ones.
boolean cooldownFound = false ;
2020-02-22 11:02:53 +01:00
2016-06-28 04:40:47 +02:00
// Iterate over a copy of getCommandCooldowns in case of concurrent modifications
2020-10-03 19:46:05 +02:00
for ( final Entry < Pattern , Long > entry : new HashMap < > ( user . getCommandCooldowns ( ) ) . entrySet ( ) ) {
2016-06-28 04:40:47 +02:00
// Remove any expired cooldowns
if ( entry . getValue ( ) < = System . currentTimeMillis ( ) ) {
user . clearCommandCooldown ( entry . getKey ( ) ) ;
// Don't break in case there are other command cooldowns left to clear.
} else if ( entry . getKey ( ) . matcher ( fullCommand ) . matches ( ) ) {
// User's current cooldown hasn't expired, inform and terminate cooldown code.
if ( entry . getValue ( ) > System . currentTimeMillis ( ) ) {
2020-10-03 19:46:05 +02:00
final String commandCooldownTime = DateUtil . formatDateDiff ( entry . getValue ( ) ) ;
2024-02-03 21:38:14 +01:00
user . sendTl ( " commandCooldown " , commandCooldownTime ) ;
2016-06-28 04:40:47 +02:00
cooldownFound = true ;
event . setCancelled ( true ) ;
break ;
}
}
}
if ( ! cooldownFound ) {
2020-10-03 19:46:05 +02:00
final Entry < Pattern , Long > cooldownEntry = ess . getSettings ( ) . getCommandCooldownEntry ( fullCommand ) ;
2016-06-28 04:40:47 +02:00
if ( cooldownEntry ! = null ) {
2016-08-06 18:53:24 +02:00
if ( ess . getSettings ( ) . isDebug ( ) ) {
ess . getLogger ( ) . info ( " Applying " + cooldownEntry . getValue ( ) + " ms cooldown on / " + fullCommand + " for " + user . getName ( ) + " . " ) ;
}
2020-10-03 19:46:05 +02:00
final Date expiry = new Date ( System . currentTimeMillis ( ) + cooldownEntry . getValue ( ) ) ;
2016-06-28 04:40:47 +02:00
user . addCommandCooldown ( cooldownEntry . getKey ( ) , expiry , ess . getSettings ( ) . isCommandCooldownPersistent ( fullCommand ) ) ;
}
}
}
2015-04-15 06:06:16 +02:00
}
@EventHandler ( priority = EventPriority . NORMAL )
public void onPlayerChangedWorldFlyReset ( final PlayerChangedWorldEvent event ) {
final User user = ess . getUser ( event . getPlayer ( ) ) ;
2020-04-23 17:13:19 +02:00
if ( ess . getSettings ( ) . isWorldChangeFlyResetEnabled ( ) ) {
if ( user . getBase ( ) . getGameMode ( ) ! = GameMode . CREATIVE
2020-10-03 19:46:05 +02:00
// COMPAT: String compare for 1.7.10
& & ! user . getBase ( ) . getGameMode ( ) . name ( ) . equals ( " SPECTATOR " )
& & ! user . isAuthorized ( " essentials.fly " ) ) {
2020-04-23 17:13:19 +02:00
user . getBase ( ) . setFallDistance ( 0f ) ;
user . getBase ( ) . setAllowFlight ( false ) ;
2015-04-15 06:06:16 +02:00
}
2020-04-23 17:13:19 +02:00
}
2015-04-15 06:06:16 +02:00
2020-04-23 17:13:19 +02:00
if ( ess . getSettings ( ) . isWorldChangeSpeedResetEnabled ( ) ) {
if ( ! user . isAuthorized ( " essentials.speed " ) ) {
user . getBase ( ) . setFlySpeed ( 0 . 1f ) ;
user . getBase ( ) . setWalkSpeed ( 0 . 2f ) ;
2015-04-15 06:06:16 +02:00
} else {
2020-04-23 17:13:19 +02:00
if ( user . getBase ( ) . getFlySpeed ( ) > ess . getSettings ( ) . getMaxFlySpeed ( ) & & ! user . isAuthorized ( " essentials.speed.bypass " ) ) {
user . getBase ( ) . setFlySpeed ( ( float ) ess . getSettings ( ) . getMaxFlySpeed ( ) ) ;
} else {
user . getBase ( ) . setFlySpeed ( user . getBase ( ) . getFlySpeed ( ) * 0 . 99999f ) ;
}
if ( user . getBase ( ) . getWalkSpeed ( ) > ess . getSettings ( ) . getMaxWalkSpeed ( ) & & ! user . isAuthorized ( " essentials.speed.bypass " ) ) {
user . getBase ( ) . setWalkSpeed ( ( float ) ess . getSettings ( ) . getMaxWalkSpeed ( ) ) ;
}
2015-04-15 06:06:16 +02:00
}
}
}
@EventHandler ( priority = EventPriority . MONITOR )
public void onPlayerChangedWorld ( final PlayerChangedWorldEvent event ) {
final User user = ess . getUser ( event . getPlayer ( ) ) ;
final String newWorld = event . getPlayer ( ) . getLocation ( ) . getWorld ( ) . getName ( ) ;
user . setDisplayNick ( ) ;
updateCompass ( user ) ;
if ( ess . getSettings ( ) . getNoGodWorlds ( ) . contains ( newWorld ) & & user . isGodModeEnabledRaw ( ) ) {
2016-07-12 01:03:08 +02:00
// Player god mode is never disabled in order to retain it when changing worlds once more.
// With that said, players will still take damage as per the result of User#isGodModeEnabled()
2024-02-03 21:38:14 +01:00
user . sendTl ( " noGodWorldWarning " ) ;
2015-04-15 06:06:16 +02:00
}
if ( ! user . getWorld ( ) . getName ( ) . equals ( newWorld ) ) {
2024-02-03 21:38:14 +01:00
user . sendTl ( " currentWorld " , newWorld ) ;
2015-04-15 06:06:16 +02:00
}
if ( user . isVanished ( ) ) {
user . setVanished ( user . isAuthorized ( " essentials.vanish " ) ) ;
}
}
@EventHandler ( priority = EventPriority . NORMAL )
public void onPlayerInteract ( final PlayerInteractEvent event ) {
2019-06-17 12:06:45 +02:00
boolean updateActivity = true ;
2015-04-15 06:06:16 +02:00
switch ( event . getAction ( ) ) {
case RIGHT_CLICK_BLOCK :
2018-09-01 11:35:08 +02:00
if ( ! event . isCancelled ( ) & & MaterialUtil . isBed ( event . getClickedBlock ( ) . getType ( ) ) & & ess . getSettings ( ) . getUpdateBedAtDaytime ( ) ) {
2021-09-15 16:40:23 +02:00
if ( VersionUtil . getServerBukkitVersion ( ) . isHigherThanOrEqualTo ( VersionUtil . v1_13_2_R01 ) & & ( ( org . bukkit . block . data . type . Bed ) event . getClickedBlock ( ) . getBlockData ( ) ) . isOccupied ( ) ) {
break ;
}
2020-10-03 19:46:05 +02:00
final User player = ess . getUser ( event . getPlayer ( ) ) ;
2019-01-05 19:43:27 +01:00
if ( player . isAuthorized ( " essentials.sethome.bed " ) & & player . getWorld ( ) . getEnvironment ( ) . equals ( World . Environment . NORMAL ) ) {
2015-04-15 06:06:16 +02:00
player . getBase ( ) . setBedSpawnLocation ( event . getClickedBlock ( ) . getLocation ( ) ) ;
2020-01-14 08:50:48 +01:00
// In 1.15 and above, vanilla sends its own bed spawn message.
if ( VersionUtil . getServerBukkitVersion ( ) . isLowerThan ( VersionUtil . v1_15_R01 ) ) {
2024-02-03 21:38:14 +01:00
player . sendTl ( " bedSet " , player . getLocation ( ) . getWorld ( ) . getName ( ) , player . getLocation ( ) . getBlockX ( ) , player . getLocation ( ) . getBlockY ( ) , player . getLocation ( ) . getBlockZ ( ) ) ;
2020-01-14 08:50:48 +01:00
}
2015-04-15 06:06:16 +02:00
}
}
2017-12-06 09:37:52 +01:00
break ;
2015-04-15 06:06:16 +02:00
case LEFT_CLICK_AIR :
if ( event . getPlayer ( ) . isFlying ( ) ) {
final User user = ess . getUser ( event . getPlayer ( ) ) ;
if ( user . isFlyClickJump ( ) ) {
useFlyClickJump ( user ) ;
2017-12-06 09:37:52 +01:00
break ;
2015-04-15 06:06:16 +02:00
}
}
2020-10-03 19:46:05 +02:00
// fall through
2015-04-15 06:06:16 +02:00
case LEFT_CLICK_BLOCK :
if ( event . getItem ( ) ! = null & & event . getItem ( ) . getType ( ) ! = Material . AIR ) {
final User user = ess . getUser ( event . getPlayer ( ) ) ;
2017-12-13 07:06:25 +01:00
if ( user . hasPowerTools ( ) & & user . arePowerToolsEnabled ( ) & & usePowertools ( user , event . getItem ( ) . getType ( ) ) ) {
2015-04-15 06:06:16 +02:00
event . setCancelled ( true ) ;
}
}
2017-12-06 09:37:52 +01:00
break ;
2019-06-17 12:06:45 +02:00
case PHYSICAL :
updateActivity = false ;
break ;
2019-12-31 14:58:09 +01:00
default :
break ;
2015-04-15 06:06:16 +02:00
}
2019-06-17 12:06:45 +02:00
if ( updateActivity ) {
2018-03-26 09:50:42 +02:00
ess . getUser ( event . getPlayer ( ) ) . updateActivityOnInteract ( true ) ;
2019-06-17 12:06:45 +02:00
}
2015-04-15 06:06:16 +02:00
}
// This method allows the /jump lock feature to work, allows teleporting while flying #EasterEgg
private void useFlyClickJump ( final User user ) {
try {
final Location otarget = LocationUtil . getTarget ( user . getBase ( ) ) ;
class DelayedClickJumpTask implements Runnable {
@Override
public void run ( ) {
2020-10-03 19:46:05 +02:00
final Location loc = user . getLocation ( ) ;
2015-04-15 06:06:16 +02:00
loc . setX ( otarget . getX ( ) ) ;
loc . setZ ( otarget . getZ ( ) ) ;
while ( LocationUtil . isBlockDamaging ( loc . getWorld ( ) , loc . getBlockX ( ) , loc . getBlockY ( ) - 1 , loc . getBlockZ ( ) ) ) {
loc . setY ( loc . getY ( ) + 1d ) ;
}
2019-02-20 13:25:05 +01:00
PaperLib . teleportAsync ( user . getBase ( ) , loc , TeleportCause . PLUGIN ) ;
2015-04-15 06:06:16 +02:00
}
}
2020-10-03 19:46:05 +02:00
2015-04-15 06:06:16 +02:00
ess . scheduleSyncDelayedTask ( new DelayedClickJumpTask ( ) ) ;
2020-10-03 19:46:05 +02:00
} catch ( final Exception ex ) {
2015-04-15 06:06:16 +02:00
if ( ess . getSettings ( ) . isDebug ( ) ) {
2022-06-27 20:54:10 +02:00
ess . getLogger ( ) . log ( Level . WARNING , ex . getMessage ( ) , ex ) ;
2015-04-15 06:06:16 +02:00
}
}
}
2017-12-13 07:06:25 +01:00
private boolean usePowertools ( final User user , final Material material ) {
final List < String > commandList = user . getPowertool ( material ) ;
2015-04-15 06:06:16 +02:00
if ( commandList = = null | | commandList . isEmpty ( ) ) {
return false ;
}
boolean used = false ;
// We need to loop through each command and execute
for ( final String command : commandList ) {
if ( command . contains ( " {player} " ) ) {
} else if ( command . startsWith ( " c: " ) ) {
used = true ;
user . getBase ( ) . chat ( command . substring ( 2 ) ) ;
} else {
used = true ;
class PowerToolUseTask implements Runnable {
@Override
public void run ( ) {
2018-09-06 21:42:05 +02:00
user . getBase ( ) . chat ( " / " + command ) ;
2022-06-27 20:54:10 +02:00
ess . getLogger ( ) . log ( Level . INFO , String . format ( " [PT] %s issued server command: /%s " , user . getName ( ) , command ) ) ;
2015-04-15 06:06:16 +02:00
}
}
2020-10-03 19:46:05 +02:00
2015-04-15 06:06:16 +02:00
ess . scheduleSyncDelayedTask ( new PowerToolUseTask ( ) ) ;
}
}
return used ;
}
@EventHandler ( priority = EventPriority . LOWEST , ignoreCancelled = true )
public void onInventoryClickEvent ( final InventoryClickEvent event ) {
Player refreshPlayer = null ;
final Inventory top = event . getView ( ) . getTopInventory ( ) ;
final InventoryType type = top . getType ( ) ;
2016-11-06 11:54:49 +01:00
final Inventory clickedInventory ;
if ( event . getRawSlot ( ) < 0 ) {
clickedInventory = null ;
} else {
clickedInventory = event . getRawSlot ( ) < top . getSize ( ) ? top : event . getView ( ) . getBottomInventory ( ) ;
}
2021-01-08 21:11:35 +01:00
final User user = ess . getUser ( ( Player ) event . getWhoClicked ( ) ) ;
2015-04-15 06:06:16 +02:00
if ( type = = InventoryType . PLAYER ) {
final InventoryHolder invHolder = top . getHolder ( ) ;
2020-04-25 14:08:57 +02:00
if ( invHolder instanceof HumanEntity ) {
2015-04-15 06:06:16 +02:00
final User invOwner = ess . getUser ( ( Player ) invHolder ) ;
if ( user . isInvSee ( ) & & ( ! user . isAuthorized ( " essentials.invsee.modify " ) | | invOwner . isAuthorized ( " essentials.invsee.preventmodify " ) | | ! invOwner . getBase ( ) . isOnline ( ) ) ) {
event . setCancelled ( true ) ;
refreshPlayer = user . getBase ( ) ;
}
}
} else if ( type = = InventoryType . ENDER_CHEST ) {
2020-10-03 19:46:05 +02:00
if ( user . isEnderSee ( ) & & ! user . isAuthorized ( " essentials.enderchest.modify " ) ) {
2015-04-15 06:06:16 +02:00
event . setCancelled ( true ) ;
refreshPlayer = user . getBase ( ) ;
}
} else if ( type = = InventoryType . WORKBENCH ) {
if ( user . isRecipeSee ( ) ) {
event . setCancelled ( true ) ;
refreshPlayer = user . getBase ( ) ;
}
} else if ( type = = InventoryType . CHEST & & top . getSize ( ) = = 9 ) {
final InventoryHolder invHolder = top . getHolder ( ) ;
2021-01-02 21:36:12 +01:00
if ( invHolder instanceof HumanEntity & & user . isInvSee ( ) & & event . getClick ( ) ! = ClickType . MIDDLE ) {
2015-04-15 06:06:16 +02:00
event . setCancelled ( true ) ;
refreshPlayer = user . getBase ( ) ;
}
2016-11-06 11:54:49 +01:00
} else if ( clickedInventory ! = null & & clickedInventory . getType ( ) = = InventoryType . PLAYER ) {
if ( ess . getSettings ( ) . isDirectHatAllowed ( ) & & event . getClick ( ) = = ClickType . LEFT & & event . getSlot ( ) = = 39
2020-10-03 19:46:05 +02:00
& & event . getCursor ( ) . getType ( ) ! = Material . AIR & & event . getCursor ( ) . getType ( ) . getMaxDurability ( ) = = 0
& & ! MaterialUtil . isSkull ( event . getCursor ( ) . getType ( ) )
2021-01-08 21:11:35 +01:00
& & user . isAuthorized ( " essentials.hat " ) & & ! user . isAuthorized ( " essentials.hat.prevent-type. " + event . getCursor ( ) . getType ( ) . name ( ) . toLowerCase ( ) )
& & ! isPreventBindingHat ( user , ( PlayerInventory ) clickedInventory ) ) {
2016-11-06 11:54:49 +01:00
event . setCancelled ( true ) ;
final PlayerInventory inv = ( PlayerInventory ) clickedInventory ;
final ItemStack head = inv . getHelmet ( ) ;
inv . setHelmet ( event . getCursor ( ) ) ;
event . setCursor ( head ) ;
}
2015-04-15 06:06:16 +02:00
}
if ( refreshPlayer ! = null ) {
2020-04-25 14:08:57 +02:00
ess . scheduleSyncDelayedTask ( refreshPlayer : : updateInventory , 1 ) ;
2015-04-15 06:06:16 +02:00
}
}
2021-01-08 21:11:35 +01:00
private boolean isPreventBindingHat ( User user , PlayerInventory inventory ) {
if ( VersionUtil . getServerBukkitVersion ( ) . isHigherThan ( VersionUtil . v1_9_4_R01 ) ) {
final ItemStack head = inventory . getHelmet ( ) ;
return head ! = null & & head . getEnchantments ( ) . containsKey ( Enchantment . BINDING_CURSE ) & & ! user . isAuthorized ( " essentials.hat.ignore-binding " ) ;
}
return false ;
}
2015-04-15 06:06:16 +02:00
@EventHandler ( priority = EventPriority . MONITOR )
public void onInventoryCloseEvent ( final InventoryCloseEvent event ) {
Player refreshPlayer = null ;
final Inventory top = event . getView ( ) . getTopInventory ( ) ;
final InventoryType type = top . getType ( ) ;
if ( type = = InventoryType . PLAYER ) {
final User user = ess . getUser ( ( Player ) event . getPlayer ( ) ) ;
user . setInvSee ( false ) ;
refreshPlayer = user . getBase ( ) ;
} else if ( type = = InventoryType . ENDER_CHEST ) {
final User user = ess . getUser ( ( Player ) event . getPlayer ( ) ) ;
user . setEnderSee ( false ) ;
refreshPlayer = user . getBase ( ) ;
} else if ( type = = InventoryType . WORKBENCH ) {
final User user = ess . getUser ( ( Player ) event . getPlayer ( ) ) ;
if ( user . isRecipeSee ( ) ) {
user . setRecipeSee ( false ) ;
event . getView ( ) . getTopInventory ( ) . clear ( ) ;
refreshPlayer = user . getBase ( ) ;
}
} else if ( type = = InventoryType . CHEST & & top . getSize ( ) = = 9 ) {
final InventoryHolder invHolder = top . getHolder ( ) ;
2020-04-25 14:08:57 +02:00
if ( invHolder instanceof HumanEntity ) {
2015-04-15 06:06:16 +02:00
final User user = ess . getUser ( ( Player ) event . getPlayer ( ) ) ;
user . setInvSee ( false ) ;
refreshPlayer = user . getBase ( ) ;
}
}
if ( refreshPlayer ! = null ) {
2020-04-25 14:08:57 +02:00
ess . scheduleSyncDelayedTask ( refreshPlayer : : updateInventory , 1 ) ;
2015-04-15 06:06:16 +02:00
}
}
@EventHandler ( priority = EventPriority . LOW , ignoreCancelled = true )
public void onPlayerFishEvent ( final PlayerFishEvent event ) {
final User user = ess . getUser ( event . getPlayer ( ) ) ;
2019-12-31 14:58:09 +01:00
user . updateActivityOnInteract ( true ) ;
2015-04-15 06:06:16 +02:00
}
2018-08-26 16:17:07 +02:00
2020-10-03 19:46:05 +02:00
private static final class ArrowPickupListener implements Listener {
2020-04-10 21:44:45 +02:00
@EventHandler ( priority = EventPriority . LOW )
public void onArrowPickup ( final org . bukkit . event . player . PlayerPickupArrowEvent event ) {
2020-04-17 01:55:06 +02:00
if ( event . getItem ( ) . hasMetadata ( Commandfireball . FIREBALL_META_KEY ) ) {
2020-04-10 21:44:45 +02:00
event . setCancelled ( true ) ;
}
}
}
2019-03-31 21:35:47 +02:00
private final class PickupListenerPre1_12 implements Listener {
2017-07-28 21:13:59 +02:00
@EventHandler ( priority = EventPriority . LOW , ignoreCancelled = true )
public void onPlayerPickupItem ( final org . bukkit . event . player . PlayerPickupItemEvent event ) {
2020-04-10 21:44:45 +02:00
if ( event . getItem ( ) . hasMetadata ( Commandfireball . FIREBALL_META_KEY ) ) {
event . setCancelled ( true ) ;
} else if ( ess . getSettings ( ) . getDisableItemPickupWhileAfk ( ) ) {
2017-07-28 21:13:59 +02:00
if ( ess . getUser ( event . getPlayer ( ) ) . isAfk ( ) ) {
event . setCancelled ( true ) ;
}
}
}
}
2018-08-26 16:17:07 +02:00
2019-03-31 21:35:47 +02:00
private final class PickupListener1_12 implements Listener {
2017-07-28 21:13:59 +02:00
@EventHandler ( priority = EventPriority . LOW , ignoreCancelled = true )
public void onPlayerPickupItem ( final org . bukkit . event . entity . EntityPickupItemEvent event ) {
if ( ess . getSettings ( ) . getDisableItemPickupWhileAfk ( ) & & event . getEntity ( ) instanceof Player ) {
if ( ess . getUser ( ( Player ) event . getEntity ( ) ) . isAfk ( ) ) {
event . setCancelled ( true ) ;
}
}
}
}
2019-03-31 21:35:47 +02:00
2023-04-03 00:29:29 +02:00
private final class SculkListener1_17 implements Listener {
@EventHandler
public void onGameEvent ( final org . bukkit . event . block . BlockReceiveGameEvent event ) {
if ( event . getEntity ( ) instanceof Player & & ess . getUser ( ( Player ) event . getEntity ( ) ) . isVanished ( ) ) {
event . setCancelled ( true ) ;
}
}
}
2021-09-15 23:23:31 +02:00
private final class CommandSendFilter implements CommandSendListenerProvider . Filter {
@Override
public Predicate < String > apply ( Player player ) {
final User user = ess . getUser ( player ) ;
2020-10-03 19:46:05 +02:00
final Set < PluginCommand > checked = new HashSet < > ( ) ;
final Set < PluginCommand > toRemove = new HashSet < > ( ) ;
2019-03-31 21:35:47 +02:00
2021-09-15 23:23:31 +02:00
return label - > {
2020-02-22 11:02:53 +01:00
if ( isEssentialsCommand ( label ) ) {
2020-10-03 19:46:05 +02:00
final PluginCommand command = ess . getServer ( ) . getPluginCommand ( label ) ;
2020-02-22 11:02:53 +01:00
if ( ! checked . contains ( command ) ) {
checked . add ( command ) ;
if ( ! user . isAuthorized ( command . getName ( ) . equals ( " r " ) ? " essentials.msg " : " essentials. " + command . getName ( ) ) ) {
toRemove . add ( command ) ;
}
}
return toRemove . contains ( command ) ;
}
return false ;
2021-09-15 23:23:31 +02:00
} ;
2019-03-31 21:35:47 +02:00
}
/ * *
* Returns true if all of the following are true :
2020-02-22 11:02:53 +01:00
* - The command is a plugin command
2021-09-15 23:23:31 +02:00
* - The plugin command is from an official EssentialsX plugin or addon
2020-02-22 11:02:53 +01:00
* - There is no known alternative OR the alternative is overridden by Essentials
2019-03-31 21:35:47 +02:00
* /
2020-10-03 19:46:05 +02:00
private boolean isEssentialsCommand ( final String label ) {
final PluginCommand command = ess . getServer ( ) . getPluginCommand ( label ) ;
2019-03-31 21:35:47 +02:00
return command ! = null
2021-09-15 23:23:31 +02:00
& & ( command . getPlugin ( ) = = ess | | command . getPlugin ( ) . getClass ( ) . getName ( ) . startsWith ( " com.earth2me.essentials " ) | | command . getPlugin ( ) . getClass ( ) . getName ( ) . startsWith ( " net.essentialsx " ) )
& & ( ess . getSettings ( ) . isCommandOverridden ( label ) | | ( ess . getAlternativeCommandsHandler ( ) . getAlternative ( label ) = = null ) ) ;
2019-03-31 21:35:47 +02:00
}
}
2021-07-27 22:23:20 +02:00
@Override
public void getUser ( Player player ) {
ess . getUser ( player ) ;
}
2012-12-16 17:03:04 +01:00
}