mirror of
https://github.com/IntellectualSites/PlotSquared.git
synced 2025-06-25 02:04:44 +02:00
Update packages. This will not be appreciated 🐱
This commit is contained in:
@ -1,855 +0,0 @@
|
||||
package com.plotsquared.bukkit;
|
||||
|
||||
import com.intellectualcrafters.configuration.ConfigurationSection;
|
||||
import com.intellectualcrafters.plot.IPlotMain;
|
||||
import com.intellectualcrafters.plot.PS;
|
||||
import com.intellectualcrafters.plot.config.C;
|
||||
import com.intellectualcrafters.plot.config.ConfigurationNode;
|
||||
import com.intellectualcrafters.plot.config.Settings;
|
||||
import com.intellectualcrafters.plot.generator.GeneratorWrapper;
|
||||
import com.intellectualcrafters.plot.generator.HybridGen;
|
||||
import com.intellectualcrafters.plot.generator.HybridUtils;
|
||||
import com.intellectualcrafters.plot.generator.IndependentPlotGenerator;
|
||||
import com.intellectualcrafters.plot.object.*;
|
||||
import com.intellectualcrafters.plot.object.chat.PlainChatManager;
|
||||
import com.intellectualcrafters.plot.object.worlds.PlotAreaManager;
|
||||
import com.intellectualcrafters.plot.object.worlds.SinglePlotArea;
|
||||
import com.intellectualcrafters.plot.object.worlds.SinglePlotAreaManager;
|
||||
import com.intellectualcrafters.plot.object.worlds.SingleWorldGenerator;
|
||||
import com.intellectualcrafters.plot.util.*;
|
||||
import com.intellectualcrafters.plot.util.block.QueueProvider;
|
||||
import com.intellectualcrafters.plot.uuid.UUIDWrapper;
|
||||
import com.plotsquared.bukkit.database.plotme.ClassicPlotMeConnector;
|
||||
import com.plotsquared.bukkit.database.plotme.LikePlotMeConverter;
|
||||
import com.plotsquared.bukkit.database.plotme.PlotMeConnector_017;
|
||||
import com.plotsquared.bukkit.generator.BukkitPlotGenerator;
|
||||
import com.plotsquared.bukkit.listeners.*;
|
||||
import com.plotsquared.bukkit.titles.DefaultTitle_111;
|
||||
import com.plotsquared.bukkit.util.*;
|
||||
import com.plotsquared.bukkit.util.block.*;
|
||||
import com.plotsquared.bukkit.uuid.*;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.bukkit.metadata.FixedMetadataValue;
|
||||
import org.bukkit.metadata.MetadataValue;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import static com.intellectualcrafters.plot.util.ReflectionUtils.getRefClass;
|
||||
|
||||
public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain {
|
||||
|
||||
public static WorldEdit worldEdit;
|
||||
private static ConcurrentHashMap<String, Plugin> pluginMap;
|
||||
|
||||
static {
|
||||
// Disable AWE as otherwise both fail to load
|
||||
PluginManager manager = Bukkit.getPluginManager();
|
||||
try {
|
||||
Settings.load(new File("plugins/PlotSquared/config/settings.yml"));
|
||||
if (Settings.Enabled_Components.PLOTME_CONVERTER) { // Only disable PlotMe if conversion is enabled
|
||||
Field pluginsField = manager.getClass().getDeclaredField("plugins");
|
||||
Field lookupNamesField = manager.getClass().getDeclaredField("lookupNames");
|
||||
pluginsField.setAccessible(true);
|
||||
lookupNamesField.setAccessible(true);
|
||||
List<Plugin> plugins = (List<Plugin>) pluginsField.get(manager);
|
||||
Iterator<Plugin> iter = plugins.iterator();
|
||||
while (iter.hasNext()) {
|
||||
if (iter.next().getName().startsWith("PlotMe")) {
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
Map<String, Plugin> lookupNames =
|
||||
(Map<String, Plugin>) lookupNamesField.get(manager);
|
||||
lookupNames.remove("PlotMe");
|
||||
lookupNames.remove("PlotMe-DefaultGenerator");
|
||||
pluginsField.set(manager, new ArrayList<Plugin>(plugins) {
|
||||
@Override public boolean add(Plugin plugin) {
|
||||
if (plugin.getName().startsWith("PlotMe")) {
|
||||
System.out.print("Disabling `" + plugin.getName()
|
||||
+ "` for PlotMe conversion (configure in PlotSquared settings.yml)");
|
||||
} else {
|
||||
return super.add(plugin);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
pluginMap = new ConcurrentHashMap<String, Plugin>(lookupNames) {
|
||||
@Override public Plugin put(String key, Plugin plugin) {
|
||||
if (!plugin.getName().startsWith("PlotMe")) {
|
||||
return super.put(key, plugin);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
lookupNamesField.set(manager, pluginMap);
|
||||
}
|
||||
} catch (Throwable ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
private int[] version;
|
||||
private String name;
|
||||
private SingleWorldListener singleWorldListener;
|
||||
private Method methodUnloadChunk0;
|
||||
private boolean methodUnloadSetup = false;
|
||||
|
||||
@Override public int[] getServerVersion() {
|
||||
if (this.version == null) {
|
||||
try {
|
||||
this.version = new int[3];
|
||||
String[] split = Bukkit.getBukkitVersion().split("-")[0].split("\\.");
|
||||
this.version[0] = Integer.parseInt(split[0]);
|
||||
this.version[1] = Integer.parseInt(split[1]);
|
||||
if (split.length == 3) {
|
||||
this.version[2] = Integer.parseInt(split[2]);
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
e.printStackTrace();
|
||||
PS.debug(StringMan.getString(Bukkit.getBukkitVersion()));
|
||||
PS.debug(StringMan.getString(Bukkit.getBukkitVersion().split("-")[0].split("\\.")));
|
||||
return new int[] {1, 13, 0};
|
||||
}
|
||||
}
|
||||
return this.version;
|
||||
}
|
||||
|
||||
@Override public void onEnable() {
|
||||
if (pluginMap != null) {
|
||||
pluginMap.put("PlotMe-DefaultGenerator", this);
|
||||
}
|
||||
this.name = getDescription().getName();
|
||||
getServer().getName();
|
||||
new PS(this, "Bukkit");
|
||||
if (Settings.Enabled_Components.METRICS) {
|
||||
new Metrics(this).start();
|
||||
PS.log(C.PREFIX + "&6Metrics enabled.");
|
||||
} else {
|
||||
PS.log(C.CONSOLE_PLEASE_ENABLE_METRICS.f(getPluginName()));
|
||||
}
|
||||
if (Settings.Enabled_Components.WORLDS) {
|
||||
TaskManager.IMP.taskRepeat(new Runnable() {
|
||||
@Override public void run() {
|
||||
unload();
|
||||
}
|
||||
}, 20);
|
||||
try {
|
||||
singleWorldListener = new SingleWorldListener(this);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public SingleWorldListener getSingleWorldListener() {
|
||||
return singleWorldListener;
|
||||
}
|
||||
|
||||
public void unload() {
|
||||
if (!methodUnloadSetup) {
|
||||
methodUnloadSetup = true;
|
||||
try {
|
||||
ReflectionUtils.RefClass classCraftWorld = getRefClass("{cb}.CraftWorld");
|
||||
methodUnloadChunk0 = classCraftWorld.getRealClass()
|
||||
.getDeclaredMethod("unloadChunk0", int.class, int.class, boolean.class);
|
||||
methodUnloadChunk0.setAccessible(true);
|
||||
} catch (Throwable ignore) {
|
||||
ignore.printStackTrace();
|
||||
}
|
||||
}
|
||||
PlotAreaManager manager = PS.get().getPlotAreaManager();
|
||||
if (manager instanceof SinglePlotAreaManager) {
|
||||
long start = System.currentTimeMillis();
|
||||
SinglePlotArea area = ((SinglePlotAreaManager) manager).getArea();
|
||||
outer:
|
||||
for (World world : Bukkit.getWorlds()) {
|
||||
String name = world.getName();
|
||||
char char0 = name.charAt(0);
|
||||
if (!Character.isDigit(char0) && char0 != '-')
|
||||
continue;
|
||||
if (!world.getPlayers().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
PlotId id = PlotId.fromString(name);
|
||||
if (id != null) {
|
||||
Plot plot = area.getOwnedPlot(id);
|
||||
if (plot != null) {
|
||||
if (PlotPlayer.wrap(plot.owner) == null) {
|
||||
if (world.getKeepSpawnInMemory()) {
|
||||
world.setKeepSpawnInMemory(false);
|
||||
return;
|
||||
}
|
||||
Chunk[] chunks = world.getLoadedChunks();
|
||||
if (chunks.length == 0) {
|
||||
if (!Bukkit.unloadWorld(world, true)) {
|
||||
PS.debug("Failed to unload " + world.getName());
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
int index = 0;
|
||||
do {
|
||||
Chunk chunkI = chunks[index++];
|
||||
boolean result;
|
||||
if (methodUnloadChunk0 != null) {
|
||||
try {
|
||||
result = (boolean) methodUnloadChunk0
|
||||
.invoke(world, chunkI.getX(), chunkI.getZ(), true);
|
||||
} catch (Throwable e) {
|
||||
methodUnloadChunk0 = null;
|
||||
e.printStackTrace();
|
||||
continue outer;
|
||||
}
|
||||
} else {
|
||||
result = world
|
||||
.unloadChunk(chunkI.getX(), chunkI.getZ(), true, false);
|
||||
}
|
||||
if (!result) {
|
||||
continue outer;
|
||||
}
|
||||
} while (index < chunks.length
|
||||
&& System.currentTimeMillis() - start < 5);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void onDisable() {
|
||||
PS.get().disable();
|
||||
Bukkit.getScheduler().cancelTasks(this);
|
||||
}
|
||||
|
||||
@Override public void log(String message) {
|
||||
try {
|
||||
message = C.color(message);
|
||||
if (!Settings.Chat.CONSOLE_COLOR) {
|
||||
message = ChatColor.stripColor(message);
|
||||
}
|
||||
this.getServer().getConsoleSender().sendMessage(message);
|
||||
} catch (Throwable ignored) {
|
||||
System.out.println(ConsoleColors.fromString(message));
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void disable() {
|
||||
onDisable();
|
||||
}
|
||||
|
||||
@Override public int[] getPluginVersion() {
|
||||
String ver = getDescription().getVersion();
|
||||
if (ver.contains("-")) {
|
||||
ver = ver.split("-")[0];
|
||||
}
|
||||
String[] split = ver.split("\\.");
|
||||
return new int[] {Integer.parseInt(split[0]), Integer.parseInt(split[1]),
|
||||
Integer.parseInt(split[2])};
|
||||
}
|
||||
|
||||
@Override public String getPluginVersionString() {
|
||||
return getDescription().getVersion();
|
||||
}
|
||||
|
||||
@Override public String getPluginName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override public void registerCommands() {
|
||||
BukkitCommand bukkitCommand = new BukkitCommand();
|
||||
PluginCommand plotCommand = getCommand("plots");
|
||||
plotCommand.setExecutor(bukkitCommand);
|
||||
plotCommand.setAliases(Arrays.asList("p", "ps", "plotme", "plot"));
|
||||
plotCommand.setTabCompleter(bukkitCommand);
|
||||
}
|
||||
|
||||
@Override public File getDirectory() {
|
||||
return getDataFolder();
|
||||
}
|
||||
|
||||
@Override public File getWorldContainer() {
|
||||
return Bukkit.getWorldContainer();
|
||||
}
|
||||
|
||||
@Override public TaskManager getTaskManager() {
|
||||
return new BukkitTaskManager(this);
|
||||
}
|
||||
|
||||
@Override public void runEntityTask() {
|
||||
PS.log(C.PREFIX + "KillAllEntities started.");
|
||||
TaskManager.runTaskRepeat(new Runnable() {
|
||||
@Override public void run() {
|
||||
PS.get().foreachPlotArea(new RunnableVal<PlotArea>() {
|
||||
@Override public void run(PlotArea plotArea) {
|
||||
World world = Bukkit.getWorld(plotArea.worldname);
|
||||
try {
|
||||
if (world == null) {
|
||||
return;
|
||||
}
|
||||
List<Entity> entities = world.getEntities();
|
||||
Iterator<Entity> iterator = entities.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Entity entity = iterator.next();
|
||||
switch (entity.getType()) {
|
||||
case EGG:
|
||||
case COMPLEX_PART:
|
||||
case FISHING_HOOK:
|
||||
case ENDER_SIGNAL:
|
||||
case LINGERING_POTION:
|
||||
case AREA_EFFECT_CLOUD:
|
||||
case EXPERIENCE_ORB:
|
||||
case LEASH_HITCH:
|
||||
case FIREWORK:
|
||||
case WEATHER:
|
||||
case LIGHTNING:
|
||||
case WITHER_SKULL:
|
||||
case UNKNOWN:
|
||||
case PLAYER:
|
||||
// non moving / unmovable
|
||||
continue;
|
||||
case THROWN_EXP_BOTTLE:
|
||||
case SPLASH_POTION:
|
||||
case SNOWBALL:
|
||||
case SHULKER_BULLET:
|
||||
case SPECTRAL_ARROW:
|
||||
case TIPPED_ARROW:
|
||||
case ENDER_PEARL:
|
||||
case ARROW:
|
||||
case LLAMA_SPIT:
|
||||
// managed elsewhere | projectile
|
||||
continue;
|
||||
case ITEM_FRAME:
|
||||
case PAINTING:
|
||||
// Not vehicles
|
||||
continue;
|
||||
case ARMOR_STAND:
|
||||
// Temporarily classify as vehicle
|
||||
case MINECART:
|
||||
case MINECART_CHEST:
|
||||
case MINECART_COMMAND:
|
||||
case MINECART_FURNACE:
|
||||
case MINECART_HOPPER:
|
||||
case MINECART_MOB_SPAWNER:
|
||||
case ENDER_CRYSTAL:
|
||||
case MINECART_TNT:
|
||||
case BOAT:
|
||||
if (Settings.Enabled_Components.KILL_ROAD_VEHICLES) {
|
||||
com.intellectualcrafters.plot.object.Location location =
|
||||
BukkitUtil.getLocation(entity.getLocation());
|
||||
Plot plot = location.getPlot();
|
||||
if (plot == null) {
|
||||
if (location.isPlotArea()) {
|
||||
iterator.remove();
|
||||
entity.remove();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
List<MetadataValue> meta = entity.getMetadata("plot");
|
||||
if (meta.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
Plot origin = (Plot) meta.get(0).value();
|
||||
if (!plot.equals(origin.getBasePlot(false))) {
|
||||
iterator.remove();
|
||||
entity.remove();
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
case SMALL_FIREBALL:
|
||||
case FIREBALL:
|
||||
case DRAGON_FIREBALL:
|
||||
case DROPPED_ITEM:
|
||||
if (Settings.Enabled_Components.KILL_ROAD_ITEMS) {
|
||||
entity.remove();
|
||||
}
|
||||
// dropped item
|
||||
continue;
|
||||
case PRIMED_TNT:
|
||||
case FALLING_BLOCK:
|
||||
// managed elsewhere
|
||||
continue;
|
||||
case LLAMA:
|
||||
case DONKEY:
|
||||
case MULE:
|
||||
case ZOMBIE_HORSE:
|
||||
case SKELETON_HORSE:
|
||||
case HUSK:
|
||||
case ELDER_GUARDIAN:
|
||||
case WITHER_SKELETON:
|
||||
case STRAY:
|
||||
case ZOMBIE_VILLAGER:
|
||||
case EVOKER:
|
||||
case EVOKER_FANGS:
|
||||
case VEX:
|
||||
case VINDICATOR:
|
||||
case POLAR_BEAR:
|
||||
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: {
|
||||
if (Settings.Enabled_Components.KILL_ROAD_MOBS) {
|
||||
Location location = entity.getLocation();
|
||||
if (BukkitUtil.getLocation(location).isPlotRoad()) {
|
||||
if (entity instanceof LivingEntity) {
|
||||
LivingEntity livingEntity =
|
||||
(LivingEntity) entity;
|
||||
if (!livingEntity.isLeashed() || !entity
|
||||
.hasMetadata("keep")) {
|
||||
Entity passenger = entity.getPassenger();
|
||||
if (!(passenger instanceof Player) && entity
|
||||
.getMetadata("keep").isEmpty()) {
|
||||
iterator.remove();
|
||||
entity.remove();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Entity passenger = entity.getPassenger();
|
||||
if (!(passenger instanceof Player) && entity
|
||||
.getMetadata("keep").isEmpty()) {
|
||||
iterator.remove();
|
||||
entity.remove();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
case SHULKER: {
|
||||
if (Settings.Enabled_Components.KILL_ROAD_MOBS) {
|
||||
LivingEntity livingEntity = (LivingEntity) entity;
|
||||
List<MetadataValue> meta = entity.getMetadata("plot");
|
||||
if (meta != null && !meta.isEmpty()) {
|
||||
if (livingEntity.isLeashed())
|
||||
continue;
|
||||
|
||||
List<MetadataValue> keep =
|
||||
entity.getMetadata("keep");
|
||||
if (keep != null && !keep.isEmpty())
|
||||
continue;
|
||||
|
||||
PlotId originalPlotId =
|
||||
(PlotId) meta.get(0).value();
|
||||
if (originalPlotId != null) {
|
||||
com.intellectualcrafters.plot.object.Location
|
||||
pLoc = BukkitUtil
|
||||
.getLocation(entity.getLocation());
|
||||
PlotArea area = pLoc.getPlotArea();
|
||||
if (area != null) {
|
||||
PlotId currentPlotId =
|
||||
PlotId.of(area.getPlotAbs(pLoc));
|
||||
if (!originalPlotId.equals(currentPlotId)
|
||||
&& (currentPlotId == null || !area
|
||||
.getPlot(originalPlotId)
|
||||
.equals(area.getPlot(currentPlotId)))) {
|
||||
iterator.remove();
|
||||
entity.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//This is to apply the metadata to already spawned shulkers (see EntitySpawnListener.java)
|
||||
com.intellectualcrafters.plot.object.Location pLoc =
|
||||
BukkitUtil.getLocation(entity.getLocation());
|
||||
PlotArea area = pLoc.getPlotArea();
|
||||
if (area != null) {
|
||||
PlotId currentPlotId =
|
||||
PlotId.of(area.getPlotAbs(pLoc));
|
||||
if (currentPlotId != null) {
|
||||
entity.setMetadata("plot",
|
||||
new FixedMetadataValue(
|
||||
(Plugin) PS.get().IMP,
|
||||
currentPlotId));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}, 20);
|
||||
}
|
||||
|
||||
@Override public final ChunkGenerator getDefaultWorldGenerator(String world, String id) {
|
||||
if (Settings.Enabled_Components.PLOTME_CONVERTER) {
|
||||
initPlotMeConverter();
|
||||
Settings.Enabled_Components.PLOTME_CONVERTER = false;
|
||||
}
|
||||
IndependentPlotGenerator result;
|
||||
if (id != null && id.equalsIgnoreCase("single")) {
|
||||
result = new SingleWorldGenerator();
|
||||
} else {
|
||||
result = PS.get().IMP.getDefaultGenerator();
|
||||
if (!PS.get().setupPlotWorld(world, id, result)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return (ChunkGenerator) result.specify(world);
|
||||
}
|
||||
|
||||
@Override public void registerPlayerEvents() {
|
||||
PlayerEvents main = new PlayerEvents();
|
||||
getServer().getPluginManager().registerEvents(main, this);
|
||||
try {
|
||||
getServer().getClass().getMethod("spigot");
|
||||
Class.forName("org.bukkit.event.entity.EntitySpawnEvent");
|
||||
getServer().getPluginManager().registerEvents(new EntitySpawnListener(), this);
|
||||
} catch (NoSuchMethodException | ClassNotFoundException ignored) {
|
||||
PS.debug("Not running Spigot. Skipping EntitySpawnListener event.");
|
||||
}
|
||||
if (PS.get().checkVersion(getServerVersion(), 1, 7, 9)) {
|
||||
try {
|
||||
getServer().getPluginManager().registerEvents(new EntityPortal_1_7_9(), this);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (PS.get().checkVersion(getServerVersion(), BukkitVersion.v1_8_0)) {
|
||||
try {
|
||||
getServer().getPluginManager().registerEvents(new PlayerEvents_1_8(), this);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (PS.get().checkVersion(getServerVersion(), BukkitVersion.v1_8_3)) {
|
||||
try {
|
||||
getServer().getPluginManager().registerEvents(new PlayerEvents183(), this);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (PS.get().checkVersion(getServerVersion(), BukkitVersion.v1_9_0)) {
|
||||
try {
|
||||
getServer().getPluginManager().registerEvents(new PlayerEvents_1_9(main), this);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void registerInventoryEvents() {
|
||||
// Part of PlayerEvents - can be moved if necessary
|
||||
}
|
||||
|
||||
@Override public void registerPlotPlusEvents() {
|
||||
PlotPlusListener.startRunnable(this);
|
||||
getServer().getPluginManager().registerEvents(new PlotPlusListener(), this);
|
||||
if (PS.get().checkVersion(getServerVersion(), BukkitVersion.v1_12_0)) {
|
||||
getServer().getPluginManager().registerEvents(new PlotPlusListener_1_12(), this);
|
||||
} else {
|
||||
getServer().getPluginManager().registerEvents(new PlotPlusListener_Legacy(), this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void registerForceFieldEvents() {
|
||||
}
|
||||
|
||||
@Override public boolean initWorldEdit() {
|
||||
if (getServer().getPluginManager().getPlugin("WorldEdit") != null) {
|
||||
worldEdit = WorldEdit.getInstance();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override public EconHandler getEconomyHandler() {
|
||||
try {
|
||||
BukkitEconHandler econ = new BukkitEconHandler();
|
||||
if (econ.init()) {
|
||||
return econ;
|
||||
}
|
||||
} catch (Throwable ignored) {
|
||||
PS.debug("No economy detected!");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override public QueueProvider initBlockQueue() {
|
||||
try {
|
||||
new SendChunk();
|
||||
MainUtil.canSendChunk = true;
|
||||
} catch (ClassNotFoundException | NoSuchFieldException | NoSuchMethodException e) {
|
||||
PS.debug(
|
||||
SendChunk.class + " does not support " + StringMan.getString(getServerVersion()));
|
||||
MainUtil.canSendChunk = false;
|
||||
}
|
||||
if (PS.get().checkVersion(getServerVersion(), BukkitVersion.v1_13_0)) {
|
||||
return QueueProvider.of(BukkitLocalQueue.class, BukkitLocalQueue.class);
|
||||
}
|
||||
if (PS.get().checkVersion(getServerVersion(), BukkitVersion.v1_9_0)) {
|
||||
return QueueProvider.of(BukkitLocalQueue_1_9.class, BukkitLocalQueue.class);
|
||||
}
|
||||
if (PS.get().checkVersion(getServerVersion(), BukkitVersion.v1_8_3)) {
|
||||
return QueueProvider.of(BukkitLocalQueue_1_8_3.class, BukkitLocalQueue.class);
|
||||
}
|
||||
if (PS.get().checkVersion(getServerVersion(), BukkitVersion.v1_8_0)) {
|
||||
return QueueProvider.of(BukkitLocalQueue_1_8.class, BukkitLocalQueue.class);
|
||||
}
|
||||
return QueueProvider.of(BukkitLocalQueue_1_7.class, BukkitLocalQueue.class);
|
||||
}
|
||||
|
||||
@Override public WorldUtil initWorldUtil() {
|
||||
return new BukkitUtil();
|
||||
}
|
||||
|
||||
@Override public boolean initPlotMeConverter() {
|
||||
if (new LikePlotMeConverter("PlotMe").run(new ClassicPlotMeConnector())) {
|
||||
return true;
|
||||
} else if (new LikePlotMeConverter("PlotMe").run(new PlotMeConnector_017())) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override public GeneratorWrapper<?> getGenerator(String world, String name) {
|
||||
if (name == null) {
|
||||
return null;
|
||||
}
|
||||
Plugin genPlugin = Bukkit.getPluginManager().getPlugin(name);
|
||||
if (genPlugin != null && genPlugin.isEnabled()) {
|
||||
ChunkGenerator gen = genPlugin.getDefaultWorldGenerator(world, "");
|
||||
if (gen instanceof GeneratorWrapper<?>) {
|
||||
return (GeneratorWrapper<?>) gen;
|
||||
}
|
||||
return new BukkitPlotGenerator(world, gen);
|
||||
} else {
|
||||
return new BukkitPlotGenerator(PS.get().IMP.getDefaultGenerator());
|
||||
}
|
||||
}
|
||||
|
||||
@Override public HybridUtils initHybridUtils() {
|
||||
return new BukkitHybridUtils();
|
||||
}
|
||||
|
||||
@Override public SetupUtils initSetupUtils() {
|
||||
return new BukkitSetupUtils();
|
||||
}
|
||||
|
||||
@Override public UUIDHandlerImplementation initUUIDHandler() {
|
||||
boolean checkVersion = false;
|
||||
try {
|
||||
OfflinePlayer.class.getDeclaredMethod("getUniqueId");
|
||||
checkVersion = true;
|
||||
} catch (Throwable ignore) {
|
||||
}
|
||||
UUIDWrapper wrapper;
|
||||
if (Settings.UUID.OFFLINE) {
|
||||
if (Settings.UUID.FORCE_LOWERCASE) {
|
||||
wrapper = new LowerOfflineUUIDWrapper();
|
||||
} else {
|
||||
wrapper = new OfflineUUIDWrapper();
|
||||
}
|
||||
Settings.UUID.OFFLINE = true;
|
||||
} else if (checkVersion) {
|
||||
wrapper = new DefaultUUIDWrapper();
|
||||
Settings.UUID.OFFLINE = false;
|
||||
} else {
|
||||
if (Settings.UUID.FORCE_LOWERCASE) {
|
||||
wrapper = new LowerOfflineUUIDWrapper();
|
||||
} else {
|
||||
wrapper = new OfflineUUIDWrapper();
|
||||
}
|
||||
Settings.UUID.OFFLINE = true;
|
||||
}
|
||||
if (!checkVersion) {
|
||||
PS.log(C.PREFIX
|
||||
+ " &c[WARN] Titles are disabled - please update your version of Bukkit to support this feature.");
|
||||
Settings.TITLES = false;
|
||||
} else {
|
||||
AbstractTitle.TITLE_CLASS = new DefaultTitle_111();
|
||||
if (wrapper instanceof DefaultUUIDWrapper
|
||||
|| wrapper.getClass() == OfflineUUIDWrapper.class && !Bukkit.getOnlineMode()) {
|
||||
Settings.UUID.NATIVE_UUID_PROVIDER = true;
|
||||
}
|
||||
}
|
||||
if (Settings.UUID.OFFLINE) {
|
||||
PS.log(C.PREFIX + " &6" + getPluginName()
|
||||
+ " is using Offline Mode UUIDs either because of user preference, or because you are using an old version of "
|
||||
+ "Bukkit");
|
||||
} else {
|
||||
PS.log(C.PREFIX + " &6" + getPluginName() + " is using online UUIDs");
|
||||
}
|
||||
if (Settings.UUID.USE_SQLUUIDHANDLER) {
|
||||
return new SQLUUIDHandler(wrapper);
|
||||
} else {
|
||||
return new FileUUIDHandler(wrapper);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public ChunkManager initChunkManager() {
|
||||
return new BukkitChunkManager();
|
||||
}
|
||||
|
||||
@Override public EventUtil initEventUtil() {
|
||||
return new BukkitEventUtil();
|
||||
}
|
||||
|
||||
@Override public void unregister(PlotPlayer player) {
|
||||
BukkitUtil.removePlayer(player.getName());
|
||||
}
|
||||
|
||||
@Override public void registerChunkProcessor() {
|
||||
getServer().getPluginManager().registerEvents(new ChunkListener(), this);
|
||||
}
|
||||
|
||||
@Override public void registerWorldEvents() {
|
||||
getServer().getPluginManager().registerEvents(new WorldEvents(), this);
|
||||
}
|
||||
|
||||
@Override public IndependentPlotGenerator getDefaultGenerator() {
|
||||
return new HybridGen();
|
||||
}
|
||||
|
||||
@Override public InventoryUtil initInventoryUtil() {
|
||||
return new BukkitInventoryUtil();
|
||||
}
|
||||
|
||||
@Override public void startMetrics() {
|
||||
new Metrics(this).start();
|
||||
PS.log(C.PREFIX + "&6Metrics enabled.");
|
||||
}
|
||||
|
||||
@Override public void setGenerator(String worldName) {
|
||||
World world = BukkitUtil.getWorld(worldName);
|
||||
if (world == null) {
|
||||
// create world
|
||||
ConfigurationSection worldConfig =
|
||||
PS.get().worlds.getConfigurationSection("worlds." + worldName);
|
||||
String manager = worldConfig.getString("generator.plugin", getPluginName());
|
||||
SetupObject setup = new SetupObject();
|
||||
setup.plotManager = manager;
|
||||
setup.setupGenerator = worldConfig.getString("generator.init", manager);
|
||||
setup.type = worldConfig.getInt("generator.type");
|
||||
setup.terrain = worldConfig.getInt("generator.terrain");
|
||||
setup.step = new ConfigurationNode[0];
|
||||
setup.world = worldName;
|
||||
SetupUtils.manager.setupWorld(setup);
|
||||
world = Bukkit.getWorld(worldName);
|
||||
} else {
|
||||
try {
|
||||
if (!PS.get().hasPlotArea(worldName)) {
|
||||
SetGenCB.setGenerator(BukkitUtil.getWorld(worldName));
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
PS.log("Failed to reload world: " + world + " | " + ignored.getMessage());
|
||||
Bukkit.getServer().unloadWorld(world, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
ChunkGenerator gen = world.getGenerator();
|
||||
if (gen instanceof BukkitPlotGenerator) {
|
||||
PS.get().loadWorld(worldName, (BukkitPlotGenerator) gen);
|
||||
} else if (gen != null) {
|
||||
PS.get().loadWorld(worldName, new BukkitPlotGenerator(worldName, gen));
|
||||
} else if (PS.get().worlds.contains("worlds." + worldName)) {
|
||||
PS.get().loadWorld(worldName, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public SchematicHandler initSchematicHandler() {
|
||||
return new BukkitSchematicHandler();
|
||||
}
|
||||
|
||||
@Override public AbstractTitle initTitleManager() {
|
||||
// Already initialized in UUID handler
|
||||
return AbstractTitle.TITLE_CLASS;
|
||||
}
|
||||
|
||||
@Override public PlotPlayer wrapPlayer(Object player) {
|
||||
if (player instanceof Player) {
|
||||
return BukkitUtil.getPlayer((Player) player);
|
||||
}
|
||||
if (player instanceof OfflinePlayer) {
|
||||
return BukkitUtil.getPlayer((OfflinePlayer) player);
|
||||
}
|
||||
if (player instanceof String) {
|
||||
return UUIDHandler.getPlayer((String) player);
|
||||
}
|
||||
if (player instanceof UUID) {
|
||||
return UUIDHandler.getPlayer((UUID) player);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override public String getNMSPackage() {
|
||||
String name = Bukkit.getServer().getClass().getPackage().getName();
|
||||
return name.substring(name.lastIndexOf('.') + 1);
|
||||
}
|
||||
|
||||
@Override public ChatManager<?> initChatManager() {
|
||||
if (Settings.Chat.INTERACTIVE) {
|
||||
return new BukkitChatManager();
|
||||
} else {
|
||||
return new PlainChatManager();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public GeneratorWrapper<?> wrapPlotGenerator(String world, IndependentPlotGenerator generator) {
|
||||
return new BukkitPlotGenerator(generator);
|
||||
}
|
||||
|
||||
@Override public List<String> getPluginIds() {
|
||||
ArrayList<String> names = new ArrayList<>();
|
||||
for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
|
||||
names.add(plugin.getName() + ';' + plugin.getDescription().getVersion() + ':' + plugin
|
||||
.isEnabled());
|
||||
}
|
||||
return names;
|
||||
}
|
||||
}
|
@ -1,107 +0,0 @@
|
||||
package com.plotsquared.bukkit.chat;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* 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>
|
||||
*
|
||||
* @param <E> The type of elements in the array.
|
||||
* @author Glen Husman
|
||||
* @see Arrays
|
||||
*/
|
||||
public final class ArrayWrapper<E> {
|
||||
|
||||
private E[] _array;
|
||||
|
||||
/**
|
||||
* Creates an array wrapper with some elements.
|
||||
*
|
||||
* @param elements The elements of the array.
|
||||
*/
|
||||
public ArrayWrapper(E... elements) {
|
||||
setArray(elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @return This object's hash code.
|
||||
* @see Arrays#hashCode(Object[])
|
||||
*/
|
||||
@Override public int hashCode() {
|
||||
return Arrays.hashCode(_array);
|
||||
}
|
||||
|
||||
}
|
@ -1,926 +0,0 @@
|
||||
package com.plotsquared.bukkit.chat;
|
||||
|
||||
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 org.bukkit.*;
|
||||
import org.bukkit.Statistic.Type;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerialization;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static com.plotsquared.bukkit.chat.TextualComponent.rawText;
|
||||
|
||||
/**
|
||||
* 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(String)} 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 {
|
||||
|
||||
private static Constructor<?> nmsPacketPlayOutChatConstructor;
|
||||
// The ChatSerializer's instance of Gson
|
||||
private static Object nmsChatSerializerGsonInstance;
|
||||
private static Method fromJsonMethod;
|
||||
private static JsonParser _stringParser = new JsonParser();
|
||||
|
||||
static {
|
||||
ConfigurationSerialization.registerClass(FancyMessage.class);
|
||||
}
|
||||
|
||||
private List<MessagePart> messageParts;
|
||||
private String jsonString;
|
||||
private boolean dirty;
|
||||
|
||||
/**
|
||||
* Creates a JSON message with text.
|
||||
*
|
||||
* @param firstPartText The existing text in the message.
|
||||
*/
|
||||
public FancyMessage(final String firstPartText) {
|
||||
this(rawText(firstPartText));
|
||||
}
|
||||
|
||||
private FancyMessage(final TextualComponent firstPartText) {
|
||||
messageParts = new ArrayList<>();
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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<>(); // 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;
|
||||
}
|
||||
|
||||
@Override public FancyMessage clone() throws CloneNotSupportedException {
|
||||
FancyMessage instance = (FancyMessage) super.clone();
|
||||
instance.messageParts = new ArrayList<>(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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @throws 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.
|
||||
* @throws 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 occurred during 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.
|
||||
* @throws 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 occurred during 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.
|
||||
* @throws 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 occurred during 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.
|
||||
* @throws 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 occurred during 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(com.plotsquared.bukkit.chat.ArrayWrapper.toArray(lines, String.class));
|
||||
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;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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(
|
||||
com.plotsquared.bukkit.chat.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 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(
|
||||
com.plotsquared.bukkit.chat.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 occurred during 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);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
// Get the three parts of the version string (major version is currently unused)
|
||||
// vX_Y_RZ
|
||||
// X = major
|
||||
// Y = minor
|
||||
// Z = revision
|
||||
final String version = Reflection.getVersion();
|
||||
String[] split =
|
||||
version.substring(1, version.length() - 1).split("_"); // Remove trailing dot
|
||||
//int majorVersion = Integer.parseInt(split[0]);
|
||||
int minorVersion = Integer.parseInt(split[1]);
|
||||
int revisionVersion = Integer.parseInt(split[2].substring(1)); // Substring to ignore R
|
||||
|
||||
if (minorVersion < 8 || (minorVersion == 8 && revisionVersion == 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<>();
|
||||
map.put("messageParts", messageParts);
|
||||
// map.put("JSON", toJSONString());
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Internally called method. Not for API consumption.</b>
|
||||
*/
|
||||
public Iterator<MessagePart> iterator() {
|
||||
return messageParts.iterator();
|
||||
}
|
||||
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
package com.plotsquared.bukkit.chat;
|
||||
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
package com.plotsquared.bukkit.chat;
|
||||
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
|
||||
public static JsonString deserialize(Map<String, Object> map) {
|
||||
return new JsonString(map.get("stringValue").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;
|
||||
}
|
||||
|
||||
@Override public String toString() {
|
||||
return _value;
|
||||
}
|
||||
|
||||
}
|
@ -1,155 +0,0 @@
|
||||
package com.plotsquared.bukkit.chat;
|
||||
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.ImmutableBiMap;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerialization;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* Internal class: Represents a component of a JSON-serializable {@link FancyMessage}.
|
||||
*/
|
||||
final class MessagePart implements JsonRepresentedObject, ConfigurationSerializable, Cloneable {
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
static {
|
||||
ConfigurationSerialization.registerClass(MessagePart.class);
|
||||
}
|
||||
|
||||
ChatColor color = ChatColor.WHITE;
|
||||
ArrayList<ChatColor> styles = new ArrayList<>();
|
||||
String clickActionName = null;
|
||||
String clickActionData = null;
|
||||
String hoverActionName = null;
|
||||
JsonRepresentedObject hoverActionData = null;
|
||||
TextualComponent text = null;
|
||||
String insertionData = null;
|
||||
ArrayList<JsonRepresentedObject> translationReplacements = new ArrayList<>();
|
||||
|
||||
MessagePart(final TextualComponent text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
MessagePart() {
|
||||
this.text = null;
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
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<>();
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
@ -1,210 +0,0 @@
|
||||
package com.plotsquared.bukkit.chat;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
|
||||
/**
|
||||
* Stores loaded classes from the {@code net.minecraft.server} package.
|
||||
*/
|
||||
private static final Map<String, Class<?>> _loadedNMSClasses = new HashMap<>();
|
||||
/**
|
||||
* Stores loaded classes from the {@code org.bukkit.craftbukkit} package (and subpackages).
|
||||
*/
|
||||
private static final Map<String, Class<?>> _loadedOBCClasses = new HashMap<>();
|
||||
private static final Map<Class<?>, Map<String, Field>> _loadedFields = new HashMap<>();
|
||||
/**
|
||||
* 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<>();
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
try {
|
||||
clazz = Class.forName(fullName);
|
||||
} catch (ClassNotFoundException e) {
|
||||
_loadedNMSClasses.put(className, null);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
_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;
|
||||
try {
|
||||
clazz = Class.forName(fullName);
|
||||
} catch (ClassNotFoundException e) {
|
||||
_loadedOBCClasses.put(className, null);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
_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)
|
||||
throws InvocationTargetException, IllegalAccessException, IllegalArgumentException {
|
||||
return getMethod(obj.getClass(), "getHandle").invoke(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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<>();
|
||||
_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 (NoSuchFieldException | SecurityException e) {
|
||||
// Error loading
|
||||
e.printStackTrace();
|
||||
// Cache field as not existing
|
||||
loaded.put(name, null);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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>
|
||||
* 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>
|
||||
* 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<>(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;
|
||||
}
|
||||
|
||||
}
|
@ -1,313 +0,0 @@
|
||||
package com.plotsquared.bukkit.chat;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerialization;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
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 && component.getKey()
|
||||
.equals("translate");
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a textual component representing a string literal.
|
||||
* <p>
|
||||
* <p>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>
|
||||
* <p><b>This method is currently guaranteed to throw an {@code UnsupportedOperationException}
|
||||
* as it is only supported on snapshot clients.</b>
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
|
||||
@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;
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
|
||||
private String key;
|
||||
private String value;
|
||||
|
||||
public ArbitraryTextTypeComponent(String key, String value) {
|
||||
setKey(key);
|
||||
setValue(value);
|
||||
}
|
||||
|
||||
public static ArbitraryTextTypeComponent deserialize(Map<String, Object> map) {
|
||||
return new ArbitraryTextTypeComponent(map.get("key").toString(),
|
||||
map.get("value").toString());
|
||||
}
|
||||
|
||||
@Override public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
Preconditions
|
||||
.checkArgument(key != null && !key.isEmpty(), "The key must be specified.");
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
Preconditions.checkArgument(value != null, "The value must be specified.");
|
||||
this.value = 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());
|
||||
}
|
||||
|
||||
@Override @SuppressWarnings("serial") public Map<String, Object> serialize() {
|
||||
return new HashMap<String, Object>() {
|
||||
{
|
||||
put("key", getKey());
|
||||
put("value", getValue());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override public String getReadableString() {
|
||||
return getValue();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Internal class used to represent a text component with a nested JSON
|
||||
* value.
|
||||
* <p>
|
||||
* <p>Exception validating done is on keys and values.
|
||||
*/
|
||||
private static final class ComplexTextTypeComponent extends TextualComponent
|
||||
implements ConfigurationSerializable {
|
||||
|
||||
private String key;
|
||||
private Map<String, String> value;
|
||||
|
||||
public ComplexTextTypeComponent(String key, Map<String, String> values) {
|
||||
setKey(key);
|
||||
setValue(values);
|
||||
}
|
||||
|
||||
public static ComplexTextTypeComponent deserialize(Map<String, Object> map) {
|
||||
String key = null;
|
||||
Map<String, String> value = new HashMap<>();
|
||||
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(valEntry.getKey().substring(6) /* Strips out the value prefix */,
|
||||
valEntry.getValue().toString());
|
||||
}
|
||||
}
|
||||
return new ComplexTextTypeComponent(key, value);
|
||||
}
|
||||
|
||||
@Override public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
Preconditions
|
||||
.checkArgument(key != null && !key.isEmpty(), "The key must be specified.");
|
||||
this.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.");
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override public TextualComponent clone() {
|
||||
// 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();
|
||||
}
|
||||
|
||||
@Override @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());
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override public String getReadableString() {
|
||||
return getKey();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,295 +0,0 @@
|
||||
package com.plotsquared.bukkit.commands;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellectualcrafters.plot.PS;
|
||||
import com.intellectualcrafters.plot.commands.CommandCategory;
|
||||
import com.intellectualcrafters.plot.commands.RequiredType;
|
||||
import com.intellectualcrafters.plot.commands.SubCommand;
|
||||
import com.intellectualcrafters.plot.config.C;
|
||||
import com.intellectualcrafters.plot.database.DBFunc;
|
||||
import com.intellectualcrafters.plot.object.OfflinePlotPlayer;
|
||||
import com.intellectualcrafters.plot.object.Plot;
|
||||
import com.intellectualcrafters.plot.object.PlotPlayer;
|
||||
import com.intellectualcrafters.plot.object.StringWrapper;
|
||||
import com.intellectualcrafters.plot.util.*;
|
||||
import com.intellectualcrafters.plot.uuid.UUIDWrapper;
|
||||
import com.plotsquared.bukkit.uuid.DatFileFilter;
|
||||
import com.plotsquared.bukkit.uuid.DefaultUUIDWrapper;
|
||||
import com.plotsquared.bukkit.uuid.LowerOfflineUUIDWrapper;
|
||||
import com.plotsquared.bukkit.uuid.OfflineUUIDWrapper;
|
||||
import com.plotsquared.general.commands.Argument;
|
||||
import com.plotsquared.general.commands.CommandDeclaration;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
@CommandDeclaration(command = "uuidconvert", permission = "plots.admin", description = "Debug UUID conversion", usage = "/plot uuidconvert <lower|offline|online>", requiredType = RequiredType.CONSOLE, category = CommandCategory.DEBUG)
|
||||
public class DebugUUID extends SubCommand {
|
||||
|
||||
public DebugUUID() {
|
||||
super(Argument.String);
|
||||
}
|
||||
|
||||
@Override public boolean onCommand(final PlotPlayer player, String[] args) {
|
||||
final UUIDWrapper currentUUIDWrapper = UUIDHandler.getUUIDWrapper();
|
||||
final UUIDWrapper newWrapper;
|
||||
|
||||
switch (args[0].toLowerCase()) {
|
||||
case "lower":
|
||||
newWrapper = new LowerOfflineUUIDWrapper();
|
||||
break;
|
||||
case "offline":
|
||||
newWrapper = new OfflineUUIDWrapper();
|
||||
break;
|
||||
case "online":
|
||||
newWrapper = new DefaultUUIDWrapper();
|
||||
break;
|
||||
default:
|
||||
try {
|
||||
Class<?> clazz = Class.forName(args[0]);
|
||||
newWrapper = (UUIDWrapper) clazz.newInstance();
|
||||
} catch (ClassNotFoundException | IllegalAccessException | InstantiationException ignored) {
|
||||
MainUtil.sendMessage(player, C.COMMAND_SYNTAX,
|
||||
"/plot uuidconvert <lower|offline|online>");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (args.length != 2 || !"-o".equals(args[1])) {
|
||||
MainUtil.sendMessage(player, C.COMMAND_SYNTAX, "/plot uuidconvert " + args[0] + " - o");
|
||||
MainUtil.sendMessage(player, "&cBe aware of the following!");
|
||||
MainUtil.sendMessage(player,
|
||||
"&8 - &cUse the database command or another method to backup your plots beforehand");
|
||||
MainUtil.sendMessage(player,
|
||||
"&8 - &cIf the process is interrupted, all plots could be deleted");
|
||||
MainUtil.sendMessage(player, "&8 - &cIf an error occurs, all plots could be deleted");
|
||||
MainUtil.sendMessage(player, "&8 - &cPlot settings WILL be lost upon conversion");
|
||||
MainUtil
|
||||
.sendMessage(player, "&cTO REITERATE: BACK UP YOUR DATABASE BEFORE USING THIS!!!");
|
||||
MainUtil.sendMessage(player,
|
||||
"&7Retype the command with the override parameter when ready :)");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (currentUUIDWrapper.getClass().getCanonicalName()
|
||||
.equals(newWrapper.getClass().getCanonicalName())) {
|
||||
MainUtil.sendMessage(player, "&cUUID mode already in use!");
|
||||
return false;
|
||||
}
|
||||
MainUtil.sendMessage(player, "&6Beginning UUID mode conversion");
|
||||
MainUtil.sendMessage(player, "&7 - Disconnecting players");
|
||||
for (Entry<String, PlotPlayer> entry : UUIDHandler.getPlayers().entrySet()) {
|
||||
entry.getValue()
|
||||
.kick("UUID conversion has been initiated. You may reconnect when finished.");
|
||||
}
|
||||
|
||||
MainUtil.sendMessage(player, "&7 - Initializing map");
|
||||
|
||||
final HashMap<UUID, UUID> uCMap = new HashMap<>();
|
||||
final HashMap<UUID, UUID> uCReverse = new HashMap<>();
|
||||
|
||||
MainUtil.sendMessage(player, "&7 - Collecting playerdata");
|
||||
|
||||
HashSet<String> worlds = Sets.newHashSet(WorldUtil.IMP.getMainWorld(), "world");
|
||||
HashSet<UUID> uuids = new HashSet<>();
|
||||
HashSet<String> names = new HashSet<>();
|
||||
for (String worldName : worlds) {
|
||||
File playerDataFolder = new File(worldName + File.separator + "playerdata");
|
||||
String[] dat = playerDataFolder.list(new DatFileFilter());
|
||||
if (dat != null) {
|
||||
for (String current : dat) {
|
||||
String s = current.replaceAll(".dat$", "");
|
||||
try {
|
||||
UUID uuid = UUID.fromString(s);
|
||||
uuids.add(uuid);
|
||||
} catch (Exception ignored) {
|
||||
MainUtil.sendMessage(player, C.PREFIX + "Invalid playerdata: " + current);
|
||||
}
|
||||
}
|
||||
}
|
||||
File playersFolder = new File(worldName + File.separator + "players");
|
||||
dat = playersFolder.list(new DatFileFilter());
|
||||
if (dat != null) {
|
||||
for (String current : dat) {
|
||||
names.add(current.replaceAll(".dat$", ""));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MainUtil.sendMessage(player, "&7 - Populating map");
|
||||
UUID uuid2;
|
||||
UUIDWrapper wrapper = new DefaultUUIDWrapper();
|
||||
for (UUID uuid : uuids) {
|
||||
try {
|
||||
OfflinePlotPlayer op = wrapper.getOfflinePlayer(uuid);
|
||||
uuid = currentUUIDWrapper.getUUID(op);
|
||||
uuid2 = newWrapper.getUUID(op);
|
||||
if (!uuid.equals(uuid2) && !uCMap.containsKey(uuid) && !uCReverse
|
||||
.containsKey(uuid2)) {
|
||||
uCMap.put(uuid, uuid2);
|
||||
uCReverse.put(uuid2, uuid);
|
||||
}
|
||||
} catch (Throwable ignored) {
|
||||
MainUtil.sendMessage(player,
|
||||
C.PREFIX + "&6Invalid playerdata: " + uuid.toString() + ".dat");
|
||||
}
|
||||
}
|
||||
for (String name : names) {
|
||||
UUID uuid = currentUUIDWrapper.getUUID(name);
|
||||
uuid2 = newWrapper.getUUID(name);
|
||||
if (!uuid.equals(uuid2)) {
|
||||
uCMap.put(uuid, uuid2);
|
||||
uCReverse.put(uuid2, uuid);
|
||||
}
|
||||
}
|
||||
if (uCMap.isEmpty()) {
|
||||
MainUtil.sendMessage(player, "&c - Error! Attempting to repopulate");
|
||||
for (OfflinePlotPlayer op : currentUUIDWrapper.getOfflinePlayers()) {
|
||||
if (op.getLastPlayed() != 0) {
|
||||
// String name = op.getPluginName();
|
||||
// StringWrapper wrap = new StringWrapper(name);
|
||||
UUID uuid = currentUUIDWrapper.getUUID(op);
|
||||
uuid2 = newWrapper.getUUID(op);
|
||||
if (!uuid.equals(uuid2)) {
|
||||
uCMap.put(uuid, uuid2);
|
||||
uCReverse.put(uuid2, uuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (uCMap.isEmpty()) {
|
||||
MainUtil.sendMessage(player, "&cError. Failed to collect UUIDs!");
|
||||
return false;
|
||||
} else {
|
||||
MainUtil.sendMessage(player, "&a - Successfully repopulated");
|
||||
}
|
||||
}
|
||||
|
||||
MainUtil.sendMessage(player, "&7 - Replacing cache");
|
||||
TaskManager.runTaskAsync(new Runnable() {
|
||||
@Override public void run() {
|
||||
for (Entry<UUID, UUID> entry : uCMap.entrySet()) {
|
||||
String name = UUIDHandler.getName(entry.getKey());
|
||||
if (name != null) {
|
||||
UUIDHandler.add(new StringWrapper(name), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
MainUtil.sendMessage(player, "&7 - Scanning for applicable files (uuids.txt)");
|
||||
|
||||
File file = new File(PS.get().IMP.getDirectory(), "uuids.txt");
|
||||
if (file.exists()) {
|
||||
try {
|
||||
List<String> lines =
|
||||
Files.readAllLines(file.toPath(), StandardCharsets.UTF_8);
|
||||
for (String line : lines) {
|
||||
try {
|
||||
line = line.trim();
|
||||
if (line.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
line = line.replaceAll("[\\|][0-9]+[\\|][0-9]+[\\|]", "");
|
||||
String[] split = line.split("\\|");
|
||||
String name = split[0];
|
||||
if (name.isEmpty() || name.length() > 16 || !StringMan
|
||||
.isAlphanumericUnd(name)) {
|
||||
continue;
|
||||
}
|
||||
UUID old = currentUUIDWrapper.getUUID(name);
|
||||
if (old == null) {
|
||||
continue;
|
||||
}
|
||||
UUID now = newWrapper.getUUID(name);
|
||||
UUIDHandler.add(new StringWrapper(name), now);
|
||||
uCMap.put(old, now);
|
||||
uCReverse.put(now, old);
|
||||
} catch (Exception e2) {
|
||||
e2.printStackTrace();
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
MainUtil.sendMessage(player, "&7 - Replacing wrapper");
|
||||
UUIDHandler.setUUIDWrapper(newWrapper);
|
||||
|
||||
MainUtil.sendMessage(player, "&7 - Updating plot objects");
|
||||
|
||||
for (Plot plot : PS.get().getPlots()) {
|
||||
UUID value = uCMap.get(plot.owner);
|
||||
if (value != null) {
|
||||
plot.owner = value;
|
||||
}
|
||||
plot.getTrusted().clear();
|
||||
plot.getMembers().clear();
|
||||
plot.getDenied().clear();
|
||||
}
|
||||
|
||||
MainUtil.sendMessage(player, "&7 - Deleting database");
|
||||
boolean result = DBFunc.deleteTables();
|
||||
|
||||
MainUtil.sendMessage(player, "&7 - Creating tables");
|
||||
|
||||
try {
|
||||
DBFunc.createTables();
|
||||
if (!result) {
|
||||
MainUtil.sendMessage(player, "&cConversion failed! Attempting recovery");
|
||||
for (Plot plot : PS.get().getPlots()) {
|
||||
UUID value = uCReverse.get(plot.owner);
|
||||
if (value != null) {
|
||||
plot.owner = value;
|
||||
}
|
||||
}
|
||||
DBFunc.createPlotsAndData(new ArrayList<>(PS.get().getPlots()),
|
||||
new Runnable() {
|
||||
@Override public void run() {
|
||||
MainUtil.sendMessage(player, "&6Recovery was successful!");
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
if (newWrapper instanceof OfflineUUIDWrapper) {
|
||||
PS.get().worlds.set("UUID.force-lowercase", false);
|
||||
PS.get().worlds.set("UUID.offline", true);
|
||||
} else if (newWrapper instanceof DefaultUUIDWrapper) {
|
||||
PS.get().worlds.set("UUID.force-lowercase", false);
|
||||
PS.get().worlds.set("UUID.offline", false);
|
||||
}
|
||||
try {
|
||||
PS.get().worlds.save(PS.get().worldsFile);
|
||||
} catch (IOException ignored) {
|
||||
MainUtil.sendMessage(player,
|
||||
"Could not save configuration. It will need to be manual set!");
|
||||
}
|
||||
|
||||
MainUtil.sendMessage(player, "&7 - Populating tables");
|
||||
|
||||
TaskManager.runTaskAsync(new Runnable() {
|
||||
@Override public void run() {
|
||||
ArrayList<Plot> plots = new ArrayList<>(PS.get().getPlots());
|
||||
DBFunc.createPlotsAndData(plots, new Runnable() {
|
||||
@Override public void run() {
|
||||
MainUtil.sendMessage(player, "&aConversion complete!");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
MainUtil.sendMessage(player, "&aIt is now safe for players to join");
|
||||
MainUtil.sendMessage(player,
|
||||
"&cConversion is still in progress, you will be notified when it is complete");
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,87 +0,0 @@
|
||||
package com.plotsquared.bukkit.database.plotme;
|
||||
|
||||
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;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
|
||||
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 boolean isValidConnection(Connection connection) {
|
||||
return connection != null;
|
||||
}
|
||||
|
||||
public void copyConfig(FileConfiguration plotConfig, String world, String actualWorldName) {
|
||||
int pathWidth = plotConfig.getInt("worlds." + world + ".PathWidth"); //
|
||||
PS.get().worlds.set("worlds." + actualWorldName + ".road.width", pathWidth);
|
||||
int plotSize = plotConfig.getInt("worlds." + world + ".PlotSize"); //
|
||||
PS.get().worlds.set("worlds." + actualWorldName + ".plot.size", plotSize);
|
||||
String wallBlock = plotConfig.getString("worlds." + world + ".WallBlockId"); //
|
||||
PS.get().worlds.set("worlds." + actualWorldName + ".wall.block", wallBlock);
|
||||
String floor = plotConfig.getString("worlds." + world + ".PlotFloorBlockId"); //
|
||||
PS.get().worlds
|
||||
.set("worlds." + actualWorldName + ".plot.floor", Collections.singletonList(floor));
|
||||
String filling = plotConfig.getString("worlds." + world + ".PlotFillingBlockId"); //
|
||||
PS.get().worlds
|
||||
.set("worlds." + actualWorldName + ".plot.filling", Collections.singletonList(filling));
|
||||
String road = plotConfig.getString("worlds." + world + ".RoadMainBlockId");
|
||||
PS.get().worlds.set("worlds." + actualWorldName + ".road.block", road);
|
||||
int height = plotConfig.getInt("worlds." + world + ".RoadHeight"); //
|
||||
PS.get().worlds.set("worlds." + actualWorldName + ".road.height", height);
|
||||
PS.get().worlds.set("worlds." + actualWorldName + ".plot.height", height);
|
||||
PS.get().worlds.set("worlds." + actualWorldName + ".wall.height", height);
|
||||
}
|
||||
|
||||
public Location getPlotTopLocAbs(int path, int plot, PlotId plotId) {
|
||||
int px = plotId.x;
|
||||
int pz = plotId.y;
|
||||
int x = px * (path + plot) - (int) Math.floor(path / 2) - 1;
|
||||
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, PlotId plotId) {
|
||||
int px = plotId.x;
|
||||
int pz = plotId.y;
|
||||
int x = px * (path + plot) - plot - (int) Math.floor(path / 2) - 1;
|
||||
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 = new PlotId(id.x, id.y);
|
||||
boolean[] merge1;
|
||||
if (plots.containsKey(id)) {
|
||||
merge1 = plots.get(id);
|
||||
} else {
|
||||
merge1 = new boolean[] {false, false, false, false};
|
||||
}
|
||||
boolean[] merge2;
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
@ -1,237 +0,0 @@
|
||||
package com.plotsquared.bukkit.database.plotme;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
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.*;
|
||||
import com.intellectualcrafters.plot.util.UUIDHandler;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.sql.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ClassicPlotMeConnector extends APlotMeConnector {
|
||||
|
||||
private String plugin = "PlotMe";
|
||||
private String prefix;
|
||||
|
||||
@Override public Connection getPlotMeConnection(String plugin, FileConfiguration plotConfig,
|
||||
String dataFolder) {
|
||||
this.plugin = plugin.toLowerCase();
|
||||
this.prefix = plotConfig.getString("mySQLprefix", this.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 {
|
||||
return new SQLite(new File(dataFolder + File.separator + "plots.db"))
|
||||
.openConnection();
|
||||
}
|
||||
} catch (SQLException | ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override public HashMap<String, HashMap<PlotId, Plot>> getPlotMePlots(Connection connection)
|
||||
throws SQLException {
|
||||
HashMap<String, Integer> plotWidth = new HashMap<>();
|
||||
HashMap<String, Integer> roadWidth = new HashMap<>();
|
||||
HashMap<String, HashMap<PlotId, Plot>> plots = new HashMap<>();
|
||||
HashMap<String, HashMap<PlotId, boolean[]>> merges = new HashMap<>();
|
||||
PreparedStatement statement =
|
||||
connection.prepareStatement("SELECT * FROM `" + this.prefix + "Plots`");
|
||||
ResultSet resultSet = statement.executeQuery();
|
||||
String column = null;
|
||||
boolean checkUUID = DBFunc.hasColumn(resultSet, "ownerid");
|
||||
boolean checkUUID2 = DBFunc.hasColumn(resultSet, "ownerId");
|
||||
if (checkUUID) {
|
||||
column = "ownerid";
|
||||
} else if (checkUUID2) {
|
||||
column = "ownerId";
|
||||
}
|
||||
boolean merge =
|
||||
!"plotme".equalsIgnoreCase(this.plugin) && Settings.Enabled_Components.PLOTME_CONVERTER;
|
||||
int missing = 0;
|
||||
while (resultSet.next()) {
|
||||
PlotId id = new PlotId(resultSet.getInt("idX"), resultSet.getInt("idZ"));
|
||||
String name = resultSet.getString("owner");
|
||||
String world = LikePlotMeConverter.getWorld(resultSet.getString("world"));
|
||||
if (!plots.containsKey(world)) {
|
||||
plots.put(world, new HashMap<PlotId, Plot>());
|
||||
if (merge) {
|
||||
int plot = PS.get().worlds.getInt("worlds." + world + ".plot.size");
|
||||
int path = PS.get().worlds.getInt("worlds." + world + ".road.width");
|
||||
plotWidth.put(world, plot);
|
||||
roadWidth.put(world, path);
|
||||
merges.put(world, new HashMap<PlotId, boolean[]>());
|
||||
}
|
||||
}
|
||||
if (merge) {
|
||||
int tx = resultSet.getInt("topX");
|
||||
int tz = resultSet.getInt("topZ");
|
||||
int bx = resultSet.getInt("bottomX") - 1;
|
||||
int bz = resultSet.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, null);
|
||||
if (owner == null) {
|
||||
if ("*".equals(name)) {
|
||||
owner = DBFunc.everyone;
|
||||
} else {
|
||||
if (checkUUID || checkUUID2) {
|
||||
byte[] bytes = resultSet.getBytes(column);
|
||||
if (bytes != null) {
|
||||
ByteBuffer bb = ByteBuffer.wrap(bytes);
|
||||
long high = bb.getLong();
|
||||
long low = bb.getLong();
|
||||
owner = new UUID(high, low);
|
||||
UUIDHandler.add(new StringWrapper(name), owner);
|
||||
}
|
||||
}
|
||||
if (name.isEmpty()) {
|
||||
PS.log("&cCould not identify owner for plot: " + id + " -> '" + name + "'");
|
||||
missing++;
|
||||
continue;
|
||||
}
|
||||
owner = UUID.nameUUIDFromBytes(
|
||||
("OfflinePlayer:" + name.toLowerCase()).getBytes(Charsets.UTF_8));
|
||||
}
|
||||
} else {
|
||||
UUIDHandler.add(new StringWrapper(name), owner);
|
||||
}
|
||||
Plot plot = new Plot(PlotArea.createGeneric(world), id, owner);
|
||||
plots.get(world).put(id, plot);
|
||||
}
|
||||
if (missing > 0) {
|
||||
PS.log("&cSome names could not be identified:");
|
||||
PS.log("&7 - Empty quotes mean PlotMe just stored an unowned plot in the database");
|
||||
PS.log("&7 - Names you have never seen before could be from people mistyping commands");
|
||||
PS.log(
|
||||
"&7 - Converting from a non-uuid version of PlotMe can't identify owners if the playerdata files are deleted (these plots will "
|
||||
+ "remain unknown until the player connects)");
|
||||
}
|
||||
|
||||
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.setMerged(entry2.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resultSet.close();
|
||||
statement.close();
|
||||
|
||||
try {
|
||||
|
||||
PS.log(" - " + this.prefix + "Denied");
|
||||
statement = connection.prepareStatement("SELECT * FROM `" + this.prefix + "Denied`");
|
||||
resultSet = statement.executeQuery();
|
||||
|
||||
while (resultSet.next()) {
|
||||
PlotId id = new PlotId(resultSet.getInt("idX"), resultSet.getInt("idZ"));
|
||||
String name = resultSet.getString("player");
|
||||
String world = LikePlotMeConverter.getWorld(resultSet.getString("world"));
|
||||
UUID denied = UUIDHandler.getUUID(name, null);
|
||||
if (denied == null) {
|
||||
if ("*".equals(name)) {
|
||||
denied = DBFunc.everyone;
|
||||
} else if (DBFunc.hasColumn(resultSet, "playerid")) {
|
||||
byte[] bytes = resultSet.getBytes("playerid");
|
||||
if (bytes != null) {
|
||||
ByteBuffer bb = ByteBuffer.wrap(bytes);
|
||||
long mostSigBits = bb.getLong();
|
||||
long leastSigBits = bb.getLong();
|
||||
denied = new UUID(mostSigBits, leastSigBits);
|
||||
UUIDHandler.add(new StringWrapper(name), denied);
|
||||
}
|
||||
}
|
||||
if (denied == null) {
|
||||
PS.log("&6Could not identify denied for plot: " + id);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
HashMap<PlotId, Plot> worldMap = plots.get(world);
|
||||
if (worldMap != null) {
|
||||
Plot plot = worldMap.get(id);
|
||||
if (plot != null) {
|
||||
plot.getDenied().add(denied);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
statement = connection.prepareStatement("SELECT * FROM `" + this.plugin + "Allowed`");
|
||||
resultSet = statement.executeQuery();
|
||||
|
||||
while (resultSet.next()) {
|
||||
PlotId id = new PlotId(resultSet.getInt("idX"), resultSet.getInt("idZ"));
|
||||
String name = resultSet.getString("player");
|
||||
String world = LikePlotMeConverter.getWorld(resultSet.getString("world"));
|
||||
UUID helper = UUIDHandler.getUUID(name, null);
|
||||
if (helper == null) {
|
||||
if ("*".equals(name)) {
|
||||
helper = DBFunc.everyone;
|
||||
} else if (DBFunc.hasColumn(resultSet, "playerid")) {
|
||||
byte[] bytes = resultSet.getBytes("playerid");
|
||||
if (bytes != null) {
|
||||
ByteBuffer bb = ByteBuffer.wrap(bytes);
|
||||
long mostSigBits = bb.getLong();
|
||||
long leastSigBits = bb.getLong();
|
||||
helper = new UUID(mostSigBits, leastSigBits);
|
||||
UUIDHandler.add(new StringWrapper(name), helper);
|
||||
}
|
||||
}
|
||||
if (helper == null) {
|
||||
PS.log("&6Could not identify helper for plot: " + id);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
HashMap<PlotId, Plot> worldMap = plots.get(world);
|
||||
if (worldMap != null) {
|
||||
Plot plot = worldMap.get(id);
|
||||
if (plot != null) {
|
||||
plot.getTrusted().add(helper);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resultSet.close();
|
||||
statement.close();
|
||||
|
||||
} catch (SQLException ignored) {
|
||||
}
|
||||
return plots;
|
||||
}
|
||||
|
||||
@Override public boolean accepts(String version) {
|
||||
return version == null || PS.get().canUpdate(version, "0.17.0") || PS.get()
|
||||
.canUpdate("0.999.999", version);
|
||||
}
|
||||
}
|
@ -1,390 +0,0 @@
|
||||
package com.plotsquared.bukkit.database.plotme;
|
||||
|
||||
import com.intellectualcrafters.configuration.ConfigurationSection;
|
||||
import com.intellectualcrafters.configuration.MemorySection;
|
||||
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.intellectualcrafters.plot.object.Plot;
|
||||
import com.intellectualcrafters.plot.object.PlotArea;
|
||||
import com.intellectualcrafters.plot.object.PlotId;
|
||||
import com.intellectualcrafters.plot.util.TaskManager;
|
||||
import com.plotsquared.bukkit.generator.BukkitPlotGenerator;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.WorldCreator;
|
||||
import org.bukkit.command.CommandException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
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.sql.SQLException;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class LikePlotMeConverter {
|
||||
|
||||
private final String plugin;
|
||||
|
||||
public LikePlotMeConverter(String plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public static String getWorld(String world) {
|
||||
for (World newWorld : Bukkit.getWorlds()) {
|
||||
if (newWorld.getName().equalsIgnoreCase(world)) {
|
||||
return newWorld.getName();
|
||||
}
|
||||
}
|
||||
return world;
|
||||
}
|
||||
|
||||
private void sendMessage(String message) {
|
||||
PS.debug("&3PlotMe&8->&3" + PS.imp().getPluginName() + "&8: &7" + message);
|
||||
}
|
||||
|
||||
public String getPlotMePath() {
|
||||
return new File(".").getAbsolutePath() + File.separator + "plugins" + File.separator
|
||||
+ plugin + File.separator;
|
||||
}
|
||||
|
||||
public FileConfiguration getPlotMeConfig(String dataFolder) {
|
||||
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 mergeWorldYml(FileConfiguration plotConfig) {
|
||||
try {
|
||||
File genConfig = new File(
|
||||
"plugins" + File.separator + plugin + File.separator + "PlotMe-DefaultGenerator"
|
||||
+ File.separator + "config.yml");
|
||||
if (genConfig.exists()) {
|
||||
YamlConfiguration yml = YamlConfiguration.loadConfiguration(genConfig);
|
||||
for (String key : yml.getKeys(true)) {
|
||||
if (!plotConfig.contains(key)) {
|
||||
Object value = yml.get(key);
|
||||
if (!(value instanceof MemorySection)) {
|
||||
plotConfig.set(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void updateWorldYml(String location) {
|
||||
try {
|
||||
Path path = Paths.get(location);
|
||||
File file = new File(location);
|
||||
if (!file.exists()) {
|
||||
return;
|
||||
}
|
||||
String content = new String(Files.readAllBytes(path), StandardCharsets.UTF_8);
|
||||
String pluginName = PS.imp().getPluginName();
|
||||
content = content.replace("PlotMe-DefaultGenerator", pluginName);
|
||||
content = content.replace("PlotMe", pluginName);
|
||||
content = content.replace("AthionPlots", pluginName);
|
||||
content = content.replace("PlotZWorld", pluginName);
|
||||
Files.write(path, content.getBytes(StandardCharsets.UTF_8));
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
private void copyConfig(ConfigurationSection plotmeDgYml, String world) throws IOException {
|
||||
String actualWorldName = getWorld(world);
|
||||
String plotMeWorldName = world.toLowerCase();
|
||||
Integer pathWidth = plotmeDgYml.getInt("worlds." + plotMeWorldName + ".PathWidth"); //
|
||||
PS.get().worlds.set("worlds." + world + ".road.width", pathWidth);
|
||||
int height = plotmeDgYml.getInt("worlds." + plotMeWorldName + ".RoadHeight",
|
||||
plotmeDgYml.getInt("worlds." + plotMeWorldName + ".GroundHeight", 64)); //
|
||||
PS.get().worlds.set("worlds." + world + ".road.height", height);
|
||||
PS.get().worlds.set("worlds." + world + ".wall.height", height);
|
||||
PS.get().worlds.set("worlds." + world + ".plot.height", height);
|
||||
int plotSize = plotmeDgYml.getInt("worlds." + plotMeWorldName + ".PlotSize", 32); //
|
||||
PS.get().worlds.set("worlds." + world + ".plot.size", plotSize);
|
||||
String wallblock = plotmeDgYml.getString("worlds." + plotMeWorldName + ".UnclaimedBorder",
|
||||
plotmeDgYml.getString("worlds." + plotMeWorldName + ".WallBlock", "44")); //
|
||||
PS.get().worlds.set("worlds." + world + ".wall.block", wallblock);
|
||||
String claimed =
|
||||
plotmeDgYml.getString("worlds." + plotMeWorldName + ".ProtectedWallBlock", "44:1"); //
|
||||
PS.get().worlds.set("worlds." + world + ".wall.block_claimed", claimed);
|
||||
String floor =
|
||||
plotmeDgYml.getString("worlds." + plotMeWorldName + ".PlotFloorBlock", "2"); //
|
||||
PS.get().worlds.set("worlds." + world + ".plot.floor", Collections.singletonList(floor));
|
||||
String filling = plotmeDgYml.getString("worlds." + plotMeWorldName + ".FillBlock", "3"); //
|
||||
PS.get().worlds
|
||||
.set("worlds." + world + ".plot.filling", Collections.singletonList(filling));
|
||||
String road = plotmeDgYml.getString("worlds." + plotMeWorldName + ".RoadMainBlock", "5");
|
||||
PS.get().worlds.set("worlds." + world + ".road.block", road);
|
||||
PS.get().worlds.set("worlds." + actualWorldName + ".road.height", height);
|
||||
PS.get().worlds.set("worlds." + actualWorldName + ".plot.height", height);
|
||||
PS.get().worlds.set("worlds." + actualWorldName + ".wall.height", height);
|
||||
PS.get().worlds.save(PS.get().worldsFile);
|
||||
}
|
||||
|
||||
public boolean run(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.debug("&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(
|
||||
"PlotMe conversion has started. To disable this, please set 'enabled-components -> plotme-converter' to false in the 'settings.yml'");
|
||||
|
||||
mergeWorldYml(plotConfig);
|
||||
|
||||
sendMessage("Connecting to PlotMe DB");
|
||||
|
||||
ArrayList<Plot> createdPlots = new ArrayList<>();
|
||||
|
||||
sendMessage("Collecting plot data");
|
||||
|
||||
String dbPrefix = "PlotMe".toLowerCase();
|
||||
sendMessage(" - " + dbPrefix + "Plots");
|
||||
final Set<String> worlds = getPlotMeWorlds(plotConfig);
|
||||
|
||||
if (Settings.Enabled_Components.PLOTME_CONVERTER) {
|
||||
sendMessage("Updating bukkit.yml");
|
||||
updateWorldYml("bukkit.yml");
|
||||
updateWorldYml("plugins/Multiverse-Core/worlds.yml");
|
||||
for (String world : plotConfig.getConfigurationSection("worlds").getKeys(false)) {
|
||||
sendMessage("Copying config for: " + world);
|
||||
try {
|
||||
String actualWorldName = getWorld(world);
|
||||
connector.copyConfig(plotConfig, world, actualWorldName);
|
||||
PS.get().worlds.save(PS.get().worldsFile);
|
||||
} catch (IOException 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);
|
||||
int plotCount = 0;
|
||||
for (Entry<String, HashMap<PlotId, Plot>> entry : plots.entrySet()) {
|
||||
plotCount += entry.getValue().size();
|
||||
}
|
||||
if (!Settings.Enabled_Components.PLOTME_CONVERTER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
sendMessage(" - " + dbPrefix + "Allowed");
|
||||
|
||||
sendMessage("Collected " + plotCount + " plots from PlotMe");
|
||||
File plotmeDgFile = new File(
|
||||
dataFolder + File.separator + "PlotMe-DefaultGenerator" + File.separator
|
||||
+ "config.yml");
|
||||
if (plotmeDgFile.exists()) {
|
||||
YamlConfiguration plotmeDgYml = YamlConfiguration.loadConfiguration(plotmeDgFile);
|
||||
try {
|
||||
HashSet<String> allWorlds = new HashSet<>(plots.keySet());
|
||||
allWorlds.addAll(worlds);
|
||||
for (String world : allWorlds) {
|
||||
copyConfig(plotmeDgYml, world);
|
||||
}
|
||||
} catch (IOException ignored) {
|
||||
ignored.printStackTrace();
|
||||
}
|
||||
}
|
||||
for (Entry<String, HashMap<PlotId, Plot>> entry : plots.entrySet()) {
|
||||
String world = entry.getKey();
|
||||
PlotArea area = PS.get().getPlotArea(world, null);
|
||||
int duplicate = 0;
|
||||
if (area != null) {
|
||||
for (Entry<PlotId, Plot> entry2 : entry.getValue().entrySet()) {
|
||||
if (area.getOwnedPlotAbs(entry2.getKey()) != null) {
|
||||
duplicate++;
|
||||
} else {
|
||||
createdPlots.add(entry2.getValue());
|
||||
}
|
||||
}
|
||||
if (duplicate > 0) {
|
||||
PS.debug("&c[WARNING] Found " + duplicate
|
||||
+ " duplicate plots already in DB for world: '" + world
|
||||
+ "'. Have you run the converter already?");
|
||||
}
|
||||
} else {
|
||||
if (PS.get().plots_tmp != null) {
|
||||
HashMap<PlotId, Plot> map = PS.get().plots_tmp.get(world);
|
||||
if (map != null) {
|
||||
for (Entry<PlotId, Plot> entry2 : entry.getValue().entrySet()) {
|
||||
if (map.containsKey(entry2.getKey())) {
|
||||
duplicate++;
|
||||
} else {
|
||||
createdPlots.add(entry2.getValue());
|
||||
}
|
||||
}
|
||||
if (duplicate > 0) {
|
||||
PS.debug("&c[WARNING] Found " + duplicate
|
||||
+ " duplicate plots already in DB for world: '" + world
|
||||
+ "'. Have you run the converter already?");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
createdPlots.addAll(entry.getValue().values());
|
||||
}
|
||||
}
|
||||
sendMessage("Creating plot DB");
|
||||
Thread.sleep(1000);
|
||||
final AtomicBoolean done = new AtomicBoolean(false);
|
||||
DBFunc.createPlotsAndData(createdPlots, new Runnable() {
|
||||
@Override public void run() {
|
||||
if (done.get()) {
|
||||
done();
|
||||
sendMessage("&aDatabase conversion is now complete!");
|
||||
PS.debug("&c - Stop the server");
|
||||
PS.debug(
|
||||
"&c - Disable 'plotme-converter' and 'plotme-convert.cache-uuids' in the settings.yml");
|
||||
PS.debug(
|
||||
"&c - Correct any generator settings that haven't copied to 'settings.yml' properly");
|
||||
PS.debug("&c - Start the server");
|
||||
PS.get().setPlots(DBFunc.getPlots());
|
||||
} else {
|
||||
sendMessage(
|
||||
"&cPlease wait until database conversion is complete. You will be notified with instructions when this happens!");
|
||||
done.set(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
sendMessage("Saving configuration...");
|
||||
try {
|
||||
PS.get().worlds.save(PS.get().worldsFile);
|
||||
} catch (IOException ignored) {
|
||||
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 (String worldName : worlds) {
|
||||
World world = Bukkit.getWorld(getWorld(worldName));
|
||||
if (world == null) {
|
||||
sendMessage(
|
||||
"&cInvalid world in PlotMe configuration: " + worldName);
|
||||
continue;
|
||||
}
|
||||
String actualWorldName = world.getName();
|
||||
sendMessage(
|
||||
"Reloading generator for world: '" + actualWorldName + "'...");
|
||||
if (!Bukkit.getWorlds().isEmpty() && Bukkit.getWorlds().get(0).getName()
|
||||
.equals(worldName)) {
|
||||
sendMessage(
|
||||
"&cYou need to stop the server to reload this world properly");
|
||||
} else {
|
||||
PS.get().removePlotAreas(actualWorldName);
|
||||
if (mv) {
|
||||
// unload world with MV
|
||||
Bukkit.getServer()
|
||||
.dispatchCommand(Bukkit.getServer().getConsoleSender(),
|
||||
"mv unload " + actualWorldName);
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException ignored) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
// load world with MV
|
||||
Bukkit.getServer()
|
||||
.dispatchCommand(Bukkit.getServer().getConsoleSender(),
|
||||
"mv import " + actualWorldName + " normal -g " + PS
|
||||
.imp().getPluginName());
|
||||
} else if (mw) {
|
||||
// unload world with MW
|
||||
Bukkit.getServer()
|
||||
.dispatchCommand(Bukkit.getServer().getConsoleSender(),
|
||||
"mw unload " + actualWorldName);
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException ignored) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
// load world with MW
|
||||
Bukkit.getServer()
|
||||
.dispatchCommand(Bukkit.getServer().getConsoleSender(),
|
||||
"mw create " + actualWorldName + " plugin:" + PS.imp()
|
||||
.getPluginName());
|
||||
} else {
|
||||
// Load using Bukkit API
|
||||
// - User must set generator manually
|
||||
Bukkit.getServer().unloadWorld(world, true);
|
||||
World myWorld = WorldCreator.name(actualWorldName).generator(
|
||||
new BukkitPlotGenerator(PS.get().IMP.getDefaultGenerator()))
|
||||
.createWorld();
|
||||
myWorld.save();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (CommandException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (done.get()) {
|
||||
done();
|
||||
sendMessage("&aDatabase conversion is now complete!");
|
||||
PS.debug("&c - Stop the server");
|
||||
PS.debug(
|
||||
"&c - Disable 'plotme-converter' and 'plotme-convert.cache-uuids' in the settings.yml");
|
||||
PS.debug(
|
||||
"&c - Correct any generator settings that haven't copied to 'settings.yml' properly");
|
||||
PS.debug("&c - Start the server");
|
||||
} else {
|
||||
sendMessage(
|
||||
"&cPlease wait until database conversion is complete. You will be notified with instructions when this happens!");
|
||||
done.set(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (InterruptedException | SQLException e) {
|
||||
e.printStackTrace();
|
||||
PS.debug("&/end/");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void done() {
|
||||
PS.get().setPlots(DBFunc.getPlots());
|
||||
}
|
||||
}
|
@ -1,194 +0,0 @@
|
||||
package com.plotsquared.bukkit.database.plotme;
|
||||
|
||||
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.*;
|
||||
import com.intellectualcrafters.plot.util.UUIDHandler;
|
||||
|
||||
import java.io.File;
|
||||
import java.sql.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.UUID;
|
||||
|
||||
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(file).openConnection();
|
||||
}
|
||||
return new SQLite(new File(dataFolder + File.separator + "plots.db"))
|
||||
.openConnection();
|
||||
}
|
||||
} catch (SQLException | ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override public HashMap<String, HashMap<PlotId, Plot>> getPlotMePlots(Connection connection)
|
||||
throws SQLException {
|
||||
ResultSet resultSet;
|
||||
PreparedStatement statement;
|
||||
HashMap<String, Integer> plotWidth = new HashMap<>();
|
||||
HashMap<String, Integer> roadWidth = new HashMap<>();
|
||||
HashMap<Integer, Plot> plots = new HashMap<>();
|
||||
HashMap<String, HashMap<PlotId, boolean[]>> merges = new HashMap<>();
|
||||
try {
|
||||
statement =
|
||||
connection.prepareStatement("SELECT * FROM `" + this.plugin + "core_plots`");
|
||||
resultSet = statement.executeQuery();
|
||||
} catch (SQLException e) {
|
||||
PS.debug("========= Table does not exist =========");
|
||||
e.printStackTrace();
|
||||
PS.debug("=======================================");
|
||||
PS.debug(
|
||||
"&8 - &7The database does not match the version specified in the PlotMe config");
|
||||
PS.debug("&8 - &7Please correct this, or if you are unsure, the most common is 0.16.3");
|
||||
return null;
|
||||
}
|
||||
boolean checkUUID = DBFunc.hasColumn(resultSet, "ownerID");
|
||||
boolean merge =
|
||||
!"plotme".equals(this.plugin) && Settings.Enabled_Components.PLOTME_CONVERTER;
|
||||
while (resultSet.next()) {
|
||||
int key = resultSet.getInt("plot_id");
|
||||
PlotId id = new PlotId(resultSet.getInt("plotX"), resultSet.getInt("plotZ"));
|
||||
String name = resultSet.getString("owner");
|
||||
String world = LikePlotMeConverter.getWorld(resultSet.getString("world"));
|
||||
if (!plots.containsKey(world) && merge) {
|
||||
int plot = PS.get().worlds.getInt("worlds." + world + ".plot.size");
|
||||
int path = PS.get().worlds.getInt("worlds." + world + ".road.width");
|
||||
plotWidth.put(world, plot);
|
||||
roadWidth.put(world, path);
|
||||
merges.put(world, new HashMap<PlotId, boolean[]>());
|
||||
}
|
||||
if (merge) {
|
||||
int tx = resultSet.getInt("topX");
|
||||
int tz = resultSet.getInt("topZ");
|
||||
int bx = resultSet.getInt("bottomX") - 1;
|
||||
int bz = resultSet.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, null);
|
||||
if (owner == null) {
|
||||
if (name.equals("*")) {
|
||||
owner = DBFunc.everyone;
|
||||
} else {
|
||||
if (checkUUID) {
|
||||
byte[] bytes = resultSet.getBytes("ownerid");
|
||||
if (bytes != null) {
|
||||
owner = UUID.nameUUIDFromBytes(bytes);
|
||||
UUIDHandler.add(new StringWrapper(name), owner);
|
||||
}
|
||||
}
|
||||
if (owner == null) {
|
||||
PS.log(
|
||||
"&cCould not identify owner for plot: " + id + " -> '" + name + '\'');
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
UUIDHandler.add(new StringWrapper(name), owner);
|
||||
}
|
||||
Plot plot = new Plot(PlotArea.createGeneric(world), id, owner);
|
||||
plots.put(key, plot);
|
||||
}
|
||||
for (Plot plot : plots.values()) {
|
||||
HashMap<PlotId, boolean[]> mergeMap = merges.get(plot.getWorldName());
|
||||
if (mergeMap != null) {
|
||||
if (mergeMap.containsKey(plot.getId())) {
|
||||
plot.setMerged(mergeMap.get(plot.getId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
resultSet.close();
|
||||
statement.close();
|
||||
try {
|
||||
PS.log(" - " + this.plugin + "core_denied");
|
||||
statement =
|
||||
connection.prepareStatement("SELECT * FROM `" + this.plugin + "core_denied`");
|
||||
resultSet = statement.executeQuery();
|
||||
|
||||
while (resultSet.next()) {
|
||||
int key = resultSet.getInt("plot_id");
|
||||
Plot plot = plots.get(key);
|
||||
if (plot == null) {
|
||||
PS.log("&6Denied (" + key + ") references deleted plot; ignoring entry.");
|
||||
continue;
|
||||
}
|
||||
String player = resultSet.getString("player");
|
||||
UUID denied = player.equals("*") ? DBFunc.everyone : UUID.fromString(player);
|
||||
plot.getDenied().add(denied);
|
||||
}
|
||||
|
||||
PS.log(" - " + this.plugin + "core_allowed");
|
||||
statement =
|
||||
connection.prepareStatement("SELECT * FROM `" + this.plugin + "core_allowed`");
|
||||
resultSet = statement.executeQuery();
|
||||
|
||||
while (resultSet.next()) {
|
||||
int key = resultSet.getInt("plot_id");
|
||||
Plot plot = plots.get(key);
|
||||
if (plot == null) {
|
||||
PS.log("&6Allowed (" + key + ") references deleted plot; ignoring entry.");
|
||||
continue;
|
||||
}
|
||||
String player = resultSet.getString("player");
|
||||
UUID allowed = player.equals("*") ? DBFunc.everyone : UUID.fromString(player);
|
||||
plot.getTrusted().add(allowed);
|
||||
}
|
||||
resultSet.close();
|
||||
statement.close();
|
||||
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
HashMap<String, HashMap<PlotId, Plot>> processed = new HashMap<>();
|
||||
|
||||
for (Plot plot : plots.values()) {
|
||||
HashMap<PlotId, Plot> map = processed.get(plot.getWorldName());
|
||||
if (map == null) {
|
||||
map = new HashMap<>();
|
||||
processed.put(plot.getWorldName(), map);
|
||||
}
|
||||
map.put(plot.getId(), plot);
|
||||
}
|
||||
return processed;
|
||||
}
|
||||
|
||||
@Override public boolean accepts(String version) {
|
||||
if (version == null) {
|
||||
return false;
|
||||
}
|
||||
return !PS.get().canUpdate(version, "0.17");
|
||||
}
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
package com.plotsquared.bukkit.events;
|
||||
|
||||
import com.intellectualcrafters.plot.flag.Flag;
|
||||
import com.intellectualcrafters.plot.object.PlotCluster;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
/**
|
||||
* Called when a flag is removed from a plot.
|
||||
*/
|
||||
public class ClusterFlagRemoveEvent extends Event implements Cancellable {
|
||||
|
||||
private static final 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 cluster PlotCluster from which the flag was removed
|
||||
*/
|
||||
public ClusterFlagRemoveEvent(Flag flag, 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(boolean b) {
|
||||
this.cancelled = b;
|
||||
}
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
package com.plotsquared.bukkit.events;
|
||||
|
||||
import com.intellectualcrafters.plot.object.Plot;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.player.PlayerEvent;
|
||||
|
||||
public class PlayerClaimPlotEvent extends PlayerEvent implements Cancellable {
|
||||
|
||||
private static final 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(Player player, Plot plot, 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(boolean b) {
|
||||
this.cancelled = b;
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
package com.plotsquared.bukkit.events;
|
||||
|
||||
import com.intellectualcrafters.plot.object.Plot;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.player.PlayerEvent;
|
||||
|
||||
public class PlayerEnterPlotEvent extends PlayerEvent {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private final Plot plot;
|
||||
|
||||
/**
|
||||
* Called when a player leaves a plot.
|
||||
*
|
||||
* @param player Player that entered the plot
|
||||
* @param plot Plot that was entered
|
||||
*/
|
||||
public PlayerEnterPlotEvent(Player player, 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;
|
||||
}
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
package com.plotsquared.bukkit.events;
|
||||
|
||||
import com.intellectualcrafters.plot.object.Plot;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.player.PlayerEvent;
|
||||
|
||||
/**
|
||||
|
||||
|
||||
*/
|
||||
public class PlayerLeavePlotEvent extends PlayerEvent {
|
||||
|
||||
private static final 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(Player player, 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;
|
||||
}
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
package com.plotsquared.bukkit.events;
|
||||
|
||||
import com.intellectualcrafters.plot.object.Plot;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class PlayerPlotDeniedEvent extends PlotEvent {
|
||||
|
||||
private static final 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(Player initiator, Plot plot, UUID player, 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;
|
||||
}
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
package com.plotsquared.bukkit.events;
|
||||
|
||||
import com.intellectualcrafters.plot.object.Plot;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
|
||||
|
||||
*/
|
||||
public class PlayerPlotHelperEvent extends PlotEvent {
|
||||
|
||||
private static final 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(Player initiator, Plot plot, UUID player, 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;
|
||||
}
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
package com.plotsquared.bukkit.events;
|
||||
|
||||
import com.intellectualcrafters.plot.object.Plot;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
|
||||
|
||||
*/
|
||||
public class PlayerPlotTrustedEvent extends PlotEvent {
|
||||
|
||||
private static final 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(Player initiator, Plot plot, UUID player, 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;
|
||||
}
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
package com.plotsquared.bukkit.events;
|
||||
|
||||
import com.intellectualcrafters.plot.object.Location;
|
||||
import com.intellectualcrafters.plot.object.Plot;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.player.PlayerEvent;
|
||||
|
||||
/**
|
||||
* Called when a player teleports to a plot
|
||||
*/
|
||||
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(Player player, Location from, 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(boolean cancelled) {
|
||||
this.cancelled = cancelled;
|
||||
}
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
package com.plotsquared.bukkit.events;
|
||||
|
||||
import com.intellectualcrafters.plot.object.Plot;
|
||||
import com.intellectualcrafters.plot.object.PlotId;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
/**
|
||||
* Called when a plot is cleared
|
||||
*/
|
||||
public class PlotClearEvent extends PlotEvent implements Cancellable {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private boolean cancelled;
|
||||
|
||||
public PlotClearEvent(Plot plot) {
|
||||
super(plot);
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the PlotId.
|
||||
*
|
||||
* @return PlotId
|
||||
*/
|
||||
public PlotId getPlotId() {
|
||||
return getPlot().getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the world name.
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public String getWorld() {
|
||||
return getPlot().getWorldName();
|
||||
}
|
||||
|
||||
@Override public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
@Override public boolean isCancelled() {
|
||||
return this.cancelled;
|
||||
}
|
||||
|
||||
@Override public void setCancelled(boolean b) {
|
||||
this.cancelled = b;
|
||||
}
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
package com.plotsquared.bukkit.events;
|
||||
|
||||
import com.intellectualcrafters.plot.object.Plot;
|
||||
import com.intellectualcrafters.plot.object.PlotId;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
/**
|
||||
* Called when a plot component is set
|
||||
*/
|
||||
public class PlotComponentSetEvent extends PlotEvent {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private final String component;
|
||||
|
||||
public PlotComponentSetEvent(Plot plot, String component) {
|
||||
super(plot);
|
||||
this.component = component;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the PlotId
|
||||
*
|
||||
* @return PlotId
|
||||
*/
|
||||
public PlotId getPlotId() {
|
||||
return getPlot().getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the world name
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public String getWorld() {
|
||||
return getPlot().getWorldName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the component which was set
|
||||
*
|
||||
* @return Component name
|
||||
*/
|
||||
public String getComponent() {
|
||||
return this.component;
|
||||
}
|
||||
|
||||
@Override public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
package com.plotsquared.bukkit.events;
|
||||
|
||||
import com.intellectualcrafters.plot.object.Plot;
|
||||
import com.intellectualcrafters.plot.object.PlotId;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
/**
|
||||
* Called when a plot is deleted
|
||||
*/
|
||||
public class PlotDeleteEvent extends PlotEvent {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
public PlotDeleteEvent(Plot plot) {
|
||||
super(plot);
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the PlotId
|
||||
*
|
||||
* @return PlotId
|
||||
*/
|
||||
public PlotId getPlotId() {
|
||||
return getPlot().getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the world name
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public String getWorld() {
|
||||
return getPlot().getWorldName();
|
||||
}
|
||||
|
||||
@Override public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
package com.plotsquared.bukkit.events;
|
||||
|
||||
import com.intellectualcrafters.plot.object.Plot;
|
||||
import org.bukkit.event.Event;
|
||||
|
||||
public abstract class PlotEvent extends Event {
|
||||
|
||||
private final Plot plot;
|
||||
|
||||
public PlotEvent(Plot plot) {
|
||||
this.plot = plot;
|
||||
}
|
||||
|
||||
public final Plot getPlot() {
|
||||
return this.plot;
|
||||
}
|
||||
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
package com.plotsquared.bukkit.events;
|
||||
|
||||
import com.intellectualcrafters.plot.flag.Flag;
|
||||
import com.intellectualcrafters.plot.object.Plot;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
/**
|
||||
* Called when a Flag is added to a plot.
|
||||
*/
|
||||
public class PlotFlagAddEvent extends PlotEvent implements Cancellable {
|
||||
|
||||
private static final 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(Flag flag, 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;
|
||||
}
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
package com.plotsquared.bukkit.events;
|
||||
|
||||
import com.intellectualcrafters.plot.flag.Flag;
|
||||
import com.intellectualcrafters.plot.object.Plot;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
/**
|
||||
* Called when a flag is removed from a plot
|
||||
*/
|
||||
public class PlotFlagRemoveEvent extends PlotEvent implements Cancellable {
|
||||
|
||||
private static final 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(Flag flag, 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;
|
||||
}
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
package com.plotsquared.bukkit.events;
|
||||
|
||||
import com.intellectualcrafters.plot.object.Plot;
|
||||
import com.intellectualcrafters.plot.object.PlotId;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class PlotMergeEvent extends PlotEvent implements Cancellable {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private final ArrayList<PlotId> plots;
|
||||
private final World world;
|
||||
private boolean cancelled;
|
||||
|
||||
/**
|
||||
* 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(World world, Plot plot, ArrayList<PlotId> plots) {
|
||||
super(plot);
|
||||
this.world = world;
|
||||
this.plots = plots;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plots being added.
|
||||
*
|
||||
* @return Plot
|
||||
*/
|
||||
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(boolean b) {
|
||||
this.cancelled = b;
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
package com.plotsquared.bukkit.events;
|
||||
|
||||
import com.intellectualcrafters.plot.object.Plot;
|
||||
import com.intellectualcrafters.plot.object.PlotPlayer;
|
||||
import com.intellectualcrafters.plot.object.Rating;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
public class PlotRateEvent extends PlotEvent {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private final PlotPlayer rater;
|
||||
private Rating rating;
|
||||
|
||||
public PlotRateEvent(PlotPlayer rater, Rating rating, Plot plot) {
|
||||
super(plot);
|
||||
this.rater = rater;
|
||||
this.rating = rating;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
public PlotPlayer getRater() {
|
||||
return this.rater;
|
||||
}
|
||||
|
||||
public Rating getRating() {
|
||||
return this.rating;
|
||||
}
|
||||
|
||||
public void setRating(Rating rating) {
|
||||
this.rating = rating;
|
||||
}
|
||||
|
||||
@Override public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
package com.plotsquared.bukkit.events;
|
||||
|
||||
import com.intellectualcrafters.plot.object.PlotArea;
|
||||
import com.intellectualcrafters.plot.object.PlotId;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class PlotUnlinkEvent extends Event implements Cancellable {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private final ArrayList<PlotId> plots;
|
||||
private final World world;
|
||||
private final PlotArea area;
|
||||
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(World world, PlotArea area, ArrayList<PlotId> plots) {
|
||||
this.plots = plots;
|
||||
this.world = world;
|
||||
this.area = area;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plots involved.
|
||||
*
|
||||
* @return The {@link PlotId}'s of the plots involved
|
||||
*/
|
||||
public ArrayList<PlotId> getPlots() {
|
||||
return this.plots;
|
||||
}
|
||||
|
||||
public World getWorld() {
|
||||
return this.world;
|
||||
}
|
||||
|
||||
public PlotArea getArea() {
|
||||
return this.area;
|
||||
}
|
||||
|
||||
@Override public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
@Override public boolean isCancelled() {
|
||||
return this.cancelled;
|
||||
}
|
||||
|
||||
@Override public void setCancelled(boolean b) {
|
||||
this.cancelled = b;
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
package com.plotsquared.bukkit.generator;
|
||||
|
||||
import com.intellectualcrafters.plot.generator.AugmentedUtils;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.generator.BlockPopulator;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class BukkitAugmentedGenerator extends BlockPopulator {
|
||||
|
||||
private static BukkitAugmentedGenerator generator;
|
||||
|
||||
public static BukkitAugmentedGenerator get(World world) {
|
||||
for (BlockPopulator populator : world.getPopulators()) {
|
||||
if (populator instanceof BukkitAugmentedGenerator) {
|
||||
return (BukkitAugmentedGenerator) populator;
|
||||
}
|
||||
}
|
||||
if (generator == null) {
|
||||
generator = new BukkitAugmentedGenerator();
|
||||
}
|
||||
world.getPopulators().add(generator);
|
||||
return generator;
|
||||
}
|
||||
|
||||
@Override public void populate(World world, Random r, Chunk chunk) {
|
||||
AugmentedUtils.generate(world.getName(), chunk.getX(), chunk.getZ(), null);
|
||||
}
|
||||
}
|
@ -1,358 +0,0 @@
|
||||
package com.plotsquared.bukkit.generator;
|
||||
|
||||
import com.intellectualcrafters.plot.PS;
|
||||
import com.intellectualcrafters.plot.generator.GeneratorWrapper;
|
||||
import com.intellectualcrafters.plot.generator.IndependentPlotGenerator;
|
||||
import com.intellectualcrafters.plot.object.*;
|
||||
import com.intellectualcrafters.plot.object.worlds.SingleWorldGenerator;
|
||||
import com.intellectualcrafters.plot.util.ChunkManager;
|
||||
import com.intellectualcrafters.plot.util.MainUtil;
|
||||
import com.intellectualcrafters.plot.util.MathMan;
|
||||
import com.intellectualcrafters.plot.util.block.GlobalBlockQueue;
|
||||
import com.intellectualcrafters.plot.util.block.LocalBlockQueue;
|
||||
import com.intellectualcrafters.plot.util.block.ScopedLocalBlockQueue;
|
||||
import com.plotsquared.bukkit.util.BukkitUtil;
|
||||
import com.plotsquared.bukkit.util.block.GenChunk;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.generator.BlockPopulator;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class BukkitPlotGenerator extends ChunkGenerator
|
||||
implements GeneratorWrapper<ChunkGenerator> {
|
||||
|
||||
private final GenChunk chunkSetter;
|
||||
private final PseudoRandom random = new PseudoRandom();
|
||||
private final IndependentPlotGenerator plotGenerator;
|
||||
private final ChunkGenerator platformGenerator;
|
||||
private final boolean full;
|
||||
private final HashMap<ChunkLoc, byte[][]> dataMap = new HashMap<>();
|
||||
private List<BlockPopulator> populators;
|
||||
private boolean loaded = false;
|
||||
|
||||
public BukkitPlotGenerator(IndependentPlotGenerator generator) {
|
||||
if (generator == null) {
|
||||
throw new IllegalArgumentException("Generator may not be null!");
|
||||
}
|
||||
this.plotGenerator = generator;
|
||||
this.platformGenerator = this;
|
||||
populators = new ArrayList<>();
|
||||
this.populators.add(new BlockPopulator() {
|
||||
|
||||
private LocalBlockQueue queue;
|
||||
|
||||
@Override public void populate(World world, Random r, Chunk c) {
|
||||
if (queue == null) {
|
||||
queue = GlobalBlockQueue.IMP.getNewQueue(world.getName(), false);
|
||||
}
|
||||
byte[][] resultData =
|
||||
dataMap.isEmpty() ? null : dataMap.remove(new ChunkLoc(c.getX(), c.getZ()));
|
||||
if (resultData == null) {
|
||||
GenChunk result = BukkitPlotGenerator.this.chunkSetter;
|
||||
// Set the chunk location
|
||||
result.setChunk(c);
|
||||
// Set the result data
|
||||
result.result = new short[16][];
|
||||
result.result_data = new byte[16][];
|
||||
result.grid = null;
|
||||
result.cd = null;
|
||||
// Catch any exceptions (as exceptions usually thrown)
|
||||
generate(world, c.getX(), c.getZ(), result);
|
||||
resultData = result.result_data;
|
||||
}
|
||||
if (resultData != null) {
|
||||
for (int i = 0; i < resultData.length; i++) {
|
||||
byte[] section = resultData[i];
|
||||
if (section == null) {
|
||||
continue;
|
||||
}
|
||||
for (int j = 0; j < section.length; j++) {
|
||||
int x = MainUtil.x_loc[i][j];
|
||||
int y = MainUtil.y_loc[i][j];
|
||||
int z = MainUtil.z_loc[i][j];
|
||||
c.getBlock(x, y, z).setData(section[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
BukkitPlotGenerator.this.random.state = c.getX() << 16 | c.getZ() & 0xFFFF;
|
||||
PlotArea area = PS.get().getPlotArea(world.getName(), null);
|
||||
ChunkWrapper wrap = new ChunkWrapper(area.worldname, c.getX(), c.getZ());
|
||||
ScopedLocalBlockQueue chunk = queue.getForChunk(wrap.x, wrap.z);
|
||||
if (BukkitPlotGenerator.this.plotGenerator
|
||||
.populateChunk(chunk, area, BukkitPlotGenerator.this.random)) {
|
||||
queue.flush();
|
||||
}
|
||||
}
|
||||
});
|
||||
this.chunkSetter = new GenChunk(null, null);
|
||||
this.full = true;
|
||||
MainUtil.initCache();
|
||||
}
|
||||
|
||||
public BukkitPlotGenerator(final String world, final ChunkGenerator cg) {
|
||||
if (cg instanceof BukkitPlotGenerator) {
|
||||
throw new IllegalArgumentException("ChunkGenerator: " + cg.getClass().getName()
|
||||
+ " is already a BukkitPlotGenerator!");
|
||||
}
|
||||
this.full = false;
|
||||
PS.debug("BukkitPlotGenerator does not fully support: " + cg);
|
||||
this.platformGenerator = cg;
|
||||
this.plotGenerator = new IndependentPlotGenerator() {
|
||||
@Override public void processSetup(SetupObject setup) {
|
||||
}
|
||||
|
||||
@Override public void initialize(PlotArea area) {
|
||||
}
|
||||
|
||||
@Override public PlotManager getNewPlotManager() {
|
||||
return PS.get().IMP.getDefaultGenerator().getNewPlotManager();
|
||||
}
|
||||
|
||||
@Override public String getName() {
|
||||
return cg.getClass().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlotArea getNewPlotArea(String world, String id, PlotId min, PlotId max) {
|
||||
return PS.get().IMP.getDefaultGenerator().getNewPlotArea(world, id, min, max);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateChunk(final ScopedLocalBlockQueue result, PlotArea settings,
|
||||
PseudoRandom random) {
|
||||
World w = BukkitUtil.getWorld(world);
|
||||
Location min = result.getMin();
|
||||
int cx = min.getX() >> 4;
|
||||
int cz = min.getZ() >> 4;
|
||||
Random r = new Random(MathMan.pair((short) cx, (short) cz));
|
||||
BiomeGrid grid = new BiomeGrid() {
|
||||
@Override public void setBiome(int x, int z, Biome biome) {
|
||||
result.setBiome(x, z, biome.name());
|
||||
}
|
||||
|
||||
@Override public Biome getBiome(int arg0, int arg1) {
|
||||
return Biome.FOREST;
|
||||
}
|
||||
};
|
||||
try {
|
||||
// ChunkData will spill a bit
|
||||
ChunkData data = cg.generateChunkData(w, r, cx, cz, grid);
|
||||
if (data != null) {
|
||||
return;
|
||||
}
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
// Populator spillage
|
||||
short[][] tmp = cg.generateExtBlockSections(w, r, cx, cz, grid);
|
||||
if (tmp != null) {
|
||||
for (int i = 0; i < tmp.length; i++) {
|
||||
short[] section = tmp[i];
|
||||
if (section == null) {
|
||||
if (i < 7) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
for (int y = i << 4; y < (i << 4) + 16; y++) {
|
||||
result.setBlock(x, y, z, (short) 0, (byte) 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
for (int j = 0; j < section.length; j++) {
|
||||
int x = MainUtil.x_loc[i][j];
|
||||
int y = MainUtil.y_loc[i][j];
|
||||
int z = MainUtil.z_loc[i][j];
|
||||
result.setBlock(x, y, z, section[j], (byte) 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (BlockPopulator populator : cg.getDefaultPopulators(w)) {
|
||||
populator.populate(w, r, w.getChunkAt(cx, cz));
|
||||
}
|
||||
}
|
||||
};
|
||||
this.chunkSetter = new GenChunk(null, new ChunkWrapper(world, 0, 0));
|
||||
MainUtil.initCache();
|
||||
}
|
||||
|
||||
@Override public void augment(PlotArea area) {
|
||||
BukkitAugmentedGenerator.get(BukkitUtil.getWorld(area.worldname));
|
||||
}
|
||||
|
||||
@Override public boolean isFull() {
|
||||
return this.full;
|
||||
}
|
||||
|
||||
@Override public IndependentPlotGenerator getPlotGenerator() {
|
||||
return this.plotGenerator;
|
||||
}
|
||||
|
||||
@Override public ChunkGenerator getPlatformGenerator() {
|
||||
return this.platformGenerator;
|
||||
}
|
||||
|
||||
@Override public List<BlockPopulator> getDefaultPopulators(World world) {
|
||||
try {
|
||||
if (!this.loaded) {
|
||||
String name = world.getName();
|
||||
PS.get().loadWorld(name, this);
|
||||
Set<PlotArea> areas = PS.get().getPlotAreas(name);
|
||||
if (!areas.isEmpty()) {
|
||||
PlotArea area = areas.iterator().next();
|
||||
if (!area.MOB_SPAWNING) {
|
||||
if (!area.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);
|
||||
}
|
||||
}
|
||||
this.loaded = true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
ArrayList<BlockPopulator> toAdd = new ArrayList<>();
|
||||
List<BlockPopulator> existing = world.getPopulators();
|
||||
if (populators == null && platformGenerator != null) {
|
||||
populators = new ArrayList<>(platformGenerator.getDefaultPopulators(world));
|
||||
}
|
||||
for (BlockPopulator populator : this.populators) {
|
||||
if (!existing.contains(populator)) {
|
||||
toAdd.add(populator);
|
||||
}
|
||||
}
|
||||
return toAdd;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkData generateChunkData(World world, Random random, int cx, int cz, BiomeGrid grid) {
|
||||
GenChunk result = this.chunkSetter;
|
||||
if (this.getPlotGenerator() instanceof SingleWorldGenerator) {
|
||||
if (result.cd != null) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
grid.setBiome(x, z, Biome.PLAINS);
|
||||
}
|
||||
}
|
||||
return result.cd;
|
||||
}
|
||||
}
|
||||
// Set the chunk location
|
||||
result.setChunk(new ChunkWrapper(world.getName(), cx, cz));
|
||||
// Set the result data
|
||||
result.cd = createChunkData(world);
|
||||
result.grid = grid;
|
||||
result.result = null;
|
||||
result.result_data = null;
|
||||
// Catch any exceptions (as exceptions usually thrown)
|
||||
try {
|
||||
// Fill the result data if necessary
|
||||
if (this.platformGenerator != this) {
|
||||
return this.platformGenerator.generateChunkData(world, random, cx, cz, grid);
|
||||
} else {
|
||||
generate(world, cx, cz, result);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// Return the result data
|
||||
return result.cd;
|
||||
}
|
||||
|
||||
public void generate(World world, int cx, int cz, ScopedLocalBlockQueue result) {
|
||||
// Load if improperly loaded
|
||||
if (!this.loaded) {
|
||||
String name = world.getName();
|
||||
PS.get().loadWorld(name, this);
|
||||
this.loaded = true;
|
||||
}
|
||||
// Set random seed
|
||||
this.random.state = cx << 16 | cz & 0xFFFF;
|
||||
// Process the chunk
|
||||
if (ChunkManager.preProcessChunk(result)) {
|
||||
return;
|
||||
}
|
||||
PlotArea area = PS.get().getPlotArea(world.getName(), null);
|
||||
try {
|
||||
this.plotGenerator.generateChunk(this.chunkSetter, area, this.random);
|
||||
} catch (Throwable e) {
|
||||
// Recover from generator error
|
||||
e.printStackTrace();
|
||||
}
|
||||
ChunkManager.postProcessChunk(result);
|
||||
}
|
||||
|
||||
@Override public short[][] generateExtBlockSections(World world, Random r, int cx, int cz,
|
||||
BiomeGrid grid) {
|
||||
GenChunk result = this.chunkSetter;
|
||||
// Set the chunk location
|
||||
result.setChunk(new ChunkWrapper(world.getName(), cx, cz));
|
||||
// Set the result data
|
||||
result.result = new short[16][];
|
||||
result.result_data = new byte[16][];
|
||||
result.grid = grid;
|
||||
result.cd = null;
|
||||
// Catch any exceptions (as exceptions usually thrown)
|
||||
try {
|
||||
// Fill the result data
|
||||
if (this.platformGenerator != this) {
|
||||
return this.platformGenerator.generateExtBlockSections(world, r, cx, cz, grid);
|
||||
} else {
|
||||
generate(world, cx, cz, result);
|
||||
for (int i = 0; i < result.result_data.length; i++) {
|
||||
if (result.result_data[i] != null) {
|
||||
this.dataMap.put(new ChunkLoc(cx, cz), result.result_data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// Return the result data
|
||||
return result.result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow spawning everywhere.
|
||||
*
|
||||
* @param world Ignored
|
||||
* @param x Ignored
|
||||
* @param z Ignored
|
||||
* @return always true
|
||||
*/
|
||||
@Override public boolean canSpawn(World world, int x, int z) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override public String toString() {
|
||||
if (this.platformGenerator == this) {
|
||||
return this.plotGenerator.getName();
|
||||
}
|
||||
if (this.platformGenerator == null) {
|
||||
return "null";
|
||||
} else {
|
||||
return this.platformGenerator.getClass().getName();
|
||||
}
|
||||
}
|
||||
|
||||
@Override public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
return toString().equals(obj.toString()) || toString().equals(obj.getClass().getName());
|
||||
}
|
||||
}
|
@ -1,287 +0,0 @@
|
||||
package com.plotsquared.bukkit.listeners;
|
||||
|
||||
import com.intellectualcrafters.plot.PS;
|
||||
import com.intellectualcrafters.plot.config.C;
|
||||
import com.intellectualcrafters.plot.config.Settings;
|
||||
import com.intellectualcrafters.plot.object.Location;
|
||||
import com.intellectualcrafters.plot.object.Plot;
|
||||
import com.intellectualcrafters.plot.util.ReflectionUtils.RefClass;
|
||||
import com.intellectualcrafters.plot.util.ReflectionUtils.RefField;
|
||||
import com.intellectualcrafters.plot.util.ReflectionUtils.RefMethod;
|
||||
import com.intellectualcrafters.plot.util.TaskManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
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 java.lang.reflect.Method;
|
||||
import java.util.HashSet;
|
||||
|
||||
import static com.intellectualcrafters.plot.util.ReflectionUtils.getRefClass;
|
||||
|
||||
public class ChunkListener implements Listener {
|
||||
|
||||
private RefMethod methodGetHandleChunk;
|
||||
private RefField mustSave;
|
||||
private Chunk lastChunk;
|
||||
private boolean ignoreUnload = false;
|
||||
|
||||
public ChunkListener() {
|
||||
if (Settings.Chunk_Processor.AUTO_TRIM) {
|
||||
try {
|
||||
RefClass classChunk = getRefClass("{nms}.Chunk");
|
||||
RefClass classCraftChunk = getRefClass("{cb}.CraftChunk");
|
||||
this.mustSave = classChunk.getField("mustSave");
|
||||
this.methodGetHandleChunk = classCraftChunk.getMethod("getHandle");
|
||||
} catch (Throwable ignored) {
|
||||
PS.debug(PS.imp().getPluginName()
|
||||
+ "/Server not compatible for chunk processor trim/gc");
|
||||
Settings.Chunk_Processor.AUTO_TRIM = false;
|
||||
}
|
||||
}
|
||||
if (!Settings.Chunk_Processor.AUTO_TRIM) {
|
||||
return;
|
||||
}
|
||||
for (World world : Bukkit.getWorlds()) {
|
||||
world.setAutoSave(false);
|
||||
}
|
||||
TaskManager.runTaskRepeat(new Runnable() {
|
||||
@Override public void run() {
|
||||
try {
|
||||
HashSet<Chunk> toUnload = new HashSet<>();
|
||||
for (World world : Bukkit.getWorlds()) {
|
||||
String worldName = world.getName();
|
||||
if (!PS.get().hasPlotArea(worldName)) {
|
||||
continue;
|
||||
}
|
||||
Object w = world.getClass().getDeclaredMethod("getHandle").invoke(world);
|
||||
Object chunkMap =
|
||||
w.getClass().getDeclaredMethod("getPlayerChunkMap").invoke(w);
|
||||
Method methodIsChunkInUse = chunkMap.getClass()
|
||||
.getDeclaredMethod("isChunkInUse", int.class, int.class);
|
||||
Chunk[] chunks = world.getLoadedChunks();
|
||||
for (Chunk chunk : chunks) {
|
||||
if ((boolean) methodIsChunkInUse
|
||||
.invoke(chunkMap, chunk.getX(), chunk.getZ())) {
|
||||
continue;
|
||||
}
|
||||
int x = chunk.getX();
|
||||
int z = chunk.getZ();
|
||||
if (!shouldSave(worldName, x, z)) {
|
||||
unloadChunk(worldName, chunk, false);
|
||||
continue;
|
||||
}
|
||||
toUnload.add(chunk);
|
||||
}
|
||||
}
|
||||
if (toUnload.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
long start = System.currentTimeMillis();
|
||||
for (Chunk chunk : toUnload) {
|
||||
if (System.currentTimeMillis() - start > 5) {
|
||||
return;
|
||||
}
|
||||
chunk.unload(true, false);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}, 1);
|
||||
}
|
||||
|
||||
public boolean unloadChunk(String world, Chunk chunk, boolean safe) {
|
||||
if (safe && shouldSave(world, chunk.getX(), chunk.getZ())) {
|
||||
return false;
|
||||
}
|
||||
Object c = this.methodGetHandleChunk.of(chunk).call();
|
||||
RefField.RefExecutor field = this.mustSave.of(c);
|
||||
if ((Boolean) field.get() == true) {
|
||||
field.set(false);
|
||||
if (chunk.isLoaded()) {
|
||||
ignoreUnload = true;
|
||||
chunk.unload(false, false);
|
||||
ignoreUnload = false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean shouldSave(String world, int X, int Z) {
|
||||
int x = X << 4;
|
||||
int z = Z << 4;
|
||||
int x2 = x + 15;
|
||||
int z2 = z + 15;
|
||||
Plot plot = new Location(world, x, 1, z).getOwnedPlotAbs();
|
||||
if (plot != null && plot.hasOwner()) {
|
||||
return true;
|
||||
}
|
||||
plot = new Location(world, x2, 1, z2).getOwnedPlotAbs();
|
||||
if (plot != null && plot.hasOwner()) {
|
||||
return true;
|
||||
}
|
||||
plot = new Location(world, x2, 1, z).getOwnedPlotAbs();
|
||||
if (plot != null && plot.hasOwner()) {
|
||||
return true;
|
||||
}
|
||||
plot = new Location(world, x, 1, z2).getOwnedPlotAbs();
|
||||
if (plot != null && plot.hasOwner()) {
|
||||
return true;
|
||||
}
|
||||
plot = new Location(world, x + 7, 1, z + 7).getOwnedPlotAbs();
|
||||
return plot != null && plot.hasOwner();
|
||||
}
|
||||
|
||||
@EventHandler public void onChunkUnload(ChunkUnloadEvent event) {
|
||||
if (ignoreUnload) {
|
||||
return;
|
||||
}
|
||||
if (Settings.Chunk_Processor.AUTO_TRIM) {
|
||||
Chunk chunk = event.getChunk();
|
||||
String world = chunk.getWorld().getName();
|
||||
if (PS.get().hasPlotArea(world)) {
|
||||
if (unloadChunk(world, chunk, true)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
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 == this.lastChunk) {
|
||||
event.getEntity().remove();
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (!PS.get().hasPlotArea(chunk.getWorld().getName())) {
|
||||
return;
|
||||
}
|
||||
Entity[] entities = chunk.getEntities();
|
||||
if (entities.length > Settings.Chunk_Processor.MAX_ENTITIES) {
|
||||
event.getEntity().remove();
|
||||
event.setCancelled(true);
|
||||
this.lastChunk = chunk;
|
||||
} else {
|
||||
this.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 == this.lastChunk) {
|
||||
event.getEntity().remove();
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (!PS.get().hasPlotArea(chunk.getWorld().getName())) {
|
||||
return;
|
||||
}
|
||||
Entity[] entities = chunk.getEntities();
|
||||
if (entities.length > Settings.Chunk_Processor.MAX_ENTITIES) {
|
||||
event.getEntity().remove();
|
||||
event.setCancelled(true);
|
||||
this.lastChunk = chunk;
|
||||
} else {
|
||||
this.lastChunk = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void cleanChunk(final Chunk chunk) {
|
||||
TaskManager.index.incrementAndGet();
|
||||
final Integer currentIndex = TaskManager.index.get();
|
||||
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.debug(C.PREFIX.s() + "&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.debug(C.PREFIX.s() + "&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.debug(C.PREFIX.s() + "&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().hasPlotArea(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.debug(C.PREFIX.s() + "&a detected unsafe chunk and processed: " + (chunk.getX() << 4)
|
||||
+ "," + (chunk.getX() << 4));
|
||||
}
|
||||
if (tiles.length > Settings.Chunk_Processor.MAX_TILES) {
|
||||
if (unload) {
|
||||
PS.debug(C.PREFIX.s() + "&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;
|
||||
}
|
||||
}
|
@ -1,95 +0,0 @@
|
||||
package com.plotsquared.bukkit.listeners;
|
||||
|
||||
import com.intellectualcrafters.plot.PS;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Vehicle;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
import org.bukkit.event.entity.EntityTeleportEvent;
|
||||
import org.bukkit.event.vehicle.*;
|
||||
import org.bukkit.metadata.FixedMetadataValue;
|
||||
import org.bukkit.metadata.MetadataValue;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EntityPortal_1_7_9 implements Listener {
|
||||
private static boolean ignoreTP = false;
|
||||
|
||||
public EntityPortal_1_7_9() {
|
||||
}
|
||||
|
||||
public static void test(Entity entity) {
|
||||
List<MetadataValue> meta = entity.getMetadata("plotworld");
|
||||
World world = entity.getLocation().getWorld();
|
||||
if (meta == null || meta.isEmpty()) {
|
||||
if (PS.get().isPlotWorld(world.getName())) {
|
||||
entity.setMetadata("plotworld",
|
||||
new FixedMetadataValue((Plugin) PS.get().IMP, entity.getLocation()));
|
||||
}
|
||||
} else {
|
||||
Location origin = (Location) meta.get(0).value();
|
||||
World originWorld = origin.getWorld();
|
||||
if (!originWorld.equals(world)) {
|
||||
if (!ignoreTP) {
|
||||
if (!world.getName().equalsIgnoreCase(originWorld + "_the_end")) {
|
||||
try {
|
||||
ignoreTP = true;
|
||||
entity.teleport(origin);
|
||||
} finally {
|
||||
ignoreTP = false;
|
||||
}
|
||||
if (entity.getLocation().getWorld().equals(world)) {
|
||||
entity.remove();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
entity.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler public void onVehicle(VehicleUpdateEvent event) {
|
||||
test(event.getVehicle());
|
||||
}
|
||||
|
||||
@EventHandler public void onVehicle(VehicleDestroyEvent event) {
|
||||
test(event.getVehicle());
|
||||
}
|
||||
|
||||
@EventHandler public void onVehicle(VehicleEntityCollisionEvent event) {
|
||||
test(event.getVehicle());
|
||||
}
|
||||
|
||||
@EventHandler public void onVehicle(VehicleCreateEvent event) {
|
||||
test(event.getVehicle());
|
||||
}
|
||||
|
||||
@EventHandler public void onVehicle(VehicleBlockCollisionEvent event) {
|
||||
test(event.getVehicle());
|
||||
}
|
||||
|
||||
@EventHandler public void onTeleport(EntityTeleportEvent event) {
|
||||
Entity ent = event.getEntity();
|
||||
if (ent instanceof Vehicle || ent instanceof ArmorStand)
|
||||
test(event.getEntity());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void vehicleMove(VehicleMoveEvent event) throws IllegalAccessException {
|
||||
test(event.getVehicle());
|
||||
}
|
||||
|
||||
@EventHandler public void spawn(CreatureSpawnEvent event) {
|
||||
switch (event.getEntityType()) {
|
||||
case ARMOR_STAND:
|
||||
test(event.getEntity());
|
||||
}
|
||||
}
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
package com.plotsquared.bukkit.listeners;
|
||||
|
||||
import com.intellectualcrafters.plot.PS;
|
||||
import com.intellectualcrafters.plot.config.Settings;
|
||||
import com.intellectualcrafters.plot.flag.Flags;
|
||||
import com.intellectualcrafters.plot.object.Location;
|
||||
import com.intellectualcrafters.plot.object.Plot;
|
||||
import com.intellectualcrafters.plot.object.PlotArea;
|
||||
import com.plotsquared.bukkit.util.BukkitUtil;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntitySpawnEvent;
|
||||
import org.bukkit.metadata.FixedMetadataValue;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class EntitySpawnListener implements Listener {
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void creatureSpawnEvent(EntitySpawnEvent event) {
|
||||
Entity entity = event.getEntity();
|
||||
Location location = BukkitUtil.getLocation(entity.getLocation());
|
||||
PlotArea area = location.getPlotArea();
|
||||
if (area == null) {
|
||||
return;
|
||||
}
|
||||
Plot plot = area.getOwnedPlotAbs(location);
|
||||
if (plot == null) {
|
||||
if (!area.MOB_SPAWNING) {
|
||||
EntityType type = entity.getType();
|
||||
switch (type) {
|
||||
case DROPPED_ITEM:
|
||||
if (Settings.Enabled_Components.KILL_ROAD_ITEMS) {
|
||||
break;
|
||||
}
|
||||
case PLAYER:
|
||||
return;
|
||||
}
|
||||
if (type.isAlive() || !area.MISC_SPAWN_UNOWNED) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (Settings.Done.RESTRICT_BUILDING && plot.hasFlag(Flags.DONE)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
switch (entity.getType()) {
|
||||
case ENDER_CRYSTAL:
|
||||
if (PlayerEvents.checkEntity(entity, plot)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
case SHULKER:
|
||||
if (!entity.hasMetadata("plot")) {
|
||||
entity.setMetadata("plot",
|
||||
new FixedMetadataValue((Plugin) PS.get().IMP, plot.getId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,104 +0,0 @@
|
||||
package com.plotsquared.bukkit.listeners;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.intellectualcrafters.plot.config.C;
|
||||
import com.intellectualcrafters.plot.flag.Flags;
|
||||
import com.intellectualcrafters.plot.object.Location;
|
||||
import com.intellectualcrafters.plot.object.Plot;
|
||||
import com.intellectualcrafters.plot.object.PlotPlayer;
|
||||
import com.intellectualcrafters.plot.util.Permissions;
|
||||
import com.plotsquared.bukkit.object.BukkitPlayer;
|
||||
import com.plotsquared.bukkit.util.BukkitUtil;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ForceFieldListener {
|
||||
|
||||
private static Set<PlotPlayer> getNearbyPlayers(Player player, Plot plot) {
|
||||
Set<PlotPlayer> players = new HashSet<>();
|
||||
for (Player nearPlayer : Iterables
|
||||
.filter(player.getNearbyEntities(5d, 5d, 5d), Player.class)) {
|
||||
PlotPlayer plotPlayer;
|
||||
if ((plotPlayer = BukkitUtil.getPlayer(nearPlayer)) == null || !plot
|
||||
.equals(plotPlayer.getCurrentPlot())) {
|
||||
continue;
|
||||
}
|
||||
if (!plot.isAdded(plotPlayer.getUUID())) {
|
||||
players.add(plotPlayer);
|
||||
}
|
||||
}
|
||||
return players;
|
||||
}
|
||||
|
||||
private static PlotPlayer hasNearbyPermitted(Player player, Plot plot) {
|
||||
for (Player nearPlayer : Iterables
|
||||
.filter(player.getNearbyEntities(5d, 5d, 5d), Player.class)) {
|
||||
PlotPlayer plotPlayer;
|
||||
if ((plotPlayer = BukkitUtil.getPlayer(nearPlayer)) == null || !plot
|
||||
.equals(plotPlayer.getCurrentPlot())) {
|
||||
continue;
|
||||
}
|
||||
if (plot.isAdded(plotPlayer.getUUID())) {
|
||||
return plotPlayer;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Vector calculateVelocity(PlotPlayer player, PlotPlayer e) {
|
||||
Location playerLocation = player.getLocationFull();
|
||||
Location oPlayerLocation = e.getLocation();
|
||||
double playerX = playerLocation.getX();
|
||||
double playerY = playerLocation.getY();
|
||||
double playerZ = playerLocation.getZ();
|
||||
double oPlayerX = oPlayerLocation.getX();
|
||||
double oPlayerY = oPlayerLocation.getY();
|
||||
double oPlayerZ = oPlayerLocation.getZ();
|
||||
double x = 0d;
|
||||
if (playerX < oPlayerX) {
|
||||
x = 1.0d;
|
||||
} else if (playerX > oPlayerX) {
|
||||
x = -1.0d;
|
||||
}
|
||||
double y = 0d;
|
||||
if (playerY < oPlayerY) {
|
||||
y = 0.5d;
|
||||
} else if (playerY > oPlayerY) {
|
||||
y = -0.5d;
|
||||
}
|
||||
double z = 0d;
|
||||
if (playerZ < oPlayerZ) {
|
||||
z = 1.0d;
|
||||
} else if (playerZ > oPlayerZ) {
|
||||
z = -1.0d;
|
||||
}
|
||||
return new Vector(x, y, z);
|
||||
}
|
||||
|
||||
public static void handleForcefield(Player player, PlotPlayer plotPlayer, Plot plot) {
|
||||
if (Flags.FORCEFIELD.isTrue(plot)) {
|
||||
UUID uuid = plotPlayer.getUUID();
|
||||
if (plot.isAdded(uuid)) {
|
||||
Set<PlotPlayer> players = getNearbyPlayers(player, plot);
|
||||
for (PlotPlayer oPlayer : players) {
|
||||
if (!Permissions.hasPermission(oPlayer, C.PERMISSION_ADMIN_ENTRY_FORCEFIELD)) {
|
||||
((BukkitPlayer) oPlayer).player
|
||||
.setVelocity(calculateVelocity(plotPlayer, oPlayer));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
PlotPlayer oPlayer = hasNearbyPermitted(player, plot);
|
||||
if (oPlayer == null) {
|
||||
return;
|
||||
}
|
||||
if (!Permissions.hasPermission(plotPlayer, C.PERMISSION_ADMIN_ENTRY_FORCEFIELD)) {
|
||||
player.setVelocity(calculateVelocity(oPlayer, plotPlayer));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,49 +0,0 @@
|
||||
package com.plotsquared.bukkit.listeners;
|
||||
|
||||
import com.intellectualcrafters.plot.PS;
|
||||
import com.intellectualcrafters.plot.flag.Flags;
|
||||
import com.intellectualcrafters.plot.object.Location;
|
||||
import com.intellectualcrafters.plot.object.Plot;
|
||||
import com.intellectualcrafters.plot.object.PlotArea;
|
||||
import com.plotsquared.bukkit.util.BukkitUtil;
|
||||
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 java.util.Iterator;
|
||||
|
||||
public class PlayerEvents183 implements Listener {
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onBigBoom(BlockExplodeEvent event) {
|
||||
Block block = event.getBlock();
|
||||
Location location = BukkitUtil.getLocation(block.getLocation());
|
||||
String world = location.getWorld();
|
||||
if (!PS.get().hasPlotArea(world)) {
|
||||
return;
|
||||
}
|
||||
PlotArea area = location.getPlotArea();
|
||||
if (area == null) {
|
||||
Iterator<Block> iterator = event.blockList().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
location = BukkitUtil.getLocation(iterator.next().getLocation());
|
||||
if (location.getPlotArea() != null) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
Plot plot = area.getOwnedPlot(location);
|
||||
if (plot == null || !plot.getFlag(Flags.EXPLOSION).or(false)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
Iterator<Block> iterator = event.blockList().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Block b = iterator.next();
|
||||
if (!plot.equals(area.getOwnedPlot(BukkitUtil.getLocation(b.getLocation())))) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,183 +0,0 @@
|
||||
package com.plotsquared.bukkit.listeners;
|
||||
|
||||
import com.intellectualcrafters.plot.PS;
|
||||
import com.intellectualcrafters.plot.config.C;
|
||||
import com.intellectualcrafters.plot.flag.Flags;
|
||||
import com.intellectualcrafters.plot.object.Location;
|
||||
import com.intellectualcrafters.plot.object.Plot;
|
||||
import com.intellectualcrafters.plot.object.PlotArea;
|
||||
import com.intellectualcrafters.plot.object.PlotPlayer;
|
||||
import com.intellectualcrafters.plot.util.MainUtil;
|
||||
import com.intellectualcrafters.plot.util.Permissions;
|
||||
import com.plotsquared.bukkit.util.BukkitUtil;
|
||||
import com.plotsquared.listener.PlotListener;
|
||||
import org.bukkit.Material;
|
||||
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 java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class PlayerEvents_1_8 extends PlotListener implements Listener {
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@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().hasPlotArea(entity.getWorld().getName())) {
|
||||
return;
|
||||
}
|
||||
Player player = (Player) entity;
|
||||
PlayerInventory inv = player.getInventory();
|
||||
int slot = inv.getHeldItemSlot();
|
||||
if ((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 (!"[(+NBT)]".equals(newLore) || (current.equals(newItem) && newLore.equals(oldLore))) {
|
||||
switch (newItem.getType()) {
|
||||
case BANNER:
|
||||
case SKULL_ITEM:
|
||||
if (newMeta != null)
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
HashSet<Material> blocks = null;
|
||||
Block block = player.getTargetBlock(blocks, 7);
|
||||
BlockState state = block.getState();
|
||||
if (state == null) {
|
||||
return;
|
||||
}
|
||||
Material stateType = state.getType();
|
||||
Material itemType = newItem.getType();
|
||||
if (stateType != itemType) {
|
||||
switch (stateType) {
|
||||
case STANDING_BANNER:
|
||||
case WALL_BANNER:
|
||||
if (itemType == Material.BANNER)
|
||||
break;
|
||||
case SKULL:
|
||||
if (itemType == Material.SKULL_ITEM)
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
Location l = BukkitUtil.getLocation(state.getLocation());
|
||||
PlotArea area = l.getPlotArea();
|
||||
if (area == null) {
|
||||
return;
|
||||
}
|
||||
Plot plot = area.getPlotAbs(l);
|
||||
PlotPlayer pp = BukkitUtil.getPlayer(player);
|
||||
boolean cancelled = false;
|
||||
if (plot == null) {
|
||||
if (!Permissions.hasPermission(pp, "plots.admin.interact.road")) {
|
||||
MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, "plots.admin.interact.road");
|
||||
cancelled = true;
|
||||
}
|
||||
} else if (!plot.hasOwner()) {
|
||||
if (!Permissions.hasPermission(pp, "plots.admin.interact.unowned")) {
|
||||
MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, "plots.admin.interact.unowned");
|
||||
cancelled = true;
|
||||
}
|
||||
} else {
|
||||
UUID uuid = pp.getUUID();
|
||||
if (!plot.isAdded(uuid)) {
|
||||
if (!Permissions.hasPermission(pp, "plots.admin.interact.other")) {
|
||||
MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, "plots.admin.interact.other");
|
||||
cancelled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cancelled) {
|
||||
if ((current.getType() == newItem.getType()) && (current.getDurability() == newItem
|
||||
.getDurability())) {
|
||||
event.setCursor(
|
||||
new ItemStack(newItem.getType(), newItem.getAmount(), newItem.getDurability()));
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
event.setCursor(
|
||||
new ItemStack(newItem.getType(), newItem.getAmount(), newItem.getDurability()));
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onInteract(PlayerInteractAtEntityEvent e) {
|
||||
Entity entity = e.getRightClicked();
|
||||
if (!(entity instanceof ArmorStand)) {
|
||||
return;
|
||||
}
|
||||
Location l = BukkitUtil.getLocation(e.getRightClicked().getLocation());
|
||||
PlotArea area = l.getPlotArea();
|
||||
if (area == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
EntityPortal_1_7_9.test(entity);
|
||||
|
||||
Plot plot = area.getPlotAbs(l);
|
||||
PlotPlayer pp = BukkitUtil.getPlayer(e.getPlayer());
|
||||
if (plot == null) {
|
||||
if (!Permissions.hasPermission(pp, "plots.admin.interact.road")) {
|
||||
MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, "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_EVENT, "plots.admin.interact.unowned");
|
||||
e.setCancelled(true);
|
||||
}
|
||||
} else {
|
||||
UUID uuid = pp.getUUID();
|
||||
if (!plot.isAdded(uuid)) {
|
||||
if (Flags.MISC_INTERACT.isTrue(plot)) {
|
||||
return;
|
||||
}
|
||||
if (!Permissions.hasPermission(pp, "plots.admin.interact.other")) {
|
||||
MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, "plots.admin.interact.other");
|
||||
e.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
package com.plotsquared.bukkit.listeners;
|
||||
|
||||
import com.intellectualcrafters.plot.PS;
|
||||
import com.intellectualcrafters.plot.object.Location;
|
||||
import com.plotsquared.bukkit.util.BukkitUtil;
|
||||
import org.bukkit.entity.LingeringPotion;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.LingeringPotionSplashEvent;
|
||||
|
||||
public class PlayerEvents_1_9 implements Listener {
|
||||
|
||||
private final PlayerEvents parent;
|
||||
|
||||
public PlayerEvents_1_9(PlayerEvents parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onPotionSplash(LingeringPotionSplashEvent event) {
|
||||
LingeringPotion entity = event.getEntity();
|
||||
Location l = BukkitUtil.getLocation(entity);
|
||||
if (!PS.get().hasPlotArea(l.getWorld())) {
|
||||
return;
|
||||
}
|
||||
if (!parent.onProjectileHit(event)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,179 +0,0 @@
|
||||
package com.plotsquared.bukkit.listeners;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import com.intellectualcrafters.plot.flag.Flags;
|
||||
import com.intellectualcrafters.plot.object.Plot;
|
||||
import com.intellectualcrafters.plot.object.PlotPlayer;
|
||||
import com.plotsquared.bukkit.events.PlayerEnterPlotEvent;
|
||||
import com.plotsquared.bukkit.events.PlayerLeavePlotEvent;
|
||||
import com.plotsquared.bukkit.util.BukkitUtil;
|
||||
import com.plotsquared.listener.PlotListener;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.block.Block;
|
||||
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.BlockBreakEvent;
|
||||
import org.bukkit.event.block.BlockDamageEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.event.player.PlayerDropItemEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.UUID;
|
||||
|
||||
public class PlotPlusListener extends PlotListener implements Listener {
|
||||
|
||||
private static final HashMap<String, Interval> feedRunnable = new HashMap<>();
|
||||
private static final HashMap<String, Interval> healRunnable = new HashMap<>();
|
||||
|
||||
public static void startRunnable(JavaPlugin plugin) {
|
||||
plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
|
||||
@Override public void run() {
|
||||
if (!healRunnable.isEmpty()) {
|
||||
for (Iterator<Entry<String, Interval>> iterator =
|
||||
healRunnable.entrySet().iterator(); iterator.hasNext(); ) {
|
||||
Entry<String, Interval> entry = iterator.next();
|
||||
Interval value = entry.getValue();
|
||||
++value.count;
|
||||
if (value.count == value.interval) {
|
||||
value.count = 0;
|
||||
Player player = Bukkit.getPlayer(entry.getKey());
|
||||
if (player == null) {
|
||||
iterator.remove();
|
||||
continue;
|
||||
}
|
||||
double level = player.getHealth();
|
||||
if (level != value.max) {
|
||||
player.setHealth(Math.min(level + value.amount, value.max));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!feedRunnable.isEmpty()) {
|
||||
for (Iterator<Entry<String, Interval>> iterator =
|
||||
feedRunnable.entrySet().iterator(); iterator.hasNext(); ) {
|
||||
Entry<String, Interval> entry = iterator.next();
|
||||
Interval value = entry.getValue();
|
||||
++value.count;
|
||||
if (value.count == value.interval) {
|
||||
value.count = 0;
|
||||
Player player = Bukkit.getPlayer(entry.getKey());
|
||||
if (player == null) {
|
||||
iterator.remove();
|
||||
continue;
|
||||
}
|
||||
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(BlockDamageEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
if (player.getGameMode() != GameMode.SURVIVAL) {
|
||||
return;
|
||||
}
|
||||
Plot plot = BukkitUtil.getLocation(player).getOwnedPlot();
|
||||
if (plot == null) {
|
||||
return;
|
||||
}
|
||||
if (Flags.INSTABREAK.isTrue(plot)) {
|
||||
Block block = event.getBlock();
|
||||
BlockBreakEvent call = new BlockBreakEvent(block, player);
|
||||
Bukkit.getServer().getPluginManager().callEvent(call);
|
||||
if (!call.isCancelled()) {
|
||||
event.getBlock().breakNaturally();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH) public void onDamage(EntityDamageEvent event) {
|
||||
if (event.getEntityType() != EntityType.PLAYER) {
|
||||
return;
|
||||
}
|
||||
Player player = (Player) event.getEntity();
|
||||
Plot plot = BukkitUtil.getLocation(player).getOwnedPlot();
|
||||
if (plot == null) {
|
||||
return;
|
||||
}
|
||||
if (Flags.INVINCIBLE.isTrue(plot)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler public void onItemDrop(PlayerDropItemEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
PlotPlayer pp = BukkitUtil.getPlayer(player);
|
||||
Plot plot = BukkitUtil.getLocation(player).getOwnedPlot();
|
||||
if (plot == null) {
|
||||
return;
|
||||
}
|
||||
UUID uuid = pp.getUUID();
|
||||
if (!plot.isAdded(uuid)) {
|
||||
if (Flags.ITEM_DROP.isFalse(plot)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler public void onPlotEnter(PlayerEnterPlotEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
Plot plot = event.getPlot();
|
||||
Optional<Integer[]> feed = plot.getFlag(Flags.FEED);
|
||||
if (feed.isPresent()) {
|
||||
Integer[] value = feed.get();
|
||||
feedRunnable.put(player.getName(), new Interval(value[0], value[1], 20));
|
||||
}
|
||||
Optional<Integer[]> heal = plot.getFlag(Flags.HEAL);
|
||||
if (heal.isPresent()) {
|
||||
Integer[] value = heal.get();
|
||||
healRunnable.put(player.getName(), new Interval(value[0], value[1], 20));
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
String name = player.getName();
|
||||
feedRunnable.remove(name);
|
||||
healRunnable.remove(name);
|
||||
}
|
||||
|
||||
@EventHandler public void onPlotLeave(PlayerLeavePlotEvent event) {
|
||||
Player leaver = event.getPlayer();
|
||||
Plot plot = event.getPlot();
|
||||
if (!plot.hasOwner()) {
|
||||
return;
|
||||
}
|
||||
BukkitUtil.getPlayer(leaver);
|
||||
String name = leaver.getName();
|
||||
feedRunnable.remove(name);
|
||||
healRunnable.remove(name);
|
||||
}
|
||||
|
||||
private static class Interval {
|
||||
|
||||
final int interval;
|
||||
final int amount;
|
||||
final int max;
|
||||
public int count = 0;
|
||||
|
||||
Interval(int interval, int amount, int max) {
|
||||
this.interval = interval;
|
||||
this.amount = amount;
|
||||
this.max = max;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
package com.plotsquared.bukkit.listeners;
|
||||
|
||||
import com.intellectualcrafters.plot.flag.Flags;
|
||||
import com.intellectualcrafters.plot.object.Plot;
|
||||
import com.intellectualcrafters.plot.object.PlotPlayer;
|
||||
import com.plotsquared.bukkit.util.BukkitUtil;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityPickupItemEvent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class PlotPlusListener_1_12 implements Listener {
|
||||
@EventHandler public void onItemPickup(EntityPickupItemEvent event) {
|
||||
LivingEntity ent = event.getEntity();
|
||||
if (ent instanceof Player) {
|
||||
Player player = (Player) ent;
|
||||
PlotPlayer pp = BukkitUtil.getPlayer(player);
|
||||
Plot plot = BukkitUtil.getLocation(player).getOwnedPlot();
|
||||
if (plot == null) {
|
||||
return;
|
||||
}
|
||||
UUID uuid = pp.getUUID();
|
||||
if (!plot.isAdded(uuid) && Flags.DROP_PROTECTION.isTrue(plot)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
package com.plotsquared.bukkit.listeners;
|
||||
|
||||
import com.intellectualcrafters.plot.flag.Flags;
|
||||
import com.intellectualcrafters.plot.object.Plot;
|
||||
import com.intellectualcrafters.plot.object.PlotPlayer;
|
||||
import com.plotsquared.bukkit.util.BukkitUtil;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerPickupItemEvent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class PlotPlusListener_Legacy implements Listener {
|
||||
@EventHandler public void onItemPickup(PlayerPickupItemEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
PlotPlayer pp = BukkitUtil.getPlayer(player);
|
||||
Plot plot = BukkitUtil.getLocation(player).getOwnedPlot();
|
||||
if (plot == null) {
|
||||
return;
|
||||
}
|
||||
UUID uuid = pp.getUUID();
|
||||
if (!plot.isAdded(uuid) && Flags.DROP_PROTECTION.isTrue(plot)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,106 +0,0 @@
|
||||
package com.plotsquared.bukkit.listeners;
|
||||
|
||||
import com.intellectualcrafters.plot.PS;
|
||||
import com.intellectualcrafters.plot.object.worlds.PlotAreaManager;
|
||||
import com.intellectualcrafters.plot.object.worlds.SinglePlotAreaManager;
|
||||
import com.intellectualcrafters.plot.util.ReflectionUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.world.ChunkEvent;
|
||||
import org.bukkit.event.world.ChunkLoadEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import static com.intellectualcrafters.plot.util.ReflectionUtils.getRefClass;
|
||||
|
||||
public class SingleWorldListener implements Listener {
|
||||
|
||||
private Method methodGetHandleChunk;
|
||||
private Field mustSave, done, lit, s;
|
||||
|
||||
public SingleWorldListener(Plugin plugin) throws Exception {
|
||||
ReflectionUtils.RefClass classChunk = getRefClass("{nms}.Chunk");
|
||||
ReflectionUtils.RefClass classCraftChunk = getRefClass("{cb}.CraftChunk");
|
||||
this.methodGetHandleChunk = classCraftChunk.getMethod("getHandle").getRealMethod();
|
||||
this.mustSave = classChunk.getField("mustSave").getRealField();
|
||||
try {
|
||||
this.done = classChunk.getField("done").getRealField();
|
||||
this.lit = classChunk.getField("lit").getRealField();
|
||||
this.s = classChunk.getField("s").getRealField();
|
||||
} catch (Throwable ignore) {
|
||||
ignore.printStackTrace();
|
||||
}
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
}
|
||||
|
||||
public void markChunkAsClean(Chunk chunk) {
|
||||
try {
|
||||
Object nmsChunk = methodGetHandleChunk.invoke(chunk);
|
||||
if (done != null)
|
||||
this.done.set(nmsChunk, true);
|
||||
if (mustSave != null)
|
||||
this.mustSave.set(nmsChunk, false);
|
||||
if (lit != null)
|
||||
this.lit.set(nmsChunk, false);
|
||||
if (s != null)
|
||||
this.s.set(nmsChunk, false);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void handle(ChunkEvent event) {
|
||||
World world = event.getWorld();
|
||||
String name = world.getName();
|
||||
PlotAreaManager man = PS.get().getPlotAreaManager();
|
||||
if (!(man instanceof SinglePlotAreaManager))
|
||||
return;
|
||||
if (!isPlotId(name))
|
||||
return;
|
||||
|
||||
markChunkAsClean(event.getChunk());
|
||||
}
|
||||
|
||||
// @EventHandler
|
||||
// public void onPopulate(ChunkPopulateEvent event) {
|
||||
// handle(event);
|
||||
// }
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST) public void onChunkLoad(ChunkLoadEvent event) {
|
||||
handle(event);
|
||||
}
|
||||
|
||||
private boolean isPlotId(String worldName) {
|
||||
int len = worldName.length();
|
||||
int separator = 0;
|
||||
for (int i = 0; i < len; i++) {
|
||||
switch (worldName.charAt(i)) {
|
||||
case ',':
|
||||
case ';':
|
||||
separator++;
|
||||
break;
|
||||
case '-':
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return separator == 1;
|
||||
}
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
package com.plotsquared.bukkit.listeners;
|
||||
|
||||
import com.intellectualcrafters.plot.PS;
|
||||
import com.intellectualcrafters.plot.generator.GeneratorWrapper;
|
||||
import com.intellectualcrafters.plot.object.worlds.PlotAreaManager;
|
||||
import com.intellectualcrafters.plot.object.worlds.SinglePlotAreaManager;
|
||||
import com.plotsquared.bukkit.generator.BukkitPlotGenerator;
|
||||
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.generator.ChunkGenerator;
|
||||
|
||||
public class WorldEvents implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onWorldInit(WorldInitEvent event) {
|
||||
World world = event.getWorld();
|
||||
String name = world.getName();
|
||||
PlotAreaManager manager = PS.get().getPlotAreaManager();
|
||||
if (manager instanceof SinglePlotAreaManager) {
|
||||
SinglePlotAreaManager single = (SinglePlotAreaManager) manager;
|
||||
if (single.isWorld(name)) {
|
||||
world.setKeepSpawnInMemory(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
ChunkGenerator gen = world.getGenerator();
|
||||
if (gen instanceof GeneratorWrapper) {
|
||||
PS.get().loadWorld(name, (GeneratorWrapper<?>) gen);
|
||||
} else {
|
||||
PS.get().loadWorld(name, new BukkitPlotGenerator(name, gen));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,136 +0,0 @@
|
||||
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;
|
||||
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 (this.pb != null) {
|
||||
return this.pb;
|
||||
}
|
||||
if (this.id == 0) {
|
||||
this.id = this.block.getTypeId();
|
||||
}
|
||||
byte data;
|
||||
switch (this.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 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 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;
|
||||
break;
|
||||
default:
|
||||
data = this.block.getData();
|
||||
break;
|
||||
}
|
||||
this.pb = PlotBlock.get((short) this.id, data);
|
||||
return this.pb;
|
||||
|
||||
}
|
||||
|
||||
@Override public int getId() {
|
||||
if (this.id == 0) {
|
||||
this.id = this.block.getTypeId();
|
||||
}
|
||||
return this.id;
|
||||
}
|
||||
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
package com.plotsquared.bukkit.object;
|
||||
|
||||
import com.intellectualcrafters.plot.object.OfflinePlotPlayer;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
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(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();
|
||||
}
|
||||
}
|
@ -1,276 +0,0 @@
|
||||
package com.plotsquared.bukkit.object;
|
||||
|
||||
import com.intellectualcrafters.plot.PS;
|
||||
import com.intellectualcrafters.plot.config.C;
|
||||
import com.intellectualcrafters.plot.object.Location;
|
||||
import com.intellectualcrafters.plot.object.PlotPlayer;
|
||||
import com.intellectualcrafters.plot.util.*;
|
||||
import com.plotsquared.bukkit.util.BukkitUtil;
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.WeatherType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventException;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
||||
import org.bukkit.permissions.PermissionAttachmentInfo;
|
||||
import org.bukkit.plugin.RegisteredListener;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class BukkitPlayer extends PlotPlayer {
|
||||
|
||||
public final Player player;
|
||||
public boolean offline;
|
||||
private UUID uuid;
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* <p>Please do not use this method. Instead use
|
||||
* BukkitUtil.getPlayer(Player), as it caches player objects.</p>
|
||||
*
|
||||
* @param player
|
||||
*/
|
||||
public BukkitPlayer(Player player) {
|
||||
this.player = player;
|
||||
super.populatePersistentMetaMap();
|
||||
}
|
||||
|
||||
public BukkitPlayer(Player player, boolean offline) {
|
||||
this.player = player;
|
||||
this.offline = offline;
|
||||
super.populatePersistentMetaMap();
|
||||
}
|
||||
|
||||
@Override public Location getLocation() {
|
||||
Location location = super.getLocation();
|
||||
return location == null ? BukkitUtil.getLocation(this.player) : location;
|
||||
}
|
||||
|
||||
@Override public UUID getUUID() {
|
||||
if (this.uuid == null) {
|
||||
this.uuid = UUIDHandler.getUUID(this);
|
||||
}
|
||||
return this.uuid;
|
||||
}
|
||||
|
||||
@Override public long getLastPlayed() {
|
||||
return this.player.getLastPlayed();
|
||||
}
|
||||
|
||||
@Override public boolean canTeleport(Location loc) {
|
||||
org.bukkit.Location to = BukkitUtil.getLocation(loc);
|
||||
org.bukkit.Location from = player.getLocation();
|
||||
PlayerTeleportEvent event = new PlayerTeleportEvent(player, from, to);
|
||||
RegisteredListener[] listeners = event.getHandlers().getRegisteredListeners();
|
||||
for (RegisteredListener listener : listeners) {
|
||||
if (listener.getPlugin().getName().equals(PS.imp().getPluginName())) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
listener.callEvent(event);
|
||||
} catch (EventException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (event.isCancelled() || !event.getTo().equals(to)) {
|
||||
return false;
|
||||
}
|
||||
event = new PlayerTeleportEvent(player, to, from);
|
||||
for (RegisteredListener listener : listeners) {
|
||||
if (listener.getPlugin().getName().equals(PS.imp().getPluginName())) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
listener.callEvent(event);
|
||||
} catch (EventException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override public boolean hasPermission(String permission) {
|
||||
if (this.offline && EconHandler.manager != null) {
|
||||
return EconHandler.manager.hasPermission(getName(), permission);
|
||||
}
|
||||
return this.player.hasPermission(permission);
|
||||
}
|
||||
|
||||
@Override public int hasPermissionRange(String stub, int range) {
|
||||
if (hasPermission(C.PERMISSION_ADMIN.s())) {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
String[] nodes = stub.split("\\.");
|
||||
StringBuilder n = new StringBuilder();
|
||||
for (int i = 0; i < (nodes.length - 1); i++) {
|
||||
n.append(nodes[i]).append(".");
|
||||
if (!stub.equals(n + C.PERMISSION_STAR.s())) {
|
||||
if (hasPermission(n + C.PERMISSION_STAR.s())) {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hasPermission(stub + ".*")) {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
int max = 0;
|
||||
String stubPlus = stub + ".";
|
||||
Set<PermissionAttachmentInfo> effective = player.getEffectivePermissions();
|
||||
if (!effective.isEmpty()) {
|
||||
for (PermissionAttachmentInfo attach : effective) {
|
||||
String perm = attach.getPermission();
|
||||
if (perm.startsWith(stubPlus)) {
|
||||
String end = perm.substring(stubPlus.length());
|
||||
if (MathMan.isInteger(end)) {
|
||||
int val = Integer.parseInt(end);
|
||||
if (val > range)
|
||||
return val;
|
||||
if (val > max)
|
||||
max = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = range; i > 0; i--) {
|
||||
if (hasPermission(stub + "." + i)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
@Override public boolean isPermissionSet(String permission) {
|
||||
return this.player.isPermissionSet(permission);
|
||||
}
|
||||
|
||||
@Override public void sendMessage(String message) {
|
||||
if (!StringMan.isEqual(this.<String>getMeta("lastMessage"), message) || (
|
||||
System.currentTimeMillis() - this.<Long>getMeta("lastMessageTime") > 5000)) {
|
||||
setMeta("lastMessage", message);
|
||||
setMeta("lastMessageTime", System.currentTimeMillis());
|
||||
this.player.sendMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void teleport(Location location) {
|
||||
if (Math.abs(location.getX()) >= 30000000 || Math.abs(location.getZ()) >= 30000000) {
|
||||
return;
|
||||
}
|
||||
this.player.teleport(
|
||||
new org.bukkit.Location(BukkitUtil.getWorld(location.getWorld()), location.getX() + 0.5,
|
||||
location.getY(), location.getZ() + 0.5, location.getYaw(), location.getPitch()),
|
||||
TeleportCause.COMMAND);
|
||||
}
|
||||
|
||||
@Override public String getName() {
|
||||
if (this.name == null) {
|
||||
this.name = this.player.getName();
|
||||
}
|
||||
return this.name;
|
||||
}
|
||||
|
||||
@Override public boolean isOnline() {
|
||||
return !this.offline && this.player.isOnline();
|
||||
}
|
||||
|
||||
@Override public void setCompassTarget(Location location) {
|
||||
this.player.setCompassTarget(
|
||||
new org.bukkit.Location(BukkitUtil.getWorld(location.getWorld()), location.getX(),
|
||||
location.getY(), location.getZ()));
|
||||
|
||||
}
|
||||
|
||||
@Override public Location getLocationFull() {
|
||||
return BukkitUtil.getLocationFull(this.player);
|
||||
}
|
||||
|
||||
@Override public void setWeather(PlotWeather weather) {
|
||||
switch (weather) {
|
||||
case CLEAR:
|
||||
this.player.setPlayerWeather(WeatherType.CLEAR);
|
||||
break;
|
||||
case RAIN:
|
||||
this.player.setPlayerWeather(WeatherType.DOWNFALL);
|
||||
break;
|
||||
case RESET:
|
||||
this.player.resetPlayerWeather();
|
||||
break;
|
||||
default:
|
||||
this.player.resetPlayerWeather();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override public PlotGameMode getGameMode() {
|
||||
switch (this.player.getGameMode()) {
|
||||
case ADVENTURE:
|
||||
return PlotGameMode.ADVENTURE;
|
||||
case CREATIVE:
|
||||
return PlotGameMode.CREATIVE;
|
||||
case SPECTATOR:
|
||||
return PlotGameMode.SPECTATOR;
|
||||
case SURVIVAL:
|
||||
return PlotGameMode.SURVIVAL;
|
||||
default:
|
||||
return PlotGameMode.NOT_SET;
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void setGameMode(PlotGameMode gameMode) {
|
||||
switch (gameMode) {
|
||||
case ADVENTURE:
|
||||
this.player.setGameMode(GameMode.ADVENTURE);
|
||||
break;
|
||||
case CREATIVE:
|
||||
this.player.setGameMode(GameMode.CREATIVE);
|
||||
break;
|
||||
case SPECTATOR:
|
||||
this.player.setGameMode(GameMode.SPECTATOR);
|
||||
break;
|
||||
case SURVIVAL:
|
||||
this.player.setGameMode(GameMode.SURVIVAL);
|
||||
break;
|
||||
default:
|
||||
this.player.setGameMode(GameMode.SURVIVAL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void setTime(long time) {
|
||||
if (time != Long.MAX_VALUE) {
|
||||
this.player.setPlayerTime(time, false);
|
||||
} else {
|
||||
this.player.resetPlayerTime();
|
||||
}
|
||||
}
|
||||
|
||||
@Override public boolean getFlight() {
|
||||
return player.getAllowFlight();
|
||||
}
|
||||
|
||||
@Override public void setFlight(boolean fly) {
|
||||
this.player.setAllowFlight(fly);
|
||||
}
|
||||
|
||||
@Override public void playMusic(Location location, int id) {
|
||||
//noinspection deprecation
|
||||
this.player.playEffect(BukkitUtil.getLocation(location), Effect.RECORD_PLAY, id);
|
||||
}
|
||||
|
||||
@Override public void kick(String message) {
|
||||
this.player.kickPlayer(message);
|
||||
}
|
||||
|
||||
@Override public void stopSpectating() {
|
||||
if (getGameMode() == PlotGameMode.SPECTATOR) {
|
||||
this.player.setSpectatorTarget(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public boolean isBanned() {
|
||||
return this.player.isBanned();
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
package com.plotsquared.bukkit.object.entity;
|
||||
|
||||
class AgeableStats {
|
||||
|
||||
int age;
|
||||
boolean locked;
|
||||
boolean adult;
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
package com.plotsquared.bukkit.object.entity;
|
||||
|
||||
class ArmorStandStats {
|
||||
|
||||
final float[] head = new float[3];
|
||||
final float[] body = new float[3];
|
||||
final float[] leftLeg = new float[3];
|
||||
final float[] rightLeg = new float[3];
|
||||
final float[] leftArm = new float[3];
|
||||
final float[] rightArm = new float[3];
|
||||
boolean arms;
|
||||
boolean noPlate;
|
||||
boolean invisible;
|
||||
boolean small;
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
package com.plotsquared.bukkit.object.entity;
|
||||
|
||||
|
||||
class EntityBaseStats {
|
||||
|
||||
EntityWrapper passenger;
|
||||
float fall;
|
||||
short fire;
|
||||
int age;
|
||||
double vZ;
|
||||
double vY;
|
||||
double vX;
|
||||
}
|
@ -1,726 +0,0 @@
|
||||
package com.plotsquared.bukkit.object.entity;
|
||||
|
||||
import com.intellectualcrafters.plot.PS;
|
||||
import com.plotsquared.bukkit.util.BukkitVersion;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.entity.Rabbit.Type;
|
||||
import org.bukkit.entity.Skeleton.SkeletonType;
|
||||
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;
|
||||
|
||||
public class EntityWrapper {
|
||||
|
||||
private final EntityType type;
|
||||
private final float yaw;
|
||||
private final float pitch;
|
||||
private final short depth;
|
||||
private final int hash;
|
||||
private final EntityBaseStats base = new EntityBaseStats();
|
||||
public double x;
|
||||
public double y;
|
||||
public double z;
|
||||
public ItemStack[] inventory;
|
||||
// Extended
|
||||
private ItemStack stack;
|
||||
private byte dataByte;
|
||||
private byte dataByte2;
|
||||
private String dataString;
|
||||
private LivingEntityStats lived;
|
||||
private AgeableStats aged;
|
||||
private TameableStats tamed;
|
||||
private ArmorStandStats stand;
|
||||
private HorseStats horse;
|
||||
private boolean noGravity;
|
||||
|
||||
public EntityWrapper(Entity entity, short depth) {
|
||||
this.hash = entity.getEntityId();
|
||||
this.depth = depth;
|
||||
Location location = entity.getLocation();
|
||||
this.yaw = location.getYaw();
|
||||
this.pitch = location.getPitch();
|
||||
this.x = location.getX();
|
||||
this.y = location.getY();
|
||||
this.z = location.getZ();
|
||||
this.type = entity.getType();
|
||||
if (depth == 0) {
|
||||
return;
|
||||
}
|
||||
Entity passenger = entity.getPassenger();
|
||||
if (passenger != null) {
|
||||
this.base.passenger = new EntityWrapper(passenger, depth);
|
||||
}
|
||||
this.base.fall = entity.getFallDistance();
|
||||
this.base.fire = (short) entity.getFireTicks();
|
||||
this.base.age = entity.getTicksLived();
|
||||
Vector velocity = entity.getVelocity();
|
||||
this.base.vX = velocity.getX();
|
||||
this.base.vY = velocity.getY();
|
||||
this.base.vZ = velocity.getZ();
|
||||
if (depth == 1) {
|
||||
return;
|
||||
}
|
||||
if (PS.get().checkVersion(PS.get().IMP.getServerVersion(), BukkitVersion.v1_10_0)
|
||||
|| entity instanceof ArmorStand) {
|
||||
if (!entity.hasGravity()) {
|
||||
this.noGravity = true;
|
||||
}
|
||||
}
|
||||
switch (entity.getType()) {
|
||||
case ARROW:
|
||||
case BOAT:
|
||||
if (PS.get().checkVersion(PS.get().IMP.getServerVersion(), BukkitVersion.v1_9_0)) {
|
||||
Boat boat = (Boat) entity;
|
||||
this.dataByte = getOrdinal(TreeSpecies.values(), boat.getWoodType());
|
||||
}
|
||||
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:
|
||||
case TIPPED_ARROW:
|
||||
case SPECTRAL_ARROW:
|
||||
case SHULKER_BULLET:
|
||||
case DRAGON_FIREBALL:
|
||||
case LINGERING_POTION:
|
||||
case AREA_EFFECT_CLOUD:
|
||||
// Do this stuff later
|
||||
return;
|
||||
default:
|
||||
PS.debug("&cCOULD NOT IDENTIFY ENTITY: " + entity.getType());
|
||||
return;
|
||||
// MISC //
|
||||
case DROPPED_ITEM:
|
||||
Item item = (Item) entity;
|
||||
this.stack = item.getItemStack();
|
||||
return;
|
||||
case ITEM_FRAME:
|
||||
this.x = Math.floor(this.x);
|
||||
this.y = Math.floor(this.y);
|
||||
this.z = Math.floor(this.z);
|
||||
ItemFrame itemFrame = (ItemFrame) entity;
|
||||
this.dataByte = getOrdinal(Rotation.values(), itemFrame.getRotation());
|
||||
this.stack = itemFrame.getItem().clone();
|
||||
return;
|
||||
case PAINTING:
|
||||
this.x = Math.floor(this.x);
|
||||
this.y = Math.floor(this.y);
|
||||
this.z = Math.floor(this.z);
|
||||
Painting painting = (Painting) entity;
|
||||
Art art = painting.getArt();
|
||||
this.dataByte = getOrdinal(BlockFace.values(), painting.getFacing());
|
||||
int h = art.getBlockHeight();
|
||||
if (h % 2 == 0) {
|
||||
this.y -= 1;
|
||||
}
|
||||
this.dataString = art.name();
|
||||
return;
|
||||
// END MISC //
|
||||
// INVENTORY HOLDER //
|
||||
case MINECART_CHEST:
|
||||
case MINECART_HOPPER:
|
||||
storeInventory((InventoryHolder) entity);
|
||||
return;
|
||||
// START LIVING ENTITY //
|
||||
// START AGEABLE //
|
||||
// START TAMEABLE //
|
||||
case HORSE:
|
||||
Horse horse = (Horse) entity;
|
||||
this.horse = new HorseStats();
|
||||
this.horse.jump = horse.getJumpStrength();
|
||||
this.horse.chest = horse.isCarryingChest();
|
||||
this.horse.variant = horse.getVariant();
|
||||
this.horse.style = horse.getStyle();
|
||||
this.horse.color = horse.getColor();
|
||||
storeTameable(horse);
|
||||
storeAgeable(horse);
|
||||
storeLiving(horse);
|
||||
storeInventory(horse);
|
||||
return;
|
||||
// END INVENTORY HOLDER //
|
||||
case WOLF:
|
||||
case OCELOT:
|
||||
storeTameable((Tameable) entity);
|
||||
storeAgeable((Ageable) entity);
|
||||
storeLiving((LivingEntity) entity);
|
||||
return;
|
||||
// END TAMEABLE //
|
||||
case SHEEP:
|
||||
Sheep sheep = (Sheep) entity;
|
||||
this.dataByte = (byte) (sheep.isSheared() ? 1 : 0);
|
||||
this.dataByte2 = sheep.getColor().getDyeData();
|
||||
storeAgeable(sheep);
|
||||
storeLiving(sheep);
|
||||
return;
|
||||
case VILLAGER:
|
||||
case CHICKEN:
|
||||
case COW:
|
||||
case MUSHROOM_COW:
|
||||
case PIG:
|
||||
case POLAR_BEAR:
|
||||
storeAgeable((Ageable) entity);
|
||||
storeLiving((LivingEntity) entity);
|
||||
return;
|
||||
case RABBIT:
|
||||
this.dataByte = getOrdinal(Type.values(), ((Rabbit) entity).getRabbitType());
|
||||
storeAgeable((Ageable) entity);
|
||||
storeLiving((LivingEntity) entity);
|
||||
return;
|
||||
// END AGEABLE //
|
||||
case GUARDIAN:
|
||||
this.dataByte = (byte) (((Guardian) entity).isElder() ? 1 : 0);
|
||||
storeLiving((LivingEntity) entity);
|
||||
return;
|
||||
case SKELETON:
|
||||
this.dataByte =
|
||||
getOrdinal(SkeletonType.values(), ((Skeleton) entity).getSkeletonType());
|
||||
storeLiving((LivingEntity) entity);
|
||||
return;
|
||||
case ARMOR_STAND:
|
||||
ArmorStand stand = (ArmorStand) entity;
|
||||
this.inventory =
|
||||
new ItemStack[] {stand.getItemInHand().clone(), stand.getHelmet().clone(),
|
||||
stand.getChestplate().clone(), stand.getLeggings().clone(),
|
||||
stand.getBoots().clone()};
|
||||
storeLiving(stand);
|
||||
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.isVisible()) {
|
||||
this.stand.invisible = true;
|
||||
}
|
||||
if (stand.isSmall()) {
|
||||
this.stand.small = true;
|
||||
}
|
||||
return;
|
||||
case ENDERMITE:
|
||||
return;
|
||||
case BAT:
|
||||
if (((Bat) entity).isAwake()) {
|
||||
this.dataByte = (byte) 1;
|
||||
} else {
|
||||
this.dataByte = (byte) 0;
|
||||
}
|
||||
return;
|
||||
case ENDER_DRAGON:
|
||||
EnderDragon entity1 = (EnderDragon) entity;
|
||||
this.dataByte = (byte) entity1.getPhase().ordinal();
|
||||
return;
|
||||
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 SHULKER:
|
||||
case SNOWMAN:
|
||||
storeLiving((LivingEntity) entity);
|
||||
return;
|
||||
case IRON_GOLEM:
|
||||
if (((IronGolem) entity).isPlayerCreated()) {
|
||||
this.dataByte = (byte) 1;
|
||||
} else {
|
||||
this.dataByte = (byte) 0;
|
||||
}
|
||||
storeLiving((LivingEntity) entity);
|
||||
// END LIVING //
|
||||
}
|
||||
}
|
||||
|
||||
@Override public boolean equals(Object obj) {
|
||||
return this.hash == obj.hashCode();
|
||||
}
|
||||
|
||||
@Override public int hashCode() {
|
||||
return this.hash;
|
||||
}
|
||||
|
||||
public void storeInventory(InventoryHolder held) {
|
||||
this.inventory = held.getInventory().getContents().clone();
|
||||
}
|
||||
|
||||
void restoreLiving(LivingEntity entity) {
|
||||
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.isEmpty()) {
|
||||
entity.addPotionEffects(this.lived.potions);
|
||||
}
|
||||
entity.setRemainingAir(this.lived.air);
|
||||
entity.setRemoveWhenFarAway(this.lived.persistent);
|
||||
if (this.lived.equipped) {
|
||||
this.restoreEquipment(entity);
|
||||
}
|
||||
if (this.lived.leashed) {
|
||||
// TODO leashes
|
||||
// World world = entity.getWorld();
|
||||
// Entity leash = world.spawnEntity(new Location(world, Math.floor(x) + lived.leashX, Math.floor(y) + lived.leashY, Math
|
||||
// .floor(z) + lived.leashZ), EntityType.LEASH_HITCH);
|
||||
// entity.setLeashHolder(leash);
|
||||
}
|
||||
}
|
||||
|
||||
void restoreEquipment(LivingEntity entity) {
|
||||
EntityEquipment equipment = entity.getEquipment();
|
||||
if (PS.get().checkVersion(PS.get().IMP.getServerVersion(), BukkitVersion.v1_9_0)) {
|
||||
equipment.setItemInMainHand(this.lived.mainHand);
|
||||
equipment.setItemInOffHand(this.lived.offHand);
|
||||
} else {
|
||||
equipment.setItemInHand(this.lived.mainHand);
|
||||
}
|
||||
equipment.setHelmet(this.lived.helmet);
|
||||
equipment.setChestplate(this.lived.chestplate);
|
||||
equipment.setLeggings(this.lived.leggings);
|
||||
equipment.setBoots(this.lived.boots);
|
||||
}
|
||||
|
||||
private void restoreInventory(InventoryHolder entity) {
|
||||
try {
|
||||
entity.getInventory().setContents(this.inventory);
|
||||
} catch (IllegalArgumentException e) {
|
||||
PS.debug("&c[WARN] Failed to restore inventory.\n Reason: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void storeLiving(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) {
|
||||
Location location = lived.getLeashHolder().getLocation();
|
||||
this.lived.leashX = (short) (this.x - location.getBlockX());
|
||||
this.lived.leashY = (short) (this.y - location.getBlockY());
|
||||
this.lived.leashZ = (short) (this.z - location.getBlockZ());
|
||||
}
|
||||
EntityEquipment equipment = lived.getEquipment();
|
||||
this.lived.equipped = equipment != null;
|
||||
if (this.lived.equipped) {
|
||||
storeEquipment(equipment);
|
||||
}
|
||||
}
|
||||
|
||||
void storeEquipment(EntityEquipment equipment) {
|
||||
if (PS.get().checkVersion(PS.get().IMP.getServerVersion(), BukkitVersion.v1_9_0)) {
|
||||
this.lived.mainHand = equipment.getItemInMainHand().clone();
|
||||
this.lived.offHand = equipment.getItemInOffHand().clone();
|
||||
} else {
|
||||
this.lived.mainHand = equipment.getItemInHand().clone();
|
||||
this.lived.offHand = null;
|
||||
}
|
||||
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(Tameable entity) {
|
||||
if (this.tamed.tamed) {
|
||||
if (this.tamed.owner != null) {
|
||||
entity.setTamed(true);
|
||||
entity.setOwner(this.tamed.owner);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void restoreAgeable(Ageable entity) {
|
||||
if (!this.aged.adult) {
|
||||
entity.setBaby();
|
||||
}
|
||||
entity.setAgeLock(this.aged.locked);
|
||||
if (this.aged.age > 0) {
|
||||
entity.setAge(this.aged.age);
|
||||
}
|
||||
}
|
||||
|
||||
public void storeAgeable(Ageable aged) {
|
||||
this.aged = new AgeableStats();
|
||||
this.aged.age = aged.getAge();
|
||||
this.aged.locked = aged.getAgeLock();
|
||||
this.aged.adult = aged.isAdult();
|
||||
}
|
||||
|
||||
public void storeTameable(Tameable tamed) {
|
||||
this.tamed = new TameableStats();
|
||||
this.tamed.owner = tamed.getOwner();
|
||||
this.tamed.tamed = tamed.isTamed();
|
||||
}
|
||||
|
||||
public Entity spawn(World world, int xOffset, int zOffset) {
|
||||
Location location = new Location(world, this.x + xOffset, this.y, this.z + zOffset);
|
||||
location.setYaw(this.yaw);
|
||||
location.setPitch(this.pitch);
|
||||
if (!this.type.isSpawnable()) {
|
||||
return null;
|
||||
}
|
||||
Entity entity;
|
||||
switch (this.type) {
|
||||
case DROPPED_ITEM:
|
||||
return world.dropItem(location, this.stack);
|
||||
case PLAYER:
|
||||
case LEASH_HITCH:
|
||||
return null;
|
||||
case ITEM_FRAME:
|
||||
entity = world.spawn(location, ItemFrame.class);
|
||||
break;
|
||||
case PAINTING:
|
||||
entity = world.spawn(location, Painting.class);
|
||||
break;
|
||||
default:
|
||||
entity = world.spawnEntity(location, this.type);
|
||||
break;
|
||||
}
|
||||
if (this.depth == 0) {
|
||||
return entity;
|
||||
}
|
||||
if (this.base.passenger != null) {
|
||||
try {
|
||||
entity.setPassenger(this.base.passenger.spawn(world, xOffset, zOffset));
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
if (this.base.fall != 0) {
|
||||
entity.setFallDistance(this.base.fall);
|
||||
}
|
||||
if (this.base.fire != 0) {
|
||||
entity.setFireTicks(this.base.fire);
|
||||
}
|
||||
if (this.base.age != 0) {
|
||||
entity.setTicksLived(this.base.age);
|
||||
}
|
||||
entity.setVelocity(new Vector(this.base.vX, this.base.vY, this.base.vZ));
|
||||
if (this.depth == 1) {
|
||||
return entity;
|
||||
}
|
||||
if (PS.get().checkVersion(PS.get().IMP.getServerVersion(), BukkitVersion.v1_10_0)
|
||||
|| entity instanceof ArmorStand) {
|
||||
if (this.noGravity) {
|
||||
entity.setGravity(false);
|
||||
}
|
||||
}
|
||||
switch (entity.getType()) {
|
||||
case ARROW:
|
||||
case BOAT:
|
||||
if (PS.get().checkVersion(PS.get().IMP.getServerVersion(), BukkitVersion.v1_9_0)) {
|
||||
Boat boat = (Boat) entity;
|
||||
boat.setWoodType(TreeSpecies.values()[dataByte]);
|
||||
}
|
||||
|
||||
case COMPLEX_PART:
|
||||
case EGG:
|
||||
case ENDER_CRYSTAL:
|
||||
case ENDER_PEARL:
|
||||
case ENDER_SIGNAL:
|
||||
case DROPPED_ITEM:
|
||||
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:
|
||||
return entity;
|
||||
case SLIME:
|
||||
((Slime) entity).setSize(this.dataByte);
|
||||
return entity;
|
||||
case SMALL_FIREBALL:
|
||||
case SNOWBALL:
|
||||
case SPLASH_POTION:
|
||||
case THROWN_EXP_BOTTLE:
|
||||
case WEATHER:
|
||||
case TIPPED_ARROW:
|
||||
case SPECTRAL_ARROW:
|
||||
case SHULKER_BULLET:
|
||||
case LINGERING_POTION:
|
||||
case AREA_EFFECT_CLOUD:
|
||||
case DRAGON_FIREBALL:
|
||||
case WITHER_SKULL:
|
||||
case MINECART_FURNACE:
|
||||
case UNKNOWN:
|
||||
// Do this stuff later
|
||||
return entity;
|
||||
default:
|
||||
PS.debug("&cCOULD NOT IDENTIFY ENTITY: " + entity.getType());
|
||||
return entity;
|
||||
// MISC //
|
||||
case ITEM_FRAME:
|
||||
ItemFrame itemframe = (ItemFrame) entity;
|
||||
itemframe.setRotation(Rotation.values()[this.dataByte]);
|
||||
itemframe.setItem(this.stack);
|
||||
return entity;
|
||||
case PAINTING:
|
||||
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:
|
||||
case MINECART_HOPPER:
|
||||
restoreInventory((InventoryHolder) entity);
|
||||
return entity;
|
||||
// START LIVING ENTITY //
|
||||
// START AGEABLE //
|
||||
// START TAMEABLE //
|
||||
case HORSE:
|
||||
Horse horse = (Horse) entity;
|
||||
horse.setJumpStrength(this.horse.jump);
|
||||
horse.setCarryingChest(this.horse.chest);
|
||||
horse.setVariant(this.horse.variant);
|
||||
horse.setStyle(this.horse.style);
|
||||
horse.setColor(this.horse.color);
|
||||
restoreTameable(horse);
|
||||
restoreAgeable(horse);
|
||||
restoreLiving(horse);
|
||||
restoreInventory(horse);
|
||||
return entity;
|
||||
// END INVENTORY HOLDER //
|
||||
case WOLF:
|
||||
case OCELOT:
|
||||
restoreTameable((Tameable) entity);
|
||||
restoreAgeable((Ageable) entity);
|
||||
restoreLiving((LivingEntity) entity);
|
||||
return entity;
|
||||
// END AGEABLE //
|
||||
case SHEEP:
|
||||
Sheep sheep = (Sheep) entity;
|
||||
if (this.dataByte == 1) {
|
||||
sheep.setSheared(true);
|
||||
}
|
||||
if (this.dataByte2 != 0) {
|
||||
sheep.setColor(DyeColor.getByDyeData(this.dataByte2));
|
||||
}
|
||||
restoreAgeable(sheep);
|
||||
restoreLiving(sheep);
|
||||
return sheep;
|
||||
case VILLAGER:
|
||||
case CHICKEN:
|
||||
case COW:
|
||||
case POLAR_BEAR:
|
||||
case MUSHROOM_COW:
|
||||
case PIG:
|
||||
restoreAgeable((Ageable) entity);
|
||||
restoreLiving((LivingEntity) entity);
|
||||
return entity;
|
||||
// END AGEABLE //
|
||||
case RABBIT:
|
||||
if (this.dataByte != 0) {
|
||||
((Rabbit) entity).setRabbitType(Type.values()[this.dataByte]);
|
||||
}
|
||||
restoreAgeable((Ageable) entity);
|
||||
restoreLiving((LivingEntity) entity);
|
||||
return entity;
|
||||
case GUARDIAN:
|
||||
if (this.dataByte != 0) {
|
||||
((Guardian) entity).setElder(true);
|
||||
}
|
||||
restoreLiving((LivingEntity) entity);
|
||||
return entity;
|
||||
case SKELETON:
|
||||
if (this.dataByte != 0) {
|
||||
((Skeleton) entity).setSkeletonType(SkeletonType.values()[this.dataByte]);
|
||||
}
|
||||
storeLiving((LivingEntity) entity);
|
||||
return entity;
|
||||
case ARMOR_STAND:
|
||||
// CHECK positions
|
||||
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.noPlate) {
|
||||
stand.setBasePlate(false);
|
||||
}
|
||||
if (this.stand.small) {
|
||||
stand.setSmall(true);
|
||||
}
|
||||
restoreLiving(stand);
|
||||
return stand;
|
||||
case BAT:
|
||||
if (this.dataByte != 0) {
|
||||
((Bat) entity).setAwake(true);
|
||||
}
|
||||
restoreLiving((LivingEntity) entity);
|
||||
return entity;
|
||||
case ENDER_DRAGON:
|
||||
if (this.dataByte != 0) {
|
||||
((EnderDragon) entity).setPhase(EnderDragon.Phase.values()[this.dataByte]);
|
||||
}
|
||||
restoreLiving((LivingEntity) entity);
|
||||
return entity;
|
||||
case ENDERMITE:
|
||||
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 SHULKER:
|
||||
restoreLiving((LivingEntity) entity);
|
||||
return entity;
|
||||
case IRON_GOLEM:
|
||||
if (this.dataByte != 0) {
|
||||
((IronGolem) entity).setPlayerCreated(true);
|
||||
}
|
||||
restoreLiving((LivingEntity) entity);
|
||||
return entity;
|
||||
// END LIVING
|
||||
}
|
||||
}
|
||||
|
||||
private byte getOrdinal(Object[] list, Object value) {
|
||||
for (byte i = 0; i < list.length; i++) {
|
||||
if (list[i].equals(value)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation") @Override public String toString() {
|
||||
return String.format("[%s, x=%s, y=%s, z=%s]", type.getName(), x, y, z);
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
package com.plotsquared.bukkit.object.entity;
|
||||
|
||||
import org.bukkit.entity.Horse;
|
||||
|
||||
class HorseStats {
|
||||
|
||||
double jump;
|
||||
boolean chest;
|
||||
Horse.Variant variant;
|
||||
Horse.Color color;
|
||||
Horse.Style style;
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
package com.plotsquared.bukkit.object.entity;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
class LivingEntityStats {
|
||||
|
||||
boolean loot;
|
||||
String name;
|
||||
boolean visible;
|
||||
float health;
|
||||
short air;
|
||||
boolean persistent;
|
||||
boolean leashed;
|
||||
short leashX;
|
||||
short leashY;
|
||||
short leashZ;
|
||||
boolean equipped;
|
||||
ItemStack mainHand;
|
||||
ItemStack helmet;
|
||||
ItemStack boots;
|
||||
ItemStack leggings;
|
||||
ItemStack chestplate;
|
||||
Collection<PotionEffect> potions;
|
||||
ItemStack offHand;
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
package com.plotsquared.bukkit.object.entity;
|
||||
|
||||
import org.bukkit.entity.AnimalTamer;
|
||||
|
||||
class TameableStats {
|
||||
|
||||
AnimalTamer owner;
|
||||
boolean tamed;
|
||||
}
|
@ -1,142 +0,0 @@
|
||||
package com.plotsquared.bukkit.object.schematic;
|
||||
|
||||
import com.intellectualcrafters.jnbt.*;
|
||||
import com.intellectualcrafters.plot.object.schematic.ItemType;
|
||||
import com.intellectualcrafters.plot.util.MathMan;
|
||||
import com.plotsquared.bukkit.util.BukkitUtil;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
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(String worldName, int x, int y, int z) {
|
||||
if (this.tag == null) {
|
||||
return false;
|
||||
}
|
||||
switch (this.tag.getString("id").toLowerCase()) {
|
||||
case "chest":
|
||||
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];
|
||||
byte[] slots = 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 (idStr != null && !MathMan.isInteger(idStr)) {
|
||||
idStr = idStr.split(":")[1].toLowerCase();
|
||||
id = (short) ItemType.getId(idStr);
|
||||
}
|
||||
ids[i] = id;
|
||||
datas[i] = (byte) itemComp.getShort("Damage");
|
||||
amounts[i] = itemComp.getByte("Count");
|
||||
slots[i] = itemComp.getByte("Slot");
|
||||
}
|
||||
World world = BukkitUtil.getWorld(worldName);
|
||||
Block block = world.getBlockAt(x, y, z);
|
||||
if (block == null) {
|
||||
return false;
|
||||
}
|
||||
BlockState state = block.getState();
|
||||
if (state instanceof InventoryHolder) {
|
||||
InventoryHolder holder = (InventoryHolder) state;
|
||||
Inventory inv = holder.getInventory();
|
||||
for (int i = 0; i < ids.length; i++) {
|
||||
ItemStack item = new ItemStack(ids[i], amounts[i], datas[i]);
|
||||
inv.addItem(item);
|
||||
}
|
||||
state.update(true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public CompoundTag getTag() {
|
||||
if (this.tag != null) {
|
||||
return this.tag;
|
||||
}
|
||||
if (this.state instanceof InventoryHolder) {
|
||||
InventoryHolder inv = (InventoryHolder) this.state;
|
||||
ItemStack[] contents = inv.getInventory().getContents();
|
||||
Map<String, Tag> values = new HashMap<>();
|
||||
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<>();
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: Move this into the sponge module!
|
||||
*
|
||||
public Map<String, Tag> serializeItem(final org.spongepowered.api.item.inventory.ItemStack item) {
|
||||
final Map<String, Tag> data = new HashMap<String, Tag>();
|
||||
|
||||
// FIXME serialize sponge item
|
||||
|
||||
return data;
|
||||
}
|
||||
*/
|
||||
|
||||
public Map<String, Tag> serializeItem(ItemStack item) {
|
||||
Map<String, Tag> data = new HashMap<>();
|
||||
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<>();
|
||||
for (Entry<Enchantment, Integer> entry : item.getEnchantments().entrySet()) {
|
||||
Map<String, Tag> enchantment = new HashMap<>();
|
||||
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<>();
|
||||
auxData.put("ench", new ListTag("ench", CompoundTag.class, enchantmentList));
|
||||
data.put("tag", new CompoundTag("tag", auxData));
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
@ -1,129 +0,0 @@
|
||||
package com.plotsquared.bukkit.titles;
|
||||
|
||||
import com.plotsquared.bukkit.chat.Reflection;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class DefaultTitleManager extends TitleManager {
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
DefaultTitleManager(String title, String subtitle, int fadeInTime, int stayTime,
|
||||
int fadeOutTime) {
|
||||
super(title, subtitle, fadeInTime, stayTime, fadeOutTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load spigot and NMS classes.
|
||||
*/
|
||||
@Override void loadClasses() {
|
||||
this.packetTitle = Reflection.getNMSClass("PacketPlayOutTitle");
|
||||
this.packetActions = Reflection.getNMSClass("EnumTitleAction");
|
||||
this.chatBaseComponent = Reflection.getNMSClass("IChatBaseComponent");
|
||||
this.nmsChatSerializer = Reflection.getNMSClass("ChatSerializer");
|
||||
}
|
||||
|
||||
@Override public void send(Player player)
|
||||
throws IllegalArgumentException, ReflectiveOperationException, SecurityException {
|
||||
if (this.packetTitle != null) {
|
||||
// First reset previous settings
|
||||
resetTitle(player);
|
||||
// Send timings first
|
||||
Object handle = getHandle(player);
|
||||
Object connection = getField(handle.getClass(), "playerConnection").get(handle);
|
||||
Object[] actions = this.packetActions.getEnumConstants();
|
||||
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.getTitle())
|
||||
+ "\",color:" + this.titleColor.name().toLowerCase() + '}');
|
||||
packet = this.packetTitle.getConstructor(this.packetActions, this.chatBaseComponent)
|
||||
.newInstance(actions[0], serialized);
|
||||
sendPacket.invoke(connection, packet);
|
||||
if (!this.getSubtitle().isEmpty()) {
|
||||
// Send subtitle if present
|
||||
serialized = getMethod(this.nmsChatSerializer, "a", String.class).invoke(null,
|
||||
"{text:\"" + ChatColor.translateAlternateColorCodes('&', this.getSubtitle())
|
||||
+ "\",color:" + this.subtitleColor.name().toLowerCase() + '}');
|
||||
packet = this.packetTitle.getConstructor(this.packetActions, this.chatBaseComponent)
|
||||
.newInstance(actions[1], serialized);
|
||||
sendPacket.invoke(connection, packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void clearTitle(Player player)
|
||||
throws IllegalArgumentException, ReflectiveOperationException, SecurityException {
|
||||
// Send timings first
|
||||
Object handle = getHandle(player);
|
||||
Object connection = getField(handle.getClass(), "playerConnection").get(handle);
|
||||
Object[] actions = this.packetActions.getEnumConstants();
|
||||
Method sendPacket = getMethod(connection.getClass(), "sendPacket");
|
||||
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 ReflectiveOperationException
|
||||
* @throws SecurityException
|
||||
*/
|
||||
@Override public void resetTitle(Player player)
|
||||
throws IllegalArgumentException, ReflectiveOperationException, SecurityException {
|
||||
// Send timings first
|
||||
Object handle = getHandle(player);
|
||||
Object connection = getField(handle.getClass(), "playerConnection").get(handle);
|
||||
Object[] actions = this.packetActions.getEnumConstants();
|
||||
Method sendPacket = getMethod(connection.getClass(), "sendPacket");
|
||||
Object packet = this.packetTitle.getConstructor(this.packetActions, this.chatBaseComponent)
|
||||
.newInstance(actions[4], null);
|
||||
sendPacket.invoke(connection, packet);
|
||||
}
|
||||
|
||||
Field getField(Class<?> clazz, String name) {
|
||||
try {
|
||||
Field field = clazz.getDeclaredField(name);
|
||||
field.setAccessible(true);
|
||||
return field;
|
||||
} catch (NoSuchFieldException | SecurityException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Method getMethod(Class<?> clazz, String name, Class<?>... args) {
|
||||
for (Method m : clazz.getMethods()) {
|
||||
if (m.getName().equals(name) && (args.length == 0 || classListEqual(args,
|
||||
m.getParameterTypes()))) {
|
||||
m.setAccessible(true);
|
||||
return m;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
package com.plotsquared.bukkit.titles;
|
||||
|
||||
import com.plotsquared.bukkit.chat.Reflection;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class DefaultTitleManager_183 extends DefaultTitleManager {
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
DefaultTitleManager_183(String title, String subtitle, int fadeInTime, int stayTime,
|
||||
int fadeOutTime) {
|
||||
super(title, subtitle, fadeInTime, stayTime, fadeOutTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load spigot and NMS classes.
|
||||
*/
|
||||
@Override void loadClasses() {
|
||||
this.packetTitle = Reflection.getNMSClass("PacketPlayOutTitle");
|
||||
this.chatBaseComponent = Reflection.getNMSClass("IChatBaseComponent");
|
||||
this.packetActions = Reflection.getNMSClass("PacketPlayOutTitle$EnumTitleAction");
|
||||
this.nmsChatSerializer = Reflection.getNMSClass("IChatBaseComponent$ChatSerializer");
|
||||
}
|
||||
|
||||
@Override public void send(Player player)
|
||||
throws IllegalArgumentException, ReflectiveOperationException, SecurityException {
|
||||
if (this.packetTitle != null) {
|
||||
// First reset previous settings
|
||||
resetTitle(player);
|
||||
// Send timings first
|
||||
Object handle = getHandle(player);
|
||||
Object connection = getField(handle.getClass(), "playerConnection").get(handle);
|
||||
Object[] actions = this.packetActions.getEnumConstants();
|
||||
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.getTitle())
|
||||
+ "\",color:" + this.titleColor.name().toLowerCase() + "}");
|
||||
packet = this.packetTitle.getConstructor(this.packetActions, this.chatBaseComponent)
|
||||
.newInstance(actions[0], serialized);
|
||||
sendPacket.invoke(connection, packet);
|
||||
if (!this.getSubtitle().isEmpty()) {
|
||||
// Send subtitle if present
|
||||
serialized = getMethod(this.nmsChatSerializer, "a", String.class).invoke(null,
|
||||
"{text:\"" + ChatColor.translateAlternateColorCodes('&', this.getSubtitle())
|
||||
+ "\",color:" + this.subtitleColor.name().toLowerCase() + "}");
|
||||
packet = this.packetTitle.getConstructor(this.packetActions, this.chatBaseComponent)
|
||||
.newInstance(actions[1], serialized);
|
||||
sendPacket.invoke(connection, packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
package com.plotsquared.bukkit.titles;
|
||||
|
||||
import com.intellectualcrafters.plot.PS;
|
||||
import com.intellectualcrafters.plot.object.PlotPlayer;
|
||||
import com.intellectualcrafters.plot.util.AbstractTitle;
|
||||
import com.plotsquared.bukkit.object.BukkitPlayer;
|
||||
import com.plotsquared.bukkit.util.BukkitVersion;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@SuppressWarnings("deprecation") public class DefaultTitle_111 extends AbstractTitle {
|
||||
|
||||
private final boolean valid;
|
||||
|
||||
public DefaultTitle_111() {
|
||||
this.valid = PS.get().checkVersion(PS.get().IMP.getServerVersion(), BukkitVersion.v1_11_0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendTitle(PlotPlayer player, String head, String sub, int in, int delay, int out) {
|
||||
if (valid) {
|
||||
try {
|
||||
final Player playerObj = ((BukkitPlayer) player).player;
|
||||
TitleManager_1_11 title = new TitleManager_1_11(head, sub, in, delay, out);
|
||||
title.send(playerObj);
|
||||
return;
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
}
|
||||
AbstractTitle.TITLE_CLASS = new DefaultTitle_180();
|
||||
AbstractTitle.TITLE_CLASS.sendTitle(player, head, sub, in, delay, out);
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package com.plotsquared.bukkit.titles;
|
||||
|
||||
import com.intellectualcrafters.plot.object.PlotPlayer;
|
||||
import com.intellectualcrafters.plot.util.AbstractTitle;
|
||||
import com.plotsquared.bukkit.object.BukkitPlayer;
|
||||
|
||||
public class DefaultTitle_180 extends AbstractTitle {
|
||||
|
||||
@Override
|
||||
public void sendTitle(PlotPlayer player, String head, String sub, int in, int delay, int out) {
|
||||
try {
|
||||
DefaultTitleManager title = new DefaultTitleManager(head, sub, in, delay, out);
|
||||
title.send(((BukkitPlayer) player).player);
|
||||
} catch (Exception ignored) {
|
||||
AbstractTitle.TITLE_CLASS = new DefaultTitle_19();
|
||||
AbstractTitle.TITLE_CLASS.sendTitle(player, head, sub, in, delay, out);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package com.plotsquared.bukkit.titles;
|
||||
|
||||
import com.intellectualcrafters.plot.object.PlotPlayer;
|
||||
import com.intellectualcrafters.plot.util.AbstractTitle;
|
||||
import com.plotsquared.bukkit.object.BukkitPlayer;
|
||||
|
||||
public class DefaultTitle_183 extends AbstractTitle {
|
||||
|
||||
@Override
|
||||
public void sendTitle(PlotPlayer player, String head, String sub, int in, int delay, int out) {
|
||||
try {
|
||||
DefaultTitleManager_183 title = new DefaultTitleManager_183(head, sub, in, delay, out);
|
||||
title.send(((BukkitPlayer) player).player);
|
||||
} catch (Exception ignored) {
|
||||
AbstractTitle.TITLE_CLASS = new HackTitle();
|
||||
AbstractTitle.TITLE_CLASS.sendTitle(player, head, sub, in, delay, out);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
package com.plotsquared.bukkit.titles;
|
||||
|
||||
import com.intellectualcrafters.plot.object.PlotPlayer;
|
||||
import com.intellectualcrafters.plot.util.AbstractTitle;
|
||||
import com.intellectualcrafters.plot.util.TaskManager;
|
||||
import com.plotsquared.bukkit.object.BukkitPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@SuppressWarnings("deprecation") public class DefaultTitle_19 extends AbstractTitle {
|
||||
|
||||
@Override
|
||||
public void sendTitle(PlotPlayer player, String head, String sub, int in, int delay, int out) {
|
||||
try {
|
||||
final Player playerObj = ((BukkitPlayer) player).player;
|
||||
playerObj.sendTitle(head, sub);
|
||||
TaskManager.runTaskLater(new Runnable() {
|
||||
@Override public void run() {
|
||||
playerObj.sendTitle("", "");
|
||||
}
|
||||
}, delay * 20);
|
||||
} catch (Throwable ignored) {
|
||||
AbstractTitle.TITLE_CLASS = new DefaultTitle_183();
|
||||
AbstractTitle.TITLE_CLASS.sendTitle(player, head, sub, in, delay, out);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
package com.plotsquared.bukkit.titles;
|
||||
|
||||
import com.intellectualcrafters.plot.PS;
|
||||
import com.intellectualcrafters.plot.config.Settings;
|
||||
import com.intellectualcrafters.plot.object.PlotPlayer;
|
||||
import com.intellectualcrafters.plot.util.AbstractTitle;
|
||||
import com.plotsquared.bukkit.object.BukkitPlayer;
|
||||
|
||||
public class HackTitle extends AbstractTitle {
|
||||
|
||||
@Override
|
||||
public void sendTitle(PlotPlayer player, String head, String sub, int in, int delay, int out) {
|
||||
try {
|
||||
HackTitleManager title = new HackTitleManager(head, sub, in, delay, out);
|
||||
title.send(((BukkitPlayer) player).player);
|
||||
} catch (Exception ignored) {
|
||||
PS.debug("&cYour server version does not support titles!");
|
||||
Settings.TITLES = false;
|
||||
AbstractTitle.TITLE_CLASS = null;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,177 +0,0 @@
|
||||
package com.plotsquared.bukkit.titles;
|
||||
|
||||
import com.plotsquared.bukkit.chat.Reflection;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class HackTitleManager extends TitleManager {
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
HackTitleManager(String title, String subtitle, int fadeInTime, int stayTime, int fadeOutTime) {
|
||||
super(title, subtitle, fadeInTime, stayTime, fadeOutTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load spigot and NMS classes.
|
||||
*/
|
||||
@Override void loadClasses() {
|
||||
this.packetTitle = getClass("org.spigotmc.ProtocolInjector$PacketTitle");
|
||||
this.packetActions = getClass("org.spigotmc.ProtocolInjector$PacketTitle$Action");
|
||||
this.nmsChatSerializer = Reflection.getNMSClass("ChatSerializer");
|
||||
}
|
||||
|
||||
@Override public void send(Player player)
|
||||
throws IllegalArgumentException, ReflectiveOperationException, SecurityException {
|
||||
if ((getProtocolVersion(player) >= 47) && isSpigot() && (this.packetTitle != null)) {
|
||||
// First reset previous settings
|
||||
resetTitle(player);
|
||||
// Send timings first
|
||||
Object handle = getHandle(player);
|
||||
Object connection = getField(handle.getClass(), "playerConnection").get(handle);
|
||||
Object[] actions = this.packetActions.getEnumConstants();
|
||||
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.getTitle())
|
||||
+ "\",color:" + this.titleColor.name().toLowerCase() + "}");
|
||||
packet = this.packetTitle
|
||||
.getConstructor(this.packetActions, Reflection.getNMSClass("IChatBaseComponent"))
|
||||
.newInstance(actions[0], serialized);
|
||||
sendPacket.invoke(connection, packet);
|
||||
if (!this.getSubtitle().isEmpty()) {
|
||||
// Send subtitle if present
|
||||
serialized = getMethod(this.nmsChatSerializer, "a", String.class).invoke(null,
|
||||
"{text:\"" + ChatColor.translateAlternateColorCodes('&', this.getSubtitle())
|
||||
+ "\",color:" + this.subtitleColor.name().toLowerCase() + "}");
|
||||
packet = this.packetTitle.getConstructor(this.packetActions,
|
||||
Reflection.getNMSClass("IChatBaseComponent"))
|
||||
.newInstance(actions[1], serialized);
|
||||
sendPacket.invoke(connection, packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void clearTitle(Player player)
|
||||
throws IllegalArgumentException, ReflectiveOperationException, SecurityException {
|
||||
if ((getProtocolVersion(player) >= 47) && isSpigot()) {
|
||||
// Send timings first
|
||||
Object handle = getHandle(player);
|
||||
Object connection = getField(handle.getClass(), "playerConnection").get(handle);
|
||||
Object[] actions = this.packetActions.getEnumConstants();
|
||||
Method sendPacket = getMethod(connection.getClass(), "sendPacket");
|
||||
Object packet =
|
||||
this.packetTitle.getConstructor(this.packetActions).newInstance(actions[3]);
|
||||
sendPacket.invoke(connection, packet);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void resetTitle(Player player)
|
||||
throws IllegalArgumentException, ReflectiveOperationException, SecurityException {
|
||||
if ((getProtocolVersion(player) >= 47) && isSpigot()) {
|
||||
// Send timings first
|
||||
Object handle = getHandle(player);
|
||||
Object connection = getField(handle.getClass(), "playerConnection").get(handle);
|
||||
Object[] actions = this.packetActions.getEnumConstants();
|
||||
Method sendPacket = getMethod(connection.getClass(), "sendPacket");
|
||||
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 IllegalArgumentException
|
||||
* @throws ReflectiveOperationException
|
||||
* @throws SecurityException
|
||||
*/
|
||||
private int getProtocolVersion(Player player)
|
||||
throws IllegalArgumentException, ReflectiveOperationException, SecurityException {
|
||||
Object handle = getHandle(player);
|
||||
Object connection = getField(handle.getClass(), "playerConnection").get(handle);
|
||||
Object networkManager = getValue("networkManager", connection);
|
||||
return (Integer) getMethod("getVersion", networkManager.getClass()).invoke(networkManager);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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(String namespace) {
|
||||
try {
|
||||
return Class.forName(namespace);
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Field getField(String name, Class<?> clazz)
|
||||
throws NoSuchFieldException, SecurityException {
|
||||
return clazz.getDeclaredField(name);
|
||||
}
|
||||
|
||||
private Object getValue(String name, Object obj)
|
||||
throws ReflectiveOperationException, SecurityException, IllegalArgumentException {
|
||||
Field f = getField(name, obj.getClass());
|
||||
f.setAccessible(true);
|
||||
return f.get(obj);
|
||||
}
|
||||
|
||||
private Field getField(Class<?> clazz, String name) {
|
||||
try {
|
||||
Field field = clazz.getDeclaredField(name);
|
||||
field.setAccessible(true);
|
||||
return field;
|
||||
} catch (SecurityException | NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Method getMethod(Class<?> clazz, String name, Class<?>... args) {
|
||||
for (Method m : clazz.getMethods()) {
|
||||
if (m.getName().equals(name) && ((args.length == 0) || classListEqual(args,
|
||||
m.getParameterTypes()))) {
|
||||
m.setAccessible(true);
|
||||
return m;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -1,256 +0,0 @@
|
||||
package com.plotsquared.bukkit.titles;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class TitleManager {
|
||||
|
||||
private static final Map<Class<?>, Class<?>> CORRESPONDING_TYPES = new HashMap<>();
|
||||
/* Title packet */ Class<?> packetTitle;
|
||||
/* Title packet actions ENUM */ Class<?> packetActions;
|
||||
/* Chat serializer */ Class<?> nmsChatSerializer;
|
||||
Class<?> chatBaseComponent;
|
||||
ChatColor titleColor = ChatColor.WHITE;
|
||||
ChatColor subtitleColor = ChatColor.WHITE;
|
||||
/* Title timings */ int fadeInTime = -1;
|
||||
int stayTime = -1;
|
||||
int fadeOutTime = -1;
|
||||
boolean ticks = false;
|
||||
/* Title text and color */
|
||||
private String title = "";
|
||||
/* Subtitle text and color */
|
||||
private String subtitle = "";
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
TitleManager(String title, String subtitle, int fadeInTime, int stayTime, int fadeOutTime) {
|
||||
this.title = title;
|
||||
this.subtitle = subtitle;
|
||||
this.fadeInTime = fadeInTime;
|
||||
this.stayTime = stayTime;
|
||||
this.fadeOutTime = fadeOutTime;
|
||||
loadClasses();
|
||||
}
|
||||
|
||||
abstract void loadClasses();
|
||||
|
||||
/**
|
||||
* Gets title text.
|
||||
*
|
||||
* @return Title text
|
||||
*/
|
||||
public final String getTitle() {
|
||||
return this.title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text for the title.
|
||||
*
|
||||
* @param title Title
|
||||
*/
|
||||
public final void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the subtitle text.
|
||||
*
|
||||
* @return Subtitle text
|
||||
*/
|
||||
public final String getSubtitle() {
|
||||
return this.subtitle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets subtitle text.
|
||||
*
|
||||
* @param subtitle Subtitle text
|
||||
*/
|
||||
public final void setSubtitle(String subtitle) {
|
||||
this.subtitle = subtitle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the title color.
|
||||
*
|
||||
* @param color Chat color
|
||||
*/
|
||||
public final void setTitleColor(ChatColor color) {
|
||||
this.titleColor = color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the subtitle color.
|
||||
*
|
||||
* @param color Chat color
|
||||
*/
|
||||
public final void setSubtitleColor(ChatColor color) {
|
||||
this.subtitleColor = color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets title fade in time.
|
||||
*
|
||||
* @param time Time
|
||||
*/
|
||||
public final void setFadeInTime(int time) {
|
||||
this.fadeInTime = time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets title fade out time.
|
||||
*
|
||||
* @param time Time
|
||||
*/
|
||||
public final void setFadeOutTime(int time) {
|
||||
this.fadeOutTime = time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets title stay time.
|
||||
*
|
||||
* @param time Time
|
||||
*/
|
||||
public final void setStayTime(int time) {
|
||||
this.stayTime = time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets timings to ticks.
|
||||
*/
|
||||
public final void setTimingsToTicks() {
|
||||
this.ticks = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets timings to seconds.
|
||||
*/
|
||||
public final void setTimingsToSeconds() {
|
||||
this.ticks = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the title to a player.
|
||||
*
|
||||
* @param player Player
|
||||
* @throws IllegalArgumentException
|
||||
* @throws ReflectiveOperationException
|
||||
* @throws SecurityException
|
||||
*/
|
||||
public abstract void send(Player player)
|
||||
throws IllegalArgumentException, ReflectiveOperationException, SecurityException;
|
||||
|
||||
/**
|
||||
* Broadcasts the title to all players.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public final void broadcast() throws Exception {
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
send(player);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the title.
|
||||
*
|
||||
* @param player Player
|
||||
* @throws IllegalArgumentException
|
||||
* @throws ReflectiveOperationException
|
||||
* @throws SecurityException
|
||||
*/
|
||||
public abstract void clearTitle(Player player)
|
||||
throws IllegalArgumentException, ReflectiveOperationException, SecurityException;
|
||||
|
||||
/**
|
||||
* Resets the title settings.
|
||||
*
|
||||
* @param player Player
|
||||
* @throws IllegalArgumentException
|
||||
* @throws ReflectiveOperationException
|
||||
* @throws SecurityException
|
||||
*/
|
||||
public abstract void resetTitle(Player player)
|
||||
throws IllegalArgumentException, ReflectiveOperationException, SecurityException;
|
||||
|
||||
private Class<?> getPrimitiveType(Class<?> clazz) {
|
||||
if (CORRESPONDING_TYPES.containsKey(clazz)) {
|
||||
return CORRESPONDING_TYPES.get(clazz);
|
||||
} else {
|
||||
return clazz;
|
||||
}
|
||||
}
|
||||
|
||||
private Class<?>[] toPrimitiveTypeArray(Class<?>[] classes) {
|
||||
int a;
|
||||
if (classes != null) {
|
||||
a = classes.length;
|
||||
} else {
|
||||
a = 0;
|
||||
}
|
||||
Class<?>[] types = new Class<?>[a];
|
||||
for (int i = 0; i < a; i++) {
|
||||
types[i] = getPrimitiveType(classes[i]);
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
final Object getHandle(Object obj) {
|
||||
try {
|
||||
return getMethod("getHandle", obj.getClass()).invoke(obj);
|
||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
final Method getMethod(String name, Class<?> clazz, Class<?>... paramTypes) {
|
||||
Class<?>[] t = toPrimitiveTypeArray(paramTypes);
|
||||
for (Method m : clazz.getMethods()) {
|
||||
Class<?>[] types = toPrimitiveTypeArray(m.getParameterTypes());
|
||||
if (m.getName().equals(name) && equalsTypeArray(types, t)) {
|
||||
return m;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean equalsTypeArray(Class<?>[] a, 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;
|
||||
}
|
||||
|
||||
boolean classListEqual(Class<?>[] l1, Class<?>[] l2) {
|
||||
if (l1.length != l2.length) {
|
||||
return false;
|
||||
}
|
||||
boolean equal = true;
|
||||
for (int i = 0; i < l1.length; i++) {
|
||||
if (l1[i] != l2[i]) {
|
||||
equal = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return equal;
|
||||
}
|
||||
}
|
@ -1,497 +0,0 @@
|
||||
package com.plotsquared.bukkit.titles;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Minecraft 1.8 Title
|
||||
* For 1.11
|
||||
*
|
||||
* @author Maxim Van de Wynckel
|
||||
* @version 1.1.0
|
||||
*/
|
||||
public class TitleManager_1_11 {
|
||||
private static final Map<Class<?>, Class<?>> CORRESPONDING_TYPES =
|
||||
new HashMap<Class<?>, Class<?>>();
|
||||
/* Title packet */
|
||||
private static Class<?> packetTitle;
|
||||
/* Title packet actions ENUM */
|
||||
private static Class<?> packetActions;
|
||||
/* Chat serializer */
|
||||
private static Class<?> nmsChatSerializer;
|
||||
private static Class<?> chatBaseComponent;
|
||||
/* NMS player and connection */
|
||||
private static Class<?> nmsPlayer;
|
||||
private static Class<?> nmsPlayerConnection;
|
||||
private static Field playerConnection;
|
||||
private static Method sendPacket;
|
||||
private static Class<?> obcPlayer;
|
||||
private static Method methodPlayerGetHandle;
|
||||
/* 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;
|
||||
|
||||
public TitleManager_1_11() {
|
||||
loadClasses();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new 1.8 title
|
||||
*
|
||||
* @param title Title
|
||||
*/
|
||||
public TitleManager_1_11(String title) {
|
||||
this.title = title;
|
||||
loadClasses();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new 1.8 title
|
||||
*
|
||||
* @param title Title text
|
||||
* @param subtitle Subtitle text
|
||||
*/
|
||||
public TitleManager_1_11(String title, String subtitle) {
|
||||
this.title = title;
|
||||
this.subtitle = subtitle;
|
||||
loadClasses();
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy 1.8 title
|
||||
*
|
||||
* @param title Title
|
||||
*/
|
||||
public TitleManager_1_11(TitleManager_1_11 title) {
|
||||
// Copy title
|
||||
this.title = title.getTitle();
|
||||
this.subtitle = title.getSubtitle();
|
||||
this.titleColor = title.getTitleColor();
|
||||
this.subtitleColor = title.getSubtitleColor();
|
||||
this.fadeInTime = title.getFadeInTime();
|
||||
this.fadeOutTime = title.getFadeOutTime();
|
||||
this.stayTime = title.getStayTime();
|
||||
this.ticks = title.isTicks();
|
||||
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
|
||||
*/
|
||||
public TitleManager_1_11(String title, String subtitle, int fadeInTime, int stayTime,
|
||||
int fadeOutTime) {
|
||||
this.title = title;
|
||||
this.subtitle = subtitle;
|
||||
this.fadeInTime = fadeInTime;
|
||||
this.stayTime = stayTime;
|
||||
this.fadeOutTime = fadeOutTime;
|
||||
loadClasses();
|
||||
}
|
||||
|
||||
private static boolean equalsTypeArray(Class<?>[] a, 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load spigot and NMS classes
|
||||
*/
|
||||
private void loadClasses() {
|
||||
if (packetTitle == null) {
|
||||
packetTitle = getNMSClass("PacketPlayOutTitle");
|
||||
packetActions = getNMSClass("PacketPlayOutTitle$EnumTitleAction");
|
||||
chatBaseComponent = getNMSClass("IChatBaseComponent");
|
||||
nmsChatSerializer = getNMSClass("ChatComponentText");
|
||||
nmsPlayer = getNMSClass("EntityPlayer");
|
||||
nmsPlayerConnection = getNMSClass("PlayerConnection");
|
||||
playerConnection = getField(nmsPlayer, "playerConnection");
|
||||
sendPacket = getMethod(nmsPlayerConnection, "sendPacket");
|
||||
obcPlayer = getOBCClass("entity.CraftPlayer");
|
||||
methodPlayerGetHandle = getMethod("getHandle", obcPlayer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get title text
|
||||
*
|
||||
* @return Title text
|
||||
*/
|
||||
public String getTitle() {
|
||||
return this.title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set title text
|
||||
*
|
||||
* @param title Title
|
||||
*/
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get subtitle text
|
||||
*
|
||||
* @return Subtitle text
|
||||
*/
|
||||
public String getSubtitle() {
|
||||
return this.subtitle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set subtitle text
|
||||
*
|
||||
* @param subtitle Subtitle text
|
||||
*/
|
||||
public void setSubtitle(String subtitle) {
|
||||
this.subtitle = subtitle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set timings to ticks
|
||||
*/
|
||||
public void setTimingsToTicks() {
|
||||
ticks = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set timings to seconds
|
||||
*/
|
||||
public void setTimingsToSeconds() {
|
||||
ticks = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the title to a player
|
||||
*
|
||||
* @param player Player
|
||||
*/
|
||||
public void send(Player player) {
|
||||
if (packetTitle != null) {
|
||||
// First reset previous settings
|
||||
resetTitle(player);
|
||||
try {
|
||||
// Send timings first
|
||||
Object handle = getHandle(player);
|
||||
Object connection = playerConnection.get(handle);
|
||||
Object[] actions = packetActions.getEnumConstants();
|
||||
Object packet = packetTitle
|
||||
.getConstructor(packetActions, chatBaseComponent, Integer.TYPE, Integer.TYPE,
|
||||
Integer.TYPE).newInstance(actions[3], null, fadeInTime * (ticks ? 1 : 20),
|
||||
stayTime * (ticks ? 1 : 20), fadeOutTime * (ticks ? 1 : 20));
|
||||
// Send if set
|
||||
if (fadeInTime != -1 && fadeOutTime != -1 && stayTime != -1)
|
||||
sendPacket.invoke(connection, packet);
|
||||
|
||||
Object serialized;
|
||||
if (!subtitle.equals("")) {
|
||||
// Send subtitle if present
|
||||
serialized = nmsChatSerializer.getConstructor(String.class).newInstance(
|
||||
subtitleColor + ChatColor.translateAlternateColorCodes('&', subtitle));
|
||||
packet = packetTitle.getConstructor(packetActions, chatBaseComponent)
|
||||
.newInstance(actions[1], serialized);
|
||||
sendPacket.invoke(connection, packet);
|
||||
}
|
||||
|
||||
// Send title
|
||||
serialized = nmsChatSerializer.getConstructor(String.class)
|
||||
.newInstance(titleColor + ChatColor.translateAlternateColorCodes('&', title));
|
||||
packet = packetTitle.getConstructor(packetActions, chatBaseComponent)
|
||||
.newInstance(actions[0], serialized);
|
||||
sendPacket.invoke(connection, packet);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updateTimes(Player player) {
|
||||
if (TitleManager_1_11.packetTitle != null) {
|
||||
try {
|
||||
Object handle = getHandle(player);
|
||||
Object connection = playerConnection.get(handle);
|
||||
Object[] actions = TitleManager_1_11.packetActions.getEnumConstants();
|
||||
Object packet = TitleManager_1_11.packetTitle.getConstructor(
|
||||
new Class[] {TitleManager_1_11.packetActions, chatBaseComponent, Integer.TYPE,
|
||||
Integer.TYPE, Integer.TYPE})
|
||||
.newInstance(actions[3], null, this.fadeInTime * (this.ticks ? 1 : 20),
|
||||
this.stayTime * (this.ticks ? 1 : 20),
|
||||
this.fadeOutTime * (this.ticks ? 1 : 20));
|
||||
if ((this.fadeInTime != -1) && (this.fadeOutTime != -1) && (this.stayTime != -1)) {
|
||||
sendPacket.invoke(connection, packet);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updateTitle(Player player) {
|
||||
if (TitleManager_1_11.packetTitle != null) {
|
||||
try {
|
||||
Object handle = getHandle(player);
|
||||
Object connection = getField(handle.getClass(), "playerConnection").get(handle);
|
||||
Object[] actions = TitleManager_1_11.packetActions.getEnumConstants();
|
||||
Method sendPacket = getMethod(connection.getClass(), "sendPacket");
|
||||
Object serialized = nmsChatSerializer.getConstructor(String.class).newInstance(
|
||||
titleColor + ChatColor.translateAlternateColorCodes('&', this.title));
|
||||
Object packet = TitleManager_1_11.packetTitle.getConstructor(
|
||||
new Class[] {TitleManager_1_11.packetActions, chatBaseComponent})
|
||||
.newInstance(actions[0], serialized);
|
||||
sendPacket.invoke(connection, packet);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updateSubtitle(Player player) {
|
||||
if (TitleManager_1_11.packetTitle != null) {
|
||||
try {
|
||||
Object handle = getHandle(player);
|
||||
Object connection = playerConnection.get(handle);
|
||||
Object[] actions = TitleManager_1_11.packetActions.getEnumConstants();
|
||||
Object serialized = nmsChatSerializer.getConstructor(String.class).newInstance(
|
||||
subtitleColor + ChatColor.translateAlternateColorCodes('&', this.subtitle));
|
||||
Object packet = TitleManager_1_11.packetTitle.getConstructor(
|
||||
new Class[] {TitleManager_1_11.packetActions, chatBaseComponent})
|
||||
.newInstance(actions[1], serialized);
|
||||
sendPacket.invoke(connection, packet);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcast the title to all players
|
||||
*/
|
||||
public void broadcast() {
|
||||
for (Player p : Bukkit.getOnlinePlayers()) {
|
||||
send(p);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the title
|
||||
*
|
||||
* @param player Player
|
||||
*/
|
||||
public void clearTitle(Player player) {
|
||||
try {
|
||||
// Send timings first
|
||||
Object handle = getHandle(player);
|
||||
Object connection = playerConnection.get(handle);
|
||||
Object[] actions = packetActions.getEnumConstants();
|
||||
Object packet = packetTitle.getConstructor(packetActions, chatBaseComponent)
|
||||
.newInstance(actions[4], null);
|
||||
sendPacket.invoke(connection, packet);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the title settings
|
||||
*
|
||||
* @param player Player
|
||||
*/
|
||||
public void resetTitle(Player player) {
|
||||
try {
|
||||
// Send timings first
|
||||
Object handle = getHandle(player);
|
||||
Object connection = playerConnection.get(handle);
|
||||
Object[] actions = packetActions.getEnumConstants();
|
||||
Object packet = packetTitle.getConstructor(packetActions, chatBaseComponent)
|
||||
.newInstance(actions[5], null);
|
||||
sendPacket.invoke(connection, packet);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private Class<?> getPrimitiveType(Class<?> clazz) {
|
||||
return CORRESPONDING_TYPES.containsKey(clazz) ? CORRESPONDING_TYPES.get(clazz) : clazz;
|
||||
}
|
||||
|
||||
private Class<?>[] toPrimitiveTypeArray(Class<?>[] classes) {
|
||||
int a = classes != null ? classes.length : 0;
|
||||
Class<?>[] types = new Class<?>[a];
|
||||
for (int i = 0; i < a; i++)
|
||||
types[i] = getPrimitiveType(classes[i]);
|
||||
return types;
|
||||
}
|
||||
|
||||
private Object getHandle(Player player) {
|
||||
try {
|
||||
return methodPlayerGetHandle.invoke(player);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Method getMethod(String name, Class<?> clazz, Class<?>... paramTypes) {
|
||||
Class<?>[] t = toPrimitiveTypeArray(paramTypes);
|
||||
for (Method m : clazz.getMethods()) {
|
||||
Class<?>[] types = toPrimitiveTypeArray(m.getParameterTypes());
|
||||
if (m.getName().equals(name) && equalsTypeArray(types, t))
|
||||
return m;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getVersion() {
|
||||
String name = Bukkit.getServer().getClass().getPackage().getName();
|
||||
String version = name.substring(name.lastIndexOf('.') + 1) + ".";
|
||||
return version;
|
||||
}
|
||||
|
||||
private Class<?> getNMSClass(String className) {
|
||||
String fullName = "net.minecraft.server." + getVersion() + className;
|
||||
Class<?> clazz = null;
|
||||
try {
|
||||
clazz = Class.forName(fullName);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return clazz;
|
||||
}
|
||||
|
||||
private Class<?> getOBCClass(String className) {
|
||||
String fullName = "org.bukkit.craftbukkit." + getVersion() + className;
|
||||
Class<?> clazz = null;
|
||||
try {
|
||||
clazz = Class.forName(fullName);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return clazz;
|
||||
}
|
||||
|
||||
private Field getField(Class<?> clazz, String name) {
|
||||
try {
|
||||
Field field = clazz.getDeclaredField(name);
|
||||
field.setAccessible(true);
|
||||
return field;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Method getMethod(Class<?> clazz, String name, Class<?>... args) {
|
||||
for (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(Class<?>[] l1, 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;
|
||||
}
|
||||
|
||||
public ChatColor getTitleColor() {
|
||||
return titleColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the title color
|
||||
*
|
||||
* @param color Chat color
|
||||
*/
|
||||
public void setTitleColor(ChatColor color) {
|
||||
this.titleColor = color;
|
||||
}
|
||||
|
||||
public ChatColor getSubtitleColor() {
|
||||
return subtitleColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the subtitle color
|
||||
*
|
||||
* @param color Chat color
|
||||
*/
|
||||
public void setSubtitleColor(ChatColor color) {
|
||||
this.subtitleColor = color;
|
||||
}
|
||||
|
||||
public int getFadeInTime() {
|
||||
return fadeInTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set title fade in time
|
||||
*
|
||||
* @param time Time
|
||||
*/
|
||||
public void setFadeInTime(int time) {
|
||||
this.fadeInTime = time;
|
||||
}
|
||||
|
||||
public int getFadeOutTime() {
|
||||
return fadeOutTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set title fade out time
|
||||
*
|
||||
* @param time Time
|
||||
*/
|
||||
public void setFadeOutTime(int time) {
|
||||
this.fadeOutTime = time;
|
||||
}
|
||||
|
||||
public int getStayTime() {
|
||||
return stayTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set title stay time
|
||||
*
|
||||
* @param time Time
|
||||
*/
|
||||
public void setStayTime(int time) {
|
||||
this.stayTime = time;
|
||||
}
|
||||
|
||||
public boolean isTicks() {
|
||||
return ticks;
|
||||
}
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
package com.plotsquared.bukkit.util;
|
||||
|
||||
import com.intellectualcrafters.plot.config.C;
|
||||
import com.intellectualcrafters.plot.config.Settings;
|
||||
import com.intellectualcrafters.plot.object.ConsolePlayer;
|
||||
import com.intellectualcrafters.plot.object.PlotMessage;
|
||||
import com.intellectualcrafters.plot.object.PlotPlayer;
|
||||
import com.intellectualcrafters.plot.util.ChatManager;
|
||||
import com.plotsquared.bukkit.chat.FancyMessage;
|
||||
import com.plotsquared.bukkit.object.BukkitPlayer;
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class BukkitChatManager extends ChatManager<FancyMessage> {
|
||||
|
||||
@Override public FancyMessage builder() {
|
||||
return new FancyMessage("");
|
||||
}
|
||||
|
||||
@Override public void color(PlotMessage message, String color) {
|
||||
message.$(this).color(ChatColor.getByChar(C.color(color).substring(1)));
|
||||
}
|
||||
|
||||
@Override public void tooltip(PlotMessage message, PlotMessage... tooltips) {
|
||||
List<FancyMessage> lines = new ArrayList<>();
|
||||
for (PlotMessage tooltip : tooltips) {
|
||||
lines.add(tooltip.$(this));
|
||||
}
|
||||
message.$(this).formattedTooltip(lines);
|
||||
}
|
||||
|
||||
@Override public void command(PlotMessage message, String command) {
|
||||
message.$(this).command(command);
|
||||
}
|
||||
|
||||
@Override public void text(PlotMessage message, String text) {
|
||||
message.$(this).then(ChatColor.stripColor(text));
|
||||
}
|
||||
|
||||
@Override public void send(PlotMessage plotMessage, PlotPlayer player) {
|
||||
if (player instanceof ConsolePlayer || !Settings.Chat.INTERACTIVE) {
|
||||
player.sendMessage(plotMessage.$(this).toOldMessageFormat());
|
||||
} else {
|
||||
plotMessage.$(this).send(((BukkitPlayer) player).player);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void suggest(PlotMessage plotMessage, String command) {
|
||||
plotMessage.$(this).suggest(command);
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,55 +0,0 @@
|
||||
package com.plotsquared.bukkit.util;
|
||||
|
||||
import com.intellectualcrafters.plot.commands.MainCommand;
|
||||
import com.intellectualcrafters.plot.object.ConsolePlayer;
|
||||
import com.intellectualcrafters.plot.object.PlotPlayer;
|
||||
import com.plotsquared.bukkit.commands.DebugUUID;
|
||||
import org.bukkit.command.*;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class BukkitCommand implements CommandExecutor, TabCompleter {
|
||||
|
||||
public BukkitCommand() {
|
||||
new DebugUUID();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender commandSender, Command command, String commandLabel,
|
||||
String[] args) {
|
||||
if (commandSender instanceof Player) {
|
||||
return MainCommand.onCommand(BukkitUtil.getPlayer((Player) commandSender), args);
|
||||
}
|
||||
if (commandSender instanceof ConsoleCommandSender
|
||||
|| commandSender instanceof ProxiedCommandSender
|
||||
|| commandSender instanceof RemoteConsoleCommandSender) {
|
||||
return MainCommand.onCommand(ConsolePlayer.getConsole(), args);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(CommandSender commandSender, Command command, String s,
|
||||
String[] args) {
|
||||
if (!(commandSender instanceof Player)) {
|
||||
return null;
|
||||
}
|
||||
PlotPlayer player = BukkitUtil.getPlayer((Player) commandSender);
|
||||
if (args.length == 0) {
|
||||
return Collections.singletonList("plots");
|
||||
}
|
||||
Collection objects = MainCommand.getInstance().tab(player, args, s.endsWith(" "));
|
||||
if (objects == null) {
|
||||
return null;
|
||||
}
|
||||
List<String> result = new ArrayList<>();
|
||||
for (Object o : objects) {
|
||||
result.add(o.toString());
|
||||
}
|
||||
return result.isEmpty() ? null : result;
|
||||
}
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
package com.plotsquared.bukkit.util;
|
||||
|
||||
import com.intellectualcrafters.plot.object.OfflinePlotPlayer;
|
||||
import com.intellectualcrafters.plot.object.PlotPlayer;
|
||||
import com.intellectualcrafters.plot.util.EconHandler;
|
||||
import com.plotsquared.bukkit.object.BukkitOfflinePlayer;
|
||||
import com.plotsquared.bukkit.object.BukkitPlayer;
|
||||
import net.milkbowl.vault.economy.Economy;
|
||||
import net.milkbowl.vault.permission.Permission;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
|
||||
public class BukkitEconHandler extends EconHandler {
|
||||
|
||||
private Economy econ;
|
||||
private Permission perms;
|
||||
|
||||
public boolean init() {
|
||||
if (this.econ == null || this.perms == null) {
|
||||
setupPermissions();
|
||||
setupEconomy();
|
||||
}
|
||||
return this.econ != null && this.perms != null;
|
||||
}
|
||||
|
||||
private boolean setupPermissions() {
|
||||
RegisteredServiceProvider<Permission> permissionProvider =
|
||||
Bukkit.getServer().getServicesManager().getRegistration(Permission.class);
|
||||
if (permissionProvider != null) {
|
||||
this.perms = permissionProvider.getProvider();
|
||||
}
|
||||
return this.perms != null;
|
||||
}
|
||||
|
||||
private boolean setupEconomy() {
|
||||
if (Bukkit.getServer().getPluginManager().getPlugin("Vault") == null) {
|
||||
return false;
|
||||
}
|
||||
RegisteredServiceProvider<Economy> economyProvider =
|
||||
Bukkit.getServer().getServicesManager().getRegistration(Economy.class);
|
||||
if (economyProvider != null) {
|
||||
this.econ = economyProvider.getProvider();
|
||||
}
|
||||
return this.econ != null;
|
||||
}
|
||||
|
||||
@Override public double getMoney(PlotPlayer player) {
|
||||
double bal = super.getMoney(player);
|
||||
if (Double.isNaN(bal)) {
|
||||
return this.econ.getBalance(((BukkitPlayer) player).player);
|
||||
}
|
||||
return bal;
|
||||
}
|
||||
|
||||
@Override public void withdrawMoney(PlotPlayer player, double amount) {
|
||||
this.econ.withdrawPlayer(((BukkitPlayer) player).player, amount);
|
||||
}
|
||||
|
||||
@Override public void depositMoney(PlotPlayer player, double amount) {
|
||||
this.econ.depositPlayer(((BukkitPlayer) player).player, amount);
|
||||
}
|
||||
|
||||
@Override public void depositMoney(OfflinePlotPlayer player, double amount) {
|
||||
this.econ.depositPlayer(((BukkitOfflinePlayer) player).player, amount);
|
||||
}
|
||||
|
||||
@Override public boolean hasPermission(String world, String player, String perm) {
|
||||
return this.perms.playerHas(world, Bukkit.getOfflinePlayer(player), perm);
|
||||
}
|
||||
|
||||
@Override public double getBalance(PlotPlayer player) {
|
||||
return this.econ.getBalance(player.getName());
|
||||
}
|
||||
|
||||
public void setPermission(String world, String player, String perm, boolean value) {
|
||||
if (value) {
|
||||
this.perms.playerAdd(world, player, perm);
|
||||
} else {
|
||||
this.perms.playerRemove(world, player, perm);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
package com.plotsquared.bukkit.util;
|
||||
|
||||
import com.intellectualcrafters.plot.flag.Flag;
|
||||
import com.intellectualcrafters.plot.object.*;
|
||||
import com.intellectualcrafters.plot.util.EventUtil;
|
||||
import com.plotsquared.bukkit.events.*;
|
||||
import com.plotsquared.bukkit.object.BukkitPlayer;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.UUID;
|
||||
|
||||
public class BukkitEventUtil extends EventUtil {
|
||||
|
||||
public Player getPlayer(PlotPlayer player) {
|
||||
if (player instanceof BukkitPlayer) {
|
||||
return ((BukkitPlayer) player).player;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean callEvent(Event event) {
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
return !(event instanceof Cancellable) || !((Cancellable) event).isCancelled();
|
||||
}
|
||||
|
||||
@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 callComponentSet(Plot plot, String component) {
|
||||
return callEvent(new PlotComponentSetEvent(plot, component));
|
||||
}
|
||||
|
||||
@Override public boolean callClear(Plot plot) {
|
||||
return callEvent(new PlotClearEvent(plot));
|
||||
}
|
||||
|
||||
@Override public void callDelete(Plot plot) {
|
||||
callEvent(new PlotDeleteEvent(plot));
|
||||
}
|
||||
|
||||
@Override public boolean callFlagAdd(Flag flag, Plot plot) {
|
||||
return callEvent(new PlotFlagAddEvent(flag, plot));
|
||||
}
|
||||
|
||||
@Override public boolean callFlagRemove(Flag<?> flag, Plot plot, Object value) {
|
||||
return callEvent(new PlotFlagRemoveEvent(flag, plot));
|
||||
}
|
||||
|
||||
@Override public boolean callMerge(Plot plot, ArrayList<PlotId> plots) {
|
||||
return callEvent(new PlotMergeEvent(BukkitUtil.getWorld(plot.getWorldName()), plot, plots));
|
||||
}
|
||||
|
||||
@Override public boolean callUnlink(PlotArea area, ArrayList<PlotId> plots) {
|
||||
return callEvent(new PlotUnlinkEvent(BukkitUtil.getWorld(area.worldname), area, 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 PlayerPlotTrustedEvent(getPlayer(initiator), plot, player, added));
|
||||
}
|
||||
|
||||
@Override public void callMember(PlotPlayer initiator, Plot plot, UUID player, boolean added) {
|
||||
callEvent(new PlayerPlotHelperEvent(getPlayer(initiator), plot, player, added));
|
||||
}
|
||||
|
||||
@Override public boolean callFlagRemove(Flag flag, Object object, PlotCluster cluster) {
|
||||
return callEvent(new ClusterFlagRemoveEvent(flag, cluster));
|
||||
}
|
||||
|
||||
@Override public Rating callRating(PlotPlayer player, Plot plot, Rating rating) {
|
||||
PlotRateEvent event = new PlotRateEvent(player, rating, plot);
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
return event.getRating();
|
||||
}
|
||||
|
||||
}
|
@ -1,279 +0,0 @@
|
||||
package com.plotsquared.bukkit.util;
|
||||
|
||||
import com.intellectualcrafters.plot.generator.HybridUtils;
|
||||
import com.intellectualcrafters.plot.object.Location;
|
||||
import com.intellectualcrafters.plot.object.PlotBlock;
|
||||
import com.intellectualcrafters.plot.object.RegionWrapper;
|
||||
import com.intellectualcrafters.plot.object.RunnableVal;
|
||||
import com.intellectualcrafters.plot.util.ChunkManager;
|
||||
import com.intellectualcrafters.plot.util.MainUtil;
|
||||
import com.intellectualcrafters.plot.util.MathMan;
|
||||
import com.intellectualcrafters.plot.util.TaskManager;
|
||||
import com.intellectualcrafters.plot.util.block.GlobalBlockQueue;
|
||||
import com.intellectualcrafters.plot.util.block.LocalBlockQueue;
|
||||
import com.intellectualcrafters.plot.util.expiry.PlotAnalysis;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.bukkit.generator.ChunkGenerator.BiomeGrid;
|
||||
import org.bukkit.material.Directional;
|
||||
import org.bukkit.material.MaterialData;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Random;
|
||||
|
||||
public class BukkitHybridUtils extends HybridUtils {
|
||||
|
||||
@Override public void analyzeRegion(final String world, final RegionWrapper region,
|
||||
final RunnableVal<PlotAnalysis> whenDone) {
|
||||
// int diff, int variety, int vertices, int rotation, int height_sd
|
||||
/*
|
||||
* diff: compare to base by looping through all blocks
|
||||
* variety: add to HashSet for each PlotBlock
|
||||
* height_sd: loop over all blocks and get top block
|
||||
*
|
||||
* vertices: store air map and compare with neighbours
|
||||
* for each block check the adjacent
|
||||
* - Store all blocks then go through in second loop
|
||||
* - recheck each block
|
||||
*
|
||||
*/
|
||||
TaskManager.runTaskAsync(new Runnable() {
|
||||
@Override public void run() {
|
||||
final LocalBlockQueue queue = GlobalBlockQueue.IMP.getNewQueue(world, false);
|
||||
final World worldObj = Bukkit.getWorld(world);
|
||||
final ChunkGenerator gen = worldObj.getGenerator();
|
||||
if (gen == null) {
|
||||
return;
|
||||
}
|
||||
final BiomeGrid nullBiomeGrid = new BiomeGrid() {
|
||||
@Override public void setBiome(int a, int b, Biome c) {
|
||||
}
|
||||
|
||||
@Override public Biome getBiome(int a, int b) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
final Location bot = new Location(world, region.minX, region.minY, region.minZ);
|
||||
final Location top = new Location(world, region.maxX, region.maxY, region.maxZ);
|
||||
|
||||
final int bx = bot.getX();
|
||||
final int bz = bot.getZ();
|
||||
final int tx = top.getX();
|
||||
final int tz = top.getZ();
|
||||
final int cbx = bx >> 4;
|
||||
final int cbz = bz >> 4;
|
||||
final int ctx = tx >> 4;
|
||||
final int ctz = tz >> 4;
|
||||
final Random r = new Random();
|
||||
MainUtil.initCache();
|
||||
final int width = tx - bx + 1;
|
||||
final int length = tz - bz + 1;
|
||||
|
||||
System.gc();
|
||||
System.gc();
|
||||
final short[][][] oldBlocks = new short[256][width][length];
|
||||
final short[][][] newBlocks = new short[256][width][length];
|
||||
|
||||
final Runnable run = new Runnable() {
|
||||
@Override public void run() {
|
||||
ChunkManager.chunkTask(bot, top, new RunnableVal<int[]>() {
|
||||
@Override public void run(int[] value) {
|
||||
// [chunkx, chunkz, pos1x, pos1z, pos2x, pos2z, isedge]
|
||||
int X = value[0];
|
||||
int Z = value[1];
|
||||
short[][] result =
|
||||
gen.generateExtBlockSections(worldObj, r, X, Z, nullBiomeGrid);
|
||||
int xb = (X << 4) - bx;
|
||||
int zb = (Z << 4) - bz;
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
if (result[i] == null) {
|
||||
for (int j = 0; j < 4096; j++) {
|
||||
int x = MainUtil.x_loc[i][j] + xb;
|
||||
if (x < 0 || x >= width) {
|
||||
continue;
|
||||
}
|
||||
int z = MainUtil.z_loc[i][j] + zb;
|
||||
if (z < 0 || z >= length) {
|
||||
continue;
|
||||
}
|
||||
int y = MainUtil.y_loc[i][j];
|
||||
oldBlocks[y][x][z] = 0;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
for (int j = 0; j < result[i].length; j++) {
|
||||
int x = MainUtil.x_loc[i][j] + xb;
|
||||
if (x < 0 || x >= width) {
|
||||
continue;
|
||||
}
|
||||
int z = MainUtil.z_loc[i][j] + zb;
|
||||
if (z < 0 || z >= length) {
|
||||
continue;
|
||||
}
|
||||
int y = MainUtil.y_loc[i][j];
|
||||
oldBlocks[y][x][z] = result[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}, new Runnable() {
|
||||
@Override public void run() {
|
||||
TaskManager.runTaskAsync(new Runnable() {
|
||||
@Override public void run() {
|
||||
int size = width * length;
|
||||
int[] changes = new int[size];
|
||||
int[] faces = new int[size];
|
||||
int[] data = new int[size];
|
||||
int[] air = new int[size];
|
||||
int[] variety = new int[size];
|
||||
int i = 0;
|
||||
for (int x = 0; x < width; x++) {
|
||||
for (int z = 0; z < length; z++) {
|
||||
HashSet<Short> types = new HashSet<>();
|
||||
for (int y = 0; y < 256; y++) {
|
||||
short old = oldBlocks[y][x][z];
|
||||
short now = newBlocks[y][x][z];
|
||||
if (old != now) {
|
||||
changes[i]++;
|
||||
}
|
||||
if (now == 0) {
|
||||
air[i]++;
|
||||
} else {
|
||||
// check vertices
|
||||
// modifications_adjacent
|
||||
if (x > 0 && z > 0 && y > 0 && x < width - 1
|
||||
&& z < length - 1 && y < 255) {
|
||||
if (newBlocks[y - 1][x][z] == 0) {
|
||||
faces[i]++;
|
||||
}
|
||||
if (newBlocks[y][x - 1][z] == 0) {
|
||||
faces[i]++;
|
||||
}
|
||||
if (newBlocks[y][x][z - 1] == 0) {
|
||||
faces[i]++;
|
||||
}
|
||||
if (newBlocks[y + 1][x][z] == 0) {
|
||||
faces[i]++;
|
||||
}
|
||||
if (newBlocks[y][x + 1][z] == 0) {
|
||||
faces[i]++;
|
||||
}
|
||||
if (newBlocks[y][x][z + 1] == 0) {
|
||||
faces[i]++;
|
||||
}
|
||||
}
|
||||
|
||||
Material material =
|
||||
Material.getMaterial(now);
|
||||
if (material != null) {
|
||||
Class<? extends MaterialData> md =
|
||||
material.getData();
|
||||
if (md.equals(Directional.class)) {
|
||||
data[i] += 8;
|
||||
} else if (!md
|
||||
.equals(MaterialData.class)) {
|
||||
data[i]++;
|
||||
}
|
||||
}
|
||||
types.add(now);
|
||||
}
|
||||
}
|
||||
variety[i] = types.size();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
// analyze plot
|
||||
// put in analysis obj
|
||||
|
||||
// run whenDone
|
||||
PlotAnalysis analysis = new PlotAnalysis();
|
||||
analysis.changes = (int) (MathMan.getMean(changes) * 100);
|
||||
analysis.faces = (int) (MathMan.getMean(faces) * 100);
|
||||
analysis.data = (int) (MathMan.getMean(data) * 100);
|
||||
analysis.air = (int) (MathMan.getMean(air) * 100);
|
||||
analysis.variety = (int) (MathMan.getMean(variety) * 100);
|
||||
|
||||
analysis.changes_sd =
|
||||
(int) MathMan.getSD(changes, analysis.changes);
|
||||
analysis.faces_sd =
|
||||
(int) MathMan.getSD(faces, analysis.faces);
|
||||
analysis.data_sd = (int) MathMan.getSD(data, analysis.data);
|
||||
analysis.air_sd = (int) MathMan.getSD(air, analysis.air);
|
||||
analysis.variety_sd =
|
||||
(int) MathMan.getSD(variety, analysis.variety);
|
||||
System.gc();
|
||||
System.gc();
|
||||
whenDone.value = analysis;
|
||||
whenDone.run();
|
||||
}
|
||||
});
|
||||
}
|
||||
}, 5);
|
||||
|
||||
}
|
||||
};
|
||||
System.gc();
|
||||
MainUtil.initCache();
|
||||
ChunkManager.chunkTask(bot, top, new RunnableVal<int[]>() {
|
||||
|
||||
@Override public void run(int[] value) {
|
||||
int X = value[0];
|
||||
int Z = value[1];
|
||||
worldObj.loadChunk(X, Z);
|
||||
int minX;
|
||||
if (X == cbx) {
|
||||
minX = bx & 15;
|
||||
} else {
|
||||
minX = 0;
|
||||
}
|
||||
int minZ;
|
||||
if (Z == cbz) {
|
||||
minZ = bz & 15;
|
||||
} else {
|
||||
minZ = 0;
|
||||
}
|
||||
int maxX;
|
||||
if (X == ctx) {
|
||||
maxX = tx & 15;
|
||||
} else {
|
||||
maxX = 16;
|
||||
}
|
||||
int maxZ;
|
||||
if (Z == ctz) {
|
||||
maxZ = tz & 15;
|
||||
} else {
|
||||
maxZ = 16;
|
||||
}
|
||||
|
||||
int cbx = X << 4;
|
||||
int cbz = Z << 4;
|
||||
|
||||
int xb = cbx - bx;
|
||||
int zb = cbz - bz;
|
||||
for (int x = minX; x <= maxX; x++) {
|
||||
int xx = cbx + x;
|
||||
for (int z = minZ; z <= maxZ; z++) {
|
||||
int zz = cbz + z;
|
||||
for (int y = 0; y < 256; y++) {
|
||||
PlotBlock block = queue.getBlock(xx, y, zz);
|
||||
int xr = xb + x;
|
||||
int zr = zb + z;
|
||||
newBlocks[y][xr][zr] = block.id;
|
||||
}
|
||||
}
|
||||
}
|
||||
worldObj.unloadChunkRequest(X, Z, true);
|
||||
}
|
||||
}, new Runnable() {
|
||||
@Override public void run() {
|
||||
TaskManager.runTaskAsync(run);
|
||||
}
|
||||
}, 5);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -1,122 +0,0 @@
|
||||
package com.plotsquared.bukkit.util;
|
||||
|
||||
import com.intellectualcrafters.plot.object.PlotInventory;
|
||||
import com.intellectualcrafters.plot.object.PlotItemStack;
|
||||
import com.intellectualcrafters.plot.object.PlotPlayer;
|
||||
import com.intellectualcrafters.plot.util.InventoryUtil;
|
||||
import com.plotsquared.bukkit.object.BukkitPlayer;
|
||||
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 java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class BukkitInventoryUtil extends InventoryUtil {
|
||||
|
||||
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 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);
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
@ -1,305 +0,0 @@
|
||||
package com.plotsquared.bukkit.util;
|
||||
|
||||
import com.intellectualcrafters.jnbt.*;
|
||||
import com.intellectualcrafters.plot.object.ChunkLoc;
|
||||
import com.intellectualcrafters.plot.object.Location;
|
||||
import com.intellectualcrafters.plot.object.RegionWrapper;
|
||||
import com.intellectualcrafters.plot.object.RunnableVal;
|
||||
import com.intellectualcrafters.plot.util.MainUtil;
|
||||
import com.intellectualcrafters.plot.util.SchematicHandler;
|
||||
import com.intellectualcrafters.plot.util.TaskManager;
|
||||
import com.intellectualcrafters.plot.util.block.LocalBlockQueue;
|
||||
import com.plotsquared.bukkit.object.schematic.StateWrapper;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Schematic Handler.
|
||||
*/
|
||||
public class BukkitSchematicHandler extends SchematicHandler {
|
||||
|
||||
@Override public void getCompoundTag(final String world, final Set<RegionWrapper> regions,
|
||||
final RunnableVal<CompoundTag> whenDone) {
|
||||
// async
|
||||
TaskManager.runTaskAsync(new Runnable() {
|
||||
@Override public void run() {
|
||||
// Main positions
|
||||
Location[] corners = MainUtil.getCorners(world, regions);
|
||||
final Location bot = corners[0];
|
||||
Location top = corners[1];
|
||||
|
||||
final int width = top.getX() - bot.getX() + 1;
|
||||
int height = top.getY() - bot.getY() + 1;
|
||||
final int length = top.getZ() - bot.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<CompoundTag> tileEntities = new ArrayList<>();
|
||||
final byte[] blocks = new byte[width * height * length];
|
||||
final byte[] blockData = new byte[width * height * length];
|
||||
// Queue
|
||||
final ArrayDeque<RegionWrapper> queue = new ArrayDeque<>(regions);
|
||||
TaskManager.runTask(new Runnable() {
|
||||
@Override public void run() {
|
||||
if (queue.isEmpty()) {
|
||||
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();
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
final Runnable regionTask = this;
|
||||
RegionWrapper region = queue.poll();
|
||||
Location pos1 = new Location(world, region.minX, region.minY, region.minZ);
|
||||
Location pos2 = new Location(world, region.maxX, region.maxY, region.maxZ);
|
||||
final int bx = bot.getX();
|
||||
final int bz = bot.getZ();
|
||||
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();
|
||||
// Generate list of chunks
|
||||
final ArrayList<ChunkLoc> chunks = new ArrayList<>();
|
||||
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.isEmpty()
|
||||
&& 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 - bz;
|
||||
int i2 = i1 + rz * width;
|
||||
for (int x = xxb; x <= xxt; x++) {
|
||||
int rx = x - bx;
|
||||
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 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 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<>(
|
||||
rawTag.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 (type > 255) {
|
||||
// if (addBlocks == null) {
|
||||
// addBlocks = new byte[(blocks.length >> 1) + 1];
|
||||
// }
|
||||
// addBlocks[index >> 1] = (byte) (((index & 1) == 0) ?
|
||||
// (addBlocks[index >> 1] & 0xF0) | ((type >> 8) & 0xF) : (addBlocks[index >> 1] & 0xF) | (((type
|
||||
// >> 8) & 0xF) << 4));
|
||||
// }
|
||||
blocks[index] = (byte) id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!chunks.isEmpty()) {
|
||||
TaskManager.runTaskLater(this, 1);
|
||||
} else {
|
||||
regionTask.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean restoreTile(LocalBlockQueue queue, CompoundTag ct, int x, int y, int z) {
|
||||
return new StateWrapper(ct).restoreTag(queue.getWorld(), x, y, z);
|
||||
}
|
||||
}
|
@ -1,249 +0,0 @@
|
||||
package com.plotsquared.bukkit.util;
|
||||
|
||||
import com.intellectualcrafters.configuration.ConfigurationSection;
|
||||
import com.intellectualcrafters.configuration.file.YamlConfiguration;
|
||||
import com.intellectualcrafters.plot.PS;
|
||||
import com.intellectualcrafters.plot.config.ConfigurationNode;
|
||||
import com.intellectualcrafters.plot.generator.GeneratorWrapper;
|
||||
import com.intellectualcrafters.plot.object.PlotArea;
|
||||
import com.intellectualcrafters.plot.object.SetupObject;
|
||||
import com.intellectualcrafters.plot.util.SetupUtils;
|
||||
import com.plotsquared.bukkit.generator.BukkitPlotGenerator;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.World.Environment;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
|
||||
public class BukkitSetupUtils extends SetupUtils {
|
||||
|
||||
@Override public void updateGenerators() {
|
||||
if (!SetupUtils.generators.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
String testWorld = "CheckingPlotSquaredGenerator";
|
||||
for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
|
||||
try {
|
||||
if (plugin.isEnabled()) {
|
||||
ChunkGenerator generator = plugin.getDefaultWorldGenerator(testWorld, "");
|
||||
if (generator != null) {
|
||||
PS.get().removePlotAreas(testWorld);
|
||||
String name = plugin.getDescription().getName();
|
||||
GeneratorWrapper<?> wrapped;
|
||||
if (generator instanceof GeneratorWrapper<?>) {
|
||||
wrapped = (GeneratorWrapper<?>) generator;
|
||||
} else {
|
||||
wrapped = new BukkitPlotGenerator(testWorld, generator);
|
||||
}
|
||||
SetupUtils.generators.put(name, wrapped);
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) { // Recover from third party generator error
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void unload(String worldName, boolean save) {
|
||||
World world = Bukkit.getWorld(worldName);
|
||||
if (world == null) {
|
||||
return;
|
||||
}
|
||||
World dw = Bukkit.getWorlds().get(0);
|
||||
for (Player player : world.getPlayers()) {
|
||||
player.teleport(dw.getSpawnLocation());
|
||||
}
|
||||
if (save) {
|
||||
for (Chunk chunk : world.getLoadedChunks()) {
|
||||
chunk.unload(true, false);
|
||||
}
|
||||
} else {
|
||||
for (Chunk chunk : world.getLoadedChunks()) {
|
||||
chunk.unload(false, false);
|
||||
}
|
||||
}
|
||||
Bukkit.unloadWorld(world, false);
|
||||
}
|
||||
|
||||
@Override public String setupWorld(SetupObject object) {
|
||||
SetupUtils.manager.updateGenerators();
|
||||
ConfigurationNode[] steps = object.step == null ? new ConfigurationNode[0] : object.step;
|
||||
String world = object.world;
|
||||
int type = object.type;
|
||||
String worldPath = "worlds." + object.world;
|
||||
switch (type) {
|
||||
case 2: {
|
||||
if (object.id != null) {
|
||||
if (!PS.get().worlds.contains(worldPath)) {
|
||||
PS.get().worlds.createSection(worldPath);
|
||||
}
|
||||
ConfigurationSection worldSection =
|
||||
PS.get().worlds.getConfigurationSection(worldPath);
|
||||
String areaName = object.id + "-" + object.min + "-" + object.max;
|
||||
String areaPath = "areas." + areaName;
|
||||
if (!worldSection.contains(areaPath)) {
|
||||
worldSection.createSection(areaPath);
|
||||
}
|
||||
ConfigurationSection areaSection =
|
||||
worldSection.getConfigurationSection(areaPath);
|
||||
HashMap<String, Object> options = new HashMap<>();
|
||||
for (ConfigurationNode step : steps) {
|
||||
options.put(step.getConstant(), step.getValue());
|
||||
}
|
||||
options.put("generator.type", object.type);
|
||||
options.put("generator.terrain", object.terrain);
|
||||
options.put("generator.plugin", object.plotManager);
|
||||
if (object.setupGenerator != null && !object.setupGenerator
|
||||
.equals(object.plotManager)) {
|
||||
options.put("generator.init", object.setupGenerator);
|
||||
}
|
||||
for (Entry<String, Object> entry : options.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
Object value = entry.getValue();
|
||||
if (worldSection.contains(key)) {
|
||||
Object current = worldSection.get(key);
|
||||
if (!Objects.equals(value, current)) {
|
||||
areaSection.set(key, value);
|
||||
}
|
||||
} else {
|
||||
worldSection.set(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
GeneratorWrapper<?> gen = SetupUtils.generators.get(object.setupGenerator);
|
||||
if (gen != null && gen.isFull()) {
|
||||
object.setupGenerator = null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
if (!PS.get().worlds.contains(worldPath)) {
|
||||
PS.get().worlds.createSection(worldPath);
|
||||
}
|
||||
ConfigurationSection worldSection =
|
||||
PS.get().worlds.getConfigurationSection(worldPath);
|
||||
for (ConfigurationNode step : steps) {
|
||||
worldSection.set(step.getConstant(), step.getValue());
|
||||
}
|
||||
PS.get().worlds.set("worlds." + world + ".generator.type", object.type);
|
||||
PS.get().worlds.set("worlds." + world + ".generator.terrain", object.terrain);
|
||||
PS.get().worlds.set("worlds." + world + ".generator.plugin", object.plotManager);
|
||||
if (object.setupGenerator != null && !object.setupGenerator
|
||||
.equals(object.plotManager)) {
|
||||
PS.get().worlds
|
||||
.set("worlds." + world + ".generator.init", object.setupGenerator);
|
||||
}
|
||||
GeneratorWrapper<?> gen = SetupUtils.generators.get(object.setupGenerator);
|
||||
if (gen != null && gen.isFull()) {
|
||||
object.setupGenerator = null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0: {
|
||||
if (steps.length != 0) {
|
||||
if (!PS.get().worlds.contains(worldPath)) {
|
||||
PS.get().worlds.createSection(worldPath);
|
||||
}
|
||||
ConfigurationSection worldSection =
|
||||
PS.get().worlds.getConfigurationSection(worldPath);
|
||||
for (ConfigurationNode step : steps) {
|
||||
worldSection.set(step.getConstant(), step.getValue());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
try {
|
||||
PS.get().worlds.save(PS.get().worldsFile);
|
||||
} catch (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);
|
||||
setGenerator(world, object.setupGenerator);
|
||||
if (Bukkit.getWorld(world) != null) {
|
||||
return world;
|
||||
}
|
||||
}
|
||||
if (Bukkit.getPluginManager().getPlugin("MultiWorld") != null && Bukkit
|
||||
.getPluginManager().getPlugin("MultiWorld").isEnabled()) {
|
||||
Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(),
|
||||
"mw create " + world + " plugin:" + object.setupGenerator);
|
||||
setGenerator(world, object.setupGenerator);
|
||||
if (Bukkit.getWorld(world) != null) {
|
||||
return world;
|
||||
}
|
||||
}
|
||||
WorldCreator wc = new WorldCreator(object.world);
|
||||
wc.generator(object.setupGenerator);
|
||||
wc.environment(Environment.NORMAL);
|
||||
wc.type(WorldType.FLAT);
|
||||
Bukkit.createWorld(wc);
|
||||
setGenerator(world, object.setupGenerator);
|
||||
} else {
|
||||
if (Bukkit.getPluginManager().getPlugin("Multiverse-Core") != null && Bukkit
|
||||
.getPluginManager().getPlugin("Multiverse-Core").isEnabled()) {
|
||||
Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(),
|
||||
"mv create " + world + " normal");
|
||||
if (Bukkit.getWorld(world) != null) {
|
||||
return world;
|
||||
}
|
||||
}
|
||||
if (Bukkit.getPluginManager().getPlugin("MultiWorld") != null && Bukkit
|
||||
.getPluginManager().getPlugin("MultiWorld").isEnabled()) {
|
||||
Bukkit.getServer()
|
||||
.dispatchCommand(Bukkit.getServer().getConsoleSender(), "mw create " + world);
|
||||
if (Bukkit.getWorld(world) != null) {
|
||||
return world;
|
||||
}
|
||||
}
|
||||
World bw =
|
||||
Bukkit.createWorld(new WorldCreator(object.world).environment(Environment.NORMAL));
|
||||
}
|
||||
return object.world;
|
||||
}
|
||||
|
||||
public void setGenerator(String world, String generator) {
|
||||
if (Bukkit.getWorlds().isEmpty() || !Bukkit.getWorlds().get(0).getName().equals(world)) {
|
||||
return;
|
||||
}
|
||||
File file = new File("bukkit.yml").getAbsoluteFile();
|
||||
YamlConfiguration yml = YamlConfiguration.loadConfiguration(file);
|
||||
yml.set("worlds." + world + ".generator", generator);
|
||||
try {
|
||||
yml.save(file);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override public String getGenerator(PlotArea plotArea) {
|
||||
if (SetupUtils.generators.isEmpty()) {
|
||||
updateGenerators();
|
||||
}
|
||||
World world = Bukkit.getWorld(plotArea.worldname);
|
||||
if (world == null) {
|
||||
return null;
|
||||
}
|
||||
ChunkGenerator generator = world.getGenerator();
|
||||
if (!(generator instanceof BukkitPlotGenerator)) {
|
||||
return null;
|
||||
}
|
||||
for (Entry<String, GeneratorWrapper<?>> entry : SetupUtils.generators.entrySet()) {
|
||||
GeneratorWrapper<?> current = entry.getValue();
|
||||
if (current.equals(generator)) {
|
||||
return entry.getKey();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
package com.plotsquared.bukkit.util;
|
||||
|
||||
import com.intellectualcrafters.plot.util.TaskManager;
|
||||
import com.plotsquared.bukkit.BukkitMain;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
public class BukkitTaskManager extends TaskManager {
|
||||
|
||||
private final BukkitMain bukkitMain;
|
||||
|
||||
public BukkitTaskManager(BukkitMain bukkitMain) {
|
||||
this.bukkitMain = bukkitMain;
|
||||
}
|
||||
|
||||
@Override public int taskRepeat(Runnable runnable, int interval) {
|
||||
return this.bukkitMain.getServer().getScheduler()
|
||||
.scheduleSyncRepeatingTask(this.bukkitMain, runnable, interval, interval);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation") @Override
|
||||
public int taskRepeatAsync(Runnable runnable, int interval) {
|
||||
return this.bukkitMain.getServer().getScheduler()
|
||||
.scheduleAsyncRepeatingTask(this.bukkitMain, runnable, interval, interval);
|
||||
}
|
||||
|
||||
@Override public void taskAsync(Runnable runnable) {
|
||||
this.bukkitMain.getServer().getScheduler().runTaskAsynchronously(this.bukkitMain, runnable)
|
||||
.getTaskId();
|
||||
}
|
||||
|
||||
@Override public void task(Runnable runnable) {
|
||||
this.bukkitMain.getServer().getScheduler().runTask(this.bukkitMain, runnable).getTaskId();
|
||||
}
|
||||
|
||||
@Override public void taskLater(Runnable runnable, int delay) {
|
||||
this.bukkitMain.getServer().getScheduler().runTaskLater(this.bukkitMain, runnable, delay)
|
||||
.getTaskId();
|
||||
}
|
||||
|
||||
@Override public void taskLaterAsync(Runnable runnable, int delay) {
|
||||
this.bukkitMain.getServer().getScheduler()
|
||||
.runTaskLaterAsynchronously(this.bukkitMain, runnable, delay);
|
||||
}
|
||||
|
||||
@Override public void cancelTask(int task) {
|
||||
if (task != -1) {
|
||||
Bukkit.getScheduler().cancelTask(task);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,332 +0,0 @@
|
||||
package com.plotsquared.bukkit.util;
|
||||
|
||||
import com.intellectualcrafters.plot.object.Location;
|
||||
import com.intellectualcrafters.plot.object.PlotBlock;
|
||||
import com.intellectualcrafters.plot.object.PlotPlayer;
|
||||
import com.intellectualcrafters.plot.object.RegionWrapper;
|
||||
import com.intellectualcrafters.plot.object.schematic.PlotItem;
|
||||
import com.intellectualcrafters.plot.util.MathMan;
|
||||
import com.intellectualcrafters.plot.util.StringComparison;
|
||||
import com.intellectualcrafters.plot.util.UUIDHandler;
|
||||
import com.intellectualcrafters.plot.util.WorldUtil;
|
||||
import com.plotsquared.bukkit.object.BukkitPlayer;
|
||||
import org.bukkit.Bukkit;
|
||||
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.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class BukkitUtil extends WorldUtil {
|
||||
|
||||
private static String lastString = null;
|
||||
private static World lastWorld = null;
|
||||
|
||||
private static Player lastPlayer = null;
|
||||
private static PlotPlayer lastPlotPlayer = null;
|
||||
|
||||
public static void removePlayer(String player) {
|
||||
lastPlayer = null;
|
||||
lastPlotPlayer = null;
|
||||
}
|
||||
|
||||
public static PlotPlayer getPlayer(OfflinePlayer op) {
|
||||
if (op.isOnline()) {
|
||||
return getPlayer(op.getPlayer());
|
||||
}
|
||||
Player player = OfflinePlayerUtil.loadPlayer(op);
|
||||
player.loadData();
|
||||
return new BukkitPlayer(player, true);
|
||||
}
|
||||
|
||||
public static PlotPlayer getPlayer(Player player) {
|
||||
if (player == lastPlayer) {
|
||||
return lastPlotPlayer;
|
||||
}
|
||||
String name = player.getName();
|
||||
PlotPlayer plotPlayer = UUIDHandler.getPlayer(name);
|
||||
if (plotPlayer != null) {
|
||||
return plotPlayer;
|
||||
}
|
||||
lastPlotPlayer = new BukkitPlayer(player);
|
||||
UUIDHandler.getPlayers().put(name, lastPlotPlayer);
|
||||
lastPlayer = player;
|
||||
return lastPlotPlayer;
|
||||
}
|
||||
|
||||
public static Location getLocation(org.bukkit.Location location) {
|
||||
return new Location(location.getWorld().getName(), MathMan.roundInt(location.getX()),
|
||||
MathMan.roundInt(location.getY()), MathMan.roundInt(location.getZ()));
|
||||
}
|
||||
|
||||
public static org.bukkit.Location getLocation(Location location) {
|
||||
return new org.bukkit.Location(getWorld(location.getWorld()), location.getX(),
|
||||
location.getY(), location.getZ());
|
||||
}
|
||||
|
||||
public static World getWorld(String string) {
|
||||
return Bukkit.getWorld(string);
|
||||
}
|
||||
|
||||
public static String getWorld(Entity entity) {
|
||||
return entity.getWorld().getName();
|
||||
}
|
||||
|
||||
public static List<Entity> getEntities(String worldName) {
|
||||
World world = getWorld(worldName);
|
||||
return world != null ? world.getEntities() : new ArrayList<Entity>();
|
||||
}
|
||||
|
||||
public static Location getLocation(Entity entity) {
|
||||
org.bukkit.Location location = entity.getLocation();
|
||||
String world = location.getWorld().getName();
|
||||
return new Location(world, location.getBlockX(), location.getBlockY(),
|
||||
location.getBlockZ());
|
||||
}
|
||||
|
||||
public static Location getLocationFull(Entity entity) {
|
||||
org.bukkit.Location location = entity.getLocation();
|
||||
return new Location(location.getWorld().getName(), MathMan.roundInt(location.getX()),
|
||||
MathMan.roundInt(location.getY()), MathMan.roundInt(location.getZ()), location.getYaw(),
|
||||
location.getPitch());
|
||||
}
|
||||
|
||||
@Override public boolean isWorld(String worldName) {
|
||||
return getWorld(worldName) != null;
|
||||
}
|
||||
|
||||
@Override public String getBiome(String world, int x, int z) {
|
||||
return getWorld(world).getBiome(x, z).name();
|
||||
}
|
||||
|
||||
@Override public void setSign(String worldName, int x, int y, int z, String[] lines) {
|
||||
World world = getWorld(worldName);
|
||||
Block block = world.getBlockAt(x, y, z);
|
||||
// block.setType(Material.AIR);
|
||||
Material type = block.getType();
|
||||
if (type != Material.SIGN && type != Material.SIGN_POST) {
|
||||
int data = 2;
|
||||
if (world.getBlockAt(x, y, z + 1).getType().isSolid())
|
||||
data = 2;
|
||||
else if (world.getBlockAt(x + 1, y, z).getType().isSolid())
|
||||
data = 4;
|
||||
else if (world.getBlockAt(x, y, z - 1).getType().isSolid())
|
||||
data = 3;
|
||||
else if (world.getBlockAt(x - 1, y, z).getType().isSolid())
|
||||
data = 5;
|
||||
block.setTypeIdAndData(Material.WALL_SIGN.getId(), (byte) data, false);
|
||||
}
|
||||
BlockState blockstate = block.getState();
|
||||
if (blockstate instanceof Sign) {
|
||||
final Sign sign = (Sign) blockstate;
|
||||
for (int i = 0; i < lines.length; i++) {
|
||||
sign.setLine(i, lines[i]);
|
||||
}
|
||||
sign.update(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public String[] getSign(Location location) {
|
||||
Block block = getWorld(location.getWorld())
|
||||
.getBlockAt(location.getX(), location.getY(), location.getZ());
|
||||
if (block != null) {
|
||||
if (block.getState() instanceof Sign) {
|
||||
Sign sign = (Sign) block.getState();
|
||||
return sign.getLines();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override public Location getSpawn(PlotPlayer player) {
|
||||
return getLocation(((BukkitPlayer) player).player.getBedSpawnLocation());
|
||||
}
|
||||
|
||||
@Override public Location getSpawn(String world) {
|
||||
org.bukkit.Location temp = getWorld(world).getSpawnLocation();
|
||||
return new Location(world, temp.getBlockX(), temp.getBlockY(), temp.getBlockZ(),
|
||||
temp.getYaw(), temp.getPitch());
|
||||
}
|
||||
|
||||
@Override public void setSpawn(Location location) {
|
||||
World world = getWorld(location.getWorld());
|
||||
if (world != null) {
|
||||
world.setSpawnLocation(location.getX(), location.getY(), location.getZ());
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void saveWorld(String worldName) {
|
||||
World world = getWorld(worldName);
|
||||
if (world != null) {
|
||||
world.save();
|
||||
}
|
||||
}
|
||||
|
||||
@Override public int getHighestBlock(String world, int x, int z) {
|
||||
World bukkitWorld = getWorld(world);
|
||||
// Skip top and bottom block
|
||||
int air = 1;
|
||||
for (int y = bukkitWorld.getMaxHeight() - 1; y >= 0; y--) {
|
||||
Block block = bukkitWorld.getBlockAt(x, y, z);
|
||||
if (block != null) {
|
||||
Material type = block.getType();
|
||||
if (type.isSolid()) {
|
||||
if (air > 1)
|
||||
return y;
|
||||
air = 0;
|
||||
} else {
|
||||
switch (type) {
|
||||
case WATER:
|
||||
case LAVA:
|
||||
case STATIONARY_LAVA:
|
||||
case STATIONARY_WATER:
|
||||
return y;
|
||||
}
|
||||
air++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return bukkitWorld.getMaxHeight() - 1;
|
||||
}
|
||||
|
||||
@Override public int getBiomeFromString(String biomeString) {
|
||||
try {
|
||||
Biome biome = Biome.valueOf(biomeString.toUpperCase());
|
||||
return Arrays.asList(Biome.values()).indexOf(biome);
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override public String[] getBiomeList() {
|
||||
Biome[] biomes = Biome.values();
|
||||
String[] list = new String[biomes.length];
|
||||
for (int i = 0; i < biomes.length; i++) {
|
||||
list[i] = biomes[i].name();
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@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 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 ignored) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override public String getClosestMatchingName(PlotBlock block) {
|
||||
try {
|
||||
return Material.getMaterial(block.id).name();
|
||||
} catch (Exception ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override public StringComparison<PlotBlock>.ComparisonResult getClosestBlock(String name) {
|
||||
try {
|
||||
Material material = Material.valueOf(name.toUpperCase());
|
||||
return new StringComparison<PlotBlock>().new ComparisonResult(0,
|
||||
PlotBlock.get((short) material.getId(), (byte) 0));
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
}
|
||||
try {
|
||||
byte data;
|
||||
String[] split = name.split(":");
|
||||
if (split.length == 2) {
|
||||
data = Byte.parseByte(split[1]);
|
||||
name = split[0];
|
||||
} else {
|
||||
data = 0;
|
||||
}
|
||||
double match;
|
||||
short id;
|
||||
if (MathMan.isInteger(split[0])) {
|
||||
id = Short.parseShort(split[0]);
|
||||
match = 0;
|
||||
} else {
|
||||
StringComparison<Material>.ComparisonResult comparison =
|
||||
new StringComparison<>(name, Material.values()).getBestMatchAdvanced();
|
||||
match = comparison.match;
|
||||
id = (short) comparison.best.getId();
|
||||
}
|
||||
PlotBlock block = PlotBlock.get(id, data);
|
||||
StringComparison<PlotBlock> outer = new StringComparison<>();
|
||||
return outer.new ComparisonResult(match, block);
|
||||
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override public void setBiomes(String worldName, RegionWrapper region, String biomeString) {
|
||||
World world = getWorld(worldName);
|
||||
Biome biome = Biome.valueOf(biomeString.toUpperCase());
|
||||
for (int x = region.minX; x <= region.maxX; x++) {
|
||||
for (int z = region.minZ; z <= region.maxZ; z++) {
|
||||
world.setBiome(x, z, biome);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override public PlotBlock getBlock(Location location) {
|
||||
World world = getWorld(location.getWorld());
|
||||
Block block = world.getBlockAt(location.getX(), location.getY(), location.getZ());
|
||||
if (block == null) {
|
||||
return PlotBlock.EVERYTHING;
|
||||
}
|
||||
return PlotBlock.get((short) block.getTypeId(), block.getData());
|
||||
}
|
||||
|
||||
@Override public String getMainWorld() {
|
||||
return Bukkit.getWorlds().get(0).getName();
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
package com.plotsquared.bukkit.util;
|
||||
|
||||
public class BukkitVersion {
|
||||
public static int[] v1_13_0 = {1, 13, 0};
|
||||
public static int[] v1_12_1 = {1, 12, 1};
|
||||
public static int[] v1_12_0 = {1, 12, 0};
|
||||
public static int[] v1_11_0 = {1, 11, 0};
|
||||
public static int[] v1_10_2 = {1, 10, 2};
|
||||
public static int[] v1_10_0 = {1, 10, 0};
|
||||
public static int[] v1_9_4 = {1, 9, 4};
|
||||
public static int[] v1_9_0 = {1, 9, 0};
|
||||
public static int[] v1_8_3 = {1, 8, 3};
|
||||
public static int[] v1_8_0 = {1, 8, 0};
|
||||
public static int[] v1_7_6 = {1, 7, 6};
|
||||
public static int[] v1_7_0 = {1, 7, 0};
|
||||
public static int[] v1_6_0 = {1, 6, 0};
|
||||
}
|
@ -1,285 +0,0 @@
|
||||
package com.plotsquared.bukkit.util;
|
||||
|
||||
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 java.io.*;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Collection;
|
||||
import java.util.UUID;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
public class Metrics {
|
||||
|
||||
/**
|
||||
* The current revision number.
|
||||
*/
|
||||
private static final 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;
|
||||
/**
|
||||
* Unique server id.
|
||||
*/
|
||||
private final String guid;
|
||||
/**
|
||||
* The scheduled task.
|
||||
*/
|
||||
private volatile BukkitTask task = null;
|
||||
|
||||
public Metrics(Plugin plugin) {
|
||||
this.plugin = plugin;
|
||||
this.guid = UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* GZip compress a string of bytes.
|
||||
*
|
||||
* @param input
|
||||
* @return byte[] the file as a byte array
|
||||
*/
|
||||
public static byte[] gzip(String input) {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
GZIPOutputStream gzos = null;
|
||||
try {
|
||||
gzos = new GZIPOutputStream(baos);
|
||||
gzos.write(input.getBytes("UTF-8"));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (gzos != null) {
|
||||
try {
|
||||
gzos.close();
|
||||
} catch (IOException ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a json encoded key/value pair to the given string builder.
|
||||
*
|
||||
* @param json
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
private static void appendJSONPair(StringBuilder json, String key, String value) {
|
||||
boolean isValueNumeric = false;
|
||||
try {
|
||||
if (value.equals("0") || !value.endsWith("0")) {
|
||||
Double.parseDouble(value);
|
||||
isValueNumeric = true;
|
||||
}
|
||||
} catch (NumberFormatException ignored) {
|
||||
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(String text) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append('"');
|
||||
for (int index = 0; index < text.length(); index++) {
|
||||
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 < ' ') {
|
||||
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(String text) throws UnsupportedEncodingException {
|
||||
return URLEncoder.encode(text, "UTF-8");
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
// 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 {
|
||||
postPlugin(!this.firstPost);
|
||||
// After the first post we set firstPost to
|
||||
// false
|
||||
// Each post thereafter will be a ping
|
||||
this.firstPost = false;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}, 0, PING_INTERVAL * 1200);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic method that posts a plugin to the metrics website.
|
||||
*/
|
||||
private void postPlugin(boolean isPing) throws IOException {
|
||||
// Server software specific section
|
||||
PluginDescriptionFile description = this.plugin.getDescription();
|
||||
String pluginName = description.getName();
|
||||
boolean onlineMode = Bukkit.getServer().getOnlineMode(); // TRUE if online mode is enabled
|
||||
String pluginVersion = description.getVersion();
|
||||
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)).size();
|
||||
} else {
|
||||
playersOnline =
|
||||
((Player[]) Bukkit.class.getMethod("getOnlinePlayers", new Class<?>[0])
|
||||
.invoke(null)).length;
|
||||
}
|
||||
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
// END server software specific section -- all code below does not use
|
||||
// any code outside of this class / Java
|
||||
// Construct the post data
|
||||
StringBuilder json = new StringBuilder(1024);
|
||||
json.append('{');
|
||||
// The plugin's description file containing 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
|
||||
String osname = System.getProperty("os.name");
|
||||
String osarch = System.getProperty("os.arch");
|
||||
String osversion = System.getProperty("os.version");
|
||||
String java_version = System.getProperty("java.version");
|
||||
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");
|
||||
}
|
||||
// close json
|
||||
json.append('}');
|
||||
// Create the url
|
||||
URL url = new URL(BASE_URL + String.format(REPORT_URL, urlEncode(pluginName)));
|
||||
// Connect to the website
|
||||
URLConnection connection = url.openConnection();
|
||||
byte[] uncompressed = json.toString().getBytes();
|
||||
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);
|
||||
try {
|
||||
try (OutputStream os = connection.getOutputStream()) {
|
||||
os.write(compressed);
|
||||
os.flush();
|
||||
}
|
||||
String response;
|
||||
try (BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(connection.getInputStream()))) {
|
||||
response = reader.readLine();
|
||||
}
|
||||
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);
|
||||
}
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,89 +0,0 @@
|
||||
package com.plotsquared.bukkit.util;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.intellectualcrafters.plot.util.ReflectionUtils.*;
|
||||
|
||||
public class OfflinePlayerUtil {
|
||||
|
||||
public static Player loadPlayer(String name) {
|
||||
return loadPlayer(Bukkit.getOfflinePlayer(name));
|
||||
}
|
||||
|
||||
public static Player loadPlayer(UUID id) {
|
||||
return loadPlayer(Bukkit.getOfflinePlayer(id));
|
||||
}
|
||||
|
||||
public static Player loadPlayer(OfflinePlayer player) {
|
||||
if (player == null) {
|
||||
return null;
|
||||
}
|
||||
if (player instanceof Player) {
|
||||
return (Player) player;
|
||||
}
|
||||
return loadPlayer(player.getUniqueId(), player.getName());
|
||||
}
|
||||
|
||||
private static Player loadPlayer(UUID id, String name) {
|
||||
Object server = getMinecraftServer();
|
||||
Object interactManager = newPlayerInteractManager();
|
||||
Object worldServer = getWorldServer();
|
||||
Object profile = newGameProfile(id, name);
|
||||
Class<?> entityPlayerClass = getNmsClass("EntityPlayer");
|
||||
Constructor entityPlayerConstructor =
|
||||
makeConstructor(entityPlayerClass, getNmsClass("MinecraftServer"),
|
||||
getNmsClass("WorldServer"), getUtilClass("com.mojang.authlib.GameProfile"),
|
||||
getNmsClass("PlayerInteractManager"));
|
||||
Object entityPlayer =
|
||||
callConstructor(entityPlayerConstructor, server, worldServer, profile, interactManager);
|
||||
return (Player) getBukkitEntity(entityPlayer);
|
||||
}
|
||||
|
||||
private static Object newGameProfile(UUID id, String name) {
|
||||
Class<?> gameProfileClass = getUtilClass("com.mojang.authlib.GameProfile");
|
||||
if (gameProfileClass == null) { //Before uuids
|
||||
return name;
|
||||
}
|
||||
Constructor gameProfileConstructor =
|
||||
makeConstructor(gameProfileClass, UUID.class, String.class);
|
||||
if (gameProfileConstructor == null) { //Version 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() {
|
||||
Object worldServer = getWorldServer();
|
||||
Class<?> playerInteractClass = getNmsClass("PlayerInteractManager");
|
||||
Class<?> worldClass = getNmsClass("World");
|
||||
Constructor c = makeConstructor(playerInteractClass, worldClass);
|
||||
return callConstructor(c, worldServer);
|
||||
}
|
||||
|
||||
private static Object getWorldServer() {
|
||||
Object server = getMinecraftServer();
|
||||
Class<?> minecraftServerClass = getNmsClass("MinecraftServer");
|
||||
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(Object o) {
|
||||
Method getBukkitEntity = makeMethod(o.getClass(), "getBukkitEntity");
|
||||
return callMethod(getBukkitEntity, o);
|
||||
}
|
||||
}
|
@ -1,171 +0,0 @@
|
||||
package com.plotsquared.bukkit.util;
|
||||
|
||||
import com.intellectualcrafters.plot.PS;
|
||||
import com.intellectualcrafters.plot.object.ChunkLoc;
|
||||
import com.intellectualcrafters.plot.object.Location;
|
||||
import com.intellectualcrafters.plot.object.Plot;
|
||||
import com.intellectualcrafters.plot.object.PlotPlayer;
|
||||
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;
|
||||
import com.intellectualcrafters.plot.util.TaskManager;
|
||||
import com.intellectualcrafters.plot.util.UUIDHandler;
|
||||
import com.plotsquared.bukkit.object.BukkitPlayer;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import static com.intellectualcrafters.plot.util.ReflectionUtils.getRefClass;
|
||||
|
||||
/**
|
||||
* An utility that can be used to send chunks, rather than using bukkit code
|
||||
* to do so (uses heavy NMS).
|
||||
*/
|
||||
public class SendChunk {
|
||||
|
||||
private final RefMethod methodGetHandlePlayer;
|
||||
private final RefMethod methodGetHandleChunk;
|
||||
private final RefConstructor mapChunk;
|
||||
private final RefField connection;
|
||||
private final RefMethod send;
|
||||
private final RefMethod methodInitLighting;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public SendChunk() throws ClassNotFoundException, NoSuchMethodException, NoSuchFieldException {
|
||||
RefConstructor tempMapChunk;
|
||||
RefClass classCraftPlayer = getRefClass("{cb}.entity.CraftPlayer");
|
||||
this.methodGetHandlePlayer = classCraftPlayer.getMethod("getHandle");
|
||||
RefClass classCraftChunk = getRefClass("{cb}.CraftChunk");
|
||||
this.methodGetHandleChunk = classCraftChunk.getMethod("getHandle");
|
||||
RefClass classChunk = getRefClass("{nms}.Chunk");
|
||||
this.methodInitLighting = classChunk.getMethod("initLighting");
|
||||
RefClass classMapChunk = getRefClass("{nms}.PacketPlayOutMapChunk");
|
||||
if (PS.get().checkVersion(PS.get().IMP.getServerVersion(), BukkitVersion.v1_9_4)) {
|
||||
//this works for 1.9.4 and 1.10
|
||||
tempMapChunk = classMapChunk.getConstructor(classChunk.getRealClass(), int.class);
|
||||
} else {
|
||||
try {
|
||||
tempMapChunk = classMapChunk
|
||||
.getConstructor(classChunk.getRealClass(), boolean.class, int.class);
|
||||
} catch (NoSuchMethodException ignored) {
|
||||
tempMapChunk = classMapChunk
|
||||
.getConstructor(classChunk.getRealClass(), boolean.class, int.class, int.class);
|
||||
}
|
||||
}
|
||||
this.mapChunk = tempMapChunk;
|
||||
RefClass classEntityPlayer = getRefClass("{nms}.EntityPlayer");
|
||||
this.connection = classEntityPlayer.getField("playerConnection");
|
||||
RefClass classPacket = getRefClass("{nms}.Packet");
|
||||
RefClass classConnection = getRefClass("{nms}.PlayerConnection");
|
||||
this.send = classConnection.getMethod("sendPacket", classPacket.getRealClass());
|
||||
}
|
||||
|
||||
public void sendChunk(Collection<Chunk> input) {
|
||||
HashSet<Chunk> chunks = new HashSet<>(input);
|
||||
HashMap<String, ArrayList<Chunk>> map = new HashMap<>();
|
||||
int view = Bukkit.getServer().getViewDistance();
|
||||
for (Chunk chunk : chunks) {
|
||||
String world = chunk.getWorld().getName();
|
||||
ArrayList<Chunk> list = map.get(world);
|
||||
if (list == null) {
|
||||
list = new ArrayList<>();
|
||||
map.put(world, list);
|
||||
}
|
||||
list.add(chunk);
|
||||
Object c = this.methodGetHandleChunk.of(chunk).call();
|
||||
this.methodInitLighting.of(c).call();
|
||||
}
|
||||
for (Entry<String, PlotPlayer> entry : UUIDHandler.getPlayers().entrySet()) {
|
||||
PlotPlayer pp = entry.getValue();
|
||||
Plot plot = pp.getCurrentPlot();
|
||||
Location location = null;
|
||||
String world;
|
||||
if (plot != null) {
|
||||
world = plot.getWorldName();
|
||||
} else {
|
||||
location = pp.getLocation();
|
||||
world = location.getWorld();
|
||||
}
|
||||
ArrayList<Chunk> list = map.get(world);
|
||||
if (list == null) {
|
||||
continue;
|
||||
}
|
||||
if (location == null) {
|
||||
location = pp.getLocation();
|
||||
}
|
||||
int cx = location.getX() >> 4;
|
||||
int cz = location.getZ() >> 4;
|
||||
Player player = ((BukkitPlayer) pp).player;
|
||||
Object entity = this.methodGetHandlePlayer.of(player).call();
|
||||
|
||||
for (Chunk chunk : list) {
|
||||
int dx = Math.abs(cx - chunk.getX());
|
||||
int dz = Math.abs(cz - chunk.getZ());
|
||||
if ((dx > view) || (dz > view)) {
|
||||
continue;
|
||||
}
|
||||
Object c = this.methodGetHandleChunk.of(chunk).call();
|
||||
chunks.remove(chunk);
|
||||
Object con = this.connection.of(entity).get();
|
||||
Object packet = null;
|
||||
if (PS.get().checkVersion(PS.get().IMP.getServerVersion(), BukkitVersion.v1_9_4)) {
|
||||
try {
|
||||
packet = this.mapChunk.create(c, 65535);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
packet = this.mapChunk.create(c, true, 65535);
|
||||
} catch (ReflectiveOperationException | IllegalArgumentException e) {
|
||||
try {
|
||||
packet = this.mapChunk.create(c, true, 65535, 5);
|
||||
} catch (ReflectiveOperationException | IllegalArgumentException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (packet == null) {
|
||||
PS.debug("Error with PacketPlayOutMapChunk reflection.");
|
||||
}
|
||||
this.send.of(con).call(packet);
|
||||
}
|
||||
}
|
||||
for (final Chunk chunk : chunks) {
|
||||
TaskManager.runTask(new Runnable() {
|
||||
@Override public void run() {
|
||||
try {
|
||||
chunk.unload(true, false);
|
||||
} catch (Throwable ignored) {
|
||||
String worldName = chunk.getWorld().getName();
|
||||
PS.debug("$4Could not save chunk: " + worldName + ';' + chunk.getX() + ";"
|
||||
+ chunk.getZ());
|
||||
PS.debug("$3 - $4File may be open in another process (e.g. MCEdit)");
|
||||
PS.debug("$3 - $4" + worldName + "/level.dat or " + worldName
|
||||
+ "/level_old.dat may be corrupt (try repairing or removing these)");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void sendChunk(String worldName, Collection<ChunkLoc> chunkLocations) {
|
||||
World myWorld = Bukkit.getWorld(worldName);
|
||||
ArrayList<Chunk> chunks = new ArrayList<>();
|
||||
for (ChunkLoc loc : chunkLocations) {
|
||||
if (myWorld.isChunkLoaded(loc.x, loc.z)) {
|
||||
chunks.add(myWorld.getChunkAt(loc.x, loc.z));
|
||||
}
|
||||
}
|
||||
sendChunk(chunks);
|
||||
}
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
package com.plotsquared.bukkit.util;
|
||||
|
||||
import com.intellectualcrafters.plot.PS;
|
||||
import com.intellectualcrafters.plot.generator.GeneratorWrapper;
|
||||
import com.intellectualcrafters.plot.util.SetupUtils;
|
||||
import com.plotsquared.bukkit.generator.BukkitAugmentedGenerator;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.generator.BlockPopulator;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
||||
public class SetGenCB {
|
||||
|
||||
public static void setGenerator(World world) throws Exception {
|
||||
SetupUtils.manager.updateGenerators();
|
||||
PS.get().removePlotAreas(world.getName());
|
||||
ChunkGenerator gen = world.getGenerator();
|
||||
if (gen == null) {
|
||||
return;
|
||||
}
|
||||
String name = gen.getClass().getCanonicalName();
|
||||
boolean set = false;
|
||||
for (GeneratorWrapper<?> wrapper : SetupUtils.generators.values()) {
|
||||
ChunkGenerator newGen = (ChunkGenerator) wrapper.getPlatformGenerator();
|
||||
if (newGen == null) {
|
||||
newGen = (ChunkGenerator) wrapper;
|
||||
}
|
||||
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
|
||||
generator.set(world, newGen);
|
||||
populators.set(world, newGen.getDefaultPopulators(world));
|
||||
// end
|
||||
set = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!set) {
|
||||
Iterator<BlockPopulator> iterator = world.getPopulators().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
if (iterator.next() instanceof BukkitAugmentedGenerator) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
PS.get().loadWorld(world.getName(), PS.get().IMP.getGenerator(world.getName(), null));
|
||||
}
|
||||
}
|
@ -1,184 +0,0 @@
|
||||
package com.plotsquared.bukkit.util.block;
|
||||
|
||||
import com.intellectualcrafters.plot.object.PlotBlock;
|
||||
import com.intellectualcrafters.plot.util.MainUtil;
|
||||
import com.intellectualcrafters.plot.util.StringMan;
|
||||
import com.intellectualcrafters.plot.util.block.BasicLocalBlockQueue;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class BukkitLocalQueue<T> extends BasicLocalBlockQueue<T> {
|
||||
|
||||
private Field fieldNeighbors;
|
||||
private Method chunkGetHandle;
|
||||
|
||||
public BukkitLocalQueue(String world) {
|
||||
super(world);
|
||||
}
|
||||
|
||||
@Override public LocalChunk<T> getLocalChunk(int x, int z) {
|
||||
return (LocalChunk<T>) new BasicLocalChunk(this, x, z) {
|
||||
// Custom stuff?
|
||||
};
|
||||
}
|
||||
|
||||
@Override public void optimize() {
|
||||
|
||||
}
|
||||
|
||||
@Override public PlotBlock getBlock(int x, int y, int z) {
|
||||
World worldObj = Bukkit.getWorld(getWorld());
|
||||
Block block = worldObj.getBlockAt(x, y, z);
|
||||
if (block == null) {
|
||||
return PlotBlock.get(0, 0);
|
||||
}
|
||||
int id = block.getTypeId();
|
||||
if (id == 0) {
|
||||
return PlotBlock.get(0, 0);
|
||||
}
|
||||
return PlotBlock.get(id, block.getData());
|
||||
}
|
||||
|
||||
@Override public void refreshChunk(int x, int z) {
|
||||
World worldObj = Bukkit.getWorld(getWorld());
|
||||
worldObj.refreshChunk(x, z);
|
||||
}
|
||||
|
||||
@Override public void fixChunkLighting(int x, int z) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override public final void regenChunk(int x, int z) {
|
||||
World worldObj = Bukkit.getWorld(getWorld());
|
||||
worldObj.regenerateChunk(x, z);
|
||||
}
|
||||
|
||||
@Override public final void setComponents(LocalChunk<T> lc) {
|
||||
setBlocks(lc);
|
||||
setBiomes(lc);
|
||||
}
|
||||
|
||||
public World getBukkitWorld() {
|
||||
return Bukkit.getWorld(getWorld());
|
||||
}
|
||||
|
||||
public Chunk getChunk(int x, int z) {
|
||||
return getBukkitWorld().getChunkAt(x, z);
|
||||
}
|
||||
|
||||
public void setBlocks(LocalChunk<T> lc) {
|
||||
World worldObj = Bukkit.getWorld(getWorld());
|
||||
Chunk chunk = worldObj.getChunkAt(lc.getX(), lc.getZ());
|
||||
chunk.load(true);
|
||||
for (int layer = 0; layer < lc.blocks.length; layer++) {
|
||||
PlotBlock[] blocksLayer = (PlotBlock[]) lc.blocks[layer];
|
||||
if (blocksLayer != null) {
|
||||
for (int j = 0; j < blocksLayer.length; j++) {
|
||||
PlotBlock block = blocksLayer[j];
|
||||
if (block != null) {
|
||||
int x = MainUtil.x_loc[layer][j];
|
||||
int y = MainUtil.y_loc[layer][j];
|
||||
int z = MainUtil.z_loc[layer][j];
|
||||
Block existing = chunk.getBlock(x, y, z);
|
||||
int existingId = existing.getTypeId();
|
||||
if (existingId == block.id) {
|
||||
if (existingId == 0) {
|
||||
continue;
|
||||
}
|
||||
if (existing.getData() == block.data) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
existing.setTypeIdAndData(block.id, block.data, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setBiomes(LocalChunk<T> lc) {
|
||||
if (lc.biomes != null) {
|
||||
World worldObj = Bukkit.getWorld(getWorld());
|
||||
int bx = lc.getX() << 4;
|
||||
int bz = lc.getX() << 4;
|
||||
String last = null;
|
||||
Biome biome = null;
|
||||
for (int x = 0; x < lc.biomes.length; x++) {
|
||||
String[] biomes2 = lc.biomes[x];
|
||||
if (biomes2 != null) {
|
||||
for (int y = 0; y < biomes2.length; y++) {
|
||||
String biomeStr = biomes2[y];
|
||||
if (biomeStr != null) {
|
||||
if (last == null || !StringMan.isEqual(last, biomeStr)) {
|
||||
biome = Biome.valueOf(biomeStr.toUpperCase());
|
||||
}
|
||||
worldObj.setBiome(bx, bz, biome);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Exploiting a bug in the vanilla lighting algorithm for faster block placement
|
||||
* - Could have been achieved without reflection by force unloading specific chunks
|
||||
* - Much faster just setting the variable manually though
|
||||
*
|
||||
* @param chunk
|
||||
* @return
|
||||
*/
|
||||
protected Object[] disableLighting(Chunk chunk) {
|
||||
try {
|
||||
if (chunkGetHandle == null) {
|
||||
chunkGetHandle = chunk.getClass().getDeclaredMethod("getHandle");
|
||||
chunkGetHandle.setAccessible(true);
|
||||
}
|
||||
Object nmsChunk = chunkGetHandle.invoke(chunk);
|
||||
if (fieldNeighbors == null) {
|
||||
fieldNeighbors = nmsChunk.getClass().getDeclaredField("neighbors");
|
||||
fieldNeighbors.setAccessible(true);
|
||||
}
|
||||
Object value = fieldNeighbors.get(nmsChunk);
|
||||
fieldNeighbors.set(nmsChunk, 0);
|
||||
return new Object[] {nmsChunk, value};
|
||||
} catch (Throwable ignore) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void disableLighting(Object[] disableResult) {
|
||||
if (disableResult != null) {
|
||||
try {
|
||||
fieldNeighbors.set(disableResult[0], 0);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void resetLighting(Object[] disableResult) {
|
||||
if (disableResult != null) {
|
||||
try {
|
||||
fieldNeighbors.set(disableResult[0], disableResult[1]);
|
||||
} catch (Throwable ignore) {
|
||||
ignore.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void enableLighting(Object[] disableResult) {
|
||||
if (disableResult != null) {
|
||||
try {
|
||||
fieldNeighbors.set(disableResult[0], 0x739C0);
|
||||
} catch (Throwable ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,129 +0,0 @@
|
||||
package com.plotsquared.bukkit.util.block;
|
||||
|
||||
import com.intellectualcrafters.plot.object.ChunkWrapper;
|
||||
import com.intellectualcrafters.plot.object.PlotBlock;
|
||||
import com.intellectualcrafters.plot.util.MainUtil;
|
||||
import com.intellectualcrafters.plot.util.ReflectionUtils;
|
||||
import com.intellectualcrafters.plot.util.TaskManager;
|
||||
import com.plotsquared.bukkit.util.SendChunk;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static com.intellectualcrafters.plot.util.ReflectionUtils.getRefClass;
|
||||
|
||||
public class BukkitLocalQueue_1_7 extends BukkitLocalQueue<PlotBlock[]> {
|
||||
|
||||
private final ReflectionUtils.RefClass classBlock = getRefClass("{nms}.Block");
|
||||
private final ReflectionUtils.RefClass classChunk = getRefClass("{nms}.Chunk");
|
||||
private final ReflectionUtils.RefClass classWorld = getRefClass("{nms}.World");
|
||||
private final ReflectionUtils.RefClass classCraftWorld = getRefClass("{cb}.CraftWorld");
|
||||
private final ReflectionUtils.RefClass classCraftChunk = getRefClass("{cb}.CraftChunk");
|
||||
private final ReflectionUtils.RefMethod methodGetHandle;
|
||||
private final ReflectionUtils.RefMethod methodGetHandleChunk;
|
||||
private final ReflectionUtils.RefMethod methodGetChunkAt;
|
||||
private final ReflectionUtils.RefMethod methodA;
|
||||
private final ReflectionUtils.RefMethod methodGetById;
|
||||
private final ReflectionUtils.RefMethod methodInitLighting;
|
||||
private final SendChunk sendChunk;
|
||||
|
||||
private final HashMap<ChunkWrapper, Chunk> toUpdate = new HashMap<>();
|
||||
|
||||
public BukkitLocalQueue_1_7(String world)
|
||||
throws NoSuchMethodException, ClassNotFoundException, NoSuchFieldException {
|
||||
super(world);
|
||||
this.methodGetHandle = this.classCraftWorld.getMethod("getHandle");
|
||||
this.methodGetChunkAt = this.classWorld.getMethod("getChunkAt", int.class, int.class);
|
||||
this.methodA = this.classChunk
|
||||
.getMethod("a", int.class, int.class, int.class, this.classBlock, int.class);
|
||||
this.methodGetById = this.classBlock.getMethod("getById", int.class);
|
||||
this.methodGetHandleChunk = this.classCraftChunk.getMethod("getHandle");
|
||||
this.methodInitLighting = this.classChunk.getMethod("initLighting");
|
||||
this.sendChunk = new SendChunk();
|
||||
TaskManager.runTaskRepeat(new Runnable() {
|
||||
@Override public void run() {
|
||||
if (BukkitLocalQueue_1_7.this.toUpdate.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
int count = 0;
|
||||
ArrayList<Chunk> chunks = new ArrayList<>();
|
||||
Iterator<Map.Entry<ChunkWrapper, Chunk>> i =
|
||||
BukkitLocalQueue_1_7.this.toUpdate.entrySet().iterator();
|
||||
while (i.hasNext() && (count < 128)) {
|
||||
chunks.add(i.next().getValue());
|
||||
i.remove();
|
||||
count++;
|
||||
}
|
||||
if (count == 0) {
|
||||
return;
|
||||
}
|
||||
update(chunks);
|
||||
}
|
||||
}, 1);
|
||||
MainUtil.initCache();
|
||||
}
|
||||
|
||||
public void update(Collection<Chunk> chunks) {
|
||||
if (chunks.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (!MainUtil.canSendChunk) {
|
||||
for (Chunk chunk : chunks) {
|
||||
chunk.getWorld().refreshChunk(chunk.getX(), chunk.getZ());
|
||||
chunk.unload(true, false);
|
||||
chunk.load();
|
||||
}
|
||||
return;
|
||||
}
|
||||
try {
|
||||
this.sendChunk.sendChunk(chunks);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
MainUtil.canSendChunk = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void fixChunkLighting(int x, int z) {
|
||||
Object c = this.methodGetHandleChunk.of(getChunk(x, z)).call();
|
||||
this.methodInitLighting.of(c).call();
|
||||
}
|
||||
|
||||
@Override public void setBlocks(LocalChunk<PlotBlock[]> lc) {
|
||||
Chunk chunk = getChunk(lc.getX(), lc.getZ());
|
||||
chunk.load(true);
|
||||
World world = chunk.getWorld();
|
||||
ChunkWrapper wrapper = new ChunkWrapper(getWorld(), lc.getX(), lc.getZ());
|
||||
if (!this.toUpdate.containsKey(wrapper)) {
|
||||
this.toUpdate.put(wrapper, chunk);
|
||||
}
|
||||
Object w = this.methodGetHandle.of(world).call();
|
||||
Object c = this.methodGetChunkAt.of(w).call(lc.getX(), lc.getZ());
|
||||
for (int i = 0; i < lc.blocks.length; i++) {
|
||||
PlotBlock[] result2 = lc.blocks[i];
|
||||
if (result2 == null) {
|
||||
continue;
|
||||
}
|
||||
for (int j = 0; j < 4096; j++) {
|
||||
int x = MainUtil.x_loc[i][j];
|
||||
int y = MainUtil.y_loc[i][j];
|
||||
int z = MainUtil.z_loc[i][j];
|
||||
PlotBlock newBlock = result2[j];
|
||||
if (newBlock != null) {
|
||||
if (newBlock.id == -1) {
|
||||
chunk.getBlock(x, y, z).setData(newBlock.data, false);
|
||||
continue;
|
||||
}
|
||||
Object block = this.methodGetById.call(newBlock.id);
|
||||
this.methodA.of(c).call(x, y, z, block, newBlock.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
fixChunkLighting(lc.getX(), lc.getZ());
|
||||
}
|
||||
|
||||
@Override public void refreshChunk(int x, int z) {
|
||||
update(Arrays.asList(Bukkit.getWorld(getWorld()).getChunkAt(x, z)));
|
||||
}
|
||||
}
|
@ -1,341 +0,0 @@
|
||||
package com.plotsquared.bukkit.util.block;
|
||||
|
||||
import com.intellectualcrafters.plot.object.ChunkWrapper;
|
||||
import com.intellectualcrafters.plot.object.PlotBlock;
|
||||
import com.intellectualcrafters.plot.util.MainUtil;
|
||||
import com.intellectualcrafters.plot.util.ReflectionUtils;
|
||||
import com.intellectualcrafters.plot.util.ReflectionUtils.RefClass;
|
||||
import com.intellectualcrafters.plot.util.ReflectionUtils.RefMethod;
|
||||
import com.intellectualcrafters.plot.util.TaskManager;
|
||||
import com.plotsquared.bukkit.util.SendChunk;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static com.intellectualcrafters.plot.util.ReflectionUtils.getRefClass;
|
||||
|
||||
public class BukkitLocalQueue_1_8 extends BukkitLocalQueue<PlotBlock[]> {
|
||||
|
||||
private final ReflectionUtils.RefMethod methodInitLighting;
|
||||
private final ReflectionUtils.RefClass classBlock = getRefClass("{nms}.Block");
|
||||
private final ReflectionUtils.RefClass classBlockPosition = getRefClass("{nms}.BlockPosition");
|
||||
private final ReflectionUtils.RefClass classIBlockData = getRefClass("{nms}.IBlockData");
|
||||
private final ReflectionUtils.RefClass classChunk = getRefClass("{nms}.Chunk");
|
||||
private final ReflectionUtils.RefClass classWorld = getRefClass("{nms}.World");
|
||||
private final ReflectionUtils.RefClass classCraftWorld = getRefClass("{cb}.CraftWorld");
|
||||
private final HashMap<ChunkWrapper, Chunk> toUpdate = new HashMap<>();
|
||||
private final ReflectionUtils.RefMethod methodGetHandle;
|
||||
private final ReflectionUtils.RefMethod methodGetChunkAt;
|
||||
private final ReflectionUtils.RefMethod methodA;
|
||||
private final ReflectionUtils.RefMethod methodGetByCombinedId;
|
||||
private final ReflectionUtils.RefConstructor constructorBlockPosition;
|
||||
private final SendChunk sendChunk;
|
||||
private final RefMethod methodGetHandleChunk;
|
||||
|
||||
public BukkitLocalQueue_1_8(String world)
|
||||
throws NoSuchMethodException, ClassNotFoundException, NoSuchFieldException {
|
||||
super(world);
|
||||
this.methodInitLighting = this.classChunk.getMethod("initLighting");
|
||||
this.constructorBlockPosition =
|
||||
this.classBlockPosition.getConstructor(int.class, int.class, int.class);
|
||||
this.methodGetByCombinedId = this.classBlock.getMethod("getByCombinedId", int.class);
|
||||
this.methodGetHandle = this.classCraftWorld.getMethod("getHandle");
|
||||
RefClass classCraftChunk = getRefClass("{cb}.CraftChunk");
|
||||
this.methodGetHandleChunk = classCraftChunk.getMethod("getHandle");
|
||||
this.methodGetChunkAt = this.classWorld.getMethod("getChunkAt", int.class, int.class);
|
||||
this.methodA =
|
||||
this.classChunk.getMethod("a", this.classBlockPosition, this.classIBlockData);
|
||||
this.sendChunk = new SendChunk();
|
||||
TaskManager.runTaskRepeat(new Runnable() {
|
||||
@Override public void run() {
|
||||
if (BukkitLocalQueue_1_8.this.toUpdate.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
int count = 0;
|
||||
ArrayList<Chunk> chunks = new ArrayList<>();
|
||||
Iterator<Map.Entry<ChunkWrapper, Chunk>> i =
|
||||
BukkitLocalQueue_1_8.this.toUpdate.entrySet().iterator();
|
||||
while (i.hasNext() && count < 128) {
|
||||
chunks.add(i.next().getValue());
|
||||
i.remove();
|
||||
count++;
|
||||
}
|
||||
if (count == 0) {
|
||||
return;
|
||||
}
|
||||
update(chunks);
|
||||
}
|
||||
}, 1);
|
||||
MainUtil.initCache();
|
||||
}
|
||||
|
||||
@Override public void fixChunkLighting(int x, int z) {
|
||||
Object c = this.methodGetHandleChunk.of(getChunk(x, z)).call();
|
||||
this.methodInitLighting.of(c).call();
|
||||
}
|
||||
|
||||
@Override public void setBlocks(LocalChunk<PlotBlock[]> lc) {
|
||||
Chunk chunk = getChunk(lc.getX(), lc.getZ());
|
||||
chunk.load(true);
|
||||
World world = chunk.getWorld();
|
||||
ChunkWrapper wrapper = new ChunkWrapper(getWorld(), lc.getX(), lc.getZ());
|
||||
if (!this.toUpdate.containsKey(wrapper)) {
|
||||
this.toUpdate.put(wrapper, chunk);
|
||||
}
|
||||
Object w = this.methodGetHandle.of(world).call();
|
||||
Object c = this.methodGetChunkAt.of(w).call(lc.getX(), lc.getZ());
|
||||
for (int i = 0; i < lc.blocks.length; i++) {
|
||||
PlotBlock[] result2 = lc.blocks[i];
|
||||
if (result2 == null) {
|
||||
continue;
|
||||
}
|
||||
for (int j = 0; j < 4096; j++) {
|
||||
int x = MainUtil.x_loc[i][j];
|
||||
int y = MainUtil.y_loc[i][j];
|
||||
int z = MainUtil.z_loc[i][j];
|
||||
PlotBlock newBlock = result2[j];
|
||||
if (newBlock == null)
|
||||
continue;
|
||||
|
||||
if (newBlock.id == -1) {
|
||||
chunk.getBlock(x, y, z).setData(newBlock.data, false);
|
||||
continue;
|
||||
}
|
||||
// Start blockstate workaround //
|
||||
switch (newBlock.id) {
|
||||
case 54:
|
||||
case 130:
|
||||
case 142:
|
||||
case 132:
|
||||
case 27:
|
||||
case 137:
|
||||
case 52:
|
||||
case 154:
|
||||
case 84:
|
||||
case 25:
|
||||
case 144:
|
||||
case 138:
|
||||
case 176:
|
||||
case 177:
|
||||
case 119:
|
||||
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:
|
||||
Block block = world.getBlockAt(x, y, z);
|
||||
if (block.getData() == newBlock.data) {
|
||||
if (block.getTypeId() != newBlock.id) {
|
||||
block.setTypeId(newBlock.id, false);
|
||||
}
|
||||
} else {
|
||||
if (block.getTypeId() == newBlock.id) {
|
||||
block.setData(newBlock.data, false);
|
||||
} else {
|
||||
block.setTypeIdAndData(newBlock.id, newBlock.data, false);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Start data value shortcut
|
||||
Block block = world.getBlockAt(x, y, z);
|
||||
int currentId = block.getTypeId();
|
||||
if (currentId == newBlock.id) {
|
||||
switch (newBlock.id) {
|
||||
case 0:
|
||||
case 2:
|
||||
case 4:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
case 20:
|
||||
case 21:
|
||||
case 22:
|
||||
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 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 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:
|
||||
continue;
|
||||
}
|
||||
if (block.getData() == newBlock.data) {
|
||||
return;
|
||||
}
|
||||
block.setData(newBlock.data, false);
|
||||
return;
|
||||
}
|
||||
// blockstate
|
||||
switch (currentId) {
|
||||
case 54:
|
||||
case 130:
|
||||
case 132:
|
||||
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 119:
|
||||
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() == newBlock.data) {
|
||||
block.setTypeId(newBlock.id, false);
|
||||
} else {
|
||||
block.setTypeIdAndData(newBlock.id, newBlock.data, false);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// End blockstate workaround //
|
||||
|
||||
// check sign
|
||||
Object pos = null;
|
||||
try {
|
||||
pos = this.constructorBlockPosition.create(x, y, z);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Object combined =
|
||||
this.methodGetByCombinedId.call(newBlock.id + (newBlock.data << 12));
|
||||
this.methodA.of(c).call(pos, combined);
|
||||
}
|
||||
}
|
||||
fixChunkLighting(lc.getX(), lc.getZ());
|
||||
}
|
||||
|
||||
public void update(Collection<Chunk> chunks) {
|
||||
if (chunks.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (!MainUtil.canSendChunk) {
|
||||
for (Chunk chunk : chunks) {
|
||||
chunk.getWorld().refreshChunk(chunk.getX(), chunk.getZ());
|
||||
chunk.unload(true, false);
|
||||
chunk.load();
|
||||
}
|
||||
return;
|
||||
}
|
||||
try {
|
||||
this.sendChunk.sendChunk(chunks);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
MainUtil.canSendChunk = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void refreshChunk(int x, int z) {
|
||||
update(Arrays.asList(Bukkit.getWorld(getWorld()).getChunkAt(x, z)));
|
||||
}
|
||||
}
|
@ -1,530 +0,0 @@
|
||||
package com.plotsquared.bukkit.util.block;
|
||||
|
||||
import com.intellectualcrafters.plot.object.ChunkLoc;
|
||||
import com.intellectualcrafters.plot.object.ChunkWrapper;
|
||||
import com.intellectualcrafters.plot.object.PseudoRandom;
|
||||
import com.intellectualcrafters.plot.util.ChunkManager;
|
||||
import com.intellectualcrafters.plot.util.MainUtil;
|
||||
import com.intellectualcrafters.plot.util.ReflectionUtils;
|
||||
import com.intellectualcrafters.plot.util.TaskManager;
|
||||
import com.intellectualcrafters.plot.util.block.BasicLocalBlockQueue;
|
||||
import com.plotsquared.bukkit.util.SendChunk;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
|
||||
import static com.intellectualcrafters.plot.util.ReflectionUtils.getRefClass;
|
||||
|
||||
public class BukkitLocalQueue_1_8_3 extends BukkitLocalQueue<char[]> {
|
||||
|
||||
private final SendChunk sendChunk;
|
||||
private final HashMap<ChunkWrapper, Chunk> toUpdate = new HashMap<>();
|
||||
private final ReflectionUtils.RefMethod methodGetHandleChunk;
|
||||
private final ReflectionUtils.RefMethod methodGetHandleWorld;
|
||||
private final ReflectionUtils.RefMethod methodInitLighting;
|
||||
private final ReflectionUtils.RefConstructor classBlockPositionConstructor;
|
||||
private final ReflectionUtils.RefConstructor classChunkSectionConstructor;
|
||||
private final ReflectionUtils.RefMethod methodX;
|
||||
private final ReflectionUtils.RefMethod methodAreNeighborsLoaded;
|
||||
private final ReflectionUtils.RefField fieldSections;
|
||||
private final ReflectionUtils.RefField fieldWorld;
|
||||
private final ReflectionUtils.RefMethod methodGetIdArray;
|
||||
private final ReflectionUtils.RefMethod methodGetWorld;
|
||||
private final ReflectionUtils.RefField tileEntityListTick;
|
||||
|
||||
public BukkitLocalQueue_1_8_3(String world)
|
||||
throws NoSuchMethodException, ClassNotFoundException, NoSuchFieldException {
|
||||
super(world);
|
||||
ReflectionUtils.RefClass classCraftChunk = getRefClass("{cb}.CraftChunk");
|
||||
ReflectionUtils.RefClass classCraftWorld = getRefClass("{cb}.CraftWorld");
|
||||
this.methodGetHandleChunk = classCraftChunk.getMethod("getHandle");
|
||||
ReflectionUtils.RefClass classChunk = getRefClass("{nms}.Chunk");
|
||||
this.methodInitLighting = classChunk.getMethod("initLighting");
|
||||
ReflectionUtils.RefClass classBlockPosition = getRefClass("{nms}.BlockPosition");
|
||||
this.classBlockPositionConstructor =
|
||||
classBlockPosition.getConstructor(int.class, int.class, int.class);
|
||||
ReflectionUtils.RefClass classWorld = getRefClass("{nms}.World");
|
||||
this.methodX = classWorld.getMethod("x", classBlockPosition.getRealClass());
|
||||
this.fieldSections = classChunk.getField("sections");
|
||||
this.fieldWorld = classChunk.getField("world");
|
||||
ReflectionUtils.RefClass classChunkSection = getRefClass("{nms}.ChunkSection");
|
||||
this.methodGetIdArray = classChunkSection.getMethod("getIdArray");
|
||||
this.methodAreNeighborsLoaded = classChunk.getMethod("areNeighborsLoaded", int.class);
|
||||
this.classChunkSectionConstructor =
|
||||
classChunkSection.getConstructor(int.class, boolean.class, char[].class);
|
||||
this.tileEntityListTick = classWorld.getField("tileEntityList");
|
||||
this.methodGetHandleWorld = classCraftWorld.getMethod("getHandle");
|
||||
this.methodGetWorld = classChunk.getMethod("getWorld");
|
||||
this.sendChunk = new SendChunk();
|
||||
TaskManager.runTaskRepeat(new Runnable() {
|
||||
@Override public void run() {
|
||||
if (BukkitLocalQueue_1_8_3.this.toUpdate.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
int count = 0;
|
||||
ArrayList<Chunk> chunks = new ArrayList<>();
|
||||
Iterator<Map.Entry<ChunkWrapper, Chunk>> i =
|
||||
BukkitLocalQueue_1_8_3.this.toUpdate.entrySet().iterator();
|
||||
while (i.hasNext() && count < 128) {
|
||||
chunks.add(i.next().getValue());
|
||||
i.remove();
|
||||
count++;
|
||||
}
|
||||
if (count == 0) {
|
||||
return;
|
||||
}
|
||||
update(chunks);
|
||||
}
|
||||
}, 1);
|
||||
MainUtil.initCache();
|
||||
}
|
||||
|
||||
@Override public LocalChunk<char[]> getLocalChunk(int x, int z) {
|
||||
return new CharLocalChunk_1_8_3(this, x, z);
|
||||
}
|
||||
|
||||
@Override public void setBlocks(LocalChunk lc) {
|
||||
CharLocalChunk_1_8_3 fs = (CharLocalChunk_1_8_3) lc;
|
||||
Chunk chunk = getChunk(lc.getX(), lc.getZ());
|
||||
chunk.load(true);
|
||||
World world = chunk.getWorld();
|
||||
ChunkWrapper wrapper = new ChunkWrapper(getWorld(), lc.getX(), lc.getZ());
|
||||
if (!this.toUpdate.containsKey(wrapper)) {
|
||||
this.toUpdate.put(wrapper, chunk);
|
||||
}
|
||||
try {
|
||||
boolean flag = world.getEnvironment() == World.Environment.NORMAL;
|
||||
|
||||
// Sections
|
||||
Method getHandle = chunk.getClass().getDeclaredMethod("getHandle");
|
||||
Object c = getHandle.invoke(chunk);
|
||||
Object w = this.methodGetWorld.of(c).call();
|
||||
Class<?> clazz = c.getClass();
|
||||
Field sections1 = clazz.getDeclaredField("sections");
|
||||
sections1.setAccessible(true);
|
||||
Field tileEntities = clazz.getDeclaredField("tileEntities");
|
||||
Field entitySlices = clazz.getDeclaredField("entitySlices");
|
||||
Object[] sections = (Object[]) sections1.get(c);
|
||||
Map<?, ?> tiles = (Map<?, ?>) tileEntities.get(c);
|
||||
Collection<?>[] entities = (Collection<?>[]) entitySlices.get(c);
|
||||
|
||||
Method getX = null;
|
||||
Method getY = null;
|
||||
Method getZ = null;
|
||||
|
||||
// Trim tiles
|
||||
boolean removed = false;
|
||||
Set<Map.Entry<?, ?>> entrySet = (Set<Map.Entry<?, ?>>) (Set<?>) tiles.entrySet();
|
||||
Iterator<Map.Entry<?, ?>> iterator = entrySet.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<?, ?> tile = iterator.next();
|
||||
Object pos = tile.getKey();
|
||||
if (getX == null) {
|
||||
Class<? extends Object> clazz2 = pos.getClass().getSuperclass();
|
||||
getX = clazz2.getDeclaredMethod("getX");
|
||||
getY = clazz2.getDeclaredMethod("getY");
|
||||
getZ = clazz2.getDeclaredMethod("getZ");
|
||||
}
|
||||
int lx = (int) getX.invoke(pos) & 15;
|
||||
int ly = (int) getY.invoke(pos);
|
||||
int lz = (int) getZ.invoke(pos) & 15;
|
||||
int j = MainUtil.CACHE_I[ly][lx][lz];
|
||||
int k = MainUtil.CACHE_J[ly][lx][lz];
|
||||
char[] array = fs.getIdArray(j);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
if (array[k] != 0) {
|
||||
removed = true;
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
if (removed) {
|
||||
((Collection) this.tileEntityListTick.of(w).get()).clear();
|
||||
}
|
||||
|
||||
// Trim entities
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if ((entities[i] != null) && (fs.getCount(i) >= 4096)) {
|
||||
entities[i].clear();
|
||||
}
|
||||
}
|
||||
|
||||
// Efficiently merge sections
|
||||
for (int j = 0; j < sections.length; j++) {
|
||||
if (fs.getCount(j) == 0) {
|
||||
continue;
|
||||
}
|
||||
char[] newArray = fs.getIdArray(j);
|
||||
if (newArray == null) {
|
||||
continue;
|
||||
}
|
||||
Object section = sections[j];
|
||||
if ((section == null) || (fs.getCount(j) >= 4096)) {
|
||||
section = sections[j] = newChunkSection(j << 4, flag, newArray);
|
||||
continue;
|
||||
}
|
||||
char[] currentArray = getIdArray(section);
|
||||
boolean fill = true;
|
||||
for (int k = 0; k < newArray.length; k++) {
|
||||
char n = newArray[k];
|
||||
switch (n) {
|
||||
case 0:
|
||||
fill = false;
|
||||
continue;
|
||||
case 1:
|
||||
fill = false;
|
||||
currentArray[k] = 0;
|
||||
continue;
|
||||
default:
|
||||
currentArray[k] = n;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (fill) {
|
||||
fs.setCount(j, Short.MAX_VALUE);
|
||||
}
|
||||
}
|
||||
// Clear
|
||||
} catch (IllegalArgumentException | SecurityException | ReflectiveOperationException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
fixLighting(chunk, fs, true);
|
||||
}
|
||||
|
||||
public Object newChunkSection(int i, boolean flag, char[] ids)
|
||||
throws ReflectiveOperationException {
|
||||
return this.classChunkSectionConstructor.create(i, flag, ids);
|
||||
}
|
||||
|
||||
public char[] getIdArray(Object obj) {
|
||||
return (char[]) this.methodGetIdArray.of(obj).call();
|
||||
}
|
||||
|
||||
@Override public void fixChunkLighting(int x, int z) {
|
||||
Object c = this.methodGetHandleChunk.of(getChunk(x, z)).call();
|
||||
this.methodInitLighting.of(c).call();
|
||||
}
|
||||
|
||||
public boolean fixLighting(Chunk chunk, CharLocalChunk_1_8_3 bc, boolean fixAll) {
|
||||
try {
|
||||
if (!chunk.isLoaded()) {
|
||||
chunk.load(false);
|
||||
} else {
|
||||
chunk.unload(true, false);
|
||||
chunk.load(false);
|
||||
}
|
||||
|
||||
// Initialize lighting
|
||||
Object c = this.methodGetHandleChunk.of(chunk).call();
|
||||
|
||||
if (fixAll && !(boolean) this.methodAreNeighborsLoaded.of(c).call(1)) {
|
||||
World world = chunk.getWorld();
|
||||
ChunkWrapper wrapper = new ChunkWrapper(getWorld(), chunk.getX(), chunk.getZ());
|
||||
for (int x = wrapper.x - 1; x <= wrapper.x + 1; x++) {
|
||||
for (int z = wrapper.z - 1; z <= wrapper.z + 1; z++) {
|
||||
if (x != 0 && z != 0) {
|
||||
Chunk other = world.getChunkAt(x, z);
|
||||
while (!other.isLoaded()) {
|
||||
other.load(true);
|
||||
}
|
||||
ChunkManager.manager.loadChunk(wrapper.world, new ChunkLoc(x, z), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
if (!(boolean) methodAreNeighborsLoaded.of(c).call(1)) {
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
this.methodInitLighting.of(c).call();
|
||||
|
||||
if (bc.getTotalRelight() == 0 && !fixAll) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Object[] sections = (Object[]) this.fieldSections.of(c).get();
|
||||
Object w = this.fieldWorld.of(c).get();
|
||||
|
||||
int X = chunk.getX() << 4;
|
||||
int Z = chunk.getZ() << 4;
|
||||
|
||||
ReflectionUtils.RefMethod.RefExecutor relight = this.methodX.of(w);
|
||||
for (int j = 0; j < sections.length; j++) {
|
||||
Object section = sections[j];
|
||||
if (section == null) {
|
||||
continue;
|
||||
}
|
||||
if ((bc.getRelight(j) == 0 && !fixAll) || bc.getCount(j) == 0 || (
|
||||
bc.getCount(j) >= 4096 && bc.getAir(j) == 0)) {
|
||||
continue;
|
||||
}
|
||||
char[] array = getIdArray(section);
|
||||
int l = PseudoRandom.random.random(2);
|
||||
for (int k = 0; k < array.length; k++) {
|
||||
int i = array[k];
|
||||
if (i < 16) {
|
||||
continue;
|
||||
}
|
||||
short id = (short) (i >> 4);
|
||||
switch (id) { // Lighting
|
||||
default:
|
||||
if (!fixAll) {
|
||||
continue;
|
||||
}
|
||||
if ((k & 1) == l) {
|
||||
l = 1 - l;
|
||||
continue;
|
||||
}
|
||||
case 10:
|
||||
case 11:
|
||||
case 39:
|
||||
case 40:
|
||||
case 50:
|
||||
case 51:
|
||||
case 62:
|
||||
case 74:
|
||||
case 76:
|
||||
case 89:
|
||||
case 122:
|
||||
case 124:
|
||||
case 130:
|
||||
case 138:
|
||||
case 169:
|
||||
int x = MainUtil.x_loc[j][k];
|
||||
int y = MainUtil.y_loc[j][k];
|
||||
int z = MainUtil.z_loc[j][k];
|
||||
if (isSurrounded(sections, x, y, z)) {
|
||||
continue;
|
||||
}
|
||||
Object pos = this.classBlockPositionConstructor.create(X + x, y, Z + z);
|
||||
relight.call(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isSurrounded(Object[] sections, int x, int y, int z) {
|
||||
return isSolid(getId(sections, x, y + 1, z)) && isSolid(getId(sections, x + 1, y - 1, z))
|
||||
&& isSolid(getId(sections, x - 1, y, z)) && isSolid(getId(sections, x, y, z + 1))
|
||||
&& isSolid(getId(sections, x, y, z - 1));
|
||||
}
|
||||
|
||||
public boolean isSolid(int i) {
|
||||
return i != 0 && Material.getMaterial(i).isOccluding();
|
||||
}
|
||||
|
||||
public int getId(Object[] sections, int x, int y, int z) {
|
||||
if (x < 0 || x > 15 || z < 0 || z > 15) {
|
||||
return 1;
|
||||
}
|
||||
if (y < 0 || y > 255) {
|
||||
return 1;
|
||||
}
|
||||
int i = MainUtil.CACHE_I[y][x][z];
|
||||
Object section = sections[i];
|
||||
if (section == null) {
|
||||
return 0;
|
||||
}
|
||||
char[] array = getIdArray(section);
|
||||
int j = MainUtil.CACHE_J[y][x][z];
|
||||
return array[j] >> 4;
|
||||
}
|
||||
|
||||
public void update(Collection<Chunk> chunks) {
|
||||
if (chunks.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (!MainUtil.canSendChunk) {
|
||||
for (Chunk chunk : chunks) {
|
||||
chunk.getWorld().refreshChunk(chunk.getX(), chunk.getZ());
|
||||
chunk.unload(true, false);
|
||||
chunk.load();
|
||||
}
|
||||
return;
|
||||
}
|
||||
try {
|
||||
this.sendChunk.sendChunk(chunks);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
MainUtil.canSendChunk = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void refreshChunk(int x, int z) {
|
||||
update(Arrays.asList(Bukkit.getWorld(getWorld()).getChunkAt(x, z)));
|
||||
}
|
||||
|
||||
|
||||
public class CharLocalChunk_1_8_3 extends CharLocalChunk {
|
||||
public short[] count;
|
||||
public short[] air;
|
||||
public short[] relight;
|
||||
|
||||
public CharLocalChunk_1_8_3(BasicLocalBlockQueue parent, int x, int z) {
|
||||
super(parent, x, z);
|
||||
this.count = new short[16];
|
||||
this.air = new short[16];
|
||||
this.relight = new short[16];
|
||||
}
|
||||
|
||||
@Override public void setBlock(int x, int y, int z, int id, int data) {
|
||||
int i = MainUtil.CACHE_I[y][x][z];
|
||||
int j = MainUtil.CACHE_J[y][x][z];
|
||||
char[] vs = this.blocks[i];
|
||||
if (vs == null) {
|
||||
vs = this.blocks[i] = new char[4096];
|
||||
this.count[i]++;
|
||||
} else if (vs[j] == 0) {
|
||||
this.count[i]++;
|
||||
}
|
||||
switch (id) {
|
||||
case 0:
|
||||
this.air[i]++;
|
||||
vs[j] = (char) 1;
|
||||
return;
|
||||
case 10:
|
||||
case 11:
|
||||
case 39:
|
||||
case 40:
|
||||
case 51:
|
||||
case 74:
|
||||
case 89:
|
||||
case 122:
|
||||
case 124:
|
||||
case 138:
|
||||
case 169:
|
||||
this.relight[i]++;
|
||||
case 2:
|
||||
case 4:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
case 20:
|
||||
case 21:
|
||||
case 22:
|
||||
case 30:
|
||||
case 32:
|
||||
case 37:
|
||||
case 41:
|
||||
case 42:
|
||||
case 45:
|
||||
case 46:
|
||||
case 47:
|
||||
case 48:
|
||||
case 49:
|
||||
case 55:
|
||||
case 56:
|
||||
case 57:
|
||||
case 58:
|
||||
case 60:
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
case 73:
|
||||
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 129:
|
||||
case 133:
|
||||
case 165:
|
||||
case 166:
|
||||
case 170:
|
||||
case 172:
|
||||
case 173:
|
||||
case 174:
|
||||
case 181:
|
||||
case 182:
|
||||
case 188:
|
||||
case 189:
|
||||
case 190:
|
||||
case 191:
|
||||
case 192:
|
||||
vs[j] = (char) (id << 4);
|
||||
return;
|
||||
case 130:
|
||||
case 76:
|
||||
case 62:
|
||||
this.relight[i]++;
|
||||
case 54:
|
||||
case 146:
|
||||
case 61:
|
||||
case 65:
|
||||
case 68:
|
||||
case 50:
|
||||
if (data < 2) {
|
||||
data = 2;
|
||||
}
|
||||
default:
|
||||
vs[j] = (char) ((id << 4) + data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public char[] getIdArray(int i) {
|
||||
return this.blocks[i];
|
||||
}
|
||||
|
||||
public int getCount(int i) {
|
||||
return this.count[i];
|
||||
}
|
||||
|
||||
public int getAir(int i) {
|
||||
return this.air[i];
|
||||
}
|
||||
|
||||
public void setCount(int i, short value) {
|
||||
this.count[i] = value;
|
||||
}
|
||||
|
||||
public int getRelight(int i) {
|
||||
return this.relight[i];
|
||||
}
|
||||
|
||||
public int getTotalCount() {
|
||||
int total = 0;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
total += this.count[i];
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
public int getTotalRelight() {
|
||||
if (getTotalCount() == 0) {
|
||||
Arrays.fill(this.count, (short) 1);
|
||||
Arrays.fill(this.relight, Short.MAX_VALUE);
|
||||
return Short.MAX_VALUE;
|
||||
}
|
||||
int total = 0;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
total += this.relight[i];
|
||||
}
|
||||
return total;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,494 +0,0 @@
|
||||
package com.plotsquared.bukkit.util.block;
|
||||
|
||||
import com.intellectualcrafters.plot.object.ChunkWrapper;
|
||||
import com.intellectualcrafters.plot.object.PseudoRandom;
|
||||
import com.intellectualcrafters.plot.util.MainUtil;
|
||||
import com.intellectualcrafters.plot.util.ReflectionUtils;
|
||||
import com.intellectualcrafters.plot.util.block.BasicLocalBlockQueue;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
|
||||
import static com.intellectualcrafters.plot.util.ReflectionUtils.getRefClass;
|
||||
|
||||
public class BukkitLocalQueue_1_9 extends BukkitLocalQueue<char[]> {
|
||||
|
||||
private final Object air;
|
||||
// private final HashMap<ChunkWrapper, Chunk> toUpdate = new HashMap<>();
|
||||
private final ReflectionUtils.RefMethod methodGetHandleChunk;
|
||||
private final ReflectionUtils.RefMethod methodInitLighting;
|
||||
private final ReflectionUtils.RefConstructor classBlockPositionConstructor;
|
||||
private final ReflectionUtils.RefConstructor classChunkSectionConstructor;
|
||||
private final ReflectionUtils.RefMethod methodW;
|
||||
private final ReflectionUtils.RefMethod methodAreNeighborsLoaded;
|
||||
private final ReflectionUtils.RefField fieldSections;
|
||||
private final ReflectionUtils.RefField fieldWorld;
|
||||
private final ReflectionUtils.RefMethod methodGetBlocks;
|
||||
private final ReflectionUtils.RefMethod methodGetType;
|
||||
private final ReflectionUtils.RefMethod methodSetType;
|
||||
private final ReflectionUtils.RefMethod methodGetCombinedId;
|
||||
private final ReflectionUtils.RefMethod methodGetByCombinedId;
|
||||
private final ReflectionUtils.RefMethod methodGetWorld;
|
||||
|
||||
private final ReflectionUtils.RefField tileEntityListTick;
|
||||
|
||||
public BukkitLocalQueue_1_9(String world)
|
||||
throws NoSuchMethodException, ClassNotFoundException, NoSuchFieldException {
|
||||
super(world);
|
||||
ReflectionUtils.RefClass classCraftChunk = getRefClass("{cb}.CraftChunk");
|
||||
this.methodGetHandleChunk = classCraftChunk.getMethod("getHandle");
|
||||
ReflectionUtils.RefClass classChunk = getRefClass("{nms}.Chunk");
|
||||
this.methodInitLighting = classChunk.getMethod("initLighting");
|
||||
ReflectionUtils.RefClass classBlockPosition = getRefClass("{nms}.BlockPosition");
|
||||
this.classBlockPositionConstructor =
|
||||
classBlockPosition.getConstructor(int.class, int.class, int.class);
|
||||
ReflectionUtils.RefClass classWorld = getRefClass("{nms}.World");
|
||||
this.tileEntityListTick = classWorld.getField("tileEntityListTick");
|
||||
this.methodGetWorld = classChunk.getMethod("getWorld");
|
||||
this.methodW = classWorld.getMethod("w", classBlockPosition.getRealClass());
|
||||
this.fieldSections = classChunk.getField("sections");
|
||||
this.fieldWorld = classChunk.getField("world");
|
||||
ReflectionUtils.RefClass classBlock = getRefClass("{nms}.Block");
|
||||
ReflectionUtils.RefClass classIBlockData = getRefClass("{nms}.IBlockData");
|
||||
this.methodGetCombinedId =
|
||||
classBlock.getMethod("getCombinedId", classIBlockData.getRealClass());
|
||||
this.methodGetByCombinedId = classBlock.getMethod("getByCombinedId", int.class);
|
||||
ReflectionUtils.RefClass classChunkSection = getRefClass("{nms}.ChunkSection");
|
||||
this.methodGetBlocks = classChunkSection.getMethod("getBlocks");
|
||||
this.methodGetType =
|
||||
classChunkSection.getMethod("getType", int.class, int.class, int.class);
|
||||
this.methodSetType = classChunkSection
|
||||
.getMethod("setType", int.class, int.class, int.class, classIBlockData.getRealClass());
|
||||
this.methodAreNeighborsLoaded = classChunk.getMethod("areNeighborsLoaded", int.class);
|
||||
this.classChunkSectionConstructor =
|
||||
classChunkSection.getConstructor(int.class, boolean.class, char[].class);
|
||||
this.air = this.methodGetByCombinedId.call(0);
|
||||
MainUtil.initCache();
|
||||
}
|
||||
|
||||
@Override public LocalChunk<char[]> getLocalChunk(int x, int z) {
|
||||
return new CharLocalChunk_1_8_3(this, x, z);
|
||||
}
|
||||
|
||||
@Override public void setBlocks(LocalChunk lc) {
|
||||
CharLocalChunk_1_8_3 fs = (CharLocalChunk_1_8_3) lc;
|
||||
Chunk chunk = getChunk(lc.getX(), lc.getZ());
|
||||
chunk.load(true);
|
||||
World world = chunk.getWorld();
|
||||
try {
|
||||
boolean flag = world.getEnvironment() == World.Environment.NORMAL;
|
||||
|
||||
// Sections
|
||||
Method getHandle = chunk.getClass().getDeclaredMethod("getHandle");
|
||||
Object c = getHandle.invoke(chunk);
|
||||
Object w = this.methodGetWorld.of(c).call();
|
||||
Class<? extends Object> clazz = c.getClass();
|
||||
Field sf = clazz.getDeclaredField("sections");
|
||||
sf.setAccessible(true);
|
||||
Field tf = clazz.getDeclaredField("tileEntities");
|
||||
Field entitySlices = clazz.getDeclaredField("entitySlices");
|
||||
Object[] sections = (Object[]) sf.get(c);
|
||||
Map<?, ?> tiles = (Map<?, ?>) tf.get(c);
|
||||
Collection<?>[] entities = (Collection<?>[]) entitySlices.get(c);
|
||||
|
||||
Method xm = null;
|
||||
Method ym = null;
|
||||
Method zm = null;
|
||||
// Trim tiles
|
||||
Collection tickList = ((Collection) this.tileEntityListTick.of(w).get());
|
||||
Set<Map.Entry<?, ?>> entrySet = (Set<Map.Entry<?, ?>>) (Set<?>) tiles.entrySet();
|
||||
Iterator<Map.Entry<?, ?>> iterator = entrySet.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<?, ?> tile = iterator.next();
|
||||
Object pos = tile.getKey();
|
||||
if (xm == null) {
|
||||
Class<?> clazz2 = pos.getClass().getSuperclass();
|
||||
xm = clazz2.getDeclaredMethod("getX");
|
||||
ym = clazz2.getDeclaredMethod("getY");
|
||||
zm = clazz2.getDeclaredMethod("getZ");
|
||||
}
|
||||
int lx = (int) xm.invoke(pos) & 15;
|
||||
int ly = (int) ym.invoke(pos);
|
||||
int lz = (int) zm.invoke(pos) & 15;
|
||||
int j = MainUtil.CACHE_I[ly][lx][lz];
|
||||
int k = MainUtil.CACHE_J[ly][lx][lz];
|
||||
char[] array = fs.getIdArray(j);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
if (array[k] != 0) {
|
||||
tickList.remove(tile.getValue());
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
|
||||
// Trim entities
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if (entities[i] != null && fs.getCount(i) >= 4096) {
|
||||
entities[i].clear();
|
||||
}
|
||||
}
|
||||
|
||||
// Efficiently merge sections
|
||||
for (int j = 0; j < sections.length; j++) {
|
||||
if (fs.getCount(j) == 0) {
|
||||
continue;
|
||||
}
|
||||
char[] newArray = fs.getIdArray(j);
|
||||
if (newArray == null) {
|
||||
continue;
|
||||
}
|
||||
Object section = sections[j];
|
||||
if (section == null || fs.getCount(j) >= 4096) {
|
||||
section = sections[j] = newChunkSection(j << 4, flag, fs.getIdArray(j));
|
||||
continue;
|
||||
}
|
||||
Object currentArray = getBlocks(section);
|
||||
ReflectionUtils.RefMethod.RefExecutor setType = this.methodSetType.of(section);
|
||||
boolean fill = true;
|
||||
for (int k = 0; k < newArray.length; k++) {
|
||||
char n = newArray[k];
|
||||
switch (n) {
|
||||
case 0:
|
||||
fill = false;
|
||||
continue;
|
||||
case 1: {
|
||||
fill = false;
|
||||
int x = MainUtil.x_loc[j][k];
|
||||
int y = MainUtil.y_loc[j][k];
|
||||
int z = MainUtil.z_loc[j][k];
|
||||
setType.call(x, y & 15, z, this.air);
|
||||
continue;
|
||||
}
|
||||
default:
|
||||
int x = MainUtil.x_loc[j][k];
|
||||
int y = MainUtil.y_loc[j][k];
|
||||
int z = MainUtil.z_loc[j][k];
|
||||
int id = n >> 4;
|
||||
int data = n & 15;
|
||||
Object iBlock =
|
||||
this.methodGetByCombinedId.call((int) (id & 0xFFF) + (data << 12));
|
||||
setType.call(x, y & 15, z, iBlock);
|
||||
}
|
||||
}
|
||||
if (fill) {
|
||||
fs.setCount(j, Short.MAX_VALUE);
|
||||
}
|
||||
}
|
||||
// Clear
|
||||
} catch (IllegalArgumentException | SecurityException | ReflectiveOperationException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
fixLighting(chunk, fs, true);
|
||||
refreshChunk(fs.getX(), fs.getZ());
|
||||
}
|
||||
|
||||
public Object newChunkSection(int i, boolean flag, char[] ids)
|
||||
throws ReflectiveOperationException {
|
||||
return this.classChunkSectionConstructor.create(i, flag, ids);
|
||||
}
|
||||
|
||||
public Object getBlocks(Object obj) {
|
||||
return this.methodGetBlocks.of(obj).call();
|
||||
}
|
||||
|
||||
@Override public void fixChunkLighting(int x, int z) {
|
||||
Object c = this.methodGetHandleChunk.of(getChunk(x, z)).call();
|
||||
this.methodInitLighting.of(c).call();
|
||||
}
|
||||
|
||||
public boolean fixLighting(Chunk chunk, CharLocalChunk_1_8_3 bc, boolean fixAll) {
|
||||
try {
|
||||
if (!chunk.isLoaded()) {
|
||||
chunk.load(false);
|
||||
} else {
|
||||
chunk.unload(true, false);
|
||||
chunk.load(false);
|
||||
}
|
||||
|
||||
// Initialize lighting
|
||||
Object c = this.methodGetHandleChunk.of(chunk).call();
|
||||
|
||||
ChunkWrapper wrapper = new ChunkWrapper(getWorld(), bc.getX(), bc.getZ());
|
||||
Object[] result = disableLighting(chunk);
|
||||
enableLighting(result);
|
||||
|
||||
this.methodInitLighting.of(c).call();
|
||||
|
||||
if (bc.getTotalRelight() != 0 || fixAll) {
|
||||
Object[] sections = (Object[]) this.fieldSections.of(c).get();
|
||||
Object w = this.fieldWorld.of(c).get();
|
||||
|
||||
int X = chunk.getX() << 4;
|
||||
int Z = chunk.getZ() << 4;
|
||||
ReflectionUtils.RefMethod.RefExecutor relight = this.methodW.of(w);
|
||||
for (int j = 0; j < sections.length; j++) {
|
||||
Object section = sections[j];
|
||||
if (section == null) {
|
||||
continue;
|
||||
}
|
||||
if (bc.getRelight(j) == 0 && !fixAll || bc.getCount(j) == 0
|
||||
|| bc.getCount(j) >= 4096 && bc.getAir(j) == 0) {
|
||||
continue;
|
||||
}
|
||||
char[] array = bc.getIdArray(j);
|
||||
if (array != null) {
|
||||
int l = PseudoRandom.random.random(2);
|
||||
for (int k = 0; k < array.length; k++) {
|
||||
int i = array[k];
|
||||
if (i < 16) {
|
||||
continue;
|
||||
}
|
||||
short id = (short) (i >> 4);
|
||||
switch (id) { // Lighting
|
||||
default:
|
||||
if (!fixAll) {
|
||||
continue;
|
||||
}
|
||||
if ((k & 1) == l) {
|
||||
l = 1 - l;
|
||||
continue;
|
||||
}
|
||||
case 10:
|
||||
case 11:
|
||||
case 39:
|
||||
case 40:
|
||||
case 50:
|
||||
case 51:
|
||||
case 62:
|
||||
case 74:
|
||||
case 76:
|
||||
case 89:
|
||||
case 122:
|
||||
case 124:
|
||||
case 130:
|
||||
case 138:
|
||||
case 169:
|
||||
int x = MainUtil.x_loc[j][k];
|
||||
int y = MainUtil.y_loc[j][k];
|
||||
int z = MainUtil.z_loc[j][k];
|
||||
if (isSurrounded(bc.blocks, x, y, z)) {
|
||||
continue;
|
||||
}
|
||||
Object pos =
|
||||
this.classBlockPositionConstructor.create(X + x, y, Z + z);
|
||||
relight.call(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
resetLighting(result);
|
||||
return true;
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override public void refreshChunk(int x, int z) {
|
||||
getBukkitWorld().refreshChunk(x, z);
|
||||
}
|
||||
|
||||
public boolean isSurrounded(char[][] sections, int x, int y, int z) {
|
||||
return isSolid(getId(sections, x, y + 1, z)) && isSolid(getId(sections, x + 1, y - 1, z))
|
||||
&& isSolid(getId(sections, x - 1, y, z)) && isSolid(getId(sections, x, y, z + 1))
|
||||
&& isSolid(getId(sections, x, y, z - 1));
|
||||
}
|
||||
|
||||
public boolean isSolid(int i) {
|
||||
if (i != 0) {
|
||||
Material material = Material.getMaterial(i);
|
||||
return material != null && Material.getMaterial(i).isOccluding();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getId(char[] section, int x, int y, int z) {
|
||||
if (section == null) {
|
||||
return 0;
|
||||
}
|
||||
int j = MainUtil.CACHE_J[y][x][z];
|
||||
return section[j] >> 4;
|
||||
}
|
||||
|
||||
public int getId(char[][] sections, int x, int y, int z) {
|
||||
if (x < 0 || x > 15 || z < 0 || z > 15) {
|
||||
return 1;
|
||||
}
|
||||
if (y < 0 || y > 255) {
|
||||
return 1;
|
||||
}
|
||||
int i = MainUtil.CACHE_I[y][x][z];
|
||||
char[] section = sections[i];
|
||||
if (section == null) {
|
||||
return 0;
|
||||
}
|
||||
return getId(section, x, y, z);
|
||||
}
|
||||
|
||||
|
||||
public class CharLocalChunk_1_8_3 extends CharLocalChunk {
|
||||
public short[] count;
|
||||
public short[] air;
|
||||
public short[] relight;
|
||||
|
||||
public CharLocalChunk_1_8_3(BasicLocalBlockQueue parent, int x, int z) {
|
||||
super(parent, x, z);
|
||||
this.count = new short[16];
|
||||
this.air = new short[16];
|
||||
this.relight = new short[16];
|
||||
}
|
||||
|
||||
@Override public void setBlock(int x, int y, int z, int id, int data) {
|
||||
int i = MainUtil.CACHE_I[y][x][z];
|
||||
int j = MainUtil.CACHE_J[y][x][z];
|
||||
char[] vs = this.blocks[i];
|
||||
if (vs == null) {
|
||||
vs = this.blocks[i] = new char[4096];
|
||||
this.count[i]++;
|
||||
} else if (vs[j] == 0) {
|
||||
this.count[i]++;
|
||||
}
|
||||
switch (id) {
|
||||
case 0:
|
||||
this.air[i]++;
|
||||
vs[j] = (char) 1;
|
||||
return;
|
||||
case 10:
|
||||
case 11:
|
||||
case 39:
|
||||
case 40:
|
||||
case 51:
|
||||
case 74:
|
||||
case 89:
|
||||
case 122:
|
||||
case 124:
|
||||
case 138:
|
||||
case 169:
|
||||
this.relight[i]++;
|
||||
case 2:
|
||||
case 4:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
case 20:
|
||||
case 21:
|
||||
case 22:
|
||||
case 30:
|
||||
case 32:
|
||||
case 37:
|
||||
case 41:
|
||||
case 42:
|
||||
case 45:
|
||||
case 46:
|
||||
case 47:
|
||||
case 48:
|
||||
case 49:
|
||||
case 55:
|
||||
case 56:
|
||||
case 57:
|
||||
case 58:
|
||||
case 60:
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
case 73:
|
||||
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 129:
|
||||
case 133:
|
||||
case 165:
|
||||
case 166:
|
||||
case 170:
|
||||
case 172:
|
||||
case 173:
|
||||
case 174:
|
||||
case 181:
|
||||
case 182:
|
||||
case 188:
|
||||
case 189:
|
||||
case 190:
|
||||
case 191:
|
||||
case 192:
|
||||
vs[j] = (char) (id << 4);
|
||||
return;
|
||||
case 130:
|
||||
case 76:
|
||||
case 62:
|
||||
this.relight[i]++;
|
||||
case 54:
|
||||
case 146:
|
||||
case 61:
|
||||
case 65:
|
||||
case 68:
|
||||
case 50:
|
||||
if (data < 2) {
|
||||
data = 2;
|
||||
}
|
||||
default:
|
||||
vs[j] = (char) ((id << 4) + data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public char[] getIdArray(int i) {
|
||||
return this.blocks[i];
|
||||
}
|
||||
|
||||
public int getCount(int i) {
|
||||
return this.count[i];
|
||||
}
|
||||
|
||||
public int getAir(int i) {
|
||||
return this.air[i];
|
||||
}
|
||||
|
||||
public void setCount(int i, short value) {
|
||||
this.count[i] = value;
|
||||
}
|
||||
|
||||
public int getRelight(int i) {
|
||||
return this.relight[i];
|
||||
}
|
||||
|
||||
public int getTotalCount() {
|
||||
int total = 0;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
total += this.count[i];
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
public int getTotalRelight() {
|
||||
if (getTotalCount() == 0) {
|
||||
Arrays.fill(this.count, (short) 1);
|
||||
Arrays.fill(this.relight, Short.MAX_VALUE);
|
||||
return Short.MAX_VALUE;
|
||||
}
|
||||
int total = 0;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
total += this.relight[i];
|
||||
}
|
||||
return total;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,209 +0,0 @@
|
||||
package com.plotsquared.bukkit.util.block;
|
||||
|
||||
import com.intellectualcrafters.plot.object.ChunkWrapper;
|
||||
import com.intellectualcrafters.plot.object.Location;
|
||||
import com.intellectualcrafters.plot.object.PlotBlock;
|
||||
import com.intellectualcrafters.plot.util.MainUtil;
|
||||
import com.intellectualcrafters.plot.util.block.ScopedLocalBlockQueue;
|
||||
import com.plotsquared.bukkit.util.BukkitUtil;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.generator.ChunkGenerator.BiomeGrid;
|
||||
import org.bukkit.generator.ChunkGenerator.ChunkData;
|
||||
import org.bukkit.material.MaterialData;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class GenChunk extends ScopedLocalBlockQueue {
|
||||
|
||||
public final Biome[] biomes;
|
||||
public short[][] result;
|
||||
public byte[][] result_data;
|
||||
public ChunkData cd;
|
||||
public BiomeGrid grid;
|
||||
|
||||
public Chunk chunk;
|
||||
public String world;
|
||||
public int cx;
|
||||
public int cz;
|
||||
|
||||
public GenChunk(Chunk chunk, ChunkWrapper wrap) {
|
||||
super(null, new Location(null, 0, 0, 0), new Location(null, 15, 255, 15));
|
||||
this.biomes = Biome.values();
|
||||
}
|
||||
|
||||
public void setChunk(Chunk chunk) {
|
||||
this.chunk = chunk;
|
||||
}
|
||||
|
||||
public Chunk getChunk() {
|
||||
if (chunk == null) {
|
||||
World worldObj = BukkitUtil.getWorld(world);
|
||||
if (worldObj != null) {
|
||||
this.chunk = worldObj.getChunkAt(cx, cz);
|
||||
}
|
||||
}
|
||||
return chunk;
|
||||
}
|
||||
|
||||
public void setChunk(ChunkWrapper wrap) {
|
||||
chunk = null;
|
||||
world = wrap.world;
|
||||
cx = wrap.x;
|
||||
cz = wrap.z;
|
||||
}
|
||||
|
||||
public ChunkWrapper getChunkWrapper() {
|
||||
if (chunk == null) {
|
||||
return new ChunkWrapper(world, cx, cz);
|
||||
}
|
||||
return new ChunkWrapper(chunk.getWorld().getName(), chunk.getX(), chunk.getZ());
|
||||
}
|
||||
|
||||
@Override public void fillBiome(String biomeName) {
|
||||
if (grid == null) {
|
||||
return;
|
||||
}
|
||||
Biome biome = Biome.valueOf(biomeName.toUpperCase());
|
||||
for (int x = 0; x < 16; x++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
this.grid.setBiome(x, z, biome);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void setCuboid(Location pos1, Location pos2, PlotBlock block) {
|
||||
if (block.data == 0 && result != null && pos1.getX() == 0 && pos1.getZ() == 0
|
||||
&& pos2.getX() == 15 && pos2.getZ() == 15) {
|
||||
for (int y = pos1.getY(); y <= pos2.getY(); y++) {
|
||||
int layer = y >> 4;
|
||||
short[] data = result[layer];
|
||||
if (data == null) {
|
||||
result[layer] = data = new short[4096];
|
||||
}
|
||||
int start = y << 8;
|
||||
int end = start + 256;
|
||||
Arrays.fill(data, start, end, block.id);
|
||||
}
|
||||
} else {
|
||||
super.setCuboid(pos1, pos2, block);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public boolean setBiome(int x, int z, String biome) {
|
||||
return setBiome(x, z, Biome.valueOf(biome.toUpperCase()));
|
||||
}
|
||||
|
||||
public boolean setBiome(int x, int z, int biome) {
|
||||
if (this.grid != null) {
|
||||
this.grid.setBiome(x, z, this.biomes[biome]);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean setBiome(int x, int z, Biome biome) {
|
||||
if (this.grid != null) {
|
||||
this.grid.setBiome(x, z, biome);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override public boolean setBlock(int x, int y, int z, int id, int data) {
|
||||
if (this.result == null) {
|
||||
this.cd.setBlock(x, y, z, new MaterialData(Material.getMaterial(id), (byte) data));
|
||||
return true;
|
||||
}
|
||||
int i = MainUtil.CACHE_I[y][x][z];
|
||||
short[] v = this.result[i];
|
||||
if (v == null) {
|
||||
this.result[i] = v = new short[4096];
|
||||
}
|
||||
int j = MainUtil.CACHE_J[y][x][z];
|
||||
v[j] = (short) id;
|
||||
if (data != 0) {
|
||||
byte[] vd = this.result_data[i];
|
||||
if (vd == null) {
|
||||
this.result_data[i] = vd = new byte[4096];
|
||||
}
|
||||
vd[j] = (byte) data;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override public PlotBlock getBlock(int x, int y, int z) {
|
||||
int i = MainUtil.CACHE_I[y][x][z];
|
||||
if (result == null) {
|
||||
MaterialData md = cd.getTypeAndData(x, y, z);
|
||||
return PlotBlock.get(md.getItemTypeId(), md.getData());
|
||||
}
|
||||
short[] array = result[i];
|
||||
if (array == null) {
|
||||
return PlotBlock.get(0, 0);
|
||||
}
|
||||
int j = MainUtil.CACHE_J[y][x][z];
|
||||
short id = array[j];
|
||||
if (id == 0) {
|
||||
return PlotBlock.get(id, 0);
|
||||
}
|
||||
byte[] dataArray = result_data[i];
|
||||
if (dataArray == null) {
|
||||
return PlotBlock.get(id, 0);
|
||||
}
|
||||
return PlotBlock.get(id, dataArray[j]);
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return chunk == null ? cx : chunk.getX();
|
||||
}
|
||||
|
||||
public int getZ() {
|
||||
return chunk == null ? cz : chunk.getZ();
|
||||
}
|
||||
|
||||
@Override public String getWorld() {
|
||||
return chunk == null ? world : chunk.getWorld().getName();
|
||||
}
|
||||
|
||||
@Override public Location getMax() {
|
||||
return new Location(getWorld(), 15 + (getX() << 4), 255, 15 + (getZ() << 4));
|
||||
}
|
||||
|
||||
@Override public Location getMin() {
|
||||
return new Location(getWorld(), getX() << 4, 0, getZ() << 4);
|
||||
}
|
||||
|
||||
public GenChunk clone() {
|
||||
GenChunk toReturn =
|
||||
new GenChunk(chunk, new ChunkWrapper(getWorld(), chunk.getX(), chunk.getZ()));
|
||||
if (this.result != null) {
|
||||
for (int i = 0; i < this.result.length; i++) {
|
||||
short[] matrix = this.result[i];
|
||||
if (matrix != null) {
|
||||
toReturn.result[i] = new short[matrix.length];
|
||||
System.arraycopy(matrix, 0, toReturn.result[i], 0, matrix.length);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < this.result_data.length; i++) {
|
||||
byte[] matrix = this.result_data[i];
|
||||
if (matrix != null) {
|
||||
toReturn.result_data[i] = new byte[matrix.length];
|
||||
System.arraycopy(matrix, 0, toReturn.result_data[i], 0, matrix.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
toReturn.cd = this.cd;
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
public GenChunk shallowClone() {
|
||||
GenChunk toReturn = new GenChunk(chunk, new ChunkWrapper(getWorld(), getX(), getZ()));
|
||||
toReturn.result = this.result;
|
||||
toReturn.result_data = this.result_data;
|
||||
toReturn.cd = this.cd;
|
||||
return toReturn;
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
package com.plotsquared.bukkit.uuid;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
|
||||
public class DatFileFilter implements FilenameFilter {
|
||||
|
||||
@Override public boolean accept(File dir, String name) {
|
||||
return name.endsWith(".dat");
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
package com.plotsquared.bukkit.uuid;
|
||||
|
||||
import com.intellectualcrafters.plot.object.OfflinePlotPlayer;
|
||||
import com.intellectualcrafters.plot.object.PlotPlayer;
|
||||
import com.intellectualcrafters.plot.uuid.UUIDWrapper;
|
||||
import com.plotsquared.bukkit.object.BukkitOfflinePlayer;
|
||||
import com.plotsquared.bukkit.object.BukkitPlayer;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class DefaultUUIDWrapper extends UUIDWrapper {
|
||||
|
||||
@Override public UUID getUUID(PlotPlayer player) {
|
||||
return ((BukkitPlayer) player).player.getUniqueId();
|
||||
}
|
||||
|
||||
@Override public UUID getUUID(OfflinePlotPlayer player) {
|
||||
return player.getUUID();
|
||||
}
|
||||
|
||||
@Override public OfflinePlotPlayer getOfflinePlayer(UUID uuid) {
|
||||
return new BukkitOfflinePlayer(Bukkit.getOfflinePlayer(uuid));
|
||||
}
|
||||
|
||||
@Override public UUID getUUID(String name) {
|
||||
return Bukkit.getOfflinePlayer(name).getUniqueId();
|
||||
}
|
||||
|
||||
@Override public OfflinePlotPlayer[] getOfflinePlayers() {
|
||||
OfflinePlayer[] ops = Bukkit.getOfflinePlayers();
|
||||
BukkitOfflinePlayer[] toReturn = new BukkitOfflinePlayer[ops.length];
|
||||
for (int i = 0; i < ops.length; i++) {
|
||||
toReturn[i] = new BukkitOfflinePlayer(ops[i]);
|
||||
}
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
@Override public OfflinePlotPlayer getOfflinePlayer(String name) {
|
||||
return new BukkitOfflinePlayer(Bukkit.getOfflinePlayer(name));
|
||||
}
|
||||
}
|
@ -1,249 +0,0 @@
|
||||
package com.plotsquared.bukkit.uuid;
|
||||
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellectualcrafters.plot.PS;
|
||||
import com.intellectualcrafters.plot.config.C;
|
||||
import com.intellectualcrafters.plot.config.Settings;
|
||||
import com.intellectualcrafters.plot.object.OfflinePlotPlayer;
|
||||
import com.intellectualcrafters.plot.object.RunnableVal;
|
||||
import com.intellectualcrafters.plot.object.StringWrapper;
|
||||
import com.intellectualcrafters.plot.util.StringMan;
|
||||
import com.intellectualcrafters.plot.util.TaskManager;
|
||||
import com.intellectualcrafters.plot.util.UUIDHandler;
|
||||
import com.intellectualcrafters.plot.util.UUIDHandlerImplementation;
|
||||
import com.intellectualcrafters.plot.util.expiry.ExpireManager;
|
||||
import com.intellectualcrafters.plot.uuid.UUIDWrapper;
|
||||
import com.plotsquared.bukkit.util.NbtFactory;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class FileUUIDHandler extends UUIDHandlerImplementation {
|
||||
|
||||
public FileUUIDHandler(UUIDWrapper wrapper) {
|
||||
super(wrapper);
|
||||
}
|
||||
|
||||
@Override public boolean startCaching(Runnable whenDone) {
|
||||
return super.startCaching(whenDone) && cache(whenDone);
|
||||
}
|
||||
|
||||
public boolean cache(final Runnable whenDone) {
|
||||
final File container = Bukkit.getWorldContainer();
|
||||
List<World> worlds = Bukkit.getWorlds();
|
||||
final String world;
|
||||
if (worlds.isEmpty()) {
|
||||
world = "world";
|
||||
} else {
|
||||
world = worlds.get(0).getName();
|
||||
}
|
||||
TaskManager.runTaskAsync(new Runnable() {
|
||||
@Override public void run() {
|
||||
PS.debug(C.PREFIX + "&6Starting player data caching for: " + world);
|
||||
File uuidFile = new File(PS.get().IMP.getDirectory(), "uuids.txt");
|
||||
if (uuidFile.exists()) {
|
||||
try {
|
||||
List<String> lines =
|
||||
Files.readAllLines(uuidFile.toPath(), StandardCharsets.UTF_8);
|
||||
for (String line : lines) {
|
||||
try {
|
||||
line = line.trim();
|
||||
if (line.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
line = line.replaceAll("[\\|][0-9]+[\\|][0-9]+[\\|]", "");
|
||||
String[] split = line.split("\\|");
|
||||
String name = split[0];
|
||||
if (name.isEmpty() || (name.length() > 16) || !StringMan
|
||||
.isAlphanumericUnd(name)) {
|
||||
continue;
|
||||
}
|
||||
UUID uuid = FileUUIDHandler.this.uuidWrapper.getUUID(name);
|
||||
if (uuid == null) {
|
||||
continue;
|
||||
}
|
||||
UUIDHandler.add(new StringWrapper(name), uuid);
|
||||
} catch (Exception e2) {
|
||||
e2.printStackTrace();
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
HashBiMap<StringWrapper, UUID> toAdd =
|
||||
HashBiMap.create(new HashMap<StringWrapper, UUID>());
|
||||
if (Settings.UUID.NATIVE_UUID_PROVIDER) {
|
||||
HashSet<UUID> all = UUIDHandler.getAllUUIDS();
|
||||
PS.debug("&aFast mode UUID caching enabled!");
|
||||
File playerDataFolder =
|
||||
new File(container, world + File.separator + "playerdata");
|
||||
String[] dat = playerDataFolder.list(new DatFileFilter());
|
||||
boolean check = all.isEmpty();
|
||||
if (dat != null) {
|
||||
for (String current : dat) {
|
||||
String s = current.replaceAll(".dat$", "");
|
||||
try {
|
||||
UUID uuid = UUID.fromString(s);
|
||||
if (check || all.remove(uuid)) {
|
||||
File file = new File(playerDataFolder, current);
|
||||
NbtFactory.NbtCompound compound = NbtFactory
|
||||
.fromStream(new FileInputStream(file),
|
||||
NbtFactory.StreamOptions.GZIP_COMPRESSION);
|
||||
if (!compound.containsKey("bukkit")) {
|
||||
PS.debug("ERROR: Player data (" + uuid.toString()
|
||||
+ ".dat) does not contain the the key \"bukkit\"");
|
||||
} else {
|
||||
NbtFactory.NbtCompound bukkit =
|
||||
(NbtFactory.NbtCompound) compound.get("bukkit");
|
||||
String name = (String) bukkit.get("lastKnownName");
|
||||
long last = (long) bukkit.get("lastPlayed");
|
||||
long first = (long) bukkit.get("firstPlayed");
|
||||
if (ExpireManager.IMP != null) {
|
||||
ExpireManager.IMP.storeDate(uuid, last);
|
||||
ExpireManager.IMP.storeAccountAge(uuid, last - first);
|
||||
}
|
||||
toAdd.put(new StringWrapper(name), uuid);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
PS.debug(C.PREFIX + "Invalid playerdata: " + current);
|
||||
}
|
||||
}
|
||||
}
|
||||
add(toAdd);
|
||||
if (all.isEmpty()) {
|
||||
if (whenDone != null) {
|
||||
whenDone.run();
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
PS.debug("Failed to cache: " + all.size()
|
||||
+ " uuids - slowly processing all files");
|
||||
}
|
||||
}
|
||||
HashSet<String> worlds = Sets.newHashSet(world, "world");
|
||||
HashSet<UUID> uuids = new HashSet<>();
|
||||
HashSet<String> names = new HashSet<>();
|
||||
File playerDataFolder = null;
|
||||
for (String worldName : worlds) {
|
||||
// Getting UUIDs
|
||||
playerDataFolder =
|
||||
new File(container, worldName + File.separator + "playerdata");
|
||||
String[] dat = playerDataFolder.list(new DatFileFilter());
|
||||
if ((dat != null) && (dat.length != 0)) {
|
||||
for (String current : dat) {
|
||||
String s = current.replaceAll(".dat$", "");
|
||||
try {
|
||||
UUID uuid = UUID.fromString(s);
|
||||
uuids.add(uuid);
|
||||
} catch (Exception ignored) {
|
||||
PS.debug(C.PREFIX + "Invalid PlayerData: " + current);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Getting names
|
||||
File playersFolder = new File(worldName + File.separator + "players");
|
||||
dat = playersFolder.list(new DatFileFilter());
|
||||
if ((dat != null) && (dat.length != 0)) {
|
||||
for (String current : dat) {
|
||||
names.add(current.replaceAll(".dat$", ""));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (UUID uuid : uuids) {
|
||||
try {
|
||||
File file =
|
||||
new File(playerDataFolder + File.separator + uuid.toString() + ".dat");
|
||||
if (!file.exists()) {
|
||||
continue;
|
||||
}
|
||||
NbtFactory.NbtCompound compound = NbtFactory
|
||||
.fromStream(new FileInputStream(file),
|
||||
NbtFactory.StreamOptions.GZIP_COMPRESSION);
|
||||
if (!compound.containsKey("bukkit")) {
|
||||
PS.debug("ERROR: Player data (" + uuid.toString()
|
||||
+ ".dat) does not contain the the key \"bukkit\"");
|
||||
} else {
|
||||
NbtFactory.NbtCompound bukkit =
|
||||
(NbtFactory.NbtCompound) compound.get("bukkit");
|
||||
String name = (String) bukkit.get("lastKnownName");
|
||||
StringWrapper wrap = new StringWrapper(name);
|
||||
if (!toAdd.containsKey(wrap)) {
|
||||
long last = (long) bukkit.get("lastPlayed");
|
||||
long first = (long) bukkit.get("firstPlayed");
|
||||
if (Settings.UUID.OFFLINE) {
|
||||
if (Settings.UUID.FORCE_LOWERCASE && !name.toLowerCase()
|
||||
.equals(name)) {
|
||||
uuid = FileUUIDHandler.this.uuidWrapper.getUUID(name);
|
||||
} else {
|
||||
long most = (long) compound.get("UUIDMost");
|
||||
long least = (long) compound.get("UUIDLeast");
|
||||
uuid = new UUID(most, least);
|
||||
}
|
||||
}
|
||||
if (ExpireManager.IMP != null) {
|
||||
ExpireManager.IMP.storeDate(uuid, last);
|
||||
ExpireManager.IMP.storeAccountAge(uuid, last - first);
|
||||
}
|
||||
toAdd.put(wrap, uuid);
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
PS.debug(C.PREFIX + "&6Invalid PlayerData: " + uuid.toString() + ".dat");
|
||||
}
|
||||
}
|
||||
for (String name : names) {
|
||||
UUID uuid = FileUUIDHandler.this.uuidWrapper.getUUID(name);
|
||||
StringWrapper nameWrap = new StringWrapper(name);
|
||||
toAdd.put(nameWrap, uuid);
|
||||
}
|
||||
|
||||
if (getUUIDMap().isEmpty()) {
|
||||
for (OfflinePlotPlayer op : FileUUIDHandler.this.uuidWrapper
|
||||
.getOfflinePlayers()) {
|
||||
long last = op.getLastPlayed();
|
||||
if (last != 0) {
|
||||
String name = op.getName();
|
||||
StringWrapper wrap = new StringWrapper(name);
|
||||
if (!toAdd.containsKey(wrap)) {
|
||||
UUID uuid = FileUUIDHandler.this.uuidWrapper.getUUID(op);
|
||||
toAdd.put(wrap, uuid);
|
||||
if (ExpireManager.IMP != null) {
|
||||
ExpireManager.IMP.storeDate(uuid, last);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
add(toAdd);
|
||||
if (whenDone != null) {
|
||||
whenDone.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override public void fetchUUID(final String name, final RunnableVal<UUID> ifFetch) {
|
||||
TaskManager.runTaskAsync(new Runnable() {
|
||||
@Override public void run() {
|
||||
ifFetch.value = FileUUIDHandler.this.uuidWrapper.getUUID(name);
|
||||
TaskManager.runTask(ifFetch);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
package com.plotsquared.bukkit.uuid;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.intellectualcrafters.plot.object.OfflinePlotPlayer;
|
||||
import com.intellectualcrafters.plot.object.PlotPlayer;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class LowerOfflineUUIDWrapper extends OfflineUUIDWrapper {
|
||||
|
||||
@Override public UUID getUUID(PlotPlayer player) {
|
||||
return UUID.nameUUIDFromBytes(
|
||||
("OfflinePlayer:" + player.getName().toLowerCase()).getBytes(Charsets.UTF_8));
|
||||
}
|
||||
|
||||
@Override public UUID getUUID(OfflinePlotPlayer player) {
|
||||
return UUID.nameUUIDFromBytes(
|
||||
("OfflinePlayer:" + player.getName().toLowerCase()).getBytes(Charsets.UTF_8));
|
||||
}
|
||||
|
||||
@Override public UUID getUUID(OfflinePlayer player) {
|
||||
return UUID.nameUUIDFromBytes(
|
||||
("OfflinePlayer:" + player.getName().toLowerCase()).getBytes(Charsets.UTF_8));
|
||||
}
|
||||
|
||||
@Override public UUID getUUID(String name) {
|
||||
return UUID
|
||||
.nameUUIDFromBytes(("OfflinePlayer:" + name.toLowerCase()).getBytes(Charsets.UTF_8));
|
||||
}
|
||||
|
||||
}
|
@ -1,108 +0,0 @@
|
||||
package com.plotsquared.bukkit.uuid;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.intellectualcrafters.plot.PS;
|
||||
import com.intellectualcrafters.plot.object.OfflinePlotPlayer;
|
||||
import com.intellectualcrafters.plot.object.PlotPlayer;
|
||||
import com.intellectualcrafters.plot.object.StringWrapper;
|
||||
import com.intellectualcrafters.plot.util.UUIDHandler;
|
||||
import com.intellectualcrafters.plot.uuid.UUIDWrapper;
|
||||
import com.plotsquared.bukkit.object.BukkitOfflinePlayer;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collection;
|
||||
import java.util.UUID;
|
||||
|
||||
public class OfflineUUIDWrapper extends UUIDWrapper {
|
||||
|
||||
private final Object[] arg = new Object[0];
|
||||
private Method getOnline = null;
|
||||
|
||||
public OfflineUUIDWrapper() {
|
||||
try {
|
||||
this.getOnline = Server.class.getMethod("getOnlinePlayers");
|
||||
} catch (NoSuchMethodException | SecurityException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override public UUID getUUID(PlotPlayer player) {
|
||||
return UUID
|
||||
.nameUUIDFromBytes(("OfflinePlayer:" + player.getName()).getBytes(Charsets.UTF_8));
|
||||
}
|
||||
|
||||
@Override public UUID getUUID(OfflinePlotPlayer player) {
|
||||
return UUID
|
||||
.nameUUIDFromBytes(("OfflinePlayer:" + player.getName()).getBytes(Charsets.UTF_8));
|
||||
}
|
||||
|
||||
public UUID getUUID(OfflinePlayer player) {
|
||||
return UUID
|
||||
.nameUUIDFromBytes(("OfflinePlayer:" + player.getName()).getBytes(Charsets.UTF_8));
|
||||
}
|
||||
|
||||
@Override public OfflinePlotPlayer getOfflinePlayer(UUID uuid) {
|
||||
BiMap<UUID, StringWrapper> map = UUIDHandler.getUuidMap().inverse();
|
||||
String name = null;
|
||||
if (map.containsKey(uuid)) {
|
||||
name = map.get(uuid).value;
|
||||
}
|
||||
if (name != null) {
|
||||
OfflinePlayer op = Bukkit.getOfflinePlayer(name);
|
||||
if (op.hasPlayedBefore()) {
|
||||
return new BukkitOfflinePlayer(op);
|
||||
}
|
||||
}
|
||||
for (OfflinePlayer player : Bukkit.getOfflinePlayers()) {
|
||||
if (getUUID(player).equals(uuid)) {
|
||||
return new BukkitOfflinePlayer(player);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Player[] getOnlinePlayers() {
|
||||
if (this.getOnline == null) {
|
||||
Collection<? extends Player> onlinePlayers = Bukkit.getOnlinePlayers();
|
||||
return onlinePlayers.toArray(new Player[onlinePlayers.size()]);
|
||||
}
|
||||
try {
|
||||
Object players = this.getOnline.invoke(Bukkit.getServer(), this.arg);
|
||||
if (players instanceof Player[]) {
|
||||
return (Player[]) players;
|
||||
} else {
|
||||
@SuppressWarnings("unchecked") Collection<? extends Player> p =
|
||||
(Collection<? extends Player>) players;
|
||||
return p.toArray(new Player[p.size()]);
|
||||
}
|
||||
} catch (IllegalAccessException | InvocationTargetException | IllegalArgumentException ignored) {
|
||||
PS.debug("Failed to resolve online players");
|
||||
this.getOnline = null;
|
||||
Collection<? extends Player> onlinePlayers = Bukkit.getOnlinePlayers();
|
||||
return onlinePlayers.toArray(new Player[onlinePlayers.size()]);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public UUID getUUID(String name) {
|
||||
return UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes(Charsets.UTF_8));
|
||||
}
|
||||
|
||||
@Override public OfflinePlotPlayer[] getOfflinePlayers() {
|
||||
OfflinePlayer[] ops = Bukkit.getOfflinePlayers();
|
||||
BukkitOfflinePlayer[] toReturn = new BukkitOfflinePlayer[ops.length];
|
||||
for (int i = 0; i < ops.length; i++) {
|
||||
toReturn[i] = new BukkitOfflinePlayer(ops[i]);
|
||||
}
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
@Override public OfflinePlotPlayer getOfflinePlayer(String name) {
|
||||
return new BukkitOfflinePlayer(Bukkit.getOfflinePlayer(name));
|
||||
}
|
||||
}
|
@ -1,261 +0,0 @@
|
||||
package com.plotsquared.bukkit.uuid;
|
||||
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.intellectualcrafters.plot.PS;
|
||||
import com.intellectualcrafters.plot.config.C;
|
||||
import com.intellectualcrafters.plot.config.Settings;
|
||||
import com.intellectualcrafters.plot.database.SQLite;
|
||||
import com.intellectualcrafters.plot.object.RunnableVal;
|
||||
import com.intellectualcrafters.plot.object.StringWrapper;
|
||||
import com.intellectualcrafters.plot.util.MainUtil;
|
||||
import com.intellectualcrafters.plot.util.TaskManager;
|
||||
import com.intellectualcrafters.plot.util.UUIDHandler;
|
||||
import com.intellectualcrafters.plot.util.UUIDHandlerImplementation;
|
||||
import com.intellectualcrafters.plot.uuid.UUIDWrapper;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
import org.json.simple.parser.ParseException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
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.ArrayDeque;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.UUID;
|
||||
|
||||
public class SQLUUIDHandler extends UUIDHandlerImplementation {
|
||||
|
||||
final int MAX_REQUESTS = 500;
|
||||
private final String PROFILE_URL =
|
||||
"https://sessionserver.mojang.com/session/minecraft/profile/";
|
||||
private final int INTERVAL = 12000;
|
||||
private final JSONParser jsonParser = new JSONParser();
|
||||
private final SQLite sqlite;
|
||||
|
||||
public SQLUUIDHandler(UUIDWrapper wrapper) {
|
||||
super(wrapper);
|
||||
this.sqlite = new SQLite(MainUtil.getFile(PS.get().IMP.getDirectory(), "usercache.db"));
|
||||
try {
|
||||
this.sqlite.openConnection();
|
||||
} catch (ClassNotFoundException | SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try (PreparedStatement stmt = getConnection().prepareStatement(
|
||||
"CREATE TABLE IF NOT EXISTS `usercache` (uuid VARCHAR(32) NOT NULL, username VARCHAR(32) NOT NULL, PRIMARY KEY (uuid, username)"
|
||||
+ ')')) {
|
||||
stmt.execute();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
startCaching(null);
|
||||
}
|
||||
|
||||
private Connection getConnection() {
|
||||
synchronized (this.sqlite) {
|
||||
return this.sqlite.getConnection();
|
||||
}
|
||||
}
|
||||
|
||||
@Override public boolean startCaching(final Runnable whenDone) {
|
||||
if (!super.startCaching(whenDone)) {
|
||||
return false;
|
||||
}
|
||||
TaskManager.runTaskAsync(new Runnable() {
|
||||
@Override public void run() {
|
||||
try {
|
||||
HashBiMap<StringWrapper, UUID> toAdd =
|
||||
HashBiMap.create(new HashMap<StringWrapper, UUID>());
|
||||
try (PreparedStatement statement = getConnection()
|
||||
.prepareStatement("SELECT `uuid`, `username` FROM `usercache`");
|
||||
ResultSet resultSet = statement.executeQuery()) {
|
||||
while (resultSet.next()) {
|
||||
StringWrapper username =
|
||||
new StringWrapper(resultSet.getString("username"));
|
||||
UUID uuid = UUID.fromString(resultSet.getString("uuid"));
|
||||
toAdd.put(new StringWrapper(username.value), uuid);
|
||||
}
|
||||
}
|
||||
add(toAdd);
|
||||
// This should be called as long as there are some unknown plots
|
||||
final ArrayDeque<UUID> toFetch = new ArrayDeque<>();
|
||||
for (UUID u : UUIDHandler.getAllUUIDS()) {
|
||||
if (!uuidExists(u)) {
|
||||
toFetch.add(u);
|
||||
}
|
||||
}
|
||||
if (toFetch.isEmpty()) {
|
||||
if (whenDone != null) {
|
||||
whenDone.run();
|
||||
}
|
||||
return;
|
||||
}
|
||||
FileUUIDHandler fileHandler =
|
||||
new FileUUIDHandler(SQLUUIDHandler.this.uuidWrapper);
|
||||
fileHandler.startCaching(new Runnable() {
|
||||
@Override public void run() {
|
||||
// If the file based UUID handler didn't cache it, then we can't cache offline mode
|
||||
// Also, trying to cache based on files again, is useless as that's what the file based uuid cacher does
|
||||
if (Settings.UUID.OFFLINE) {
|
||||
if (whenDone != null) {
|
||||
whenDone.run();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
TaskManager.runTaskAsync(new Runnable() {
|
||||
@Override public void run() {
|
||||
while (!toFetch.isEmpty()) {
|
||||
try {
|
||||
for (int i = 0;
|
||||
i < Math.min(500, toFetch.size()); i++) {
|
||||
UUID uuid = toFetch.pop();
|
||||
HttpURLConnection connection =
|
||||
(HttpURLConnection) new URL(
|
||||
SQLUUIDHandler.this.PROFILE_URL + uuid
|
||||
.toString().replace("-", ""))
|
||||
.openConnection();
|
||||
try (InputStream con = connection
|
||||
.getInputStream()) {
|
||||
InputStreamReader reader =
|
||||
new InputStreamReader(con);
|
||||
JSONObject response =
|
||||
(JSONObject) SQLUUIDHandler.this.jsonParser
|
||||
.parse(reader);
|
||||
String name = (String) response.get("name");
|
||||
if (name != null) {
|
||||
add(new StringWrapper(name), uuid);
|
||||
}
|
||||
}
|
||||
connection.disconnect();
|
||||
}
|
||||
} catch (IOException | ParseException e) {
|
||||
PS.debug(
|
||||
"Invalid response from Mojang: Some UUIDs will be cached later. (`unknown` until then or player joins)");
|
||||
}
|
||||
try {
|
||||
Thread.sleep(INTERVAL * 50);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (whenDone != null) {
|
||||
whenDone.run();
|
||||
}
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} catch (SQLException e) {
|
||||
throw new SQLUUIDHandlerException("Couldn't select :s", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override public void fetchUUID(final String name, final RunnableVal<UUID> ifFetch) {
|
||||
PS.debug(C.PREFIX + "UUID for '" + name
|
||||
+ "' was null. We'll cache this from the Mojang servers!");
|
||||
if (ifFetch == null) {
|
||||
return;
|
||||
}
|
||||
TaskManager.runTaskAsync(new Runnable() {
|
||||
@Override public void run() {
|
||||
try {
|
||||
URL url = new URL(SQLUUIDHandler.this.PROFILE_URL);
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod("POST");
|
||||
connection.setRequestProperty("Content-Type", "application/json");
|
||||
connection.setUseCaches(false);
|
||||
connection.setDoInput(true);
|
||||
connection.setDoOutput(true);
|
||||
String body = JSONArray.toJSONString(Collections.singletonList(name));
|
||||
OutputStream stream = connection.getOutputStream();
|
||||
stream.write(body.getBytes());
|
||||
stream.flush();
|
||||
stream.close();
|
||||
JSONArray array = (JSONArray) SQLUUIDHandler.this.jsonParser
|
||||
.parse(new InputStreamReader(connection.getInputStream()));
|
||||
JSONObject jsonProfile = (JSONObject) array.get(0);
|
||||
String id = (String) jsonProfile.get("id");
|
||||
String name = (String) jsonProfile.get("name");
|
||||
ifFetch.value = UUID.fromString(
|
||||
id.substring(0, 8) + '-' + id.substring(8, 12) + '-' + id.substring(12, 16)
|
||||
+ '-' + id.substring(16, 20) + '-' + id.substring(20, 32));
|
||||
} catch (IOException | ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
TaskManager.runTask(ifFetch);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override public void handleShutdown() {
|
||||
super.handleShutdown();
|
||||
try {
|
||||
getConnection().close();
|
||||
} catch (SQLException e) {
|
||||
throw new SQLUUIDHandlerException("Couldn't close database connection", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public boolean add(final StringWrapper name, final UUID uuid) {
|
||||
// Ignoring duplicates
|
||||
if (super.add(name, uuid)) {
|
||||
TaskManager.runTaskAsync(new Runnable() {
|
||||
@Override public void run() {
|
||||
try (PreparedStatement statement = getConnection().prepareStatement(
|
||||
"REPLACE INTO usercache (`uuid`, `username`) VALUES(?, ?)")) {
|
||||
statement.setString(1, uuid.toString());
|
||||
statement.setString(2, name.toString());
|
||||
statement.execute();
|
||||
PS.debug(C.PREFIX + "&cAdded '&6" + uuid + "&c' - '&6" + name + "&c'");
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is useful for name changes
|
||||
*/
|
||||
@Override public void rename(final UUID uuid, final StringWrapper name) {
|
||||
super.rename(uuid, name);
|
||||
TaskManager.runTaskAsync(new Runnable() {
|
||||
@Override public void run() {
|
||||
try (PreparedStatement statement = getConnection()
|
||||
.prepareStatement("UPDATE usercache SET `username`=? WHERE `uuid`=?")) {
|
||||
statement.setString(1, name.value);
|
||||
statement.setString(2, uuid.toString());
|
||||
statement.execute();
|
||||
PS.debug(C.PREFIX + "Name change for '" + uuid + "' to '" + name.value + '\'');
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private class SQLUUIDHandlerException extends RuntimeException {
|
||||
|
||||
SQLUUIDHandlerException(String s, Throwable c) {
|
||||
super("SQLUUIDHandler caused an exception: " + s, c);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user