2019-12-16 16:47:51 +01:00
package world.bentobox.limits.listeners ;
2019-02-09 07:35:29 +01:00
2020-01-09 23:42:37 +01:00
import java.util.Arrays ;
2019-02-09 07:35:29 +01:00
import java.util.Locale ;
2019-11-17 01:23:37 +01:00
import java.util.Objects ;
2019-02-09 20:13:20 +01:00
import java.util.UUID ;
2019-02-09 07:35:29 +01:00
import org.apache.commons.lang.math.NumberUtils ;
2019-02-09 20:13:20 +01:00
import org.bukkit.Bukkit ;
2019-02-09 07:35:29 +01:00
import org.bukkit.Material ;
2019-02-09 20:13:20 +01:00
import org.bukkit.OfflinePlayer ;
import org.bukkit.World ;
2020-01-09 23:42:37 +01:00
import org.bukkit.entity.EntityType ;
2019-02-09 07:35:29 +01:00
import org.bukkit.entity.Player ;
import org.bukkit.event.EventHandler ;
import org.bukkit.event.EventPriority ;
import org.bukkit.event.Listener ;
import org.bukkit.event.player.PlayerJoinEvent ;
import org.bukkit.permissions.PermissionAttachmentInfo ;
2019-02-09 20:13:20 +01:00
import world.bentobox.bentobox.api.events.island.IslandEvent ;
import world.bentobox.bentobox.api.events.island.IslandEvent.Reason ;
import world.bentobox.bentobox.api.events.team.TeamEvent.TeamSetownerEvent ;
import world.bentobox.bentobox.database.objects.Island ;
2019-12-16 16:47:51 +01:00
import world.bentobox.limits.Limits ;
2020-04-11 13:53:28 +02:00
import world.bentobox.limits.Settings.EntityGroup ;
2020-06-03 02:54:54 +02:00
import world.bentobox.limits.events.LimitsJoinPermCheckEvent ;
2020-11-14 20:03:13 +01:00
import world.bentobox.limits.events.LimitsPermCheckEvent ;
2019-12-16 16:47:51 +01:00
import world.bentobox.limits.objects.IslandBlockCount ;
2019-02-09 07:35:29 +01:00
/ * *
* Sets block limits based on player permission
* @author tastybento
*
* /
public class JoinListener implements Listener {
2019-02-09 19:30:02 +01:00
private final Limits addon ;
2019-02-09 07:35:29 +01:00
public JoinListener ( Limits addon ) {
this . addon = addon ;
}
2019-02-09 19:30:02 +01:00
private void checkPerms ( Player player , String permissionPrefix , String islandId , String gameMode ) {
2019-02-09 07:35:29 +01:00
IslandBlockCount ibc = addon . getBlockLimitListener ( ) . getIsland ( islandId ) ;
2020-06-03 02:54:54 +02:00
// Fire event, so other addons can cancel this permissions change
LimitsJoinPermCheckEvent e = new LimitsJoinPermCheckEvent ( player , gameMode , ibc ) ;
Bukkit . getPluginManager ( ) . callEvent ( e ) ;
if ( e . isCancelled ( ) ) return ;
// Get ibc from event if it has changed
ibc = e . getIbc ( ) ;
// If perms should be ignored, but the IBC given in the event used, then set it and return
if ( e . isIgnorePerms ( ) & & ibc ! = null ) {
addon . getBlockLimitListener ( ) . setIsland ( islandId , ibc ) ;
return ;
}
// Check permissions
2020-01-11 18:49:15 +01:00
if ( ibc ! = null ) {
// Clear permission limits
ibc . getEntityLimits ( ) . clear ( ) ;
2020-04-11 17:42:18 +02:00
ibc . getEntityGroupLimits ( ) . clear ( ) ;
2020-01-11 18:49:15 +01:00
ibc . getBlockLimits ( ) . clear ( ) ;
}
2019-02-09 07:35:29 +01:00
for ( PermissionAttachmentInfo perms : player . getEffectivePermissions ( ) ) {
2020-03-18 16:36:40 +01:00
if ( ! perms . getValue ( ) | | ! perms . getPermission ( ) . startsWith ( permissionPrefix ) ) continue ;
2020-01-09 23:42:37 +01:00
// No wildcards
if ( perms . getPermission ( ) . contains ( permissionPrefix + " * " ) ) {
logError ( player . getName ( ) , perms . getPermission ( ) , " wildcards are not allowed. " ) ;
return ;
}
// Check formatting
String [ ] split = perms . getPermission ( ) . split ( " \\ . " ) ;
if ( split . length ! = 5 ) {
2020-04-11 13:53:28 +02:00
logError ( player . getName ( ) , perms . getPermission ( ) , " format must be ' " + permissionPrefix + " MATERIAL.NUMBER', ' " + permissionPrefix + " ENTITY-TYPE.NUMBER', or ' " + permissionPrefix + " ENTITY-GROUP.NUMBER' " ) ;
2020-01-09 23:42:37 +01:00
return ;
}
// Check value
if ( ! NumberUtils . isDigits ( split [ 4 ] ) ) {
logError ( player . getName ( ) , perms . getPermission ( ) , " the last part MUST be a number! " ) ;
return ;
}
// Entities & materials
EntityType et = Arrays . stream ( EntityType . values ( ) ) . filter ( t - > t . name ( ) . equalsIgnoreCase ( split [ 3 ] ) ) . findFirst ( ) . orElse ( null ) ;
Material m = Arrays . stream ( Material . values ( ) ) . filter ( t - > t . name ( ) . equalsIgnoreCase ( split [ 3 ] ) ) . findFirst ( ) . orElse ( null ) ;
2020-06-21 18:23:08 +02:00
EntityGroup entgroup = addon . getSettings ( ) . getGroupLimitDefinitions ( ) . stream ( ) . filter ( t - > t . getName ( ) . equalsIgnoreCase ( split [ 3 ] ) ) . findFirst ( ) . orElse ( null ) ;
2020-01-09 23:42:37 +01:00
2020-04-11 17:42:18 +02:00
if ( entgroup = = null & & et = = null & & m = = null ) {
logError ( player . getName ( ) , perms . getPermission ( ) , split [ 3 ] . toUpperCase ( Locale . ENGLISH ) + " is not a valid material or entity type/group. " ) ;
2020-01-09 23:42:37 +01:00
break ;
}
// Make an ibc if required
if ( ibc = = null ) {
ibc = new IslandBlockCount ( islandId , gameMode ) ;
}
2020-11-14 20:03:13 +01:00
int value = Integer . valueOf ( split [ 4 ] ) ;
// Fire perm check event
LimitsPermCheckEvent l = new LimitsPermCheckEvent ( player , gameMode , ibc , entgroup , et , m , value ) ;
Bukkit . getPluginManager ( ) . callEvent ( l ) ;
if ( l . isCancelled ( ) ) continue ;
// Use event values
ibc = l . getIbc ( ) ;
entgroup = l . getEntityGroup ( ) ;
et = l . getEntityType ( ) ;
m = l . getMaterial ( ) ;
value = l . getValue ( ) ;
2020-04-11 13:53:28 +02:00
if ( entgroup ! = null ) {
2020-04-11 17:42:18 +02:00
// Entity group limit
2020-11-14 20:03:13 +01:00
ibc . setEntityGroupLimit ( entgroup . getName ( ) , Math . max ( ibc . getEntityGroupLimit ( entgroup . getName ( ) ) , value ) ) ;
2020-04-11 13:53:28 +02:00
} else if ( et ! = null & & m = = null ) {
2020-01-09 23:42:37 +01:00
// Entity limit
2020-11-14 20:03:13 +01:00
ibc . setEntityLimit ( et , Math . max ( ibc . getEntityLimit ( et ) , value ) ) ;
2020-01-09 23:42:37 +01:00
} else if ( m ! = null & & et = = null ) {
// Material limit
2020-11-14 20:03:13 +01:00
ibc . setBlockLimit ( m , Math . max ( ibc . getBlockLimit ( m ) , value ) ) ;
2020-01-09 23:42:37 +01:00
} else {
if ( m . isBlock ( ) ) {
// Material limit
2020-11-14 20:03:13 +01:00
ibc . setBlockLimit ( m , Math . max ( ibc . getBlockLimit ( m ) , value ) ) ;
2020-01-09 23:42:37 +01:00
} else {
// This is an entity setting
2020-11-14 20:03:13 +01:00
ibc . setEntityLimit ( et , Math . max ( ibc . getEntityLimit ( et ) , value ) ) ;
2019-02-09 07:35:29 +01:00
}
}
}
2020-01-11 18:49:15 +01:00
// Check removed permissions
2020-01-09 23:42:37 +01:00
// If any changes have been made then store it - don't make files unless they are needed
if ( ibc ! = null ) addon . getBlockLimitListener ( ) . setIsland ( islandId , ibc ) ;
2019-02-09 07:35:29 +01:00
}
private void logError ( String name , String perm , String error ) {
2019-07-05 03:07:56 +02:00
addon . logError ( " Player " + name + " has permission: ' " + perm + " ' but " + error + " Ignoring... " ) ;
2019-02-09 07:35:29 +01:00
}
2019-02-09 20:13:20 +01:00
/ *
* Event handling
* /
@EventHandler ( priority = EventPriority . MONITOR , ignoreCancelled = true )
public void onNewIsland ( IslandEvent e ) {
if ( ! e . getReason ( ) . equals ( Reason . CREATED )
& & ! e . getReason ( ) . equals ( Reason . RESETTED )
& & ! e . getReason ( ) . equals ( Reason . REGISTERED ) ) {
return ;
}
setOwnerPerms ( e . getIsland ( ) , e . getOwner ( ) ) ;
}
@EventHandler ( priority = EventPriority . MONITOR , ignoreCancelled = true )
public void onOwnerChange ( TeamSetownerEvent e ) {
removeOwnerPerms ( e . getIsland ( ) ) ;
setOwnerPerms ( e . getIsland ( ) , e . getNewOwner ( ) ) ;
}
@EventHandler ( priority = EventPriority . NORMAL , ignoreCancelled = true )
public void onPlayerJoin ( PlayerJoinEvent e ) {
// Check if player has any islands in the game modes
addon . getGameModes ( ) . forEach ( gm - > {
if ( addon . getIslands ( ) . hasIsland ( gm . getOverWorld ( ) , e . getPlayer ( ) . getUniqueId ( ) ) ) {
2020-06-03 02:54:54 +02:00
String islandId = Objects . requireNonNull ( addon . getIslands ( ) . getIsland ( gm . getOverWorld ( ) , e . getPlayer ( ) . getUniqueId ( ) ) ) . getUniqueId ( ) ;
2019-02-09 20:13:20 +01:00
checkPerms ( e . getPlayer ( ) , gm . getPermissionPrefix ( ) + " island.limit. " , islandId , gm . getDescription ( ) . getName ( ) ) ;
}
} ) ;
}
@EventHandler ( priority = EventPriority . MONITOR , ignoreCancelled = true )
public void onUnregisterIsland ( IslandEvent e ) {
if ( ! e . getReason ( ) . equals ( Reason . UNREGISTERED ) ) {
return ;
}
removeOwnerPerms ( e . getIsland ( ) ) ;
}
/ *
* Utility methods
* /
private void removeOwnerPerms ( Island island ) {
World world = island . getWorld ( ) ;
if ( addon . inGameModeWorld ( world ) ) {
IslandBlockCount ibc = addon . getBlockLimitListener ( ) . getIsland ( island . getUniqueId ( ) ) ;
if ( ibc ! = null ) {
ibc . getBlockLimits ( ) . clear ( ) ;
}
}
}
private void setOwnerPerms ( Island island , UUID ownerUUID ) {
World world = island . getWorld ( ) ;
if ( addon . inGameModeWorld ( world ) ) {
// Check if owner is online
OfflinePlayer owner = Bukkit . getOfflinePlayer ( ownerUUID ) ;
if ( owner . isOnline ( ) ) {
// Set perm-based limits
String prefix = addon . getGameModePermPrefix ( world ) ;
String name = addon . getGameModeName ( world ) ;
2019-11-17 01:23:37 +01:00
if ( ! prefix . isEmpty ( ) & & ! name . isEmpty ( ) & & owner . getPlayer ( ) ! = null ) {
checkPerms ( Objects . requireNonNull ( owner . getPlayer ( ) ) , prefix + " island.limit. " , island . getUniqueId ( ) , name ) ;
2019-02-09 20:13:20 +01:00
}
}
}
}
2019-02-09 07:35:29 +01:00
}