package de.robotricker.transportpipes; import ch.jalu.injector.Injector; import ch.jalu.injector.InjectorBuilder; import co.aikar.commands.PaperCommandManager; import de.robotricker.transportpipes.api.TransportPipesAPI; import de.robotricker.transportpipes.commands.TPCommand; import de.robotricker.transportpipes.config.GeneralConf; import de.robotricker.transportpipes.config.LangConf; import de.robotricker.transportpipes.config.PlayerSettingsConf; import de.robotricker.transportpipes.duct.Duct; import de.robotricker.transportpipes.duct.DuctRegister; import de.robotricker.transportpipes.duct.factory.PipeFactory; import de.robotricker.transportpipes.duct.manager.GlobalDuctManager; import de.robotricker.transportpipes.duct.manager.PipeManager; import de.robotricker.transportpipes.duct.pipe.Pipe; import de.robotricker.transportpipes.duct.types.BaseDuctType; import de.robotricker.transportpipes.inventory.PlayerSettingsInventory; import de.robotricker.transportpipes.items.PipeItemManager; import de.robotricker.transportpipes.listener.DuctListener; import de.robotricker.transportpipes.listener.PlayerListener; import de.robotricker.transportpipes.listener.TPContainerListener; import de.robotricker.transportpipes.listener.WorldListener; import de.robotricker.transportpipes.log.LoggerService; import de.robotricker.transportpipes.log.SentryService; import de.robotricker.transportpipes.protocol.ProtocolService; import de.robotricker.transportpipes.rendersystems.RenderSystem; import de.robotricker.transportpipes.rendersystems.pipe.modelled.ModelledPipeRenderSystem; import de.robotricker.transportpipes.rendersystems.pipe.vanilla.VanillaPipeRenderSystem; import de.robotricker.transportpipes.saving.DiskService; import de.robotricker.transportpipes.utils.LWCUtils; import de.robotricker.transportpipes.utils.legacy.LegacyUtils; import de.robotricker.transportpipes.utils.legacy.LegacyUtils_1_13; import io.sentry.event.Breadcrumb; import org.bukkit.Bukkit; import org.bukkit.Chunk; import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Iterator; import java.util.logging.Logger; import java.util.stream.Collectors; public class TransportPipes extends JavaPlugin { private Injector injector; private SentryService sentry; private ThreadService thread; private DiskService diskService; @Override public void onEnable() { if (Bukkit.getVersion().contains("1.13")) { LegacyUtils.setInstance(new LegacyUtils_1_13()); } else { System.err.println("------------------------------------------"); System.err.println("TransportPipes currently only works with Minecraft 1.13.1 and 1.13.2"); System.err.println("------------------------------------------"); Bukkit.getPluginManager().disablePlugin(this); return; } try { Class.forName("org.bukkit.inventory.RecipeChoice"); } catch (ClassNotFoundException e) { System.err.println("------------------------------------------"); System.err.println("TransportPipes currently only works with Minecraft 1.13.1 and 1.13.2"); System.err.println("------------------------------------------"); Bukkit.getPluginManager().disablePlugin(this); return; } if (Files.isRegularFile(Paths.get(getDataFolder().getPath(), "recipes.yml"))) { System.err.println("------------------------------------------"); System.err.println("Please delete the old plugins/TransportPipes directory so TransportPipes can recreate it with a bunch of new config values"); System.err.println("------------------------------------------"); Bukkit.getPluginManager().disablePlugin(this); return; } //Initialize dependency injector injector = new InjectorBuilder().addDefaultHandlers("de.robotricker.transportpipes").create(); injector.register(Logger.class, getLogger()); injector.register(Plugin.class, this); injector.register(JavaPlugin.class, this); injector.register(TransportPipes.class, this); //Initialize logger LoggerService logger = injector.getSingleton(LoggerService.class); //Initialize sentry sentry = injector.getSingleton(SentryService.class); if (!sentry.init("https://[email protected]/1281889?stacktrace.app.packages=de.robotricker&release=" + getDescription().getVersion())) { logger.warning("Unable to initialize sentry!"); } sentry.addTag("thread", Thread.currentThread().getName()); sentry.injectThread(Thread.currentThread()); sentry.breadcrumb(Breadcrumb.Level.INFO, "MAIN", "enabling plugin"); //Initialize configs injector.getSingleton(GeneralConf.class); injector.register(LangConf.class, new LangConf(this, injector.getSingleton(GeneralConf.class).getLanguage())); //Initialize API injector.getSingleton(TransportPipesAPI.class); //Initialize thread thread = injector.getSingleton(ThreadService.class); thread.start(); //Register pipe BaseDuctType<Pipe> baseDuctType = injector.getSingleton(DuctRegister.class).registerBaseDuctType("Pipe", PipeManager.class, PipeFactory.class, PipeItemManager.class); baseDuctType.setModelledRenderSystem(injector.newInstance(ModelledPipeRenderSystem.class)); baseDuctType.setVanillaRenderSystem(injector.newInstance(VanillaPipeRenderSystem.class)); //Register listeners Bukkit.getPluginManager().registerEvents(injector.getSingleton(TPContainerListener.class), this); Bukkit.getPluginManager().registerEvents(injector.getSingleton(PlayerListener.class), this); Bukkit.getPluginManager().registerEvents(injector.getSingleton(DuctListener.class), this); Bukkit.getPluginManager().registerEvents(injector.getSingleton(WorldListener.class), this); Bukkit.getPluginManager().registerEvents(injector.getSingleton(PlayerSettingsInventory.class), this); Bukkit.getPluginManager().registerEvents(injector.getSingleton(ResourcepackService.class), this); //Register commands PaperCommandManager commandManager = new PaperCommandManager(this); commandManager.enableUnstableAPI("help"); commandManager.registerCommand(injector.getSingleton(TPCommand.class)); commandManager.getCommandCompletions().registerCompletion("baseDuctType", c -> injector.getSingleton(DuctRegister.class).baseDuctTypes().stream().map(BaseDuctType::getName).collect(Collectors.toList())); sentry.breadcrumb(Breadcrumb.Level.INFO, "MAIN", "enabled plugin"); diskService = injector.getSingleton(DiskService.class); TPContainerListener tpContainerListener = injector.getSingleton(TPContainerListener.class); runTaskSync(() -> { for (World world : Bukkit.getWorlds()) { for (Chunk loadedChunk : world.getLoadedChunks()) { tpContainerListener.handleChunkLoadSync(loadedChunk, true); } diskService.loadDuctsSync(world); } }); if (Bukkit.getPluginManager().isPluginEnabled("LWC")) { try { com.griefcraft.scripting.Module module = injector.getSingleton(LWCUtils.class); com.griefcraft.lwc.LWC.getInstance().getModuleLoader().registerModule(this, module); } catch (Exception e) { e.printStackTrace(); sentry.record(e); } } } @Override public void onDisable() { if (sentry != null && thread != null) { sentry.breadcrumb(Breadcrumb.Level.INFO, "MAIN", "disabling plugin"); // Stop tpThread gracefully try { thread.stopRunning(); thread.join(); } catch (InterruptedException e) { e.printStackTrace(); } for (World world : Bukkit.getWorlds()) { saveWorld(world); } sentry.breadcrumb(Breadcrumb.Level.INFO, "MAIN", "disabled plugin"); } } public void saveWorld(World world) { sentry.breadcrumb(Breadcrumb.Level.INFO, "MAIN", "saving world " + world.getName()); diskService.saveDuctsSync(world); sentry.breadcrumb(Breadcrumb.Level.INFO, "MAIN", "saved world " + world.getName()); } public void runTaskSync(Runnable task) { if (isEnabled()) { Bukkit.getScheduler().runTask(this, task); } } public void runTaskSyncLater(Runnable task, long delay) { if (isEnabled()) { Bukkit.getScheduler().runTaskLater(this, task, delay); } } public void runTaskAsync(Runnable runnable, long delay) { thread.getTasks().put(runnable, delay); } public Injector getInjector() { return injector; } public void changeRenderSystem(Player p, String newRenderSystemName) { PlayerSettingsConf playerSettingsConf = injector.getSingleton(PlayerSettingsService.class).getOrCreateSettingsConf(p); DuctRegister ductRegister = injector.getSingleton(DuctRegister.class); GlobalDuctManager globalDuctManager = injector.getSingleton(GlobalDuctManager.class); ProtocolService protocolService = injector.getSingleton(ProtocolService.class); // change render system String oldRenderSystemName = playerSettingsConf.getRenderSystemName(); if (oldRenderSystemName.equalsIgnoreCase(newRenderSystemName)) { return; } playerSettingsConf.setRenderSystemName(newRenderSystemName); for (BaseDuctType baseDuctType : ductRegister.baseDuctTypes()) { RenderSystem oldRenderSystem = RenderSystem.getRenderSystem(oldRenderSystemName, baseDuctType); // switch render system synchronized (globalDuctManager.getPlayerDucts(p)) { Iterator<Duct> ductIt = globalDuctManager.getPlayerDucts(p).iterator(); while (ductIt.hasNext()) { Duct nextDuct = ductIt.next(); protocolService.removeASD(p, oldRenderSystem.getASDForDuct(nextDuct)); ductIt.remove(); } } } } public long convertVersionToLong(String version) { long versionLong = 0; try { if (version.contains("-")) { for (String subVersion : version.split("-")) { if (subVersion.startsWith("b")) { int buildNumber = 0; String buildNumberString = subVersion.substring(1); if (!buildNumberString.equalsIgnoreCase("CUSTOM")) { buildNumber = Integer.parseInt(buildNumberString); } versionLong |= buildNumber; } else if (!subVersion.equalsIgnoreCase("SNAPSHOT")) { versionLong |= (long) convertMainVersionStringToInt(subVersion) << 32; } } } else { versionLong = (long) convertMainVersionStringToInt(version) << 32; } } catch (Exception e) { e.printStackTrace(); } return versionLong; } private int convertMainVersionStringToInt(String mainVersion) { int versionInt = 0; if (mainVersion.contains(".")) { // shift for every version number 1 byte to the left int leftShift = (mainVersion.split("\\.").length - 1) * 8; for (String subVersion : mainVersion.split("\\.")) { byte v = Byte.parseByte(subVersion); versionInt |= ((int) v << leftShift); leftShift -= 8; } } else { versionInt = Byte.parseByte(mainVersion); } return versionInt; } }