/* * This file is part of NucleusFramework for Bukkit, licensed under the MIT License (MIT). * * Copyright (c) JCThePants (www.jcwhatever.com) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.jcwhatever.nucleus; import com.jcwhatever.nucleus.events.NucleusLoadedEvent; import com.jcwhatever.nucleus.internal.InternalLeashTracker; import com.jcwhatever.nucleus.internal.InternalPlayerTracker; import com.jcwhatever.nucleus.internal.actionbar.InternalActionBarManager; import com.jcwhatever.nucleus.internal.blockselect.InternalBlockSelector; import com.jcwhatever.nucleus.internal.commands.DebugAllCommand; import com.jcwhatever.nucleus.internal.commands.DebugCommand; import com.jcwhatever.nucleus.internal.commands.GiveCommand; import com.jcwhatever.nucleus.internal.commands.TPCommand; import com.jcwhatever.nucleus.internal.commands.economy.NEconomyCommand; import com.jcwhatever.nucleus.internal.commands.friends.NFriendsCommand; import com.jcwhatever.nucleus.internal.commands.jail.JailCommand; import com.jcwhatever.nucleus.internal.commands.kits.KitsCommand; import com.jcwhatever.nucleus.internal.commands.players.PlayersCommand; import com.jcwhatever.nucleus.internal.commands.plugins.PluginsCommand; import com.jcwhatever.nucleus.internal.commands.providers.ProvidersCommand; import com.jcwhatever.nucleus.internal.commands.regions.RegionsCommand; import com.jcwhatever.nucleus.internal.commands.respacks.ResPacksCommand; import com.jcwhatever.nucleus.internal.commands.scripts.ScriptsCommand; import com.jcwhatever.nucleus.internal.commands.signs.SignsCommand; import com.jcwhatever.nucleus.internal.commands.storage.StorageCommand; import com.jcwhatever.nucleus.internal.events.InternalEventManager; import com.jcwhatever.nucleus.internal.listeners.JCGEventListener; import com.jcwhatever.nucleus.internal.listeners.SpawnEggListener; import com.jcwhatever.nucleus.internal.listeners.StartupListener; import com.jcwhatever.nucleus.internal.managed.astar.InternalAStarManager; import com.jcwhatever.nucleus.internal.managed.commands.InternalCommandManager; import com.jcwhatever.nucleus.internal.managed.commands.response.InternalResponseRequestor; import com.jcwhatever.nucleus.internal.managed.entity.InternalEntityTracker; import com.jcwhatever.nucleus.internal.managed.entity.meta.InternalEntityMetaManager; import com.jcwhatever.nucleus.internal.managed.entity.mobs.InternalMobSerializer; import com.jcwhatever.nucleus.internal.managed.items.equipper.InternalEquipperManager; import com.jcwhatever.nucleus.internal.managed.items.floating.InternalFloatingItemManager; import com.jcwhatever.nucleus.internal.managed.items.meta.InternalItemMetaHandlers; import com.jcwhatever.nucleus.internal.managed.items.serializer.InternalItemSerializationManager; import com.jcwhatever.nucleus.internal.managed.language.InternalLanguageManager; import com.jcwhatever.nucleus.internal.managed.nms.InternalNmsManager; import com.jcwhatever.nucleus.internal.managed.particles.InternalParticleEffectFactory; import com.jcwhatever.nucleus.internal.managed.reflection.InternalReflectionManager; import com.jcwhatever.nucleus.internal.managed.resourcepacks.InternalResourcePackManager; import com.jcwhatever.nucleus.internal.managed.scheduler.InternalTaskScheduler; import com.jcwhatever.nucleus.internal.managed.scoreboards.InternalScoreboardManager; import com.jcwhatever.nucleus.internal.managed.scripting.InternalScriptApiRepo; import com.jcwhatever.nucleus.internal.managed.scripting.InternalScriptEngineLoader; import com.jcwhatever.nucleus.internal.managed.scripting.InternalScriptEngineManager; import com.jcwhatever.nucleus.internal.managed.scripting.InternalScriptManager; import com.jcwhatever.nucleus.internal.managed.signs.InternalSignManager; import com.jcwhatever.nucleus.internal.managed.sounds.InternalSoundManager; import com.jcwhatever.nucleus.internal.managed.teleport.InternalTeleportManager; import com.jcwhatever.nucleus.internal.managed.titles.InternalTitleManager; import com.jcwhatever.nucleus.internal.providers.InternalProviderLoader; import com.jcwhatever.nucleus.internal.providers.InternalProviderManager; import com.jcwhatever.nucleus.internal.regions.InternalRegionManager; import com.jcwhatever.nucleus.managed.messaging.IMessengerFactory; import com.jcwhatever.nucleus.managed.scheduler.ITaskScheduler; import com.jcwhatever.nucleus.providers.storage.DataStorage; import com.jcwhatever.nucleus.storage.DataPath; import com.jcwhatever.nucleus.storage.IDataNode; import com.jcwhatever.nucleus.utils.text.TextColor; import org.bukkit.Bukkit; import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.java.JavaPluginLoader; import javax.script.ScriptEngineManager; import java.io.File; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * NucleusFramework's Bukkit Plugin */ public final class BukkitPlugin extends NucleusPlugin { InternalProviderManager _providerManager; InternalEventManager _eventManager; InternalRegionManager _regionManager; InternalScriptManager _scriptManager; InternalScriptApiRepo _scriptApiRepo; InternalSoundManager _soundManager; InternalMobSerializer _mobSerializer; InternalNmsManager _nmsManager; InternalSignManager _signManager; InternalEntityTracker _entityTracker; InternalFloatingItemManager _floatingItemManager; InternalItemSerializationManager _itemSerialization; InternalScoreboardManager _scoreboardTracker; InternalLanguageManager _languageManager; InternalEquipperManager _equipperManager; InternalLeashTracker _leashTracker; InternalBlockSelector _blockSelector; InternalResponseRequestor _responseRequestor; InternalItemMetaHandlers _itemMetaHandlers; InternalTeleportManager _teleportManager; InternalTitleManager _titleManager; InternalActionBarManager _actionBarManager; InternalReflectionManager _reflectionManager; InternalCommandManager _commandManager; InternalParticleEffectFactory _particleFactory; InternalResourcePackManager _resourcePacks; InternalEntityMetaManager _entityMetaManager; InternalAStarManager _astarManager; ITaskScheduler _scheduler; ScriptEngineManager _scriptEngineManager; IMessengerFactory _messengerFactory; InternalScriptEngineLoader _scriptEngineLoader; boolean _isModulesReady; /** * Constructor. */ public BukkitPlugin() { super(); Nucleus._plugin = this; // init rhino javascript engine if present try { initRhinoClassLoader(); } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ignore) { // rhino not found } } /** * Constructor for testing. */ protected BukkitPlugin(JavaPluginLoader loader, PluginDescriptionFile description, File dataFolder, File file) { super(loader, description, dataFolder, file); Nucleus._plugin = this; } @Override public String getChatPrefix() { return TextColor.BLUE + "[" + TextColor.WHITE + "Nucleus" + TextColor.BLUE + "] " + TextColor.WHITE; } @Override public String getConsolePrefix() { return "[NucleusFramework] "; } @Override public boolean isLoaded() { return isEnabled() && _isModulesReady; } @Override protected void onPreEnable() { new StartupListener().preventLogins(); _reflectionManager = new InternalReflectionManager(); _languageManager = new InternalLanguageManager(); _itemMetaHandlers = new InternalItemMetaHandlers(); _itemSerialization = new InternalItemSerializationManager(); _equipperManager = new InternalEquipperManager(); _scoreboardTracker = new InternalScoreboardManager(); _entityMetaManager = new InternalEntityMetaManager(); _scheduler = new InternalTaskScheduler(); _teleportManager = new InternalTeleportManager(); _leashTracker = new InternalLeashTracker(); _mobSerializer = new InternalMobSerializer(); _astarManager = new InternalAStarManager(); _providerManager = new InternalProviderManager(isTesting()); InternalProviderLoader providerLoader = new InternalProviderLoader(_providerManager); providerLoader.loadModules(); _eventManager = new InternalEventManager(this); _scriptApiRepo = new InternalScriptApiRepo(); _regionManager = new InternalRegionManager(this); _soundManager = new InternalSoundManager(); _signManager = new InternalSignManager(); _entityTracker = new InternalEntityTracker(); _blockSelector = new InternalBlockSelector(); _responseRequestor = new InternalResponseRequestor(); } @Override protected void onPostPreEnable() { _nmsManager = new InternalNmsManager(); _titleManager = new InternalTitleManager(); _actionBarManager = new InternalActionBarManager(); _particleFactory = new InternalParticleEffectFactory(); _commandManager = new InternalCommandManager(); _scriptEngineManager = new InternalScriptEngineManager(); _scriptEngineLoader = new InternalScriptEngineLoader(_scriptEngineManager); _scriptEngineLoader.loadModules(); _floatingItemManager = new InternalFloatingItemManager(); IDataNode resPackNode = DataStorage.get(Nucleus.getPlugin(), new DataPath("resource-packs")); resPackNode.load(); _resourcePacks = new InternalResourcePackManager(resPackNode); } @Override protected void onEnablePlugin() { registerEventListeners( new JCGEventListener(_regionManager), new SpawnEggListener()); registerCommand(DebugCommand.class); registerCommand(DebugAllCommand.class); registerCommand(GiveCommand.class); registerCommand(NEconomyCommand.class); registerCommand(NFriendsCommand.class); registerCommand(JailCommand.class); registerCommand(KitsCommand.class); registerCommand(PlayersCommand.class); registerCommand(PluginsCommand.class); registerCommand(ProvidersCommand.class); registerCommand(RegionsCommand.class); registerCommand(ResPacksCommand.class); registerCommand(ScriptsCommand.class); registerCommand(SignsCommand.class); registerCommand(StorageCommand.class); registerCommand(TPCommand.class); loadScriptManager(); // initialize player tracker InternalPlayerTracker.get(); } @Override protected void onDisablePlugin() { // make sure that evaluated scripts are disposed if (_scriptManager != null) { _scriptManager.clearScripts(); } } private void loadScriptManager() { // allow script engines to find nucleus classes Thread.currentThread().setContextClassLoader(getClassLoader()); File scriptFolder = new File(getDataFolder(), "scripts"); if (!scriptFolder.exists() && !scriptFolder.mkdirs()) { throw new RuntimeException("Failed to create script folder."); } _scriptManager = new InternalScriptManager(scriptFolder); _scriptManager.reload(); } /** * Invoked by the provider loader when all providers are ready. */ public void notifyProvidersReady() { if (_isModulesReady) return; _isModulesReady = true; onEnablePlugin(); // enable Nucleus plugins for (NucleusPlugin plugin : NucleusPlugin._enabled) { if (plugin instanceof BukkitPlugin) continue; // skip plugins that were disabled before this point. if (!plugin.isEnabled()) continue; try { plugin._isEnabled = true; plugin.onEnablePlugin(); } catch (Throwable e) { e.printStackTrace(); plugin._isEnabled = false; Bukkit.getPluginManager().disablePlugin(plugin); } } NucleusLoadedEvent event = new NucleusLoadedEvent(); Bukkit.getPluginManager().callEvent(event); } /* * Init class loader into global factory. * Reflection used to prevent compile issues with "internal" package. * * Equivalent code: * * ContextFactory factory = ContextFactory.getGlobal(); * ClassLoader loader = Nucleus.class.getClassLoader(); * * if (loader == null) { * factory.initApplicationClassLoader(loader); * } */ private void initRhinoClassLoader() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { Class<?> contextFactoryClass = Class.forName("sun.org.mozilla.javascript.internal.ContextFactory"); Method getGlobal = contextFactoryClass.getDeclaredMethod("getGlobal"); getGlobal.setAccessible(true); ClassLoader classLoader = Nucleus.class.getClassLoader(); Object contextFactory = getGlobal.invoke(null); Method getApplicationClassLoader = contextFactoryClass.getDeclaredMethod( "getApplicationClassLoader"); getApplicationClassLoader.setAccessible(true); ClassLoader current = (ClassLoader) getApplicationClassLoader.invoke(contextFactory); if (current == null) { Method initApplicationClassLoader = contextFactoryClass.getDeclaredMethod( "initApplicationClassLoader", ClassLoader.class); initApplicationClassLoader.setAccessible(true); initApplicationClassLoader.invoke(contextFactory, classLoader); } } }