Stanislav 11 years ago
parent
commit
09a341517b
  1. 39
      src/main/java/ru/simsonic/rscPermissions/Backends/BackendMySQL.java
  2. 4
      src/main/java/ru/simsonic/rscPermissions/BridgeForBukkitAPI.java
  3. 112
      src/main/java/ru/simsonic/rscPermissions/Bukkit/BukkitPermissions.java
  4. 3
      src/main/java/ru/simsonic/rscPermissions/Bukkit/BukkitPluginConfiguration.java
  5. 70
      src/main/java/ru/simsonic/rscPermissions/Bukkit/PlayerEventsListener.java
  6. 2
      src/main/java/ru/simsonic/rscPermissions/Bukkit/VaultChat.java
  7. 2
      src/main/java/ru/simsonic/rscPermissions/Bukkit/VaultPermission.java
  8. 2
      src/main/java/ru/simsonic/rscPermissions/CommandHelper.java
  9. 6
      src/main/java/ru/simsonic/rscPermissions/ConnectionHelper.java
  10. 9
      src/main/java/ru/simsonic/rscPermissions/DataTypes/ConditionalRow.java
  11. 65
      src/main/java/ru/simsonic/rscPermissions/DataTypes/Destination.java
  12. 22
      src/main/java/ru/simsonic/rscPermissions/DataTypes/RowInheritance.java
  13. 6
      src/main/java/ru/simsonic/rscPermissions/DataTypes/RowPermission.java
  14. 8
      src/main/java/ru/simsonic/rscPermissions/InternalCache/AsyncPlayerInfo.java
  15. 55
      src/main/java/ru/simsonic/rscPermissions/InternalCache/BrandNewCache.java
  16. 4
      src/main/java/ru/simsonic/rscPermissions/InternalCache/LocalCacheFunctions.java
  17. 12
      src/main/java/ru/simsonic/rscPermissions/InternalCache/LocalCacheTree.java
  18. 5
      src/main/java/ru/simsonic/rscPermissions/Ladders.java
  19. 145
      src/main/java/ru/simsonic/rscPermissions/MainPluginClass.java
  20. 7
      src/main/java/ru/simsonic/rscPermissions/RegionUpdateObserver.java
  21. 3
      src/main/java/ru/simsonic/rscPermissions/Settings.java

39
src/main/java/ru/simsonic/rscPermissions/Backends/BackendMySQL.java

