2015-11-18 08:49:57 +01:00
|
|
|
package com.boydti.fawe.bukkit;
|
|
|
|
|
|
|
|
import com.boydti.fawe.Fawe;
|
|
|
|
import com.boydti.fawe.IFawe;
|
2017-07-28 07:12:41 +02:00
|
|
|
import com.boydti.fawe.bukkit.chat.BukkitChatManager;
|
2017-08-31 08:03:43 +02:00
|
|
|
import com.boydti.fawe.bukkit.listener.BrushListener;
|
|
|
|
import com.boydti.fawe.bukkit.listener.RenderListener;
|
2015-11-18 08:49:57 +01:00
|
|
|
import com.boydti.fawe.bukkit.regions.FactionsFeature;
|
2016-04-21 07:53:37 +02:00
|
|
|
import com.boydti.fawe.bukkit.regions.FactionsOneFeature;
|
2015-11-18 08:49:57 +01:00
|
|
|
import com.boydti.fawe.bukkit.regions.FactionsUUIDFeature;
|
|
|
|
import com.boydti.fawe.bukkit.regions.GriefPreventionFeature;
|
|
|
|
import com.boydti.fawe.bukkit.regions.PlotMeFeature;
|
|
|
|
import com.boydti.fawe.bukkit.regions.PreciousStonesFeature;
|
|
|
|
import com.boydti.fawe.bukkit.regions.ResidenceFeature;
|
|
|
|
import com.boydti.fawe.bukkit.regions.TownyFeature;
|
|
|
|
import com.boydti.fawe.bukkit.regions.Worldguard;
|
2017-08-31 08:03:43 +02:00
|
|
|
import com.boydti.fawe.bukkit.util.BukkitTaskMan;
|
|
|
|
import com.boydti.fawe.bukkit.util.ItemUtil;
|
|
|
|
import com.boydti.fawe.bukkit.util.VaultUtil;
|
2017-09-11 19:02:44 +02:00
|
|
|
import com.boydti.fawe.bukkit.util.image.BukkitImageListener;
|
|
|
|
import com.boydti.fawe.bukkit.util.image.BukkitImageViewer;
|
2017-07-09 14:54:04 +02:00
|
|
|
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
|
2016-04-21 17:41:54 +02:00
|
|
|
import com.boydti.fawe.bukkit.v0.BukkitQueue_All;
|
2016-04-29 23:24:59 +02:00
|
|
|
import com.boydti.fawe.bukkit.v0.ChunkListener;
|
2017-07-09 14:54:04 +02:00
|
|
|
import com.boydti.fawe.bukkit.v1_10.BukkitQueue_1_10;
|
|
|
|
import com.boydti.fawe.bukkit.v1_11.BukkitQueue_1_11;
|
|
|
|
import com.boydti.fawe.bukkit.v1_12.BukkitQueue_1_12;
|
|
|
|
import com.boydti.fawe.bukkit.v1_12.NMSRegistryDumper;
|
|
|
|
import com.boydti.fawe.bukkit.v1_7.BukkitQueue17;
|
|
|
|
import com.boydti.fawe.bukkit.v1_8.BukkitQueue18R3;
|
|
|
|
import com.boydti.fawe.bukkit.v1_9.BukkitQueue_1_9_R1;
|
2016-08-10 09:36:28 +02:00
|
|
|
import com.boydti.fawe.config.BBC;
|
2016-04-19 22:30:34 +02:00
|
|
|
import com.boydti.fawe.config.Settings;
|
2015-11-18 08:49:57 +01:00
|
|
|
import com.boydti.fawe.object.FaweCommand;
|
|
|
|
import com.boydti.fawe.object.FawePlayer;
|
2016-05-22 19:37:55 +02:00
|
|
|
import com.boydti.fawe.object.FaweQueue;
|
2016-07-12 09:54:00 +02:00
|
|
|
import com.boydti.fawe.regions.FaweMaskManager;
|
2017-09-11 19:02:44 +02:00
|
|
|
import com.boydti.fawe.util.Jars;
|
2016-05-19 09:41:55 +02:00
|
|
|
import com.boydti.fawe.util.MainUtil;
|
2016-04-22 18:11:46 +02:00
|
|
|
import com.boydti.fawe.util.ReflectionUtils;
|
2015-11-18 08:49:57 +01:00
|
|
|
import com.boydti.fawe.util.TaskManager;
|
2017-09-11 19:02:44 +02:00
|
|
|
import com.boydti.fawe.util.image.ImageViewer;
|
2017-08-16 09:27:56 +02:00
|
|
|
import com.boydti.fawe.util.metrics.BStats;
|
2017-07-17 15:51:01 +02:00
|
|
|
import com.sk89q.bukkit.util.FallbackRegistrationListener;
|
2017-07-28 07:12:41 +02:00
|
|
|
import com.sk89q.worldedit.bukkit.BukkitPlayerBlockBag;
|
2017-06-28 13:20:00 +02:00
|
|
|
import com.sk89q.worldedit.bukkit.BukkitWorld;
|
2016-09-20 10:46:49 +02:00
|
|
|
import com.sk89q.worldedit.bukkit.EditSessionBlockChangeDelegate;
|
2015-11-18 08:49:57 +01:00
|
|
|
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
2016-04-23 22:41:07 +02:00
|
|
|
import com.sk89q.worldedit.world.World;
|
2016-04-02 07:58:42 +02:00
|
|
|
import java.io.File;
|
2017-09-11 19:02:44 +02:00
|
|
|
import java.io.FileOutputStream;
|
2016-04-22 18:11:46 +02:00
|
|
|
import java.lang.reflect.Field;
|
2017-03-13 08:55:33 +01:00
|
|
|
import java.lang.reflect.Method;
|
2016-04-22 18:11:46 +02:00
|
|
|
import java.lang.reflect.Modifier;
|
2016-04-02 07:58:42 +02:00
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Collection;
|
2017-07-06 07:49:56 +02:00
|
|
|
import java.util.List;
|
2016-04-21 06:07:28 +02:00
|
|
|
import java.util.UUID;
|
2016-04-02 07:58:42 +02:00
|
|
|
import org.bukkit.Bukkit;
|
2016-08-10 09:36:28 +02:00
|
|
|
import org.bukkit.command.ConsoleCommandSender;
|
2016-04-02 07:58:42 +02:00
|
|
|
import org.bukkit.entity.Player;
|
2016-04-02 18:50:50 +02:00
|
|
|
import org.bukkit.event.EventHandler;
|
2017-04-09 06:19:03 +02:00
|
|
|
import org.bukkit.event.EventPriority;
|
2016-04-02 18:50:50 +02:00
|
|
|
import org.bukkit.event.Listener;
|
|
|
|
import org.bukkit.event.player.PlayerQuitEvent;
|
2016-04-02 07:58:42 +02:00
|
|
|
import org.bukkit.plugin.Plugin;
|
2017-09-11 19:02:44 +02:00
|
|
|
import org.bukkit.plugin.PluginManager;
|
2017-08-16 09:27:56 +02:00
|
|
|
import org.bukkit.plugin.RegisteredServiceProvider;
|
2016-07-12 09:54:00 +02:00
|
|
|
import org.primesoft.blockshub.BlocksHubBukkit;
|
2015-11-18 08:49:57 +01:00
|
|
|
|
2016-04-29 23:24:59 +02:00
|
|
|
public class FaweBukkit implements IFawe, Listener {
|
2016-03-31 11:23:10 +02:00
|
|
|
|
2016-11-24 07:36:44 +01:00
|
|
|
private final BukkitMain plugin;
|
2015-11-18 08:49:57 +01:00
|
|
|
private VaultUtil vault;
|
|
|
|
private WorldEditPlugin worldedit;
|
2017-08-31 08:03:43 +02:00
|
|
|
private ItemUtil itemUtil;
|
2017-09-11 19:02:44 +02:00
|
|
|
private boolean listening;
|
|
|
|
private BukkitImageListener listener;
|
2016-03-31 11:23:10 +02:00
|
|
|
|
2015-11-18 08:49:57 +01:00
|
|
|
public VaultUtil getVault() {
|
2016-03-31 11:23:10 +02:00
|
|
|
return this.vault;
|
2015-11-18 08:49:57 +01:00
|
|
|
}
|
2016-03-31 11:23:10 +02:00
|
|
|
|
2015-11-18 08:49:57 +01:00
|
|
|
public WorldEditPlugin getWorldEditPlugin() {
|
2016-03-31 11:23:10 +02:00
|
|
|
if (this.worldedit == null) {
|
|
|
|
this.worldedit = (WorldEditPlugin) Bukkit.getPluginManager().getPlugin("WorldEdit");
|
2015-11-18 08:49:57 +01:00
|
|
|
}
|
2016-03-31 11:23:10 +02:00
|
|
|
return this.worldedit;
|
2015-11-18 08:49:57 +01:00
|
|
|
}
|
2016-03-31 11:23:10 +02:00
|
|
|
|
2016-11-24 07:36:44 +01:00
|
|
|
public FaweBukkit(BukkitMain plugin) {
|
2016-04-29 23:24:59 +02:00
|
|
|
this.plugin = plugin;
|
2015-11-18 08:49:57 +01:00
|
|
|
try {
|
|
|
|
Fawe.set(this);
|
2016-11-30 08:45:30 +01:00
|
|
|
setupInjector();
|
2017-08-30 06:44:43 +02:00
|
|
|
try {
|
|
|
|
com.sk89q.worldedit.bukkit.BukkitPlayer.inject(); // Fixes
|
|
|
|
BukkitWorld.inject(); // Fixes
|
|
|
|
BukkitPlayerBlockBag.inject(); // features
|
|
|
|
FallbackRegistrationListener.inject(); // Fixes
|
|
|
|
} catch (Throwable e) {
|
|
|
|
debug("========= INJECTOR FAILED =========");
|
|
|
|
e.printStackTrace();
|
|
|
|
debug("===================================");
|
|
|
|
}
|
2017-06-09 09:37:26 +02:00
|
|
|
try {
|
|
|
|
new BrushListener(plugin);
|
|
|
|
} catch (Throwable e) {
|
|
|
|
debug("====== BRUSH LISTENER FAILED ======");
|
|
|
|
e.printStackTrace();
|
|
|
|
debug("===================================");
|
|
|
|
}
|
2016-08-14 02:26:51 +02:00
|
|
|
if (Bukkit.getVersion().contains("git-Spigot")) {
|
2016-12-05 08:39:35 +01:00
|
|
|
debug("====== USE PAPER ======");
|
2016-06-18 06:19:56 +02:00
|
|
|
debug("DOWNLOAD: https://ci.destroystokyo.com/job/PaperSpigot/");
|
2016-04-22 18:11:46 +02:00
|
|
|
debug("GUIDE: https://www.spigotmc.org/threads/21726/");
|
|
|
|
debug(" - This is only a recommendation");
|
|
|
|
debug("==============================");
|
|
|
|
}
|
2017-06-16 07:28:10 +02:00
|
|
|
if (Bukkit.getVersion().contains("git-Paper") && Settings.IMP.EXPERIMENTAL.DYNAMIC_CHUNK_RENDERING) {
|
|
|
|
new RenderListener(plugin);
|
|
|
|
}
|
2017-07-28 07:12:41 +02:00
|
|
|
try {
|
|
|
|
Fawe.get().setChatManager(new BukkitChatManager());
|
|
|
|
} catch (Throwable ignore) {
|
|
|
|
ignore.printStackTrace();
|
|
|
|
}
|
2016-04-02 07:58:42 +02:00
|
|
|
} catch (final Throwable e) {
|
2016-05-19 09:41:55 +02:00
|
|
|
MainUtil.handleError(e);
|
2016-04-29 23:24:59 +02:00
|
|
|
Bukkit.getServer().shutdown();
|
2015-11-18 08:49:57 +01:00
|
|
|
}
|
2016-04-29 23:24:59 +02:00
|
|
|
TaskManager.IMP.task(new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
2016-06-19 04:24:28 +02:00
|
|
|
Bukkit.getPluginManager().registerEvents(FaweBukkit.this, FaweBukkit.this.plugin);
|
2016-04-29 23:24:59 +02:00
|
|
|
new ChunkListener();
|
|
|
|
}
|
|
|
|
});
|
2016-11-30 08:45:30 +01:00
|
|
|
}
|
|
|
|
|
2017-09-11 19:02:44 +02:00
|
|
|
@Override
|
|
|
|
public synchronized ImageViewer getImageViewer(FawePlayer fp) {
|
|
|
|
if (listening && listener == null) return null;
|
|
|
|
try {
|
|
|
|
listening = true;
|
|
|
|
PluginManager manager = Bukkit.getPluginManager();
|
|
|
|
if (manager.getPlugin("PacketListenerApi") == null) {
|
|
|
|
File output = new File(plugin.getDataFolder().getParentFile(), "PacketListenerAPI_v3.6.0-SNAPSHOT.jar");
|
|
|
|
byte[] jarData = Jars.PL_v3_6_0.download();
|
|
|
|
try (FileOutputStream fos = new FileOutputStream(output)) {
|
|
|
|
fos.write(jarData);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (manager.getPlugin("MapManager") == null) {
|
|
|
|
File output = new File(plugin.getDataFolder().getParentFile(), "MapManager_v1.4.0-SNAPSHOT.jar");
|
|
|
|
byte[] jarData = Jars.MM_v1_4_0.download();
|
|
|
|
try (FileOutputStream fos = new FileOutputStream(output)) {
|
|
|
|
fos.write(jarData);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
BukkitImageViewer viewer = new BukkitImageViewer((Player) fp.parent);
|
|
|
|
if (listener == null) {
|
|
|
|
this.listener = new BukkitImageListener(plugin);
|
|
|
|
}
|
|
|
|
return viewer;
|
|
|
|
} catch (Throwable ignore) {}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2017-08-15 11:43:17 +02:00
|
|
|
@Override
|
|
|
|
public int getPlayerCount() {
|
|
|
|
return plugin.getServer().getOnlinePlayers().size();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean isOnlineMode() {
|
|
|
|
return Bukkit.getOnlineMode();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String getPlatformVersion() {
|
2017-08-15 16:04:45 +02:00
|
|
|
String bukkitVersion = Bukkit.getVersion();
|
|
|
|
int index = bukkitVersion.indexOf("MC: ");
|
|
|
|
return index == -1 ? bukkitVersion : bukkitVersion.substring(index + 4, bukkitVersion.length() - 1);
|
2017-08-15 11:43:17 +02:00
|
|
|
}
|
|
|
|
|
2016-11-30 08:45:30 +01:00
|
|
|
public void setupInjector() {
|
2016-12-27 13:28:43 +01:00
|
|
|
Fawe.setupInjector();
|
|
|
|
// Inject
|
|
|
|
EditSessionBlockChangeDelegate.inject();
|
2015-11-18 08:49:57 +01:00
|
|
|
}
|
2016-03-31 11:23:10 +02:00
|
|
|
|
2015-11-18 08:49:57 +01:00
|
|
|
@Override
|
|
|
|
public void debug(final String s) {
|
2016-08-10 09:36:28 +02:00
|
|
|
ConsoleCommandSender console = Bukkit.getConsoleSender();
|
|
|
|
if (console != null) {
|
|
|
|
console.sendMessage(BBC.color(s));
|
|
|
|
} else {
|
|
|
|
Bukkit.getLogger().info(BBC.color(s));
|
|
|
|
}
|
2015-11-18 08:49:57 +01:00
|
|
|
}
|
2016-03-31 11:23:10 +02:00
|
|
|
|
2015-11-18 08:49:57 +01:00
|
|
|
@Override
|
|
|
|
public File getDirectory() {
|
2016-04-29 23:24:59 +02:00
|
|
|
return plugin.getDataFolder();
|
2015-11-18 08:49:57 +01:00
|
|
|
}
|
2016-03-31 11:23:10 +02:00
|
|
|
|
2015-11-18 08:49:57 +01:00
|
|
|
@Override
|
|
|
|
public void setupCommand(final String label, final FaweCommand cmd) {
|
2016-04-29 23:24:59 +02:00
|
|
|
plugin.getCommand(label).setExecutor(new BukkitCommand(cmd));
|
2015-11-18 08:49:57 +01:00
|
|
|
}
|
2016-03-31 11:23:10 +02:00
|
|
|
|
2015-11-18 08:49:57 +01:00
|
|
|
@Override
|
|
|
|
public FawePlayer<Player> wrap(final Object obj) {
|
|
|
|
if (obj.getClass() == String.class) {
|
2016-04-02 18:50:50 +02:00
|
|
|
String name = (String) obj;
|
|
|
|
FawePlayer existing = Fawe.get().getCachedPlayer(name);
|
|
|
|
if (existing != null) {
|
|
|
|
return existing;
|
|
|
|
}
|
2017-04-09 06:19:03 +02:00
|
|
|
Player player = Bukkit.getPlayer(name);
|
|
|
|
return player != null ? new BukkitPlayer(player) : null;
|
2015-11-18 08:49:57 +01:00
|
|
|
} else if (obj instanceof Player) {
|
2016-04-02 18:50:50 +02:00
|
|
|
Player player = (Player) obj;
|
|
|
|
FawePlayer existing = Fawe.get().getCachedPlayer(player.getName());
|
|
|
|
return existing != null ? existing : new BukkitPlayer(player);
|
2017-03-13 08:55:33 +01:00
|
|
|
} else if (obj != null && obj.getClass().getName().contains("EntityPlayer")) {
|
|
|
|
try {
|
|
|
|
Method method = obj.getClass().getDeclaredMethod("getBukkitEntity");
|
|
|
|
return wrap(method.invoke(obj));
|
|
|
|
} catch (Throwable e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
return null;
|
|
|
|
}
|
2015-11-18 08:49:57 +01:00
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
2016-03-31 11:23:10 +02:00
|
|
|
|
2016-04-02 07:58:42 +02:00
|
|
|
@Override
|
|
|
|
public void startMetrics() {
|
2016-04-29 23:24:59 +02:00
|
|
|
Metrics metrics = new Metrics(plugin);
|
2016-04-02 07:58:42 +02:00
|
|
|
metrics.start();
|
2017-08-16 09:27:56 +02:00
|
|
|
TaskManager.IMP.task(new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
ArrayList<Class<?>> services = new ArrayList(Bukkit.getServicesManager().getKnownServices());
|
|
|
|
services.forEach(service -> {
|
|
|
|
try {
|
|
|
|
service.getField("B_STATS_VERSION");
|
|
|
|
ArrayList<RegisteredServiceProvider<?>> providers = new ArrayList(Bukkit.getServicesManager().getRegistrations(service));
|
|
|
|
for (RegisteredServiceProvider<?> provider : providers) {
|
|
|
|
Object instance = provider.getProvider();
|
|
|
|
|
|
|
|
// Link it to FAWE's metrics instead
|
|
|
|
BStats.linkMetrics(instance);
|
|
|
|
|
|
|
|
// Disable the other metrics
|
|
|
|
Bukkit.getServicesManager().unregister(service, instance);
|
|
|
|
try {
|
|
|
|
Class<? extends Object> clazz = instance.getClass();
|
2017-08-22 12:05:34 +02:00
|
|
|
Field logFailedRequests = ReflectionUtils.findField(clazz, boolean.class);
|
2017-08-16 09:27:56 +02:00
|
|
|
logFailedRequests.set(null, false);
|
2017-08-20 14:09:38 +02:00
|
|
|
Field url = null;
|
2017-08-22 12:05:34 +02:00
|
|
|
try { url = clazz.getDeclaredField("URL"); } catch (NoSuchFieldException ignore) {
|
|
|
|
for (Field field : clazz.getDeclaredFields()) if (ReflectionUtils.setAccessible(field).get(null).toString().startsWith("http")) { url = field; break; }
|
|
|
|
}
|
2017-08-20 14:09:38 +02:00
|
|
|
if (url != null) ReflectionUtils.setFailsafeFieldValue(url, null, null);
|
2017-08-16 09:27:56 +02:00
|
|
|
} catch (NoSuchFieldError | IllegalAccessException ignore) {}
|
2017-08-31 14:42:29 +02:00
|
|
|
catch (Throwable e) {}
|
2017-08-16 09:27:56 +02:00
|
|
|
}
|
|
|
|
} catch (NoSuchFieldException ignored) { }
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2016-04-02 07:58:42 +02:00
|
|
|
}
|
|
|
|
|
2017-08-31 08:03:43 +02:00
|
|
|
public ItemUtil getItemUtil() {
|
2017-09-03 15:24:49 +02:00
|
|
|
ItemUtil tmp = itemUtil;
|
|
|
|
if (tmp == null) {
|
|
|
|
try {
|
|
|
|
this.itemUtil = tmp = new ItemUtil();
|
|
|
|
} catch (Throwable e) {
|
|
|
|
Settings.IMP.EXPERIMENTAL.PERSISTENT_BRUSHES = false;
|
|
|
|
debug("===== PERSISTENT BRUSH FAILED =====");
|
|
|
|
e.printStackTrace();
|
|
|
|
debug("===================================");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return tmp;
|
2017-08-31 08:03:43 +02:00
|
|
|
}
|
|
|
|
|
2016-04-01 07:20:35 +02:00
|
|
|
/**
|
|
|
|
* Vault isn't required, but used for setting player permissions (WorldEdit bypass)
|
|
|
|
* @return
|
|
|
|
*/
|
2015-11-18 08:49:57 +01:00
|
|
|
@Override
|
|
|
|
public void setupVault() {
|
|
|
|
try {
|
2016-03-31 11:23:10 +02:00
|
|
|
this.vault = new VaultUtil();
|
2015-11-18 08:49:57 +01:00
|
|
|
} catch (final Throwable e) {
|
2016-12-12 07:37:16 +01:00
|
|
|
this.debug("&dVault is used for persistent `/wea` toggles.");
|
2015-11-18 08:49:57 +01:00
|
|
|
}
|
|
|
|
}
|
2016-03-31 11:23:10 +02:00
|
|
|
|
2017-07-06 07:49:56 +02:00
|
|
|
@Override
|
|
|
|
public String getDebugInfo() {
|
|
|
|
StringBuilder msg = new StringBuilder();
|
|
|
|
List<String> pl = new ArrayList<>();
|
2017-07-11 14:37:41 +02:00
|
|
|
msg.append("server.plugins: \n");
|
2017-07-06 07:49:56 +02:00
|
|
|
for (Plugin p : Bukkit.getPluginManager().getPlugins()) {
|
2017-07-11 14:37:41 +02:00
|
|
|
msg.append(" - " + p.getName() + ": " + p.getDescription().getVersion() + "\n");
|
2017-07-06 07:49:56 +02:00
|
|
|
}
|
2017-07-11 14:37:41 +02:00
|
|
|
msg.append("server.version: " + Bukkit.getVersion() + " / " + Bukkit.getBukkitVersion() + "\n");
|
2017-07-06 07:49:56 +02:00
|
|
|
return msg.toString();
|
|
|
|
}
|
|
|
|
|
2016-04-01 07:20:35 +02:00
|
|
|
/**
|
|
|
|
* The task manager handles sync/async tasks
|
|
|
|
*/
|
2015-11-18 08:49:57 +01:00
|
|
|
@Override
|
|
|
|
public TaskManager getTaskManager() {
|
2016-04-29 23:24:59 +02:00
|
|
|
return new BukkitTaskMan(plugin);
|
2015-11-18 08:49:57 +01:00
|
|
|
}
|
2016-03-31 11:23:10 +02:00
|
|
|
|
2016-04-21 17:41:54 +02:00
|
|
|
private boolean hasNMS = true;
|
2016-08-20 14:01:43 +02:00
|
|
|
private boolean playerChunk = false;
|
2016-04-21 17:41:54 +02:00
|
|
|
|
2016-09-13 07:43:23 +02:00
|
|
|
@Override
|
|
|
|
public FaweQueue getNewQueue(String world, boolean fast) {
|
|
|
|
if (playerChunk != (playerChunk = true)) {
|
|
|
|
try {
|
|
|
|
Field fieldDirtyCount = ReflectionUtils.getRefClass("{nms}.PlayerChunk").getField("dirtyCount").getRealField();
|
|
|
|
fieldDirtyCount.setAccessible(true);
|
|
|
|
int mod = fieldDirtyCount.getModifiers();
|
|
|
|
if ((mod & Modifier.VOLATILE) == 0) {
|
|
|
|
Field modifiersField = Field.class.getDeclaredField("modifiers");
|
|
|
|
modifiersField.setAccessible(true);
|
|
|
|
modifiersField.setInt(fieldDirtyCount, mod + Modifier.VOLATILE);
|
|
|
|
}
|
|
|
|
} catch (Throwable ignore) {}
|
|
|
|
}
|
|
|
|
try {
|
2017-07-09 14:54:04 +02:00
|
|
|
return getQueue(world);
|
2016-09-29 22:12:08 +02:00
|
|
|
} catch (Throwable ignore) {
|
|
|
|
// Disable incompatible settings
|
2017-01-15 08:45:12 +01:00
|
|
|
Settings.IMP.QUEUE.PARALLEL_THREADS = 1; // BukkitAPI placer is too slow to parallel thread at the chunk level
|
|
|
|
Settings.IMP.HISTORY.COMBINE_STAGES = false; // Performing a chunk copy (if possible) wouldn't be faster using the BukkitAPI
|
2016-09-29 22:12:08 +02:00
|
|
|
if (hasNMS) {
|
2017-04-03 12:07:57 +02:00
|
|
|
|
2016-09-29 22:12:08 +02:00
|
|
|
debug("====== NO NMS BLOCK PLACER FOUND ======");
|
|
|
|
debug("FAWE couldn't find a fast block placer");
|
|
|
|
debug("Bukkit version: " + Bukkit.getVersion());
|
|
|
|
debug("NMS label: " + plugin.getClass().getSimpleName().split("_")[1]);
|
|
|
|
debug("Fallback placer: " + BukkitQueue_All.class);
|
|
|
|
debug("=======================================");
|
|
|
|
debug("Download the version of FAWE for your platform");
|
|
|
|
debug(" - http://ci.athion.net/job/FastAsyncWorldEdit/lastSuccessfulBuild/artifact/target");
|
|
|
|
debug("=======================================");
|
2017-04-03 12:07:57 +02:00
|
|
|
ignore.printStackTrace();
|
|
|
|
debug("=======================================");
|
2016-09-29 22:12:08 +02:00
|
|
|
TaskManager.IMP.laterAsync(new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
MainUtil.sendAdmin("&cNo NMS placer found, see console!");
|
|
|
|
}
|
|
|
|
}, 1);
|
|
|
|
hasNMS = false;
|
|
|
|
}
|
|
|
|
return new BukkitQueue_All(world);
|
2016-09-13 07:43:23 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-01 07:20:35 +02:00
|
|
|
/**
|
|
|
|
* The FaweQueue is a core part of block placement<br>
|
|
|
|
* - The queue returned here is used in the SetQueue class (SetQueue handles the implementation specific queue)<br>
|
|
|
|
* - Block changes are grouped by chunk (as it's more efficient for lighting/packet sending)<br>
|
|
|
|
* - The FaweQueue returned here will provide the wrapper around the chunk object (FaweChunk)<br>
|
|
|
|
* - When a block change is requested, the SetQueue will first check if the chunk exists in the queue, or it will create and add it<br>
|
|
|
|
*/
|
2015-11-18 08:49:57 +01:00
|
|
|
@Override
|
2016-10-03 16:21:27 +02:00
|
|
|
public FaweQueue getNewQueue(World world, boolean fast) {
|
|
|
|
if (fast) {
|
|
|
|
if (playerChunk != (playerChunk = true)) {
|
|
|
|
try {
|
|
|
|
Field fieldDirtyCount = ReflectionUtils.getRefClass("{nms}.PlayerChunk").getField("dirtyCount").getRealField();
|
|
|
|
fieldDirtyCount.setAccessible(true);
|
|
|
|
int mod = fieldDirtyCount.getModifiers();
|
|
|
|
if ((mod & Modifier.VOLATILE) == 0) {
|
|
|
|
Field modifiersField = Field.class.getDeclaredField("modifiers");
|
|
|
|
modifiersField.setAccessible(true);
|
|
|
|
modifiersField.setInt(fieldDirtyCount, mod + Modifier.VOLATILE);
|
|
|
|
}
|
|
|
|
} catch (Throwable ignore) {
|
2016-08-20 14:01:43 +02:00
|
|
|
}
|
2016-10-03 16:21:27 +02:00
|
|
|
}
|
2017-04-03 12:07:57 +02:00
|
|
|
Throwable error = null;
|
2016-10-03 16:21:27 +02:00
|
|
|
try {
|
2017-07-09 14:54:04 +02:00
|
|
|
return getQueue(world);
|
2016-10-03 16:21:27 +02:00
|
|
|
} catch (Throwable ignore) {
|
2017-04-03 12:07:57 +02:00
|
|
|
error = ignore;
|
2016-10-03 16:21:27 +02:00
|
|
|
}
|
|
|
|
// Disable incompatible settings
|
2017-01-15 08:45:12 +01:00
|
|
|
Settings.IMP.QUEUE.PARALLEL_THREADS = 1; // BukkitAPI placer is too slow to parallel thread at the chunk level
|
|
|
|
Settings.IMP.HISTORY.COMBINE_STAGES = false; // Performing a chunk copy (if possible) wouldn't be faster using the BukkitAPI
|
2016-10-03 16:21:27 +02:00
|
|
|
if (hasNMS) {
|
|
|
|
debug("====== NO NMS BLOCK PLACER FOUND ======");
|
|
|
|
debug("FAWE couldn't find a fast block placer");
|
|
|
|
debug("Bukkit version: " + Bukkit.getVersion());
|
2017-04-03 12:07:57 +02:00
|
|
|
debug("NMS label: " + plugin.getClass().getSimpleName());
|
2016-10-03 16:21:27 +02:00
|
|
|
debug("Fallback placer: " + BukkitQueue_All.class);
|
|
|
|
debug("=======================================");
|
|
|
|
debug("Download the version of FAWE for your platform");
|
|
|
|
debug(" - http://ci.athion.net/job/FastAsyncWorldEdit/lastSuccessfulBuild/artifact/target");
|
|
|
|
debug("=======================================");
|
2017-04-03 12:07:57 +02:00
|
|
|
error.printStackTrace();
|
|
|
|
debug("=======================================");
|
2016-10-03 16:21:27 +02:00
|
|
|
TaskManager.IMP.laterAsync(new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
MainUtil.sendAdmin("&cNo NMS placer found, see console!");
|
|
|
|
}
|
|
|
|
}, 1);
|
|
|
|
hasNMS = false;
|
|
|
|
}
|
2016-03-02 22:51:41 +01:00
|
|
|
}
|
2016-04-21 18:31:20 +02:00
|
|
|
return new BukkitQueue_All(world);
|
2015-11-18 08:49:57 +01:00
|
|
|
}
|
2016-03-31 11:23:10 +02:00
|
|
|
|
2016-11-24 07:36:44 +01:00
|
|
|
public BukkitMain getPlugin() {
|
2016-04-29 23:24:59 +02:00
|
|
|
return plugin;
|
|
|
|
}
|
|
|
|
|
2016-04-23 22:41:07 +02:00
|
|
|
@Override
|
|
|
|
public String getWorldName(World world) {
|
|
|
|
return world.getName();
|
|
|
|
}
|
|
|
|
|
2016-04-01 07:20:35 +02:00
|
|
|
/**
|
|
|
|
* A mask manager handles region restrictions e.g. PlotSquared plots / WorldGuard regions
|
|
|
|
*/
|
2015-11-18 08:49:57 +01:00
|
|
|
@Override
|
|
|
|
public Collection<FaweMaskManager> getMaskManagers() {
|
|
|
|
final Plugin worldguardPlugin = Bukkit.getServer().getPluginManager().getPlugin("WorldGuard");
|
|
|
|
final ArrayList<FaweMaskManager> managers = new ArrayList<>();
|
|
|
|
if ((worldguardPlugin != null) && worldguardPlugin.isEnabled()) {
|
2016-02-09 11:15:03 +01:00
|
|
|
try {
|
|
|
|
managers.add(new Worldguard(worldguardPlugin, this));
|
|
|
|
Fawe.debug("Plugin 'WorldGuard' found. Using it now.");
|
2016-03-31 11:23:10 +02:00
|
|
|
} catch (final Throwable e) {
|
2016-05-19 09:41:55 +02:00
|
|
|
MainUtil.handleError(e);
|
2016-02-09 11:15:03 +01:00
|
|
|
}
|
2015-11-18 08:49:57 +01:00
|
|
|
}
|
|
|
|
final Plugin plotmePlugin = Bukkit.getServer().getPluginManager().getPlugin("PlotMe");
|
|
|
|
if ((plotmePlugin != null) && plotmePlugin.isEnabled()) {
|
2016-02-09 11:15:03 +01:00
|
|
|
try {
|
|
|
|
managers.add(new PlotMeFeature(plotmePlugin, this));
|
|
|
|
Fawe.debug("Plugin 'PlotMe' found. Using it now.");
|
2016-03-31 11:23:10 +02:00
|
|
|
} catch (final Throwable e) {
|
2016-05-19 09:41:55 +02:00
|
|
|
MainUtil.handleError(e);
|
2016-02-09 11:15:03 +01:00
|
|
|
}
|
2015-11-18 08:49:57 +01:00
|
|
|
}
|
|
|
|
final Plugin townyPlugin = Bukkit.getServer().getPluginManager().getPlugin("Towny");
|
|
|
|
if ((townyPlugin != null) && townyPlugin.isEnabled()) {
|
2016-02-09 11:15:03 +01:00
|
|
|
try {
|
|
|
|
managers.add(new TownyFeature(townyPlugin, this));
|
|
|
|
Fawe.debug("Plugin 'Towny' found. Using it now.");
|
2016-03-31 11:23:10 +02:00
|
|
|
} catch (final Throwable e) {
|
2016-05-19 09:41:55 +02:00
|
|
|
MainUtil.handleError(e);
|
2016-02-09 11:15:03 +01:00
|
|
|
}
|
2015-11-18 08:49:57 +01:00
|
|
|
}
|
|
|
|
final Plugin factionsPlugin = Bukkit.getServer().getPluginManager().getPlugin("Factions");
|
|
|
|
if ((factionsPlugin != null) && factionsPlugin.isEnabled()) {
|
|
|
|
try {
|
|
|
|
managers.add(new FactionsFeature(factionsPlugin, this));
|
|
|
|
Fawe.debug("Plugin 'Factions' found. Using it now.");
|
|
|
|
} catch (final Throwable e) {
|
2016-04-21 07:53:37 +02:00
|
|
|
try {
|
|
|
|
managers.add(new FactionsUUIDFeature(factionsPlugin, this));
|
|
|
|
Fawe.debug("Plugin 'FactionsUUID' found. Using it now.");
|
|
|
|
} catch (Throwable e2) {
|
|
|
|
try {
|
|
|
|
managers.add(new FactionsOneFeature(factionsPlugin, this));
|
|
|
|
Fawe.debug("Plugin 'FactionsUUID' found. Using it now.");
|
|
|
|
} catch (Throwable e3) {
|
2016-05-19 09:41:55 +02:00
|
|
|
MainUtil.handleError(e);
|
2016-04-21 07:53:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2015-11-18 08:49:57 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
final Plugin residencePlugin = Bukkit.getServer().getPluginManager().getPlugin("Residence");
|
|
|
|
if ((residencePlugin != null) && residencePlugin.isEnabled()) {
|
2016-02-09 11:15:03 +01:00
|
|
|
try {
|
|
|
|
managers.add(new ResidenceFeature(residencePlugin, this));
|
|
|
|
Fawe.debug("Plugin 'Residence' found. Using it now.");
|
2016-03-31 11:23:10 +02:00
|
|
|
} catch (final Throwable e) {
|
2016-05-19 09:41:55 +02:00
|
|
|
MainUtil.handleError(e);
|
2016-02-09 11:15:03 +01:00
|
|
|
}
|
2015-11-18 08:49:57 +01:00
|
|
|
}
|
|
|
|
final Plugin griefpreventionPlugin = Bukkit.getServer().getPluginManager().getPlugin("GriefPrevention");
|
|
|
|
if ((griefpreventionPlugin != null) && griefpreventionPlugin.isEnabled()) {
|
2016-02-09 11:15:03 +01:00
|
|
|
try {
|
|
|
|
managers.add(new GriefPreventionFeature(griefpreventionPlugin, this));
|
|
|
|
Fawe.debug("Plugin 'GriefPrevention' found. Using it now.");
|
2016-03-31 11:23:10 +02:00
|
|
|
} catch (final Throwable e) {
|
2016-05-19 09:41:55 +02:00
|
|
|
MainUtil.handleError(e);
|
2016-02-09 11:15:03 +01:00
|
|
|
}
|
2015-11-18 08:49:57 +01:00
|
|
|
}
|
|
|
|
final Plugin preciousstonesPlugin = Bukkit.getServer().getPluginManager().getPlugin("PreciousStones");
|
|
|
|
if ((preciousstonesPlugin != null) && preciousstonesPlugin.isEnabled()) {
|
2016-02-09 11:15:03 +01:00
|
|
|
try {
|
|
|
|
managers.add(new PreciousStonesFeature(preciousstonesPlugin, this));
|
|
|
|
Fawe.debug("Plugin 'PreciousStones' found. Using it now.");
|
2016-03-31 11:23:10 +02:00
|
|
|
} catch (final Throwable e) {
|
2016-05-19 09:41:55 +02:00
|
|
|
MainUtil.handleError(e);
|
2016-02-09 11:15:03 +01:00
|
|
|
}
|
2015-11-18 08:49:57 +01:00
|
|
|
}
|
|
|
|
return managers;
|
|
|
|
}
|
2017-04-18 14:56:38 +02:00
|
|
|
//
|
|
|
|
// @EventHandler
|
|
|
|
// public void onWorldLoad(WorldLoadEvent event) {
|
|
|
|
// org.bukkit.World world = event.getWorld();
|
|
|
|
// world.setKeepSpawnInMemory(false);
|
|
|
|
// WorldServer nmsWorld = ((CraftWorld) world).getHandle();
|
|
|
|
// ChunkProviderServer provider = nmsWorld.getChunkProviderServer();
|
|
|
|
// try {
|
|
|
|
// Field fieldChunkLoader = provider.getClass().getDeclaredField("chunkLoader");
|
|
|
|
// ReflectionUtils.setFailsafeFieldValue(fieldChunkLoader, provider, new FaweChunkLoader());
|
|
|
|
// } catch (Throwable e) {
|
|
|
|
// e.printStackTrace();
|
|
|
|
// }
|
|
|
|
// }
|
2016-04-02 18:50:50 +02:00
|
|
|
|
2017-04-09 06:19:03 +02:00
|
|
|
@EventHandler(priority = EventPriority.MONITOR)
|
2016-04-02 18:50:50 +02:00
|
|
|
public void onPlayerQuit(PlayerQuitEvent event) {
|
2016-04-19 22:30:34 +02:00
|
|
|
Player player = event.getPlayer();
|
|
|
|
FawePlayer fp = FawePlayer.wrap(player);
|
2017-02-04 07:44:33 +01:00
|
|
|
if (fp != null) {
|
|
|
|
fp.unregister();
|
|
|
|
}
|
2016-04-02 18:50:50 +02:00
|
|
|
Fawe.get().unregister(event.getPlayer().getName());
|
|
|
|
}
|
2016-04-19 22:30:34 +02:00
|
|
|
|
2016-04-20 20:22:47 +02:00
|
|
|
@Override
|
|
|
|
public String getPlatform() {
|
2016-11-29 05:05:18 +01:00
|
|
|
return "bukkit";
|
2016-04-20 20:22:47 +02:00
|
|
|
}
|
2016-04-21 06:07:28 +02:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public UUID getUUID(String name) {
|
|
|
|
return Bukkit.getOfflinePlayer(name).getUniqueId();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String getName(UUID uuid) {
|
|
|
|
return Bukkit.getOfflinePlayer(uuid).getName();
|
|
|
|
}
|
2016-07-12 09:54:00 +02:00
|
|
|
|
|
|
|
private boolean enabledBlocksHub = true;
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Object getBlocksHubApi() {
|
|
|
|
if (!enabledBlocksHub) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
Plugin blocksHubPlugin = Bukkit.getPluginManager().getPlugin("BlocksHub");
|
|
|
|
if (blocksHubPlugin == null) {
|
|
|
|
enabledBlocksHub = false;
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return ((BlocksHubBukkit) blocksHubPlugin).getApi();
|
|
|
|
}
|
2017-07-09 14:54:04 +02:00
|
|
|
|
|
|
|
private Version version = null;
|
|
|
|
|
|
|
|
public Version getVersion() {
|
|
|
|
Version tmp = this.version;
|
|
|
|
if (tmp == null) {
|
2017-07-12 05:50:13 +02:00
|
|
|
tmp = Version.NONE;
|
2017-07-09 14:54:04 +02:00
|
|
|
for (Version v : Version.values()) {
|
|
|
|
try {
|
|
|
|
BukkitQueue_0.checkVersion(v.name());
|
|
|
|
this.version = tmp = v;
|
|
|
|
if (tmp == Version.v1_12_R1) {
|
|
|
|
try {
|
|
|
|
Fawe.debug("Running 1.12 registry dumper!");
|
|
|
|
NMSRegistryDumper dumper = new NMSRegistryDumper(MainUtil.getFile(plugin.getDataFolder(), "extrablocks.json"));
|
|
|
|
dumper.run();
|
|
|
|
} catch (Throwable e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
} catch (IllegalStateException e) {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
public enum Version {
|
|
|
|
v1_7_R4,
|
|
|
|
v1_8_R3,
|
|
|
|
v1_9_R2,
|
|
|
|
v1_10_R1,
|
|
|
|
v1_11_R1,
|
|
|
|
v1_12_R1,
|
2017-08-13 04:38:19 +02:00
|
|
|
v1_12_R2,
|
|
|
|
v1_13_R1,
|
2017-07-09 14:54:04 +02:00
|
|
|
NONE,
|
|
|
|
}
|
|
|
|
|
|
|
|
private FaweQueue getQueue(World world) {
|
|
|
|
switch (getVersion()) {
|
|
|
|
case v1_7_R4:
|
|
|
|
return new BukkitQueue17(world);
|
|
|
|
case v1_8_R3:
|
|
|
|
return new BukkitQueue18R3(world);
|
|
|
|
case v1_9_R2:
|
|
|
|
return new BukkitQueue_1_9_R1(world);
|
|
|
|
case v1_10_R1:
|
|
|
|
return new BukkitQueue_1_10(world);
|
|
|
|
case v1_11_R1:
|
|
|
|
return new BukkitQueue_1_11(world);
|
|
|
|
case v1_12_R1:
|
|
|
|
return new BukkitQueue_1_12(world);
|
|
|
|
default:
|
|
|
|
case NONE:
|
|
|
|
return new BukkitQueue_All(world);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private FaweQueue getQueue(String world) {
|
|
|
|
switch (getVersion()) {
|
|
|
|
case v1_7_R4:
|
|
|
|
return new BukkitQueue17(world);
|
|
|
|
case v1_8_R3:
|
|
|
|
return new BukkitQueue18R3(world);
|
|
|
|
case v1_9_R2:
|
|
|
|
return new BukkitQueue_1_9_R1(world);
|
|
|
|
case v1_10_R1:
|
|
|
|
return new BukkitQueue_1_10(world);
|
|
|
|
case v1_11_R1:
|
|
|
|
return new BukkitQueue_1_11(world);
|
|
|
|
case v1_12_R1:
|
|
|
|
return new BukkitQueue_1_12(world);
|
|
|
|
default:
|
|
|
|
case NONE:
|
|
|
|
return new BukkitQueue_All(world);
|
|
|
|
}
|
|
|
|
}
|
2016-12-05 08:39:35 +01:00
|
|
|
}
|