Move bukkit specific files

This commit is contained in:
Sauilitired
2015-07-26 16:51:12 +02:00
parent 85d68455e4
commit 9184010c9f
152 changed files with 355 additions and 548 deletions

View File

@ -0,0 +1,589 @@
package com.plotsquared.bukkit;
import com.intellectualcrafters.plot.IPlotMain;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.commands.*;
import com.intellectualcrafters.plot.config.C;
import com.intellectualcrafters.plot.config.Settings;
import com.plotsquared.bukkit.database.plotme.ClassicPlotMeConnector;
import com.plotsquared.bukkit.database.plotme.LikePlotMeConverter;
import com.plotsquared.bukkit.database.plotme.PlotMeConnector_017;
import com.intellectualcrafters.plot.flag.FlagManager;
import com.intellectualcrafters.plot.generator.BukkitHybridUtils;
import com.plotsquared.bukkit.generator.HybridGen;
import com.intellectualcrafters.plot.generator.HybridUtils;
import com.plotsquared.bukkit.listeners.*;
import com.plotsquared.bukkit.listeners.worldedit.WEListener;
import com.plotsquared.bukkit.listeners.worldedit.WESubscriber;
import com.intellectualcrafters.plot.object.PlotManager;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.object.PlotWorld;
import com.plotsquared.bukkit.titles.AbstractTitle;
import com.plotsquared.bukkit.titles.DefaultTitle;
import com.intellectualcrafters.plot.util.*;
import com.intellectualcrafters.plot.uuid.DefaultUUIDWrapper;
import com.intellectualcrafters.plot.uuid.LowerOfflineUUIDWrapper;
import com.intellectualcrafters.plot.uuid.OfflineUUIDWrapper;
import com.intellectualcrafters.plot.uuid.UUIDWrapper;
import com.plotsquared.bukkit.util.SetupUtils;
import com.plotsquared.bukkit.util.bukkit.*;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.command.PluginCommand;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
public class BukkitMain extends JavaPlugin implements Listener, IPlotMain {
public static BukkitMain THIS = null;
private int[] version;
@Override
public boolean checkVersion(final int major, final int minor, final int minor2) {
if (version == null) {
try {
version = new int[3];
final String[] split = Bukkit.getBukkitVersion().split("-")[0].split("\\.");
version[0] = Integer.parseInt(split[0]);
version[1] = Integer.parseInt(split[1]);
if (version.length == 3) {
version[2] = Integer.parseInt(split[2]);
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
return (version[0] > major) || ((version[0] == major) && (version[1] > minor)) || ((version[0] == major) && (version[1] == minor) && (version[2] >= minor2));
}
@Override
public void onEnable() {
THIS = this;
PS.instance = new PS(this);
if (Settings.METRICS) {
try {
final Metrics metrics = new Metrics(this);
metrics.start();
log(C.PREFIX.s() + "&6Metrics enabled.");
} catch (final Exception e) {
log(C.PREFIX.s() + "&cFailed to load up metrics.");
}
} else {
log("&dUsing metrics will allow us to improve the plugin, please consider it :)");
}
List<World> worlds = Bukkit.getWorlds();
if (worlds.size() > 0) {
UUIDHandler.startCaching();
for (World world : worlds) {
try {
SetGenCB.setGenerator(world);
} catch (Exception e) {
log("Failed to reload world: " + world.getName());
Bukkit.getServer().unloadWorld(world, false);
}
}
}
}
@Override
public void onDisable() {
PS.get().disable();
THIS = null;
}
@Override
public void log(String message) {
if (message == null) {
return;
}
if (THIS != null && Bukkit.getServer().getConsoleSender() != null) {
try {
message = C.color(message);
if (!Settings.CONSOLE_COLOR) {
message = ChatColor.stripColor(message);
}
Bukkit.getServer().getConsoleSender().sendMessage(message);
return;
}
catch (Throwable e) {};
}
System.out.println(ConsoleColors.fromString(message));
}
@Override
public void disable() {
if (THIS != null) {
onDisable();
}
}
@Override
public String getVersion() {
return this.getDescription().getVersion();
}
@Override
public void handleKick(UUID uuid, C c) {
Player player = Bukkit.getPlayer(uuid);
if (player != null && player.isOnline()) {
MainUtil.sendMessage(BukkitUtil.getPlayer(player), c);
player.teleport(player.getWorld().getSpawnLocation());
}
}
@Override
public void registerCommands() {
new MainCommand();
MainCommand.subCommands.add(new Buy());
MainCommand.subCommands.add(new Save());
MainCommand.subCommands.add(new Load());
MainCommand.subCommands.add(new Download());
MainCommand.subCommands.add(new Disable());
MainCommand.subCommands.add(new Update());
MainCommand.subCommands.add(new Template());
MainCommand.subCommands.add(new Setup());
MainCommand.subCommands.add(new DebugUUID());
MainCommand.subCommands.add(new DebugFill());
MainCommand.subCommands.add(new DebugSaveTest());
MainCommand.subCommands.add(new DebugLoadTest());
MainCommand.subCommands.add(new CreateRoadSchematic());
MainCommand.subCommands.add(new DebugAllowUnsafe());
MainCommand.subCommands.add(new RegenAllRoads());
MainCommand.subCommands.add(new DebugClear());
MainCommand.subCommands.add(new Claim());
MainCommand.subCommands.add(new Auto());
MainCommand.subCommands.add(new Home());
MainCommand.subCommands.add(new Visit());
MainCommand.subCommands.add(new TP());
MainCommand.subCommands.add(new Set());
MainCommand.subCommands.add(new Toggle());
MainCommand.subCommands.add(new Clear());
MainCommand.subCommands.add(new Delete());
MainCommand.subCommands.add(new SetOwner());
if (Settings.ENABLE_CLUSTERS) {
MainCommand.subCommands.add(new Cluster());
}
MainCommand.subCommands.add(new Trust());
MainCommand.subCommands.add(new Add());
MainCommand.subCommands.add(new Deny());
MainCommand.subCommands.add(new Untrust());
MainCommand.subCommands.add(new Remove());
MainCommand.subCommands.add(new Undeny());
MainCommand.subCommands.add(new Info());
MainCommand.subCommands.add(new list());
MainCommand.subCommands.add(new Help());
MainCommand.subCommands.add(new Debug());
MainCommand.subCommands.add(new SchematicCmd());
MainCommand.subCommands.add(new plugin());
MainCommand.subCommands.add(new Inventory());
MainCommand.subCommands.add(new Purge());
MainCommand.subCommands.add(new Reload());
MainCommand.subCommands.add(new Merge());
MainCommand.subCommands.add(new DebugPaste());
MainCommand.subCommands.add(new Unlink());
MainCommand.subCommands.add(new Kick());
MainCommand.subCommands.add(new Rate());
MainCommand.subCommands.add(new DebugClaimTest());
MainCommand.subCommands.add(new Inbox());
MainCommand.subCommands.add(new Comment());
MainCommand.subCommands.add(new Database());
MainCommand.subCommands.add(new Unclaim());
MainCommand.subCommands.add(new Swap());
MainCommand.subCommands.add(new MusicSubcommand());
MainCommand.subCommands.add(new DebugRoadRegen());
MainCommand.subCommands.add(new Trim());
MainCommand.subCommands.add(new DebugExec());
MainCommand.subCommands.add(new FlagCmd());
MainCommand.subCommands.add(new Target());
MainCommand.subCommands.add(new DebugFixFlags());
MainCommand.subCommands.add(new Move());
MainCommand.subCommands.add(new Condense());
MainCommand.subCommands.add(new Confirm());
MainCommand.subCommands.add(new Copy());
MainCommand.subCommands.add(new Chat());
final BukkitCommand bcmd = new BukkitCommand();
final PluginCommand plotCommand = getCommand("plots");
plotCommand.setExecutor(bcmd);
plotCommand.setAliases(Arrays.asList("p", "ps", "plotme", "plot"));
plotCommand.setTabCompleter(bcmd);
}
@Override
public File getDirectory() {
return getDataFolder();
}
@Override
public TaskManager getTaskManager() {
return new BukkitTaskManager();
}
private ArrayDeque<Entity> fastTickEntities;
private ArrayDeque<Entity> slowTickEntities;
@Override
public void runEntityTask() {
// fastTickEntities = new ArrayDeque<>();
// slowTickEntities = new ArrayDeque<>();
log(C.PREFIX.s() + "KillAllEntities started.");
TaskManager.runTaskRepeat(new Runnable() {
long ticked = 0l;
long error = 0l;
@Override
public void run() {
if (this.ticked > 36_000L) {
this.ticked = 0l;
if (this.error > 0) {
log(C.PREFIX.s() + "KillAllEntities has been running for 6 hours. Errors: " + this.error);
}
this.error = 0l;
}
World world;
for (final PlotWorld pw : PS.get().getPlotWorldObjects()) {
PlotManager manager = PS.get().getPlotManager(pw.worldname);
world = Bukkit.getWorld(pw.worldname);
try {
for (Entity entity : world.getEntities()) {
switch (entity.getType()) {
case EGG:
case ENDER_CRYSTAL:
case COMPLEX_PART:
case ARMOR_STAND:
case FISHING_HOOK:
case ENDER_SIGNAL:
case EXPERIENCE_ORB:
case LEASH_HITCH:
case FIREWORK:
case WEATHER:
case LIGHTNING:
case WITHER_SKULL:
case UNKNOWN:
case ITEM_FRAME:
case PAINTING:
case PLAYER: {
// non moving / unremovable
continue;
}
case THROWN_EXP_BOTTLE:
case SPLASH_POTION:
case SNOWBALL:
case ENDER_PEARL:
case ARROW: {
// managed elsewhere | projectile
continue;
}
case MINECART:
case MINECART_CHEST:
case MINECART_COMMAND:
case MINECART_FURNACE:
case MINECART_HOPPER:
case MINECART_MOB_SPAWNER:
case MINECART_TNT:
case BOAT: {
// vehicle
continue;
}
case SMALL_FIREBALL:
case FIREBALL:
case DROPPED_ITEM: {
// dropped item
continue;
}
case PRIMED_TNT:
case FALLING_BLOCK: {
// managed elsewhere
continue;
}
case BAT:
case BLAZE:
case CAVE_SPIDER:
case CHICKEN:
case COW:
case CREEPER:
case ENDERMAN:
case ENDERMITE:
case ENDER_DRAGON:
case GHAST:
case GIANT:
case GUARDIAN:
case HORSE:
case IRON_GOLEM:
case MAGMA_CUBE:
case MUSHROOM_COW:
case OCELOT:
case PIG:
case PIG_ZOMBIE:
case RABBIT:
case SHEEP:
case SILVERFISH:
case SKELETON:
case SLIME:
case SNOWMAN:
case SPIDER:
case SQUID:
case VILLAGER:
case WITCH:
case WITHER:
case WOLF:
case ZOMBIE:
default: {
Location loc = entity.getLocation();
if (MainUtil.isPlotRoad(BukkitUtil.getLocation(loc))) {
entity.remove();
}
break;
}
}
}
} catch (final Throwable e) {
++this.error;
} finally {
++this.ticked;
}
}
}
}, 20);
}
@Override
final public ChunkGenerator getDefaultWorldGenerator(final String world, final String id) {
WorldEvents.lastWorld = world;
if (!PS.get().setupPlotWorld(world, id)) {
return null;
}
HybridGen result = new HybridGen(world);
TaskManager.runTaskLater(new Runnable() {
@Override
public void run() {
if (WorldEvents.lastWorld != null && WorldEvents.lastWorld.equals(world)) {
WorldEvents.lastWorld = null;
}
}
}, 20);
return result;
}
@Override
public void registerPlayerEvents() {
getServer().getPluginManager().registerEvents(new PlayerEvents(), this);
if (checkVersion(1, 8, 0)) {
getServer().getPluginManager().registerEvents(new PlayerEvents_1_8(), this);
}
if (checkVersion(1, 8, 3)) {
getServer().getPluginManager().registerEvents(new PlayerEvents_1_8_3(), this);
}
}
@Override
public void registerInventoryEvents() {
getServer().getPluginManager().registerEvents(new InventoryListener(), this);
}
@Override
public void registerPlotPlusEvents() {
PlotPlusListener.startRunnable(this);
getServer().getPluginManager().registerEvents(new PlotPlusListener(), this);
}
@Override
public void registerForceFieldEvents() {
getServer().getPluginManager().registerEvents(new ForceFieldListener(), this);
}
@Override
public void registerWorldEditEvents() {
if (getServer().getPluginManager().getPlugin("WorldEdit") != null) {
PS.get().worldEdit = (WorldEditPlugin) getServer().getPluginManager().getPlugin("WorldEdit");
final String version = PS.get().worldEdit.getDescription().getVersion();
if ((version != null) && version.startsWith("5.")) {
log("&cThis version of WorldEdit does not support PlotSquared.");
log("&cPlease use WorldEdit 6+ for masking support");
log("&c - http://builds.enginehub.org/job/worldedit");
} else {
getServer().getPluginManager().registerEvents(new WEListener(), this);
WorldEdit.getInstance().getEventBus().register(new WESubscriber());
MainCommand.subCommands.add(new WE_Anywhere());
}
}
}
@Override
public EconHandler getEconomyHandler() {
try {
BukkitEconHandler econ = new BukkitEconHandler();
if (econ.init()) {
return econ;
}
} catch (Throwable e) {
}
return null;
}
@Override
public BlockManager initBlockManager() {
if (checkVersion(1, 8, 0)) {
try {
BukkitSetBlockManager.setBlockManager = new SetBlockFast_1_8();
} catch (final Throwable e) {
e.printStackTrace();
BukkitSetBlockManager.setBlockManager = new SetBlockSlow();
}
try {
new SendChunk();
MainUtil.canSendChunk = true;
} catch (final Throwable e) {
MainUtil.canSendChunk = false;
}
} else {
try {
BukkitSetBlockManager.setBlockManager = new SetBlockFast();
} catch (final Throwable e) {
MainUtil.canSetFast = false;
BukkitSetBlockManager.setBlockManager = new SetBlockSlow();
}
}
BlockUpdateUtil.setBlockManager = BukkitSetBlockManager.setBlockManager;
return BlockManager.manager = new BukkitUtil();
}
@Override
public boolean initPlotMeConverter() {
TaskManager.runTaskLaterAsync(new Runnable() {
@Override
public void run() {
if (new LikePlotMeConverter("PlotMe").run(new ClassicPlotMeConnector())) return;
if (new LikePlotMeConverter("PlotMe").run(new PlotMeConnector_017())) return;
if (new LikePlotMeConverter("AthionPlots").run(new ClassicPlotMeConnector())) return;
}
}, 20);
return Bukkit.getPluginManager().getPlugin("PlotMe") != null || Bukkit.getPluginManager().getPlugin("AthionPlots") != null;
}
@Override
public ChunkGenerator getGenerator(final String world, final String name) {
final Plugin gen_plugin = Bukkit.getPluginManager().getPlugin(name);
if ((gen_plugin != null) && gen_plugin.isEnabled()) {
return gen_plugin.getDefaultWorldGenerator(world, "");
} else {
return new HybridGen(world);
}
}
@Override
public HybridUtils initHybridUtils() {
return new BukkitHybridUtils();
}
@Override
public SetupUtils initSetupUtils() {
return new BukkitSetupUtils();
}
@Override
public UUIDWrapper initUUIDHandler() {
final boolean checkVersion = checkVersion(1, 7, 6);
if (Settings.OFFLINE_MODE) {
if (Settings.UUID_LOWERCASE) {
UUIDHandler.setUUIDWrapper(new LowerOfflineUUIDWrapper());
} else {
UUIDHandler.setUUIDWrapper(new OfflineUUIDWrapper());
}
Settings.OFFLINE_MODE = true;
} else if (checkVersion) {
UUIDHandler.setUUIDWrapper(new DefaultUUIDWrapper());
Settings.OFFLINE_MODE = false;
} else {
if (Settings.UUID_LOWERCASE) {
UUIDHandler.setUUIDWrapper(new LowerOfflineUUIDWrapper());
} else {
UUIDHandler.setUUIDWrapper(new OfflineUUIDWrapper());
}
Settings.OFFLINE_MODE = true;
}
if (!checkVersion) {
log(C.PREFIX.s() + " &c[WARN] Titles are disabled - please update your version of Bukkit to support this feature.");
Settings.TITLES = false;
FlagManager.removeFlag(FlagManager.getFlag("titles"));
} else {
AbstractTitle.TITLE_CLASS = new DefaultTitle();
if (UUIDHandler.getUUIDWrapper() instanceof DefaultUUIDWrapper) {
Settings.TWIN_MODE_UUID = true;
} else if (UUIDHandler.getUUIDWrapper() instanceof OfflineUUIDWrapper && !Bukkit.getOnlineMode()) {
Settings.TWIN_MODE_UUID = true;
}
}
if (Settings.OFFLINE_MODE) {
log(C.PREFIX.s() + " &6PlotSquared is using Offline Mode UUIDs either because of user preference, or because you are using an old version of Bukkit");
} else {
log(C.PREFIX.s() + " &6PlotSquared is using online UUIDs");
}
return UUIDHandler.getUUIDWrapper();
}
@Override
public ChunkManager initChunkManager() {
return new BukkitChunkManager();
}
@Override
public EventUtil initEventUtil() {
return new BukkitEventUtil();
}
@Override
public void registerTNTListener() {
getServer().getPluginManager().registerEvents(new TNTListener(), this);
}
@Override
public void unregister(PlotPlayer player) {
BukkitUtil.removePlayer(player.getName());
}
@Override
public APlotListener initPlotListener() {
return new PlotListener();
}
@Override
public void registerChunkProcessor() {
getServer().getPluginManager().registerEvents(new ChunkListener(), this);
}
@Override
public void registerWorldEvents() {
getServer().getPluginManager().registerEvents(new WorldEvents(), this);
}
@Override
public PlayerManager initPlayerManager() {
return new BukkitPlayerManager();
}
@Override
public InventoryUtil initInventoryUtil() {
return new BukkitInventoryUtil();
}
@Override
public String getServerName() {
return Bukkit.getServerName();
}
}

View File

@ -0,0 +1,117 @@
package com.plotsquared.bukkit.database.plotme;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.HashMap;
import org.bukkit.Bukkit;
import org.bukkit.World;
import com.intellectualcrafters.configuration.file.FileConfiguration;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotId;
public abstract class APlotMeConnector {
public abstract Connection getPlotMeConnection(String plugin, FileConfiguration plotConfig, String dataFolder);
public abstract HashMap<String, HashMap<PlotId, Plot>> getPlotMePlots(Connection connection) throws SQLException;
public abstract boolean accepts(String version);
public String getWorld(final String world) {
for (final World newworld : Bukkit.getWorlds()) {
if (newworld.getName().equalsIgnoreCase(world)) {
return newworld.getName();
}
}
return world;
}
public boolean isValidConnection(Connection connection) {
return connection != null;
}
public void copyConfig(FileConfiguration plotConfig, String world, String actualWorldName) {
final Integer pathwidth = plotConfig.getInt("worlds." + world + ".PathWidth"); //
PS.get().config.set("worlds." + actualWorldName + ".road.width", pathwidth);
final Integer plotsize = plotConfig.getInt("worlds." + world + ".PlotSize"); //
PS.get().config.set("worlds." + actualWorldName + ".plot.size", plotsize);
final String wallblock = plotConfig.getString("worlds." + world + ".WallBlockId"); //
PS.get().config.set("worlds." + actualWorldName + ".wall.block", wallblock);
final String floor = plotConfig.getString("worlds." + world + ".PlotFloorBlockId"); //
PS.get().config.set("worlds." + actualWorldName + ".plot.floor", Arrays.asList(floor));
final String filling = plotConfig.getString("worlds." + world + ".PlotFillingBlockId"); //
PS.get().config.set("worlds." + actualWorldName + ".plot.filling", Arrays.asList(filling));
final String road = plotConfig.getString("worlds." + world + ".RoadMainBlockId");
PS.get().config.set("worlds." + actualWorldName + ".road.block", road);
Integer height = plotConfig.getInt("worlds." + world + ".RoadHeight"); //
if (height == null) {
height = 64;
}
PS.get().config.set("worlds." + actualWorldName + ".road.height", height);
}
public Location getPlotTopLocAbs(int path, int plot, final PlotId plotid) {
final int px = plotid.x;
final int pz = plotid.y;
final int x = (px * (path + plot)) - ((int) Math.floor(path / 2)) - 1;
final int z = (pz * (path + plot)) - ((int) Math.floor(path / 2)) - 1;
return new Location(null, x, 256, z);
}
public Location getPlotBottomLocAbs(int path, int plot, final PlotId plotid) {
final int px = plotid.x;
final int pz = plotid.y;
final int x = (px * (path + plot)) - plot - ((int) Math.floor(path / 2)) - 1;
final int z = (pz * (path + plot)) - plot - ((int) Math.floor(path / 2)) - 1;
return new Location(null, x, 1, z);
}
public void setMerged(HashMap<String, HashMap<PlotId, boolean[]>> merges, String world, PlotId id, int direction) {
HashMap<PlotId, boolean[]> plots = merges.get(world);
PlotId id2;
switch (direction) {
case 0: {
id2 = new PlotId(id.x, id.y);
break;
}
case 1: {
id2 = new PlotId(id.x, id.y);
break;
}
case 2: {
id2 = new PlotId(id.x, id.y);
break;
}
case 3: {
id2 = new PlotId(id.x, id.y);
break;
}
default: {
return;
}
}
boolean[] merge1;
boolean[] merge2;
if (plots.containsKey(id)) {
merge1 = plots.get(id);
}
else {
merge1 = new boolean[]{false, false, false, false};
}
if (plots.containsKey(id2)) {
merge2 = plots.get(id2);
}
else {
merge2 = new boolean[]{false, false, false, false};
}
merge1[direction] = true;
merge2[(direction + 2) % 4] = true;
plots.put(id, merge1);
plots.put(id2, merge1);
}
}

View File

@ -0,0 +1,202 @@
package com.plotsquared.bukkit.database.plotme;
import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.UUID;
import com.intellectualcrafters.configuration.file.FileConfiguration;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.config.Settings;
import com.intellectualcrafters.plot.database.DBFunc;
import com.intellectualcrafters.plot.database.SQLite;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotId;
import com.intellectualcrafters.plot.object.StringWrapper;
import com.intellectualcrafters.plot.util.MainUtil;
import com.plotsquared.bukkit.util.bukkit.UUIDHandler;
public class ClassicPlotMeConnector extends APlotMeConnector {
private String plugin;
@Override
public Connection getPlotMeConnection(String plugin, FileConfiguration plotConfig, String dataFolder) {
this.plugin = plugin.toLowerCase();
try {
if (plotConfig.getBoolean("usemySQL")) {
final String user = plotConfig.getString("mySQLuname");
final String password = plotConfig.getString("mySQLpass");
final String con = plotConfig.getString("mySQLconn");
return DriverManager.getConnection(con, user, password);
// return new MySQL(plotsquared, hostname, port, database, username, password)
} else {
return new SQLite(dataFolder + File.separator + "plots.db").openConnection();
}
}
catch (SQLException | ClassNotFoundException e) {}
return null;
}
@Override
public HashMap<String, HashMap<PlotId, Plot>> getPlotMePlots(Connection connection) throws SQLException {
ResultSet r;
PreparedStatement stmt;
final HashMap<String, Integer> plotWidth = new HashMap<>();
final HashMap<String, Integer> roadWidth = new HashMap<>();
final HashMap<String, HashMap<PlotId, Plot>> plots = new HashMap<>();
final HashMap<String, HashMap<PlotId, boolean[]>> merges = new HashMap<>();
stmt = connection.prepareStatement("SELECT * FROM `" + plugin + "Plots`");
r = stmt.executeQuery();
boolean checkUUID = DBFunc.hasColumn(r, "ownerid");
boolean merge = !plugin.equals("plotme") && Settings.CONVERT_PLOTME;
while (r.next()) {
final PlotId id = new PlotId(r.getInt("idX"), r.getInt("idZ"));
final String name = r.getString("owner");
final String world = LikePlotMeConverter.getWorld(r.getString("world"));
if (!plots.containsKey(world)) {
plots.put(world, new HashMap<PlotId, Plot>());
if (merge) {
int plot = PS.get().config.getInt("worlds." + world + ".plot.size");
int path = PS.get().config.getInt("worlds." + world + ".road.width");
plotWidth.put(world, plot);
roadWidth.put(world, path);
merges.put(world, new HashMap<PlotId,boolean[]>());
}
}
if (merge) {
int tx = r.getInt("topX");
int tz = r.getInt("topZ");
int bx = r.getInt("bottomX") - 1;
int bz = r.getInt("bottomZ") - 1;
int path = roadWidth.get(world);
int plot = plotWidth.get(world);
Location top = getPlotTopLocAbs(path, plot, id);
Location bot = getPlotBottomLocAbs(path, plot, id);
if (tx > top.getX()) {
setMerged(merges, world, id, 1);
}
if (tz > top.getZ()) {
setMerged(merges, world, id, 2);
}
if (bx < bot.getX()) {
setMerged(merges, world, id, 3);
}
if (bz > bot.getZ()) {
setMerged(merges, world, id, 0);
}
}
UUID owner = UUIDHandler.getUUID(name);
if (owner == null) {
if (name.equals("*")) {
owner = DBFunc.everyone;
}
else {
if (checkUUID){
try {
byte[] bytes = r.getBytes("ownerid");
if (bytes != null) {
owner = UUID.nameUUIDFromBytes(bytes);
if (owner != null) {
UUIDHandler.add(new StringWrapper(name), owner);
}
}
}
catch (Exception e) {
e.printStackTrace();
}
}
if (owner == null) {
MainUtil.sendConsoleMessage("&cCould not identify owner for plot: " + id + " -> '" + name + "'");
continue;
}
}
}
else {
UUIDHandler.add(new StringWrapper(name), owner);
}
final Plot plot = new Plot(world, id, owner);
plots.get(world).put(id, plot);
}
for (Entry<String, HashMap<PlotId, boolean[]>> entry : merges.entrySet()) {
String world = entry.getKey();
for (Entry<PlotId, boolean[]> entry2 : entry.getValue().entrySet()) {
HashMap<PlotId, Plot> newplots = plots.get(world);
Plot plot = newplots.get(entry2.getKey());
if (plot != null) {
plot.getSettings().setMerged(entry2.getValue());
}
}
}
r.close();
stmt.close();
try {
MainUtil.sendConsoleMessage(" - " + plugin + "Denied");
stmt = connection.prepareStatement("SELECT * FROM `" + plugin + "Denied`");
r = stmt.executeQuery();
while (r.next()) {
final PlotId id = new PlotId(r.getInt("idX"), r.getInt("idZ"));
final String name = r.getString("player");
final String world = LikePlotMeConverter.getWorld(r.getString("world"));
UUID denied = UUIDHandler.getUUID(name);
if (denied == null) {
if (name.equals("*")) {
denied = DBFunc.everyone;
} else {
MainUtil.sendConsoleMessage("&6Could not identify denied for plot: " + id);
continue;
}
}
if (plots.get(world).containsKey(id)) {
plots.get(world).get(id).getDenied().add(denied);
}
}
stmt = connection.prepareStatement("SELECT * FROM `" + plugin + "Allowed`");
r = stmt.executeQuery();
while (r.next()) {
final PlotId id = new PlotId(r.getInt("idX"), r.getInt("idZ"));
final String name = r.getString("player");
final String world = LikePlotMeConverter.getWorld(r.getString("world"));
UUID helper = UUIDHandler.getUUID(name);
if (helper == null) {
if (name.equals("*")) {
helper = DBFunc.everyone;
} else {
MainUtil.sendConsoleMessage("&6Could not identify helper for plot: " + id);
continue;
}
}
if (plots.get(world).containsKey(id)) {
plots.get(world).get(id).getTrusted().add(helper);
}
}
r.close();
stmt.close();
}
catch (Exception e) {}
return plots;
}
@Override
public boolean accepts(String version) {
if (version == null) {
return true;
}
return PS.get().canUpdate(version, "0.17.0");
}
}

View File

@ -0,0 +1,323 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// PlotSquared - A plot manager and world generator for the Bukkit API /
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters /
// /
// This program is free software; you can redistribute it and/or modify /
// it under the terms of the GNU General Public License as published by /
// the Free Software Foundation; either version 3 of the License, or /
// (at your option) any later version. /
// /
// This program is distributed in the hope that it will be useful, /
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the /
// GNU General Public License for more details. /
// /
// You should have received a copy of the GNU General Public License /
// along with this program; if not, write to the Free Software Foundation, /
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /
// /
// You can contact us via: support@intellectualsites.com /
////////////////////////////////////////////////////////////////////////////////////////////////////
package com.plotsquared.bukkit.database.plotme;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.WorldCreator;
import com.intellectualcrafters.configuration.file.FileConfiguration;
import com.intellectualcrafters.configuration.file.YamlConfiguration;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.config.Settings;
import com.intellectualcrafters.plot.database.DBFunc;
import com.plotsquared.bukkit.generator.HybridGen;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotId;
import com.intellectualcrafters.plot.util.TaskManager;
/**
* Created 2014-08-17 for PlotSquared
*
* @author Citymonstret
* @author Empire92
*/
public class LikePlotMeConverter {
private String plugin;
/**
* Constructor
*
* @param plugin Plugin Used to run the converter
*/
public LikePlotMeConverter(String plugin) {
this.plugin = plugin;
}
public static String getWorld(final String world) {
for (final World newworld : Bukkit.getWorlds()) {
if (newworld.getName().equalsIgnoreCase(world)) {
return newworld.getName();
}
}
return world;
}
private void sendMessage(final String message) {
PS.log("&3PlotMe&8->&3PlotSquared&8: &7" + message);
}
public String getPlotMePath() {
return new File(".").getAbsolutePath() + File.separator + "plugins" + File.separator + plugin + File.separator;
}
public String getAthionPlotsPath() {
return new File(".").getAbsolutePath() + File.separator + "plugins" + File.separator + plugin + File.separator;
}
public FileConfiguration getPlotMeConfig(String dataFolder) {
final File plotMeFile = new File(dataFolder + "config.yml");
if (!plotMeFile.exists()) {
return null;
}
return YamlConfiguration.loadConfiguration(plotMeFile);
}
public Set<String> getPlotMeWorlds(FileConfiguration plotConfig) {
return plotConfig.getConfigurationSection("worlds").getKeys(false);
}
public void updateWorldYml(String plugin, String location) {
try {
Path path = Paths.get(location);
File file = new File(location);
if (!file.exists()) {
return;
}
Charset charset = StandardCharsets.UTF_8;
String content = new String(Files.readAllBytes(path), charset);
content = content.replaceAll("PlotMe-DefaultGenerator", "PlotSquared");
content = content.replaceAll(plugin, "PlotSquared");
Files.write(path, content.getBytes(charset));
} catch (Exception e) {
}
}
public boolean run(final APlotMeConnector connector) {
try {
String dataFolder = getPlotMePath();
FileConfiguration plotConfig = getPlotMeConfig(dataFolder);
if (plotConfig == null) {
return false;
}
String version = plotConfig.getString("Version");
if (version == null) version = plotConfig.getString("version");
if (!connector.accepts(version)) {
return false;
}
PS.log("&3Using connector: " + connector.getClass().getCanonicalName());
Connection connection = connector.getPlotMeConnection(plugin, plotConfig, dataFolder);
if (!connector.isValidConnection(connection)) {
sendMessage("Cannot connect to PlotMe DB. Conversion process will not continue");
return false;
}
sendMessage(plugin + " conversion has started. To disable this, please set 'plotme-convert.enabled' in the 'settings.yml'");
sendMessage("Connecting to " + plugin + " DB");
int plotCount = 0;
final ArrayList<Plot> createdPlots = new ArrayList<>();
sendMessage("Collecting plot data");
String dbPrefix = plugin.toLowerCase();
sendMessage(" - " + dbPrefix + "Plots");
final Set<String> worlds = getPlotMeWorlds(plotConfig);
if (Settings.CONVERT_PLOTME) {
sendMessage("Updating bukkit.yml");
updateWorldYml(plugin, "bukkit.yml");
updateWorldYml(plugin, "plugins/Multiverse-Core/worlds.yml");
for (final String world : plotConfig.getConfigurationSection("worlds").getKeys(false)) {
sendMessage("Copying config for: " + world);
try {
String actualWorldName = getWorld(world);
connector.copyConfig(plotConfig, world, actualWorldName);
PS.get().config.save(PS.get().configFile);
} catch (final Exception e) {
e.printStackTrace();
sendMessage("&c-- &lFailed to save configuration for world '" + world + "'\nThis will need to be done using the setup command, or manually");
}
}
}
HashMap<String, HashMap<PlotId, Plot>> plots = connector.getPlotMePlots(connection);
for (Entry<String, HashMap<PlotId, Plot>> entry : plots.entrySet()) {
plotCount += entry.getValue().size();
}
if (!Settings.CONVERT_PLOTME) {
return false;
}
sendMessage(" - " + dbPrefix + "Allowed");
sendMessage("Collected " + plotCount + " plots from PlotMe");
final File PLOTME_DG_FILE = new File(dataFolder + File.separator + "PlotMe-DefaultGenerator" + File.separator + "config.yml");
if (PLOTME_DG_FILE.exists()) {
final YamlConfiguration PLOTME_DG_YML = YamlConfiguration.loadConfiguration(PLOTME_DG_FILE);
try {
for (final String world : plots.keySet()) {
String actualWorldName = getWorld(world);
final String plotMeWorldName = world.toLowerCase();
Integer pathwidth = PLOTME_DG_YML.getInt("worlds." + plotMeWorldName + ".PathWidth"); //
if (pathwidth == null) {
pathwidth = 7;
}
PS.get().config.set("worlds." + world + ".road.width", pathwidth);
Integer plotsize = PLOTME_DG_YML.getInt("worlds." + plotMeWorldName + ".PlotSize"); //
if (plotsize == null) {
plotsize = 32;
}
PS.get().config.set("worlds." + world + ".plot.size", plotsize);
String wallblock = PLOTME_DG_YML.getString("worlds." + plotMeWorldName + ".WallBlock"); //
if (wallblock == null) {
wallblock = "44";
}
PS.get().config.set("worlds." + world + ".wall.block", wallblock);
String floor = PLOTME_DG_YML.getString("worlds." + plotMeWorldName + ".PlotFloorBlock"); //
if (floor == null) {
floor = "2";
}
PS.get().config.set("worlds." + world + ".plot.floor", Arrays.asList(floor));
String filling = PLOTME_DG_YML.getString("worlds." + plotMeWorldName + ".FillBlock"); //
if (filling == null) {
filling = "3";
}
PS.get().config.set("worlds." + world + ".plot.filling", Arrays.asList(filling));
String road = PLOTME_DG_YML.getString("worlds." + plotMeWorldName + ".RoadMainBlock");
if (road == null) {
road = "5";
}
PS.get().config.set("worlds." + world + ".road.block", road);
Integer height = PLOTME_DG_YML.getInt("worlds." + plotMeWorldName + ".RoadHeight"); //
if ((height == null) || (height == 0)) {
height = PLOTME_DG_YML.getInt("worlds." + plotMeWorldName + ".GroundHeight"); //
if ((height == null) || (height == 0)) {
height = 64;
}
}
PS.get().config.set("worlds." + actualWorldName + ".road.height", height);
PS.get().config.set("worlds." + actualWorldName + ".plot.height", height);
PS.get().config.set("worlds." + actualWorldName + ".wall.height", height);
PS.get().config.save(PS.get().configFile);
}
} catch (final Exception e) {
}
}
for (final String world : plots.keySet()) {
int duplicate = 0;
for (final Plot plot : plots.get(world).values()) {
if (!PS.get().getPlots(world).containsKey(plot.id)) {
createdPlots.add(plot);
} else {
duplicate++;
}
}
if (duplicate > 0) {
PS.log("&c[WARNING] Found " + duplicate + " duplicate plots already in DB for world: '" + world + "'. Have you run the converter already?");
}
}
sendMessage("Creating plot DB");
Thread.sleep(1000);
DBFunc.createPlotsAndData(createdPlots, new Runnable() {
@Override
public void run() {
sendMessage("&aDatabase conversion is now complete!");
PS.log("&c - Stop the server");
PS.log("&c - Disable 'plotme-convert.enabled' and 'plotme-convert.cache-uuids' in the settings.yml");
PS.log("&c - Correct any generator settings that haven't copied to 'settings.yml' properly");
PS.log("&c - Start the server");
PS.get().setAllPlotsRaw(DBFunc.getPlots());
}
});
sendMessage("Saving configuration...");
try {
PS.get().config.save(PS.get().configFile);
} catch (final IOException e) {
sendMessage(" - &cFailed to save configuration.");
}
TaskManager.runTask(new Runnable() {
@Override
public void run() {
try {
boolean MV = false;
boolean MW = false;
if ((Bukkit.getPluginManager().getPlugin("Multiverse-Core") != null) && Bukkit.getPluginManager().getPlugin("Multiverse-Core").isEnabled()) {
MV = true;
} else if ((Bukkit.getPluginManager().getPlugin("MultiWorld") != null) && Bukkit.getPluginManager().getPlugin("MultiWorld").isEnabled()) {
MW = true;
}
for (final String worldname : worlds) {
final World world = Bukkit.getWorld(getWorld(worldname));
if (world == null) {
sendMessage("&cInvalid world in PlotMe configuration: " + worldname);
}
final String actualWorldName = world.getName();
sendMessage("Reloading generator for world: '" + actualWorldName + "'...");
PS.get().removePlotWorld(actualWorldName);
if (MV) {
// unload world with MV
Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), "mv unload " + actualWorldName);
try {
Thread.sleep(1000);
} catch (final InterruptedException ex) {
Thread.currentThread().interrupt();
}
// load world with MV
Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), "mv import " + actualWorldName + " normal -g PlotSquared");
} else if (MW) {
// unload world with MW
Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), "mw unload " + actualWorldName);
try {
Thread.sleep(1000);
} catch (final InterruptedException ex) {
Thread.currentThread().interrupt();
}
// load world with MW
Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), "mw create " + actualWorldName + " plugin:PlotSquared");
} else {
// Load using Bukkit API
// - User must set generator manually
Bukkit.getServer().unloadWorld(world, true);
final World myworld = WorldCreator.name(actualWorldName).generator(new HybridGen(actualWorldName)).createWorld();
myworld.save();
}
}
} catch (final Exception e) {
e.printStackTrace();
}
sendMessage("&cPlease wait until database conversion is complete. You will be notified with instructions when this happens!");
}
});
} catch (final Exception e) {
e.printStackTrace();
PS.log("&/end/");
}
return true;
}
}

View File

@ -0,0 +1,198 @@
package com.plotsquared.bukkit.database.plotme;
import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.UUID;
import com.intellectualcrafters.configuration.file.FileConfiguration;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.config.Settings;
import com.intellectualcrafters.plot.database.DBFunc;
import com.intellectualcrafters.plot.database.SQLite;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotId;
import com.intellectualcrafters.plot.object.StringWrapper;
import com.intellectualcrafters.plot.util.MainUtil;
import com.plotsquared.bukkit.util.bukkit.UUIDHandler;
public class PlotMeConnector_017 extends APlotMeConnector {
private String plugin;
@Override
public Connection getPlotMeConnection(String plugin, FileConfiguration plotConfig, String dataFolder) {
this.plugin = plugin.toLowerCase();
try {
if (plotConfig.getBoolean("usemySQL")) {
String user = plotConfig.getString("mySQLuname");
String password = plotConfig.getString("mySQLpass");
String con = plotConfig.getString("mySQLconn");
return DriverManager.getConnection(con, user, password);
} else {
File file = new File(dataFolder + File.separator + "plotmecore.db");
if (file.exists()) {
return new SQLite(dataFolder + File.separator + "plotmecore.db").openConnection();
}
return new SQLite(dataFolder + File.separator + "plots.db").openConnection();
}
}
catch (SQLException | ClassNotFoundException e) {}
return null;
}
@Override
public HashMap<String, HashMap<PlotId, Plot>> getPlotMePlots(Connection connection) throws SQLException {
ResultSet r;
PreparedStatement stmt;
HashMap<String, Integer> plotWidth = new HashMap<>();
HashMap<String, Integer> roadWidth = new HashMap<>();
final HashMap<Integer, Plot> plots = new HashMap<>();
HashMap<String, HashMap<PlotId, boolean[]>> merges = new HashMap<>();
stmt = connection.prepareStatement("SELECT * FROM `" + plugin + "core_plots`");
r = stmt.executeQuery();
boolean checkUUID = DBFunc.hasColumn(r, "ownerID");
boolean merge = !plugin.equals("plotme") && Settings.CONVERT_PLOTME;
while (r.next()) {
int key = r.getInt("plot_id");
PlotId id = new PlotId(r.getInt("plotX"), r.getInt("plotZ"));
String name = r.getString("owner");
String world = LikePlotMeConverter.getWorld(r.getString("world"));
if (!plots.containsKey(world)) {
if (merge) {
int plot = PS.get().config.getInt("worlds." + world + ".plot.size");
int path = PS.get().config.getInt("worlds." + world + ".road.width");
plotWidth.put(world, plot);
roadWidth.put(world, path);
merges.put(world, new HashMap<PlotId,boolean[]>());
}
}
if (merge) {
int tx = r.getInt("topX");
int tz = r.getInt("topZ");
int bx = r.getInt("bottomX") - 1;
int bz = r.getInt("bottomZ") - 1;
int path = roadWidth.get(world);
int plot = plotWidth.get(world);
Location top = getPlotTopLocAbs(path, plot, id);
Location bot = getPlotBottomLocAbs(path, plot, id);
if (tx > top.getX()) {
setMerged(merges, world, id, 1);
}
if (tz > top.getZ()) {
setMerged(merges, world, id, 2);
}
if (bx < bot.getX()) {
setMerged(merges, world, id, 3);
}
if (bz > bot.getZ()) {
setMerged(merges, world, id, 0);
}
}
UUID owner = UUIDHandler.getUUID(name);
if (owner == null) {
if (name.equals("*")) {
owner = DBFunc.everyone;
}
else {
if (checkUUID){
try {
byte[] bytes = r.getBytes("ownerid");
if (bytes != null) {
owner = UUID.nameUUIDFromBytes(bytes);
if (owner != null) {
UUIDHandler.add(new StringWrapper(name), owner);
}
}
}
catch (Exception e) {
e.printStackTrace();
}
}
if (owner == null) {
MainUtil.sendConsoleMessage("&cCould not identify owner for plot: " + id + " -> '" + name + "'");
continue;
}
}
}
else {
UUIDHandler.add(new StringWrapper(name), owner);
}
Plot plot = new Plot(world, id, owner);
plots.put(key, plot);
}
for (Entry<Integer, Plot> entry : plots.entrySet()) {
Plot plot = entry.getValue();
HashMap<PlotId, boolean[]> mergeMap = merges.get(plot.world);
if (mergeMap != null) {
if (mergeMap.containsKey(plot.id)) {
plot.getSettings().setMerged(mergeMap.get(plot.id));
}
}
}
r.close();
stmt.close();
try {
MainUtil.sendConsoleMessage(" - " + plugin + "core_denied");
stmt = connection.prepareStatement("SELECT * FROM `" + plugin + "core_denied`");
r = stmt.executeQuery();
while (r.next()) {
int key = r.getInt("plot_id");
Plot plot = plots.get(key);
if (plot == null) {
MainUtil.sendConsoleMessage("&6Denied (" + key + ") references deleted plot; ignoring entry.");
continue;
}
UUID denied = UUID.fromString(r.getString("player"));
plot.getDenied().add(denied);
}
MainUtil.sendConsoleMessage(" - " + plugin + "core_allowed");
stmt = connection.prepareStatement("SELECT * FROM `" + plugin + "core_allowed`");
r = stmt.executeQuery();
while (r.next()) {
int key = r.getInt("plot_id");
Plot plot = plots.get(key);
if (plot == null) {
MainUtil.sendConsoleMessage("&6Allowed (" + key + ") references deleted plot; ignoring entry.");
continue;
}
UUID allowed = UUID.fromString(r.getString("player"));
plot.getTrusted().add(allowed);
}
r.close();
stmt.close();
}
catch (Exception e) {
e.printStackTrace();
}
HashMap<String, HashMap<PlotId, Plot>> processed = new HashMap<>();
for (Entry<Integer, Plot> entry : plots.entrySet()) {
Plot plot = entry.getValue();
HashMap<PlotId, Plot> map = processed.get(plot.world);
if (map == null) {
map = new HashMap<>();
processed.put(plot.world, map);
}
map.put(plot.id, plot);
}
return processed ;
}
@Override
public boolean accepts(String version) {
if (version == null) {
return false;
}
return !PS.get().canUpdate(version, "0.17");
}
}

View File

@ -0,0 +1,89 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// PlotSquared - A plot manager and world generator for the Bukkit API /
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters /
// /
// This program is free software; you can redistribute it and/or modify /
// it under the terms of the GNU General Public License as published by /
// the Free Software Foundation; either version 3 of the License, or /
// (at your option) any later version. /
// /
// This program is distributed in the hope that it will be useful, /
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the /
// GNU General Public License for more details. /
// /
// You should have received a copy of the GNU General Public License /
// along with this program; if not, write to the Free Software Foundation, /
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /
// /
// You can contact us via: support@intellectualsites.com /
////////////////////////////////////////////////////////////////////////////////////////////////////
package com.plotsquared.bukkit.events;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import com.intellectualcrafters.plot.flag.Flag;
import com.intellectualcrafters.plot.object.PlotCluster;
/**
* Called when a flag is removed from a plot
*
* @author Citymonstret
* @author Empire92
*/
public class ClusterFlagRemoveEvent extends Event implements Cancellable {
private static HandlerList handlers = new HandlerList();
private final PlotCluster cluster;
private final Flag flag;
private boolean cancelled;
/**
* PlotFlagRemoveEvent: Called when a flag is removed from a plot
*
* @param flag Flag that was removed
* @param plot Plot from which the flag was removed
*/
public ClusterFlagRemoveEvent(final Flag flag, final PlotCluster cluster) {
this.cluster = cluster;
this.flag = flag;
}
public static HandlerList getHandlerList() {
return handlers;
}
/**
* Get the cluster involved
*
* @return PlotCluster
*/
public PlotCluster getCluster() {
return this.cluster;
}
/**
* Get the flag involved
*
* @return Flag
*/
public Flag getFlag() {
return this.flag;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
@Override
public void setCancelled(final boolean b) {
this.cancelled = b;
}
}

View File

@ -0,0 +1,86 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// PlotSquared - A plot manager and world generator for the Bukkit API /
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters /
// /
// This program is free software; you can redistribute it and/or modify /
// it under the terms of the GNU General Public License as published by /
// the Free Software Foundation; either version 3 of the License, or /
// (at your option) any later version. /
// /
// This program is distributed in the hope that it will be useful, /
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the /
// GNU General Public License for more details. /
// /
// You should have received a copy of the GNU General Public License /
// along with this program; if not, write to the Free Software Foundation, /
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /
// /
// You can contact us via: support@intellectualsites.com /
////////////////////////////////////////////////////////////////////////////////////////////////////
package com.plotsquared.bukkit.events;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import com.intellectualcrafters.plot.object.Plot;
/**
* @author Citymonstret
* @author Empire92
*/
public class PlayerClaimPlotEvent extends PlayerEvent implements Cancellable {
private static HandlerList handlers = new HandlerList();
private final Plot plot;
private final boolean auto;
private boolean cancelled;
/**
* PlayerClaimPlotEvent: Called when a plot is claimed
*
* @param player Player that claimed the plot
* @param plot Plot that was claimed
*/
public PlayerClaimPlotEvent(final Player player, final Plot plot, final boolean auto) {
super(player);
this.plot = plot;
this.auto = auto;
}
public static HandlerList getHandlerList() {
return handlers;
}
/**
* Get the plot involved
*
* @return Plot
*/
public Plot getPlot() {
return this.plot;
}
/**
* @return true if it was an automated claim, else false
*/
public boolean wasAuto() {
return this.auto;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
@Override
public void setCancelled(final boolean b) {
this.cancelled = b;
}
}

View File

@ -0,0 +1,65 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// PlotSquared - A plot manager and world generator for the Bukkit API /
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters /
// /
// This program is free software; you can redistribute it and/or modify /
// it under the terms of the GNU General Public License as published by /
// the Free Software Foundation; either version 3 of the License, or /
// (at your option) any later version. /
// /
// This program is distributed in the hope that it will be useful, /
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the /
// GNU General Public License for more details. /
// /
// You should have received a copy of the GNU General Public License /
// along with this program; if not, write to the Free Software Foundation, /
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /
// /
// You can contact us via: support@intellectualsites.com /
////////////////////////////////////////////////////////////////////////////////////////////////////
package com.plotsquared.bukkit.events;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import com.intellectualcrafters.plot.object.Plot;
/**
* @author Citymonstret
* @author Empire92
*/
public class PlayerEnterPlotEvent extends PlayerEvent {
private static HandlerList handlers = new HandlerList();
private final Plot plot;
/**
* PlayerEnterPlotEvent: Called when a player leaves a plot
*
* @param player Player that entered the plot
* @param plot Plot that was entered
*/
public PlayerEnterPlotEvent(final Player player, final Plot plot) {
super(player);
this.plot = plot;
}
public static HandlerList getHandlerList() {
return handlers;
}
/**
* Get the plot involved
*
* @return Plot
*/
public Plot getPlot() {
return this.plot;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
}

View File

@ -0,0 +1,66 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// PlotSquared - A plot manager and world generator for the Bukkit API /
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters /
// /
// This program is free software; you can redistribute it and/or modify /
// it under the terms of the GNU General Public License as published by /
// the Free Software Foundation; either version 3 of the License, or /
// (at your option) any later version. /
// /
// This program is distributed in the hope that it will be useful, /
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the /
// GNU General Public License for more details. /
// /
// You should have received a copy of the GNU General Public License /
// along with this program; if not, write to the Free Software Foundation, /
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /
// /
// You can contact us via: support@intellectualsites.com /
////////////////////////////////////////////////////////////////////////////////////////////////////
package com.plotsquared.bukkit.events;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import com.intellectualcrafters.plot.object.Plot;
/**
* @author Citymonstret
* @author Empire92
*/
public class PlayerLeavePlotEvent extends PlayerEvent {
private static HandlerList handlers = new HandlerList();
private final Plot plot;
/**
* PlayerLeavePlotEvent: Called when a player leaves a plot
*
* @param player Player that left the plot
* @param plot Plot that was left
*/
public PlayerLeavePlotEvent(final Player player, final Plot plot) {
super(player);
this.plot = plot;
}
public static HandlerList getHandlerList() {
return handlers;
}
/**
* Get the plot involved
*
* @return Plot
*/
public Plot getPlot() {
return this.plot;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
}

View File

@ -0,0 +1,91 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// PlotSquared - A plot manager and world generator for the Bukkit API /
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters /
// /
// This program is free software; you can redistribute it and/or modify /
// it under the terms of the GNU General Public License as published by /
// the Free Software Foundation; either version 3 of the License, or /
// (at your option) any later version. /
// /
// This program is distributed in the hope that it will be useful, /
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the /
// GNU General Public License for more details. /
// /
// You should have received a copy of the GNU General Public License /
// along with this program; if not, write to the Free Software Foundation, /
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /
// /
// You can contact us via: support@intellectualsites.com /
////////////////////////////////////////////////////////////////////////////////////////////////////
package com.plotsquared.bukkit.events;
import java.util.UUID;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import com.intellectualcrafters.plot.object.Plot;
/**
* @author Citymonstret
* @author Empire92
*/
public class PlayerPlotDeniedEvent extends PlotEvent {
private static HandlerList handlers = new HandlerList();
private final Player initiator;
private final boolean added;
private final UUID player;
/**
* PlayerPlotDeniedEvent: Called when the denied UUID list is modified for a plot
*
* @param initiator Player that initiated the event
* @param plot Plot in which the event occurred
* @param player Player that was denied/un-denied
* @param added true of add to deny list, false if removed
*/
public PlayerPlotDeniedEvent(final Player initiator, final Plot plot, final UUID player, final boolean added) {
super(plot);
this.initiator = initiator;
this.added = added;
this.player = player;
}
public static HandlerList getHandlerList() {
return handlers;
}
/**
* If a user was added
*
* @return boolean
*/
public boolean wasAdded() {
return this.added;
}
/**
* The player added/removed
*
* @return UUID
*/
public UUID getPlayer() {
return this.player;
}
/**
* The player initiating the action
*
* @return Player
*/
public Player getInitiator() {
return this.initiator;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
}

View File

@ -0,0 +1,91 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// PlotSquared - A plot manager and world generator for the Bukkit API /
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters /
// /
// This program is free software; you can redistribute it and/or modify /
// it under the terms of the GNU General Public License as published by /
// the Free Software Foundation; either version 3 of the License, or /
// (at your option) any later version. /
// /
// This program is distributed in the hope that it will be useful, /
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the /
// GNU General Public License for more details. /
// /
// You should have received a copy of the GNU General Public License /
// along with this program; if not, write to the Free Software Foundation, /
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /
// /
// You can contact us via: support@intellectualsites.com /
////////////////////////////////////////////////////////////////////////////////////////////////////
package com.plotsquared.bukkit.events;
import java.util.UUID;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import com.intellectualcrafters.plot.object.Plot;
/**
* @author Empire92
* @author Citymonstret
*/
public class PlayerPlotHelperEvent extends PlotEvent {
private static HandlerList handlers = new HandlerList();
private final Player initiator;
private final boolean added;
private final UUID player;
/**
* PlayerPlotHelperEvent: Called when a plot helper is added/removed
*
* @param initiator Player that initiated the event
* @param plot Plot in which the event occurred
* @param player Player that was added/removed from the helper list
* @param added true of the player was added, false if the player was removed
*/
public PlayerPlotHelperEvent(final Player initiator, final Plot plot, final UUID player, final boolean added) {
super(plot);
this.initiator = initiator;
this.added = added;
this.player = player;
}
public static HandlerList getHandlerList() {
return handlers;
}
/**
* If a player was added
*
* @return boolean
*/
public boolean wasAdded() {
return this.added;
}
/**
* The UUID added/removed
*
* @return UUID
*/
public UUID getPlayer() {
return this.player;
}
/**
* The player initiating the action
*
* @return Player
*/
public Player getInitiator() {
return this.initiator;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
}

View File

@ -0,0 +1,91 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// PlotSquared - A plot manager and world generator for the Bukkit API /
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters /
// /
// This program is free software; you can redistribute it and/or modify /
// it under the terms of the GNU General Public License as published by /
// the Free Software Foundation; either version 3 of the License, or /
// (at your option) any later version. /
// /
// This program is distributed in the hope that it will be useful, /
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the /
// GNU General Public License for more details. /
// /
// You should have received a copy of the GNU General Public License /
// along with this program; if not, write to the Free Software Foundation, /
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /
// /
// You can contact us via: support@intellectualsites.com /
////////////////////////////////////////////////////////////////////////////////////////////////////
package com.plotsquared.bukkit.events;
import java.util.UUID;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import com.intellectualcrafters.plot.object.Plot;
/**
* @author Citymonstret
* @author Empire92
*/
public class PlayerPlotTrustedEvent extends PlotEvent {
private static HandlerList handlers = new HandlerList();
private final Player initiator;
private final boolean added;
private final UUID player;
/**
* PlayerPlotTrustedEvent: Called when a plot trusted user is added/removed
*
* @param initiator Player that initiated the event
* @param plot Plot in which the event occurred
* @param player Player that was added/removed from the trusted list
* @param added true of the player was added, false if the player was removed
*/
public PlayerPlotTrustedEvent(final Player initiator, final Plot plot, final UUID player, final boolean added) {
super(plot);
this.initiator = initiator;
this.added = added;
this.player = player;
}
public static HandlerList getHandlerList() {
return handlers;
}
/**
* If a player was added
*
* @return boolean
*/
public boolean wasAdded() {
return this.added;
}
/**
* The UUID added/removed
*
* @return UUID
*/
public UUID getPlayer() {
return this.player;
}
/**
* The player initiating the action
*
* @return Player
*/
public Player getInitiator() {
return this.initiator;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
}

View File

@ -0,0 +1,92 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// PlotSquared - A plot manager and world generator for the Bukkit API /
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters /
// /
// This program is free software; you can redistribute it and/or modify /
// it under the terms of the GNU General Public License as published by /
// the Free Software Foundation; either version 3 of the License, or /
// (at your option) any later version. /
// /
// This program is distributed in the hope that it will be useful, /
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the /
// GNU General Public License for more details. /
// /
// You should have received a copy of the GNU General Public License /
// along with this program; if not, write to the Free Software Foundation, /
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /
// /
// You can contact us via: support@intellectualsites.com /
////////////////////////////////////////////////////////////////////////////////////////////////////
package com.plotsquared.bukkit.events;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
/**
* Called when a player teleports to a plot
*
* @author Citymonstret
* @author Empire92
*/
public class PlayerTeleportToPlotEvent extends PlayerEvent implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private final Location from;
private final Plot plot;
private boolean cancelled;
/**
* PlayerTeleportToPlotEvent: Called when a player teleports to a plot
*
* @param player That was teleported
* @param from Start location
* @param plot Plot to which the player was teleported
*/
public PlayerTeleportToPlotEvent(final Player player, final Location from, final Plot plot) {
super(player);
this.from = from;
this.plot = plot;
}
public static HandlerList getHandlerList() {
return handlers;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
/**
* Get the from location
*
* @return Location
*/
public Location getFrom() {
return this.from;
}
/**
* Get the plot involved
*
* @return Plot
*/
public Plot getPlot() {
return this.plot;
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
@Override
public void setCancelled(final boolean cancelled) {
this.cancelled = cancelled;
}
}

View File

@ -0,0 +1,88 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// PlotSquared - A plot manager and world generator for the Bukkit API /
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters /
// /
// This program is free software; you can redistribute it and/or modify /
// it under the terms of the GNU General Public License as published by /
// the Free Software Foundation; either version 3 of the License, or /
// (at your option) any later version. /
// /
// This program is distributed in the hope that it will be useful, /
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the /
// GNU General Public License for more details. /
// /
// You should have received a copy of the GNU General Public License /
// along with this program; if not, write to the Free Software Foundation, /
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /
// /
// You can contact us via: support@intellectualsites.com /
////////////////////////////////////////////////////////////////////////////////////////////////////
package com.plotsquared.bukkit.events;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import com.intellectualcrafters.plot.object.PlotId;
/**
* Called when a plot is cleared
*
* @author Citymonstret
* @author Empire92
*/
public class PlotClearEvent extends Event implements Cancellable {
private static HandlerList handlers = new HandlerList();
private final PlotId id;
private final String world;
private boolean cancelled;
/**
* PlotDeleteEvent: Called when a plot is cleared
*
* @param world The world in which the plot was cleared
* @param id The plot that was cleared
*/
public PlotClearEvent(final String world, final PlotId id) {
this.id = id;
this.world = world;
}
public static HandlerList getHandlerList() {
return handlers;
}
/**
* Get the PlotId
*
* @return PlotId
*/
public PlotId getPlotId() {
return this.id;
}
/**
* Get the world name
*
* @return String
*/
public String getWorld() {
return this.world;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
@Override
public void setCancelled(final boolean b) {
this.cancelled = b;
}
}

View File

@ -0,0 +1,76 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// PlotSquared - A plot manager and world generator for the Bukkit API /
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters /
// /
// This program is free software; you can redistribute it and/or modify /
// it under the terms of the GNU General Public License as published by /
// the Free Software Foundation; either version 3 of the License, or /
// (at your option) any later version. /
// /
// This program is distributed in the hope that it will be useful, /
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the /
// GNU General Public License for more details. /
// /
// You should have received a copy of the GNU General Public License /
// along with this program; if not, write to the Free Software Foundation, /
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /
// /
// You can contact us via: support@intellectualsites.com /
////////////////////////////////////////////////////////////////////////////////////////////////////
package com.plotsquared.bukkit.events;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import com.intellectualcrafters.plot.object.PlotId;
/**
* Called when a plot is deleted
*
* @author Citymonstret
* @author Empire92
*/
public class PlotDeleteEvent extends Event {
private static HandlerList handlers = new HandlerList();
private final PlotId id;
private final String world;
/**
* PlotDeleteEvent: Called when a plot is deleted
*
* @param world The world in which the plot was deleted
* @param id The ID of the plot that was deleted
*/
public PlotDeleteEvent(final String world, final PlotId id) {
this.id = id;
this.world = world;
}
public static HandlerList getHandlerList() {
return handlers;
}
/**
* Get the PlotId
*
* @return PlotId
*/
public PlotId getPlotId() {
return this.id;
}
/**
* Get the world name
*
* @return String
*/
public String getWorld() {
return this.world;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
}

View File

@ -0,0 +1,19 @@
package com.plotsquared.bukkit.events;
import org.bukkit.event.Event;
import com.intellectualcrafters.plot.object.Plot;
public abstract class PlotEvent extends Event {
private final Plot plot;
public PlotEvent(final Plot plot) {
this.plot = plot;
}
public final Plot getPlot() {
return this.plot;
}
}

View File

@ -0,0 +1,79 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// PlotSquared - A plot manager and world generator for the Bukkit API /
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters /
// /
// This program is free software; you can redistribute it and/or modify /
// it under the terms of the GNU General Public License as published by /
// the Free Software Foundation; either version 3 of the License, or /
// (at your option) any later version. /
// /
// This program is distributed in the hope that it will be useful, /
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the /
// GNU General Public License for more details. /
// /
// You should have received a copy of the GNU General Public License /
// along with this program; if not, write to the Free Software Foundation, /
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /
// /
// You can contact us via: support@intellectualsites.com /
////////////////////////////////////////////////////////////////////////////////////////////////////
package com.plotsquared.bukkit.events;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import com.intellectualcrafters.plot.flag.Flag;
import com.intellectualcrafters.plot.object.Plot;
/**
* Called when a Flag is added to a plot
*
* @author Citymonstret
* @author Empire92
*/
public class PlotFlagAddEvent extends PlotEvent implements Cancellable {
private static HandlerList handlers = new HandlerList();
private final Flag flag;
private boolean cancelled;
/**
* PlotFlagAddEvent: Called when a Flag is added to a plot
*
* @param flag Flag that was added
* @param plot Plot to which the flag was added
*/
public PlotFlagAddEvent(final Flag flag, final Plot plot) {
super(plot);
this.flag = flag;
}
public static HandlerList getHandlerList() {
return handlers;
}
/**
* Get the flag involved
*
* @return Flag
*/
public Flag getFlag() {
return this.flag;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
@Override
public final boolean isCancelled() {
return this.cancelled;
}
@Override
public final void setCancelled(boolean cancelled) {
this.cancelled = cancelled;
}
}

View File

@ -0,0 +1,80 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// PlotSquared - A plot manager and world generator for the Bukkit API /
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters /
// /
// This program is free software; you can redistribute it and/or modify /
// it under the terms of the GNU General Public License as published by /
// the Free Software Foundation; either version 3 of the License, or /
// (at your option) any later version. /
// /
// This program is distributed in the hope that it will be useful, /
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the /
// GNU General Public License for more details. /
// /
// You should have received a copy of the GNU General Public License /
// along with this program; if not, write to the Free Software Foundation, /
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /
// /
// You can contact us via: support@intellectualsites.com /
////////////////////////////////////////////////////////////////////////////////////////////////////
package com.plotsquared.bukkit.events;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import com.intellectualcrafters.plot.flag.Flag;
import com.intellectualcrafters.plot.object.Plot;
/**
* Called when a flag is removed from a plot
*
* @author Citymonstret
* @author Empire92
*/
public class PlotFlagRemoveEvent extends PlotEvent implements Cancellable {
private static HandlerList handlers = new HandlerList();
private final Flag flag;
private boolean cancelled;
/**
* PlotFlagRemoveEvent: Called when a flag is removed from a plot
*
* @param flag Flag that was removed
* @param plot Plot from which the flag was removed
*/
public PlotFlagRemoveEvent(final Flag flag, final Plot plot) {
super(plot);
this.flag = flag;
}
public static HandlerList getHandlerList() {
return handlers;
}
/**
* Get the flag involved
*
* @return Flag
*/
public Flag getFlag() {
return this.flag;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
@Override
public final boolean isCancelled() {
return this.cancelled;
}
@Override
public final void setCancelled(boolean cancelled) {
this.cancelled = cancelled;
}
}

View File

@ -0,0 +1,94 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// PlotSquared - A plot manager and world generator for the Bukkit API /
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters /
// /
// This program is free software; you can redistribute it and/or modify /
// it under the terms of the GNU General Public License as published by /
// the Free Software Foundation; either version 3 of the License, or /
// (at your option) any later version. /
// /
// This program is distributed in the hope that it will be useful, /
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the /
// GNU General Public License for more details. /
// /
// You should have received a copy of the GNU General Public License /
// along with this program; if not, write to the Free Software Foundation, /
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /
// /
// You can contact us via: support@intellectualsites.com /
////////////////////////////////////////////////////////////////////////////////////////////////////
package com.plotsquared.bukkit.events;
import java.util.ArrayList;
import org.bukkit.World;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotId;
/**
* @author Empire92
*/
public class PlotMergeEvent extends Event implements Cancellable {
private static HandlerList handlers = new HandlerList();
private final ArrayList<PlotId> plots;
private boolean cancelled;
private Plot plot;
private World world;
/**
* PlotMergeEvent: Called when plots are merged
*
* @param world World in which the event occurred
* @param plot Plot that was merged
* @param plots A list of plots involved in the event
*/
public PlotMergeEvent(final World world, final Plot plot, final ArrayList<PlotId> plots) {
this.plots = plots;
}
public static HandlerList getHandlerList() {
return handlers;
}
/**
* Get the plots being added;
*
* @return Plot
*/
public ArrayList<PlotId> getPlots() {
return this.plots;
}
/**
* Get the main plot
*
* @return Plot
*/
public Plot getPlot() {
return this.plot;
}
public World getWorld() {
return this.world;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
@Override
public void setCancelled(final boolean b) {
this.cancelled = b;
}
}

View File

@ -0,0 +1,46 @@
package com.plotsquared.bukkit.events;
import org.bukkit.event.HandlerList;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotPlayer;
/**
* Created 2015-07-13 for PlotSquaredGit
*
* @author Citymonstret
*/
public class PlotRateEvent extends PlotEvent {
private static HandlerList handlers = new HandlerList();
private final PlotPlayer rater;
private int rating;
public PlotRateEvent(final PlotPlayer rater, final int rating, final Plot plot) {
super(plot);
this.rater = rater;
this.rating = rating;
}
public static HandlerList getHandlerList() {
return handlers;
}
public PlotPlayer getRater() {
return this.rater;
}
public void setRating(int rating) {
this.rating = rating;
}
public int getRating() {
return this.rating;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
}

View File

@ -0,0 +1,83 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// PlotSquared - A plot manager and world generator for the Bukkit API /
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters /
// /
// This program is free software; you can redistribute it and/or modify /
// it under the terms of the GNU General Public License as published by /
// the Free Software Foundation; either version 3 of the License, or /
// (at your option) any later version. /
// /
// This program is distributed in the hope that it will be useful, /
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the /
// GNU General Public License for more details. /
// /
// You should have received a copy of the GNU General Public License /
// along with this program; if not, write to the Free Software Foundation, /
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /
// /
// You can contact us via: support@intellectualsites.com /
////////////////////////////////////////////////////////////////////////////////////////////////////
package com.plotsquared.bukkit.events;
import java.util.ArrayList;
import org.bukkit.World;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import com.intellectualcrafters.plot.object.PlotId;
/**
* @author Empire92
*/
public class PlotUnlinkEvent extends Event implements Cancellable {
private static HandlerList handlers = new HandlerList();
private final ArrayList<PlotId> plots;
private final World world;
private boolean cancelled;
/**
* Called when a mega-plot is unlinked.
*
* @param world World in which the event occurred
* @param plots Plots that are involved in the event
*/
public PlotUnlinkEvent(final World world, final ArrayList<PlotId> plots) {
this.plots = plots;
this.world = world;
}
public static HandlerList getHandlerList() {
return handlers;
}
/**
* Get the plots involved
*
* @return PlotId
*/
public ArrayList<PlotId> getPlots() {
return this.plots;
}
public World getWorld() {
return this.world;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
@Override
public void setCancelled(final boolean b) {
this.cancelled = b;
}
}

View File

@ -0,0 +1,287 @@
package com.plotsquared.bukkit.generator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Random;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.World;
import org.bukkit.block.Biome;
import org.bukkit.generator.BlockPopulator;
import com.intellectualcrafters.plot.PS;
import com.plotsquared.bukkit.object.BlockWrapper;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.PlotCluster;
import com.plotsquared.bukkit.object.PlotGenerator;
import com.intellectualcrafters.plot.object.PlotId;
import com.intellectualcrafters.plot.object.PlotLoc;
import com.intellectualcrafters.plot.object.PlotManager;
import com.intellectualcrafters.plot.object.PlotWorld;
import com.intellectualcrafters.plot.object.RegionWrapper;
import com.intellectualcrafters.plot.util.ChunkManager;
import com.intellectualcrafters.plot.util.TaskManager;
import com.plotsquared.bukkit.util.bukkit.BukkitChunkManager;
import com.plotsquared.bukkit.util.bukkit.BukkitSetBlockManager;
public class AugmentedPopulator extends BlockPopulator {
public static short[][] x_loc;
public static short[][] y_loc;
public static short[][] z_loc;
public final PlotWorld plotworld;
public final PlotManager manager;
public final PlotGenerator generator;
public final PlotCluster cluster;
public final Random r = new Random();
public final boolean p;
public final boolean b;
public final boolean o;
private final int bx;
private final int bz;
private final int tx;
private final int tz;
public AugmentedPopulator(final String world, final PlotGenerator generator, final PlotCluster cluster, final boolean p, final boolean b) {
initCache();
this.cluster = cluster;
this.generator = generator;
this.plotworld = PS.get().getPlotWorld(world);
this.manager = generator.getPlotManager();
this.p = p;
this.b = b;
this.o = (this.plotworld.TERRAIN == 1) || (this.plotworld.TERRAIN == 2);
final World bukkitWorld = Bukkit.getWorld(world);
if (cluster != null) {
final Location bl = this.manager.getPlotBottomLocAbs(this.plotworld, cluster.getP1());
final Location tl = this.manager.getPlotTopLocAbs(this.plotworld, cluster.getP2()).add(1, 0, 1);
this.bx = bl.getX();
this.bz = bl.getZ();
this.tx = tl.getX();
this.tz = tl.getZ();
} else {
this.bx = Integer.MIN_VALUE;
this.bz = Integer.MIN_VALUE;
this.tx = Integer.MAX_VALUE;
this.tz = Integer.MAX_VALUE;
}
// Add the populator
if (this.o) {
bukkitWorld.getPopulators().add(0, this);
} else {
bukkitWorld.getPopulators().add(this);
}
}
public static void removePopulator(final String worldname, final PlotCluster cluster) {
final World world = Bukkit.getWorld(worldname);
for (final Iterator<BlockPopulator> iterator = world.getPopulators().iterator(); iterator.hasNext();) {
final BlockPopulator populator = iterator.next();
if (populator instanceof AugmentedPopulator) {
if (((AugmentedPopulator) populator).cluster.equals(cluster)) {
iterator.remove();
}
}
}
}
public static void initCache() {
if (x_loc == null) {
x_loc = new short[16][4096];
y_loc = new short[16][4096];
z_loc = new short[16][4096];
for (int i = 0; i < 16; i++) {
int i4 = i << 4;
for (int j = 0; j < 4096; j++) {
final int y = (i4) + (j >> 8);
final int a = (j - ((y & 0xF) << 8));
final int z1 = (a >> 4);
final int x1 = a - (z1 << 4);
x_loc[i][j] = (short) x1;
y_loc[i][j] = (short) y;
z_loc[i][j] = (short) z1;
}
}
}
}
public BlockWrapper get(final int x, final int z, final int i, final int j, final short[][] r, final boolean c) {
final int y = (i << 4) + (j >> 8);
final int a = (j - ((y & 0xF) << 8));
final int z1 = (a >> 4);
final int x1 = a - (z1 << 4);
if (r[i] == null) {
return (c && (((z + z1) < this.bz) || ((z + z1) > this.tz) || ((x + x1) < this.bx) || ((x + x1) > this.tx))) ? null : new BlockWrapper(x1, y, z1, (short) 0, (byte) 0);
} else {
return (c && (((z + z1) < this.bz) || ((z + z1) > this.tz) || ((x + x1) < this.bx) || ((x + x1) > this.tx))) ? null : new BlockWrapper(x1, y, z1, r[i][j], (byte) 0);
}
}
@Override
public void populate(final World world, final Random rand, final Chunk chunk) {
final int cx = chunk.getX();
final int cz = chunk.getZ();
final int bx = cx << 4;
final int bz = cz << 4;
final int tx = bx + 15;
final int tz = bz + 15;
final boolean inX1 = ((bx >= this.bx) && (bx <= this.tx));
final boolean inX2 = ((tx >= this.bx) && (tx <= this.tx));
final boolean inZ1 = ((bz >= this.bz) && (bz <= this.tz));
final boolean inZ2 = ((tz >= this.bz) && (tz <= this.tz));
final boolean inX = inX1 || inX2;
final boolean inZ = inZ1 || inZ2;
if (!inX || !inZ) {
return;
}
if (this.plotworld.TERRAIN == 3) {
int X = chunk.getX() << 4;
int Z = chunk.getZ() << 4;
if (ChunkManager.FORCE_PASTE) {
for (short x = 0; x < 16; x++) {
for (short z = 0; z < 16; z++) {
final PlotLoc loc = new PlotLoc((short) (X + x), (short) (Z + z));
final HashMap<Short, Short> blocks = ChunkManager.GENERATE_BLOCKS.get(loc);
HashMap<Short, Byte> datas = ChunkManager.GENERATE_DATA.get(loc);
for (final Entry<Short, Short> entry : blocks.entrySet()) {
int y = entry.getKey();
byte data;
if (datas != null) {
data = datas.get(y);
}
else {
data = 0;
}
BukkitSetBlockManager.setBlockManager.set(world, x, y, z, blocks.get(y), data);
}
}
}
return;
}
if (ChunkManager.CURRENT_PLOT_CLEAR != null) {
PlotLoc loc;
for (Entry<PlotLoc, HashMap<Short, Byte>> entry : ChunkManager.GENERATE_DATA.entrySet()) {
HashMap<Short, Byte> datas = ChunkManager.GENERATE_DATA.get(entry.getKey());
for (Entry<Short, Byte> entry2 : entry.getValue().entrySet()) {
Short y = entry2.getKey();
byte data;
if (datas != null) {
data = datas.get(y);
}
else {
data = 0;
}
loc = entry.getKey();
int xx = loc.x - X;
int zz = loc.z - Z;
if (xx >= 0 && xx < 16) {
if (zz >= 0 && zz < 16) {
BukkitSetBlockManager.setBlockManager.set(world, xx, y, zz, entry2.getValue(), data);
}
}
}
}
}
return;
}
final boolean check;
check = !inX1 || !inX2 || !inZ1 || !inZ2;
if (this.plotworld.TERRAIN > 1) {
final PlotId plot1 = this.manager.getPlotIdAbs(this.plotworld, bx, 0, bz);
final PlotId plot2 = this.manager.getPlotIdAbs(this.plotworld, tx, 0, tz);
if ((plot1 != null) && (plot2 != null) && plot1.equals(plot2)) {
return;
}
}
if (this.o) {
populateBlocks(world, rand, cx, cz, bx, bz, check);
} else {
TaskManager.runTaskLater(new Runnable() {
@Override
public void run() {
populateBiome(world, bx, bz);
}
}, 20 + rand.nextInt(10));
TaskManager.runTaskLater(new Runnable() {
@Override
public void run() {
chunk.load(true);
populateBlocks(world, rand, cx, cz, bx, bz, check);
}
}, 40 + rand.nextInt(40));
}
}
private void populateBiome(final World world, final int x, final int z) {
final Biome biome = Biome.valueOf(this.plotworld.PLOT_BIOME);
if (this.b) {
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
world.setBiome(x + i, z + j, biome);
}
}
}
}
private void populateBlocks(final World world, final Random rand, final int X, final int Z, final int x, final int z, final boolean check) {
final short[][] result = this.generator.generateExtBlockSections(world, rand, X, Z, null);
for (int i = 0; i < result.length; i++) {
if (result[i] != null) {
for (int j = 0; j < 4096; j++) {
int x1 = x_loc[i][j];
int y = y_loc[i][j];
int z1 = z_loc[i][j];
short id = result[i][j];
final int xx = x + x1;
final int zz = z + z1;
if (check && (((zz) < this.bz) || ((zz) > this.tz) || ((xx) < this.bx) || ((xx) > this.tx))) {
continue;
}
if (this.p) {
if (ChunkManager.CURRENT_PLOT_CLEAR != null) {
if (BukkitChunkManager.isIn(ChunkManager.CURRENT_PLOT_CLEAR, xx, zz)) {
continue;
}
} else if (this.manager.getPlotIdAbs(this.plotworld, xx, 0, zz) != null) {
continue;
}
}
BukkitSetBlockManager.setBlockManager.set(world, xx, y, zz, id, (byte) 0);
}
}
else {
short y_min = y_loc[i][0];
if (y_min < 128) {
for (int x1 = x; x1 < x + 16; x1++) {
for (int z1 = z; z1 < z + 16; z1++) {
if (check && (((z1) < this.bz) || ((z1) > this.tz) || ((x1) < this.bx) || ((x1) > this.tx))) {
continue;
}
if (this.p) {
if (ChunkManager.CURRENT_PLOT_CLEAR != null) {
if (BukkitChunkManager.isIn(ChunkManager.CURRENT_PLOT_CLEAR, x1, z1)) {
continue;
}
} else if (this.manager.getPlotIdAbs(this.plotworld, x1, 0, z1) != null) {
continue;
}
}
for (int y = y_min; y < y_min + 16; y++) {
BukkitSetBlockManager.setBlockManager.set(world, x1, y, z1, 0, (byte) 0);
}
}
}
}
}
}
for (final BlockPopulator populator : this.generator.getPopulators(world.getName())) {
Chunk chunk = world.getChunkAt(X, Z);
populator.populate(world, this.r, chunk);
}
}
public boolean isIn(final RegionWrapper plot, final int x, final int z) {
return ((x >= plot.minX) && (x <= plot.maxX) && (z >= plot.minZ) && (z <= plot.maxZ));
}
}

View File

@ -0,0 +1,297 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// PlotSquared - A plot manager and world generator for the Bukkit API /
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters /
// /
// This program is free software; you can redistribute it and/or modify /
// it under the terms of the GNU General Public License as published by /
// the Free Software Foundation; either version 3 of the License, or /
// (at your option) any later version. /
// /
// This program is distributed in the hope that it will be useful, /
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the /
// GNU General Public License for more details. /
// /
// You should have received a copy of the GNU General Public License /
// along with this program; if not, write to the Free Software Foundation, /
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /
// /
// You can contact us via: support@intellectualsites.com /
////////////////////////////////////////////////////////////////////////////////////////////////////
package com.plotsquared.bukkit.generator;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import com.intellectualcrafters.plot.generator.HybridPlotManager;
import com.intellectualcrafters.plot.generator.HybridPlotWorld;
import com.intellectualcrafters.plot.generator.HybridPop;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.block.Biome;
import com.plotsquared.bukkit.object.PlotGenerator;
import com.intellectualcrafters.plot.object.PlotLoc;
import com.intellectualcrafters.plot.object.PlotManager;
import com.plotsquared.bukkit.object.PlotPopulator;
import com.intellectualcrafters.plot.object.PlotWorld;
import com.intellectualcrafters.plot.object.PseudoRandom;
import com.intellectualcrafters.plot.object.RegionWrapper;
/**
* The default generator is very messy, as we have decided to try externalize all calculations from within the loop. -
* You will see a lot of slower implementations have a single for loop. - This is perfectly fine to do, it will just
* mean world generation may take somewhat longer
*
* @author Citymonstret
* @author Empire92
*/
public class HybridGen extends PlotGenerator {
public HybridGen(String world) {
super(world);
}
/**
* Set to static to re-use the same managet for all Default World Generators
*/
private static PlotManager manager = null;
/**
* plotworld object
*/
public HybridPlotWorld plotworld = null;
/**
* Some generator specific variables (implementation dependent)
*/
int plotsize;
int pathsize;
short wall;
short wallfilling;
short roadblock;
int size;
Biome biome;
int roadheight;
int wallheight;
int plotheight;
short[] plotfloors;
short[] filling;
short pathWidthLower;
short pathWidthUpper;
boolean doState = false;
int maxY = 0;
short[][] cached;
/**
* Initialize variables, and create plotworld object used in calculations
*/
public void init(PlotWorld plotworld) {
if (plotworld != null) {
this.plotworld = (HybridPlotWorld) plotworld;
}
this.plotsize = this.plotworld.PLOT_WIDTH;
this.pathsize = this.plotworld.ROAD_WIDTH;
this.roadblock = this.plotworld.ROAD_BLOCK.id;
this.wallfilling = this.plotworld.WALL_FILLING.id;
this.size = this.pathsize + this.plotsize;
this.wall = this.plotworld.WALL_BLOCK.id;
this.plotfloors = new short[this.plotworld.TOP_BLOCK.length];
for (int i = 0; i < this.plotworld.TOP_BLOCK.length; i++) {
this.plotfloors[i] = this.plotworld.TOP_BLOCK[i].id;
}
this.filling = new short[this.plotworld.MAIN_BLOCK.length];
for (int i = 0; i < this.plotworld.MAIN_BLOCK.length; i++) {
this.filling[i] = this.plotworld.MAIN_BLOCK[i].id;
}
if ((this.filling.length > 1) || (this.plotfloors.length > 1)) {
this.doState = true;
}
this.wallheight = this.plotworld.WALL_HEIGHT;
this.roadheight = this.plotworld.ROAD_HEIGHT;
this.plotheight = this.plotworld.PLOT_HEIGHT;
if (this.pathsize == 0) {
this.pathWidthLower = (short) -1;
this.pathWidthUpper = (short) (this.plotsize + 1);
}
else {
if ((this.pathsize % 2) == 0) {
this.pathWidthLower = (short) (Math.floor(this.pathsize / 2) - 1);
} else {
this.pathWidthLower = (short) (Math.floor(this.pathsize / 2));
}
this.pathWidthUpper = (short) (this.pathWidthLower + this.plotsize + 1);
}
this.biome = Biome.valueOf(this.plotworld.PLOT_BIOME);
try {
this.maxY = Bukkit.getWorld(plotworld.worldname).getMaxHeight();
} catch (final NullPointerException e) {}
if (this.maxY == 0) {
this.maxY = 256;
}
// create cached chunk (for optimized chunk generation)
if (!this.plotworld.PLOT_SCHEMATIC) {
this.cached = new short[(plotheight + 16) / 16][];
for (int i = 0; i < cached.length; i++) {
cached[i] = new short[4096];
}
PseudoRandom random = new PseudoRandom();
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
cached[CACHE_I[plotheight][x][z]][CACHE_J[plotheight][x][z]] = plotfloors[random.random(plotfloors.length)];
if (this.plotworld.PLOT_BEDROCK) {
cached[CACHE_I[0][x][z]][CACHE_J[0][x][z]] = 7;
}
for (int y = 1; y < plotheight; y++) {
cached[CACHE_I[y][x][z]][CACHE_J[y][x][z]] = filling[random.random(filling.length)];
}
}
}
}
}
/**
* Return the plot manager for this type of generator, or create one For square plots you may as well use the
* default plot manager which comes with PlotSquared
*/
public PlotManager getPlotManager() {
if (HybridGen.manager == null) {
HybridGen.manager = new HybridPlotManager();
}
return HybridGen.manager;
}
/**
* Get a new plotworld class For square plots you can use the DefaultPlotWorld class which comes with PlotSquared
*/
public PlotWorld getNewPlotWorld(final String world) {
if (this.plotworld == null) {
this.plotworld = new HybridPlotWorld(world);
}
return this.plotworld;
}
/**
* Return the block populator
*/
public List<PlotPopulator> getPopulators(final String world) {
// You can have as many populators as you would like, e.g. tree
// populator, ore populator
return Arrays.asList((PlotPopulator) new HybridPop(this.plotworld));
}
/**
* This part is a fucking mess. - Refer to a proper tutorial if you would like to learn how to make a world
* generator
*/
public void generateChunk(final World world, RegionWrapper region, final PseudoRandom random, final int cx, final int cz, final BiomeGrid biomes) {
int sx = (short) ((this.X - this.plotworld.ROAD_OFFSET_X) % this.size);
int sz = (short) ((this.Z - this.plotworld.ROAD_OFFSET_Z) % this.size);
if (sx < 0) {
sx += this.size;
}
if (sz < 0) {
sz += this.size;
}
if (biomes != null) {
for (short x = 0; x < 16; x++) {
for (short z = 0; z < 16; z++) {
biomes.setBiome(x, z, this.biome);
}
}
}
if (cached != null) {
if (sx > pathWidthLower && sz > pathWidthLower && sx + 15 < pathWidthUpper&& sz + 15 < pathWidthUpper) {
setResult(cached);
return;
}
}
if (this.plotworld.PLOT_BEDROCK) {
for (short x = 0; x < 16; x++) {
for (short z = 0; z < 16; z++) {
setBlock(x, 0, z, (short) 7);
}
}
}
if (region != null) {
for (short x = 0; x < 16; x++) {
final int absX = ((sx + x) % this.size);
for (short z = 0; z < 16; z++) {
if (contains(region, x, z)) {
for (short y = 1; y < this.plotheight; y++) {
setBlock(x, y, z, this.filling);
}
setBlock(x, this.plotheight, z, this.plotfloors);
final int absZ = ((sz + z) % this.size);
final PlotLoc loc = new PlotLoc(absX, absZ);
final HashMap<Short, Short> blocks = plotworld.G_SCH.get(loc);
if (blocks != null) {
for (final Entry<Short, Short> entry : blocks.entrySet()) {
setBlock(x, this.plotheight + entry.getKey(), z, entry.getValue());
}
}
}
}
}
return;
}
for (short x = 0; x < 16; x++) {
final int absX = ((sx + x) % this.size);
final boolean gx = absX > this.pathWidthLower;
final boolean lx = absX < this.pathWidthUpper;
for (short z = 0; z < 16; z++) {
final int absZ = ((sz + z) % this.size);
final boolean gz = absZ > this.pathWidthLower;
final boolean lz = absZ < this.pathWidthUpper;
// inside plot
if (gx && gz && lx && lz) {
for (short y = 1; y < this.plotheight; y++) {
setBlock(x, y, z, this.filling);
}
setBlock(x, this.plotheight, z, this.plotfloors);
if (this.plotworld.PLOT_SCHEMATIC) {
final PlotLoc loc = new PlotLoc(absX, absZ);
final HashMap<Short, Short> blocks = this.plotworld.G_SCH.get(loc);
if (blocks != null) {
for (final Entry<Short, Short> entry : blocks.entrySet()) {
setBlock(x, this.plotheight + entry.getKey(), z, entry.getValue());
}
}
}
} else if (pathsize != 0) {
// wall
if (((absX >= this.pathWidthLower) && (absX <= this.pathWidthUpper) && (absZ >= this.pathWidthLower) && (absZ <= this.pathWidthUpper))) {
for (short y = 1; y <= this.wallheight; y++) {
setBlock(x, y, z, this.wallfilling);
}
if (!this.plotworld.ROAD_SCHEMATIC_ENABLED) {
setBlock(x, this.wallheight + 1, z, this.wall);
}
}
// road
else {
for (short y = 1; y <= this.roadheight; y++) {
setBlock(x, y, z, this.roadblock);
}
}
if (this.plotworld.ROAD_SCHEMATIC_ENABLED) {
final PlotLoc loc = new PlotLoc(absX, absZ);
final HashMap<Short, Short> blocks = this.plotworld.G_SCH.get(loc);
if (blocks != null) {
for (final Entry<Short, Short> entry : blocks.entrySet()) {
setBlock(x, this.roadheight + entry.getKey(), z, entry.getValue());
}
}
}
}
}
}
return;
}
}

View File

@ -0,0 +1,13 @@
package com.plotsquared.bukkit.listeners;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotPlayer;
public abstract class APlotListener {
public static APlotListener manager;
public abstract boolean plotEntry(final PlotPlayer player, final Plot plot);
public abstract boolean plotExit(final PlotPlayer player, final Plot plot);
}

View File

@ -0,0 +1,63 @@
package com.plotsquared.bukkit.listeners;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
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.AsyncPlayerChatEvent;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.config.C;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotId;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.object.PlotWorld;
import com.intellectualcrafters.plot.util.MainUtil;
import com.plotsquared.bukkit.util.bukkit.BukkitUtil;
/**
* Created 2015-07-13 for PlotSquaredGit
*
* @author Citymonstret
*/
public class ChatListener implements Listener {
@EventHandler(priority = EventPriority.HIGHEST)
public void onChat(final AsyncPlayerChatEvent event) {
final Player player = event.getPlayer();
final String world = player.getWorld().getName();
if (!PS.get().isPlotWorld(world)) {
return;
}
final PlotWorld plotworld = PS.get().getPlotWorld(world);
final PlotPlayer plr = BukkitUtil.getPlayer(player);
if (!plotworld.PLOT_CHAT && (plr.getMeta("chat") == null || !(Boolean) plr.getMeta("chat"))) {
return;
}
final Location loc = BukkitUtil.getLocation(player);
final Plot plot = MainUtil.getPlot(loc);
if (plot == null) {
return;
}
final String message = event.getMessage();
String format = C.PLOT_CHAT_FORMAT.s();
final String sender = event.getPlayer().getDisplayName();
final PlotId id = plot.id;
final Set<Player> recipients = event.getRecipients();
recipients.clear();
for (final Player p : Bukkit.getOnlinePlayers()) {
if (p.hasPermission("plots.admin.command.chat") || plot.equals(MainUtil.getPlot(BukkitUtil.getLocation(p)))) {
recipients.add(p);
}
}
format = format.replaceAll("%plot_id%", id.x + ";" + id.y).replaceAll("%sender%", sender).replaceAll("%msg%", message.replaceAll("([%]{1})", "%%"));
format = ChatColor.translateAlternateColorCodes('&', format);
event.setFormat(format);
}
}

View File

@ -0,0 +1,160 @@
package com.plotsquared.bukkit.listeners;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Material;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Item;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockPhysicsEvent;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.entity.ItemSpawnEvent;
import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.event.world.ChunkUnloadEvent;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.config.Settings;
import com.intellectualcrafters.plot.util.TaskManager;
public class ChunkListener implements Listener {
private Chunk lastChunk = null;
private long last = 0;
private int count = 0;
@EventHandler
public void onChunkUnload(ChunkUnloadEvent event) {
if (processChunk(event.getChunk(), true)) {
event.setCancelled(true);
}
}
@EventHandler
public void onChunkLoad(ChunkLoadEvent event) {
processChunk(event.getChunk(), false);
}
@EventHandler(priority=EventPriority.LOWEST)
public void onItemSpawn(ItemSpawnEvent event) {
Item entity = event.getEntity();
Chunk chunk = entity.getLocation().getChunk();
if (chunk == lastChunk) {
event.getEntity().remove();
event.setCancelled(true);
return;
}
if (!PS.get().isPlotWorld(chunk.getWorld().getName())) {
return;
}
Entity[] entities = chunk.getEntities();
if (entities.length > Settings.CHUNK_PROCESSOR_MAX_ENTITIES) {
event.getEntity().remove();
event.setCancelled(true);
lastChunk = chunk;
}
else {
lastChunk = null;
}
}
@EventHandler(priority=EventPriority.HIGHEST, ignoreCancelled=true)
public void onBlockPhysics(BlockPhysicsEvent event) {
if (Settings.CHUNK_PROCESSOR_DISABLE_PHYSICS) {
event.setCancelled(true);
}
}
@EventHandler(priority=EventPriority.LOWEST)
public void onEntitySpawn(CreatureSpawnEvent event) {
LivingEntity entity = event.getEntity();
Chunk chunk = entity.getLocation().getChunk();
if (chunk == lastChunk) {
event.getEntity().remove();
event.setCancelled(true);
return;
}
if (!PS.get().isPlotWorld(chunk.getWorld().getName())) {
return;
}
Entity[] entities = chunk.getEntities();
if (entities.length > Settings.CHUNK_PROCESSOR_MAX_ENTITIES) {
event.getEntity().remove();
event.setCancelled(true);
lastChunk = chunk;
}
else {
lastChunk = null;
}
}
public void cleanChunk(final Chunk chunk) {
TaskManager.index.increment();
final Integer currentIndex = TaskManager.index.toInteger();
final Integer task = TaskManager.runTaskRepeat(new Runnable() {
@Override
public void run() {
if (!chunk.isLoaded()) {
Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
TaskManager.tasks.remove(currentIndex);
PS.log("[PlotSquared] &aSuccessfully processed and unloaded chunk!");
chunk.unload(true, true);
return;
}
BlockState[] tiles = chunk.getTileEntities();
if (tiles.length == 0) {
Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
TaskManager.tasks.remove(currentIndex);
PS.log("[PlotSquared] &aSuccessfully processed and unloaded chunk!");
chunk.unload(true, true);
return;
}
long start = System.currentTimeMillis();
int i = 0;
while (System.currentTimeMillis() - start < 250) {
if (i >= tiles.length) {
Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
TaskManager.tasks.remove(currentIndex);
PS.log("[PlotSquared] &aSuccessfully processed and unloaded chunk!");
chunk.unload(true, true);
return;
}
tiles[i].getBlock().setType(Material.AIR, false);
i++;
}
}
}, 5);
TaskManager.tasks.put(currentIndex, task);
}
public boolean processChunk(Chunk chunk, boolean unload) {
if (!PS.get().isPlotWorld(chunk.getWorld().getName())) {
return false;
}
Entity[] entities = chunk.getEntities();
BlockState[] tiles = chunk.getTileEntities();
if (entities.length > Settings.CHUNK_PROCESSOR_MAX_ENTITIES) {
for (Entity ent : entities) {
if (!(ent instanceof Player)) {
ent.remove();
}
}
PS.log("[PlotSquared] &a detected unsafe chunk and processed: " + (chunk.getX() << 4) + "," + (chunk.getX() << 4));
}
if (tiles.length > Settings.CHUNK_PROCESSOR_MAX_BLOCKSTATES) {
if (unload) {
PS.log("[PlotSquared] &c detected unsafe chunk: " + (chunk.getX() << 4) + "," + (chunk.getX() << 4));
cleanChunk(chunk);
return true;
}
for (BlockState tile : tiles) {
tile.getBlock().setType(Material.AIR, false);
}
}
return false;
}
}

View File

@ -0,0 +1,125 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// PlotSquared - A plot manager and world generator for the Bukkit API /
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters /
// /
// This program is free software; you can redistribute it and/or modify /
// it under the terms of the GNU General Public License as published by /
// the Free Software Foundation; either version 3 of the License, or /
// (at your option) any later version. /
// /
// This program is distributed in the hope that it will be useful, /
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the /
// GNU General Public License for more details. /
// /
// You should have received a copy of the GNU General Public License /
// along with this program; if not, write to the Free Software Foundation, /
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /
// /
// You can contact us via: support@intellectualsites.com /
////////////////////////////////////////////////////////////////////////////////////////////////////
package com.plotsquared.bukkit.listeners;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.util.Vector;
import com.plotsquared.bukkit.events.PlayerEnterPlotEvent;
import com.intellectualcrafters.plot.flag.FlagManager;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.plotsquared.bukkit.util.bukkit.BukkitPlayerFunctions;
import com.plotsquared.bukkit.util.bukkit.BukkitUtil;
import com.plotsquared.bukkit.util.bukkit.UUIDHandler;
/**
* @author Citymonstret
*/
public class ForceFieldListener implements Listener {
private Set<Player> getNearbyPlayers(final Player player, final Plot plot) {
final Set<Player> players = new HashSet<>();
Player oPlayer;
for (final Entity entity : player.getNearbyEntities(5d, 5d, 5d)) {
if (!(entity instanceof Player) || ((oPlayer = (Player) entity) == null) || !BukkitPlayerFunctions.isInPlot(oPlayer) || !BukkitPlayerFunctions.getCurrentPlot(oPlayer).equals(plot)) {
continue;
}
final UUID uuid = UUIDHandler.getUUID(BukkitUtil.getPlayer(oPlayer));
if (!plot.isAdded(uuid)) {
players.add(oPlayer);
}
}
return players;
}
private Player hasNearbyPermitted(final Player player, final Plot plot) {
Player oPlayer;
for (final Entity entity : player.getNearbyEntities(5d, 5d, 5d)) {
if (!(entity instanceof Player) || ((oPlayer = (Player) entity) == null) || !BukkitPlayerFunctions.isInPlot(oPlayer) || !BukkitPlayerFunctions.getCurrentPlot(oPlayer).equals(plot)) {
continue;
}
final UUID uuid = UUIDHandler.getUUID(BukkitUtil.getPlayer(oPlayer));
if (plot.isAdded(uuid)) {
return oPlayer;
}
}
return null;
}
public Vector calculateVelocity(final Player p, final Player e) {
final org.bukkit.Location playerLocation = p.getLocation();
final org.bukkit.Location oPlayerLocation = e.getLocation();
final double playerX = playerLocation.getX(), playerY = playerLocation.getY(), playerZ = playerLocation.getZ(), oPlayerX = oPlayerLocation.getX(), oPlayerY = oPlayerLocation.getY(), oPlayerZ = oPlayerLocation.getZ();
double x = 0d, y = 0d, z = 0d;
if (playerX < oPlayerX) {
x = 1.0d;
} else if (playerX > oPlayerX) {
x = -1.0d;
}
if (playerY < oPlayerY) {
y = 0.5d;
} else if (playerY > oPlayerY) {
y = -0.5d;
}
if (playerZ < oPlayerZ) {
z = 1.0d;
} else if (playerZ > oPlayerZ) {
z = -1.0d;
}
return new Vector(x, y, z);
}
@EventHandler
public void onPlotEntry(final PlayerEnterPlotEvent event) {
final Player player = event.getPlayer();
final PlotPlayer pp = BukkitUtil.getPlayer(player);
final Location loc = pp.getLocation();
final Plot plot = event.getPlot();
if (plot == null) {
return;
}
if ((FlagManager.getPlotFlag(plot, "forcefield") != null) && FlagManager.getPlotFlag(plot, "forcefield").getValue().equals("true")) {
if (!FlagManager.isBooleanFlag(plot, "forcefield", false)) {
final UUID uuid = pp.getUUID();
if (plot.isAdded(uuid)) {
final Set<Player> players = getNearbyPlayers(player, plot);
for (final Player oPlayer : players) {
oPlayer.setVelocity(calculateVelocity(player, oPlayer));
}
} else {
final Player oPlayer = hasNearbyPermitted(player, plot);
if (oPlayer == null) {
return;
}
player.setVelocity(calculateVelocity(oPlayer, player));
}
}
}
}
}

View File

@ -0,0 +1,44 @@
package com.plotsquared.bukkit.listeners;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryInteractEvent;
import org.bukkit.inventory.Inventory;
import com.plotsquared.bukkit.object.InfoInventory;
import com.intellectualcrafters.plot.util.MainUtil;
import com.plotsquared.bukkit.util.bukkit.BukkitUtil;
/**
* Created 2014-11-18 for PlotSquared
* @author Citymonstret
*/
public class InventoryListener implements Listener {
@EventHandler
public void onInventoryAction(final InventoryInteractEvent event) {
if (event.getInventory().getHolder() instanceof InfoInventory) {
event.setResult(Event.Result.DENY);
}
}
@EventHandler
public void onInventoryClick(final InventoryClickEvent event) {
final Inventory inventory = event.getInventory();
final Player player = (Player) event.getWhoClicked();
if (inventory.getHolder() instanceof InfoInventory) {
switch (event.getSlot()) {
case 3:
case 4:
case 5:
case 6:
MainUtil.sendMessage(BukkitUtil.getPlayer(player), "This is not implemented yet");
break;
default:
break;
}
}
}
}

View File

@ -0,0 +1,42 @@
package com.plotsquared.bukkit.listeners;
public enum PlayerBlockEventType {
// Non interactive
EAT,
READ,
// Right click with monster egg
SPAWN_MOB,
// Dragon egg
TELEPORT_OBJECT,
// armor stands
PLACE_MISC,
// blocks
PLACE_BLOCK,
// paintings / item frames
PLACE_HANGING,
// vehicles
PLACE_VEHICLE,
// armor stands
BREAK_MISC,
// blocks
BREAK_BLOCK,
// paintings / item frames
BREAK_HANGING,
BREAK_VEHICLE,
// armor stands
INTERACT_MISC,
// blocks
INTERACT_BLOCK,
// vehicle
INTERACT_VEHICLE,
// item frame / painting
INTERACT_HANGING,
// Pressure plate, tripwire etc
TRIGGER_PHYSICAL,
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,159 @@
package com.plotsquared.bukkit.listeners;
import java.util.HashSet;
import java.util.List;
import java.util.UUID;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Entity;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryAction;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.ItemMeta;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.config.C;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.Permissions;
import com.plotsquared.bukkit.util.bukkit.BukkitUtil;
public class PlayerEvents_1_8 extends PlotListener implements Listener {
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onInventoryClick(InventoryClickEvent event) {
if (!event.isLeftClick() || event.getAction() != InventoryAction.PLACE_ALL || event.isShiftClick()) {
return;
}
HumanEntity entity = event.getWhoClicked();
if (!(entity instanceof Player) || !PS.get().isPlotWorld(entity.getWorld().getName())) {
return;
}
Player player = (Player) entity;
PlayerInventory inv = player.getInventory();
int slot = inv.getHeldItemSlot();
if (slot != event.getSlot() || slot > 8 || !event.getEventName().equals("InventoryCreativeEvent")) {
return;
}
ItemStack current = inv.getItemInHand();
ItemStack newItem = event.getCursor();
ItemMeta newMeta = newItem.getItemMeta();
ItemMeta oldMeta = newItem.getItemMeta();
String newLore = "";
if (newMeta != null) {
List<String> lore = newMeta.getLore();
if (lore != null) {
newLore = lore.toString();
}
}
String oldLore = "";
if (oldMeta != null) {
List<String> lore = oldMeta.getLore();
if (lore != null) {
oldLore = lore.toString();
}
}
if (!newLore.equals("[(+NBT)]") || (current.equals(newItem) && newLore.equals(oldLore))) {
return;
}
HashSet<Byte> blocks = null;
Block block = player.getTargetBlock(blocks, 7);
BlockState state = block.getState();
if (state == null) {
return;
}
if (state.getType() != newItem.getType()) {
return;
}
final Location l = BukkitUtil.getLocation(state.getLocation());
Plot plot = MainUtil.getPlot(l);
PlotPlayer pp = BukkitUtil.getPlayer(player);
boolean cancelled = false;
if (plot == null) {
if (!MainUtil.isPlotArea(l)) {
return;
}
if (!Permissions.hasPermission(pp, "plots.admin.interact.road")) {
MainUtil.sendMessage(pp, C.NO_PERMISSION, "plots.admin.interact.road");
cancelled = true;
}
}
else {
if (!plot.hasOwner()) {
if (!Permissions.hasPermission(pp, "plots.admin.interact.unowned")) {
MainUtil.sendMessage(pp, C.NO_PERMISSION, "plots.admin.interact.unowned");
cancelled = true;
}
}
else {
final UUID uuid = pp.getUUID();
if (!plot.isAdded(uuid)) {
if (!Permissions.hasPermission(pp, "plots.admin.interact.other")) {
MainUtil.sendMessage(pp, C.NO_PERMISSION, "plots.admin.interact.other");
cancelled = true;
}
}
}
}
if (cancelled) {
if (current.getTypeId() == newItem.getTypeId() && current.getDurability() == newItem.getDurability()) {
event.setCursor(new ItemStack(newItem.getTypeId(), newItem.getAmount(), newItem.getDurability()));
event.setCancelled(true);
return;
}
event.setCursor(new ItemStack(newItem.getTypeId(), newItem.getAmount(), newItem.getDurability()));
}
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onInteract(final PlayerInteractAtEntityEvent e) {
Entity entity = e.getRightClicked();
if (!(entity instanceof ArmorStand)) {
return;
}
final Location l = BukkitUtil.getLocation(e.getRightClicked().getLocation());
String world = l.getWorld();
if (!PS.get().isPlotWorld(world)) {
return;
}
Plot plot = MainUtil.getPlot(l);
PlotPlayer pp = BukkitUtil.getPlayer(e.getPlayer());
if (plot == null) {
if (!MainUtil.isPlotArea(l)) {
return;
}
if (!Permissions.hasPermission(pp, "plots.admin.interact.road")) {
MainUtil.sendMessage(pp, C.NO_PERMISSION, "plots.admin.interact.road");
e.setCancelled(true);
}
}
else {
if (!plot.hasOwner()) {
if (!Permissions.hasPermission(pp, "plots.admin.interact.unowned")) {
MainUtil.sendMessage(pp, C.NO_PERMISSION, "plots.admin.interact.unowned");
e.setCancelled(true);
}
}
else {
final UUID uuid = pp.getUUID();
if (!plot.isAdded(uuid)) {
if (!Permissions.hasPermission(pp, "plots.admin.interact.other")) {
MainUtil.sendMessage(pp, C.NO_PERMISSION, "plots.admin.interact.other");
e.setCancelled(true);
}
}
}
}
}
}

View File

@ -0,0 +1,52 @@
package com.plotsquared.bukkit.listeners;
import java.util.Iterator;
import org.bukkit.block.Block;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockExplodeEvent;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.flag.FlagManager;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.util.MainUtil;
import com.plotsquared.bukkit.util.bukkit.BukkitUtil;
public class PlayerEvents_1_8_3 implements Listener {
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onBigBoom(final BlockExplodeEvent event) {
Block block = event.getBlock();
Location loc = BukkitUtil.getLocation(block.getLocation());
final String world = loc.getWorld();
if (!PS.get().isPlotWorld(world)) {
return;
}
final Plot plot = MainUtil.getPlot(loc);
if ((plot != null) && plot.hasOwner()) {
if (FlagManager.isPlotFlagTrue(plot, "explosion")) {
final Iterator<Block> iter = event.blockList().iterator();
while (iter.hasNext()) {
final Block b = iter.next();
if (!plot.equals(MainUtil.getPlot(BukkitUtil.getLocation(b.getLocation())))) {
iter.remove();
}
}
return;
}
}
if (MainUtil.isPlotArea(loc)) {
event.setCancelled(true);
} else {
final Iterator<Block> iter = event.blockList().iterator();
while (iter.hasNext()) {
iter.next();
if (MainUtil.isPlotArea(loc)) {
iter.remove();
}
}
}
}
}

View File

@ -0,0 +1,262 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// PlotSquared - A plot manager and world generator for the Bukkit API /
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters /
// /
// This program is free software; you can redistribute it and/or modify /
// it under the terms of the GNU General Public License as published by /
// the Free Software Foundation; either version 3 of the License, or /
// (at your option) any later version. /
// /
// This program is distributed in the hope that it will be useful, /
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the /
// GNU General Public License for more details. /
// /
// You should have received a copy of the GNU General Public License /
// along with this program; if not, write to the Free Software Foundation, /
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /
// /
// You can contact us via: support@intellectualsites.com /
////////////////////////////////////////////////////////////////////////////////////////////////////
package com.plotsquared.bukkit.listeners;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Effect;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.WeatherType;
import org.bukkit.entity.Player;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.config.C;
import com.intellectualcrafters.plot.config.Settings;
import com.plotsquared.bukkit.events.PlayerEnterPlotEvent;
import com.plotsquared.bukkit.events.PlayerLeavePlotEvent;
import com.intellectualcrafters.plot.flag.Flag;
import com.intellectualcrafters.plot.flag.FlagManager;
import com.plotsquared.bukkit.object.BukkitPlayer;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.plotsquared.bukkit.object.comment.CommentManager;
import com.plotsquared.bukkit.titles.AbstractTitle;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.Permissions;
import com.intellectualcrafters.plot.util.StringMan;
import com.intellectualcrafters.plot.util.TaskManager;
import com.plotsquared.bukkit.util.bukkit.UUIDHandler;
/**
* @author Citymonstret
* @author Empire92
*/
public class PlotListener extends APlotListener {
public void textures(final Player p) {
if ((Settings.PLOT_SPECIFIC_RESOURCE_PACK.length() > 1) && PS.get().isPlotWorld(p.getWorld().getName())) {
p.setResourcePack(Settings.PLOT_SPECIFIC_RESOURCE_PACK);
}
}
private String getName(final UUID id) {
if (id == null) {
return "none";
}
final String name = UUIDHandler.getName(id);
if (name == null) {
return "unknown";
}
return name;
}
private void setWeather(Player player, String str) {
switch (str.toLowerCase()) {
case "clear": {
player.setPlayerWeather(WeatherType.CLEAR);
return;
}
case "rain": {
player.setPlayerWeather(WeatherType.DOWNFALL);
return;
}
}
}
private GameMode getGameMode(final String str) {
switch (str) {
case "creative":
return GameMode.CREATIVE;
case "survival":
return GameMode.SURVIVAL;
case "adventure":
return GameMode.ADVENTURE;
default:
return Bukkit.getDefaultGameMode();
}
}
public boolean plotEntry(final PlotPlayer pp, final Plot plot) {
if (plot.isDenied(pp.getUUID()) && !Permissions.hasPermission(pp, "plots.admin.entry.denied")) {
return false;
}
Plot last = (Plot) pp.getMeta("lastplot");
if (last != null && !last.id.equals(plot.id)) {
plotExit(pp, last);
}
pp.setMeta("lastplot", plot);
final Player player = ((BukkitPlayer) pp).player;
final PlayerEnterPlotEvent callEvent = new PlayerEnterPlotEvent(player, plot);
Bukkit.getPluginManager().callEvent(callEvent);
if (plot.hasOwner()) {
HashMap<String, Flag> flags = FlagManager.getPlotFlags(plot);
int size = flags.size();
boolean titles = Settings.TITLES;
final String greeting;
if (size != 0) {
Flag titleFlag = flags.get("titles");
if (titleFlag != null) {
titles = (Boolean) titleFlag.getValue();
}
Flag greetingFlag = flags.get("greeting");
if (greetingFlag != null) {
greeting = (String) greetingFlag.getValue();
}
else {
greeting = "";
}
final Flag gamemodeFlag = flags.get("gamemode");
if (gamemodeFlag != null) {
if (player.getGameMode() != getGameMode(gamemodeFlag.getValueString())) {
if (!player.hasPermission("plots.gamemode.bypass")) {
player.setGameMode(getGameMode(gamemodeFlag.getValueString()));
}
else {
MainUtil.sendMessage(pp, StringMan.replaceAll(C.GAMEMODE_WAS_BYPASSED.s(), "{plot}", plot.id, "{gamemode}", gamemodeFlag.getValue()));
}
}
}
final Flag flyFlag = flags.get("fly");
if (flyFlag != null) {
player.setAllowFlight((boolean) flyFlag.getValue());
}
final Flag timeFlag = flags.get("time");
if (timeFlag != null) {
try {
final long time = (long) timeFlag.getValue();
player.setPlayerTime(time, false);
} catch (final Exception e) {
FlagManager.removePlotFlag(plot, "time");
}
}
final Flag weatherFlag = flags.get("weather");
if (weatherFlag != null) {
setWeather(player, weatherFlag.getValueString());
}
Flag musicFlag = flags.get("music");
if (musicFlag != null) {
final Integer id = (Integer) musicFlag.getValue();
if ((id >= 2256 && id <= 2267) || id == 0) {
final org.bukkit.Location loc = player.getLocation();
org.bukkit.Location lastLoc = (org.bukkit.Location) pp.getMeta("music");
if (lastLoc != null) {
player.playEffect(lastLoc, Effect.RECORD_PLAY, 0);
if (id == 0) {
pp.deleteMeta("music");
}
}
if (id != 0) {
try {
pp.setMeta("music", loc);
player.playEffect(loc, Effect.RECORD_PLAY, Material.getMaterial(id));
}
catch (Exception e) {}
}
}
}
else {
org.bukkit.Location lastLoc = (org.bukkit.Location) pp.getMeta("music");
if (lastLoc != null) {
pp.deleteMeta("music");
player.playEffect(lastLoc, Effect.RECORD_PLAY, 0);
}
}
CommentManager.sendTitle(pp, plot);
}
else if (titles) {
greeting = "";
}
else {
return true;
}
if (titles) {
if (C.TITLE_ENTERED_PLOT.s().length() != 0 || C.TITLE_ENTERED_PLOT_SUB.s().length() != 0) {
TaskManager.runTaskLaterAsync(new Runnable() {
@Override
public void run() {
Plot lastPlot = (Plot) pp.getMeta("lastplot");
if (lastPlot != null && plot.id.equals(lastPlot.id)) {
Map<String, String> replacements = new HashMap<>();
replacements.put("%x%", lastPlot.id.x + "");
replacements.put("%z%", lastPlot.id.y + "");
replacements.put("%world%", plot.world);
replacements.put("%greeting%", greeting);
replacements.put("%alias", plot.toString());
replacements.put("%s", getName(plot.owner));
String main = StringMan.replaceFromMap(C.TITLE_ENTERED_PLOT.s(), replacements);
String sub = StringMan.replaceFromMap(C.TITLE_ENTERED_PLOT_SUB.s(), replacements);
AbstractTitle.sendTitle(pp, main, sub, ChatColor.valueOf(C.TITLE_ENTERED_PLOT_COLOR.s()), ChatColor.valueOf(C.TITLE_ENTERED_PLOT_SUB_COLOR.s()));
}
}
}, 20);
}
}
return true;
}
return true;
}
public boolean plotExit(final PlotPlayer pp, final Plot plot) {
pp.deleteMeta("lastplot");
Player player = ((BukkitPlayer) pp).player;
final PlayerLeavePlotEvent callEvent = new PlayerLeavePlotEvent(player, plot);
Bukkit.getPluginManager().callEvent(callEvent);
if (plot.hasOwner()) {
if (FlagManager.getPlotFlag(plot, "fly") != null) {
player.setAllowFlight(Bukkit.getAllowFlight());
}
if (FlagManager.getPlotFlag(plot, "gamemode") != null) {
if (player.getGameMode() != Bukkit.getDefaultGameMode()) {
if (!player.hasPermission("plots.gamemode.bypass")) {
player.setGameMode(Bukkit.getDefaultGameMode());
}
else {
MainUtil.sendMessage(pp, StringMan.replaceAll(C.GAMEMODE_WAS_BYPASSED.s(), "{plot}", plot.world, "{gamemode}", Bukkit.getDefaultGameMode().name().toLowerCase()));
}
}
}
if (FlagManager.getPlotFlag(plot, "time") != null) {
player.resetPlayerTime();
}
if (FlagManager.getPlotFlag(plot, "weather") != null) {
player.resetPlayerWeather();
}
org.bukkit.Location lastLoc = (org.bukkit.Location) pp.getMeta("music");
if (lastLoc != null) {
pp.deleteMeta("music");
player.playEffect(lastLoc, Effect.RECORD_PLAY, 0);
}
}
return true;
}
public boolean getFlagValue(final String value) {
return Arrays.asList("true", "on", "enabled", "yes").contains(value.toLowerCase());
}
}

View File

@ -0,0 +1,299 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// PlotSquared - A plot manager and world generator for the Bukkit API /
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters /
// /
// This program is free software; you can redistribute it and/or modify /
// it under the terms of the GNU General Public License as published by /
// the Free Software Foundation; either version 3 of the License, or /
// (at your option) any later version. /
// /
// This program is distributed in the hope that it will be useful, /
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the /
// GNU General Public License for more details. /
// /
// You should have received a copy of the GNU General Public License /
// along with this program; if not, write to the Free Software Foundation, /
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /
// /
// You can contact us via: support@intellectualsites.com /
////////////////////////////////////////////////////////////////////////////////////////////////////
package com.plotsquared.bukkit.listeners;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockDamageEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.java.JavaPlugin;
import com.intellectualcrafters.plot.config.C;
import com.plotsquared.bukkit.events.PlayerEnterPlotEvent;
import com.plotsquared.bukkit.events.PlayerLeavePlotEvent;
import com.intellectualcrafters.plot.flag.Flag;
import com.intellectualcrafters.plot.flag.FlagManager;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotHandler;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.Permissions;
import com.plotsquared.bukkit.util.bukkit.BukkitUtil;
import com.plotsquared.bukkit.util.bukkit.UUIDHandler;
/**
* Created 2014-10-30 for PlotSquared
*
* @author Citymonstret
*/
@SuppressWarnings({ "deprecation"})
public class PlotPlusListener extends PlotListener implements Listener {
private final static HashMap<String, Interval> feedRunnable = new HashMap<>();
private final static HashMap<String, Interval> healRunnable = new HashMap<>();
public static void startRunnable(final JavaPlugin plugin) {
plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
@Override
public void run() {
for (Iterator<Entry<String, Interval>> iter = healRunnable.entrySet().iterator(); iter.hasNext();){
Entry<String, Interval> entry = iter.next();
final Interval value = entry.getValue();
++value.count;
if (value.count == value.interval) {
value.count = 0;
final Player player = Bukkit.getPlayer(entry.getKey());
if (player == null) {
iter.remove();
continue;
}
final double level = player.getHealth();
if (level != value.max) {
player.setHealth(Math.min(level + value.amount, value.max));
}
}
}
for (Iterator<Entry<String, Interval>> iter = feedRunnable.entrySet().iterator(); iter.hasNext();){
Entry<String, Interval> entry = iter.next();
final Interval value = entry.getValue();
++value.count;
if (value.count == value.interval) {
value.count = 0;
final Player player = Bukkit.getPlayer(entry.getKey());
if (player == null) {
iter.remove();
continue;
}
final int level = player.getFoodLevel();
if (level != value.max) {
player.setFoodLevel(Math.min(level + value.amount, value.max));
}
}
}
}
}, 0l, 20l);
}
@EventHandler(priority = EventPriority.HIGH)
public void onInteract(final BlockDamageEvent event) {
final Player player = event.getPlayer();
if (player.getGameMode() != GameMode.SURVIVAL) {
return;
}
final Plot plot = MainUtil.getPlot(BukkitUtil.getLocation(player));
if (plot == null) {
return;
}
if (FlagManager.isBooleanFlag(plot, "instabreak", false)) {
event.getBlock().breakNaturally();
}
}
@EventHandler(priority = EventPriority.HIGH)
public void onDamage(final EntityDamageEvent event) {
if (event.getEntityType() != EntityType.PLAYER) {
return;
}
final Player player = (Player) event.getEntity();
final Plot plot = MainUtil.getPlot(BukkitUtil.getLocation(player));
if (plot == null) {
return;
}
if (FlagManager.isBooleanFlag(plot, "invincible", false)) {
event.setCancelled(true);
}
}
@EventHandler
public void onItemPickup(final PlayerPickupItemEvent event) {
final Player player = event.getPlayer();
final PlotPlayer pp = BukkitUtil.getPlayer(player);
final Plot plot = MainUtil.getPlot(pp.getLocation());
if (plot == null) {
return;
}
final UUID uuid = pp.getUUID();
if (plot.isAdded(uuid) && FlagManager.isBooleanFlag(plot, "drop-protection", false)) {
event.setCancelled(true);
}
}
@EventHandler
public void onItemDrop(final PlayerDropItemEvent event) {
final Player player = event.getPlayer();
final PlotPlayer pp = BukkitUtil.getPlayer(player);
final Plot plot = MainUtil.getPlot(pp.getLocation());
if (plot == null) {
return;
}
final UUID uuid = pp.getUUID();
if (plot.isAdded(uuid) && FlagManager.isBooleanFlag(plot, "item-drop", false)) {
event.setCancelled(true);
}
}
@EventHandler
public void onPlotEnter(final PlayerEnterPlotEvent event) {
Player player = event.getPlayer();
final Plot plot = event.getPlot();
if (FlagManager.getPlotFlag(plot, "greeting") != null) {
event.getPlayer().sendMessage(ChatColor.translateAlternateColorCodes('&', C.PREFIX_GREETING.s().replaceAll("%id%", plot.id + "") + FlagManager.getPlotFlag(plot, "greeting").getValueString()));
}
Flag feed = FlagManager.getPlotFlag(plot, "feed");
if (feed != null) {
Integer[] value = (Integer[]) feed.getValue();
feedRunnable.put(player.getName(), new Interval(value[0], value[1], 20));
}
Flag heal = FlagManager.getPlotFlag(plot, "heal");
if (heal != null) {
Integer[] value = (Integer[]) heal.getValue();
healRunnable.put(player.getName(), new Interval(value[0], value[1], 20));
}
if (FlagManager.isBooleanFlag(plot, "notify-enter", false)) {
final Player trespasser = event.getPlayer();
final PlotPlayer pt = BukkitUtil.getPlayer(trespasser);
if (Permissions.hasPermission(pt, "plots.flag.notify-enter.bypass")) {
return;
}
if (plot.hasOwner()) {
for (UUID owner : PlotHandler.getOwners(plot)) {
final PlotPlayer pp = UUIDHandler.getPlayer(owner);
if (pp == null) {
return;
}
if (pp.getUUID().equals(pt.getUUID())) {
return;
}
if (pp.isOnline()) {
MainUtil.sendMessage(pp, C.NOTIFY_ENTER.s().replace("%player", trespasser.getName()).replace("%plot", plot.getId().toString()));
}
}
}
}
}
@EventHandler
public void onPlayerQuit(final PlayerQuitEvent event) {
final Player player = event.getPlayer();
final String name = player.getName();
feedRunnable.remove(name);
healRunnable.remove(name);
}
@EventHandler
public void onPlotLeave(final PlayerLeavePlotEvent event) {
final Player leaver = event.getPlayer();
final Plot plot = event.getPlot();
if (!plot.hasOwner()) {
return;
}
if (FlagManager.getPlotFlag(plot, "farewell") != null) {
event.getPlayer().sendMessage(ChatColor.translateAlternateColorCodes('&', C.PREFIX_FAREWELL.s().replaceAll("%id%", plot.id + "") + FlagManager.getPlotFlag(plot, "farewell").getValueString()));
}
final PlotPlayer pl = BukkitUtil.getPlayer(leaver);
String name = leaver.getName();
feedRunnable.remove(name);
healRunnable.remove(name);
if (FlagManager.isBooleanFlag(plot, "notify-leave", false)) {
if (Permissions.hasPermission(pl, "plots.flag.notify-leave.bypass")) {
return;
}
if (plot.hasOwner()) {
for (UUID owner : PlotHandler.getOwners(plot)) {
final PlotPlayer pp = UUIDHandler.getPlayer(owner);
if (pp == null) {
return;
}
if (pp.getUUID().equals(pl.getUUID())) {
return;
}
if (pp.isOnline()) {
MainUtil.sendMessage(pp, C.NOTIFY_LEAVE.s().replace("%player", leaver.getName()).replace("%plot", plot.getId().toString()));
}
}
}
}
}
public static class Interval {
public final int interval;
public final int amount;
public final int max;
public int count = 0;
public Interval(final int interval, final int amount, final int max) {
this.interval = interval;
this.amount = amount;
this.max = max;
}
}
/**
* Record Meta Class
*
* @author Citymonstret
*/
public static class RecordMeta {
public final static List<RecordMeta> metaList = new ArrayList<>();
static {
for (int x = 3; x < 12; x++) {
metaList.add(new RecordMeta(x + "", Material.valueOf("RECORD_" + x)));
}
}
private final String name;
private final Material material;
public RecordMeta(final String name, final Material material) {
this.name = name;
this.material = material;
}
@Override
public String toString() {
return this.name;
}
@Override
public int hashCode() {
return this.name.hashCode();
}
public Material getMaterial() {
return this.material;
}
}
}

View File

@ -0,0 +1,122 @@
package com.plotsquared.bukkit.listeners;
import java.util.List;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.entity.ExplosionPrimeEvent;
import org.bukkit.util.Vector;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.flag.FlagManager;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.util.MainUtil;
import com.plotsquared.bukkit.util.bukkit.BukkitUtil;
public class TNTListener implements Listener {
private double lastRadius;
@EventHandler
public void onPrime(ExplosionPrimeEvent event) {
lastRadius = event.getRadius() + 1;
}
@EventHandler
public void onExplode(EntityExplodeEvent event) {
Entity entity = event.getEntity();
if (entity == null) {
return;
}
World world = entity.getWorld();
String worldname = world.getName();
if (!PS.get().isPlotWorld(worldname)) {
return;
}
Plot plot = MainUtil.getPlot(BukkitUtil.getLocation(entity));
if (plot == null) {
return;
}
if (!FlagManager.isPlotFlagTrue(plot, "explosion")) {
return;
}
Location bot = MainUtil.getPlotBottomLoc(plot.world, plot.id);
Location top = MainUtil.getPlotTopLoc(plot.world, plot.id);
List<Entity> nearby = entity.getNearbyEntities(lastRadius, lastRadius, lastRadius);
for (Entity near : nearby) {
if (near instanceof TNTPrimed || near.getType() == EntityType.MINECART_TNT) {
Vector velocity = near.getVelocity();
Location loc = BukkitUtil.getLocation(near);
Plot nearPlot = MainUtil.getPlot(loc);
if (!plot.equals(nearPlot)) {
near.setVelocity(new Vector(0, 0, 0));
continue;
}
double vx = velocity.getX();
double vy = velocity.getX();
double vz = velocity.getX();
int dx;
int dz;
if (vx > 0) {
dx = top.getX() - loc.getX();
}
else {
dx = bot.getX() - loc.getX();
}
if (vz > 0) {
dz = top.getZ() - loc.getZ();
}
else {
dz = bot.getZ() - loc.getZ();
}
double s1 = dx / vx;
double s2 = dz / vz;
Vector v1 = new Vector(dx, 0, vz * s1);
Vector v2 = new Vector(vx * s2, 0, dz);
Vector shortest;
if (v1.length() < v2.length()) {
shortest = v1;
}
else {
shortest = v2;
}
Location landing = loc.add(shortest.getBlockX() + 1, 0, shortest.getBlockZ() + 1);
int ty = BukkitUtil.getHeighestBlock(worldname, landing.getX(), landing.getZ());
int diff = ty - loc.getY();
double calcDiff = getY(velocity, Math.sqrt(shortest.getBlockX() * shortest.getBlockX() + shortest.getBlockZ() * shortest.getBlockZ()));
if (calcDiff > diff) {
near.setVelocity(new Vector(0, 0, 0));
}
}
}
event.getEntity().setVelocity(new Vector(0, 0, 0));
}
public double getY(Vector velocity, double x) {
double g = 16;
double l1 = velocity.length();
double l2 = Math.sqrt(velocity.getX() * velocity.getX() + velocity.getZ() * velocity.getZ());
double v = l1 * 20;
double theta = Math.acos(l2/l1);
if (velocity.getY() < 0) {
theta = -theta;
}
double cos = Math.cos(theta);
double yDiff = (x * Math.tan(theta)) - ((g * x * x) / (2 * (v * v * cos * cos)));
return yDiff;
}
}

View File

@ -0,0 +1,48 @@
package com.plotsquared.bukkit.listeners;
import org.bukkit.World;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.world.WorldInitEvent;
import org.bukkit.event.world.WorldLoadEvent;
import org.bukkit.generator.ChunkGenerator;
import com.intellectualcrafters.plot.PS;
import com.plotsquared.bukkit.object.PlotGenerator;
import com.plotsquared.bukkit.util.bukkit.UUIDHandler;
public class WorldEvents implements Listener {
public static String lastWorld = null;
public static String getName(World world) {
if (lastWorld != null && !lastWorld.equals("CheckingPlotSquaredGenerator")) {
return lastWorld;
}
else {
return world.getName();
}
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public static void onWorldInit(final WorldInitEvent event) {
final World world = event.getWorld();
String name = getName(world);
final ChunkGenerator gen = world.getGenerator();
if (gen instanceof PlotGenerator) {
//
PS.get().loadWorld(name, (PlotGenerator) gen);
} else {
if (PS.get().config.contains("worlds." + name)) {
PS.get().loadWorld(name, null);
}
}
lastWorld = null;
}
@EventHandler
public void worldLoad(final WorldLoadEvent event) {
UUIDHandler.cacheWorld(event.getWorld().getName());
}
}

View File

@ -0,0 +1,75 @@
package com.plotsquared.bukkit.listeners.worldedit;
import java.util.ArrayList;
import java.util.List;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.biome.BaseBiome;
public class NullExtent implements Extent {
@Override
public BaseBiome getBiome(Vector2D arg0) {
return null;
}
@Override
public BaseBlock getBlock(Vector arg0) {
return null;
}
@Override
public BaseBlock getLazyBlock(Vector arg0) {
return null;
}
@Override
public Operation commit() {
return null;
}
@Override
public boolean setBiome(Vector2D arg0, BaseBiome arg1) {
return false;
}
@Override
public boolean setBlock(Vector arg0, BaseBlock arg1) throws WorldEditException {
return false;
}
@Override
public Entity createEntity(Location arg0, BaseEntity arg1) {
return null;
}
@Override
public List<? extends Entity> getEntities() {
return new ArrayList<>();
}
@Override
public List<? extends Entity> getEntities(Region arg0) {
return new ArrayList<>();
}
@Override
public Vector getMaximumPoint() {
return new Vector(0, 0, 0);
}
@Override
public Vector getMinimumPoint() {
return new Vector(0, 0, 0);
}
}

View File

@ -0,0 +1,108 @@
package com.plotsquared.bukkit.listeners.worldedit;
import java.util.HashSet;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.config.Settings;
import com.intellectualcrafters.plot.object.RegionWrapper;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.biome.BaseBiome;
public class ProcessedWEExtent extends AbstractDelegateExtent {
private final HashSet<RegionWrapper> mask;
int BScount = 0;
int Ecount = 0;
boolean BSblocked = false;
boolean Eblocked = false;
public ProcessedWEExtent(HashSet<RegionWrapper> mask, Extent extent) {
super(extent);
this.mask = mask;
}
@Override
public boolean setBlock(Vector location, BaseBlock block) throws WorldEditException {
switch (block.getType()) {
case 54:
case 130:
case 142:
case 27:
case 137:
case 52:
case 154:
case 84:
case 25:
case 144:
case 138:
case 176:
case 177:
case 63:
case 68:
case 323:
case 117:
case 116:
case 28:
case 66:
case 157:
case 61:
case 62:
case 140:
case 146:
case 149:
case 150:
case 158:
case 23:
case 123:
case 124:
case 29:
case 33:
case 151:
case 178: {
if (BSblocked) {
return false;
}
BScount++;
if (BScount > Settings.CHUNK_PROCESSOR_MAX_BLOCKSTATES) {
BSblocked = true;
PS.log("&cPlotSquared detected unsafe WorldEdit: " + (location.getBlockX()) + "," + (location.getBlockZ()));
}
}
}
if (WEManager.maskContains(mask, location.getBlockX(), location.getBlockZ())) {
return super.setBlock(location, block);
}
return false;
}
@Override
public Entity createEntity(Location location, BaseEntity entity) {
if (Eblocked) {
return null;
}
Ecount++;
if (Ecount > Settings.CHUNK_PROCESSOR_MAX_ENTITIES) {
Eblocked = true;
PS.log("&cPlotSquared detected unsafe WorldEdit: " + (location.getBlockX()) + "," + (location.getBlockZ()));
}
if (WEManager.maskContains(mask, location.getBlockX(), location.getBlockZ())) {
return super.createEntity(location, entity);
}
return null;
}
@Override
public boolean setBiome(Vector2D position, BaseBiome biome) {
if (WEManager.maskContains(mask, position.getBlockX(), position.getBlockZ())) {
return super.setBiome(position, biome);
}
return false;
}
}

View File

@ -0,0 +1,48 @@
package com.plotsquared.bukkit.listeners.worldedit;
import java.util.HashSet;
import com.intellectualcrafters.plot.object.RegionWrapper;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.biome.BaseBiome;
public class WEExtent extends AbstractDelegateExtent {
private final HashSet<RegionWrapper> mask;
public WEExtent(HashSet<RegionWrapper> mask, Extent extent) {
super(extent);
this.mask = mask;
}
@Override
public boolean setBlock(Vector location, BaseBlock block) throws WorldEditException {
if (WEManager.maskContains(mask, location.getBlockX(), location.getBlockZ())) {
return super.setBlock(location, block);
}
return false;
}
@Override
public Entity createEntity(Location location, BaseEntity entity) {
if (WEManager.maskContains(mask, location.getBlockX(), location.getBlockZ())) {
return super.createEntity(location, entity);
}
return null;
}
@Override
public boolean setBiome(Vector2D position, BaseBiome biome) {
if (WEManager.maskContains(mask, position.getBlockX(), position.getBlockZ())) {
return super.setBiome(position, biome);
}
return false;
}
}

View File

@ -0,0 +1,255 @@
package com.plotsquared.bukkit.listeners.worldedit;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.config.C;
import com.intellectualcrafters.plot.config.Settings;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.object.RegionWrapper;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.Permissions;
import com.plotsquared.bukkit.util.bukkit.BukkitUtil;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.bukkit.selections.Selection;
public class WEListener implements Listener {
public final HashSet<String> rad1 = new HashSet<>(Arrays.asList("forestgen", "pumpkins", "drain", "fixwater", "fixlava", "replacenear", "snow", "thaw", "ex", "butcher", "size"));
public final HashSet<String> rad2 = new HashSet<>(Arrays.asList("fill", "fillr", "removenear", "remove"));
public final HashSet<String> rad2_1 = new HashSet<>(Arrays.asList("hcyl", "cyl"));
public final HashSet<String> rad2_2 = new HashSet<>(Arrays.asList("sphere", "pyramid"));
public final HashSet<String> rad2_3 = new HashSet<>(Arrays.asList("brush smooth"));
public final HashSet<String> rad3_1 = new HashSet<>(Arrays.asList("brush gravity"));
public final HashSet<String> rad3_2 = new HashSet<>(Arrays.asList("brush sphere", "brush cylinder"));
public final HashSet<String> region = new HashSet<>(Arrays.asList("move", "set", "replace", "overlay", "walls", "outline", "deform", "hollow", "smooth", "naturalize", "paste", "count", "distr", "regen", "copy", "cut", "green", "setbiome"));
public final HashSet<String> regionExtend = new HashSet<>(Arrays.asList("stack"));
public final HashSet<String> unregioned = new HashSet<>(Arrays.asList("paste", "redo", "undo", "rotate", "flip", "generate", "schematic", "schem"));
public final HashSet<String> unsafe1 = new HashSet<>(Arrays.asList("cs", ".s", "restore", "snapshot", "delchunks", "listchunks"));
public final HashSet<String> restricted = new HashSet<>(Arrays.asList("up"));
public boolean checkCommand(List<String> list, String cmd) {
for (String identifier : list) {
if (("/" + identifier).equals(cmd) || ("//" + identifier).equals(cmd) || ("/worldedit:/" + identifier).equals(cmd) || ("/worldedit:" + identifier).equals(cmd)) {
return true;
}
}
return false;
}
public String reduceCmd(String cmd, boolean single) {
if (cmd.startsWith("/worldedit:/")) {
return cmd.substring(12);
}
if (cmd.startsWith("/worldedit:")) {
return cmd.substring(11);
}
if (cmd.startsWith("//")) {
return cmd.substring(2);
}
if (single && cmd.startsWith("/")) {
return cmd.substring(1);
}
return cmd;
}
public int getInt(String s) {
try {
int max = 0;
String[] split = s.split(",");
for (String rad : split) {
int val = Integer.parseInt(rad);
if (val > max) {
max = val;
}
}
return max;
}
catch (NumberFormatException e) {
return 0;
}
}
public boolean checkVolume(PlotPlayer player, long volume, long max, Cancellable e) {
if (volume > max) {
MainUtil.sendMessage(player, C.WORLDEDIT_VOLUME.s().replaceAll("%current%", volume + "").replaceAll("%max%", max + ""));
e.setCancelled(true);
}
if (Permissions.hasPermission(player, "plots.worldedit.bypass")) {
MainUtil.sendMessage(player, C.WORLDEDIT_BYPASS);
}
return true;
}
public boolean checkSelection(Player p, PlotPlayer pp, int modifier, long max, Cancellable e) {
final Selection selection = PS.get().worldEdit.getSelection(p);
if (selection == null) {
return true;
}
final BlockVector pos1 = selection.getNativeMinimumPoint().toBlockVector();
final BlockVector pos2 = selection.getNativeMaximumPoint().toBlockVector();
HashSet<RegionWrapper> mask = WEManager.getMask(pp);
RegionWrapper region = new RegionWrapper(pos1.getBlockX(), pos2.getBlockX(), pos1.getBlockZ(), pos2.getBlockZ());
if (Settings.REQUIRE_SELECTION) {
String arg = null;
if (!WEManager.regionContains(region, mask)) {
arg = "pos1 + pos2";
}
else if (!WEManager.maskContains(mask, pos1.getBlockX(), pos1.getBlockZ())) {
arg = "pos1";
}
else if (!WEManager.maskContains(mask, pos2.getBlockX(), pos2.getBlockZ())) {
arg = "pos2";
}
if (arg != null) {
e.setCancelled(true);
MainUtil.sendMessage(pp, C.REQUIRE_SELECTION_IN_MASK, arg);
if (Permissions.hasPermission(pp, "plots.worldedit.bypass")) {
MainUtil.sendMessage(pp, C.WORLDEDIT_BYPASS);
}
return true;
}
if (!WEManager.regionContains(region, mask)) {
MainUtil.sendMessage(pp, C.REQUIRE_SELECTION_IN_MASK, "pos1 + pos2");
e.setCancelled(true);
if (Permissions.hasPermission(pp, "plots.worldedit.bypass")) {
MainUtil.sendMessage(pp, C.WORLDEDIT_BYPASS);
}
return true;
}
}
long volume = Math.abs((pos1.getBlockX() - pos2.getBlockX()) * (pos1.getBlockY() - pos2.getBlockY()) * (pos1.getBlockZ() - pos2.getBlockZ())) * modifier;
return checkVolume(pp, volume, max, e);
}
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public boolean onPlayerCommand(final PlayerCommandPreprocessEvent e) {
final Player p = e.getPlayer();
final PlotPlayer pp = BukkitUtil.getPlayer(p);
if (!PS.get().isPlotWorld(p.getWorld().getName())) {
return true;
}
String cmd = e.getMessage().toLowerCase();
boolean single = true;
String[] split = cmd.split(" ");
long maxVolume = Settings.WE_MAX_VOLUME;
long maxIterations = Settings.WE_MAX_ITERATIONS;
if (WEManager.bypass.contains(pp.getName())) {
return true;
}
if (split.length >= 2) {
String reduced = reduceCmd(split[0], single);
String reduced2 = reduceCmd(split[0] + " " + split[1], single);
if (rad1.contains(reduced)) {
long volume = getInt(split[1]) * 256;
return checkVolume(pp, volume, maxVolume, e);
}
if (rad2.contains(reduced)) {
if (split.length >= 3) {
long volume = getInt(split[2]) * 256;
return checkVolume(pp, volume, maxVolume, e);
}
return true;
}
if (rad2_1.contains(reduced)) {
if (split.length >= 4) {
long volume = getInt(split[2]) * getInt(split[3]);
return checkVolume(pp, volume, maxVolume, e);
}
return true;
}
if (rad2_2.contains(reduced)) {
if (split.length >= 3) {
long radius = getInt(split[2]);
long volume = radius * radius;
return checkVolume(pp, volume, maxVolume, e);
}
return true;
}
if (rad2_3.contains(reduced2)) {
if (split.length >= 3) {
if (split.length == 4) {
int iterations = getInt(split[3]);
if (iterations > maxIterations) {
MainUtil.sendMessage(pp, C.WORLDEDIT_ITERATIONS.s().replaceAll("%current%", iterations + "").replaceAll("%max%", maxIterations + ""));
e.setCancelled(true);
if (Permissions.hasPermission(pp, "plots.worldedit.bypass")) {
MainUtil.sendMessage(pp, C.WORLDEDIT_BYPASS);
}
return true;
}
}
long radius = getInt(split[2]);
long volume = radius * radius;
return checkVolume(pp, volume, maxVolume, e);
}
return true;
}
if (rad3_1.contains(reduced2)) {
if (split.length >= 3) {
int i = 2;
if (split[i].equalsIgnoreCase("-h")) {
i = 3;
}
long radius = getInt(split[i]);
long volume = radius * radius;
return checkVolume(pp, volume, maxVolume, e);
}
return true;
}
if (rad3_2.contains(reduced2)) {
if (split.length >= 4) {
int i = 3;
if (split[i].equalsIgnoreCase("-h")) {
i = 4;
}
long radius = getInt(split[i]);
long volume = radius * radius;
return checkVolume(pp, volume, maxVolume, e);
}
return true;
}
if (regionExtend.contains(reduced)) {
return checkSelection(p, pp, getInt(split[1]), maxVolume, e);
}
}
String reduced = reduceCmd(split[0], single);
if (Settings.WE_BLACKLIST.contains(reduced)) {
MainUtil.sendMessage(pp, C.WORLDEDIT_UNSAFE);
e.setCancelled(true);
if (Permissions.hasPermission(pp, "plots.worldedit.bypass")) {
MainUtil.sendMessage(pp, C.WORLDEDIT_BYPASS);
}
}
if (restricted.contains(reduced)) {
Plot plot = MainUtil.getPlot(pp.getLocation());
if (plot != null && plot.isAdded(pp.getUUID())) {
return true;
}
e.setCancelled(true);
MainUtil.sendMessage(pp, C.NO_PLOT_PERMS);
if (Permissions.hasPermission(pp, "plots.worldedit.bypass")) {
MainUtil.sendMessage(pp, C.WORLDEDIT_BYPASS);
}
return true;
}
if (region.contains(reduced)) {
return checkSelection(p, pp, 1, maxVolume, e);
}
return true;
}
}

View File

@ -0,0 +1,56 @@
package com.plotsquared.bukkit.listeners.worldedit;
import java.util.HashSet;
import java.util.UUID;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.config.Settings;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.object.RegionWrapper;
import com.intellectualcrafters.plot.util.MainUtil;
public class WEManager {
public static HashSet<String> bypass = new HashSet<>();
public static boolean maskContains(HashSet<RegionWrapper> mask, int x, int z) {
for (RegionWrapper region : mask) {
if ((x >= region.minX) && (x <= region.maxX) && (z >= region.minZ) && (z <= region.maxZ)) {
return true;
}
}
return false;
}
public static HashSet<RegionWrapper> getMask(PlotPlayer player) {
HashSet<RegionWrapper> regions = new HashSet<>();
UUID uuid = player.getUUID();
for (Plot plot : PS.get().getPlots(player.getLocation().getWorld()).values()) {
if (!plot.getMerged(0) && !plot.getMerged(3)) {
if (Settings.WE_ALLOW_HELPER ? plot.isAdded(uuid) : (plot.isOwner(uuid) || plot.getTrusted().contains(uuid))) {
Location pos1 = MainUtil.getPlotBottomLoc(plot.world, plot.id).add(1, 0, 1);
Location pos2 = MainUtil.getPlotTopLoc(plot.world, plot.id);
regions.add(new RegionWrapper(pos1.getX(), pos2.getX(), pos1.getZ(), pos2.getZ()));
}
}
}
return regions;
}
public static boolean intersects(RegionWrapper region1, RegionWrapper region2) {
if ((region1.minX <= region2.maxX) && (region1.maxX >= region2.minX) && (region1.minZ <= region2.maxZ) && (region1.maxZ >= region2.minZ)) {
return true;
}
return false;
}
public static boolean regionContains(RegionWrapper selection, HashSet<RegionWrapper> mask) {
for (RegionWrapper region : mask) {
if (intersects(region, selection)) {
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,49 @@
package com.plotsquared.bukkit.listeners.worldedit;
import java.util.HashSet;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.config.C;
import com.intellectualcrafters.plot.config.Settings;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.object.RegionWrapper;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.Permissions;
import com.plotsquared.bukkit.util.bukkit.UUIDHandler;
import com.sk89q.worldedit.event.extent.EditSessionEvent;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.util.eventbus.EventHandler.Priority;
import com.sk89q.worldedit.util.eventbus.Subscribe;
public class WESubscriber {
@Subscribe(priority=Priority.VERY_EARLY)
public void onEditSession(EditSessionEvent event) {
String world = event.getWorld().getName();
if (!PS.get().isPlotWorld(world)) {
return;
}
Actor actor = event.getActor();
if (actor != null && actor.isPlayer()) {
String name = actor.getName();
if (WEManager.bypass.contains(name)) {
return;
}
PlotPlayer player = UUIDHandler.getPlayer(actor.getName());
HashSet<RegionWrapper> mask = WEManager.getMask(player);
if (mask.size() == 0) {
if (Permissions.hasPermission(player, "plots.worldedit.bypass")) {
MainUtil.sendMessage(player, C.WORLDEDIT_BYPASS);
}
event.setExtent(new NullExtent());
return;
}
if (Settings.CHUNK_PROCESSOR) {
event.setExtent(new ProcessedWEExtent(mask, event.getExtent()));
}
else {
event.setExtent(new WEExtent(mask, event.getExtent()));
}
}
}
}

View File

@ -0,0 +1,100 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// PlotSquared - A plot manager and world generator for the Bukkit API /
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters /
// /
// This program is free software; you can redistribute it and/or modify /
// it under the terms of the GNU General Public License as published by /
// the Free Software Foundation; either version 3 of the License, or /
// (at your option) any later version. /
// /
// This program is distributed in the hope that it will be useful, /
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the /
// GNU General Public License for more details. /
// /
// You should have received a copy of the GNU General Public License /
// along with this program; if not, write to the Free Software Foundation, /
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /
// /
// You can contact us via: support@intellectualsites.com /
////////////////////////////////////////////////////////////////////////////////////////////////////
package com.plotsquared.bukkit.object;
import org.bukkit.World;
import org.bukkit.block.Block;
/**
* Wrapper class for blocks, using pure data rather than the object.
*
* Useful for NMS
*
* @author Empire92
* @author Citymonstret
*/
public class BlockWrapper {
/**
* X Coordinate
*/
public final int x;
/**
* Y Coordinate
*/
public final int y;
/**
* Z Coordinate
*/
public final int z;
/**
* Block ID
*/
public final int id;
/**
* Block Data Value
*/
public final byte data;
/**
* Constructor
*
* @param x X Loc Value
* @param y Y Loc Value
* @param z Z Loc Value
* @param id Material ID
* @param data Data Value
*/
public BlockWrapper(final int x, final int y, final int z, final short id, final byte data) {
this.x = x;
this.y = y;
this.z = z;
this.id = id;
this.data = data;
}
/**
* Alternative Constructor Uses block data, rather than typed data
*
* @param block Block from which we get the data
*/
@SuppressWarnings({ "deprecation", "unused" })
public BlockWrapper(final Block block) {
this.x = block.getX();
this.y = block.getY();
this.z = block.getZ();
this.id = block.getTypeId();
this.data = block.getData();
}
/**
* Get a block based on the block wrapper
*
* @param world World in which the block is/will be, located
*
* @return block created/fetched from settings
*/
@SuppressWarnings({ "unused", "deprecation" })
public Block toBlock(final World world) {
final Block block = world.getBlockAt(this.x, this.y, this.z);
block.setTypeIdAndData(this.id, this.data, true);
return block;
}
}

View File

@ -0,0 +1,140 @@
package com.plotsquared.bukkit.object;
import com.intellectualcrafters.plot.object.LazyBlock;
import com.intellectualcrafters.plot.object.PlotBlock;
import org.bukkit.block.Block;
public class BukkitLazyBlock extends LazyBlock {
private int id = -1;
private Block block;
private PlotBlock pb;
public BukkitLazyBlock(int id, Block block) {
this.id = id;
this.block = block;
}
public BukkitLazyBlock(PlotBlock pb) {
this.id = pb.id;
this.pb = pb;
}
public BukkitLazyBlock(Block block) {
this.block = block;
}
@Override
public PlotBlock getPlotBlock() {
if (pb != null) {
return pb;
}
if (id == -1 ) {
id = block.getTypeId();
}
byte data;
switch(id) {
case 0:
case 2:
case 4:
case 13:
case 14:
case 15:
case 20:
case 21:
case 22:
case 24:
case 25:
case 30:
case 32:
case 37:
case 39:
case 40:
case 41:
case 42:
case 45:
case 46:
case 47:
case 48:
case 49:
case 50:
case 51:
case 52:
case 54:
case 55:
case 56:
case 57:
case 58:
case 60:
case 61:
case 62:
case 7:
case 8:
case 9:
case 10:
case 11:
case 73:
case 74:
case 75:
case 76:
case 78:
case 79:
case 80:
case 81:
case 82:
case 83:
case 84:
case 85:
case 87:
case 88:
case 101:
case 102:
case 103:
case 110:
case 112:
case 113:
case 117:
case 121:
case 122:
case 123:
case 124:
case 129:
case 133:
case 138:
case 137:
case 140:
case 165:
case 166:
case 169:
case 170:
case 172:
case 173:
case 174:
case 176:
case 177:
case 181:
case 182:
case 188:
case 189:
case 190:
case 191:
case 192:
data = 0;
default:
data = block.getData();
}
pb = new PlotBlock((short) id, data);
return pb;
}
@Override
public int getId() {
if (id == -1) {
id = block.getTypeId();
}
return id;
}
}

View File

@ -0,0 +1,39 @@
package com.plotsquared.bukkit.object;
import java.util.UUID;
import com.intellectualcrafters.plot.object.OfflinePlotPlayer;
import org.bukkit.OfflinePlayer;
public class BukkitOfflinePlayer implements OfflinePlotPlayer {
public final OfflinePlayer player;
/**
* Please do not use this method. Instead use BukkitUtil.getPlayer(Player), as it caches player objects.
* @param player
*/
public BukkitOfflinePlayer(final OfflinePlayer player) {
this.player = player;
}
@Override
public UUID getUUID() {
return this.player.getUniqueId();
}
@Override
public long getLastPlayed() {
return this.player.getLastPlayed();
}
@Override
public boolean isOnline() {
return this.player.isOnline();
}
@Override
public String getName() {
return this.player.getName();
}
}

View File

@ -0,0 +1,193 @@
package com.plotsquared.bukkit.object;
import java.util.HashMap;
import java.util.HashSet;
import java.util.UUID;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.PlotPlayer;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionDefault;
import com.intellectualcrafters.plot.config.Settings;
import com.intellectualcrafters.plot.util.EconHandler;
import com.plotsquared.bukkit.util.bukkit.BukkitUtil;
import com.plotsquared.bukkit.util.bukkit.UUIDHandler;
public class BukkitPlayer implements PlotPlayer {
public final Player player;
UUID uuid;
String name;
private int op = 0;
private long last = 0;
public HashSet<String> hasPerm = new HashSet<>();
public HashSet<String> noPerm = new HashSet<>();
private HashMap<String, Object> meta;
/**
* Please do not use this method. Instead use BukkitUtil.getPlayer(Player), as it caches player objects.
* @param player
*/
public BukkitPlayer(final Player player) {
this.player = player;
}
public long getPreviousLogin() {
if (last == 0) {
last = player.getLastPlayed();
}
return last;
}
@Override
public Location getLocation() {
return BukkitUtil.getLocation(this.player);
}
@Override
public UUID getUUID() {
if (this.uuid == null) {
this.uuid = UUIDHandler.getUUID(this);
}
return this.uuid;
}
@Override
public boolean hasPermission(final String perm) {
if (Settings.PERMISSION_CACHING) {
if (this.noPerm.contains(perm)) {
return false;
}
if (this.hasPerm.contains(perm)) {
return true;
}
final boolean result = this.player.hasPermission(perm);
if (!result) {
this.noPerm.add(perm);
return false;
}
this.hasPerm.add(perm);
return true;
}
return this.player.hasPermission(perm);
}
@Override
public void sendMessage(final String message) {
this.player.sendMessage(message);
}
@Override
public void teleport(final Location loc) {
this.player.teleport(new org.bukkit.Location(BukkitUtil.getWorld(loc.getWorld()), loc.getX() + 0.5, loc.getY(), loc.getZ() + 0.5, loc.getYaw(), loc.getPitch()));
}
@Override
public boolean isOp() {
if (this.op != 0) {
if (this.op == 1) {
return false;
}
return true;
}
final boolean result = this.player.isOp();
if (!result) {
this.op = 1;
return false;
}
this.op = 2;
return true;
}
@Override
public String getName() {
if (this.name == null) {
this.name = this.player.getName();
}
return this.name;
}
@Override
public boolean isOnline() {
return this.player.isOnline();
}
@Override
public void setCompassTarget(final Location loc) {
this.player.setCompassTarget(new org.bukkit.Location(BukkitUtil.getWorld(loc.getWorld()), loc.getX(), loc.getY(), loc.getZ()));
}
@Override
public Location getLocationFull() {
return BukkitUtil.getLocationFull(this.player);
}
@Override
public void setMeta(String key, Object value) {
if (this.meta == null) {
this.meta = new HashMap<String, Object>();
}
this.meta.put(key, value);
}
@Override
public Object getMeta(String key) {
if (this.meta != null) {
return this.meta.get(key);
}
return null;
}
@Override
public void deleteMeta(String key) {
if (this.meta != null) {
this.meta.remove(key);
}
}
@Override
public String toString() {
return getName();
}
@Override
public void setAttribute(String key) {
key = "plotsquared_user_attributes." + key;
EconHandler.manager.setPermission(this, key, true);
}
@Override
public boolean getAttribute(String key) {
key = "plotsquared_user_attributes." + key;
Permission perm = Bukkit.getServer().getPluginManager().getPermission(key);
if (perm == null) {
perm = new Permission(key, PermissionDefault.FALSE);
Bukkit.getServer().getPluginManager().addPermission(perm);
Bukkit.getServer().getPluginManager().recalculatePermissionDefaults(perm);
}
return player.hasPermission(key);
}
@Override
public void removeAttribute(String key) {
key = "plotsquared_user_attributes." + key;
EconHandler.manager.setPermission(this, key, false);
}
@Override
public void loadData() {
if (!player.isOnline()) {
player.loadData();
}
}
@Override
public void saveData() {
player.saveData();
}
}

View File

@ -0,0 +1,88 @@
package com.plotsquared.bukkit.object;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotPlayer;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import com.plotsquared.bukkit.util.bukkit.BukkitUtil;
import com.plotsquared.bukkit.util.bukkit.UUIDHandler;
/**
* Created 2014-11-18 for PlotSquared
*
* @author Citymonstret
*/
public class InfoInventory implements InventoryHolder {
private final Plot plot;
private final Inventory inventory;
private final Player player;
/**
* Constructor
*
* @param plot from which we take information
*/
public InfoInventory(final Plot plot, final PlotPlayer plr) {
this.plot = plot;
this.player = ((BukkitPlayer) plr).player;
this.inventory = Bukkit.createInventory(this, 9, "Plot: " + plot.id.toString());
}
@Override
public Inventory getInventory() {
return this.inventory;
}
public String getName(final UUID uuid) {
final String name = UUIDHandler.getName(this.plot.owner);
if (name == null) {
return "unknown";
}
return name;
}
public InfoInventory build() {
final UUID uuid = UUIDHandler.getUUID(BukkitUtil.getPlayer(this.player));
final ItemStack generalInfo = getItem(Material.EMERALD, "&cPlot Info", "&cID: &6" + this.plot.getId().toString(), "&cOwner: &6" + getName(this.plot.owner), "&cAlias: &6" + this.plot.getSettings().getAlias(), "&cBiome: &6" + this.plot.getSettings().getBiome().toString().replaceAll("_", "").toLowerCase(), "&cCan Build: &6" + this.plot.isAdded(uuid), "&cIs Denied: &6" + this.plot.isDenied(uuid));
final ItemStack trusted = getItem(Material.EMERALD, "&cTrusted", "&cAmount: &6" + this.plot.getTrusted().size(), "&8Click to view a list of the trusted users");
final ItemStack members = getItem(Material.EMERALD, "&cMembers", "&cAmount: &6" + this.plot.getMembers().size(), "&8Click to view a list of plot members");
final ItemStack denied = getItem(Material.EMERALD, "&cDenied", "&cAmount: &6" + this.plot.getDenied().size(), "&8Click to view a list of denied players");
final ItemStack flags = getItem(Material.EMERALD, "&cFlags", "&cAmount: &6" + this.plot.getSettings().flags.size(), "&8Click to view a list of plot flags");
this.inventory.setItem(2, generalInfo);
this.inventory.setItem(3, trusted);
this.inventory.setItem(4, members);
this.inventory.setItem(5, denied);
this.inventory.setItem(6, flags);
return this;
}
public InfoInventory display() {
this.player.closeInventory();
this.player.openInventory(this.inventory);
return this;
}
private ItemStack getItem(final Material material, final String name, final String... lore) {
final ItemStack stack = new ItemStack(material);
final ItemMeta meta = stack.getItemMeta();
meta.setDisplayName(ChatColor.translateAlternateColorCodes('&', name));
final List<String> lList = new ArrayList<>();
for (final String l : lore) {
lList.add(ChatColor.translateAlternateColorCodes('&', l));
}
meta.setLore(lList);
stack.setItemMeta(meta);
return stack;
}
}

View File

@ -0,0 +1,257 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// PlotSquared - A plot manager and world generator for the Bukkit API /
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters /
// /
// This program is free software; you can redistribute it and/or modify /
// it under the terms of the GNU General Public License as published by /
// the Free Software Foundation; either version 3 of the License, or /
// (at your option) any later version. /
// /
// This program is distributed in the hope that it will be useful, /
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the /
// GNU General Public License for more details. /
// /
// You should have received a copy of the GNU General Public License /
// along with this program; if not, write to the Free Software Foundation, /
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /
// /
// You can contact us via: support@intellectualsites.com /
////////////////////////////////////////////////////////////////////////////////////////////////////
package com.plotsquared.bukkit.object;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.Random;
import com.intellectualcrafters.plot.object.*;
import org.bukkit.World;
import org.bukkit.block.Biome;
import org.bukkit.generator.BlockPopulator;
import org.bukkit.generator.ChunkGenerator;
import com.intellectualcrafters.plot.PS;
import com.plotsquared.bukkit.listeners.WorldEvents;
import com.intellectualcrafters.plot.util.ChunkManager;
public abstract class PlotGenerator extends ChunkGenerator {
public static short[][][] CACHE_I = null;
public static short[][][] CACHE_J = null;
public int X;
public int Z;
private boolean loaded = false;
private short[][] result;
private PseudoRandom random = new PseudoRandom();
public PlotGenerator(String world) {
WorldEvents.lastWorld = world;
initCache();
}
public void initCache() {
if (CACHE_I == null) {
CACHE_I = new short[256][16][16];
CACHE_J = new short[256][16][16];
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
for (int y = 0; y < 256; y++) {
short i = (short) (y >> 4);
short j = (short) (((y & 0xF) << 8) | (z << 4) | x);
CACHE_I[y][x][z] = i;
CACHE_J[y][x][z] = j;
}
}
}
}
}
@SuppressWarnings("unchecked")
@Override
public List<BlockPopulator> getDefaultPopulators(World world) {
try {
if (!loaded) {
PS.get().loadWorld(WorldEvents.getName(world), this);
PlotWorld plotworld = PS.get().getPlotWorld(WorldEvents.getName(world));
if (!plotworld.MOB_SPAWNING) {
if (!plotworld.SPAWN_EGGS) {
world.setSpawnFlags(false, false);
}
world.setAmbientSpawnLimit(0);
world.setAnimalSpawnLimit(0);
world.setMonsterSpawnLimit(0);
world.setWaterAnimalSpawnLimit(0);
}
else {
world.setSpawnFlags(true, true);
world.setAmbientSpawnLimit(-1);
world.setAnimalSpawnLimit(-1);
world.setMonsterSpawnLimit(-1);
world.setWaterAnimalSpawnLimit(-1);
}
loaded = true;
return (List<BlockPopulator>)(List<?>) getPopulators(WorldEvents.getName(world));
}
}
catch (Exception e) {
e.printStackTrace();
}
return new ArrayList<BlockPopulator>();
}
/**
* Set the result;
* @param result
*/
public void setResult(short[][] result) {
this.result = result;
}
@Override
public short[][] generateExtBlockSections(World world, Random r, int cx, int cz, BiomeGrid biomes) {
try {
if (!loaded) {
PS.get().loadWorld(WorldEvents.getName(world), this);
loaded = true;
}
final int prime = 13;
int h = 1;
h = (prime * h) + cx;
h = (prime * h) + cz;
this.random.state = h;
this.result = new short[16][];
this.X = cx << 4;
this.Z = cz << 4;
if (ChunkManager.FORCE_PASTE) {
PlotWorld plotworld = PS.get().getPlotWorld(world.getName());
Biome biome = Biome.valueOf(plotworld.PLOT_BIOME);
for (short x = 0; x < 16; x++) {
for (short z = 0; z < 16; z++) {
if (biomes != null) {
biomes.setBiome(x, z, biome);
}
final PlotLoc loc = new PlotLoc((X + x), (Z + z));
final HashMap<Short, Short> blocks = ChunkManager.GENERATE_BLOCKS.get(loc);
for (final Entry<Short, Short> entry : blocks.entrySet()) {
setBlock(x, entry.getKey(), z, entry.getValue());
}
}
}
return this.result;
}
generateChunk(world, ChunkManager.CURRENT_PLOT_CLEAR, random, cx, cz, biomes);
if (ChunkManager.CURRENT_PLOT_CLEAR != null) {
PlotLoc loc;
for (Entry<PlotLoc, HashMap<Short, Short>> entry : ChunkManager.GENERATE_BLOCKS.entrySet()) {
for (Entry<Short, Short> entry2 : entry.getValue().entrySet()) {
loc = entry.getKey();
int xx = loc.x - X;
int zz = loc.z - Z;
if (xx >= 0 && xx < 16) {
if (zz >= 0 && zz < 16) {
setBlock(xx, entry2.getKey(), zz, entry2.getValue());
}
}
}
}
}
}
catch (Exception e) {
e.printStackTrace();
}
return result;
}
public void setBlock(final int x, final int y, final int z, final short blkid) {
if (result[CACHE_I[y][x][z]] == null) {
result[CACHE_I[y][x][z]] = new short[4096];
}
result[CACHE_I[y][x][z]][CACHE_J[y][x][z]] = blkid;
}
public void setBlock(final int x, final int y, final int z, final short[] blkid) {
if (blkid.length == 1) {
setBlock(x, y, z, blkid[0]);
}
short id = blkid[random.random(blkid.length)];
if (result[CACHE_I[y][x][z]] == null) {
result[CACHE_I[y][x][z]] = new short[4096];
}
result[CACHE_I[y][x][z]][CACHE_J[y][x][z]] = id;
}
/**
* check if a region contains a location. (x, z) must be between [0,15], [0,15]
* @param plot
* @param x
* @param z
* @return
*/
public boolean contains(final RegionWrapper plot, final int x, final int z) {
int xx = X + x;
int zz = Z + z;
return ((xx >= plot.minX) && (xx <= plot.maxX) && (zz >= plot.minZ) && (zz <= plot.maxZ));
}
/**
* Allow spawning everywhere
*/
@Override
public boolean canSpawn(final World world, final int x, final int z) {
return true;
}
/**
* <b>random</b> is an optimized random number generator.<br>
* - Change the state to have the same chunk random each time it generates<br>
* <b>requiredRegion</b> If a plot is being regenerated, you are only required to generate content in this area<br>
* - use the contains(RegionWrapper, x, z) method to check if the region contains a location<br>
* - You can ignore this if you do not want to further optimize your generator<br>
* - will be null if no restrictions are set<br>
* <b>result</b> is the standard 2D block data array used for generation<br>
* <b>biomes</b> is the standard BiomeGrid used for generation
*
* @param world
* @param random
* @param cx
* @param cz
* @param requiredRegion
* @param biomes
* @param result
* @return
*/
public abstract void generateChunk(final World world, RegionWrapper requiredRegion, final PseudoRandom random, final int cx, final int cz, final BiomeGrid biomes);
public abstract List<PlotPopulator> getPopulators(String world);
/**
* This is called when the generator is initialized.
* You don't need to do anything with it necessarily.
* @param plotworld
*/
public abstract void init(PlotWorld plotworld);
/**
* Return a new instance of the PlotWorld for a world
* @param world
* @return
*/
public abstract PlotWorld getNewPlotWorld(final String world);
/**
* Get the PlotManager class for this generator
* @return
*/
public abstract PlotManager getPlotManager();
/**
* If you need to do anything fancy for /plot setup<br>
* - Otherwise it will just use the PlotWorld configuration<br>
* Feel free to extend BukkitSetupUtils and customize world creation
* @param object
*/
public void processSetup(SetupObject object) {
}
}

View File

@ -0,0 +1,111 @@
package com.plotsquared.bukkit.object;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Random;
import com.intellectualcrafters.plot.object.PlotLoc;
import com.intellectualcrafters.plot.object.PseudoRandom;
import com.intellectualcrafters.plot.object.RegionWrapper;
import org.bukkit.Chunk;
import org.bukkit.World;
import org.bukkit.generator.BlockPopulator;
import com.intellectualcrafters.plot.util.ChunkManager;
import com.plotsquared.bukkit.util.bukkit.BukkitUtil;
public abstract class PlotPopulator extends BlockPopulator {
private PseudoRandom random = new PseudoRandom();
public int X;
public int Z;
private World world;
@Override
public void populate(World world, Random rand, Chunk chunk) {
this.world = world;
this.X = chunk.getX() << 4;
this.Z = chunk.getZ() << 4;
if (ChunkManager.FORCE_PASTE) {
for (short x = 0; x < 16; x++) {
for (short z = 0; z < 16; z++) {
final PlotLoc loc = new PlotLoc((short) (X + x), (short) (Z + z));
final HashMap<Short, Byte> blocks = ChunkManager.GENERATE_DATA.get(loc);
for (final Entry<Short, Byte> entry : blocks.entrySet()) {
setBlock(x, entry.getKey(), z, entry.getValue());
}
}
}
return;
}
populate(world, ChunkManager.CURRENT_PLOT_CLEAR, random, X, Z);
if (ChunkManager.CURRENT_PLOT_CLEAR != null) {
PlotLoc loc;
for (Entry<PlotLoc, HashMap<Short, Byte>> entry : ChunkManager.GENERATE_DATA.entrySet()) {
for (Entry<Short, Byte> entry2 : entry.getValue().entrySet()) {
loc = entry.getKey();
int xx = loc.x - X;
int zz = loc.z - Z;
if (xx >= 0 && xx < 16) {
if (zz >= 0 && zz < 16) {
setBlock(xx, entry2.getKey(), zz, entry2.getValue());
}
}
}
}
}
}
public abstract void populate(World world, RegionWrapper requiredRegion, PseudoRandom random, int cx, int cz);
/**
* Set the id and data at a location. (x, y, z) must be between [0,15], [0,255], [0,15]
* @param x
* @param y
* @param z
* @param id
* @param data
*/
public void setBlock(int x, int y, int z, short id, byte data) {
BukkitUtil.setBlock(world, X + x, y, Z + z, id, data);
}
/**
* Set the data at a location. (x, y, z) must be between [0,15], [0,255], [0,15]
* @param x
* @param y
* @param z
* @param data
*/
public void setBlock(int x, int y, int z, byte data) {
if (data != 0) {
world.getBlockAt(X + x, y, Z + z).setData(data);
}
}
/**
* Like setblock, but lacks the data != 0 check
* @param x
* @param y
* @param z
* @param data
*/
public void setBlockAbs(int x, int y, int z, byte data) {
world.getBlockAt(X + x, y, Z + z).setData(data);
}
/**
* check if a region contains a location. (x, z) must be between [0,15], [0,15]
* @param plot
* @param x
* @param z
* @return
*/
public boolean contains(final RegionWrapper plot, final int x, final int z) {
int xx = X + x;
int zz = Z + z;
return ((xx >= plot.minX) && (xx <= plot.maxX) && (zz >= plot.minZ) && (zz <= plot.maxZ));
}
}

View File

@ -0,0 +1,80 @@
package com.plotsquared.bukkit.object.comment;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.concurrent.atomic.AtomicInteger;
import com.intellectualcrafters.plot.object.comment.*;
import org.bukkit.ChatColor;
import com.intellectualcrafters.plot.config.C;
import com.intellectualcrafters.plot.config.Settings;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.object.RunnableVal;
import com.plotsquared.bukkit.titles.AbstractTitle;
import com.intellectualcrafters.plot.util.TaskManager;
public class CommentManager {
public static HashMap<String, CommentInbox> inboxes = new HashMap<>();
public static void sendTitle(final PlotPlayer player, final Plot plot) {
if (!Settings.COMMENT_NOTIFICATIONS) {
return;
}
if (!plot.isOwner(player.getUUID())) {
return;
}
TaskManager.runTaskLaterAsync(new Runnable() {
@Override
public void run() {
Collection<CommentInbox> boxes = CommentManager.inboxes.values();
final AtomicInteger count = new AtomicInteger(0);
final AtomicInteger size = new AtomicInteger(boxes.size());
for (final CommentInbox inbox : inboxes.values()) {
inbox.getComments(plot, new RunnableVal() {
@Override
public void run() {
int total;
if (value != null) {
int num = 0;
for (PlotComment comment : (ArrayList<PlotComment>) value) {
if (comment.timestamp > getTimestamp(player, inbox.toString())) {
num++;
}
}
total = count.addAndGet(num);
}
else {
total = count.get();
}
if (size.decrementAndGet() == 0 && total > 0) {
AbstractTitle.sendTitle(player, "", C.INBOX_NOTIFICATION.s().replaceAll("%s", "" + total), ChatColor.GOLD, ChatColor.valueOf(C.TITLE_ENTERED_PLOT_SUB_COLOR.s()));
}
}
});
}
}
}, 20);
}
public static long getTimestamp(PlotPlayer player, String inbox) {
Object meta = player.getMeta("inbox:"+inbox);
if (meta == null) {
return player.getPreviousLogin();
}
return (Long) meta;
}
public static void addInbox(CommentInbox inbox) {
inboxes.put(inbox.toString().toLowerCase(), inbox);
}
public static void registerDefaultInboxes() {
addInbox(new InboxReport());
addInbox(new InboxPublic());
addInbox(new InboxOwner());
}
}

View File

@ -0,0 +1,665 @@
package com.plotsquared.bukkit.object.entity;
import com.intellectualcrafters.plot.object.entity.AgeableStats;
import com.intellectualcrafters.plot.object.entity.ArmorStandStats;
import com.intellectualcrafters.plot.object.entity.EntityBaseStats;
import com.intellectualcrafters.plot.object.entity.HorseStats;
import org.bukkit.Art;
import org.bukkit.DyeColor;
import org.bukkit.Location;
import org.bukkit.Rotation;
import org.bukkit.World;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Ageable;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Guardian;
import org.bukkit.entity.Horse;
import org.bukkit.entity.Horse.Color;
import org.bukkit.entity.Horse.Style;
import org.bukkit.entity.Horse.Variant;
import org.bukkit.entity.Item;
import org.bukkit.entity.ItemFrame;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Painting;
import org.bukkit.entity.Rabbit;
import org.bukkit.entity.Rabbit.Type;
import org.bukkit.entity.Sheep;
import org.bukkit.entity.Skeleton;
import org.bukkit.entity.Skeleton.SkeletonType;
import org.bukkit.entity.Tameable;
import org.bukkit.inventory.EntityEquipment;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.EulerAngle;
import org.bukkit.util.Vector;
import com.intellectualcrafters.plot.PS;
public class EntityWrapper {
public short id;
public float yaw;
public float pitch;
public double x;
public double y;
public double z;
public short depth;
public EntityBaseStats base = null;
// Extended
public ItemStack stack;
public ItemStack[] inventory;
public byte dataByte;
public byte dataByte2;
public String dataString;
public LivingEntityStats lived;
public AgeableStats aged;
public TameableStats tamed;
private HorseStats horse;
private ArmorStandStats stand;
public void storeInventory(final InventoryHolder held) {
this.inventory = held.getInventory().getContents().clone();
}
private void restoreLiving(final LivingEntity entity) {
if (this.lived.loot) {
entity.setCanPickupItems(this.lived.loot);
}
if (this.lived.name != null) {
entity.setCustomName(this.lived.name);
entity.setCustomNameVisible(this.lived.visible);
}
if ((this.lived.potions != null) && (this.lived.potions.size() > 0)) {
entity.addPotionEffects(this.lived.potions);
}
entity.setRemainingAir(this.lived.air);
entity.setRemoveWhenFarAway(this.lived.persistent);
if (this.lived.equipped) {
final EntityEquipment equipment = entity.getEquipment();
equipment.setItemInHand(this.lived.hands);
equipment.setHelmet(this.lived.helmet);
equipment.setChestplate(this.lived.chestplate);
equipment.setLeggings(this.lived.leggings);
equipment.setBoots(this.lived.boots);
}
if (this.lived.leashed) {
// TODO leashes
// World world = entity.getWorld();
// Entity leash = world.spawnEntity(new Location(world, Math.floor(x) + lived.leash_x, Math.floor(y) + lived.leash_y, Math.floor(z) + lived.leash_z), EntityType.LEASH_HITCH);
// entity.setLeashHolder(leash);
}
}
private void restoreInventory(final InventoryHolder entity) {
entity.getInventory().setContents(this.inventory);
}
public void storeLiving(final LivingEntity lived) {
this.lived = new LivingEntityStats();
this.lived.potions = lived.getActivePotionEffects();
this.lived.loot = lived.getCanPickupItems();
this.lived.name = lived.getCustomName();
this.lived.visible = lived.isCustomNameVisible();
this.lived.health = (float) lived.getHealth();
this.lived.air = (short) lived.getRemainingAir();
this.lived.persistent = lived.getRemoveWhenFarAway();
this.lived.leashed = lived.isLeashed();
if (this.lived.leashed) {
final Location loc = lived.getLeashHolder().getLocation();
this.lived.leash_x = (short) (this.x - loc.getBlockX());
this.lived.leash_y = (short) (this.y - loc.getBlockY());
this.lived.leash_z = (short) (this.z - loc.getBlockZ());
}
final EntityEquipment equipment = lived.getEquipment();
this.lived.equipped = equipment != null;
if (this.lived.equipped) {
this.lived.hands = equipment.getItemInHand().clone();
this.lived.boots = equipment.getBoots().clone();
this.lived.leggings = equipment.getLeggings().clone();
this.lived.chestplate = equipment.getChestplate().clone();
this.lived.helmet = equipment.getHelmet().clone();
}
}
private void restoreTameable(final Tameable entity) {
if (this.tamed.tamed) {
if (this.tamed.owner != null) {
entity.setTamed(true);
entity.setOwner(this.tamed.owner);
}
}
}
private void restoreAgeable(final Ageable entity) {
if (!this.aged.adult) {
entity.setBaby();
}
if (this.aged.locked) {
entity.setAgeLock(this.aged.locked);
}
entity.setAge(this.aged.age);
}
public void storeAgeable(final Ageable aged) {
this.aged = new AgeableStats();
this.aged.age = aged.getAge();
this.aged.locked = aged.getAgeLock();
this.aged.adult = aged.isAdult();
}
public void storeTameable(final Tameable tamed) {
this.tamed = new TameableStats();
this.tamed.owner = tamed.getOwner();
this.tamed.tamed = tamed.isTamed();
}
@SuppressWarnings("deprecation")
public EntityWrapper(final org.bukkit.entity.Entity entity, final short depth) {
this.depth = depth;
final Location loc = entity.getLocation();
this.yaw = loc.getYaw();
this.pitch = loc.getPitch();
this.x = loc.getX();
this.y = loc.getY();
this.z = loc.getZ();
this.id = entity.getType().getTypeId();
if (depth == 0) {
return;
}
this.base = new EntityBaseStats();
final Entity p = entity.getPassenger();
if (p != null) {
this.base.passenger = new EntityWrapper(p, depth);
}
this.base.fall = entity.getFallDistance();
this.base.fire = (short) entity.getFireTicks();
this.base.age = entity.getTicksLived();
final Vector velocity = entity.getVelocity();
this.base.v_x = velocity.getX();
this.base.v_y = velocity.getY();
this.base.v_z = velocity.getZ();
if (depth == 1) {
return;
}
switch (entity.getType()) {
case ARROW:
case BOAT:
case COMPLEX_PART:
case EGG:
case ENDER_CRYSTAL:
case ENDER_PEARL:
case ENDER_SIGNAL:
case EXPERIENCE_ORB:
case FALLING_BLOCK:
case FIREBALL:
case FIREWORK:
case FISHING_HOOK:
case LEASH_HITCH:
case LIGHTNING:
case MINECART:
case MINECART_COMMAND:
case MINECART_MOB_SPAWNER:
case MINECART_TNT:
case PLAYER:
case PRIMED_TNT:
case SLIME:
case SMALL_FIREBALL:
case SNOWBALL:
case MINECART_FURNACE:
case SPLASH_POTION:
case THROWN_EXP_BOTTLE:
case WEATHER:
case WITHER_SKULL:
case UNKNOWN: {
// Do this stuff later
return;
}
default: {
PS.log("&cCOULD NOT IDENTIFY ENTITY: " + entity.getType());
return;
}
// MISC //
case DROPPED_ITEM: {
final Item item = (Item) entity;
this.stack = item.getItemStack();
return;
}
case ITEM_FRAME: {
final ItemFrame itemframe = (ItemFrame) entity;
this.x = Math.floor(this.x);
this.y = Math.floor(this.y);
this.z = Math.floor(this.z);
this.dataByte = getOrdinal(Rotation.values(), itemframe.getRotation());
this.stack = itemframe.getItem().clone();
return;
}
case PAINTING: {
final Painting painting = (Painting) entity;
this.x = Math.floor(this.x);
this.y = Math.floor(this.y);
this.z = Math.floor(this.z);
final Art a = painting.getArt();
this.dataByte = getOrdinal(BlockFace.values(), painting.getFacing());
final int h = a.getBlockHeight();
if ((h % 2) == 0) {
this.y -= 1;
}
this.dataString = a.name();
return;
}
// END MISC //
// INVENTORY HOLDER //
case MINECART_CHEST: {
storeInventory((InventoryHolder) entity);
return;
}
case MINECART_HOPPER: {
storeInventory((InventoryHolder) entity);
return;
}
// START LIVING ENTITY //
// START AGEABLE //
// START TAMEABLE //
case HORSE: {
final Horse horse = (Horse) entity;
this.horse = new HorseStats();
this.horse.jump = horse.getJumpStrength();
this.horse.chest = horse.isCarryingChest();
this.horse.variant = getOrdinal(Variant.values(), horse.getVariant());
this.horse.style = getOrdinal(Style.values(), horse.getStyle());
this.horse.color = getOrdinal(Color.values(), horse.getColor());
storeTameable((Tameable) entity);
storeAgeable((Ageable) entity);
storeLiving((LivingEntity) entity);
storeInventory((InventoryHolder) entity);
return;
}
// END INVENTORY HOLDER //
case WOLF:
case OCELOT: {
storeTameable((Tameable) entity);
storeAgeable((Ageable) entity);
storeLiving((LivingEntity) entity);
return;
}
// END AMEABLE //
case SHEEP: {
final Sheep sheep = (Sheep) entity;
this.dataByte = (byte) ((sheep).isSheared() ? 1 : 0);
this.dataByte2 = sheep.getColor().getDyeData();
storeAgeable((Ageable) entity);
storeLiving((LivingEntity) entity);
return;
}
case VILLAGER:
case CHICKEN:
case COW:
case MUSHROOM_COW:
case PIG: {
storeAgeable((Ageable) entity);
storeLiving((LivingEntity) entity);
return;
}
// END AGEABLE //
case RABBIT: { // NEW
this.dataByte = getOrdinal(Type.values(), ((Rabbit) entity).getRabbitType());
storeAgeable((Ageable) entity);
storeLiving((LivingEntity) entity);
return;
}
case GUARDIAN: { // NEW
this.dataByte = (byte) (((Guardian) entity).isElder() ? 1 : 0);
storeLiving((LivingEntity) entity);
return;
}
case SKELETON: { // NEW
this.dataByte = (byte) ((Skeleton) entity).getSkeletonType().getId();
storeLiving((LivingEntity) entity);
return;
}
case ARMOR_STAND: { // NEW
// CHECK positions
final ArmorStand stand = (ArmorStand) entity;
this.inventory = new ItemStack[] { stand.getItemInHand().clone(), stand.getHelmet().clone(), stand.getChestplate().clone(), stand.getLeggings().clone(), stand.getBoots().clone() };
storeLiving((LivingEntity) entity);
this.stand = new ArmorStandStats();
EulerAngle head = stand.getHeadPose();
this.stand.head[0] = (float) head.getX();
this.stand.head[1] = (float) head.getY();
this.stand.head[2] = (float) head.getZ();
EulerAngle body = stand.getBodyPose();
this.stand.body[0] = (float) body.getX();
this.stand.body[1] = (float) body.getY();
this.stand.body[2] = (float) body.getZ();
EulerAngle leftLeg = stand.getLeftLegPose();
this.stand.leftLeg[0] = (float) leftLeg.getX();
this.stand.leftLeg[1] = (float) leftLeg.getY();
this.stand.leftLeg[2] = (float) leftLeg.getZ();
EulerAngle rightLeg = stand.getRightLegPose();
this.stand.rightLeg[0] = (float) rightLeg.getX();
this.stand.rightLeg[1] = (float) rightLeg.getY();
this.stand.rightLeg[2] = (float) rightLeg.getZ();
EulerAngle leftArm = stand.getLeftArmPose();
this.stand.leftArm[0] = (float) leftArm.getX();
this.stand.leftArm[1] = (float) leftArm.getY();
this.stand.leftArm[2] = (float) leftArm.getZ();
EulerAngle rightArm = stand.getRightArmPose();
this.stand.rightArm[0] = (float) rightArm.getX();
this.stand.rightArm[1] = (float) rightArm.getY();
this.stand.rightArm[2] = (float) rightArm.getZ();
if (stand.hasArms()) {
this.stand.arms = true;
}
if (!stand.hasBasePlate()) {
this.stand.noplate = true;
}
if (!stand.hasGravity()) {
this.stand.nogravity = true;
}
if (!stand.isVisible()) {
this.stand.invisible = true;
}
if (stand.isSmall()) {
this.stand.small = true;
}
return;
}
case ENDERMITE: // NEW
case BAT:
case ENDER_DRAGON:
case GHAST:
case MAGMA_CUBE:
case SQUID:
case PIG_ZOMBIE:
case ZOMBIE:
case WITHER:
case WITCH:
case SPIDER:
case CAVE_SPIDER:
case SILVERFISH:
case GIANT:
case ENDERMAN:
case CREEPER:
case BLAZE:
case SNOWMAN:
case IRON_GOLEM: {
storeLiving((LivingEntity) entity);
return;
}
// END LIVING //
}
}
@SuppressWarnings("deprecation")
public Entity spawn(final World world, final int x_offset, final int z_offset) {
final Location loc = new Location(world, this.x + x_offset, this.y, this.z + z_offset);
loc.setYaw(this.yaw);
loc.setPitch(this.pitch);
if (this.id == -1) {
return null;
}
final EntityType type = EntityType.fromId(this.id);
Entity entity;
switch (type) {
case DROPPED_ITEM: {
return world.dropItem(loc, this.stack);
}
case PLAYER:
case LEASH_HITCH: {
return null;
}
default:
entity = world.spawnEntity(loc, type);
break;
}
if (this.depth == 0) {
return entity;
}
if (this.base.passenger != null) {
try {
entity.setPassenger(this.base.passenger.spawn(world, x_offset, z_offset));
} catch (final Exception e) {
}
}
entity.setFallDistance(this.base.fall);
entity.setFireTicks(this.base.fire);
entity.setTicksLived(this.base.age);
entity.setVelocity(new Vector(this.base.v_x, this.base.v_y, this.base.v_z));
if (this.depth == 1) {
return entity;
}
switch (entity.getType()) {
case ARROW:
case BOAT:
case COMPLEX_PART:
case EGG:
case ENDER_CRYSTAL:
case ENDER_PEARL:
case ENDER_SIGNAL:
case EXPERIENCE_ORB:
case FALLING_BLOCK:
case FIREBALL:
case FIREWORK:
case FISHING_HOOK:
case LEASH_HITCH:
case LIGHTNING:
case MINECART:
case MINECART_COMMAND:
case MINECART_MOB_SPAWNER:
case MINECART_TNT:
case PLAYER:
case PRIMED_TNT:
case SLIME:
case SMALL_FIREBALL:
case SNOWBALL:
case SPLASH_POTION:
case THROWN_EXP_BOTTLE:
case WEATHER:
case WITHER_SKULL:
case MINECART_FURNACE:
case UNKNOWN: {
// Do this stuff later
return entity;
}
default: {
PS.log("&cCOULD NOT IDENTIFY ENTITY: " + entity.getType());
return entity;
}
// MISC //
case ITEM_FRAME: {
final ItemFrame itemframe = (ItemFrame) entity;
itemframe.setRotation(Rotation.values()[this.dataByte]);
itemframe.setItem(this.stack);
return entity;
}
case PAINTING: {
final Painting painting = (Painting) entity;
painting.setFacingDirection(BlockFace.values()[this.dataByte], true);
painting.setArt(Art.getByName(this.dataString), true);
return entity;
}
// END MISC //
// INVENTORY HOLDER //
case MINECART_CHEST: {
restoreInventory((InventoryHolder) entity);
return entity;
}
case MINECART_HOPPER: {
restoreInventory((InventoryHolder) entity);
return entity;
}
// START LIVING ENTITY //
// START AGEABLE //
// START TAMEABLE //
case HORSE: {
final Horse horse = (Horse) entity;
horse.setJumpStrength(this.horse.jump);
horse.setCarryingChest(this.horse.chest);
horse.setVariant(Variant.values()[this.horse.variant]);
horse.setStyle(Style.values()[this.horse.style]);
horse.setColor(Color.values()[this.horse.color]);
restoreTameable((Tameable) entity);
restoreAgeable((Ageable) entity);
restoreLiving((LivingEntity) entity);
restoreInventory((InventoryHolder) entity);
return entity;
}
// END INVENTORY HOLDER //
case WOLF:
case OCELOT: {
restoreTameable((Tameable) entity);
restoreAgeable((Ageable) entity);
restoreLiving((LivingEntity) entity);
return entity;
}
// END AMEABLE //
case SHEEP: {
final Sheep sheep = (Sheep) entity;
if (this.dataByte == 1) {
sheep.setSheared(true);
}
if (this.dataByte2 != 0) {
sheep.setColor(DyeColor.getByDyeData(this.dataByte2));
}
restoreAgeable((Ageable) entity);
restoreLiving((LivingEntity) entity);
return entity;
}
case VILLAGER:
case CHICKEN:
case COW:
case MUSHROOM_COW:
case PIG: {
restoreAgeable((Ageable) entity);
restoreLiving((LivingEntity) entity);
return entity;
}
// END AGEABLE //
case RABBIT: { // NEW
if (this.dataByte != 0) {
((Rabbit) entity).setRabbitType(Type.values()[this.dataByte]);
}
restoreAgeable((Ageable) entity);
restoreLiving((LivingEntity) entity);
return entity;
}
case GUARDIAN: { // NEW
if (this.dataByte != 0) {
((Guardian) entity).setElder(true);
}
restoreLiving((LivingEntity) entity);
return entity;
}
case SKELETON: { // NEW
if (this.dataByte != 0) {
((Skeleton) entity).setSkeletonType(SkeletonType.values()[this.dataByte]);
}
storeLiving((LivingEntity) entity);
return entity;
}
case ARMOR_STAND: { // NEW
// CHECK positions
final ArmorStand stand = (ArmorStand) entity;
if (this.inventory[0] != null) {
stand.setItemInHand(this.inventory[0]);
}
if (this.inventory[1] != null) {
stand.setHelmet(this.inventory[1]);
}
if (this.inventory[2] != null) {
stand.setChestplate(this.inventory[2]);
}
if (this.inventory[3] != null) {
stand.setLeggings(this.inventory[3]);
}
if (this.inventory[4] != null) {
stand.setBoots(this.inventory[4]);
}
if (this.stand.head[0] != 0 || this.stand.head[1] != 0 || this.stand.head[2] != 0) {
EulerAngle pose = new EulerAngle(this.stand.head[0], this.stand.head[1], this.stand.head[2]);
stand.setHeadPose(pose);
}
if (this.stand.body[0] != 0 || this.stand.body[1] != 0 || this.stand.body[2] != 0) {
EulerAngle pose = new EulerAngle(this.stand.body[0], this.stand.body[1], this.stand.body[2]);
stand.setBodyPose(pose);
}
if (this.stand.leftLeg[0] != 0 || this.stand.leftLeg[1] != 0 || this.stand.leftLeg[2] != 0) {
EulerAngle pose = new EulerAngle(this.stand.leftLeg[0], this.stand.leftLeg[1], this.stand.leftLeg[2]);
stand.setLeftLegPose(pose);
}
if (this.stand.rightLeg[0] != 0 || this.stand.rightLeg[1] != 0 || this.stand.rightLeg[2] != 0) {
EulerAngle pose = new EulerAngle(this.stand.rightLeg[0], this.stand.rightLeg[1], this.stand.rightLeg[2]);
stand.setRightLegPose(pose);
}
if (this.stand.leftArm[0] != 0 || this.stand.leftArm[1] != 0 || this.stand.leftArm[2] != 0) {
EulerAngle pose = new EulerAngle(this.stand.leftArm[0], this.stand.leftArm[1], this.stand.leftArm[2]);
stand.setLeftArmPose(pose);
}
if (this.stand.rightArm[0] != 0 || this.stand.rightArm[1] != 0 || this.stand.rightArm[2] != 0) {
EulerAngle pose = new EulerAngle(this.stand.rightArm[0], this.stand.rightArm[1], this.stand.rightArm[2]);
stand.setRightArmPose(pose);
}
if (this.stand.invisible) {
stand.setVisible(false);
}
if (this.stand.arms) {
stand.setArms(true);
}
if (this.stand.nogravity) {
stand.setGravity(false);
}
if (this.stand.noplate) {
stand.setBasePlate(false);
}
if (this.stand.small) {
stand.setSmall(true);
}
restoreLiving((LivingEntity) entity);
return entity;
}
case ENDERMITE: // NEW
case BAT:
case ENDER_DRAGON:
case GHAST:
case MAGMA_CUBE:
case SQUID:
case PIG_ZOMBIE:
case ZOMBIE:
case WITHER:
case WITCH:
case SPIDER:
case CAVE_SPIDER:
case SILVERFISH:
case GIANT:
case ENDERMAN:
case CREEPER:
case BLAZE:
case SNOWMAN:
case IRON_GOLEM: {
restoreLiving((LivingEntity) entity);
return entity;
}
// END LIVING //
}
}
private byte getOrdinal(final Object[] list, final Object value) {
for (byte i = 0; i < list.length; i++) {
if (list[i].equals(value)) {
return i;
}
}
return 0;
}
}

View File

@ -0,0 +1,26 @@
package com.plotsquared.bukkit.object.entity;
import java.util.Collection;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
public class LivingEntityStats {
public boolean loot;
public String name;
public boolean visible;
public float health;
public short air;
public boolean persistent;
public boolean leashed;
public short leash_x;
public short leash_y;
public short leash_z;
public boolean equipped;
public ItemStack hands;
public ItemStack helmet;
public ItemStack boots;
public ItemStack leggings;
public ItemStack chestplate;
public Collection<PotionEffect> potions;
}

View File

@ -0,0 +1,8 @@
package com.plotsquared.bukkit.object.entity;
import org.bukkit.entity.AnimalTamer;
public class TameableStats {
public AnimalTamer owner;
public boolean tamed;
}

View File

@ -0,0 +1,114 @@
package com.plotsquared.bukkit.object.schematic;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import com.intellectualcrafters.plot.object.schematic.ItemType;
import com.intellectualcrafters.plot.object.schematic.PlotItem;
import org.apache.commons.lang.StringUtils;
import org.bukkit.block.BlockState;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import com.intellectualcrafters.jnbt.ByteTag;
import com.intellectualcrafters.jnbt.CompoundTag;
import com.intellectualcrafters.jnbt.ListTag;
import com.intellectualcrafters.jnbt.ShortTag;
import com.intellectualcrafters.jnbt.Tag;
import com.intellectualcrafters.plot.util.SchematicHandler.Schematic;
public class StateWrapper {
public BlockState state = null;
public CompoundTag tag = null;
public StateWrapper(BlockState state) {
this.state = state;
}
public StateWrapper(CompoundTag tag) {
this.tag = tag;
}
public boolean restoreTag(short x, short y, short z, Schematic schematic) {
if (this.tag == null) {
return false;
}
List<Tag> itemsTag = this.tag.getListTag("Items").getValue();
int length = itemsTag.size();
short[] ids = new short[length];
byte[] datas = new byte[length];
byte[] amounts = new byte[length];
for (int i = 0; i < length; i++) {
Tag itemTag = itemsTag.get(i);
CompoundTag itemComp = (CompoundTag) itemTag;
short id = itemComp.getShort("id");
String idStr = itemComp.getString("id");
if (!StringUtils.isNumeric(idStr) && idStr != null) {
idStr = idStr.split(":")[1].toLowerCase();
id = (short) ItemType.getId(idStr);
}
ids[i] = id;
datas[i] = (byte) itemComp.getShort("Damage");
amounts[i] = itemComp.getByte("Count");
}
if (length != 0) {
schematic.addItem(new PlotItem(x, y, z, ids, datas, amounts));
}
return true;
}
public CompoundTag getTag() {
if (this.tag != null) {
return this.tag;
}
if (state instanceof InventoryHolder) {
InventoryHolder inv = (InventoryHolder) state;
ItemStack[] contents = inv.getInventory().getContents();
Map<String, Tag> values = new HashMap<String, Tag>();
values.put("Items", new ListTag("Items", CompoundTag.class, serializeInventory(contents)));
return new CompoundTag(values);
}
return null;
}
public String getId() {
return "Chest";
}
public List<CompoundTag> serializeInventory(ItemStack[] items) {
List<CompoundTag> tags = new ArrayList<CompoundTag>();
for (int i = 0; i < items.length; ++i) {
if (items[i] != null) {
Map<String, Tag> tagData = serializeItem(items[i]);
tagData.put("Slot", new ByteTag("Slot", (byte) i));
tags.add(new CompoundTag(tagData));
}
}
return tags;
}
public Map<String, Tag> serializeItem(ItemStack item) {
Map<String, Tag> data = new HashMap<String, Tag>();
data.put("id", new ShortTag("id", (short) item.getTypeId()));
data.put("Damage", new ShortTag("Damage", item.getDurability()));
data.put("Count", new ByteTag("Count", (byte) item.getAmount()));
if (!item.getEnchantments().isEmpty()) {
List<CompoundTag> enchantmentList = new ArrayList<CompoundTag>();
for(Entry<Enchantment, Integer> entry : item.getEnchantments().entrySet()) {
Map<String, Tag> enchantment = new HashMap<String, Tag>();
enchantment.put("id", new ShortTag("id", (short) entry.getKey().getId()));
enchantment.put("lvl", new ShortTag("lvl", entry.getValue().shortValue()));
enchantmentList.add(new CompoundTag(enchantment));
}
Map<String, Tag> auxData = new HashMap<String, Tag>();
auxData.put("ench", new ListTag("ench", CompoundTag.class, enchantmentList));
data.put("tag", new CompoundTag("tag", auxData));
}
return data;
}
}

View File

@ -0,0 +1,17 @@
package com.plotsquared.bukkit.titles;
import org.bukkit.ChatColor;
import com.intellectualcrafters.plot.object.PlotPlayer;
public abstract class AbstractTitle {
public static AbstractTitle TITLE_CLASS;
public static void sendTitle(PlotPlayer player, String head, String sub, ChatColor head_color, ChatColor sub_color) {
if (TITLE_CLASS != null && !player.getAttribute("disabletitles")) {
TITLE_CLASS.sendTitle(player, head, sub, head_color, sub_color, 1, 2, 1);
}
}
public abstract void sendTitle(PlotPlayer player, String head, String sub, ChatColor head_color, ChatColor sub_color, int in, int delay, int out);
}

View File

@ -0,0 +1,21 @@
package com.plotsquared.bukkit.titles;
import org.bukkit.ChatColor;
import com.plotsquared.bukkit.object.BukkitPlayer;
import com.intellectualcrafters.plot.object.PlotPlayer;
public class DefaultTitle extends AbstractTitle {
@Override
public void sendTitle(final PlotPlayer player, final String head, final String sub, final ChatColor head_color, final ChatColor sub_color, int in, int delay, int out) {
try {
final DefaultTitleManager title = new DefaultTitleManager(head, sub, in, delay, out);
title.setTitleColor(head_color);
title.setSubtitleColor(sub_color);
title.send(((BukkitPlayer) player).player);
} catch (final Throwable e) {
AbstractTitle.TITLE_CLASS = new DefaultTitle_183();
AbstractTitle.TITLE_CLASS.sendTitle(player, head, sub, head_color, sub_color, in, delay, out);
}
}
}

View File

@ -0,0 +1,397 @@
package com.plotsquared.bukkit.titles;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
/**
* [ PlotSquared DefaultTitleManager by Maxim Van de Wynckel ]
*
* @version 1.1.0
* @author Maxim Van de Wynckel
*
*/
public class DefaultTitleManager {
/* Title packet */
private Class<?> packetTitle;
/* Title packet actions ENUM */
private Class<?> packetActions;
/* Chat serializer */
private Class<?> nmsChatSerializer;
private Class<?> chatBaseComponent;
/* Title text and color */
private String title = "";
private ChatColor titleColor = ChatColor.WHITE;
/* Subtitle text and color */
private String subtitle = "";
private ChatColor subtitleColor = ChatColor.WHITE;
/* Title timings */
private int fadeInTime = -1;
private int stayTime = -1;
private int fadeOutTime = -1;
private boolean ticks = false;
private static final Map<Class<?>, Class<?>> CORRESPONDING_TYPES = new HashMap<Class<?>, Class<?>>();
/**
* Create a new 1.8 title
*
* @param title
* Title
* @throws ClassNotFoundException
*/
public DefaultTitleManager(final String title) throws ClassNotFoundException {
this.title = title;
loadClasses();
}
/**
* Create a new 1.8 title
*
* @param title
* Title text
* @param subtitle
* Subtitle text
* @throws ClassNotFoundException
*/
public DefaultTitleManager(final String title, final String subtitle) throws ClassNotFoundException {
this.title = title;
this.subtitle = subtitle;
loadClasses();
}
/**
* Copy 1.8 title
*
* @param title
* Title
* @throws ClassNotFoundException
*/
public DefaultTitleManager(final DefaultTitleManager title) throws ClassNotFoundException {
// Copy title
this.title = title.title;
this.subtitle = title.subtitle;
this.titleColor = title.titleColor;
this.subtitleColor = title.subtitleColor;
this.fadeInTime = title.fadeInTime;
this.fadeOutTime = title.fadeOutTime;
this.stayTime = title.stayTime;
this.ticks = title.ticks;
loadClasses();
}
/**
* Create a new 1.8 title
*
* @param title
* Title text
* @param subtitle
* Subtitle text
* @param fadeInTime
* Fade in time
* @param stayTime
* Stay on screen time
* @param fadeOutTime
* Fade out time
* @throws ClassNotFoundException
*/
public DefaultTitleManager(final String title, final String subtitle, final int fadeInTime, final int stayTime, final int fadeOutTime) throws ClassNotFoundException {
this.title = title;
this.subtitle = subtitle;
this.fadeInTime = fadeInTime;
this.stayTime = stayTime;
this.fadeOutTime = fadeOutTime;
loadClasses();
}
/**
* Load spigot and NMS classes
* @throws ClassNotFoundException
*/
private void loadClasses() throws ClassNotFoundException {
this.packetTitle = getNMSClass("PacketPlayOutTitle");
this.packetActions = getNMSClass("EnumTitleAction");
this.chatBaseComponent = getNMSClass("IChatBaseComponent");
this.nmsChatSerializer = getNMSClass("ChatSerializer");
}
/**
* Set title text
*
* @param title
* Title
*/
public void setTitle(final String title) {
this.title = title;
}
/**
* Get title text
*
* @return Title text
*/
public String getTitle() {
return this.title;
}
/**
* Set subtitle text
*
* @param subtitle
* Subtitle text
*/
public void setSubtitle(final String subtitle) {
this.subtitle = subtitle;
}
/**
* Get subtitle text
*
* @return Subtitle text
*/
public String getSubtitle() {
return this.subtitle;
}
/**
* Set the title color
*
* @param color
* Chat color
*/
public void setTitleColor(final ChatColor color) {
this.titleColor = color;
}
/**
* Set the subtitle color
*
* @param color
* Chat color
*/
public void setSubtitleColor(final ChatColor color) {
this.subtitleColor = color;
}
/**
* Set title fade in time
*
* @param time
* Time
*/
public void setFadeInTime(final int time) {
this.fadeInTime = time;
}
/**
* Set title fade out time
*
* @param time
* Time
*/
public void setFadeOutTime(final int time) {
this.fadeOutTime = time;
}
/**
* Set title stay time
*
* @param time
* Time
*/
public void setStayTime(final int time) {
this.stayTime = time;
}
/**
* Set timings to ticks
*/
public void setTimingsToTicks() {
this.ticks = true;
}
/**
* Set timings to seconds
*/
public void setTimingsToSeconds() {
this.ticks = false;
}
/**
* Send the title to a player
*
* @param player
* Player
* @throws InvocationTargetException
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/
public void send(final Player player) throws Exception {
if (this.packetTitle != null) {
// First reset previous settings
resetTitle(player);
// Send timings first
final Object handle = getHandle(player);
final Object connection = getField(handle.getClass(), "playerConnection").get(handle);
final Object[] actions = this.packetActions.getEnumConstants();
final Method sendPacket = getMethod(connection.getClass(), "sendPacket");
Object packet = this.packetTitle.getConstructor(this.packetActions, this.chatBaseComponent, Integer.TYPE, Integer.TYPE, Integer.TYPE).newInstance(actions[2], null, this.fadeInTime * (this.ticks ? 1 : 20), this.stayTime * (this.ticks ? 1 : 20), this.fadeOutTime * (this.ticks ? 1 : 20));
// Send if set
if ((this.fadeInTime != -1) && (this.fadeOutTime != -1) && (this.stayTime != -1)) {
sendPacket.invoke(connection, packet);
}
// Send title
Object serialized = getMethod(this.nmsChatSerializer, "a", String.class).invoke(null, "{text:\"" + ChatColor.translateAlternateColorCodes('&', this.title) + "\",color:" + this.titleColor.name().toLowerCase() + "}");
packet = this.packetTitle.getConstructor(this.packetActions, this.chatBaseComponent).newInstance(actions[0], serialized);
sendPacket.invoke(connection, packet);
if (this.subtitle != "") {
// Send subtitle if present
serialized = getMethod(this.nmsChatSerializer, "a", String.class).invoke(null, "{text:\"" + ChatColor.translateAlternateColorCodes('&', this.subtitle) + "\",color:" + this.subtitleColor.name().toLowerCase() + "}");
packet = this.packetTitle.getConstructor(this.packetActions, this.chatBaseComponent).newInstance(actions[1], serialized);
sendPacket.invoke(connection, packet);
}
}
}
/**
* Broadcast the title to all players
* @throws Exception
*/
public void broadcast() throws Exception {
for (final Player p : Bukkit.getOnlinePlayers()) {
send(p);
}
}
/**
* Clear the title
*
* @param player
* Player
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
public void clearTitle(final Player player) throws Exception {
// Send timings first
final Object handle = getHandle(player);
final Object connection = getField(handle.getClass(), "playerConnection").get(handle);
final Object[] actions = this.packetActions.getEnumConstants();
final Method sendPacket = getMethod(connection.getClass(), "sendPacket");
final Object packet = this.packetTitle.getConstructor(this.packetActions, this.chatBaseComponent).newInstance(actions[3], null);
sendPacket.invoke(connection, packet);
}
/**
* Reset the title settings
*
* @param player
* Player
*/
public void resetTitle(final Player player) throws Exception {
// Send timings first
final Object handle = getHandle(player);
final Object connection = getField(handle.getClass(), "playerConnection").get(handle);
final Object[] actions = this.packetActions.getEnumConstants();
final Method sendPacket = getMethod(connection.getClass(), "sendPacket");
final Object packet = this.packetTitle.getConstructor(this.packetActions, this.chatBaseComponent).newInstance(actions[4], null);
sendPacket.invoke(connection, packet);
}
private Class<?> getPrimitiveType(final Class<?> clazz) {
return CORRESPONDING_TYPES.containsKey(clazz) ? CORRESPONDING_TYPES.get(clazz) : clazz;
}
private Class<?>[] toPrimitiveTypeArray(final Class<?>[] classes) {
final int a = classes != null ? classes.length : 0;
final Class<?>[] types = new Class<?>[a];
for (int i = 0; i < a; i++) {
types[i] = getPrimitiveType(classes[i]);
}
return types;
}
private static boolean equalsTypeArray(final Class<?>[] a, final Class<?>[] o) {
if (a.length != o.length) {
return false;
}
for (int i = 0; i < a.length; i++) {
if (!a[i].equals(o[i]) && !a[i].isAssignableFrom(o[i])) {
return false;
}
}
return true;
}
private Object getHandle(final Object obj) {
try {
return getMethod("getHandle", obj.getClass()).invoke(obj);
} catch (final Exception e) {
e.printStackTrace();
return null;
}
}
private Method getMethod(final String name, final Class<?> clazz, final Class<?>... paramTypes) {
final Class<?>[] t = toPrimitiveTypeArray(paramTypes);
for (final Method m : clazz.getMethods()) {
final Class<?>[] types = toPrimitiveTypeArray(m.getParameterTypes());
if (m.getName().equals(name) && equalsTypeArray(types, t)) {
return m;
}
}
return null;
}
private String getVersion() {
final String name = Bukkit.getServer().getClass().getPackage().getName();
final String version = name.substring(name.lastIndexOf('.') + 1) + ".";
return version;
}
private Class<?> getNMSClass(final String className) throws ClassNotFoundException {
final String fullName = "net.minecraft.server." + getVersion() + className;
Class<?> clazz = null;
clazz = Class.forName(fullName);
return clazz;
}
private Field getField(final Class<?> clazz, final String name) {
try {
final Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
return field;
} catch (final Exception e) {
e.printStackTrace();
return null;
}
}
private Method getMethod(final Class<?> clazz, final String name, final Class<?>... args) {
for (final Method m : clazz.getMethods()) {
if (m.getName().equals(name) && ((args.length == 0) || ClassListEqual(args, m.getParameterTypes()))) {
m.setAccessible(true);
return m;
}
}
return null;
}
private boolean ClassListEqual(final Class<?>[] l1, final Class<?>[] l2) {
boolean equal = true;
if (l1.length != l2.length) {
return false;
}
for (int i = 0; i < l1.length; i++) {
if (l1[i] != l2[i]) {
equal = false;
break;
}
}
return equal;
}
}

View File

@ -0,0 +1,404 @@
package com.plotsquared.bukkit.titles;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
/**
* [ PlotSquared DefaultTitleManager by Maxim Van de Wynckel ]
*
* @version 1.1.0
* @author Maxim Van de Wynckel
*
*/
public class DefaultTitleManager_183 {
/* Title packet */
private Class<?> packetTitle;
/* Title packet actions ENUM */
private Class<?> packetActions;
/* Chat serializer */
private Class<?> nmsChatSerializer;
private Class<?> chatBaseComponent;
/* Title text and color */
private String title = "";
private ChatColor titleColor = ChatColor.WHITE;
/* Subtitle text and color */
private String subtitle = "";
private ChatColor subtitleColor = ChatColor.WHITE;
/* Title timings */
private int fadeInTime = -1;
private int stayTime = -1;
private int fadeOutTime = -1;
private boolean ticks = false;
private static final Map<Class<?>, Class<?>> CORRESPONDING_TYPES = new HashMap<Class<?>, Class<?>>();
/**
* Create a new 1.8 title
*
* @param title
* Title
* @throws ClassNotFoundException
*/
public DefaultTitleManager_183(final String title) throws ClassNotFoundException {
this.title = title;
loadClasses();
}
/**
* Create a new 1.8 title
*
* @param title
* Title text
* @param subtitle
* Subtitle text
* @throws ClassNotFoundException
*/
public DefaultTitleManager_183(final String title, final String subtitle) throws ClassNotFoundException {
this.title = title;
this.subtitle = subtitle;
loadClasses();
}
/**
* Copy 1.8 title
*
* @param title
* Title
* @throws ClassNotFoundException
*/
public DefaultTitleManager_183(final DefaultTitleManager_183 title) throws ClassNotFoundException {
// Copy title
this.title = title.title;
this.subtitle = title.subtitle;
this.titleColor = title.titleColor;
this.subtitleColor = title.subtitleColor;
this.fadeInTime = title.fadeInTime;
this.fadeOutTime = title.fadeOutTime;
this.stayTime = title.stayTime;
this.ticks = title.ticks;
loadClasses();
}
/**
* Create a new 1.8 title
*
* @param title
* Title text
* @param subtitle
* Subtitle text
* @param fadeInTime
* Fade in time
* @param stayTime
* Stay on screen time
* @param fadeOutTime
* Fade out time
* @throws ClassNotFoundException
*/
public DefaultTitleManager_183(final String title, final String subtitle, final int fadeInTime, final int stayTime, final int fadeOutTime) throws ClassNotFoundException {
this.title = title;
this.subtitle = subtitle;
this.fadeInTime = fadeInTime;
this.stayTime = stayTime;
this.fadeOutTime = fadeOutTime;
loadClasses();
}
/**
* Load spigot and NMS classes
* @throws ClassNotFoundException
*/
private void loadClasses() throws ClassNotFoundException {
this.packetTitle = getNMSClass("PacketPlayOutTitle");
this.chatBaseComponent = getNMSClass("IChatBaseComponent");
this.packetActions = getNMSClass("PacketPlayOutTitle$EnumTitleAction");
this.nmsChatSerializer = getNMSClass("IChatBaseComponent$ChatSerializer");
}
/**
* Set title text
*
* @param title
* Title
*/
public void setTitle(final String title) {
this.title = title;
}
/**
* Get title text
*
* @return Title text
*/
public String getTitle() {
return this.title;
}
/**
* Set subtitle text
*
* @param subtitle
* Subtitle text
*/
public void setSubtitle(final String subtitle) {
this.subtitle = subtitle;
}
/**
* Get subtitle text
*
* @return Subtitle text
*/
public String getSubtitle() {
return this.subtitle;
}
/**
* Set the title color
*
* @param color
* Chat color
*/
public void setTitleColor(final ChatColor color) {
this.titleColor = color;
}
/**
* Set the subtitle color
*
* @param color
* Chat color
*/
public void setSubtitleColor(final ChatColor color) {
this.subtitleColor = color;
}
/**
* Set title fade in time
*
* @param time
* Time
*/
public void setFadeInTime(final int time) {
this.fadeInTime = time;
}
/**
* Set title fade out time
*
* @param time
* Time
*/
public void setFadeOutTime(final int time) {
this.fadeOutTime = time;
}
/**
* Set title stay time
*
* @param time
* Time
*/
public void setStayTime(final int time) {
this.stayTime = time;
}
/**
* Set timings to ticks
*/
public void setTimingsToTicks() {
this.ticks = true;
}
/**
* Set timings to seconds
*/
public void setTimingsToSeconds() {
this.ticks = false;
}
/**
* Send the title to a player
*
* @param player
* Player
* @throws InvocationTargetException
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/
public void send(final Player player) throws Exception {
if (this.packetTitle != null) {
// First reset previous settings
resetTitle(player);
// Send timings first
final Object handle = getHandle(player);
final Object connection = getField(handle.getClass(), "playerConnection").get(handle);
final Object[] actions = this.packetActions.getEnumConstants();
final Method sendPacket = getMethod(connection.getClass(), "sendPacket");
Object packet = this.packetTitle.getConstructor(this.packetActions, this.chatBaseComponent, Integer.TYPE, Integer.TYPE, Integer.TYPE).newInstance(actions[2], null, this.fadeInTime * (this.ticks ? 1 : 20), this.stayTime * (this.ticks ? 1 : 20), this.fadeOutTime * (this.ticks ? 1 : 20));
// Send if set
if ((this.fadeInTime != -1) && (this.fadeOutTime != -1) && (this.stayTime != -1)) {
sendPacket.invoke(connection, packet);
}
// Send title
Object serialized = getMethod(this.nmsChatSerializer, "a", String.class).invoke(null, "{text:\"" + ChatColor.translateAlternateColorCodes('&', this.title) + "\",color:" + this.titleColor.name().toLowerCase() + "}");
packet = this.packetTitle.getConstructor(this.packetActions, this.chatBaseComponent).newInstance(actions[0], serialized);
sendPacket.invoke(connection, packet);
if (this.subtitle != "") {
// Send subtitle if present
serialized = getMethod(this.nmsChatSerializer, "a", String.class).invoke(null, "{text:\"" + ChatColor.translateAlternateColorCodes('&', this.subtitle) + "\",color:" + this.subtitleColor.name().toLowerCase() + "}");
packet = this.packetTitle.getConstructor(this.packetActions, this.chatBaseComponent).newInstance(actions[1], serialized);
sendPacket.invoke(connection, packet);
}
}
}
/**
* Broadcast the title to all players
* @throws Exception
*/
public void broadcast() throws Exception {
for (final Player p : Bukkit.getOnlinePlayers()) {
send(p);
}
}
/**
* Clear the title
*
* @param player
* Player
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
public void clearTitle(final Player player) throws Exception {
// Send timings first
final Object handle = getHandle(player);
final Object connection = getField(handle.getClass(), "playerConnection").get(handle);
final Object[] actions = this.packetActions.getEnumConstants();
final Method sendPacket = getMethod(connection.getClass(), "sendPacket");
final Object packet = this.packetTitle.getConstructor(this.packetActions, this.chatBaseComponent).newInstance(actions[3], null);
sendPacket.invoke(connection, packet);
}
/**
* Reset the title settings
*
* @param player
* Player
* @throws SecurityException
* @throws NoSuchMethodException
* @throws InvocationTargetException
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InstantiationException
*/
public void resetTitle(final Player player) throws Exception {
// Send timings first
final Object handle = getHandle(player);
final Object connection = getField(handle.getClass(), "playerConnection").get(handle);
final Object[] actions = this.packetActions.getEnumConstants();
final Method sendPacket = getMethod(connection.getClass(), "sendPacket");
final Object packet = this.packetTitle.getConstructor(this.packetActions, this.chatBaseComponent).newInstance(actions[4], null);
sendPacket.invoke(connection, packet);
}
private Class<?> getPrimitiveType(final Class<?> clazz) {
return CORRESPONDING_TYPES.containsKey(clazz) ? CORRESPONDING_TYPES.get(clazz) : clazz;
}
private Class<?>[] toPrimitiveTypeArray(final Class<?>[] classes) {
final int a = classes != null ? classes.length : 0;
final Class<?>[] types = new Class<?>[a];
for (int i = 0; i < a; i++) {
types[i] = getPrimitiveType(classes[i]);
}
return types;
}
private static boolean equalsTypeArray(final Class<?>[] a, final Class<?>[] o) {
if (a.length != o.length) {
return false;
}
for (int i = 0; i < a.length; i++) {
if (!a[i].equals(o[i]) && !a[i].isAssignableFrom(o[i])) {
return false;
}
}
return true;
}
private Object getHandle(final Object obj) {
try {
return getMethod("getHandle", obj.getClass()).invoke(obj);
} catch (final Exception e) {
e.printStackTrace();
return null;
}
}
private Method getMethod(final String name, final Class<?> clazz, final Class<?>... paramTypes) {
final Class<?>[] t = toPrimitiveTypeArray(paramTypes);
for (final Method m : clazz.getMethods()) {
final Class<?>[] types = toPrimitiveTypeArray(m.getParameterTypes());
if (m.getName().equals(name) && equalsTypeArray(types, t)) {
return m;
}
}
return null;
}
private String getVersion() {
final String name = Bukkit.getServer().getClass().getPackage().getName();
final String version = name.substring(name.lastIndexOf('.') + 1) + ".";
return version;
}
private Class<?> getNMSClass(final String className) throws ClassNotFoundException {
final String fullName = "net.minecraft.server." + getVersion() + className;
Class<?> clazz = null;
clazz = Class.forName(fullName);
return clazz;
}
private Field getField(final Class<?> clazz, final String name) {
try {
final Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
return field;
} catch (final Exception e) {
e.printStackTrace();
return null;
}
}
private Method getMethod(final Class<?> clazz, final String name, final Class<?>... args) {
for (final Method m : clazz.getMethods()) {
if (m.getName().equals(name) && ((args.length == 0) || ClassListEqual(args, m.getParameterTypes()))) {
m.setAccessible(true);
return m;
}
}
return null;
}
private boolean ClassListEqual(final Class<?>[] l1, final Class<?>[] l2) {
boolean equal = true;
if (l1.length != l2.length) {
return false;
}
for (int i = 0; i < l1.length; i++) {
if (l1[i] != l2[i]) {
equal = false;
break;
}
}
return equal;
}
}

View File

@ -0,0 +1,21 @@
package com.plotsquared.bukkit.titles;
import org.bukkit.ChatColor;
import com.plotsquared.bukkit.object.BukkitPlayer;
import com.intellectualcrafters.plot.object.PlotPlayer;
public class DefaultTitle_183 extends AbstractTitle {
@Override
public void sendTitle(final PlotPlayer player, final String head, final String sub, final ChatColor head_color, final ChatColor sub_color, int in, int delay, int out) {
try {
final DefaultTitleManager_183 title = new DefaultTitleManager_183(head, sub, in, delay, out);
title.setTitleColor(head_color);
title.setSubtitleColor(sub_color);
title.send(((BukkitPlayer) player).player);
} catch (final Throwable e) {
AbstractTitle.TITLE_CLASS = new HackTitle();
AbstractTitle.TITLE_CLASS.sendTitle(player, head, sub, head_color, sub_color, in, delay, out);
}
}
}

View File

@ -0,0 +1,24 @@
package com.plotsquared.bukkit.titles;
import org.bukkit.ChatColor;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.config.Settings;
import com.plotsquared.bukkit.object.BukkitPlayer;
import com.intellectualcrafters.plot.object.PlotPlayer;
public class HackTitle extends AbstractTitle {
@Override
public void sendTitle(final PlotPlayer player, final String head, final String sub, final ChatColor head_color, final ChatColor sub_color, int in, int delay, int out) {
try {
final HackTitleManager title = new HackTitleManager(head, sub, in, delay, out);
title.setTitleColor(head_color);
title.setSubtitleColor(sub_color);
title.send(((BukkitPlayer) player).player);
} catch (final Throwable e) {
PS.log("&cYour server version does not support titles!");
Settings.TITLES = false;
AbstractTitle.TITLE_CLASS = null;
}
}
}

View File

@ -0,0 +1,443 @@
package com.plotsquared.bukkit.titles;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
/**
* Minecraft 1.8 Title
*
* @version 1.0.4
* @author Maxim Van de Wynckel
*/
public class HackTitleManager {
/* Title packet */
private Class<?> packetTitle;
/* Title packet actions ENUM */
private Class<?> packetActions;
/* Chat serializer */
private Class<?> nmsChatSerializer;
/* Title text and color */
private String title = "";
private ChatColor titleColor = ChatColor.WHITE;
/* Subtitle text and color */
private String subtitle = "";
private ChatColor subtitleColor = ChatColor.WHITE;
/* Title timings */
private int fadeInTime = -1;
private int stayTime = -1;
private int fadeOutTime = -1;
private boolean ticks = false;
private static final Map<Class<?>, Class<?>> CORRESPONDING_TYPES = new HashMap<Class<?>, Class<?>>();
/**
* Create a new 1.8 title
*
* @param title
* Title
* @throws ClassNotFoundException
*/
public HackTitleManager(final String title) throws ClassNotFoundException {
this.title = title;
loadClasses();
}
/**
* Create a new 1.8 title
*
* @param title
* Title text
* @param subtitle
* Subtitle text
* @throws ClassNotFoundException
*/
public HackTitleManager(final String title, final String subtitle) throws ClassNotFoundException {
this.title = title;
this.subtitle = subtitle;
loadClasses();
}
/**
* Copy 1.8 title
*
* @param title
* Title
* @throws ClassNotFoundException
*/
public HackTitleManager(final HackTitleManager title) throws ClassNotFoundException {
// Copy title
this.title = title.title;
this.subtitle = title.subtitle;
this.titleColor = title.titleColor;
this.subtitleColor = title.subtitleColor;
this.fadeInTime = title.fadeInTime;
this.fadeOutTime = title.fadeOutTime;
this.stayTime = title.stayTime;
this.ticks = title.ticks;
loadClasses();
}
/**
* Create a new 1.8 title
*
* @param title
* Title text
* @param subtitle
* Subtitle text
* @param fadeInTime
* Fade in time
* @param stayTime
* Stay on screen time
* @param fadeOutTime
* Fade out time
* @throws ClassNotFoundException
*/
public HackTitleManager(final String title, final String subtitle, final int fadeInTime, final int stayTime, final int fadeOutTime) throws ClassNotFoundException {
this.title = title;
this.subtitle = subtitle;
this.fadeInTime = fadeInTime;
this.stayTime = stayTime;
this.fadeOutTime = fadeOutTime;
loadClasses();
}
/**
* Load spigot and NMS classes
* @throws ClassNotFoundException
*/
private void loadClasses() throws ClassNotFoundException {
this.packetTitle = getClass("org.spigotmc.ProtocolInjector$PacketTitle");
this.packetActions = getClass("org.spigotmc.ProtocolInjector$PacketTitle$Action");
this.nmsChatSerializer = getNMSClass("ChatSerializer");
}
/**
* Set title text
*
* @param title
* Title
*/
public void setTitle(final String title) {
this.title = title;
}
/**
* Get title text
*
* @return Title text
*/
public String getTitle() {
return this.title;
}
/**
* Set subtitle text
*
* @param subtitle
* Subtitle text
*/
public void setSubtitle(final String subtitle) {
this.subtitle = subtitle;
}
/**
* Get subtitle text
*
* @return Subtitle text
*/
public String getSubtitle() {
return this.subtitle;
}
/**
* Set the title color
*
* @param color
* Chat color
*/
public void setTitleColor(final ChatColor color) {
this.titleColor = color;
}
/**
* Set the subtitle color
*
* @param color
* Chat color
*/
public void setSubtitleColor(final ChatColor color) {
this.subtitleColor = color;
}
/**
* Set title fade in time
*
* @param time
* Time
*/
public void setFadeInTime(final int time) {
this.fadeInTime = time;
}
/**
* Set title fade out time
*
* @param time
* Time
*/
public void setFadeOutTime(final int time) {
this.fadeOutTime = time;
}
/**
* Set title stay time
*
* @param time
* Time
*/
public void setStayTime(final int time) {
this.stayTime = time;
}
/**
* Set timings to ticks
*/
public void setTimingsToTicks() {
this.ticks = true;
}
/**
* Set timings to seconds
*/
public void setTimingsToSeconds() {
this.ticks = false;
}
/**
* Send the title to a player
*
* @param player
* Player
*/
public void send(final Player player) throws Exception {
if ((getProtocolVersion(player) >= 47) && isSpigot() && (this.packetTitle != null)) {
// First reset previous settings
resetTitle(player);
// Send timings first
final Object handle = getHandle(player);
final Object connection = getField(handle.getClass(), "playerConnection").get(handle);
final Object[] actions = this.packetActions.getEnumConstants();
final Method sendPacket = getMethod(connection.getClass(), "sendPacket");
Object packet = this.packetTitle.getConstructor(this.packetActions, Integer.TYPE, Integer.TYPE, Integer.TYPE).newInstance(actions[2], this.fadeInTime * (this.ticks ? 1 : 20), this.stayTime * (this.ticks ? 1 : 20), this.fadeOutTime * (this.ticks ? 1 : 20));
// Send if set
if ((this.fadeInTime != -1) && (this.fadeOutTime != -1) && (this.stayTime != -1)) {
sendPacket.invoke(connection, packet);
}
// Send title
Object serialized = getMethod(this.nmsChatSerializer, "a", String.class).invoke(null, "{text:\"" + ChatColor.translateAlternateColorCodes('&', this.title) + "\",color:" + this.titleColor.name().toLowerCase() + "}");
packet = this.packetTitle.getConstructor(this.packetActions, getNMSClass("IChatBaseComponent")).newInstance(actions[0], serialized);
sendPacket.invoke(connection, packet);
if (this.subtitle != "") {
// Send subtitle if present
serialized = getMethod(this.nmsChatSerializer, "a", String.class).invoke(null, "{text:\"" + ChatColor.translateAlternateColorCodes('&', this.subtitle) + "\",color:" + this.subtitleColor.name().toLowerCase() + "}");
packet = this.packetTitle.getConstructor(this.packetActions, getNMSClass("IChatBaseComponent")).newInstance(actions[1], serialized);
sendPacket.invoke(connection, packet);
}
}
}
/**
* Broadcast the title to all players
*/
public void broadcast() throws Exception {
for (final Player p : Bukkit.getOnlinePlayers()) {
send(p);
}
}
/**
* Clear the title
*
* @param player
* Player
* @throws Exception
*/
public void clearTitle(final Player player) throws Exception {
if ((getProtocolVersion(player) >= 47) && isSpigot()) {
// Send timings first
final Object handle = getHandle(player);
final Object connection = getField(handle.getClass(), "playerConnection").get(handle);
final Object[] actions = this.packetActions.getEnumConstants();
final Method sendPacket = getMethod(connection.getClass(), "sendPacket");
final Object packet = this.packetTitle.getConstructor(this.packetActions).newInstance(actions[3]);
sendPacket.invoke(connection, packet);
}
}
/**
* Reset the title settings
*
* @param player
* Player
* @throws Exception
*/
public void resetTitle(final Player player) throws Exception {
if ((getProtocolVersion(player) >= 47) && isSpigot()) {
// Send timings first
final Object handle = getHandle(player);
final Object connection = getField(handle.getClass(), "playerConnection").get(handle);
final Object[] actions = this.packetActions.getEnumConstants();
final Method sendPacket = getMethod(connection.getClass(), "sendPacket");
final Object packet = this.packetTitle.getConstructor(this.packetActions).newInstance(actions[4]);
sendPacket.invoke(connection, packet);
}
}
/**
* Get the protocol version of the player
*
* @param player
* Player
* @return Protocol version
* @throws Exception
*/
private int getProtocolVersion(final Player player) throws Exception {
final Object handle = getHandle(player);
final Object connection = getField(handle.getClass(), "playerConnection").get(handle);
final Object networkManager = getValue("networkManager", connection);
Integer version = (Integer) getMethod("getVersion", networkManager.getClass()).invoke(networkManager);
return version;
}
/**
* Check if running spigot
*
* @return Spigot
*/
private boolean isSpigot() {
return Bukkit.getVersion().contains("Spigot");
}
/**
* Get class by url
*
* @param namespace
* Namespace url
* @return Class
*/
private Class<?> getClass(final String namespace) {
try {
return Class.forName(namespace);
} catch (final Exception e) {
}
return null;
}
private Field getField(final String name, final Class<?> clazz) throws Exception {
return clazz.getDeclaredField(name);
}
private Object getValue(final String name, final Object obj) throws Exception {
final Field f = getField(name, obj.getClass());
f.setAccessible(true);
return f.get(obj);
}
private Class<?> getPrimitiveType(final Class<?> clazz) {
return CORRESPONDING_TYPES.containsKey(clazz) ? CORRESPONDING_TYPES.get(clazz) : clazz;
}
private Class<?>[] toPrimitiveTypeArray(final Class<?>[] classes) {
final int a = classes != null ? classes.length : 0;
final Class<?>[] types = new Class<?>[a];
for (int i = 0; i < a; i++) {
types[i] = getPrimitiveType(classes[i]);
}
return types;
}
private static boolean equalsTypeArray(final Class<?>[] a, final Class<?>[] o) {
if (a.length != o.length) {
return false;
}
for (int i = 0; i < a.length; i++) {
if (!a[i].equals(o[i]) && !a[i].isAssignableFrom(o[i])) {
return false;
}
}
return true;
}
private Object getHandle(final Object obj) {
try {
return getMethod("getHandle", obj.getClass()).invoke(obj);
} catch (final Exception e) {
e.printStackTrace();
return null;
}
}
private Method getMethod(final String name, final Class<?> clazz, final Class<?>... paramTypes) {
final Class<?>[] t = toPrimitiveTypeArray(paramTypes);
for (final Method m : clazz.getMethods()) {
final Class<?>[] types = toPrimitiveTypeArray(m.getParameterTypes());
if (m.getName().equals(name) && equalsTypeArray(types, t)) {
return m;
}
}
return null;
}
private String getVersion() {
final String name = Bukkit.getServer().getClass().getPackage().getName();
final String version = name.substring(name.lastIndexOf('.') + 1) + ".";
return version;
}
private Class<?> getNMSClass(final String className) throws ClassNotFoundException {
final String fullName = "net.minecraft.server." + getVersion() + className;
Class<?> clazz = null;
clazz = Class.forName(fullName);
return clazz;
}
private Field getField(final Class<?> clazz, final String name) {
try {
final Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
return field;
} catch (final Exception e) {
e.printStackTrace();
return null;
}
}
private Method getMethod(final Class<?> clazz, final String name, final Class<?>... args) {
for (final Method m : clazz.getMethods()) {
if (m.getName().equals(name) && ((args.length == 0) || ClassListEqual(args, m.getParameterTypes()))) {
m.setAccessible(true);
return m;
}
}
return null;
}
private boolean ClassListEqual(final Class<?>[] l1, final Class<?>[] l2) {
boolean equal = true;
if (l1.length != l2.length) {
return false;
}
for (int i = 0; i < l1.length; i++) {
if (l1[i] != l2[i]) {
equal = false;
break;
}
}
return equal;
}
}

View File

@ -0,0 +1,148 @@
package com.plotsquared.bukkit.util;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.bukkit.Bukkit;
/**
* Reflection Utilities for minecraft
*
*/
public class ReflectionUtil {
public static Class<?> getNmsClass(final String name) {
final String className = "net.minecraft.server." + getVersion() + "." + name;
return getClass(className);
}
public static Class<?> getCbClass(final String name) {
final String className = "org.bukkit.craftbukkit." + getVersion() + "." + name;
return getClass(className);
}
public static Class<?> getUtilClass(final String name) {
try {
return Class.forName(name); //Try before 1.8 first
} catch (final ClassNotFoundException ex) {
try {
return Class.forName("net.minecraft.util." + name); //Not 1.8
} catch (final ClassNotFoundException ex2) {
return null;
}
}
}
public static String getVersion() {
final String packageName = Bukkit.getServer().getClass().getPackage().getName();
return packageName.substring(packageName.lastIndexOf('.') + 1);
}
public static Object getHandle(final Object wrapper) {
final Method getHandle = makeMethod(wrapper.getClass(), "getHandle");
return callMethod(getHandle, wrapper);
}
//Utils
public static Method makeMethod(final Class<?> clazz, final String methodName, final Class<?>... paramaters) {
try {
return clazz.getDeclaredMethod(methodName, paramaters);
} catch (final NoSuchMethodException ex) {
return null;
} catch (final Exception ex) {
throw new RuntimeException(ex);
}
}
@SuppressWarnings("unchecked")
public static <T> T callMethod(final Method method, final Object instance, final Object... paramaters) {
if (method == null) {
throw new RuntimeException("No such method");
}
method.setAccessible(true);
try {
return (T) method.invoke(instance, paramaters);
} catch (final InvocationTargetException ex) {
throw new RuntimeException(ex.getCause());
} catch (final Exception ex) {
throw new RuntimeException(ex);
}
}
@SuppressWarnings("unchecked")
public static <T> Constructor<T> makeConstructor(final Class<?> clazz, final Class<?>... paramaterTypes) {
try {
return (Constructor<T>) clazz.getConstructor(paramaterTypes);
} catch (final NoSuchMethodException ex) {
return null;
} catch (final Exception ex) {
throw new RuntimeException(ex);
}
}
public static <T> T callConstructor(final Constructor<T> constructor, final Object... paramaters) {
if (constructor == null) {
throw new RuntimeException("No such constructor");
}
constructor.setAccessible(true);
try {
return constructor.newInstance(paramaters);
} catch (final InvocationTargetException ex) {
throw new RuntimeException(ex.getCause());
} catch (final Exception ex) {
throw new RuntimeException(ex);
}
}
public static Field makeField(final Class<?> clazz, final String name) {
try {
return clazz.getDeclaredField(name);
} catch (final NoSuchFieldException ex) {
return null;
} catch (final Exception ex) {
throw new RuntimeException(ex);
}
}
@SuppressWarnings("unchecked")
public static <T> T getField(final Field field, final Object instance) {
if (field == null) {
throw new RuntimeException("No such field");
}
field.setAccessible(true);
try {
return (T) field.get(instance);
} catch (final Exception ex) {
throw new RuntimeException(ex);
}
}
public static void setField(final Field field, final Object instance, final Object value) {
if (field == null) {
throw new RuntimeException("No such field");
}
field.setAccessible(true);
try {
field.set(instance, value);
} catch (final Exception ex) {
throw new RuntimeException(ex);
}
}
public static Class<?> getClass(final String name) {
try {
return Class.forName(name);
} catch (final ClassNotFoundException ex) {
return null;
}
}
public static <T> Class<? extends T> getClass(final String name, final Class<T> superClass) {
try {
return Class.forName(name).asSubclass(superClass);
} catch (ClassCastException | ClassNotFoundException ex) {
return null;
}
}
}

View File

@ -0,0 +1,23 @@
package com.plotsquared.bukkit.util;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.generator.ChunkGenerator;
import com.intellectualcrafters.plot.object.PlotWorld;
import com.intellectualcrafters.plot.object.SetupObject;
public abstract class SetupUtils {
public static SetupUtils manager;
public final static Map<String, SetupObject> setupMap = new HashMap<>();
public static HashMap<String, ChunkGenerator> generators = new HashMap<>();
public abstract void updateGenerators();
public abstract String getGenerator(PlotWorld plotworld);
public abstract String setupWorld(final SetupObject object);
}

View File

@ -0,0 +1,35 @@
package com.plotsquared.bukkit.util;
import java.io.File;
import com.intellectualcrafters.plot.util.MainUtil;
import org.bukkit.Bukkit;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.PlotId;
import com.sk89q.worldedit.CuboidClipboard;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.bukkit.BukkitWorld;
public class WorldEditSchematic {
public void saveSchematic(String file, final String world, final PlotId id) {
Location bot = MainUtil.getPlotBottomLoc(world, id).add(1, 0, 1);
Location top = MainUtil.getPlotTopLoc(world, id);
Vector size = new Vector(top.getX() - bot.getX() + 1, top.getY() - bot.getY() - 1, top.getZ() - bot.getZ() + 1);
Vector origin = new Vector(bot.getX(), bot.getY(), bot.getZ());
CuboidClipboard clipboard = new CuboidClipboard(size, origin);
Vector pos1 = new Vector(bot.getX(), bot.getY(), bot.getZ());
Vector pos2 = new Vector(top.getX(), top.getY(), top.getZ());
EditSession session = PS.get().worldEdit.getWorldEdit().getEditSessionFactory().getEditSession(new BukkitWorld(Bukkit.getWorld(world)), 999999999);
clipboard.copy(session);
try {
clipboard.saveSchematic(new File(file));
MainUtil.sendMessage(null, "&7 - &a success: " + id);
} catch (Exception e) {
e.printStackTrace();
MainUtil.sendMessage(null, "&7 - Failed to save &c" + id);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,75 @@
package com.plotsquared.bukkit.util.bukkit;
import net.milkbowl.vault.economy.Economy;
import net.milkbowl.vault.permission.Permission;
import org.bukkit.Bukkit;
import org.bukkit.plugin.RegisteredServiceProvider;
import com.plotsquared.bukkit.object.BukkitOfflinePlayer;
import com.plotsquared.bukkit.object.BukkitPlayer;
import com.intellectualcrafters.plot.object.OfflinePlotPlayer;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.util.EconHandler;
public class BukkitEconHandler extends EconHandler {
private Economy econ;
private Permission perms;
public boolean init() {
if (econ == null || perms == null) {
setupPermissions();
setupEconomy();
}
return econ != null && perms != null;
}
private boolean setupPermissions()
{
RegisteredServiceProvider<Permission> permissionProvider = Bukkit.getServer().getServicesManager().getRegistration(net.milkbowl.vault.permission.Permission.class);
if (permissionProvider != null) {
perms = permissionProvider.getProvider();
}
return (perms != null);
}
private boolean setupEconomy()
{
RegisteredServiceProvider<Economy> economyProvider = Bukkit.getServer().getServicesManager().getRegistration(net.milkbowl.vault.economy.Economy.class);
if (economyProvider != null) {
econ = economyProvider.getProvider();
}
return (econ != null);
}
@Override
public double getMoney(PlotPlayer player) {
return econ.getBalance(player.getName());
}
@Override
public void withdrawMoney(PlotPlayer player, double amount) {
econ.withdrawPlayer(player.getName(), amount);
}
@Override
public void depositMoney(PlotPlayer player, double amount) {
econ.depositPlayer(player.getName(), amount);
}
@Override
public void depositMoney(OfflinePlotPlayer player, double amount) {
econ.depositPlayer(((BukkitOfflinePlayer) player).player, amount);
}
@Override
public void setPermission(PlotPlayer player, String perm, boolean value) {
if (value) {
perms.playerAdd(((BukkitPlayer) player).player, perm);
}
else {
perms.playerRemove(((BukkitPlayer) player).player, perm);
}
}
}

View File

@ -0,0 +1,118 @@
package com.plotsquared.bukkit.util.bukkit;
import java.util.ArrayList;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import com.plotsquared.bukkit.events.ClusterFlagRemoveEvent;
import com.plotsquared.bukkit.events.PlayerClaimPlotEvent;
import com.plotsquared.bukkit.events.PlayerEnterPlotEvent;
import com.plotsquared.bukkit.events.PlayerLeavePlotEvent;
import com.plotsquared.bukkit.events.PlayerPlotDeniedEvent;
import com.plotsquared.bukkit.events.PlayerPlotHelperEvent;
import com.plotsquared.bukkit.events.PlayerPlotTrustedEvent;
import com.plotsquared.bukkit.events.PlayerTeleportToPlotEvent;
import com.plotsquared.bukkit.events.PlotClearEvent;
import com.plotsquared.bukkit.events.PlotDeleteEvent;
import com.plotsquared.bukkit.events.PlotFlagAddEvent;
import com.plotsquared.bukkit.events.PlotFlagRemoveEvent;
import com.plotsquared.bukkit.events.PlotMergeEvent;
import com.plotsquared.bukkit.events.PlotUnlinkEvent;
import com.intellectualcrafters.plot.flag.Flag;
import com.plotsquared.bukkit.object.BukkitPlayer;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotCluster;
import com.intellectualcrafters.plot.object.PlotId;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.util.EventUtil;
public class BukkitEventUtil extends EventUtil {
public Player getPlayer(PlotPlayer player) {
return ((BukkitPlayer) player).player;
}
public boolean callEvent(Event event) {
Bukkit.getServer().getPluginManager().callEvent(event);
if (event instanceof Cancellable) {
return !((Cancellable) event).isCancelled();
}
return true;
}
@Override
public boolean callClaim(PlotPlayer player, Plot plot, boolean auto) {
return callEvent(new PlayerClaimPlotEvent(getPlayer(player), plot, auto));
}
@Override
public boolean callTeleport(PlotPlayer player, Location from, Plot plot) {
return callEvent(new PlayerTeleportToPlotEvent(getPlayer(player), from, plot));
}
@Override
public boolean callClear(String world, PlotId id) {
return callEvent(new PlotClearEvent(world, id));
}
@Override
public void callDelete(String world, PlotId id) {
callEvent(new PlotDeleteEvent(world, id));
}
@Override
public boolean callFlagAdd(Flag flag, Plot plot) {
return callEvent(new PlotFlagAddEvent(flag, plot));
}
@Override
public boolean callFlagRemove(Flag flag, Plot plot) {
return callEvent(new PlotFlagRemoveEvent(flag, plot));
}
@Override
public boolean callMerge(String world, Plot plot, ArrayList<PlotId> plots) {
return callEvent(new PlotMergeEvent(BukkitUtil.getWorld(world), plot, plots));
}
@Override
public boolean callUnlink(String world, ArrayList<PlotId> plots) {
return callEvent(new PlotUnlinkEvent(BukkitUtil.getWorld(world), plots));
}
@Override
public void callEntry(PlotPlayer player, Plot plot) {
callEvent(new PlayerEnterPlotEvent(getPlayer(player), plot));
}
@Override
public void callLeave(PlotPlayer player, Plot plot) {
callEvent(new PlayerLeavePlotEvent(getPlayer(player), plot));
}
@Override
public void callDenied(PlotPlayer initiator, Plot plot, UUID player, boolean added) {
callEvent(new PlayerPlotDeniedEvent(getPlayer(initiator), plot, player, added));
}
@Override
public void callTrusted(PlotPlayer initiator, Plot plot, UUID player, boolean added) {
callEvent(new PlayerPlotHelperEvent(getPlayer(initiator), plot, player, added));
}
@Override
public void callMember(PlotPlayer initiator, Plot plot, UUID player, boolean added) {
callEvent(new PlayerPlotTrustedEvent(getPlayer(initiator), plot, player, added));
}
@Override
public boolean callFlagRemove(Flag flag, PlotCluster cluster) {
return callEvent(new ClusterFlagRemoveEvent(flag, cluster));
}
}

View File

@ -0,0 +1,127 @@
package com.plotsquared.bukkit.util.bukkit;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.ItemMeta;
import com.plotsquared.bukkit.object.BukkitPlayer;
import com.intellectualcrafters.plot.object.PlotInventory;
import com.intellectualcrafters.plot.object.PlotItemStack;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.util.InventoryUtil;
public class BukkitInventoryUtil extends InventoryUtil {
@Override
public void open(PlotInventory inv) {
BukkitPlayer bp = ((BukkitPlayer) inv.player);
Inventory inventory = Bukkit.createInventory(null, inv.size * 9, inv.getTitle());
PlotItemStack[] items = inv.getItems();
for (int i = 0; i < inv.size * 9; i++) {
PlotItemStack item = items[i];
if (item != null) {
inventory.setItem(i, getItem(item));
}
}
inv.player.setMeta("inventory", inv);
bp.player.openInventory(inventory);
}
@Override
public void close(PlotInventory inv) {
if (!inv.isOpen()) {
return;
}
inv.player.deleteMeta("inventory");
BukkitPlayer bp = ((BukkitPlayer) inv.player);
bp.player.closeInventory();
}
@Override
public void setItem(PlotInventory inv, int index, PlotItemStack item) {
BukkitPlayer bp = ((BukkitPlayer) inv.player);
InventoryView opened = bp.player.getOpenInventory();
if (!inv.isOpen()) {
return;
}
opened.setItem(index, getItem(item));
bp.player.updateInventory();
}
public PlotItemStack getItem(ItemStack item ) {
if (item == null) {
return null;
}
int id = item.getTypeId();
short data = item.getDurability();
int amount = item.getAmount();
String name = null;
String[] lore = null;
if (item.hasItemMeta()) {
ItemMeta meta = item.getItemMeta();
if (meta.hasDisplayName()) {
name = meta.getDisplayName();
}
if (meta.hasLore()) {
List<String> itemLore = meta.getLore();
lore = itemLore.toArray(new String[itemLore.size()]);
}
}
return new PlotItemStack(id, data, amount, name, lore);
}
public static ItemStack getItem(PlotItemStack item) {
if (item == null) {
return null;
}
ItemStack stack = new ItemStack(item.id, item.amount, item.data);
ItemMeta meta = null;
if (item.name != null) {
meta = stack.getItemMeta();
meta.setDisplayName(ChatColor.translateAlternateColorCodes('&', item.name));
}
if (item.lore != null) {
if (meta == null) {
meta = stack.getItemMeta();
}
List<String> lore = new ArrayList<>();
for (String entry : item.lore) {
lore.add(ChatColor.translateAlternateColorCodes('&', entry));
}
meta.setLore(lore);
}
if (meta != null) {
stack.setItemMeta(meta);
}
return stack;
}
@Override
public PlotItemStack[] getItems(PlotPlayer player) {
BukkitPlayer bp = ((BukkitPlayer) player);
PlayerInventory inv = bp.player.getInventory();
PlotItemStack[] items = new PlotItemStack[36];
for (int i = 0; i < 36; i++) {
items[i] = getItem(inv.getItem(i));
}
return items;
}
@Override
public boolean isOpen(PlotInventory inv) {
if (!inv.isOpen()) {
return false;
}
BukkitPlayer bp = ((BukkitPlayer) inv.player);
InventoryView opened = bp.player.getOpenInventory();
return (inv.isOpen() && opened.getType() == InventoryType.CRAFTING && opened.getTitle() == null);
}
}

View File

@ -0,0 +1,142 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// PlotSquared - A plot manager and world generator for the Bukkit API /
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters /
// /
// This program is free software; you can redistribute it and/or modify /
// it under the terms of the GNU General Public License as published by /
// the Free Software Foundation; either version 3 of the License, or /
// (at your option) any later version. /
// /
// This program is distributed in the hope that it will be useful, /
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the /
// GNU General Public License for more details. /
// /
// You should have received a copy of the GNU General Public License /
// along with this program; if not, write to the Free Software Foundation, /
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /
// /
// You can contact us via: support@intellectualsites.com /
////////////////////////////////////////////////////////////////////////////////////////////////////
package com.plotsquared.bukkit.util.bukkit;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import org.bukkit.entity.Player;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.config.C;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotId;
import com.intellectualcrafters.plot.util.MainUtil;
/**
* Functions involving players, plots and locations.
*/
public class BukkitPlayerFunctions {
/*
* =========== NOTICE ================
* - We will try to move as many functions as we can out of this class and into the MainUtil class
*/
/**
* Clear a plot. Use null player if no player is present
* @param player
* @param world
* @param plot
* @param isDelete
*/
public static void clear(final Player player, final String world, final Plot plot, final boolean isDelete) {
final long start = System.currentTimeMillis();
final Runnable whenDone = new Runnable() {
@Override
public void run() {
if ((player != null) && player.isOnline()) {
MainUtil.sendMessage(BukkitUtil.getPlayer(player), C.CLEARING_DONE, "" + (System.currentTimeMillis() - start));
}
}
};
if (!MainUtil.clearAsPlayer(plot, isDelete, whenDone)) {
MainUtil.sendMessage(null, C.WAIT_FOR_TIMER);
}
}
public static String getPlayerName(final UUID uuid) {
if (uuid == null) {
return "unknown";
}
final String name = UUIDHandler.getName(uuid);
if (name == null) {
return "unknown";
}
return name;
}
/**
* @param player player
*
* @return boolean
*/
public static boolean isInPlot(final Player player) {
return getCurrentPlot(player) != null;
}
public static ArrayList<PlotId> getMaxPlotSelectionIds(final String world, PlotId pos1, PlotId pos2) {
final Plot plot1 = PS.get().getPlots(world).get(pos1);
final Plot plot2 = PS.get().getPlots(world).get(pos2);
if (plot1 != null) {
pos1 = MainUtil.getBottomPlot(plot1).id;
}
if (plot2 != null) {
pos2 = MainUtil.getTopPlot(plot2).id;
}
final ArrayList<PlotId> myplots = new ArrayList<>();
for (int x = pos1.x; x <= pos2.x; x++) {
for (int y = pos1.y; y <= pos2.y; y++) {
myplots.add(new PlotId(x, y));
}
}
return myplots;
}
/**
* Returns the plot a player is currently in.
*
* @param player
*
* @return boolean
*/
public static Plot getCurrentPlot(final Player player) {
if (!PS.get().isPlotWorld(player.getWorld().getName())) {
return null;
}
final PlotId id = MainUtil.getPlotId(BukkitUtil.getLocation(player));
final String world = player.getWorld().getName();
if (id == null) {
return null;
}
if (PS.get().getPlots(world).containsKey(id)) {
return PS.get().getPlots(world).get(id);
}
return new Plot(world, id, null);
}
/**
* Get the plots for a player
*
* @param plr
*
* @return boolean
*/
public static Set<Plot> getPlayerPlots(final String world, final Player plr) {
final Set<Plot> p = PS.get().getPlots(world, plr.getName());
if (p == null) {
return new HashSet<>();
}
return p;
}
}

View File

@ -0,0 +1,14 @@
package com.plotsquared.bukkit.util.bukkit;
import com.plotsquared.bukkit.object.BukkitPlayer;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.util.PlayerManager;
public class BukkitPlayerManager extends PlayerManager {
@Override
public void kickPlayer(PlotPlayer player, String reason) {
((BukkitPlayer) player).player.kickPlayer(reason);
}
}

View File

@ -0,0 +1,321 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// PlotSquared - A plot manager and world generator for the Bukkit API /
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters /
// /
// This program is free software; you can redistribute it and/or modify /
// it under the terms of the GNU General Public License as published by /
// the Free Software Foundation; either version 3 of the License, or /
// (at your option) any later version. /
// /
// This program is distributed in the hope that it will be useful, /
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the /
// GNU General Public License for more details. /
// /
// You should have received a copy of the GNU General Public License /
// along with this program; if not, write to the Free Software Foundation, /
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /
// /
// You can contact us via: support@intellectualsites.com /
////////////////////////////////////////////////////////////////////////////////////////////////////
package com.plotsquared.bukkit.util.bukkit;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import com.intellectualcrafters.plot.util.SchematicHandler;
import com.intellectualcrafters.plot.util.TaskManager;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import com.intellectualcrafters.jnbt.ByteArrayTag;
import com.intellectualcrafters.jnbt.CompoundTag;
import com.intellectualcrafters.jnbt.IntTag;
import com.intellectualcrafters.jnbt.ListTag;
import com.intellectualcrafters.jnbt.ShortTag;
import com.intellectualcrafters.jnbt.StringTag;
import com.intellectualcrafters.jnbt.Tag;
import com.intellectualcrafters.plot.object.ChunkLoc;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.RunnableVal;
import com.plotsquared.bukkit.object.schematic.StateWrapper;
/**
* Schematic Handler
*
* @author Citymonstret
* @author Empire92
*/
public class BukkitSchematicHandler extends SchematicHandler {
@Override
public void getCompoundTag(final String world, final Location pos1, final Location pos2, final RunnableVal<CompoundTag> whenDone) {
// async
TaskManager.runTaskAsync(new Runnable() {
@Override
public void run() {
// Main positions
final int p1x = pos1.getX();
final int p1z = pos1.getZ();
final int p2x = pos2.getX();
final int p2z = pos2.getZ();
final int bcx = p1x >> 4;
final int bcz = p1z >> 4;
final int tcx = p2x >> 4;
final int tcz = p2z >> 4;
final int sy = pos1.getY();
final int ey = pos2.getY();
final int width = (pos2.getX() - pos1.getX()) + 1;
final int height = (pos2.getY() - pos1.getY()) + 1;
final int length = (pos2.getZ() - pos1.getZ()) + 1;
// Main Schematic tag
final HashMap<String, Tag> schematic = new HashMap<>();
schematic.put("Width", new ShortTag("Width", (short) width));
schematic.put("Length", new ShortTag("Length", (short) length));
schematic.put("Height", new ShortTag("Height", (short) height));
schematic.put("Materials", new StringTag("Materials", "Alpha"));
schematic.put("WEOriginX", new IntTag("WEOriginX", 0));
schematic.put("WEOriginY", new IntTag("WEOriginY", 0));
schematic.put("WEOriginZ", new IntTag("WEOriginZ", 0));
schematic.put("WEOffsetX", new IntTag("WEOffsetX", 0));
schematic.put("WEOffsetY", new IntTag("WEOffsetY", 0));
schematic.put("WEOffsetZ", new IntTag("WEOffsetZ", 0));
// Arrays of data types
final List<Tag> tileEntities = new ArrayList<Tag>();
final byte[] blocks = new byte[width * height * length];
final byte[] blockData = new byte[width * height * length];
// Generate list of chunks
final ArrayList<ChunkLoc> chunks = new ArrayList<ChunkLoc>();
for (int x = bcx; x <= tcx; x++) {
for (int z = bcz; z <= tcz; z++) {
chunks.add(new ChunkLoc(x, z));
}
}
final World worldObj = Bukkit.getWorld(world);
// Main thread
TaskManager.runTask(new Runnable() {
@Override
public void run() {
long start = System.currentTimeMillis();
while (chunks.size() > 0 && System.currentTimeMillis() - start < 20) {
// save schematics
ChunkLoc chunk = chunks.remove(0);
Chunk bc = worldObj.getChunkAt(chunk.x, chunk.z);
if (!bc.load(false)) {
continue;
}
int X = chunk.x;
int Z = chunk.z;
int xxb = X << 4;
int zzb = Z << 4;
int xxt = xxb + 15;
int zzt = zzb + 15;
if (X == bcx) {
xxb = p1x;
}
if (X == tcx) {
xxt = p2x;
}
if (Z == bcz) {
zzb = p1z;
}
if (Z == tcz) {
zzt = p2z;
}
for (int y = sy; y <= Math.min(255, ey); y++) {
int ry = y - sy;
int i1 = (ry * width * length);
for (int z = zzb; z <= zzt; z++) {
int rz = z - p1z;
int i2 = i1 + (rz * width);
for (int x = xxb; x <= xxt; x++) {
int rx = x - p1x;
final int index = i2 + rx;
Block block = worldObj.getBlockAt(x, y, z);
int id = block.getTypeId();
switch (id) {
case 0:
case 2:
case 4:
case 13:
case 14:
case 15:
case 20:
case 21:
case 22:
case 24:
case 30:
case 32:
case 37:
case 39:
case 40:
case 41:
case 42:
case 45:
case 46:
case 47:
case 48:
case 49:
case 50:
case 51:
case 55:
case 56:
case 57:
case 58:
case 60:
case 7:
case 8:
case 9:
case 10:
case 11:
case 73:
case 74:
case 75:
case 76:
case 78:
case 79:
case 80:
case 81:
case 82:
case 83:
case 85:
case 87:
case 88:
case 101:
case 102:
case 103:
case 110:
case 112:
case 113:
case 121:
case 122:
case 129:
case 133:
case 165:
case 166:
case 169:
case 170:
case 172:
case 173:
case 174:
case 181:
case 182:
case 188:
case 189:
case 190:
case 191:
case 192: {
break;
}
case 54:
case 130:
case 142:
case 27:
case 137:
case 52:
case 154:
case 84:
case 25:
case 144:
case 138:
case 176:
case 177:
case 63:
case 68:
case 323:
case 117:
case 116:
case 28:
case 66:
case 157:
case 61:
case 62:
case 140:
case 146:
case 149:
case 150:
case 158:
case 23:
case 123:
case 124:
case 29:
case 33:
case 151:
case 178: {
// TODO implement fully
BlockState state = block.getState();
if (state != null) {
StateWrapper wrapper = new StateWrapper(state);
CompoundTag rawTag = wrapper.getTag();
if (rawTag != null) {
Map<String, Tag> values = new HashMap<String, Tag>();
for (Entry<String, Tag> entry : rawTag.getValue().entrySet()) {
values.put(entry.getKey(), entry.getValue());
}
values.put("id", new StringTag("id", wrapper.getId()));
values.put("x", new IntTag("x", x));
values.put("y", new IntTag("y", y));
values.put("z", new IntTag("z", z));
CompoundTag tileEntityTag = new CompoundTag(values);
tileEntities.add(tileEntityTag);
}
}
}
default: {
blockData[index] = block.getData();
}
}
// For optimization reasons, we are not supporting custom data types
// Especially since the most likely reason beyond this range is modded servers in which the blocks have NBT
// if (id > 255) {
// if (addBlocks == null) {
// addBlocks = new byte[(blocks.length >> 1) + 1];
// }
// addBlocks[index >> 1] = (byte) (((index & 1) == 0) ? (addBlocks[index >> 1] & 0xF0) | ((id >> 8) & 0xF) : (addBlocks[index >> 1] & 0xF) | (((id >> 8) & 0xF) << 4));
// }
blocks[index] = (byte) id;
}
}
}
}
if (chunks.size() != 0) {
TaskManager.runTaskLater(this, 1);
} else {
TaskManager.runTaskAsync(new Runnable() {
@Override
public void run() {
schematic.put("Blocks", new ByteArrayTag("Blocks", blocks));
schematic.put("Data", new ByteArrayTag("Data", blockData));
schematic.put("Entities", new ListTag("Entities", CompoundTag.class, new ArrayList<Tag>()));
schematic.put("TileEntities", new ListTag("TileEntities", CompoundTag.class, tileEntities));
whenDone.value = new CompoundTag("Schematic", schematic);
TaskManager.runTask(whenDone);
System.gc();
System.gc();
}
});
}
}
});
}
});
}
}

View File

@ -0,0 +1,28 @@
package com.plotsquared.bukkit.util.bukkit;
import java.util.ArrayList;
import java.util.Collection;
import org.bukkit.Chunk;
import org.bukkit.World;
import com.intellectualcrafters.plot.object.ChunkLoc;
import com.intellectualcrafters.plot.util.BlockUpdateUtil;
public abstract class BukkitSetBlockManager extends BlockUpdateUtil {
public static BukkitSetBlockManager setBlockManager = null;
public abstract void set(final org.bukkit.World world, final int x, final int y, final int z, final int blockId, final byte data);
public abstract void update(Collection<Chunk> list);
@Override
public void update(final String worldname, final Collection<ChunkLoc> chunkLocs) {
final World world = BukkitUtil.getWorld(worldname);
final ArrayList<Chunk> chunks = new ArrayList<Chunk>();
for (final ChunkLoc loc : chunkLocs) {
chunks.add(world.getChunkAt(loc.x, loc.z));
}
setBlockManager.update(chunks);
}
}

View File

@ -0,0 +1,116 @@
package com.plotsquared.bukkit.util.bukkit;
import java.io.IOException;
import java.util.Map.Entry;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.World.Environment;
import org.bukkit.WorldCreator;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.plugin.Plugin;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.config.ConfigurationNode;
import com.plotsquared.bukkit.object.PlotGenerator;
import com.intellectualcrafters.plot.object.PlotWorld;
import com.intellectualcrafters.plot.object.SetupObject;
import com.plotsquared.bukkit.util.SetupUtils;
public class BukkitSetupUtils extends SetupUtils {
@Override
public void updateGenerators() {
if (SetupUtils.generators.size() > 0) {
return;
}
final String testWorld = "CheckingPlotSquaredGenerator";
for (final Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
if (plugin.isEnabled()) {
final ChunkGenerator generator = plugin.getDefaultWorldGenerator(testWorld, "");
if (generator != null) {
PS.get().removePlotWorld(testWorld);
final String name = plugin.getDescription().getName();
// final PlotGenerator pgen = (PlotGenerator) generator;
// if (pgen.getPlotManager() instanceof SquarePlotManager) {
SetupUtils.generators.put(name, generator);
// }
// }
}
}
}
}
@Override
public String setupWorld(final SetupObject object) {
SetupUtils.manager.updateGenerators();
final ConfigurationNode[] steps = object.step;
final String world = object.world;
for (final ConfigurationNode step : steps) {
PS.get().config.set("worlds." + world + "." + step.getConstant(), step.getValue());
}
if (object.type != 0) {
PS.get().config.set("worlds." + world + "." + "generator.type", object.type);
PS.get().config.set("worlds." + world + "." + "generator.terrain", object.terrain);
PS.get().config.set("worlds." + world + "." + "generator.plugin", object.plotManager);
if (object.setupGenerator != null && !object.setupGenerator.equals(object.plotManager)) {
PS.get().config.set("worlds." + world + "." + "generator.init", object.setupGenerator);
}
ChunkGenerator gen = generators.get(object.setupGenerator);
if (gen instanceof PlotGenerator) {
object.setupGenerator = null;
}
}
try {
PS.get().config.save(PS.get().configFile);
} catch (final IOException e) {
e.printStackTrace();
}
if (object.setupGenerator != null) {
if ((Bukkit.getPluginManager().getPlugin("Multiverse-Core") != null) && Bukkit.getPluginManager().getPlugin("Multiverse-Core").isEnabled()) {
Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), "mv create " + world + " normal -g " + object.setupGenerator);
} else {
if ((Bukkit.getPluginManager().getPlugin("MultiWorld") != null) && Bukkit.getPluginManager().getPlugin("MultiWorld").isEnabled()) {
Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), "mw create " + world + " plugin:" + object.setupGenerator);
} else {
final WorldCreator wc = new WorldCreator(object.world);
wc.generator(object.setupGenerator);
wc.environment(Environment.NORMAL);
Bukkit.createWorld(wc);
}
}
} else {
if ((Bukkit.getPluginManager().getPlugin("Multiverse-Core") != null) && Bukkit.getPluginManager().getPlugin("Multiverse-Core").isEnabled()) {
Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), "mv create " + world + " normal");
} else {
if ((Bukkit.getPluginManager().getPlugin("MultiWorld") != null) && Bukkit.getPluginManager().getPlugin("MultiWorld").isEnabled()) {
Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), "mw create " + world);
} else {
Bukkit.createWorld(new WorldCreator(object.world).environment(World.Environment.NORMAL));
}
}
}
return object.world;
}
@Override
public String getGenerator(PlotWorld plotworld) {
if (SetupUtils.generators.size() == 0) {
updateGenerators();
}
World world = Bukkit.getWorld(plotworld.worldname);
if (world == null) {
return null;
}
ChunkGenerator generator = world.getGenerator();
if (!(generator instanceof PlotGenerator)) {
return null;
}
for (Entry<String, ChunkGenerator> entry : generators.entrySet()) {
if (entry.getValue().getClass().getName().equals(generator.getClass().getName())) {
return entry.getKey();
}
}
return null;
}
}

View File

@ -0,0 +1,40 @@
package com.plotsquared.bukkit.util.bukkit;
import org.bukkit.Bukkit;
import com.plotsquared.bukkit.BukkitMain;
import com.intellectualcrafters.plot.util.TaskManager;
public class BukkitTaskManager extends TaskManager {
@Override
public int taskRepeat(final Runnable r, final int interval) {
return BukkitMain.THIS.getServer().getScheduler().scheduleSyncRepeatingTask(BukkitMain.THIS, r, interval, interval);
}
@Override
public void taskAsync(final Runnable r) {
BukkitMain.THIS.getServer().getScheduler().runTaskAsynchronously(BukkitMain.THIS, r).getTaskId();
}
@Override
public void task(final Runnable r) {
BukkitMain.THIS.getServer().getScheduler().runTask(BukkitMain.THIS, r).getTaskId();
}
@Override
public void taskLater(final Runnable r, final int delay) {
BukkitMain.THIS.getServer().getScheduler().runTaskLater(BukkitMain.THIS, r, delay).getTaskId();
}
@Override
public void taskLaterAsync(final Runnable r, final int delay) {
BukkitMain.THIS.getServer().getScheduler().runTaskLaterAsynchronously(BukkitMain.THIS, r, delay);
}
@Override
public void cancelTask(final int task) {
if (task != -1) {
Bukkit.getScheduler().cancelTask(task);
}
}
}

View File

@ -0,0 +1,399 @@
package com.plotsquared.bukkit.util.bukkit;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.block.Biome;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.Sign;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.material.MaterialData;
import org.bukkit.material.Sandstone;
import org.bukkit.material.Step;
import org.bukkit.material.Tree;
import org.bukkit.material.WoodenStep;
import org.bukkit.material.Wool;
import com.plotsquared.bukkit.object.BukkitPlayer;
import com.intellectualcrafters.plot.object.ChunkLoc;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.PlotBlock;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.object.schematic.PlotItem;
import com.intellectualcrafters.plot.util.BlockManager;
import com.intellectualcrafters.plot.util.ChunkManager;
import com.intellectualcrafters.plot.util.StringComparison;
public class BukkitUtil extends BlockManager {
private static HashMap<String, World> worlds = new HashMap<>();
private static String lastString = null;
private static World lastWorld = null;
private static Player lastPlayer = null;
private static PlotPlayer lastPlotPlayer = null;
public static void removePlayer(final String plr) {
lastPlayer = null;
lastPlotPlayer = null;
UUIDHandler.getPlayers().remove(plr);
}
@Override
public boolean isWorld(final String world) {
return getWorld(world) != null;
}
public static PlotPlayer getPlayer(final OfflinePlayer op) {
if (op.isOnline()) {
return getPlayer(op.getPlayer());
}
Player player = OfflinePlayerUtil.loadPlayer(op);
player.loadData();
return new BukkitPlayer(player);
}
public static PlotPlayer getPlayer(final Player player) {
if (player == lastPlayer) {
return lastPlotPlayer;
}
String name = player.getName();
PlotPlayer pp = UUIDHandler.getPlayers().get(name);
if (pp != null) {
return pp;
}
lastPlotPlayer = new BukkitPlayer(player);
UUIDHandler.getPlayers().put(name, lastPlotPlayer);
lastPlayer = player;
return lastPlotPlayer;
}
@Override
public String getBiome(final Location loc) {
return getWorld(loc.getWorld()).getBiome(loc.getX(), loc.getZ()).name();
}
public static Location getLocation(final org.bukkit.Location loc) {
return new Location(loc.getWorld().getName(), (int) loc.getX(), (int) loc.getY(), (int) loc.getZ());
}
public static org.bukkit.Location getLocation(final Location loc) {
return new org.bukkit.Location(getWorld(loc.getWorld()), loc.getX(), loc.getY(), loc.getZ());
}
public static World getWorld(final String string) {
if (string == lastString) {
return lastWorld;
}
World world = worlds.get(string);
if (world == null) {
world = Bukkit.getWorld(string);
worlds.put(string, world);
}
return world;
}
public static int getMaxHeight(final String world) {
return getWorld(world).getMaxHeight();
}
public static int getHeighestBlock(final String world, final int x, final int z) {
return getWorld(world).getHighestBlockYAt(x, z);
}
public static void unloadChunkAt(String worldname, int X, int Z, boolean save, boolean safe) {
final World world = getWorld(worldname);
world.unloadChunk(X, Z, save, safe);
}
public static void loadChunkAt(final String worldname, int X, int Z, boolean force) {
final World world = getWorld(worldname);
world.loadChunk(X, Z, force);
}
public static Chunk getChunkAt(final String worldname, final int x, final int z) {
final World world = getWorld(worldname);
return world.getChunkAt(x, z);
}
// public static void update(final String world, final int x, final int z) {
// final ArrayList<Chunk> chunks = new ArrayList<>();
// final int distance = Bukkit.getViewDistance();
// for (int cx = -distance; cx < distance; cx++) {
// for (int cz = -distance; cz < distance; cz++) {
// final Chunk chunk = getChunkAt(world, (x >> 4) + cx, (z >> 4) + cz);
// chunks.add(chunk);
// }
// }
// BukkitSetBlockManager.setBlockManager.update(chunks);
// }
public static String getWorld(final Entity entity) {
return entity.getWorld().getName();
}
public static void teleportPlayer(final Player player, final Location loc) {
final org.bukkit.Location bukkitLoc = new org.bukkit.Location(getWorld(loc.getWorld()), loc.getX(), loc.getY(), loc.getZ());
player.teleport(bukkitLoc);
}
public static List<Entity> getEntities(final String worldname) {
return getWorld(worldname).getEntities();
}
public static void setBlock(final World world, final int x, final int y, final int z, final int id, final byte data) {
try {
BukkitSetBlockManager.setBlockManager.set(world, x, y, z, id, data);
} catch (final Throwable e) {
BukkitSetBlockManager.setBlockManager = new SetBlockSlow();
BukkitSetBlockManager.setBlockManager.set(world, x, y, z, id, data);
}
}
public static void setBiome(final String worldname, final int pos1_x, final int pos1_z, final int pos2_x, final int pos2_z, final String biome) {
final Biome b = Biome.valueOf(biome.toUpperCase());
final World world = getWorld(worldname);
for (int x = pos1_x; x <= pos2_x; x++) {
for (int z = pos1_z; z <= pos2_z; z++) {
if (world.getBiome(x, z) == b) {
continue;
}
world.setBiome(x, z, b);
}
}
}
public static void refreshChunk(final String name, final int x, final int z) {
World world = getWorld(name);
world.refreshChunk(x, z);
world.loadChunk(x, z);
}
public static void regenerateChunk(final String world, final int x, final int z) {
World worldObj = getWorld(world);
Chunk chunk = worldObj.getChunkAt(x, z);
if (chunk.isLoaded() || chunk.load(false)) {
ChunkManager.manager.regenerateChunk(world, new ChunkLoc(x, z));
}
}
public static PlotBlock getBlock(final Location loc) {
final World world = getWorld(loc.getWorld());
final Block block = world.getBlockAt(loc.getX(), loc.getY(), loc.getZ());
if (block == null) {
return new PlotBlock((short) 0, (byte) 0);
}
return new PlotBlock((short) block.getTypeId(), block.getData());
}
public static Location getLocation(final Entity entity) {
final org.bukkit.Location loc = entity.getLocation();
final String world = loc.getWorld().getName();
return new Location(world, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
}
public static Location getLocationFull(final Entity entity) {
return getLocation(entity.getLocation());
}
public static Location getLocationFull(final org.bukkit.Location loc) {
final String world = loc.getWorld().getName();
return new Location(world, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), loc.getYaw(), loc.getPitch());
}
@Override
public void functionSetBlocks(final String worldname, final int[] x, final int[] y, final int[] z, final int[] id, final byte[] data) {
final World world = getWorld(worldname);
for (int i = 0; i < x.length; i++) {
BukkitUtil.setBlock(world, x[i], y[i], z[i], id[i], data[i]);
}
}
@Override
public void functionSetSign(final String worldname, final int x, final int y, final int z, final String[] lines) {
final World world = getWorld(worldname);
final Block block = world.getBlockAt(x, y, z);
block.setType(Material.AIR);
block.setTypeIdAndData(Material.WALL_SIGN.getId(), (byte) 2, false);
final BlockState blockstate = block.getState();
if ((blockstate instanceof Sign)) {
for (int i = 0; i < lines.length; i++) {
((Sign) blockstate).setLine(i, lines[i]);
}
((Sign) blockstate).update(true);
}
}
public static int getViewDistance() {
return Bukkit.getViewDistance();
}
@Override
public void functionSetBiomes(final String worldname, final int[] x, final int[] z, final int[] biome) {
final World world = getWorld(worldname);
final Biome[] biomes = Biome.values();
for (int i = 0; i < x.length; i++) {
world.setBiome(x[i], z[i], biomes[biome[i]]);
}
}
@Override
public void functionSetBlock(final String worldname, final int x, final int y, final int z, final int id, final byte data) {
BukkitUtil.setBlock(getWorld(worldname), x, y, z, id, data);
}
@Override
public String[] getSign(final Location loc) {
final Block block = getWorld(loc.getWorld()).getBlockAt(loc.getX(), loc.getY(), loc.getZ());
if (block != null) {
if (block.getState() instanceof Sign) {
final Sign sign = (Sign) block.getState();
return sign.getLines();
}
}
return null;
}
@Override
public Location getSpawn(final String world) {
final org.bukkit.Location temp = getWorld(world).getSpawnLocation();
return new Location(world, temp.getBlockX(), temp.getBlockY(), temp.getBlockZ(), temp.getYaw(), temp.getPitch());
}
@Override
public int getHeighestBlock(final Location loc) {
return getWorld(loc.getWorld()).getHighestBlockAt(loc.getX(), loc.getZ()).getY();
}
@Override
public int getBiomeFromString(final String biomeStr) {
try {
final Biome biome = Biome.valueOf(biomeStr.toUpperCase());
if (biome == null) {
return -1;
}
return Arrays.asList(Biome.values()).indexOf(biome);
}
catch (IllegalArgumentException e) {
return -1;
}
}
@Override
public String[] getBiomeList() {
final Biome[] biomes = Biome.values();
final String[] list = new String[biomes.length];
for (int i = 0; i < biomes.length; i++) {
list[i] = biomes[i].name();
}
return list;
}
@Override
public int getBlockIdFromString(final String block) {
final Material material = Material.valueOf(block.toUpperCase());
if (material == null) {
return -1;
}
return material.getId();
}
@Override
public boolean addItems(String worldname, PlotItem items) {
World world = getWorld(worldname);
Block block = world.getBlockAt(items.x, items.y, items.z);
if (block == null) {
return false;
}
BlockState state = block.getState();
if (state != null && state instanceof InventoryHolder) {
InventoryHolder holder = ((InventoryHolder) state);
Inventory inv = holder.getInventory();
for (int i = 0; i < items.id.length; i++) {
ItemStack item = new ItemStack(items.id[i], items.amount[i], items.data[i]);
inv.addItem(item);
}
state.update(true);
return true;
}
return false;
}
@Override
public boolean isBlockSolid(PlotBlock block) {
try {
Material material = Material.getMaterial(block.id);
if (material.isBlock() && material.isSolid() && !material.hasGravity()) {
Class<? extends MaterialData> data = material.getData();
if ((data.equals(MaterialData.class) && !material.isTransparent() && material.isOccluding()) || data.equals(Tree.class) || data.equals(Sandstone.class) || data.equals(Wool.class) || data.equals(Step.class) || data.equals(WoodenStep.class)) {
switch (material) {
case NOTE_BLOCK:
case MOB_SPAWNER: {
return false;
}
default:
return true;
}
}
}
return false;
}
catch (Exception e) {
return false;
}
}
@Override
public String getClosestMatchingName(PlotBlock block) {
try {
return Material.getMaterial(block.id).name();
}
catch (Exception e) {
return null;
}
}
@Override
public StringComparison<PlotBlock>.ComparisonResult getClosestBlock(String name) {
try {
double match;
short id;
byte data;
String[] split = name.split(":");
if (split.length == 2) {
data = Byte.parseByte(split[1]);
name = split[0];
}
else {
data = 0;
}
if (StringUtils.isNumeric(split[0])) {
id = Short.parseShort(split[0]);
match = 0;
}
else {
StringComparison<Material>.ComparisonResult comparison = new StringComparison<Material>(name, Material.values()).getBestMatchAdvanced();
match = comparison.match;
id = (short) comparison.best.getId();
}
PlotBlock block = new PlotBlock(id, data);
StringComparison<PlotBlock> outer = new StringComparison<PlotBlock>();
return outer.new ComparisonResult(match, block);
}
catch (Exception e) {}
return null;
}
}

View File

@ -0,0 +1,713 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// PlotSquared - A plot manager and world generator for the Bukkit API /
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters /
// /
// This program is free software; you can redistribute it and/or modify /
// it under the terms of the GNU General Public License as published by /
// the Free Software Foundation; either version 3 of the License, or /
// (at your option) any later version. /
// /
// This program is distributed in the hope that it will be useful, /
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the /
// GNU General Public License for more details. /
// /
// You should have received a copy of the GNU General Public License /
// along with this program; if not, write to the Free Software Foundation, /
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /
// /
// You can contact us via: support@intellectualsites.com /
////////////////////////////////////////////////////////////////////////////////////////////////////
package com.plotsquared.bukkit.util.bukkit;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.net.Proxy;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.UUID;
import java.util.logging.Level;
import java.util.zip.GZIPOutputStream;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.scheduler.BukkitTask;
import com.intellectualcrafters.configuration.InvalidConfigurationException;
import com.intellectualcrafters.configuration.file.YamlConfiguration;
import com.intellectualcrafters.plot.PS;
public class Metrics {
/**
* The current revision number
*/
private final static int REVISION = 7;
/**
* The base url of the metrics domain
*/
private static final String BASE_URL = "http://report.mcstats.org";
/**
* The url used to report a server's status
*/
private static final String REPORT_URL = "/plugin/%s";
/**
* Interval of time to ping (in minutes)
*/
private static final int PING_INTERVAL = 15;
/**
* The plugin this metrics submits for
*/
private final Plugin plugin;
/**
* All of the custom graphs to submit to metrics
*/
private final Set<Graph> graphs = Collections.synchronizedSet(new HashSet<Graph>());
/**
* The plugin configuration file
*/
private final YamlConfiguration configuration;
/**
* The plugin configuration file
*/
private final File configurationFile;
/**
* Unique server id
*/
private final String guid;
/**
* Debug mode
*/
private final boolean debug;
/**
* Lock for synchronization
*/
private final Object optOutLock = new Object();
/**
* The scheduled task
*/
private volatile BukkitTask task = null;
public Metrics(final Plugin plugin) throws IOException {
if (plugin == null) {
throw new IllegalArgumentException("Plugin cannot be null");
}
this.plugin = plugin;
// load the config
this.configurationFile = getConfigFile();
this.configuration = YamlConfiguration.loadConfiguration(this.configurationFile);
// add some defaults
this.configuration.addDefault("opt-out", false);
this.configuration.addDefault("guid", UUID.randomUUID().toString());
this.configuration.addDefault("debug", false);
// Do we need to create the file?
if (this.configuration.get("guid", null) == null) {
this.configuration.options().header("http://mcstats.org").copyDefaults(true);
this.configuration.save(this.configurationFile);
}
// Load the guid then
this.guid = this.configuration.getString("guid");
this.debug = this.configuration.getBoolean("debug", false);
}
/**
* GZip compress a string of bytes
*
* @param input
*
* @return byte[] the file as a byte array
*/
public static byte[] gzip(final String input) {
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream gzos = null;
try {
gzos = new GZIPOutputStream(baos);
gzos.write(input.getBytes("UTF-8"));
} catch (final IOException e) {
e.printStackTrace();
} finally {
if (gzos != null) {
try {
gzos.close();
} catch (final IOException ignore) {
}
}
}
return baos.toByteArray();
}
/**
* Appends a json encoded key/value pair to the given string builder.
*
* @param json
* @param key
* @param value
*
* @throws UnsupportedEncodingException
*/
private static void appendJSONPair(final StringBuilder json, final String key, final String value) throws UnsupportedEncodingException {
boolean isValueNumeric = false;
try {
if (value.equals("0") || !value.endsWith("0")) {
Double.parseDouble(value);
isValueNumeric = true;
}
} catch (final NumberFormatException e) {
isValueNumeric = false;
}
if (json.charAt(json.length() - 1) != '{') {
json.append(',');
}
json.append(escapeJSON(key));
json.append(':');
if (isValueNumeric) {
json.append(value);
} else {
json.append(escapeJSON(value));
}
}
/**
* Escape a string to create a valid JSON string
*
* @param text
*
* @return String
*/
private static String escapeJSON(final String text) {
final StringBuilder builder = new StringBuilder();
builder.append('"');
for (int index = 0; index < text.length(); index++) {
final char chr = text.charAt(index);
switch (chr) {
case '"':
case '\\':
builder.append('\\');
builder.append(chr);
break;
case '\b':
builder.append("\\b");
break;
case '\t':
builder.append("\\t");
break;
case '\n':
builder.append("\\n");
break;
case '\r':
builder.append("\\r");
break;
default:
if (chr < ' ') {
final String t = "000" + Integer.toHexString(chr);
builder.append("\\u" + t.substring(t.length() - 4));
} else {
builder.append(chr);
}
break;
}
}
builder.append('"');
return builder.toString();
}
/**
* Encode text as UTF-8
*
* @param text the text to encode
*
* @return the encoded text, as UTF-8
*/
private static String urlEncode(final String text) throws UnsupportedEncodingException {
return URLEncoder.encode(text, "UTF-8");
}
/**
* Construct and create a Graph that can be used to separate specific plotters to their own graphs on the metrics
* website. Plotters can be added to the graph object returned.
*
* @param name The name of the graph
*
* @return Graph object created. Will never return NULL under normal circumstances unless bad parameters are given
*/
public Graph createGraph(final String name) {
if (name == null) {
throw new IllegalArgumentException("Graph name cannot be null");
}
// Construct the graph object
final Graph graph = new Graph(name);
// Now we can add our graph
this.graphs.add(graph);
// and return back
return graph;
}
/**
* Add a Graph object to BukkitMetrics that represents data for the plugin that should be sent to the backend
*
* @param graph The name of the graph
*/
public void addGraph(final Graph graph) {
if (graph == null) {
throw new IllegalArgumentException("Graph cannot be null");
}
this.graphs.add(graph);
}
/**
* Start measuring statistics. This will immediately create an async repeating task as the plugin and send the
* initial data to the metrics backend, and then after that it will post in increments of PING_INTERVAL * 1200
* ticks.
*
* @return True if statistics measuring is running, otherwise false.
*/
public boolean start() {
synchronized (this.optOutLock) {
// Did we opt out?
if (isOptOut()) {
return false;
}
// Is metrics already running?
if (this.task != null) {
return true;
}
// Begin hitting the server with glorious data
this.task = this.plugin.getServer().getScheduler().runTaskTimerAsynchronously(this.plugin, new Runnable() {
private boolean firstPost = true;
@Override
public void run() {
try {
// This has to be synchronized or it can collide
// with
// the disable method.
synchronized (Metrics.this.optOutLock) {
// Disable Task, if it is running and the
// server
// owner decided to opt-out
if (isOptOut() && (Metrics.this.task != null)) {
Metrics.this.task.cancel();
Metrics.this.task = null;
// Tell all plotters to stop gathering
// information.
for (final Graph graph : Metrics.this.graphs) {
graph.onOptOut();
}
}
}
// We use the inverse of firstPost because if it
// is the
// first time we are posting,
// it is not a interval ping, so it evaluates to
// FALSE
// Each time thereafter it will evaluate to
// TRUE, i.e
// PING!
postPlugin(!this.firstPost);
// After the first post we set firstPost to
// false
// Each post thereafter will be a ping
this.firstPost = false;
} catch (final IOException e) {
if (Metrics.this.debug) {
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + e.getMessage());
}
}
}
}, 0, PING_INTERVAL * 1200);
return true;
}
}
/**
* Has the server owner denied plugin metrics?
*
* @return true if metrics should be opted out of it
*/
public boolean isOptOut() {
synchronized (this.optOutLock) {
try {
// Reload the metrics file
this.configuration.load(getConfigFile());
} catch (final IOException ex) {
if (this.debug) {
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage());
}
return true;
} catch (final InvalidConfigurationException ex) {
if (this.debug) {
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage());
}
return true;
}
return this.configuration.getBoolean("opt-out", false);
}
}
/**
* Enables metrics for the server by setting "opt-out" to false in the config file and starting the metrics task.
*
* @throws java.io.IOException
*/
public void enable() throws IOException {
// This has to be synchronized or it can collide with the check in the
// task.
synchronized (this.optOutLock) {
// Check if the server owner has already set opt-out, if not, set
// it.
if (isOptOut()) {
this.configuration.set("opt-out", false);
this.configuration.save(this.configurationFile);
}
// Enable Task, if it is not running
if (this.task == null) {
start();
}
}
}
/**
* Disables metrics for the server by setting "opt-out" to true in the config file and canceling the metrics task.
*
* @throws java.io.IOException
*/
public void disable() throws IOException {
// This has to be synchronized or it can collide with the check in the
// task.
synchronized (this.optOutLock) {
// Check if the server owner has already set opt-out, if not, set
// it.
if (!isOptOut()) {
this.configuration.set("opt-out", true);
this.configuration.save(this.configurationFile);
}
// Disable Task, if it is running
if (this.task != null) {
this.task.cancel();
this.task = null;
}
}
}
/**
* Gets the File object of the config file that should be used to store data such as the GUID and opt-out status
*
* @return the File object for the config file
*/
public File getConfigFile() {
// I believe the easiest way to get the base folder (e.g craftbukkit set
// via -P) for plugins to use
// is to abuse the plugin object we already have
// plugin.getDataFolder() => base/plugins/PluginA/
// pluginsFolder => base/plugins/
// The base is not necessarily relative to the startup directory.
final File pluginsFolder = this.plugin.getDataFolder().getParentFile();
// return => base/plugins/PluginMetrics/config.yml
return new File(new File(pluginsFolder, "PluginMetrics"), "config.yml");
}
/**
* Generic method that posts a plugin to the metrics website
*/
private void postPlugin(final boolean isPing) throws IOException {
// Server software specific section
final PluginDescriptionFile description = this.plugin.getDescription();
final String pluginName = description.getName();
final boolean onlineMode = Bukkit.getServer().getOnlineMode(); // TRUE
// if
// online
// mode
// is
// enabled
final String pluginVersion = description.getVersion();
final String serverVersion = Bukkit.getVersion();
int playersOnline = 0;
try {
if (Bukkit.class.getMethod("getOnlinePlayers", new Class<?>[0]).getReturnType() == Collection.class) {
playersOnline = ((Collection<?>) Bukkit.class.getMethod("getOnlinePlayers", new Class<?>[0]).invoke(null, new Object[0])).size();
} else {
playersOnline = ((Player[]) Bukkit.class.getMethod("getOnlinePlayers", new Class<?>[0]).invoke(null, new Object[0])).length;
}
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException ex) {
}
// END server software specific section -- all code below does not use
// any code outside of this class / Java
// Construct the post data
final StringBuilder json = new StringBuilder(1024);
json.append('{');
// The plugin's description file containg all of the plugin data such as
// name, version, author, etc
appendJSONPair(json, "guid", this.guid);
appendJSONPair(json, "plugin_version", pluginVersion);
appendJSONPair(json, "server_version", serverVersion);
appendJSONPair(json, "players_online", Integer.toString(playersOnline));
// New data as of R6
final String osname = System.getProperty("os.name");
String osarch = System.getProperty("os.arch");
final String osversion = System.getProperty("os.version");
final String java_version = System.getProperty("java.version");
final int coreCount = Runtime.getRuntime().availableProcessors();
// normalize os arch .. amd64 -> x86_64
if (osarch.equals("amd64")) {
osarch = "x86_64";
}
appendJSONPair(json, "osname", osname);
appendJSONPair(json, "osarch", osarch);
appendJSONPair(json, "osversion", osversion);
appendJSONPair(json, "cores", Integer.toString(coreCount));
appendJSONPair(json, "auth_mode", onlineMode ? "1" : "0");
appendJSONPair(json, "java_version", java_version);
// If we're pinging, append it
if (isPing) {
appendJSONPair(json, "ping", "1");
}
if (this.graphs.size() > 0) {
synchronized (this.graphs) {
json.append(',');
json.append('"');
json.append("graphs");
json.append('"');
json.append(':');
json.append('{');
boolean firstGraph = true;
for (final Graph graph : this.graphs) {
final StringBuilder graphJson = new StringBuilder();
graphJson.append('{');
for (final Plotter plotter : graph.getPlotters()) {
appendJSONPair(graphJson, plotter.getColumnName(), Integer.toString(plotter.getValue()));
}
graphJson.append('}');
if (!firstGraph) {
json.append(',');
}
json.append(escapeJSON(graph.getName()));
json.append(':');
json.append(graphJson);
firstGraph = false;
}
json.append('}');
}
}
// close json
json.append('}');
// Create the url
final URL url = new URL(BASE_URL + String.format(REPORT_URL, urlEncode(pluginName)));
// Connect to the website
URLConnection connection;
// Mineshafter creates a socks proxy, so we can safely bypass it
// It does not reroute POST requests so we need to go around it
if (isMineshafterPresent()) {
connection = url.openConnection(Proxy.NO_PROXY);
} else {
connection = url.openConnection();
}
final byte[] uncompressed = json.toString().getBytes();
final byte[] compressed = gzip(json.toString());
// Headers
connection.addRequestProperty("User-Agent", "MCStats/" + REVISION);
connection.addRequestProperty("Content-Type", "application/json");
connection.addRequestProperty("Content-Encoding", "gzip");
connection.addRequestProperty("Content-Length", Integer.toString(compressed.length));
connection.addRequestProperty("Accept", "application/json");
connection.addRequestProperty("Connection", "close");
connection.setDoOutput(true);
if (this.debug) {
PS.log("[Metrics] Prepared request for " + pluginName + " uncompressed=" + uncompressed.length + " compressed=" + compressed.length);
}
// Write the data
final OutputStream os = connection.getOutputStream();
os.write(compressed);
os.flush();
// Now read the response
final BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String response = reader.readLine();
// close resources
os.close();
reader.close();
if ((response == null) || response.startsWith("ERR") || response.startsWith("7")) {
if (response == null) {
response = "null";
} else if (response.startsWith("7")) {
response = response.substring(response.startsWith("7,") ? 2 : 1);
}
throw new IOException(response);
} else {
// Is this the first update this hour?
if (response.equals("1") || response.contains("This is your first update this hour")) {
synchronized (this.graphs) {
for (final Graph graph : this.graphs) {
for (final Plotter plotter : graph.getPlotters()) {
plotter.reset();
}
}
}
}
}
}
/**
* Check if mineshafter is present. If it is, we need to bypass it to send POST requests
*
* @return true if mineshafter is installed on the server
*/
private boolean isMineshafterPresent() {
try {
Class.forName("mineshafter.MineServer");
return true;
} catch (final Exception e) {
return false;
}
}
/**
* Represents a custom graph on the website
*/
public static class Graph {
/**
* The graph's name, alphanumeric and spaces only :) If it does not comply to the above when submitted, it is
* rejected
*/
private final String name;
/**
* The set of plotters that are contained within this graph
*/
private final Set<Plotter> plotters = new LinkedHashSet<Plotter>();
private Graph(final String name) {
this.name = name;
}
/**
* Gets the graph's name
*
* @return the Graph's name
*/
public String getName() {
return this.name;
}
/**
* Add a plotter to the graph, which will be used to plot entries
*
* @param plotter the plotter to add to the graph
*/
public void addPlotter(final Plotter plotter) {
this.plotters.add(plotter);
}
/**
* Remove a plotter from the graph
*
* @param plotter the plotter to remove from the graph
*/
public void removePlotter(final Plotter plotter) {
this.plotters.remove(plotter);
}
/**
* Gets an <b>unmodifiable</b> set of the plotter objects in the graph
*
* @return an unmodifiable {@link java.util.Set} of the plotter objects
*/
public Set<Plotter> getPlotters() {
return Collections.unmodifiableSet(this.plotters);
}
@Override
public int hashCode() {
return this.name.hashCode();
}
@Override
public boolean equals(final Object object) {
if (!(object instanceof Graph)) {
return false;
}
final Graph graph = (Graph) object;
return graph.name.equals(this.name);
}
/**
* Called when the server owner decides to opt-out of BukkitMetrics while the server is running.
*/
protected void onOptOut() {
}
}
/**
* Interface used to collect custom data for a plugin
*/
public static abstract class Plotter {
/**
* The plot's name
*/
private final String name;
/**
* Construct a plotter with the default plot name
*/
public Plotter() {
this("Default");
}
/**
* Construct a plotter with a specific plot name
*
* @param name the name of the plotter to use, which will show up on the website
*/
public Plotter(final String name) {
this.name = name;
}
/**
* Get the current value for the plotted point. Since this function defers to an external function it may or may
* not return immediately thus cannot be guaranteed to be thread friendly or safe. This function can be called
* from any thread so care should be taken when accessing resources that need to be synchronized.
*
* @return the current value for the point to be plotted.
*/
public abstract int getValue();
/**
* Get the column name for the plotted point
*
* @return the plotted point's column name
*/
public String getColumnName() {
return this.name;
}
/**
* Called after the website graphs have been updated
*/
public void reset() {
}
@Override
public int hashCode() {
return getColumnName().hashCode();
}
@Override
public boolean equals(final Object object) {
if (!(object instanceof Plotter)) {
return false;
}
final Plotter plotter = (Plotter) object;
return plotter.name.equals(this.name) && (plotter.getValue() == getValue());
}
}
}

View File

@ -0,0 +1,92 @@
package com.plotsquared.bukkit.util.bukkit;
import static com.intellectualcrafters.plot.util.ReflectionUtils.callConstructor;
import static com.intellectualcrafters.plot.util.ReflectionUtils.callMethod;
import static com.intellectualcrafters.plot.util.ReflectionUtils.getCbClass;
import static com.intellectualcrafters.plot.util.ReflectionUtils.getNmsClass;
import static com.intellectualcrafters.plot.util.ReflectionUtils.getUtilClass;
import static com.intellectualcrafters.plot.util.ReflectionUtils.makeConstructor;
import static com.intellectualcrafters.plot.util.ReflectionUtils.makeMethod;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
public class OfflinePlayerUtil {
public static Player loadPlayer(final String name) {
return loadPlayer(Bukkit.getOfflinePlayer(name));
}
public static Player loadPlayer(final UUID id) {
return loadPlayer(Bukkit.getOfflinePlayer(id));
}
public static Player loadPlayer(final OfflinePlayer player) {
if (player == null) {
return null;
}
if (player instanceof Player) {
return (Player) player;
}
return loadPlayer(player.getUniqueId(), player.getName());
}
private static Player loadPlayer(final UUID id, final String name) {
final Object server = getMinecraftServer();
final Object interactManager = newPlayerInteractManager();
final Object worldServer = getWorldServer();
final Object profile = newGameProfile(id, name);
final Class<?> entityPlayerClass = getNmsClass("EntityPlayer");
final Constructor entityPlayerConstructor = makeConstructor(entityPlayerClass, getNmsClass("MinecraftServer"), getNmsClass("WorldServer"), getUtilClass("com.mojang.authlib.GameProfile"), getNmsClass("PlayerInteractManager"));
final Object entityPlayer = callConstructor(entityPlayerConstructor, server, worldServer, profile, interactManager);
final Player player = (Player) getBukkitEntity(entityPlayer);
return player;
}
private static Object newGameProfile(final UUID id, final String name) {
final Class<?> gameProfileClass = getUtilClass("com.mojang.authlib.GameProfile");
if (gameProfileClass == null) { //Before uuids
return name;
}
Constructor gameProfileConstructor = null;
gameProfileConstructor = makeConstructor(gameProfileClass, UUID.class, String.class);
if (gameProfileConstructor == null) { //Verson has string constructor
gameProfileConstructor = makeConstructor(gameProfileClass, String.class, String.class);
return callConstructor(gameProfileConstructor, id.toString(), name);
} else { //Version has uuid constructor
return callConstructor(gameProfileConstructor, id, name);
}
}
private static Object newPlayerInteractManager() {
final Object worldServer = getWorldServer();
final Class<?> playerInteractClass = getNmsClass("PlayerInteractManager");
final Class<?> worldClass = getNmsClass("World");
final Constructor c = makeConstructor(playerInteractClass, worldClass);
return callConstructor(c, worldServer);
}
private static Object getWorldServer() {
final Object server = getMinecraftServer();
final Class<?> minecraftServerClass = getNmsClass("MinecraftServer");
final Method getWorldServer = makeMethod(minecraftServerClass, "getWorldServer", int.class);
return callMethod(getWorldServer, server, 0);
}
//NMS Utils
private static Object getMinecraftServer() {
return callMethod(makeMethod(getCbClass("CraftServer"), "getServer"), Bukkit.getServer());
}
private static Entity getBukkitEntity(final Object o) {
final Method getBukkitEntity = makeMethod(o.getClass(), "getBukkitEntity");
return callMethod(getBukkitEntity, o);
}
}

View File

@ -0,0 +1,103 @@
package com.plotsquared.bukkit.util.bukkit;
import static com.intellectualcrafters.plot.util.ReflectionUtils.getRefClass;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.World;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.object.ChunkLoc;
import com.intellectualcrafters.plot.util.ReflectionUtils.RefClass;
import com.intellectualcrafters.plot.util.ReflectionUtils.RefConstructor;
import com.intellectualcrafters.plot.util.ReflectionUtils.RefField;
import com.intellectualcrafters.plot.util.ReflectionUtils.RefMethod;
/**
* An utility that can be used to send chunks, rather than using bukkit code to do so (uses heavy NMS)
*
* @author Empire92
*/
public class SendChunk {
// Ref Class
private static final RefClass classWorld = getRefClass("{nms}.World");
private static final RefClass classEntityPlayer = getRefClass("{nms}.EntityPlayer");
private static final RefClass classChunkCoordIntPair = getRefClass("{nms}.ChunkCoordIntPair");
private static final RefClass classCraftChunk = getRefClass("{cb}.CraftChunk");
private static final RefClass classChunk = getRefClass("{nms}.Chunk");
private static boolean v1_7_10 = PS.get().IMP.checkVersion(1, 7, 10) && !PS.get().IMP.checkVersion(1, 8, 0);
// Ref Method
private static RefMethod methodGetHandle;
// Ref Field
private static RefField chunkCoordIntPairQueue;
private static RefField players;
private static RefField locX;
private static RefField locZ;
private static RefField world;
// Ref Constructor
private static RefConstructor ChunkCoordIntPairCon;
/**
* Constructor
*
* @throws NoSuchMethodException
*/
public SendChunk() throws NoSuchMethodException {
methodGetHandle = classCraftChunk.getMethod("getHandle");
chunkCoordIntPairQueue = classEntityPlayer.getField("chunkCoordIntPairQueue");
players = classWorld.getField("players");
locX = classEntityPlayer.getField("locX");
locZ = classEntityPlayer.getField("locZ");
world = classChunk.getField("world");
ChunkCoordIntPairCon = classChunkCoordIntPair.getConstructor(int.class, int.class);
}
public static void sendChunk(final Collection<Chunk> chunks) {
int diffx, diffz;
final int view = Bukkit.getServer().getViewDistance() << 4;
for (final Chunk chunk : chunks) {
if (!chunk.isLoaded()) {
continue;
}
boolean unload = true;
final Object c = methodGetHandle.of(chunk).call();
final Object w = world.of(c).get();
final Object p = players.of(w).get();
for (final Object ep : (List<Object>) p) {
final int x = ((Double) locX.of(ep).get()).intValue();
final int z = ((Double) locZ.of(ep).get()).intValue();
diffx = Math.abs(x - (chunk.getX() << 4));
diffz = Math.abs(z - (chunk.getZ() << 4));
if ((diffx <= view) && (diffz <= view)) {
unload = false;
if (v1_7_10) {
chunk.getWorld().refreshChunk(chunk.getX(), chunk.getZ());
chunk.load(true);
}
else {
final Object pair = ChunkCoordIntPairCon.create(chunk.getX(), chunk.getZ());
final Object pq = chunkCoordIntPairQueue.of(ep).get();
((List) pq).add(pair);
}
}
}
if (unload) {
chunk.unload(true, true);
}
}
}
public static void sendChunk(final String worldname, final List<ChunkLoc> locs) {
final World myworld = Bukkit.getWorld(worldname);
final ArrayList<Chunk> chunks = new ArrayList<>();
for (final ChunkLoc loc : locs) {
chunks.add(myworld.getChunkAt(loc.x, loc.z));
}
sendChunk(chunks);
}
}

View File

@ -0,0 +1,135 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// PlotSquared - A plot manager and world generator for the Bukkit API /
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters /
// /
// This program is free software; you can redistribute it and/or modify /
// it under the terms of the GNU General Public License as published by /
// the Free Software Foundation; either version 3 of the License, or /
// (at your option) any later version. /
// /
// This program is distributed in the hope that it will be useful, /
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the /
// GNU General Public License for more details. /
// /
// You should have received a copy of the GNU General Public License /
// along with this program; if not, write to the Free Software Foundation, /
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /
// /
// You can contact us via: support@intellectualsites.com /
////////////////////////////////////////////////////////////////////////////////////////////////////
package com.plotsquared.bukkit.util.bukkit;
import static com.intellectualcrafters.plot.util.ReflectionUtils.getRefClass;
import java.util.Collection;
import java.util.HashMap;
import org.bukkit.Chunk;
import com.intellectualcrafters.plot.object.ChunkLoc;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.ReflectionUtils.RefClass;
import com.intellectualcrafters.plot.util.ReflectionUtils.RefMethod;
import com.intellectualcrafters.plot.util.TaskManager;
/**
* SetBlockFast class<br> Used to do fast world editing
*
* @author Empire92
*/
public class SetBlockFast extends BukkitSetBlockManager {
private static final RefClass classBlock = getRefClass("{nms}.Block");
private static final RefClass classChunk = getRefClass("{nms}.Chunk");
private static final RefClass classWorld = getRefClass("{nms}.World");
private static final RefClass classCraftWorld = getRefClass("{cb}.CraftWorld");
private static RefMethod methodGetHandle;
private static RefMethod methodGetChunkAt;
private static RefMethod methodA;
private static RefMethod methodGetById;
public static HashMap<ChunkLoc, Chunk> toUpdate = new HashMap<>();
/**
* Constructor
*
* @throws NoSuchMethodException
*/
public SetBlockFast() throws NoSuchMethodException {
methodGetHandle = classCraftWorld.getMethod("getHandle");
methodGetChunkAt = classWorld.getMethod("getChunkAt", int.class, int.class);
methodA = classChunk.getMethod("a", int.class, int.class, int.class, classBlock, int.class);
methodGetById = classBlock.getMethod("getById", int.class);
TaskManager.runTaskRepeat(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
update(toUpdate.values());
toUpdate = new HashMap<>();
}
}, 20);
}
private ChunkLoc lastLoc = null;
/**
* Set the block at the location
*
* @param world World in which the block should be set
* @param x X Coordinate
* @param y Y Coordinate
* @param z Z Coordinate
* @param blockId Block ID
* @param data Block Data Value
*
*/
@Override
public void set(final org.bukkit.World world, final int x, final int y, final int z, final int blockId, final byte data) {
if (blockId == -1) {
world.getBlockAt(x, y, z).setData(data, false);
return;
}
int X = x >> 4;
int Z = z >> 4;
ChunkLoc loc = new ChunkLoc(X, Z);
if (!loc.equals(lastLoc)) {
Chunk chunk = toUpdate.get(loc);
if (chunk == null) {
chunk = world.getChunkAt(X, Z);
toUpdate.put(loc, chunk);
}
chunk.load(false);
}
final Object w = methodGetHandle.of(world).call();
final Object chunk = methodGetChunkAt.of(w).call(x >> 4, z >> 4);
final Object block = methodGetById.of(null).call(blockId);
methodA.of(chunk).call(x & 0x0f, y, z & 0x0f, block, data);
}
/**
* Update chunks
*
* @param chunks list of chunks to update
*/
@Override
public void update(final Collection<Chunk> chunks) {
if (chunks.size() == 0) {
return;
}
if (!MainUtil.canSendChunk) {
for (Chunk chunk : chunks) {
chunk.getWorld().refreshChunk(chunk.getX(), chunk.getZ());
chunk.unload(true, false);
chunk.load();
}
return;
}
try {
SendChunk.sendChunk(chunks);
} catch (final Throwable e) {
MainUtil.canSendChunk = false;
}
}
}

View File

@ -0,0 +1,348 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// PlotSquared - A plot manager and world generator for the Bukkit API /
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters /
// /
// This program is free software; you can redistribute it and/or modify /
// it under the terms of the GNU General Public License as published by /
// the Free Software Foundation; either version 3 of the License, or /
// (at your option) any later version. /
// /
// This program is distributed in the hope that it will be useful, /
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the /
// GNU General Public License for more details. /
// /
// You should have received a copy of the GNU General Public License /
// along with this program; if not, write to the Free Software Foundation, /
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /
// /
// You can contact us via: support@intellectualsites.com /
////////////////////////////////////////////////////////////////////////////////////////////////////
package com.plotsquared.bukkit.util.bukkit;
import static com.intellectualcrafters.plot.util.ReflectionUtils.getRefClass;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import org.bukkit.Chunk;
import org.bukkit.World;
import org.bukkit.block.Block;
import com.intellectualcrafters.plot.object.ChunkLoc;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.ReflectionUtils.RefClass;
import com.intellectualcrafters.plot.util.ReflectionUtils.RefConstructor;
import com.intellectualcrafters.plot.util.ReflectionUtils.RefMethod;
import com.intellectualcrafters.plot.util.TaskManager;
/**
* SetBlockFast class<br> Used to do fast world editing
*
* @author Empire92
*/
public class SetBlockFast_1_8 extends BukkitSetBlockManager {
private static final RefClass classBlock = getRefClass("{nms}.Block");
private static final RefClass classBlockPosition = getRefClass("{nms}.BlockPosition");
private static final RefClass classIBlockData = getRefClass("{nms}.IBlockData");
private static final RefClass classChunk = getRefClass("{nms}.Chunk");
private static final RefClass classWorld = getRefClass("{nms}.World");
private static final RefClass classCraftWorld = getRefClass("{cb}.CraftWorld");
private static RefMethod methodGetHandle;
private static RefMethod methodGetChunkAt;
private static RefMethod methodA;
private static RefMethod methodGetByCombinedId;
private static RefConstructor constructorBlockPosition;
public static HashMap<ChunkLoc, Chunk> toUpdate = new HashMap<>();
/**
* Constructor
*
* @throws NoSuchMethodException
*/
public SetBlockFast_1_8() throws NoSuchMethodException {
constructorBlockPosition = classBlockPosition.getConstructor(int.class, int.class, int.class);
methodGetByCombinedId = classBlock.getMethod("getByCombinedId", int.class);
methodGetHandle = classCraftWorld.getMethod("getHandle");
methodGetChunkAt = classWorld.getMethod("getChunkAt", int.class, int.class);
methodA = classChunk.getMethod("a", classBlockPosition, classIBlockData);
TaskManager.runTaskRepeat(new Runnable() {
@Override
public void run() {
int count = 0;
ArrayList<Chunk> chunks = new ArrayList<Chunk>();
Iterator<Entry<ChunkLoc, Chunk>> i = toUpdate.entrySet().iterator();
while (i.hasNext() && count < 1024) {
chunks.add(i.next().getValue());
i.remove();
count++;
}
if (count == 0) {
return;
}
update(chunks);
}
}, 20);
}
private ChunkLoc lastLoc = null;
/**
* Set the block at the location
*
* @param world World in which the block should be set
* @param x X Coordinate
* @param y Y Coordinate
* @param z Z Coordinate
* @param id Block ID
* @param data Block Data Value
*/
@SuppressWarnings("deprecation")
@Override
public void set(final World world, final int x, final int y, final int z, final int id, final byte data) {
if (id == -1) {
world.getBlockAt(x, y, z).setData(data, false);
return;
}
// Start blockstate workaround //
switch (id) {
case 54:
case 130:
case 142:
case 27:
case 137:
case 52:
case 154:
case 84:
case 25:
case 144:
case 138:
case 176:
case 177:
case 63:
case 68:
case 323:
case 117:
case 116:
case 28:
case 66:
case 157:
case 61:
case 62:
case 140:
case 146:
case 149:
case 150:
case 158:
case 23:
case 123:
case 124:
case 29:
case 33:
case 151:
case 178: {
final Block block = world.getBlockAt(x, y, z);
if (block.getData() == data) {
if (block.getTypeId() != id) {
block.setTypeId(id, false);
}
} else {
if (block.getTypeId() == id) {
block.setData(data, false);
} else {
block.setTypeIdAndData(id, data, false);
}
}
return;
}
}
// Start data value shortcut
Block block = world.getBlockAt(x, y, z);
int currentId = block.getTypeId();
if (currentId == id) {
switch(id) {
case 0:
case 2:
case 4:
case 13:
case 14:
case 15:
case 20:
case 21:
case 22:
case 24:
case 25:
case 30:
case 32:
case 37:
case 39:
case 40:
case 41:
case 42:
case 45:
case 46:
case 47:
case 48:
case 49:
case 50:
case 51:
case 52:
case 54:
case 55:
case 56:
case 57:
case 58:
case 60:
case 61:
case 62:
case 7:
case 8:
case 9:
case 10:
case 11:
case 73:
case 74:
case 75:
case 76:
case 78:
case 79:
case 80:
case 81:
case 82:
case 83:
case 84:
case 85:
case 87:
case 88:
case 101:
case 102:
case 103:
case 110:
case 112:
case 113:
case 117:
case 121:
case 122:
case 123:
case 124:
case 129:
case 133:
case 138:
case 137:
case 140:
case 165:
case 166:
case 169:
case 170:
case 172:
case 173:
case 174:
case 176:
case 177:
case 181:
case 182:
case 188:
case 189:
case 190:
case 191:
case 192: {
return;
}
}
if (block.getData() == data) {
return;
}
block.setData(data);
return;
}
switch(currentId) {
case 54:
case 130:
case 142:
case 27:
case 137:
case 52:
case 154:
case 84:
case 25:
case 144:
case 138:
case 176:
case 177:
case 63:
case 68:
case 323:
case 117:
case 116:
case 28:
case 66:
case 157:
case 61:
case 62:
case 140:
case 146:
case 149:
case 150:
case 158:
case 23:
case 123:
case 124:
case 29:
case 33:
case 151:
case 178: {
if (block.getData() == data) {
block.setTypeId(id, false);
} else {
block.setTypeIdAndData(id, data, false);
}
return;
}
}
// End blockstate workaround //
int X = x >> 4;
int Z = z >> 4;
ChunkLoc loc = new ChunkLoc(X, Z);
if (!loc.equals(lastLoc)) {
Chunk chunk = toUpdate.get(loc);
if (chunk == null) {
chunk = world.getChunkAt(X, Z);
toUpdate.put(loc, chunk);
}
chunk.load(false);
}
// check sign
final Object w = methodGetHandle.of(world).call();
final Object chunk = methodGetChunkAt.of(w).call(x >> 4, z >> 4);
final Object pos = constructorBlockPosition.create(x & 0x0f, y, z & 0x0f);
final Object combined = methodGetByCombinedId.of(null).call(id + (data << 12));
methodA.of(chunk).call(pos, combined);
}
@Override
public void update(final Collection<Chunk> chunks) {
if (chunks.size() == 0) {
return;
}
if (!MainUtil.canSendChunk) {
for (Chunk chunk : chunks) {
chunk.getWorld().refreshChunk(chunk.getX(), chunk.getZ());
chunk.unload(true, false);
chunk.load();
}
return;
}
try {
SendChunk.sendChunk(chunks);
} catch (final Throwable e) {
MainUtil.canSendChunk = false;
}
}
}

View File

@ -0,0 +1,48 @@
package com.plotsquared.bukkit.util.bukkit;
import java.util.Collection;
import org.bukkit.Chunk;
import org.bukkit.World;
import org.bukkit.block.Block;
import com.intellectualcrafters.plot.util.MainUtil;
public class SetBlockSlow extends BukkitSetBlockManager {
@Override
public void set(final World world, final int x, final int y, final int z, final int id, final byte data) {
final Block block = world.getBlockAt(x, y, z);
if (id == -1) {
block.setData(data, false);
return;
}
if (block.getData() == data) {
if (block.getTypeId() != id) {
block.setTypeId(id, false);
}
} else {
if (block.getTypeId() == id) {
block.setData(data, false);
} else {
block.setTypeIdAndData(id, data, false);
}
}
}
@Override
public void update(final Collection<Chunk> chunks) {
if (MainUtil.canSendChunk) {
try {
SendChunk.sendChunk(chunks);
} catch (final Throwable e) {
MainUtil.canSendChunk = false;
}
}
else {
for (Chunk chunk : chunks) {
chunk.unload();
chunk.load(true);
}
}
}
}

View File

@ -0,0 +1,55 @@
package com.plotsquared.bukkit.util.bukkit;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Iterator;
import org.bukkit.World;
import org.bukkit.generator.BlockPopulator;
import org.bukkit.generator.ChunkGenerator;
import com.intellectualcrafters.plot.PS;
import com.plotsquared.bukkit.generator.AugmentedPopulator;
import com.plotsquared.bukkit.util.SetupUtils;
public class SetGenCB {
public static void setGenerator(World world) throws Exception {
SetupUtils.manager.updateGenerators();
PS.get().removePlotWorldAbs(world.getName());
ChunkGenerator gen = world.getGenerator();
if (gen == null) {
return;
}
String name = gen.getClass().getCanonicalName();
boolean set = false;
for (ChunkGenerator newGen : SetupUtils.generators.values()) {
if (newGen.getClass().getCanonicalName().equals(name)) {
// set generator
Field generator = world.getClass().getDeclaredField("generator");
Field populators = world.getClass().getDeclaredField("populators");
generator.setAccessible(true);
populators.setAccessible(true);
// Set populators (just in case)
populators.set(world, new ArrayList<>());
// Set generator
Constructor<? extends ChunkGenerator> constructor = newGen.getClass().getConstructor(String.class);
ChunkGenerator newNewGen = constructor.newInstance(world.getName());
generator.set(world, newNewGen);
populators.set(world, newNewGen.getDefaultPopulators(world));
// end
set = true;
break;
}
}
if (!set) {
Iterator<BlockPopulator> iter = world.getPopulators().iterator();
while (iter.hasNext()) {
if (iter.next() instanceof AugmentedPopulator) {
iter.remove();
}
}
}
PS.get().loadWorld(world.getName(), null);
}
}

View File

@ -0,0 +1,126 @@
package com.plotsquared.bukkit.util.bukkit;
import java.util.HashSet;
import java.util.Map;
import java.util.UUID;
import com.plotsquared.bukkit.util.bukkit.uuid.UUIDHandlerImplementation;
import com.google.common.collect.BiMap;
import com.intellectualcrafters.plot.PS;
import com.plotsquared.bukkit.object.BukkitOfflinePlayer;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.object.StringWrapper;
import com.intellectualcrafters.plot.uuid.UUIDWrapper;
public class UUIDHandler {
public static UUIDHandlerImplementation implementation;
public static void add(final StringWrapper name, final UUID uuid) {
implementation.add(name, uuid);
}
/**
* Get the map containing all names/uuids
*
* @return map with names + uuids
*
* @see com.google.common.collect.BiMap
*/
public static BiMap<StringWrapper, UUID> getUuidMap() {
return implementation.getUUIDMap();
}
/**
* Check if a uuid is cached
*
* @param uuid to check
*
* @return true of the uuid is cached
*
* @see com.google.common.collect.BiMap#containsValue(Object)
*/
public static boolean uuidExists(final UUID uuid) {
return implementation.uuidExists(uuid);
}
/**
* Check if a name is cached
*
* @param name to check
*
* @return true of the name is cached
*
* @see com.google.common.collect.BiMap#containsKey(Object)
*/
public static boolean nameExists(final StringWrapper name) {
return implementation.nameExists(name);
}
public static HashSet<UUID> getAllUUIDS() {
HashSet<UUID> uuids = new HashSet<>();
for (Plot plot : PS.get().getPlotsRaw()) {
if (plot.owner != null) {
uuids.add(plot.owner);
uuids.addAll(plot.getTrusted());
uuids.addAll(plot.getMembers());
uuids.addAll(plot.getDenied());
}
}
return uuids;
}
public static UUIDWrapper getUUIDWrapper() {
return implementation.getUUIDWrapper();
}
public static void setUUIDWrapper(final UUIDWrapper wrapper) {
implementation.setUUIDWrapper(wrapper);
}
public static void startCaching() {
implementation.startCaching();
}
public static void cache(final Map<StringWrapper, UUID> toAdd) {
implementation.cache(toAdd);
}
public static UUID getUUID(final PlotPlayer player) {
return implementation.getUUID(player);
}
public static UUID getUUID(final BukkitOfflinePlayer player) {
return implementation.getUUID(player);
}
public static String getName(final UUID uuid) {
return implementation.getName(uuid);
}
public static PlotPlayer getPlayer(final UUID uuid) {
return implementation.getPlayer(uuid);
}
public static PlotPlayer getPlayer(final String name) {
return implementation.getPlayer(name);
}
public static UUID getUUID(final String name) {
return implementation.getUUID(name);
}
public static Map<String, PlotPlayer> getPlayers() {
return implementation.getPlayers();
}
public static void cacheWorld(String world) {
implementation.cacheWorld(world);
}
public static void handleShutdown() {
implementation.handleShutdown();
}
}

View File

@ -0,0 +1,106 @@
package com.plotsquared.bukkit.util.bukkit.chat;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Collection;
import org.apache.commons.lang.Validate;
/**
* Represents a wrapper around an array class of an arbitrary reference type,
* which properly implements "value" hash code and equality functions.
* <p>
* This class is intended for use as a key to a map.
* </p>
* @author Glen Husman
* @param <E> The type of elements in the array.
* @see Arrays
*/
public final class ArrayWrapper<E> {
/**
* Creates an array wrapper with some elements.
* @param elements The elements of the array.
*/
public ArrayWrapper(E... elements){
setArray(elements);
}
private E[] _array;
/**
* Retrieves a reference to the wrapped array instance.
* @return The array wrapped by this instance.
*/
public E[] getArray(){
return _array;
}
/**
* Set this wrapper to wrap a new array instance.
* @param array The new wrapped array.
*/
public void setArray(E[] array){
Validate.notNull(array, "The array must not be null.");
_array = array;
}
/**
* Determines if this object has a value equivalent to another object.
* @see Arrays#equals(Object[], Object[])
*/
@SuppressWarnings("rawtypes")
@Override
public boolean equals(Object other)
{
if (!(other instanceof ArrayWrapper))
{
return false;
}
return Arrays.equals(_array, ((ArrayWrapper)other)._array);
}
/**
* Gets the hash code represented by this objects value.
* @see Arrays#hashCode(Object[])
* @return This object's hash code.
*/
@Override
public int hashCode()
{
return Arrays.hashCode(_array);
}
/**
* Converts an iterable element collection to an array of elements.
* The iteration order of the specified object will be used as the array element order.
* @param list The iterable of objects which will be converted to an array.
* @param c The type of the elements of the array.
* @return An array of elements in the specified iterable.
*/
@SuppressWarnings("unchecked")
public static <T> T[] toArray(Iterable<? extends T> list, Class<T> c) {
int size = -1;
if(list instanceof Collection<?>){
@SuppressWarnings("rawtypes")
Collection coll = (Collection)list;
size = coll.size();
}
if(size < 0){
size = 0;
// Ugly hack: Count it ourselves
for(@SuppressWarnings("unused") T element : list){
size++;
}
}
T[] result = (T[]) Array.newInstance(c, size);
int i = 0;
for(T element : list){ // Assumes iteration order is consistent
result[i++] = element; // Assign array element at index THEN increment counter
}
return result;
}
}

View File

@ -0,0 +1,845 @@
package com.plotsquared.bukkit.util.bukkit.chat;
import static com.plotsquared.bukkit.util.bukkit.chat.TextualComponent.rawText;
import java.io.IOException;
import java.io.StringWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import org.bukkit.Achievement;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.Statistic;
import org.bukkit.Statistic.Type;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.stream.JsonWriter;
import com.intellectualcrafters.configuration.serialization.ConfigurationSerializable;
import com.intellectualcrafters.configuration.serialization.ConfigurationSerialization;
/**
* Represents a formattable message. Such messages can use elements such as colors, formatting codes, hover and click data, and other features provided by the vanilla Minecraft <a href="http://minecraft.gamepedia.com/Tellraw#Raw_JSON_Text">JSON message formatter</a>.
* This class allows plugins to emulate the functionality of the vanilla Minecraft <a href="http://minecraft.gamepedia.com/Commands#tellraw">tellraw command</a>.
* <p>
* This class follows the builder pattern, allowing for method chaining.
* It is set up such that invocations of property-setting methods will affect the current editing component,
* and a call to {@link #then()} or {@link #then(Object)} will append a new editing component to the end of the message,
* optionally initializing it with text. Further property-setting method calls will affect that editing component.
* </p>
*/
public class FancyMessage implements JsonRepresentedObject, Cloneable, Iterable<MessagePart>, ConfigurationSerializable {
static{
ConfigurationSerialization.registerClass(FancyMessage.class);
}
private List<MessagePart> messageParts;
private String jsonString;
private boolean dirty;
private static Constructor<?> nmsPacketPlayOutChatConstructor;
@Override
public FancyMessage clone() throws CloneNotSupportedException{
FancyMessage instance = (FancyMessage)super.clone();
instance.messageParts = new ArrayList<MessagePart>(messageParts.size());
for(int i = 0; i < messageParts.size(); i++){
instance.messageParts.add(i, messageParts.get(i).clone());
}
instance.dirty = false;
instance.jsonString = null;
return instance;
}
/**
* Creates a JSON message with text.
* @param firstPartText The existing text in the message.
*/
public FancyMessage(final String firstPartText) {
this(rawText(firstPartText));
}
public FancyMessage(final TextualComponent firstPartText) {
messageParts = new ArrayList<MessagePart>();
messageParts.add(new MessagePart(firstPartText));
jsonString = null;
dirty = false;
if(nmsPacketPlayOutChatConstructor == null){
try {
nmsPacketPlayOutChatConstructor = Reflection.getNMSClass("PacketPlayOutChat").getDeclaredConstructor(Reflection.getNMSClass("IChatBaseComponent"));
nmsPacketPlayOutChatConstructor.setAccessible(true);
} catch (NoSuchMethodException e) {
Bukkit.getLogger().log(Level.SEVERE, "Could not find Minecraft method or constructor.", e);
} catch (SecurityException e) {
Bukkit.getLogger().log(Level.WARNING, "Could not access constructor.", e);
}
}
}
/**
* Creates a JSON message without text.
*/
public FancyMessage() {
this((TextualComponent)null);
}
/**
* Sets the text of the current editing component to a value.
* @param text The new text of the current editing component.
* @return This builder instance.
*/
public FancyMessage text(String text) {
MessagePart latest = latest();
latest.text = rawText(text);
dirty = true;
return this;
}
/**
* Sets the text of the current editing component to a value.
* @param text The new text of the current editing component.
* @return This builder instance.
*/
public FancyMessage text(TextualComponent text) {
MessagePart latest = latest();
latest.text = text;
dirty = true;
return this;
}
/**
* Sets the color of the current editing component to a value.
* @param color The new color of the current editing component.
* @return This builder instance.
* @exception IllegalArgumentException If the specified {@code ChatColor} enumeration value is not a color (but a format value).
*/
public FancyMessage color(final ChatColor color) {
if (!color.isColor()) {
throw new IllegalArgumentException(color.name() + " is not a color");
}
latest().color = color;
dirty = true;
return this;
}
/**
* Sets the stylization of the current editing component.
* @param styles The array of styles to apply to the editing component.
* @return This builder instance.
* @exception IllegalArgumentException If any of the enumeration values in the array do not represent formatters.
*/
public FancyMessage style(ChatColor... styles) {
for (final ChatColor style : styles) {
if (!style.isFormat()) {
throw new IllegalArgumentException(style.name() + " is not a style");
}
}
latest().styles.addAll(Arrays.asList(styles));
dirty = true;
return this;
}
/**
* Set the behavior of the current editing component to instruct the client to open a file on the client side filesystem when the currently edited part of the {@code FancyMessage} is clicked.
* @param path The path of the file on the client filesystem.
* @return This builder instance.
*/
public FancyMessage file(final String path) {
onClick("open_file", path);
return this;
}
/**
* Set the behavior of the current editing component to instruct the client to open a webpage in the client's web browser when the currently edited part of the {@code FancyMessage} is clicked.
* @param url The URL of the page to open when the link is clicked.
* @return This builder instance.
*/
public FancyMessage link(final String url) {
onClick("open_url", url);
return this;
}
/**
* Set the behavior of the current editing component to instruct the client to replace the chat input box content with the specified string when the currently edited part of the {@code FancyMessage} is clicked.
* The client will not immediately send the command to the server to be executed unless the client player submits the command/chat message, usually with the enter key.
* @param command The text to display in the chat bar of the client.
* @return This builder instance.
*/
public FancyMessage suggest(final String command) {
onClick("suggest_command", command);
return this;
}
/**
* Set the behavior of the current editing component to instruct the client to append the chat input box content with the specified string when the currently edited part of the {@code FancyMessage} is SHIFT-CLICKED.
* The client will not immediately send the command to the server to be executed unless the client player submits the command/chat message, usually with the enter key.
* @param command The text to append to the chat bar of the client.
* @return This builder instance.
*/
public FancyMessage insert(final String command) {
latest().insertionData = command;
dirty = true;
return this;
}
/**
* Set the behavior of the current editing component to instruct the client to send the specified string to the server as a chat message when the currently edited part of the {@code FancyMessage} is clicked.
* The client <b>will</b> immediately send the command to the server to be executed when the editing component is clicked.
* @param command The text to display in the chat bar of the client.
* @return This builder instance.
*/
public FancyMessage command(final String command) {
onClick("run_command", command);
return this;
}
/**
* Set the behavior of the current editing component to display information about an achievement when the client hovers over the text.
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
* @param name The name of the achievement to display, excluding the "achievement." prefix.
* @return This builder instance.
*/
public FancyMessage achievementTooltip(final String name) {
onHover("show_achievement", new JsonString("achievement." + name));
return this;
}
/**
* Set the behavior of the current editing component to display information about an achievement when the client hovers over the text.
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
* @param which The achievement to display.
* @return This builder instance.
*/
public FancyMessage achievementTooltip(final Achievement which) {
try {
Object achievement = Reflection.getMethod(Reflection.getOBCClass("CraftStatistic"), "getNMSAchievement", Achievement.class).invoke(null, which);
return achievementTooltip((String) Reflection.getField(Reflection.getNMSClass("Achievement"), "name").get(achievement));
} catch (IllegalAccessException e) {
Bukkit.getLogger().log(Level.WARNING, "Could not access method.", e);
return this;
} catch (IllegalArgumentException e) {
Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e);
return this;
} catch (InvocationTargetException e) {
Bukkit.getLogger().log(Level.WARNING, "A error has occured durring invoking of method.", e);
return this;
}
}
/**
* Set the behavior of the current editing component to display information about a parameterless statistic when the client hovers over the text.
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
* @param which The statistic to display.
* @return This builder instance.
* @exception IllegalArgumentException If the statistic requires a parameter which was not supplied.
*/
public FancyMessage statisticTooltip(final Statistic which) {
Type type = which.getType();
if (type != Type.UNTYPED) {
throw new IllegalArgumentException("That statistic requires an additional " + type + " parameter!");
}
try {
Object statistic = Reflection.getMethod(Reflection.getOBCClass("CraftStatistic"), "getNMSStatistic", Statistic.class).invoke(null, which);
return achievementTooltip((String) Reflection.getField(Reflection.getNMSClass("Statistic"), "name").get(statistic));
} catch (IllegalAccessException e) {
Bukkit.getLogger().log(Level.WARNING, "Could not access method.", e);
return this;
} catch (IllegalArgumentException e) {
Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e);
return this;
} catch (InvocationTargetException e) {
Bukkit.getLogger().log(Level.WARNING, "A error has occured durring invoking of method.", e);
return this;
}
}
/**
* Set the behavior of the current editing component to display information about a statistic parameter with a material when the client hovers over the text.
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
* @param which The statistic to display.
* @param item The sole material parameter to the statistic.
* @return This builder instance.
* @exception IllegalArgumentException If the statistic requires a parameter which was not supplied, or was supplied a parameter that was not required.
*/
public FancyMessage statisticTooltip(final Statistic which, Material item) {
Type type = which.getType();
if (type == Type.UNTYPED) {
throw new IllegalArgumentException("That statistic needs no additional parameter!");
}
if ((type == Type.BLOCK && item.isBlock()) || type == Type.ENTITY) {
throw new IllegalArgumentException("Wrong parameter type for that statistic - needs " + type + "!");
}
try {
Object statistic = Reflection.getMethod(Reflection.getOBCClass("CraftStatistic"), "getMaterialStatistic", Statistic.class, Material.class).invoke(null, which, item);
return achievementTooltip((String) Reflection.getField(Reflection.getNMSClass("Statistic"), "name").get(statistic));
} catch (IllegalAccessException e) {
Bukkit.getLogger().log(Level.WARNING, "Could not access method.", e);
return this;
} catch (IllegalArgumentException e) {
Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e);
return this;
} catch (InvocationTargetException e) {
Bukkit.getLogger().log(Level.WARNING, "A error has occured durring invoking of method.", e);
return this;
}
}
/**
* Set the behavior of the current editing component to display information about a statistic parameter with an entity type when the client hovers over the text.
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
* @param which The statistic to display.
* @param entity The sole entity type parameter to the statistic.
* @return This builder instance.
* @exception IllegalArgumentException If the statistic requires a parameter which was not supplied, or was supplied a parameter that was not required.
*/
public FancyMessage statisticTooltip(final Statistic which, EntityType entity) {
Type type = which.getType();
if (type == Type.UNTYPED) {
throw new IllegalArgumentException("That statistic needs no additional parameter!");
}
if (type != Type.ENTITY) {
throw new IllegalArgumentException("Wrong parameter type for that statistic - needs " + type + "!");
}
try {
Object statistic = Reflection.getMethod(Reflection.getOBCClass("CraftStatistic"), "getEntityStatistic", Statistic.class, EntityType.class).invoke(null, which, entity);
return achievementTooltip((String) Reflection.getField(Reflection.getNMSClass("Statistic"), "name").get(statistic));
} catch (IllegalAccessException e) {
Bukkit.getLogger().log(Level.WARNING, "Could not access method.", e);
return this;
} catch (IllegalArgumentException e) {
Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e);
return this;
} catch (InvocationTargetException e) {
Bukkit.getLogger().log(Level.WARNING, "A error has occured durring invoking of method.", e);
return this;
}
}
/**
* Set the behavior of the current editing component to display information about an item when the client hovers over the text.
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
* @param itemJSON A string representing the JSON-serialized NBT data tag of an {@link ItemStack}.
* @return This builder instance.
*/
public FancyMessage itemTooltip(final String itemJSON) {
onHover("show_item", new JsonString(itemJSON)); // Seems a bit hacky, considering we have a JSON object as a parameter
return this;
}
/**
* Set the behavior of the current editing component to display information about an item when the client hovers over the text.
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
* @param itemStack The stack for which to display information.
* @return This builder instance.
*/
public FancyMessage itemTooltip(final ItemStack itemStack) {
try {
Object nmsItem = Reflection.getMethod(Reflection.getOBCClass("inventory.CraftItemStack"), "asNMSCopy", ItemStack.class).invoke(null, itemStack);
return itemTooltip(Reflection.getMethod(Reflection.getNMSClass("ItemStack"), "save", Reflection.getNMSClass("NBTTagCompound")).invoke(nmsItem, Reflection.getNMSClass("NBTTagCompound").newInstance()).toString());
} catch (Exception e) {
e.printStackTrace();
return this;
}
}
/**
* Set the behavior of the current editing component to display raw text when the client hovers over the text.
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
* @param text The text, which supports newlines, which will be displayed to the client upon hovering.
* @return This builder instance.
*/
public FancyMessage tooltip(final String text) {
onHover("show_text", new JsonString(text));
return this;
}
/**
* Set the behavior of the current editing component to display raw text when the client hovers over the text.
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
* @param lines The lines of text which will be displayed to the client upon hovering. The iteration order of this object will be the order in which the lines of the tooltip are created.
* @return This builder instance.
*/
public FancyMessage tooltip(final Iterable<String> lines) {
tooltip(ArrayWrapper.toArray(lines, String.class));
return this;
}
/**
* Set the behavior of the current editing component to display raw text when the client hovers over the text.
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
* @param lines The lines of text which will be displayed to the client upon hovering.
* @return This builder instance.
*/
public FancyMessage tooltip(final String... lines) {
StringBuilder builder = new StringBuilder();
for(int i = 0; i < lines.length; i++){
builder.append(lines[i]);
if(i != lines.length - 1){
builder.append('\n');
}
}
tooltip(builder.toString());
return this;
}
/**
* Set the behavior of the current editing component to display formatted text when the client hovers over the text.
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
* @param text The formatted text which will be displayed to the client upon hovering.
* @return This builder instance.
*/
public FancyMessage formattedTooltip(FancyMessage text){
for(MessagePart component : text.messageParts){
if(component.clickActionData != null && component.clickActionName != null){
throw new IllegalArgumentException("The tooltip text cannot have click data.");
}else if(component.hoverActionData != null && component.hoverActionName != null){
throw new IllegalArgumentException("The tooltip text cannot have a tooltip.");
}
}
onHover("show_text", text);
return this;
}
/**
* Set the behavior of the current editing component to display the specified lines of formatted text when the client hovers over the text.
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
* @param lines The lines of formatted text which will be displayed to the client upon hovering.
* @return This builder instance.
*/
public FancyMessage formattedTooltip(FancyMessage... lines){
if(lines.length < 1){
onHover(null, null); // Clear tooltip
return this;
}
FancyMessage result = new FancyMessage();
result.messageParts.clear(); // Remove the one existing text component that exists by default, which destabilizes the object
for(int i = 0; i < lines.length; i++){
try{
for(MessagePart component : lines[i]){
if(component.clickActionData != null && component.clickActionName != null){
throw new IllegalArgumentException("The tooltip text cannot have click data.");
}else if(component.hoverActionData != null && component.hoverActionName != null){
throw new IllegalArgumentException("The tooltip text cannot have a tooltip.");
}
if(component.hasText()){
result.messageParts.add(component.clone());
}
}
if(i != lines.length - 1){
result.messageParts.add(new MessagePart(rawText("\n")));
}
} catch (CloneNotSupportedException e) {
Bukkit.getLogger().log(Level.WARNING, "Failed to clone object", e);
return this;
}
}
return formattedTooltip(result.messageParts.isEmpty() ? null : result); // Throws NPE if size is 0, intended
}
/**
* Set the behavior of the current editing component to display the specified lines of formatted text when the client hovers over the text.
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
* @param lines The lines of text which will be displayed to the client upon hovering. The iteration order of this object will be the order in which the lines of the tooltip are created.
* @return This builder instance.
*/
public FancyMessage formattedTooltip(final Iterable<FancyMessage> lines){
return formattedTooltip(ArrayWrapper.toArray(lines, FancyMessage.class));
}
/**
* If the text is a translatable key, and it has replaceable values, this function can be used to set the replacements that will be used in the message.
* @param replacements The replacements, in order, that will be used in the language-specific message.
* @return This builder instance.
*/
public FancyMessage translationReplacements(final String... replacements){
for(String str : replacements){
latest().translationReplacements.add(new JsonString(str));
}
dirty = true;
return this;
}
/*
/**
* If the text is a translatable key, and it has replaceable values, this function can be used to set the replacements that will be used in the message.
* @param replacements The replacements, in order, that will be used in the language-specific message.
* @return This builder instance.
*/ /* ------------
public FancyMessage translationReplacements(final Iterable<? extends CharSequence> replacements){
for(CharSequence str : replacements){
latest().translationReplacements.add(new JsonString(str));
}
return this;
}
*/
/**
* If the text is a translatable key, and it has replaceable values, this function can be used to set the replacements that will be used in the message.
* @param replacements The replacements, in order, that will be used in the language-specific message.
* @return This builder instance.
*/
public FancyMessage translationReplacements(final FancyMessage... replacements){
for(FancyMessage str : replacements){
latest().translationReplacements.add(str);
}
dirty = true;
return this;
}
/**
* If the text is a translatable key, and it has replaceable values, this function can be used to set the replacements that will be used in the message.
* @param replacements The replacements, in order, that will be used in the language-specific message.
* @return This builder instance.
*/
public FancyMessage translationReplacements(final Iterable<FancyMessage> replacements){
return translationReplacements(ArrayWrapper.toArray(replacements, FancyMessage.class));
}
/**
* Terminate construction of the current editing component, and begin construction of a new message component.
* After a successful call to this method, all setter methods will refer to a new message component, created as a result of the call to this method.
* @param text The text which will populate the new message component.
* @return This builder instance.
*/
public FancyMessage then(final String text) {
return then(rawText(text));
}
/**
* Terminate construction of the current editing component, and begin construction of a new message component.
* After a successful call to this method, all setter methods will refer to a new message component, created as a result of the call to this method.
* @param text The text which will populate the new message component.
* @return This builder instance.
*/
public FancyMessage then(final TextualComponent text) {
if (!latest().hasText()) {
throw new IllegalStateException("previous message part has no text");
}
messageParts.add(new MessagePart(text));
dirty = true;
return this;
}
/**
* Terminate construction of the current editing component, and begin construction of a new message component.
* After a successful call to this method, all setter methods will refer to a new message component, created as a result of the call to this method.
* @return This builder instance.
*/
public FancyMessage then() {
if (!latest().hasText()) {
throw new IllegalStateException("previous message part has no text");
}
messageParts.add(new MessagePart());
dirty = true;
return this;
}
@Override
public void writeJson(JsonWriter writer) throws IOException{
if (messageParts.size() == 1) {
latest().writeJson(writer);
} else {
writer.beginObject().name("text").value("").name("extra").beginArray();
for (final MessagePart part : this) {
part.writeJson(writer);
}
writer.endArray().endObject();
}
}
/**
* Serialize this fancy message, converting it into syntactically-valid JSON using a {@link JsonWriter}.
* This JSON should be compatible with vanilla formatter commands such as {@code /tellraw}.
* @return The JSON string representing this object.
*/
public String toJSONString() {
if (!dirty && jsonString != null) {
return jsonString;
}
StringWriter string = new StringWriter();
JsonWriter json = new JsonWriter(string);
try {
writeJson(json);
json.close();
} catch (IOException e) {
throw new RuntimeException("invalid message");
}
jsonString = string.toString();
dirty = false;
return jsonString;
}
/**
* Sends this message to a player. The player will receive the fully-fledged formatted display of this message.
* @param player The player who will receive the message.
*/
public void send(Player player){
send(player, toJSONString());
}
private void send(CommandSender sender, String jsonString){
if (!(sender instanceof Player)){
sender.sendMessage(toOldMessageFormat());
return;
}
Player player = (Player) sender;
try {
Object handle = Reflection.getHandle(player);
Object connection = Reflection.getField(handle.getClass(), "playerConnection").get(handle);
Reflection.getMethod(connection.getClass(), "sendPacket", Reflection.getNMSClass("Packet")).invoke(connection, createChatPacket(jsonString));
} catch (IllegalArgumentException e) {
Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e);
} catch (IllegalAccessException e) {
Bukkit.getLogger().log(Level.WARNING, "Could not access method.", e);
} catch (InstantiationException e) {
Bukkit.getLogger().log(Level.WARNING, "Underlying class is abstract.", e);
} catch (InvocationTargetException e) {
Bukkit.getLogger().log(Level.WARNING, "A error has occured durring invoking of method.", e);
} catch (NoSuchMethodException e) {
Bukkit.getLogger().log(Level.WARNING, "Could not find method.", e);
} catch (ClassNotFoundException e) {
Bukkit.getLogger().log(Level.WARNING, "Could not find class.", e);
}
}
// The ChatSerializer's instance of Gson
private static Object nmsChatSerializerGsonInstance;
private static Method fromJsonMethod;
private Object createChatPacket(String json) throws IllegalArgumentException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException, ClassNotFoundException {
if(nmsChatSerializerGsonInstance == null){
// Find the field and its value, completely bypassing obfuscation
Class<?> chatSerializerClazz;
String version = Reflection.getVersion();
double majorVersion = Double.parseDouble(version.replace('_', '.').substring(1, 4));
int lesserVersion = Integer.parseInt(version.substring(6, 7));
if (majorVersion < 1.8 || (majorVersion == 1.8 && lesserVersion == 1)) {
chatSerializerClazz = Reflection.getNMSClass("ChatSerializer");
} else {
chatSerializerClazz = Reflection.getNMSClass("IChatBaseComponent$ChatSerializer");
}
if (chatSerializerClazz == null) {
throw new ClassNotFoundException("Can't find the ChatSerializer class");
}
for (Field declaredField : chatSerializerClazz.getDeclaredFields()) {
if (Modifier.isFinal(declaredField.getModifiers()) && Modifier.isStatic(declaredField.getModifiers()) && declaredField.getType().getName().endsWith("Gson")) {
// We've found our field
declaredField.setAccessible(true);
nmsChatSerializerGsonInstance = declaredField.get(null);
fromJsonMethod = nmsChatSerializerGsonInstance.getClass().getMethod("fromJson", String.class, Class.class);
break;
}
}
}
// Since the method is so simple, and all the obfuscated methods have the same name, it's easier to reimplement 'IChatBaseComponent a(String)' than to reflectively call it
// Of course, the implementation may change, but fuzzy matches might break with signature changes
Object serializedChatComponent = fromJsonMethod.invoke(nmsChatSerializerGsonInstance, json, Reflection.getNMSClass("IChatBaseComponent"));
return nmsPacketPlayOutChatConstructor.newInstance(serializedChatComponent);
}
/**
* Sends this message to a command sender.
* If the sender is a player, they will receive the fully-fledged formatted display of this message.
* Otherwise, they will receive a version of this message with less formatting.
* @param sender The command sender who will receive the message.
* @see #toOldMessageFormat()
*/
public void send(CommandSender sender) {
send(sender, toJSONString());
}
/**
* Sends this message to multiple command senders.
* @param senders The command senders who will receive the message.
* @see #send(CommandSender)
*/
public void send(final Iterable<? extends CommandSender> senders) {
String string = toJSONString();
for (final CommandSender sender : senders) {
send(sender, string);
}
}
/**
* Convert this message to a human-readable string with limited formatting.
* This method is used to send this message to clients without JSON formatting support.
* <p>
* Serialization of this message by using this message will include (in this order for each message part):
* <ol>
* <li>The color of each message part.</li>
* <li>The applicable stylizations for each message part.</li>
* <li>The core text of the message part.</li>
* </ol>
* The primary omissions are tooltips and clickable actions. Consequently, this method should be used only as a last resort.
* </p>
* <p>
* Color and formatting can be removed from the returned string by using {@link ChatColor#stripColor(String)}.</p>
* @return A human-readable string representing limited formatting in addition to the core text of this message.
*/
public String toOldMessageFormat() {
StringBuilder result = new StringBuilder();
for (MessagePart part : this) {
result.append(part.color == null ? "" : part.color);
for(ChatColor formatSpecifier : part.styles){
result.append(formatSpecifier);
}
result.append(part.text);
}
return result.toString();
}
private MessagePart latest() {
return messageParts.get(messageParts.size() - 1);
}
private void onClick(final String name, final String data) {
final MessagePart latest = latest();
latest.clickActionName = name;
latest.clickActionData = data;
dirty = true;
}
private void onHover(final String name, final JsonRepresentedObject data) {
final MessagePart latest = latest();
latest.hoverActionName = name;
latest.hoverActionData = data;
dirty = true;
}
// Doc copied from interface
public Map<String, Object> serialize() {
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("messageParts", messageParts);
// map.put("JSON", toJSONString());
return map;
}
/**
* Deserializes a JSON-represented message from a mapping of key-value pairs.
* This is called by the Bukkit serialization API.
* It is not intended for direct public API consumption.
* @param serialized The key-value mapping which represents a fancy message.
*/
@SuppressWarnings("unchecked")
public static FancyMessage deserialize(Map<String, Object> serialized){
FancyMessage msg = new FancyMessage();
msg.messageParts = (List<MessagePart>)serialized.get("messageParts");
msg.jsonString = serialized.containsKey("JSON") ? serialized.get("JSON").toString() : null;
msg.dirty = !serialized.containsKey("JSON");
return msg;
}
/**
* <b>Internally called method. Not for API consumption.</b>
*/
public Iterator<MessagePart> iterator() {
return messageParts.iterator();
}
private static JsonParser _stringParser = new JsonParser();
/**
* Deserializes a fancy message from its JSON representation. This JSON representation is of the format of
* that returned by {@link #toJSONString()}, and is compatible with vanilla inputs.
* @param json The JSON string which represents a fancy message.
* @return A {@code FancyMessage} representing the parameterized JSON message.
*/
public static FancyMessage deserialize(String json){
JsonObject serialized = _stringParser.parse(json).getAsJsonObject();
JsonArray extra = serialized.getAsJsonArray("extra"); // Get the extra component
FancyMessage returnVal = new FancyMessage();
returnVal.messageParts.clear();
for(JsonElement mPrt : extra){
MessagePart component = new MessagePart();
JsonObject messagePart = mPrt.getAsJsonObject();
for(Map.Entry<String, JsonElement> entry : messagePart.entrySet()){
// Deserialize text
if(TextualComponent.isTextKey(entry.getKey())){
// The map mimics the YAML serialization, which has a "key" field and one or more "value" fields
Map<String, Object> serializedMapForm = new HashMap<String, Object>(); // Must be object due to Bukkit serializer API compliance
serializedMapForm.put("key", entry.getKey());
if(entry.getValue().isJsonPrimitive()){
// Assume string
serializedMapForm.put("value", entry.getValue().getAsString());
}else{
// Composite object, but we assume each element is a string
for(Map.Entry<String, JsonElement> compositeNestedElement : entry.getValue().getAsJsonObject().entrySet()){
serializedMapForm.put("value." + compositeNestedElement.getKey(), compositeNestedElement.getValue().getAsString());
}
}
component.text = TextualComponent.deserialize(serializedMapForm);
}else if(MessagePart.stylesToNames.inverse().containsKey(entry.getKey())){
if(entry.getValue().getAsBoolean()){
component.styles.add(MessagePart.stylesToNames.inverse().get(entry.getKey()));
}
}else if(entry.getKey().equals("color")){
component.color = ChatColor.valueOf(entry.getValue().getAsString().toUpperCase());
}else if(entry.getKey().equals("clickEvent")){
JsonObject object = entry.getValue().getAsJsonObject();
component.clickActionName = object.get("action").getAsString();
component.clickActionData = object.get("value").getAsString();
}else if(entry.getKey().equals("hoverEvent")){
JsonObject object = entry.getValue().getAsJsonObject();
component.hoverActionName = object.get("action").getAsString();
if(object.get("value").isJsonPrimitive()){
// Assume string
component.hoverActionData = new JsonString(object.get("value").getAsString());
}else{
// Assume composite type
// The only composite type we currently store is another FancyMessage
// Therefore, recursion time!
component.hoverActionData = deserialize(object.get("value").toString() /* This should properly serialize the JSON object as a JSON string */);
}
}else if(entry.getKey().equals("insertion")){
component.insertionData = entry.getValue().getAsString();
}else if(entry.getKey().equals("with")){
for(JsonElement object : entry.getValue().getAsJsonArray()){
if(object.isJsonPrimitive()){
component.translationReplacements.add(new JsonString(object.getAsString()));
}else{
// Only composite type stored in this array is - again - FancyMessages
// Recurse within this function to parse this as a translation replacement
component.translationReplacements.add(deserialize(object.toString()));
}
}
}
}
returnVal.messageParts.add(component);
}
return returnVal;
}
}

View File

@ -0,0 +1,19 @@
package com.plotsquared.bukkit.util.bukkit.chat;
import java.io.IOException;
import com.google.gson.stream.JsonWriter;
/**
* Represents an object that can be serialized to a JSON writer instance.
*/
interface JsonRepresentedObject {
/**
* Writes the JSON representation of this object to the specified writer.
* @param writer The JSON writer which will receive the object.
* @throws IOException If an error occurs writing to the stream.
*/
public void writeJson(JsonWriter writer) throws IOException;
}

View File

@ -0,0 +1,46 @@
package com.plotsquared.bukkit.util.bukkit.chat;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import com.google.gson.stream.JsonWriter;
import com.intellectualcrafters.configuration.serialization.ConfigurationSerializable;
/**
* Represents a JSON string value.
* Writes by this object will not write name values nor begin/end objects in the JSON stream.
* All writes merely write the represented string value.
*/
final class JsonString implements JsonRepresentedObject, ConfigurationSerializable {
private String _value;
public JsonString(CharSequence value){
_value = value == null ? null : value.toString();
}
@Override
public void writeJson(JsonWriter writer) throws IOException {
writer.value(getValue());
}
public String getValue(){
return _value;
}
public Map<String, Object> serialize() {
HashMap<String, Object> theSingleValue = new HashMap<String, Object>();
theSingleValue.put("stringValue", _value);
return theSingleValue;
}
public static JsonString deserialize(Map<String, Object> map){
return new JsonString(map.get("stringValue").toString());
}
@Override
public String toString(){
return _value;
}
}

View File

@ -0,0 +1,154 @@
package com.plotsquared.bukkit.util.bukkit.chat;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import com.google.common.collect.BiMap;
import com.google.common.collect.ImmutableBiMap;
import com.google.gson.stream.JsonWriter;
import com.intellectualcrafters.configuration.serialization.ConfigurationSerializable;
import com.intellectualcrafters.configuration.serialization.ConfigurationSerialization;
/**
* Internal class: Represents a component of a JSON-serializable {@link FancyMessage}.
*/
final class MessagePart implements JsonRepresentedObject, ConfigurationSerializable, Cloneable {
ChatColor color = ChatColor.WHITE;
ArrayList<ChatColor> styles = new ArrayList<ChatColor>();
String clickActionName = null, clickActionData = null,
hoverActionName = null;
JsonRepresentedObject hoverActionData = null;
TextualComponent text = null;
String insertionData = null;
ArrayList<JsonRepresentedObject> translationReplacements = new ArrayList<JsonRepresentedObject>();
MessagePart(final TextualComponent text){
this.text = text;
}
MessagePart() {
this.text = null;
}
boolean hasText() {
return text != null;
}
@Override
@SuppressWarnings("unchecked")
public MessagePart clone() throws CloneNotSupportedException{
MessagePart obj = (MessagePart)super.clone();
obj.styles = (ArrayList<ChatColor>)styles.clone();
if(hoverActionData instanceof JsonString){
obj.hoverActionData = new JsonString(((JsonString)hoverActionData).getValue());
}else if(hoverActionData instanceof FancyMessage){
obj.hoverActionData = ((FancyMessage)hoverActionData).clone();
}
obj.translationReplacements = (ArrayList<JsonRepresentedObject>)translationReplacements.clone();
return obj;
}
static final BiMap<ChatColor, String> stylesToNames;
static{
ImmutableBiMap.Builder<ChatColor, String> builder = ImmutableBiMap.builder();
for (final ChatColor style : ChatColor.values()){
if(!style.isFormat()){
continue;
}
String styleName;
switch (style) {
case MAGIC:
styleName = "obfuscated"; break;
case UNDERLINE:
styleName = "underlined"; break;
default:
styleName = style.name().toLowerCase(); break;
}
builder.put(style, styleName);
}
stylesToNames = builder.build();
}
public void writeJson(JsonWriter json) {
try {
json.beginObject();
text.writeJson(json);
json.name("color").value(color.name().toLowerCase());
for (final ChatColor style : styles) {
json.name(stylesToNames.get(style)).value(true);
}
if (clickActionName != null && clickActionData != null) {
json.name("clickEvent")
.beginObject()
.name("action").value(clickActionName)
.name("value").value(clickActionData)
.endObject();
}
if (hoverActionName != null && hoverActionData != null) {
json.name("hoverEvent")
.beginObject()
.name("action").value(hoverActionName)
.name("value");
hoverActionData.writeJson(json);
json.endObject();
}
if(insertionData != null){
json.name("insertion").value(insertionData);
}
if(translationReplacements.size() > 0 && text != null && TextualComponent.isTranslatableText(text)){
json.name("with").beginArray();
for(JsonRepresentedObject obj : translationReplacements){
obj.writeJson(json);
}
json.endArray();
}
json.endObject();
} catch(IOException e){
Bukkit.getLogger().log(Level.WARNING, "A problem occured during writing of JSON string", e);
}
}
public Map<String, Object> serialize() {
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("text", text);
map.put("styles", styles);
map.put("color", color.getChar());
map.put("hoverActionName", hoverActionName);
map.put("hoverActionData", hoverActionData);
map.put("clickActionName", clickActionName);
map.put("clickActionData", clickActionData);
map.put("insertion", insertionData);
map.put("translationReplacements", translationReplacements);
return map;
}
@SuppressWarnings("unchecked")
public static MessagePart deserialize(Map<String, Object> serialized){
MessagePart part = new MessagePart((TextualComponent)serialized.get("text"));
part.styles = (ArrayList<ChatColor>)serialized.get("styles");
part.color = ChatColor.getByChar(serialized.get("color").toString());
part.hoverActionName = (String)serialized.get("hoverActionName");
part.hoverActionData = (JsonRepresentedObject)serialized.get("hoverActionData");
part.clickActionName = (String)serialized.get("clickActionName");
part.clickActionData = (String)serialized.get("clickActionData");
part.insertionData = (String)serialized.get("insertion");
part.translationReplacements = (ArrayList<JsonRepresentedObject>)serialized.get("translationReplacements");
return part;
}
static{
ConfigurationSerialization.registerClass(MessagePart.class);
}
}

View File

@ -0,0 +1,213 @@
package com.plotsquared.bukkit.util.bukkit.chat;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.Bukkit;
/**
* A class containing static utility methods and caches which are intended as reflective conveniences.
* Unless otherwise noted, upon failure methods will return {@code null}.
*/
public final class Reflection {
private static String _versionString;
private Reflection(){
}
/**
* Gets the version string from the package name of the CraftBukkit server implementation.
* This is needed to bypass the JAR package name changing on each update.
* @return The version string of the OBC and NMS packages, <em>including the trailing dot</em>.
*/
public synchronized static String getVersion() {
if(_versionString == null){
if(Bukkit.getServer() == null){
// The server hasn't started, static initializer call?
return null;
}
String name = Bukkit.getServer().getClass().getPackage().getName();
_versionString = name.substring(name.lastIndexOf('.') + 1) + ".";
}
return _versionString;
}
/**
* Stores loaded classes from the {@code net.minecraft.server} package.
*/
private static final Map<String, Class<?>> _loadedNMSClasses = new HashMap<String, Class<?>>();
/**
* Stores loaded classes from the {@code org.bukkit.craftbukkit} package (and subpackages).
*/
private static final Map<String, Class<?>> _loadedOBCClasses = new HashMap<String, Class<?>>();
/**
* Gets a {@link Class} object representing a type contained within the {@code net.minecraft.server} versioned package.
* The class instances returned by this method are cached, such that no lookup will be done twice (unless multiple threads are accessing this method simultaneously).
* @param className The name of the class, excluding the package, within NMS.
* @return The class instance representing the specified NMS class, or {@code null} if it could not be loaded.
*/
public synchronized static Class<?> getNMSClass(String className) {
if(_loadedNMSClasses.containsKey(className)){
return _loadedNMSClasses.get(className);
}
String fullName = "net.minecraft.server." + getVersion() + className;
Class<?> clazz = null;
try {
clazz = Class.forName(fullName);
} catch (Exception e) {
e.printStackTrace();
_loadedNMSClasses.put(className, null);
return null;
}
_loadedNMSClasses.put(className, clazz);
return clazz;
}
/**
* Gets a {@link Class} object representing a type contained within the {@code org.bukkit.craftbukkit} versioned package.
* The class instances returned by this method are cached, such that no lookup will be done twice (unless multiple threads are accessing this method simultaneously).
* @param className The name of the class, excluding the package, within OBC. This name may contain a subpackage name, such as {@code inventory.CraftItemStack}.
* @return The class instance representing the specified OBC class, or {@code null} if it could not be loaded.
*/
public synchronized static Class<?> getOBCClass(String className) {
if(_loadedOBCClasses.containsKey(className)){
return _loadedOBCClasses.get(className);
}
String fullName = "org.bukkit.craftbukkit." + getVersion() + className;
Class<?> clazz = null;
try {
clazz = Class.forName(fullName);
} catch (Exception e) {
e.printStackTrace();
_loadedOBCClasses.put(className, null);
return null;
}
_loadedOBCClasses.put(className, clazz);
return clazz;
}
/**
* Attempts to get the NMS handle of a CraftBukkit object.
* <p>
* The only match currently attempted by this method is a retrieval by using a parameterless {@code getHandle()} method implemented by the runtime type of the specified object.
* </p>
* @param obj The object for which to retrieve an NMS handle.
* @return The NMS handle of the specified object, or {@code null} if it could not be retrieved using {@code getHandle()}.
*/
public synchronized static Object getHandle(Object obj) {
try {
return getMethod(obj.getClass(), "getHandle").invoke(obj);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
private static final Map<Class<?>, Map<String, Field>> _loadedFields = new HashMap<Class<?>, Map<String, Field>>();
/**
* Retrieves a {@link Field} instance declared by the specified class with the specified name.
* Java access modifiers are ignored during this retrieval. No guarantee is made as to whether the field
* returned will be an instance or static field.
* <p>
* A global caching mechanism within this class is used to store fields. Combined with synchronization, this guarantees that
* no field will be reflectively looked up twice.
* </p>
* <p>
* If a field is deemed suitable for return, {@link Field#setAccessible(boolean) setAccessible} will be invoked with an argument of {@code true} before it is returned.
* This ensures that callers do not have to check or worry about Java access modifiers when dealing with the returned instance.
* </p>
* @param clazz The class which contains the field to retrieve.
* @param name The declared name of the field in the class.
* @return A field object with the specified name declared by the specified class.
* @see Class#getDeclaredField(String)
*/
public synchronized static Field getField(Class<?> clazz, String name) {
Map<String, Field> loaded;
if(!_loadedFields.containsKey(clazz)){
loaded = new HashMap<String, Field>();
_loadedFields.put(clazz, loaded);
}else{
loaded = _loadedFields.get(clazz);
}
if(loaded.containsKey(name)){
// If the field is loaded (or cached as not existing), return the relevant value, which might be null
return loaded.get(name);
}
try {
Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
loaded.put(name, field);
return field;
} catch (Exception e) {
// Error loading
e.printStackTrace();
// Cache field as not existing
loaded.put(name, null);
return null;
}
}
/**
* Contains loaded methods in a cache.
* The map maps [types to maps of [method names to maps of [parameter types to method instances]]].
*/
private static final Map<Class<?>, Map<String, Map<ArrayWrapper<Class<?>>, Method>>> _loadedMethods = new HashMap<Class<?>, Map<String, Map<ArrayWrapper<Class<?>>, Method>>>();
/**
* Retrieves a {@link Method} instance declared by the specified class with the specified name and argument types.
* Java access modifiers are ignored during this retrieval. No guarantee is made as to whether the field
* returned will be an instance or static field.
* <p>
* A global caching mechanism within this class is used to store method. Combined with synchronization, this guarantees that
* no method will be reflectively looked up twice.
* </p>
* <p>
* If a method is deemed suitable for return, {@link Method#setAccessible(boolean) setAccessible} will be invoked with an argument of {@code true} before it is returned.
* This ensures that callers do not have to check or worry about Java access modifiers when dealing with the returned instance.
* </p>
* <p>
* This method does <em>not</em> search superclasses of the specified type for methods with the specified signature.
* Callers wishing this behavior should use {@link Class#getDeclaredMethod(String, Class...)}.
* @param clazz The class which contains the method to retrieve.
* @param name The declared name of the method in the class.
* @param args The formal argument types of the method.
* @return A method object with the specified name declared by the specified class.
*/
public synchronized static Method getMethod(Class<?> clazz, String name,
Class<?>... args) {
if(!_loadedMethods.containsKey(clazz)){
_loadedMethods.put(clazz, new HashMap<String, Map<ArrayWrapper<Class<?>>, Method>>());
}
Map<String, Map<ArrayWrapper<Class<?>>, Method>> loadedMethodNames = _loadedMethods.get(clazz);
if(!loadedMethodNames.containsKey(name)){
loadedMethodNames.put(name, new HashMap<ArrayWrapper<Class<?>>, Method>());
}
Map<ArrayWrapper<Class<?>>, Method> loadedSignatures = loadedMethodNames.get(name);
ArrayWrapper<Class<?>> wrappedArg = new ArrayWrapper<Class<?>>(args);
if(loadedSignatures.containsKey(wrappedArg)){
return loadedSignatures.get(wrappedArg);
}
for (Method m : clazz.getMethods())
if (m.getName().equals(name) && Arrays.equals(args, m.getParameterTypes())) {
m.setAccessible(true);
loadedSignatures.put(wrappedArg, m);
return m;
}
loadedSignatures.put(wrappedArg, null);
return null;
}
}

View File

@ -0,0 +1,291 @@
package com.plotsquared.bukkit.util.bukkit.chat;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.gson.stream.JsonWriter;
import com.intellectualcrafters.configuration.serialization.ConfigurationSerializable;
import com.intellectualcrafters.configuration.serialization.ConfigurationSerialization;
/**
* Represents a textual component of a message part.
* This can be used to not only represent string literals in a JSON message,
* but also to represent localized strings and other text values.
* <p>Different instances of this class can be created with static constructor methods.</p>
*/
public abstract class TextualComponent implements Cloneable {
static{
ConfigurationSerialization.registerClass(TextualComponent.ArbitraryTextTypeComponent.class);
ConfigurationSerialization.registerClass(TextualComponent.ComplexTextTypeComponent.class);
}
@Override
public String toString() {
return getReadableString();
}
/**
* @return The JSON key used to represent text components of this type.
*/
public abstract String getKey();
/**
* @return A readable String
*/
public abstract String getReadableString();
/**
* Clones a textual component instance.
* The returned object should not reference this textual component instance, but should maintain the same key and value.
*/
@Override
public abstract TextualComponent clone() throws CloneNotSupportedException;
/**
* Writes the text data represented by this textual component to the specified JSON writer object.
* A new object within the writer is not started.
* @param writer The object to which to write the JSON data.
* @throws IOException If an error occurs while writing to the stream.
*/
public abstract void writeJson(JsonWriter writer) throws IOException;
static TextualComponent deserialize(Map<String, Object> map){
if(map.containsKey("key") && map.size() == 2 && map.containsKey("value")){
// Arbitrary text component
return ArbitraryTextTypeComponent.deserialize(map);
}else if(map.size() >= 2 && map.containsKey("key") && !map.containsKey("value") /* It contains keys that START WITH value */){
// Complex JSON object
return ComplexTextTypeComponent.deserialize(map);
}
return null;
}
static boolean isTextKey(String key){
return key.equals("translate") || key.equals("text") || key.equals("score") || key.equals("selector");
}
static boolean isTranslatableText(TextualComponent component){
return component instanceof ComplexTextTypeComponent && ((ComplexTextTypeComponent)component).getKey().equals("translate");
}
/**
* Internal class used to represent all types of text components.
* Exception validating done is on keys and values.
*/
private static final class ArbitraryTextTypeComponent extends TextualComponent implements ConfigurationSerializable {
public ArbitraryTextTypeComponent(String key, String value){
setKey(key);
setValue(value);
}
@Override
public String getKey() {
return _key;
}
public void setKey(String key) {
Preconditions.checkArgument(key != null && !key.isEmpty(), "The key must be specified.");
_key = key;
}
public String getValue() {
return _value;
}
public void setValue(String value) {
Preconditions.checkArgument(value != null, "The value must be specified.");
_value = value;
}
private String _key;
private String _value;
@Override
public TextualComponent clone() throws CloneNotSupportedException {
// Since this is a private and final class, we can just reinstantiate this class instead of casting super.clone
return new ArbitraryTextTypeComponent(getKey(), getValue());
}
@Override
public void writeJson(JsonWriter writer) throws IOException {
writer.name(getKey()).value(getValue());
}
@SuppressWarnings("serial")
public Map<String, Object> serialize() {
return new HashMap<String, Object>(){{
put("key", getKey());
put("value", getValue());
}};
}
public static ArbitraryTextTypeComponent deserialize(Map<String, Object> map){
return new ArbitraryTextTypeComponent(map.get("key").toString(), map.get("value").toString());
}
@Override
public String getReadableString() {
return getValue();
}
}
/**
* Internal class used to represent a text component with a nested JSON value.
* Exception validating done is on keys and values.
*/
private static final class ComplexTextTypeComponent extends TextualComponent implements ConfigurationSerializable{
public ComplexTextTypeComponent(String key, Map<String, String> values){
setKey(key);
setValue(values);
}
@Override
public String getKey() {
return _key;
}
public void setKey(String key) {
Preconditions.checkArgument(key != null && !key.isEmpty(), "The key must be specified.");
_key = key;
}
public Map<String, String> getValue() {
return _value;
}
public void setValue(Map<String, String> value) {
Preconditions.checkArgument(value != null, "The value must be specified.");
_value = value;
}
private String _key;
private Map<String, String> _value;
@Override
public TextualComponent clone() throws CloneNotSupportedException {
// Since this is a private and final class, we can just reinstantiate this class instead of casting super.clone
return new ComplexTextTypeComponent(getKey(), getValue());
}
@Override
public void writeJson(JsonWriter writer) throws IOException {
writer.name(getKey());
writer.beginObject();
for(Map.Entry<String, String> jsonPair : _value.entrySet()){
writer.name(jsonPair.getKey()).value(jsonPair.getValue());
}
writer.endObject();
}
@SuppressWarnings("serial")
public Map<String, Object> serialize() {
return new java.util.HashMap<String, Object>(){{
put("key", getKey());
for(Map.Entry<String, String> valEntry : getValue().entrySet()){
put("value." + valEntry.getKey(), valEntry.getValue());
}
}};
}
public static ComplexTextTypeComponent deserialize(Map<String, Object> map){
String key = null;
Map<String, String> value = new HashMap<String, String>();
for(Map.Entry<String, Object> valEntry : map.entrySet()){
if(valEntry.getKey().equals("key")){
key = (String) valEntry.getValue();
}else if(valEntry.getKey().startsWith("value.")){
value.put(((String) valEntry.getKey()).substring(6) /* Strips out the value prefix */, valEntry.getValue().toString());
}
}
return new ComplexTextTypeComponent(key, value);
}
@Override
public String getReadableString() {
return getKey();
}
}
/**
* Create a textual component representing a string literal.
* This is the default type of textual component when a single string literal is given to a method.
* @param textValue The text which will be represented.
* @return The text component representing the specified literal text.
*/
public static TextualComponent rawText(String textValue){
return new ArbitraryTextTypeComponent("text", textValue);
}
/**
* Create a textual component representing a localized string.
* The client will see this text component as their localized version of the specified string <em>key</em>, which can be overridden by a resource pack.
* <p>
* If the specified translation key is not present on the client resource pack, the translation key will be displayed as a string literal to the client.
* </p>
* @param translateKey The string key which maps to localized text.
* @return The text component representing the specified localized text.
*/
public static TextualComponent localizedText(String translateKey){
return new ArbitraryTextTypeComponent("translate", translateKey);
}
private static void throwUnsupportedSnapshot(){
throw new UnsupportedOperationException("This feature is only supported in snapshot releases.");
}
/**
* Create a textual component representing a scoreboard value.
* The client will see their own score for the specified objective as the text represented by this component.
* <p>
* <b>This method is currently guaranteed to throw an {@code UnsupportedOperationException} as it is only supported on snapshot clients.</b>
* </p>
* @param scoreboardObjective The name of the objective for which to display the score.
* @return The text component representing the specified scoreboard score (for the viewing player), or {@code null} if an error occurs during JSON serialization.
*/
public static TextualComponent objectiveScore(String scoreboardObjective){
return objectiveScore("*", scoreboardObjective);
}
/**
* Create a textual component representing a scoreboard value.
* The client will see the score of the specified player for the specified objective as the text represented by this component.
* <p>
* <b>This method is currently guaranteed to throw an {@code UnsupportedOperationException} as it is only supported on snapshot clients.</b>
* </p>
* @param playerName The name of the player whos score will be shown. If this string represents the single-character sequence "*", the viewing player's score will be displayed.
* Standard minecraft selectors (@a, @p, etc) are <em>not</em> supported.
* @param scoreboardObjective The name of the objective for which to display the score.
* @return The text component representing the specified scoreboard score for the specified player, or {@code null} if an error occurs during JSON serialization.
*/
public static TextualComponent objectiveScore(String playerName, String scoreboardObjective){
throwUnsupportedSnapshot(); // Remove this line when the feature is released to non-snapshot versions, in addition to updating ALL THE OVERLOADS documentation accordingly
return new ComplexTextTypeComponent("score", ImmutableMap.<String, String>builder()
.put("name", playerName)
.put("objective", scoreboardObjective)
.build());
}
/**
* Create a textual component representing a player name, retrievable by using a standard minecraft selector.
* The client will see the players or entities captured by the specified selector as the text represented by this component.
* <p>
* <b>This method is currently guaranteed to throw an {@code UnsupportedOperationException} as it is only supported on snapshot clients.</b>
* </p>
* @param selector The minecraft player or entity selector which will capture the entities whose string representations will be displayed in the place of this text component.
* @return The text component representing the name of the entities captured by the selector.
*/
public static TextualComponent selector(String selector){
throwUnsupportedSnapshot(); // Remove this line when the feature is released to non-snapshot versions, in addition to updating ALL THE OVERLOADS documentation accordingly
return new ArbitraryTextTypeComponent("selector", selector);
}
}

View File

@ -0,0 +1,305 @@
package com.plotsquared.bukkit.util.bukkit.uuid;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.io.Files;
import com.google.common.io.InputSupplier;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.config.C;
import com.intellectualcrafters.plot.config.Settings;
import com.intellectualcrafters.plot.database.DBFunc;
import com.intellectualcrafters.plot.object.*;
import com.intellectualcrafters.plot.util.ExpireManager;
import com.intellectualcrafters.plot.util.NbtFactory;
import com.intellectualcrafters.plot.util.TaskManager;
import com.plotsquared.bukkit.object.BukkitOfflinePlayer;
import com.plotsquared.bukkit.util.bukkit.UUIDHandler;
import com.intellectualcrafters.plot.uuid.OfflineUUIDWrapper;
import com.intellectualcrafters.plot.uuid.UUIDWrapper;
import org.bukkit.Bukkit;
import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.UUID;
public class FileUUIDHandler implements UUIDHandlerImplementation {
private final BiMap<StringWrapper, UUID> uuidMap = HashBiMap.create(new HashMap<StringWrapper, UUID>());
public boolean CACHED = false;
public UUIDWrapper uuidWrapper = null;
public HashMap<String, PlotPlayer> players = new HashMap<>();
@Override
public void add(final StringWrapper name, final UUID uuid) {
if ((uuid == null) || (name == null)) {
return;
}
BiMap<UUID, StringWrapper> inverse = uuidMap.inverse();
if (inverse.containsKey(uuid)) {
if (uuidMap.containsKey(name)) {
return;
}
inverse.remove(uuid);
}
uuidMap.put(name, uuid);
}
@Override
public void handleShutdown() {}
@Override
public BiMap<StringWrapper, UUID> getUUIDMap() {
return uuidMap;
}
@Override
public boolean uuidExists(final UUID uuid) {
return uuidMap.containsValue(uuid);
}
@Override
public boolean nameExists(final StringWrapper name) {
return uuidMap.containsKey(name);
}
@Override
public void startCaching() {
if (Bukkit.getWorlds().size() > 1) {
cacheWorld(Bukkit.getWorlds().get(0).getName());
}
}
@Override
public void setUUIDWrapper(UUIDWrapper wrapper) {
this.uuidWrapper = wrapper;
}
@Override
public UUIDWrapper getUUIDWrapper() {
return uuidWrapper;
}
@Override
public Map<String, PlotPlayer> getPlayers() {
return players;
}
@Override
public void cacheWorld(final String world) {
if (CACHED) {
return;
}
final File container = Bukkit.getWorldContainer();
CACHED = true;
TaskManager.runTaskAsync(new Runnable() {
@Override
public void run() {
PS.log(C.PREFIX.s() + "&6Starting player data caching for: " + world);
final HashMap<StringWrapper, UUID> toAdd = new HashMap<>();
toAdd.put(new StringWrapper("*"), DBFunc.everyone);
if (Settings.TWIN_MODE_UUID) {
HashSet<UUID> all = UUIDHandler.getAllUUIDS();
PS.log("&aFast mode UUID caching enabled!");
final File playerdataFolder = new File(container, world + File.separator + "playerdata");
String[] dat = playerdataFolder.list(new FilenameFilter() {
@Override
public boolean accept(final File f, final String s) {
return s.endsWith(".dat");
}
});
boolean check = all.size() == 0;
if (dat != null) {
for (final String current : dat) {
final String s = current.replaceAll(".dat$", "");
try {
UUID uuid = UUID.fromString(s);
if (check || all.contains(uuid)) {
File file = new File(playerdataFolder + File.separator + current);
InputSupplier<FileInputStream> is = Files.newInputStreamSupplier(file);
NbtFactory.NbtCompound compound = NbtFactory.fromStream(is, NbtFactory.StreamOptions.GZIP_COMPRESSION);
NbtFactory.NbtCompound bukkit = (NbtFactory.NbtCompound) compound.get("bukkit");
String name = (String) bukkit.get("lastKnownName");
long last = (long) bukkit.get("lastPlayed");
ExpireManager.dates.put(uuid, last);
toAdd.put(new StringWrapper(name), uuid);
}
} catch (final Exception e) {
e.printStackTrace();
PS.log(C.PREFIX.s() + "Invalid playerdata: " + current);
}
}
}
cache(toAdd);
return;
}
final HashSet<String> worlds = new HashSet<>();
worlds.add(world);
worlds.add("world");
final HashSet<UUID> uuids = new HashSet<>();
final HashSet<String> names = new HashSet<>();
File playerdataFolder = null;
for (final String worldname : worlds) {
// Getting UUIDs
playerdataFolder = new File(container, worldname + File.separator + "playerdata");
String[] dat = playerdataFolder.list(new FilenameFilter() {
@Override
public boolean accept(final File f, final String s) {
return s.endsWith(".dat");
}
});
if (dat != null && dat.length != 0) {
for (final String current : dat) {
final String s = current.replaceAll(".dat$", "");
try {
final UUID uuid = UUID.fromString(s);
uuids.add(uuid);
} catch (final Exception e) {
PS.log(C.PREFIX.s() + "Invalid playerdata: " + current);
}
}
break;
}
// Getting names
final File playersFolder = new File(worldname + File.separator + "players");
dat = playersFolder.list(new FilenameFilter() {
@Override
public boolean accept(final File f, final String s) {
return s.endsWith(".dat");
}
});
if (dat != null && dat.length != 0) {
for (final String current : dat) {
names.add(current.replaceAll(".dat$", ""));
}
break;
}
}
for (UUID uuid : uuids) {
try {
File file = new File(playerdataFolder + File.separator + uuid.toString() + ".dat");
InputSupplier<FileInputStream> is = Files.newInputStreamSupplier(file);
NbtFactory.NbtCompound compound = NbtFactory.fromStream(is, NbtFactory.StreamOptions.GZIP_COMPRESSION);
NbtFactory.NbtCompound bukkit = (NbtFactory.NbtCompound) compound.get("bukkit");
String name = (String) bukkit.get("lastKnownName");
long last = (long) bukkit.get("lastPlayed");
if (Settings.OFFLINE_MODE) {
if (Settings.UUID_LOWERCASE && !name.toLowerCase().equals(name)) {
uuid = uuidWrapper.getUUID(name);
} else {
long most = (long) compound.get("UUIDMost");
long least = (long) compound.get("UUIDLeast");
uuid = new UUID(most, least);
}
}
ExpireManager.dates.put(uuid, last);
toAdd.put(new StringWrapper(name), uuid);
} catch (final Throwable e) {
PS.log(C.PREFIX.s() + "&6Invalid playerdata: " + uuid.toString() + ".dat");
}
}
for (final String name : names) {
final UUID uuid = uuidWrapper.getUUID(name);
final StringWrapper nameWrap = new StringWrapper(name);
toAdd.put(nameWrap, uuid);
}
if (uuidMap.size() == 0) {
for (OfflinePlotPlayer op : uuidWrapper.getOfflinePlayers()) {
if (op.getLastPlayed() != 0) {
String name = op.getName();
StringWrapper wrap = new StringWrapper(name);
UUID uuid = uuidWrapper.getUUID(op);
toAdd.put(wrap, uuid);
}
}
}
cache(toAdd);
}
});
}
@Override
public void cache(final Map<StringWrapper, UUID> toAdd) {
TaskManager.runTask(new Runnable() {
@Override
public void run() {
for (Map.Entry<StringWrapper, UUID> entry : toAdd.entrySet()) {
add(entry.getKey(), entry.getValue());
}
PS.log(C.PREFIX.s() + "&6Cached a total of: " + uuidMap.size() + " UUIDs");
}
});
}
@Override
public UUID getUUID(final PlotPlayer player) {
return uuidWrapper.getUUID(player);
}
@Override
public UUID getUUID(final BukkitOfflinePlayer player) {
return uuidWrapper.getUUID(player);
}
@Override
public String getName(final UUID uuid) {
if (uuid == null) {
return null;
}
// check online
final PlotPlayer player = getPlayer(uuid);
if (player != null) {
return player.getName();
}
// check cache
final StringWrapper name = uuidMap.inverse().get(uuid);
if (name != null) {
return name.value;
}
return null;
}
@Override
public PlotPlayer getPlayer(final UUID uuid) {
for (final PlotPlayer player : players.values()) {
if (player.getUUID().equals(uuid)) {
return player;
}
}
return null;
}
@Override
public PlotPlayer getPlayer(final String name) {
return players.get(name);
}
@Override
public UUID getUUID(final String name) {
if ((name == null) || (name.length() == 0)) {
return null;
}
// check online
final PlotPlayer player = getPlayer(name);
if (player != null) {
return player.getUUID();
}
// check cache
final StringWrapper wrap = new StringWrapper(name);
UUID uuid = uuidMap.get(wrap);
if (uuid != null) {
return uuid;
}
// Read from disk OR convert directly to offline UUID
if (Settings.UUID_FROM_DISK || (uuidWrapper instanceof OfflineUUIDWrapper)) {
uuid = uuidWrapper.getUUID(name);
add(new StringWrapper(name), uuid);
return uuid;
}
return null;
}
}

View File

@ -0,0 +1,570 @@
package com.plotsquared.bukkit.util.bukkit.uuid;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import com.google.common.collect.Maps;
import com.intellectualcrafters.json.JSONObject;
import com.plotsquared.bukkit.BukkitMain;
import com.intellectualcrafters.plot.database.SQLite;
import com.plotsquared.bukkit.util.bukkit.UUIDHandler;
import com.intellectualcrafters.plot.uuid.LowerOfflineUUIDWrapper;
import org.bukkit.Bukkit;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.io.Files;
import com.google.common.io.InputSupplier;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.config.C;
import com.intellectualcrafters.plot.config.Settings;
import com.intellectualcrafters.plot.database.DBFunc;
import com.plotsquared.bukkit.object.BukkitOfflinePlayer;
import com.intellectualcrafters.plot.object.OfflinePlotPlayer;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.object.StringWrapper;
import com.intellectualcrafters.plot.util.ExpireManager;
import com.intellectualcrafters.plot.util.NbtFactory;
import com.intellectualcrafters.plot.util.NbtFactory.NbtCompound;
import com.intellectualcrafters.plot.util.NbtFactory.StreamOptions;
import com.intellectualcrafters.plot.util.TaskManager;
import com.intellectualcrafters.plot.uuid.OfflineUUIDWrapper;
import com.intellectualcrafters.plot.uuid.UUIDWrapper;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.plugin.java.JavaPlugin;
public class SQLUUIDHandler implements Listener, UUIDHandlerImplementation {
private class SQLUUIDHandlerException extends RuntimeException {
SQLUUIDHandlerException(String s, Throwable c) {
super("SQLUUIDHandler caused an exception: " + s, c);
}
@SuppressWarnings("unused")
SQLUUIDHandlerException(String s) {
super("SQLUUIDHandler caused an exception: " + s);
}
}
private final SQLite _sqLite;
private final BiMap<String, UUID> _uuidMap;
private UUIDWrapper _uuidWrapper;
private final Map<String, PlotPlayer> _players = new ConcurrentHashMap<>();
private Connection getConnection() {
synchronized (_sqLite) {
return _sqLite.getConnection();
}
}
public SQLUUIDHandler() {
Bukkit.getPluginManager().registerEvents(this, JavaPlugin.getPlugin(BukkitMain.class));
_sqLite = new SQLite("./plugins/PlotSquared/usercache.db");
try {
_sqLite.openConnection();
} catch(final Exception e) {
e.printStackTrace();
}
try {
PreparedStatement stmt = getConnection().prepareStatement("CREATE TABLE IF NOT EXISTS `usercache` (cache_key INTEGER PRIMARY KEY, uuid VARCHAR(32) NOT NULL, username VARCHAR(32) NOT NULL)");
stmt.execute();
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
_uuidMap = Maps.synchronizedBiMap(HashBiMap.create(new HashMap<String, UUID>()));
_startCaching();
}
@Override
public void handleShutdown() {
try {
getConnection().close();
} catch (SQLException e) {
throw new SQLUUIDHandlerException("Couldn't close database connection", e);
}
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
@SuppressWarnings("unused")
public void onPlayerJoin(final PlayerLoginEvent event) {
TaskManager.runTaskAsync(new Runnable() {
@Override
public void run() {
if (!nameExists(new StringWrapper(event.getPlayer().getName()))) {
add(new StringWrapper(event.getPlayer().getName()), event.getPlayer().getUniqueId());
}
}
});
}
@Override
public void startCaching() {
// startCaching();
}
@Override
public void setUUIDWrapper(UUIDWrapper wrapper) {
this._uuidWrapper = wrapper;
}
@Override
public UUIDWrapper getUUIDWrapper() {
return _uuidWrapper;
}
@Override
public Map<String, PlotPlayer> getPlayers() {
return _players;
}
public void _startCaching() {
TaskManager.runTaskAsync(new Runnable() {
@Override
public void run() {
try {
PreparedStatement statement = getConnection().prepareStatement("SELECT `uuid`, `username` FROM `usercache`");
ResultSet resultSet = statement.executeQuery();
StringWrapper username;
UUID uuid;
boolean found = false;
while (resultSet.next()) {
found = true;
username = new StringWrapper(resultSet.getString("username"));
uuid = UUID.fromString(resultSet.getString("uuid"));
_uuidMap.put(username.value, uuid);
}
_uuidMap.put("*", DBFunc.everyone);
statement.close();
if (!found) {
PS.log(C.PREFIX.s() + "&cUsing player data files, couldn't find any cached UUIDs");
for (World world : Bukkit.getWorlds()) {
_cacheAll(world.getName());
}
PS.log(C.PREFIX.s() + "&cWill fetch the uuids for all plots!");
List<UUID> toFetch = new ArrayList<>();
for (UUID u : UUIDHandler.getAllUUIDS()) {
if (!uuidExists(u)) {
toFetch.add(u);
}
}
PS.log(C.PREFIX.s() + "&cFetching &6" + toFetch.size() + "&c uuids!");
if (Settings.OFFLINE_MODE) {
if (!(_uuidWrapper instanceof OfflineUUIDWrapper)) {
PS.log(C.PREFIX.s() + "Offline mode is on, but the uuid wrapper isn't set for offline mode. Activating appropriate uuid wrapper");
if (Settings.UUID_LOWERCASE) {
_uuidWrapper = new LowerOfflineUUIDWrapper();
} else {
_uuidWrapper = new OfflineUUIDWrapper();
}
}
}
List<UUID> fetched = new ArrayList<>();
for (UUID u : toFetch) {
OfflinePlayer plr = Bukkit.getOfflinePlayer(u);
if (plr != null) {
if (plr.getName() != null) {
add(new StringWrapper(plr.getName()), u);
fetched.add(u);
}
}
}
PS.log(C.PREFIX.s() + "&cFetched &6" + fetched.size() + "&c from player files!");
toFetch.removeAll(fetched);
if (!Settings.OFFLINE_MODE) {
if (toFetch.isEmpty()) {
return;
}
PS.log(C.PREFIX.s() + "&cWill fetch &6" + toFetch.size() + "&c from mojang!");
int i = 0;
Iterator<UUID> iterator = toFetch.iterator();
while(iterator.hasNext()) {
StringBuilder url = new StringBuilder("http://api.intellectualsites.com/uuid/?user=");
List<UUID> currentIteration = new ArrayList<>();
while (i++ <= 15 && iterator.hasNext()) {
UUID _uuid = iterator.next();
url.append(_uuid.toString());
if (iterator.hasNext()) {
url.append(",");
}
currentIteration.add(_uuid);
}
PS.log(C.PREFIX.s() + "&cWill attempt to fetch &6" + currentIteration.size() + "&c uuids from: &6" + url.toString());
try {
HttpURLConnection connection = (HttpURLConnection) new URL(url.toString()).openConnection();
connection.setRequestProperty("User-Agent", "Mozilla/5.0");
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
StringBuilder rawJSON = new StringBuilder();
while ((line = reader.readLine()) != null) {
rawJSON.append(line);
}
reader.close();
JSONObject object = new JSONObject(rawJSON.toString());
for (UUID _u : currentIteration) {
Object o = object.getJSONObject(_u.toString().replace("-", "")).get("username");
if (o == null || !(o instanceof String)) {
continue;
}
add(new StringWrapper(o.toString()), _u);
}
} catch(final Exception e) {
e.printStackTrace();
}
i = 0;
}
}
}
} catch (SQLException e) {
throw new SQLUUIDHandlerException("Couldn't select :s", e);
}
}
});
}
@Override
public void add(final StringWrapper name, final UUID uuid) {
if ((uuid == null) || (name == null)) {
PS.log(C.PREFIX.s() + "&cSQL Caching Failed: name/uuid was null??");
return;
}
if (name.value == null) {
PS.log(C.PREFIX.s() + "&cname.value == null for: " + uuid);
return;
}
if (_uuidMap.containsKey(name.value)) {
_uuidMap.remove(name.value);
}
if (_uuidMap.containsValue(uuid)) {
_uuidMap.inverse().remove(uuid);
}
_uuidMap.put(name.value, uuid);
TaskManager.runTaskAsync(new Runnable() {
@Override
public void run() {
try {
PreparedStatement statement = getConnection().prepareStatement("INSERT INTO usercache (`uuid`, `username`) VALUES(?, ?)");
statement.setString(1, uuid.toString());
statement.setString(2, name.toString());
statement.execute();
PS.log(C.PREFIX.s() + "&cAdded '&6" + uuid + "&c' - '&6" + name + "&c'");
} catch (SQLException e) {
e.printStackTrace();
}
}
});
}
@Override
public boolean uuidExists(final UUID uuid) {
return _uuidMap.containsValue(uuid);
}
@Override
public BiMap<StringWrapper, UUID> getUUIDMap() {
BiMap<StringWrapper, UUID> map = HashBiMap.create();
for (Map.Entry<String, UUID> entry : _uuidMap.entrySet()) {
map.put(new StringWrapper(entry.getKey()), entry.getValue());
}
return map;
}
@Override
public boolean nameExists(final StringWrapper name) {
return _uuidMap.containsKey(name.value);
}
@Override
public void cacheWorld(String world) {}
@SuppressWarnings("deprecation")
private void _cacheAll(final String world) {
final File container = Bukkit.getWorldContainer();
PS.log(C.PREFIX.s() + "&6Starting player data caching for: " + world);
final HashMap<StringWrapper, UUID> toAdd = new HashMap<>();
if (Settings.TWIN_MODE_UUID) {
Set<UUID> all = getUUIDMap().values();
PS.log("&aFast mode UUID caching enabled!");
final File playerdataFolder = new File(container, world + File.separator + "playerdata");
String[] dat = playerdataFolder.list(new FilenameFilter() {
@Override
public boolean accept(final File f, final String s) {
return s.endsWith(".dat");
}
});
boolean check = all.size() == 0;
if (dat != null) {
for (final String current : dat) {
final String s = current.replaceAll(".dat$", "");
try {
UUID uuid = UUID.fromString(s);
if (check || all.contains(uuid)) {
File file = new File(playerdataFolder + File.separator + current);
InputSupplier<FileInputStream> is = Files.newInputStreamSupplier(file);
NbtCompound compound = NbtFactory.fromStream(is, StreamOptions.GZIP_COMPRESSION);
NbtCompound bukkit = (NbtCompound) compound.get("bukkit");
String name = (String) bukkit.get("lastKnownName");
long last = (long) bukkit.get("lastPlayed");
ExpireManager.dates.put(uuid, last);
toAdd.put(new StringWrapper(name), uuid);
}
} catch (final Exception e) {
e.printStackTrace();
PS.log(C.PREFIX.s() + "Invalid playerdata: " + current);
}
}
}
cache(toAdd);
return;
}
final HashSet<String> worlds = new HashSet<>();
worlds.add(world);
worlds.add("world");
final HashSet<UUID> uuids = new HashSet<>();
final HashSet<String> names = new HashSet<>();
File playerdataFolder = null;
for (final String worldname : worlds) {
// Getting UUIDs
playerdataFolder = new File(container, worldname + File.separator + "playerdata");
String[] dat = playerdataFolder.list(new FilenameFilter() {
@Override
public boolean accept(final File f, final String s) {
return s.endsWith(".dat");
}
});
if (dat != null && dat.length != 0) {
for (final String current : dat) {
final String s = current.replaceAll(".dat$", "");
try {
final UUID uuid = UUID.fromString(s);
uuids.add(uuid);
} catch (final Exception e) {
PS.log(C.PREFIX.s() + "Invalid playerdata: " + current);
}
}
break;
}
// Getting names
final File playersFolder = new File(worldname + File.separator + "players");
dat = playersFolder.list(new FilenameFilter() {
@Override
public boolean accept(final File f, final String s) {
return s.endsWith(".dat");
}
});
if (dat != null && dat.length != 0) {
for (final String current : dat) {
names.add(current.replaceAll(".dat$", ""));
}
break;
}
}
for (UUID uuid : uuids) {
try {
File file = new File(playerdataFolder + File.separator + uuid.toString() + ".dat");
InputSupplier<FileInputStream> is = Files.newInputStreamSupplier(file);
NbtCompound compound = NbtFactory.fromStream(is, StreamOptions.GZIP_COMPRESSION);
NbtCompound bukkit = (NbtCompound) compound.get("bukkit");
String name = (String) bukkit.get("lastKnownName");
long last = (long) bukkit.get("lastPlayed");
if (Settings.OFFLINE_MODE) {
if (Settings.UUID_LOWERCASE && !name.toLowerCase().equals(name)) {
uuid = _uuidWrapper.getUUID(name);
} else {
long most = (long) compound.get("UUIDMost");
long least = (long) compound.get("UUIDLeast");
uuid = new UUID(most, least);
}
}
ExpireManager.dates.put(uuid, last);
toAdd.put(new StringWrapper(name), uuid);
} catch (final Throwable e) {
PS.log(C.PREFIX.s() + "&6Invalid playerdata: " + uuid.toString() + ".dat");
}
}
for (final String name : names) {
final UUID uuid = _uuidWrapper.getUUID(name);
final StringWrapper nameWrap = new StringWrapper(name);
toAdd.put(nameWrap, uuid);
}
if (_uuidMap.size() == 0) {
for (OfflinePlotPlayer op : _uuidWrapper.getOfflinePlayers()) {
if (op.getLastPlayed() != 0) {
String name = op.getName();
StringWrapper wrap = new StringWrapper(name);
UUID uuid = _uuidWrapper.getUUID(op);
toAdd.put(wrap, uuid);
}
}
}
cache(toAdd);
}
@Override
public void cache(final Map<StringWrapper, UUID> toAdd) {
for (Map.Entry<StringWrapper, UUID> entry : toAdd.entrySet()) {
add(entry.getKey(), entry.getValue());
}
}
@Override
public String getName(final UUID uuid) {
if (uuid == null) {
return null;
}
final PlotPlayer player = getPlayer(uuid);
if (player != null) {
return player.getName();
}
if (_uuidMap.containsValue(uuid)) {
return _uuidMap.inverse().get(uuid);
}
if (Settings.OFFLINE_MODE) {
if (!(_uuidWrapper instanceof OfflineUUIDWrapper)) {
PS.log(C.PREFIX.s() + "Offline mode is on, but the uuid wrapper isn't set for offline mode. Activating appropriate uuid wrapper");
if (Settings.UUID_LOWERCASE) {
_uuidWrapper = new LowerOfflineUUIDWrapper();
} else {
_uuidWrapper = new OfflineUUIDWrapper();
}
}
}
OfflinePlayer plr = Bukkit.getOfflinePlayer(uuid);
if (plr != null) {
add(new StringWrapper(plr.getName()), plr.getUniqueId());
return plr.getName();
}
if (!Settings.OFFLINE_MODE) {
PS.log(C.PREFIX.s() + "Name for '" + uuid + "' was null. We'll cache this from the mojang servers!");
TaskManager.runTaskAsync(new Runnable() {
@Override
public void run() {
String url = "http://api.intellectualsites.com/uuid/?user=" + uuid;
try {
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
connection.setRequestProperty("User-Agent", "Mozilla/5.0");
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
StringBuilder rawJSON = new StringBuilder();
while ((line = reader.readLine()) != null) {
rawJSON.append(line);
}
reader.close();
JSONObject object = new JSONObject(rawJSON.toString());
String username = object.getJSONObject(uuid.toString().replace("-", "")).getString("username");
add(new StringWrapper(username), uuid);
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
return null;
}
@Override
public UUID getUUID(final PlotPlayer player) {
return _uuidWrapper.getUUID(player);
}
@Override
public UUID getUUID(final BukkitOfflinePlayer player) {
return _uuidWrapper.getUUID(player);
}
@Override
public PlotPlayer getPlayer(final UUID uuid) {
for (final PlotPlayer player : _players.values()) {
if (player.getUUID().equals(uuid)) {
return player;
}
}
return null;
}
@Override
public PlotPlayer getPlayer(final String name) {
return _players.get(name);
}
@Override
public UUID getUUID(final String name) {
if ((name == null) || (name.length() == 0)) {
return null;
}
// check online
final PlotPlayer player = getPlayer(name);
if (player != null) {
return player.getUUID();
}
// check cache
UUID uuid = _uuidMap.get(name);
if (uuid != null) {
return uuid;
}
if (Settings.OFFLINE_MODE) {
if (!(_uuidWrapper instanceof OfflineUUIDWrapper)) {
PS.log(C.PREFIX.s() + "Offline mode is on, but the uuid wrapper isn't set for offline mode. Activating appropriate uuid wrapper");
if (Settings.UUID_LOWERCASE) {
_uuidWrapper = new LowerOfflineUUIDWrapper();
} else {
_uuidWrapper = new OfflineUUIDWrapper();
}
}
}
// Read from disk OR convert directly to offline UUID
if (Settings.UUID_FROM_DISK || (_uuidWrapper instanceof OfflineUUIDWrapper)) {
uuid = _uuidWrapper.getUUID(name);
add(new StringWrapper(name), uuid);
return uuid;
}
PS.log(C.PREFIX.s() + "UUID for '" + name + "' was null. We'll cache this from the mojang servers!");
TaskManager.runTaskAsync(new Runnable() {
@Override
public void run() {
String url = "http://api.intellectualsites.com/uuid/?user=" + name;
try {
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
connection.setRequestProperty("User-Agent", "Mozilla/5.0");
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
StringBuilder rawJSON = new StringBuilder();
while ((line = reader.readLine()) != null) {
rawJSON.append(line);
}
reader.close();
JSONObject object = new JSONObject(rawJSON.toString());
UUID uuid = UUID.fromString(object.getJSONObject(name).getString("dashed"));
add(new StringWrapper(name), uuid);
} catch (IOException e) {
e.printStackTrace();
}
}
});
return null;
}
}

View File

@ -0,0 +1,32 @@
package com.plotsquared.bukkit.util.bukkit.uuid;
import com.google.common.collect.BiMap;
import com.plotsquared.bukkit.object.BukkitOfflinePlayer;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.object.StringWrapper;
import com.intellectualcrafters.plot.uuid.UUIDWrapper;
import java.util.Map;
import java.util.UUID;
public interface UUIDHandlerImplementation {
void add(final StringWrapper name, final UUID uuid);
boolean uuidExists(final UUID uuid);
BiMap<StringWrapper, UUID> getUUIDMap();
boolean nameExists(final StringWrapper wrapper);
void handleShutdown();
void cacheWorld(String world);
void cache(final Map<StringWrapper, UUID> toAdd);
String getName(final UUID uuid);
UUID getUUID(final PlotPlayer player);
UUID getUUID(final BukkitOfflinePlayer player);
PlotPlayer getPlayer(final UUID uuid);
PlotPlayer getPlayer(String name);
UUID getUUID(String name);
void startCaching();
void setUUIDWrapper(UUIDWrapper wrapper);
UUIDWrapper getUUIDWrapper();
Map<String, PlotPlayer> getPlayers();
}