@ -1,19 +1,18 @@
package ru.simsonic.rscPermissions.Backends;
import ru.simsonic.utilities.*;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.logging.Level;
import ru.simsonic.rscPermissions.DataTypes.Destination;
import ru.simsonic.rscPermissions.DataTypes.RowEntity;
import ru.simsonic.rscPermissions.DataTypes.EntityType;
import ru.simsonic.rscPermissions.DataTypes.RowEntity;
import ru.simsonic.rscPermissions.DataTypes.RowInheritance;
import ru.simsonic.rscPermissions.DataTypes.RowLadder;
import ru.simsonic.rscPermissions.DataTypes.RowPermission;
import ru.simsonic.rscPermissions.InternalCache.LocalCacheData;
import ru.simsonic.rscPermissions.MainPluginClass;
import ru.simsonic.rscPermissions.Bukkit.BukkitPluginConfiguration;
import ru.simsonic.rscPermissions.Settings;
import ru.simsonic.utilities.*;
public class BackendMySQL extends ConnectionMySQL implements Backend
{
@ -58,7 +57,7 @@ public class BackendMySQL extends ConnectionMySQL implements Backend
return false;
if(super.Connect())
{
executeUpdate(loadResourceSQLT("Initialize_main_v1"));
executeUpdateT("Initialize_main_v1");
cleanupTables();
return true;
}
@ -80,7 +79,7 @@ public class BackendMySQL extends ConnectionMySQL implements Backend
}
private void cleanupTables()
{
executeUpdate(loadResourceSQLT("Cleanup_tables"));
executeUpdateT("Cleanup_tables");
}
@Override
public synchronized void fetchIntoCache(LocalCacheData cache)
@ -117,7 +116,7 @@ public class BackendMySQL extends ConnectionMySQL implements Backend
}
rs.close();
} catch(SQLException ex) {
MainPluginClass.consoleLog.log(Level.WARNING, "[rscp] Exception in rs2e(): {0}", ex.getLocalizedMessage());
MainPluginClass.consoleLog.log(Level.WARNING, "[rscp] Exception in rs2e(): {0}", ex);
}
return result.toArray(new RowEntity[result.size()]);
}
@ -131,9 +130,9 @@ public class BackendMySQL extends ConnectionMySQL implements Backend
{
while(rs.next())
{
for(Destination destination : Destination.ParseDestinations(rs.getString("destination")))
for(Destination destination : Destination.parseDestinations(rs.getString("destination")))
{
if(destination.IsServerIdApplicable(serverId) == false)
if(destination.isServerIdApplicable(serverId) == false)
continue;
RowPermission row = new RowPermission();
row.id = rs.getInt("id");
@ -149,7 +148,7 @@ public class BackendMySQL extends ConnectionMySQL implements Backend
}
rs.close();
} catch(SQLException ex) {
MainPluginClass.consoleLog.log(Level.WARNING, "[rscp] Exception in rs2p(): {0}", ex.getLocalizedMessage());
MainPluginClass.consoleLog.log(Level.WARNING, "[rscp] Exception in rs2p(): {0}", ex);
}
return result.toArray(new RowPermission[result.size()]);
}
@ -163,9 +162,9 @@ public class BackendMySQL extends ConnectionMySQL implements Backend
{
while(rs.next())
{
for(Destination destination : Destination.ParseDestinations(rs.getString("destination")))
for(Destination destination : Destination.parseDestinations(rs.getString("destination")))
{
if(destination.IsServerIdApplicable(serverId) == false)
if(destination.isServerIdApplicable(serverId) == false)
continue;
RowInheritance row = new RowInheritance();
row.id = rs.getInt("id");
@ -182,7 +181,7 @@ public class BackendMySQL extends ConnectionMySQL implements Backend
}
rs.close();
} catch(SQLException ex) {
MainPluginClass.consoleLog.log(Level.WARNING, "[rscp] Exception in rs2i(): {0}", ex.getLocalizedMessage());
MainPluginClass.consoleLog.log(Level.WARNING, "[rscp] Exception in rs2i(): {0}", ex);
}
return result.toArray(new RowInheritance[result.size()]);
}
@ -202,7 +201,7 @@ public class BackendMySQL extends ConnectionMySQL implements Backend
row.climber = null;
row.climberType = EntityType.byValue(rs.getInt("climber_type"));
row.ladder = rs.getString("ladder");
String[] breaked = row.ladder.split(BukkitPluginConfiguration.separatorRegExp);
String[] breaked = row.ladder.split(Settings.separatorRegExp);
if(breaked.length == 2)
{
row.ladder = breaked[0];
@ -213,14 +212,14 @@ public class BackendMySQL extends ConnectionMySQL implements Backend
}
rs.close();
} catch(SQLException ex) {
MainPluginClass.consoleLog.log(Level.WARNING, "[rscp] Exception in rs2l(): {0}", ex.getLocalizedMessage());
MainPluginClass.consoleLog.log(Level.WARNING, "[rscp] Exception in rs2l(): {0}", ex);
}
return result.toArray(new RowLadder[result.size()]);
}
@Override
public synchronized void insertExampleRows()
{
executeUpdate(loadResourceSQLT("Insert_example_rows_v1"));
executeUpdateT("Insert_example_rows_v1");
}
@Override
public synchronized void updateEntityText(String entity, boolean entity_type, String text, boolean isPrefix)
@ -233,7 +232,7 @@ public class BackendMySQL extends ConnectionMySQL implements Backend
setupQueryTemplate("{ENTITY_TYPE}", entity_type ? "1" : "0");
setupQueryTemplate("{TEXT_TYPE}", isPrefix ? "prefix" : "suffix");
setupQueryTemplate("{TEXT}", (text != null) ? "'" + text + "'" : "NULL");
executeUpdate(loadResourceSQLT("Update_entity_text"));
executeUpdateT("Update_entity_text");
}
@Override
public synchronized void setUserRank(String user, String ladder, int rank)
@ -243,13 +242,13 @@ public class BackendMySQL extends ConnectionMySQL implements Backend
setupQueryTemplate("{USER}", user);
setupQueryTemplate("{LADDER}", ladder);
setupQueryTemplate("{RANK}", Integer.toString(rank));
executeUpdate(loadResourceSQLT("Set_user_rank"));
executeUpdateT("Set_user_rank");
}
@Override
public synchronized void dropUserFromLadder(String user, String ladder)
{
String instance = "";
String[] breaked = ladder.split(BukkitPluginConfiguration.separatorRegExp);
String[] breaked = ladder.split(Settings.separatorRegExp);
if(breaked.length == 2)
{
ladder = breaked[0];
@ -260,7 +259,7 @@ public class BackendMySQL extends ConnectionMySQL implements Backend
setupQueryTemplate("{USER}", user);
setupQueryTemplate("{LADDER}", ladder);
setupQueryTemplate("{INSTANCE}", instance);
executeUpdate(loadResourceSQLT("Drop_user_from_ladder"));
executeUpdateT("Drop_user_from_ladder");
}
@Override
public synchronized void addUserParentGroup(String user, String newGroup)

4
src/main/java/ru/simsonic/rscPermissions/BridgeForBukkitAPI.java

@ -1,6 +1,6 @@
package ru.simsonic.rscPermissions;
import ru.simsonic.rscPermissions.Frontends.VaultChat;
import ru.simsonic.rscPermissions.Frontends.VaultPermission;
import ru.simsonic.rscPermissions.Bukkit.VaultChat;
import ru.simsonic.rscPermissions.Bukkit.VaultPermission;
public class BridgeForBukkitAPI
{

112
src/main/java/ru/simsonic/rscPermissions/Bukkit/BukkitPermissions.java

@ -0,0 +1,112 @@
package ru.simsonic.rscPermissions.Bukkit;
import java.util.Arrays;
import java.util.HashMap;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.logging.Level;
import org.bukkit.entity.Player;
import org.bukkit.permissions.PermissionAttachment;
import ru.simsonic.rscPermissions.DataTypes.RowPermission;
import ru.simsonic.rscPermissions.InternalCache.BrandNewCache;
import ru.simsonic.rscPermissions.MainPluginClass;
public class BukkitPermissions implements Runnable
{
private final MainPluginClass rscp;
public BukkitPermissions(MainPluginClass plugin)
{
this.rscp = plugin;
}
private Thread thread;
private final LinkedBlockingQueue<Player> updateQueue = new LinkedBlockingQueue<>();
private final HashMap<Player, String> prefixes = new HashMap<>();
private final HashMap<Player, String> suffixes = new HashMap<>();
private final HashMap<Player, RowPermission[]> persistentPermissions = new HashMap<>();
private final HashMap<Player, RowPermission[]> transientPermissions = new HashMap<>();
public final HashMap<Player, PermissionAttachment> attachments = new HashMap<>();
public void recalculateOnlinePlayers()
{
updateQueue.addAll(Arrays.asList(rscp.getServer().getOnlinePlayers()));
rscp.scheduleAutoUpdate();
}
public void recalculatePlayer(Player player)
{
try
{
updateQueue.put(player);
} catch(InterruptedException ex) {
}
}
public void start()
{
stop();
thread = new Thread(this);
thread.start();
}
public void stop()
{
if(thread != null)
{
if(thread.isAlive())
{
try
{
thread.interrupt();
thread.join();
} catch(InterruptedException ex) {
MainPluginClass.consoleLog.log(Level.SEVERE, "[rscp] Exception in BukkitPermissions: {0}", ex);
}
}
thread = null;
}
}
@Override
public void run()
{
Thread.currentThread().setName("rscp:PermissionManager");
Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
try
{
for(Player current = updateQueue.take(); current != null; current = updateQueue.take())
{
final BrandNewCache.ResolutionResult result = rscp.cache2.resolvePlayer(current);
prefixes.put(current, result.prefix);
suffixes.put(current, result.suffix);
persistentPermissions.put(current, result.permissions);
final Player player = current;
rscp.getServer().getScheduler().runTask(rscp, new Runnable()
{
@Override
public void run()
{
// Remove old
final PermissionAttachment previous = attachments.get(player);
if(previous != null)
{
player.removeAttachment(previous);
attachments.remove(player);
}
// Create new
final RowPermission[] pp = persistentPermissions.get(player);
final RowPermission[] tp = transientPermissions.get(player);
if(pp == null && tp == null)
return;
final PermissionAttachment attachment = player.addAttachment(rscp);
attachments.put(player, attachment);
if(pp != null)
for(RowPermission row : pp)
attachment.setPermission(row.permission, row.value);
if(tp != null)
for(RowPermission row : tp)
attachment.setPermission(row.permission, row.value);
// Server operator
final Boolean asterisk = attachment.getPermissions().get("*");
if(rscp.settings.isAsteriskOP())
player.setOp((asterisk != null) ? asterisk : false);
}
});
}
} catch(InterruptedException ex) {
}
updateQueue.clear();
}
}

3
src/main/java/ru/simsonic/rscPermissions/Bukkit/BukkitPluginConfiguration.java

@ -23,9 +23,6 @@ public class BukkitPluginConfiguration implements Settings
private int nAutoReloadDelayTicks = 20 * 900;
private int nRegionFinderGranularity = 1000;
public final int CurrentVersion = 3;
public static final String instantiator = "?";
public static final String separator = ".";
public static final String separatorRegExp = "\\.";
public BukkitPluginConfiguration(final MainPluginClass plugin)
{
this.plugin = plugin;

70
src/main/java/ru/simsonic/rscPermissions/Bukkit/PlayerEventsListener.java

@ -0,0 +1,70 @@
package ru.simsonic.rscPermissions.Bukkit;
import java.util.HashMap;
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.AsyncPlayerPreLoginEvent;
import org.bukkit.event.player.PlayerExpChangeEvent;
import org.bukkit.event.player.PlayerKickEvent;
import org.bukkit.event.player.PlayerLevelChangeEvent;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.permissions.PermissionAttachment;
import ru.simsonic.rscPermissions.MainPluginClass;
public class PlayerEventsListener implements Listener
{
private final MainPluginClass rscp;
public PlayerEventsListener(MainPluginClass plugin)
{
this.rscp = plugin;
}
@EventHandler
public void onPlayerAsyncPreLogin(AsyncPlayerPreLoginEvent event)
{
rscp.cache2.resolvePlayer(new String[]
{
event.getName(),
event.getUniqueId().toString(),
event.getAddress().getHostAddress(),
});
}
@EventHandler(priority = EventPriority.LOWEST)
public void onPlayerLogin(PlayerLoginEvent event)
{
final Player player = event.getPlayer();
String name = event.getPlayer().getName();
final HashMap<String, Boolean> pending = rscp.cache.mapPermissions.get(name);
if(pending != null)
{
final PermissionAttachment attachment = player.addAttachment(rscp);
for(String permission : pending.keySet())
attachment.setPermission(permission, pending.get(permission));
rscp.permissionManager.attachments.put(player, attachment);
}
rscp.cache.calculatePlayerPermissions(player);
}
@EventHandler
public void onPlayerExp(PlayerLevelChangeEvent event)
{
rscp.cache.calculatePlayerPermissions(event.getPlayer());
}
@EventHandler
public void onPlayerLevel(PlayerExpChangeEvent event)
{
rscp.cache.calculatePlayerPermissions(event.getPlayer());
}
@EventHandler
public void onPlayerKick(PlayerKickEvent event)
{
rscp.permissionManager.attachments.remove(event.getPlayer());
rscp.regionListProvider.removePlayer(event.getPlayer());
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event)
{
rscp.permissionManager.attachments.remove(event.getPlayer());
rscp.regionListProvider.removePlayer(event.getPlayer());
}
}

2
src/main/java/ru/simsonic/rscPermissions/Frontends/VaultChat.java → src/main/java/ru/simsonic/rscPermissions/Bukkit/VaultChat.java

@ -1,4 +1,4 @@
package ru.simsonic.rscPermissions.Frontends;
package ru.simsonic.rscPermissions.Bukkit;
import net.milkbowl.vault.permission.Permission;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;

2
src/main/java/ru/simsonic/rscPermissions/Frontends/VaultPermission.java → src/main/java/ru/simsonic/rscPermissions/Bukkit/VaultPermission.java

@ -1,4 +1,4 @@
package ru.simsonic.rscPermissions.Frontends;
package ru.simsonic.rscPermissions.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.command.CommandSender;

2
src/main/java/ru/simsonic/rscPermissions/CommandHelper.java

@ -210,7 +210,7 @@ public class CommandHelper
{
case "permissions":
list.add("{MAGENTA}Permission list for {_YL}" + player.getName());
final PermissionAttachment pa = plugin.attachments.get(player);
final PermissionAttachment pa = plugin.permissionManager.attachments.get(player);
if(pa == null)
break;
final Map<String, Boolean> pv = pa.getPermissions();

6
src/main/java/ru/simsonic/rscPermissions/ConnectionHelper.java

@ -50,7 +50,7 @@ public class ConnectionHelper extends BackendMySQL
@Override
public synchronized void run()
{
plugin.recalculateOnlinePlayers();
plugin.permissionManager.recalculateOnlinePlayers();
notify();
}
};
@ -60,7 +60,7 @@ public class ConnectionHelper extends BackendMySQL
syncTask.wait();
}
} catch(InterruptedException ex) {
MainPluginClass.consoleLog.log(Level.SEVERE, "[rscp] Exception in FetchTables(): {0}", ex.getLocalizedMessage());
MainPluginClass.consoleLog.log(Level.SEVERE, "[rscp] Exception in FetchTables(): {0}", ex);
}
plugin.cache.calculateStartupPermissions();
}
@ -118,7 +118,7 @@ public class ConnectionHelper extends BackendMySQL
}
});
} catch(InterruptedException ex) {
MainPluginClass.consoleLog.log(Level.SEVERE, "[rscp] Exception in MigrateFromPExSQL(): {0}", ex.getLocalizedMessage());
MainPluginClass.consoleLog.log(Level.SEVERE, "[rscp] Exception in MigrateFromPExSQL(): {0}", ex);
}
}
};

9
src/main/java/ru/simsonic/rscPermissions/DataTypes/ConditionalRow.java

@ -0,0 +1,9 @@
package ru.simsonic.rscPermissions.DataTypes;
import java.sql.Timestamp;
public abstract class ConditionalRow extends AbstractRow
{
public Destination destination;
public int expirience;
public Timestamp lifetime;
}

65
src/main/java/ru/simsonic/rscPermissions/DataTypes/Destination.java

@ -5,7 +5,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.bukkit.Location;
import org.bukkit.World;
import ru.simsonic.rscPermissions.Bukkit.BukkitPluginConfiguration;
import ru.simsonic.rscPermissions.Settings;
import ru.simsonic.utilities.LanguageUtility;
public class Destination
@ -25,45 +25,66 @@ public class Destination
this.world = world;
this.serverId = serverId;
}
public boolean IsServerIdApplicable(String serverId)
public boolean isServerIdApplicable(String serverId)
{
return wildcardTesting(serverId, this.serverId);
return wildcardTest(serverId, this.serverId);
}
public boolean IsLocationApplicable(Location location, Set<String> regions, String instantiator)
public boolean isLocationApplicable(Location location, Set<String> regions, String instantiator)
{
if(location != null)
{
if(location.getWorld() != null)
if(IsWorldApplicable(location.getWorld(), instantiator))
return IsRegionApplicable(regions, instantiator);
if(isWorldApplicable(location.getWorld(), instantiator))
return isRegionApplicable(regions, instantiator);
} else {
if(this.world == null)
return IsRegionApplicable(regions, instantiator);
return isRegionApplicable(regions, instantiator);
}
return false;
}
private boolean IsWorldApplicable(World world, String instantiator)
public boolean isWorldApplicable(World world, String instantiator)
{
if(this.world == null || this.world.isEmpty() || "*".equals(this.world))
return true;
final String instantiated = (instantiator != null && !instantiator.isEmpty())
? this.world.replace(BukkitPluginConfiguration.instantiator, instantiator)
? this.world.replace(Settings.instantiator, instantiator)
: this.world;
return wildcardTesting(world.getName(), instantiated);
return wildcardTest(world.getName(), instantiated);
}
private boolean IsRegionApplicable(Set<String> regions, String instantiator)
public boolean isWorldApplicable(String world, String instantiator)
{
if(this.world == null || this.world.isEmpty() || "*".equals(this.world))
return true;
final String instantiated = (instantiator != null && !instantiator.isEmpty())
? this.world.replace(Settings.instantiator, instantiator)
: this.world;
return wildcardTest(world, instantiated);
}
public boolean isRegionApplicable(Set<String> regions, String instantiator)
{
if(this.region == null || "".equals(this.region) || "*".equals(this.region))
return true;
final String instantiated = (instantiator != null && !"".equals(instantiator))
? this.region.replace(Settings.instantiator, instantiator)
: this.region;
for(String regionId : regions)
if(wildcardTest(regionId, instantiated))
return true;
return false;
}
public boolean isRegionApplicable(String[] regions, String instantiator)
{
if(this.region == null || "".equals(this.region) || "*".equals(this.region))
return true;
final String instantiated = (instantiator != null && !"".equals(instantiator))
? this.region.replace(BukkitPluginConfiguration.instantiator, instantiator)
? this.region.replace(Settings.instantiator, instantiator)
: this.region;
for(String regionId : regions)
if(wildcardTesting(regionId, instantiated))
if(wildcardTest(regionId, instantiated))
return true;
return false;
}
private static boolean wildcardTesting(String testing, String pattern)
private static boolean wildcardTest(String testing, String pattern)
{
if(pattern == null || "".equals(pattern))
return true;
@ -73,23 +94,23 @@ public class Destination
"<wildcard>" + testing.toLowerCase() + "</wildcard>",
"<wildcard>" + pattern.toLowerCase() + "</wildcard>");
}
private static final String destinationSplitting = "\\s*[;,\\r\\n]+\\s*";
public static Destination[] ParseDestinations(String destinations)
private static final String destinationSplitter = "\\s*[;,\\r\\n]+\\s*";
public static Destination[] parseDestinations(String destinations)
{
if(destinations == null || destinations.isEmpty())
return new Destination[] { new Destination() };
final String[] destinationsList = destinations.split(destinationSplitting);
final String[] destinationsList = destinations.split(destinationSplitter);
final ArrayList<Destination> result = new ArrayList(destinationsList.length);
for(String inList : destinationsList)
if(inList != null && !inList.isEmpty())
result.add(ParseDestination(inList));
result.add(parseDestination(inList));
return result.toArray(new Destination[result.size()]);
}
private static final Pattern patternDestination = Pattern.compile(
private static final Pattern destinationPattern = Pattern.compile(
"^(?:((?:\\w|\\*|\\?)*):)?((?:\\w|\\*|\\?)*)?(?:@((?:\\w|\\*|\\?)*))?$");
private static Destination ParseDestination(String destination)
private static Destination parseDestination(String destination)
{
final Matcher match = patternDestination.matcher(destination);
final Matcher match = destinationPattern.matcher(destination);
if(match.find())
{
final String groupR = match.group(1);
@ -102,4 +123,4 @@ public class Destination
}
return new Destination();
}
}
}

22
src/main/java/ru/simsonic/rscPermissions/DataTypes/RowInheritance.java

@ -1,27 +1,23 @@
package ru.simsonic.rscPermissions.DataTypes;
import java.sql.Timestamp;
import java.util.Arrays;
import ru.simsonic.rscPermissions.Bukkit.BukkitPluginConfiguration;
import ru.simsonic.rscPermissions.Settings;
import ru.simsonic.utilities.LanguageUtility;
public class RowInheritance extends AbstractRow implements Comparable<RowInheritance>
public class RowInheritance extends ConditionalRow implements Comparable<RowInheritance>
{
public String entity;
public String parent;
public String instance;
public EntityType childType;
public int priority;
public Destination destination;
public int expirience;
public Timestamp lifetime;
public void deriveInstance()
{
if(parent != null)
{
final String[] splitted = parent.split(BukkitPluginConfiguration.separatorRegExp);
final String[] splitted = parent.split(Settings.separatorRegExp);
if(splitted.length > 1)
{
parent = LanguageUtility.glue(Arrays.copyOf(splitted, splitted.length - 1), BukkitPluginConfiguration.separator);
parent = LanguageUtility.glue(Arrays.copyOf(splitted, splitted.length - 1), Settings.separator);
instance = splitted[splitted.length - 1];
return;
}
@ -29,13 +25,13 @@ public class RowInheritance extends AbstractRow implements Comparable<RowInherit
instance = null;
}
@Override
public int compareTo(RowInheritance t)
public Table getTable()
{
return (priority != t.priority) ? priority - t.priority : parent.compareTo(t.parent);
return Table.inheritance;
}
@Override
public Table getTable()
public int compareTo(RowInheritance t)
{
return Table.inheritance;
return (priority != t.priority) ? priority - t.priority : parent.compareTo(t.parent);
}
}
}

6
src/main/java/ru/simsonic/rscPermissions/DataTypes/RowPermission.java

@ -1,15 +1,11 @@
package ru.simsonic.rscPermissions.DataTypes;
import java.sql.Timestamp;
public class RowPermission extends AbstractRow
public class RowPermission extends ConditionalRow
{
public String entity;
public EntityType entityType;
public String permission;
public boolean value;
public Destination destination;
public int expirience;
public Timestamp lifetime;
@Override
public Table getTable()
{

8
src/main/java/ru/simsonic/rscPermissions/InternalCache/AsyncPlayerInfo.java

@ -73,25 +73,25 @@ public class AsyncPlayerInfo
public boolean isPlayerPermissionApplicable(RowPermission row)
{
if(isPlayerEntityApplicable(row.entity) || "".equals(row.entity))
return (row.destination.IsLocationApplicable(location, regions, null) && row.expirience <= expirience);
return (row.destination.isLocationApplicable(location, regions, null) && row.expirience <= expirience);
return false;
}
public boolean isGroupPermissionApplicable(RowPermission row, ResolutionLeaf leaf)
{
if(row.entity.equalsIgnoreCase(leaf.group) || "".equals(row.entity))
return (row.destination.IsLocationApplicable(location, regions, leaf.instance) && row.expirience <= expirience);
return (row.destination.isLocationApplicable(location, regions, leaf.instance) && row.expirience <= expirience);
return false;
}
public boolean isPlayerInheritanceApplicable(RowInheritance row)
{
if(isPlayerEntityApplicable(row.entity))
return (row.destination.IsLocationApplicable(location, regions, row.instance) && row.expirience <= expirience);
return (row.destination.isLocationApplicable(location, regions, row.instance) && row.expirience <= expirience);
return false;
}
public boolean isGroupInheritanceApplicable(RowInheritance row, ResolutionLeaf leaf)
{
if(row.entity.equalsIgnoreCase(leaf.group))
return (row.destination.IsLocationApplicable(location, regions, leaf.instance) && row.expirience <= expirience);
return (row.destination.isLocationApplicable(location, regions, leaf.instance) && row.expirience <= expirience);
return false;
}
}

55
src/main/java/ru/simsonic/rscPermissions/InternalCache/BrandNewCache.java

@ -12,7 +12,7 @@ import ru.simsonic.rscPermissions.DataTypes.RowInheritance;
import ru.simsonic.rscPermissions.DataTypes.RowLadder;
import ru.simsonic.rscPermissions.DataTypes.RowPermission;
import ru.simsonic.rscPermissions.MainPluginClass;
import ru.simsonic.rscPermissions.Bukkit.BukkitPluginConfiguration;
import ru.simsonic.rscPermissions.Settings;
public class BrandNewCache implements AbstractPermissionsCache
{
@ -54,6 +54,7 @@ public class BrandNewCache implements AbstractPermissionsCache
public String[] destRegions;
public String destWorld;
public String destServerId;
public int expirience;
}
public static class ResolutionResult
{
@ -103,7 +104,7 @@ public class BrandNewCache implements AbstractPermissionsCache
result.subleafs = subleafs.toArray(new InheritanceLeaf[subleafs.size()]);
return result;
}
public ResolutionResult resolvePlayer(Player player)
public synchronized ResolutionResult resolvePlayer(Player player)
{
final ResolutionParams params = new ResolutionParams();
params.applicableIdentifiers = getPlayerIdentifiers(player);
@ -115,15 +116,21 @@ public class BrandNewCache implements AbstractPermissionsCache
params.destRegions = new String[] {};
params.destWorld = player.getLocation().getWorld().getName();
params.destServerId = plugin.getServer().getServerId();
params.expirience = player.getLevel();
return resolvePlayer(params);
}
public ResolutionResult resolvePlayer(String player)
public synchronized ResolutionResult resolvePlayer(String player)
{
return resolvePlayer(new String[] { player });
}
public synchronized ResolutionResult resolvePlayer(String[] player)
{
final ResolutionParams params = new ResolutionParams();
params.applicableIdentifiers = new String[] { player };
params.applicableIdentifiers = player;
params.destRegions = new String[] {};
params.destWorld = "";
// params.destWorld = "";
params.destServerId = plugin.getServer().getServerId();
// params.expirience = 0;
return resolvePlayer(params);
}
private static String[] getPlayerIdentifiers(Player player)
@ -161,25 +168,27 @@ public class BrandNewCache implements AbstractPermissionsCache
// Begin resolution
final ArrayList<ResolutionResult> intermediateResults = new ArrayList<>();
for(InheritanceLeaf branch : applicableBranches)
intermediateResults.add(resolveBranch(branch, ""));
final ResolutionResult result = processResultColumn(intermediateResults, "");
if(isInheritanceApplicable(params, branch.node, ""))
intermediateResults.add(resolveBranch(params, branch, ""));
final ResolutionResult result = processResultColumn(params, intermediateResults, "");
intermediateResults.clear();
return result;
}
private ResolutionResult resolveBranch(InheritanceLeaf branch, String instantiator)
private ResolutionResult resolveBranch(ResolutionParams params, InheritanceLeaf branch, String instantiator)
{
final ArrayList<ResolutionResult> intermediateResults = new ArrayList<>();
for(InheritanceLeaf subleaf : branch.subleafs)
{
final String overloadedInstantiator = (subleaf.instantiator != null && !"".equals(subleaf.instantiator))
? subleaf.instantiator : instantiator;
intermediateResults.add(resolveBranch(subleaf, overloadedInstantiator));
if(isInheritanceApplicable(params, subleaf.node, overloadedInstantiator))
intermediateResults.add(resolveBranch(params, subleaf, overloadedInstantiator));
}
final ResolutionResult result = processResultColumn(intermediateResults, branch.instantiator);
final ResolutionResult result = processResultColumn(params, intermediateResults, branch.instantiator);
intermediateResults.clear();
return result;
}
private ResolutionResult processResultColumn(ArrayList<ResolutionResult> resultList, String instantiator)
private ResolutionResult processResultColumn(ResolutionParams params, ArrayList<ResolutionResult> resultList, String instantiator)
{
switch(resultList.size())
{
@ -199,15 +208,33 @@ public class BrandNewCache implements AbstractPermissionsCache
result.prefix = result.prefix.replace("%", result.prefix);
if(intermediate.suffix != null && !"".equals(intermediate.suffix))
result.suffix = result.suffix.replace("%", result.suffix);
result.prefix = result.prefix.replace(BukkitPluginConfiguration.instantiator, instantiator);
result.suffix = result.suffix.replace(BukkitPluginConfiguration.instantiator, instantiator);
result.prefix = result.prefix.replace(Settings.instantiator, instantiator);
result.suffix = result.suffix.replace(Settings.instantiator, instantiator);
// Permissions
permissions.addAll(Arrays.asList(intermediate.permissions));
for(RowPermission permission : intermediate.permissions)
if(isPermissionApplicable(params, permission, instantiator))
permissions.add(permission);
}
result.permissions = permissions.toArray(new RowPermission[permissions.size()]);
return result;
}
}
private boolean isPermissionApplicable(ResolutionParams params, RowPermission row, String instantiator)
{
if(params.expirience < row.expirience)
return false;
return row.destination.isWorldApplicable(params.destWorld, instantiator)
? row.destination.isRegionApplicable(params.destRegions, instantiator)
: false;
}
private boolean isInheritanceApplicable(ResolutionParams params, RowInheritance row, String instantiator)
{
if(params.expirience < row.expirience)
return false;
return row.destination.isWorldApplicable(params.destWorld, instantiator)
? row.destination.isRegionApplicable(params.destRegions, instantiator)
: false;
}
@Override
public synchronized int ImportEntities(RowEntity[] rows)
{

4
src/main/java/ru/simsonic/rscPermissions/InternalCache/LocalCacheFunctions.java

@ -8,7 +8,7 @@ import ru.simsonic.rscPermissions.DataTypes.RowInheritance;
import ru.simsonic.rscPermissions.DataTypes.RowLadder;
import ru.simsonic.rscPermissions.DataTypes.RowPermission;
import ru.simsonic.rscPermissions.MainPluginClass;
import ru.simsonic.rscPermissions.Bukkit.BukkitPluginConfiguration;
import ru.simsonic.rscPermissions.Settings;
public class LocalCacheFunctions extends LocalCacheTree
{
@ -76,7 +76,7 @@ public class LocalCacheFunctions extends LocalCacheTree
return null;
final ArrayList<String> result = new ArrayList<>();
for(ResolutionLeaf leaf : tree)
result.add(leaf.instance != null ? leaf.group + BukkitPluginConfiguration.separator + leaf.instance : leaf.group);
result.add(leaf.instance != null ? leaf.group + Settings.separator + leaf.instance : leaf.group);
return result;
}
public synchronized Set<String> getAllPossibleGroups()

12
src/main/java/ru/simsonic/rscPermissions/InternalCache/LocalCacheTree.java

@ -11,7 +11,7 @@ import ru.simsonic.rscPermissions.DataTypes.RowInheritance;
import ru.simsonic.rscPermissions.DataTypes.RowLadder;
import ru.simsonic.rscPermissions.DataTypes.RowPermission;
import ru.simsonic.rscPermissions.MainPluginClass;
import ru.simsonic.rscPermissions.Bukkit.BukkitPluginConfiguration;
import ru.simsonic.rscPermissions.Settings;
import ru.simsonic.utilities.LanguageUtility;
public class LocalCacheTree extends LocalCacheData
@ -81,7 +81,7 @@ public class LocalCacheTree extends LocalCacheData
public void calculatePlayerPermissions(Player player)
{
final AsyncPlayerInfo api = new AsyncPlayerInfo(player, plugin.regionListProvider.getPlayerRegions(player));
plugin.recalculatingPlayers.offer(api);
// plugin.recalculatingPlayers.offer(api);
}
public synchronized HashMap<String, Boolean> treeToPermissions(AsyncPlayerInfo p2rc)
{
@ -99,8 +99,8 @@ public class LocalCacheTree extends LocalCacheData
{
String permission = row.permission;
// Additional processing
if(permission.contains(BukkitPluginConfiguration.instantiator) && (leaf.instance != null))
permission = permission.replace(BukkitPluginConfiguration.instantiator, leaf.instance);
if(permission.contains(Settings.instantiator) && (leaf.instance != null))
permission = permission.replace(Settings.instantiator, leaf.instance);
permissions.put(permission, row.value);
}
RowEntity entity = entities_g.get(leaf.group.toLowerCase());
@ -110,8 +110,8 @@ public class LocalCacheTree extends LocalCacheData
prefix = entity.prefix.replace("%", prefix);
if(entity.suffix != null && !"".equals(entity.suffix))
suffix = entity.suffix.replace("%", suffix);
prefix = prefix.replace(BukkitPluginConfiguration.instantiator, leaf.instance);
suffix = suffix.replace(BukkitPluginConfiguration.instantiator, leaf.instance);
prefix = prefix.replace(Settings.instantiator, leaf.instance);
suffix = suffix.replace(Settings.instantiator, leaf.instance);
}
}
// User permissions

5
src/main/java/ru/simsonic/rscPermissions/Ladders.java

@ -1,5 +1,4 @@
package ru.simsonic.rscPermissions;
import ru.simsonic.rscPermissions.Bukkit.BukkitPluginConfiguration;
import java.util.ArrayList;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@ -29,7 +28,7 @@ public class Ladders
return new String[] { "Player must be online." };
String template = ladder;
String instance = "";
String[] breaked = ladder.split(BukkitPluginConfiguration.separatorRegExp);
String[] breaked = ladder.split(Settings.separatorRegExp);
if(breaked.length == 2)
{
template = breaked[0].toLowerCase();
@ -78,7 +77,7 @@ public class Ladders
if(position.prevNode != null)
position = position.prevNode;
if(position.instance != null)
if(BukkitPluginConfiguration.instantiator.equals(position.instance))
if(Settings.instantiator.equals(position.instance))
{
if("".equals(instance))
return new String[] { "Operation requires ladder instance (<template>.<instance>)." };

145
src/main/java/ru/simsonic/rscPermissions/MainPluginClass.java

@ -1,48 +1,37 @@
package ru.simsonic.rscPermissions;
import ru.simsonic.rscPermissions.Bukkit.BukkitPluginConfiguration;
import ru.simsonic.rscPermissions.InternalCache.LocalCacheFunctions;
import ru.simsonic.rscPermissions.InternalCache.AsyncPlayerInfo;
import java.io.IOException;
import java.util.HashMap;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerExpChangeEvent;
import org.bukkit.event.player.PlayerLevelChangeEvent;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.permissions.PermissionAttachment;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitScheduler;
import org.mcstats.MetricsLite;
import ru.simsonic.rscPermissions.Bukkit.BukkitPermissions;
import ru.simsonic.rscPermissions.Bukkit.PlayerEventsListener;
import ru.simsonic.rscPermissions.InternalCache.BrandNewCache;
import ru.simsonic.utilities.CommandAnswerException;
import ru.simsonic.utilities.LanguageUtility;
public final class MainPluginClass extends JavaPlugin implements Listener
public final class MainPluginClass extends JavaPlugin
{
private static final String chatPrefix = "{_YL}[rscp] {GOLD}";
public static final Logger consoleLog = Logger.getLogger("Minecraft");
public final Settings settings = new BukkitPluginConfiguration(this);
public final LocalCacheFunctions cache = new LocalCacheFunctions(this);
public final CommandHelper commandHelper = new CommandHelper(this);
public final MaintenanceMode maintenance = new MaintenanceMode(this);
public final PlayerEventsListener listener = new PlayerEventsListener(this);
public final BrandNewCache cache2 = new BrandNewCache(this);
public final BukkitPermissions permissionManager = new BukkitPermissions(this);
public final RegionListProviders regionListProvider = new RegionListProviders(this);
private final RegionUpdateObserver regionUpdateObserver = new RegionUpdateObserver(this);
public final CommandHelper commandHelper = new CommandHelper(this);
public final MaintenanceMode maintenance = new MaintenanceMode(this);
public final LocalCacheFunctions cache = new LocalCacheFunctions(this);
public ConnectionHelper connectionList;
public Thread threadPermissions;
private MetricsLite metrics;
public final HashMap<Player, PermissionAttachment> attachments = new HashMap<>();
public final LinkedBlockingQueue<AsyncPlayerInfo> recalculatingPlayers = new LinkedBlockingQueue<>();
// private final HashSet<String> verbosePlayers = new HashSet<>();
public final rscpAPI API = new rscpAPI(this);
private final BrandNewCache newCache = new BrandNewCache(this);
private final BridgeForBukkitAPI api = new BridgeForBukkitAPI(this);
@Override
public void onLoad()
@ -63,14 +52,13 @@ public final class MainPluginClass extends JavaPlugin implements Listener
return;
}
// Register event's dispatcher
getServer().getPluginManager().registerEvents(this, this);
getServer().getPluginManager().registerEvents(maintenance, this);
regionUpdateObserver.registerListeners();
// WorldGuard, Residence and other possible region list providers
regionListProvider.integrate();
// Start all needed threads
cache.setDefaultGroup(settings.getDefaultGroup());
StartRecalcThread();
permissionManager.start();
regionUpdateObserver.start();
connectionList.threadFetchTablesData();
// Metrics
@ -82,7 +70,7 @@ public final class MainPluginClass extends JavaPlugin implements Listener
metrics.start();
consoleLog.info("[rscp] Metrics enabled.");
} catch(IOException ex) {
consoleLog.log(Level.INFO, "[rscp][Metrics] Exception: {0}", ex.getLocalizedMessage());
consoleLog.log(Level.INFO, "[rscp][Metrics] Exception: {0}", ex);
}
}
consoleLog.info("[rscp] rscPermissions has been successfully enabled.");
@ -92,7 +80,7 @@ public final class MainPluginClass extends JavaPlugin implements Listener
{
getServer().getServicesManager().unregisterAll(this);
regionUpdateObserver.stop();
StopRecalcThread();
permissionManager.stop();
cache.clear();
connectionList.Disconnect();
connectionList = null;
@ -100,74 +88,8 @@ public final class MainPluginClass extends JavaPlugin implements Listener
metrics = null;
consoleLog.info("[rscp] rscPermissions has been disabled.");
}
public void StopRecalcThread()
{
if(threadPermissions != null)
try
{
threadPermissions.interrupt();
threadPermissions.join();
threadPermissions = null;
} catch(InterruptedException ex) {
consoleLog.log(Level.WARNING, "[rscp] Exception in StopRecalcThread: {0}", ex.getLocalizedMessage());
}
}
public void StartRecalcThread()
{
StopRecalcThread();
final MainPluginClass plugin = this;
threadPermissions = new Thread()
{
@Override
public void run()
{
setName("rscp:PermCalculator");
setPriority(Thread.MIN_PRIORITY);
try
{
AsyncPlayerInfo p2rc;
while((p2rc = recalculatingPlayers.take()) != null)
{
// Build inheritance tree and calculate permissions
final HashMap<String, Boolean> permissions = cache.treeToPermissions(p2rc);
// Schedule attachment update
final Player player = p2rc.player;
getServer().getScheduler().runTask(plugin, new Runnable()
{
@Override
public void run()
{
PermissionAttachment attachment = attachments.get(player);
if(attachment != null)
attachment.remove();
attachment = player.addAttachment(plugin);
attachments.put(player, attachment);
for(String permission : permissions.keySet())
attachment.setPermission(permission, permissions.get(permission));
if(settings.isAsteriskOP())
{
final Boolean asteriskValue = permissions.get("*");
player.setOp(asteriskValue != null ? asteriskValue : false);
}
}
});
}
} catch(InterruptedException ex) {
}
recalculatingPlayers.clear();
}
};
threadPermissions.start();
}
public void recalculateOnlinePlayers()
{
for(Player player : Bukkit.getServer().getOnlinePlayers())
if(player != null)
cache.calculatePlayerPermissions(player);
rescheduleAutoUpdate();
}
private int nAutoUpdaterTaskId = -1;
private void rescheduleAutoUpdate()
private int nAutoUpdaterTaskId = -1;
public void scheduleAutoUpdate()
{
final BukkitScheduler scheduler = getServer().getScheduler();
if(nAutoUpdaterTaskId != -1)
@ -196,43 +118,6 @@ public final class MainPluginClass extends JavaPlugin implements Listener
}
return true;
}
@org.bukkit.event.EventHandler(priority = EventPriority.LOWEST)
public void onPlayerLogin(PlayerLoginEvent event)
{
final Player player = event.getPlayer();
String name = event.getPlayer().getName();
final HashMap<String, Boolean> pending = cache.mapPermissions.get(name);
if(pending != null)
{
final PermissionAttachment attachment = player.addAttachment(this);
for(String permission : pending.keySet())
attachment.setPermission(permission, pending.get(permission));
attachments.put(player, attachment);
}
cache.calculatePlayerPermissions(player);
}
@org.bukkit.event.EventHandler
public void onPlayerExp(PlayerLevelChangeEvent event)
{
cache.calculatePlayerPermissions(event.getPlayer());
}
@org.bukkit.event.EventHandler
public void onPlayerLevel(PlayerExpChangeEvent event)
{
cache.calculatePlayerPermissions(event.getPlayer());
}
@org.bukkit.event.EventHandler
public void onPlayerKick(PlayerQuitEvent event)
{
attachments.remove(event.getPlayer());
regionListProvider.removePlayer(event.getPlayer());
}
@org.bukkit.event.EventHandler
public void onPlayerQuit(PlayerQuitEvent event)
{
attachments.remove(event.getPlayer());
regionListProvider.removePlayer(event.getPlayer());
}
public void formattedMessage(CommandSender sender, String message)
{
if(message == null || "".equals(message))
@ -247,4 +132,4 @@ public final class MainPluginClass extends JavaPlugin implements Listener
System.out.println("http://dev.bukkit.org/bukkit-plugins/rscpermissions/");
// TEST SECTION STARTS BELOW
}
}
}

7
src/main/java/ru/simsonic/rscPermissions/RegionUpdateObserver.java

@ -1,11 +1,9 @@
package ru.simsonic.rscPermissions;
import static java.lang.Thread.MIN_PRIORITY;
import java.util.logging.Level;
import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
import ru.simsonic.utilities.MovingPlayersCatcher;
public class RegionUpdateObserver implements Runnable, Listener
public class RegionUpdateObserver implements Runnable
{
private static final long granularityMin = 20;
private static final long granularityMax = 10000;
@ -18,7 +16,6 @@ public class RegionUpdateObserver implements Runnable, Listener
}
public void registerListeners()
{
rscp.getServer().getPluginManager().registerEvents(this, rscp);
rscp.getServer().getPluginManager().registerEvents(movedPlayers, rscp);
}
public void start()
@ -50,7 +47,7 @@ public class RegionUpdateObserver implements Runnable, Listener
try
{
Thread.currentThread().setName("rscp:RegionUpdateObserver");
Thread.currentThread().setPriority(MIN_PRIORITY);
Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
long granularity = rscp.settings.getRegionFinderGranularity();
if(granularity < granularityMin)
granularity = granularityMin;

3
src/main/java/ru/simsonic/rscPermissions/Settings.java

@ -2,6 +2,9 @@ package ru.simsonic.rscPermissions;
public interface Settings
{
public static final String instantiator = "?";
public static final String separator = ".";
public static final String separatorRegExp = "\\.";
public void onLoad();
public void readSettings();
public String getDefaultGroup();

Loading…
Cancel
Save