/* * This file is part of BukkitBridge. * * Copyright (c) 2012 Spout LLC <http://www.spout.org/> * BukkitBridge is licensed under the GNU General Public License. * * BukkitBridge is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * BukkitBridge is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.spout.bridge.bukkit; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.UUID; import java.util.logging.Level; import java.util.logging.Logger; import com.avaje.ebean.config.ServerConfig; import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.OfflinePlayer; import org.bukkit.Server; import org.bukkit.Warning.WarningState; import org.bukkit.World; import org.bukkit.WorldCreator; import org.bukkit.command.CommandException; import org.bukkit.command.CommandSender; import org.bukkit.command.ConsoleCommandSender; import org.bukkit.command.PluginCommand; import org.bukkit.entity.Player; import org.bukkit.event.inventory.InventoryType; import org.bukkit.help.HelpMap; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.ItemFactory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.Recipe; import org.bukkit.map.MapView; import org.bukkit.permissions.Permission; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginLoadOrder; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.ServicesManager; import org.bukkit.plugin.SimpleServicesManager; import org.bukkit.plugin.java.JavaPluginLoader; import org.bukkit.plugin.messaging.Messenger; import org.bukkit.potion.PotionEffectType; import org.bukkit.scheduler.BukkitScheduler; import org.bukkit.scoreboard.ScoreboardManager; import org.bukkit.util.permissions.DefaultPermissions; import org.spout.api.util.access.BanType; import org.spout.bridge.BukkitBridgePlugin; import org.spout.bridge.BukkitUtil; import org.spout.bridge.bukkit.command.BridgeConsoleCommandSender; import org.spout.bridge.bukkit.entity.EntityFactory; import org.spout.bridge.bukkit.scheduler.BridgeScheduler; import org.spout.vanilla.data.configuration.VanillaConfiguration; import org.spout.vanilla.data.configuration.WorldConfiguration; import org.spout.vanilla.inventory.recipe.VanillaRecipes; /** * BridgeServer is Bridge's version of Bukkit's Server. */ public class BridgeServer implements Server { private final BukkitBridgePlugin plugin; private final org.spout.api.Server server; private final SimpleServicesManager servicesManager; private final BridgeScheduler scheduler; private final PluginManager pluginManager; private final String bridgeVersion = getPOMVersion(); private final String serverVersion; private final ConsoleCommandSender consoleSender; public BridgeServer(org.spout.api.Server server, BukkitBridgePlugin plugin) { this.server = server; this.plugin = plugin; this.consoleSender = new BridgeConsoleCommandSender(); serverVersion = "Spout Server ( " + server.getVersion() + " )"; servicesManager = new SimpleServicesManager(); scheduler = new BridgeScheduler(plugin); pluginManager = new ForwardingPluginManager(this); org.bukkit.enchantments.Enchantment.stopAcceptingRegistrations(); PotionEffectType.stopAcceptingRegistrations(); } public void loadPlugins() { pluginManager.registerInterface(JavaPluginLoader.class); File pluginFolder = new File(plugin.getDataFolder(), "plugins"); if (pluginFolder.exists()) { Plugin[] plugins = pluginManager.loadPlugins(pluginFolder); for (Plugin plugin : plugins) { try { String message = String.format("Loading %s", plugin.getDescription().getFullName()); plugin.getLogger().info(message); plugin.onLoad(); } catch (Throwable ex) { getLogger().log(Level.SEVERE, ex.getMessage() + " initializing " + plugin.getDescription().getFullName(), ex); } } } else { pluginFolder.mkdirs(); } } public void enablePlugins(PluginLoadOrder type) { Plugin[] plugins = pluginManager.getPlugins(); for (Plugin plugin : plugins) { if ((!plugin.isEnabled()) && (plugin.getDescription().getLoad() == type)) { loadPlugin(plugin); } } if (type == PluginLoadOrder.POSTWORLD) { DefaultPermissions.registerCorePermissions(); } } public void disablePlugins() { pluginManager.disablePlugins(); } private void loadPlugin(Plugin plugin) { try { pluginManager.enablePlugin(plugin); List<Permission> perms = plugin.getDescription().getPermissions(); for (Permission perm : perms) { try { pluginManager.addPermission(perm); } catch (IllegalArgumentException ex) { getLogger().log(Level.WARNING, "Plugin " + plugin.getDescription().getFullName() + " tried to register permission '" + perm.getName() + "' but it's already registered", ex); } } } catch (Throwable ex) { getLogger().log(Level.SEVERE, ex.getMessage() + " loading " + plugin.getDescription().getFullName(), ex); } } @Override public Set<String> getListeningPluginChannels() { throw new UnsupportedOperationException(); } @Override public void sendPluginMessage(Plugin arg0, String arg1, byte[] arg2) { throw new UnsupportedOperationException(); } @Override public boolean addRecipe(Recipe recipe) { throw new UnsupportedOperationException(); } @Override public void banIP(String ip) { server.getAccessManager().ban(BanType.IP, ip); } @Override public int broadcast(String perm, String message) { server.broadcastMessage(perm, message); return 0; } @Override public int broadcastMessage(String message) { server.broadcastMessage(message); return 0; } @Override public void clearRecipes() { throw new UnsupportedOperationException(); } @Override public void configureDbConfig(ServerConfig arg0) { throw new UnsupportedOperationException(); } @Override public Inventory createInventory(InventoryHolder arg0, InventoryType arg1) { throw new UnsupportedOperationException(); } @Override public Inventory createInventory(InventoryHolder arg0, int arg1) { throw new UnsupportedOperationException(); } @Override public Inventory createInventory(InventoryHolder arg0, int arg1, String arg2) { throw new UnsupportedOperationException(); } @Override public MapView createMap(World arg0) { throw new UnsupportedOperationException(); } @Override public World createWorld(WorldCreator arg0) { throw new UnsupportedOperationException(); } @Override public boolean dispatchCommand(CommandSender sender, String commandLine) throws CommandException { if (sender instanceof Player) { ((Player) sender).performCommand(commandLine); } else if (sender instanceof ConsoleCommandSender) { BukkitUtil.processCommand(server.getCommandSource(), commandLine); } return true; } @Override public boolean getAllowEnd() { return WorldConfiguration.THE_END.LOAD.getBoolean(); } @Override public boolean getAllowFlight() { return WorldConfiguration.NORMAL.ALLOW_FLIGHT.getBoolean(); } @Override public boolean isHardcore() { return false; // TODO: } @Override public boolean getAllowNether() { return WorldConfiguration.NETHER.LOAD.getBoolean(); } @Override public int getAnimalSpawnLimit() { throw new UnsupportedOperationException(); } @Override public Set<OfflinePlayer> getBannedPlayers() { throw new UnsupportedOperationException(); } @Override public String getBukkitVersion() { return bridgeVersion; } @Override public Map<String, String[]> getCommandAliases() { throw new UnsupportedOperationException(); } @Override public long getConnectionThrottle() { return 0; } @Override public ConsoleCommandSender getConsoleSender() { return consoleSender; } @Override public GameMode getDefaultGameMode() { return GameMode.valueOf(WorldConfiguration.NORMAL.GAMEMODE.getString().toUpperCase()); } @Override public boolean getGenerateStructures() { throw new UnsupportedOperationException(); } @Override public HelpMap getHelpMap() { throw new UnsupportedOperationException(); } @Override public Set<String> getIPBans() { return new HashSet<String>(server.getAccessManager().getBanned(BanType.IP)); } @Override public String getIp() { return ""; } @Override public Logger getLogger() { return server.getLogger(); } @Override public MapView getMap(short arg0) { throw new UnsupportedOperationException(); } @Override public int getMaxPlayers() { return server.getMaxPlayers(); } @Override public Messenger getMessenger() { throw new UnsupportedOperationException(); } @Override public int getMonsterSpawnLimit() { throw new UnsupportedOperationException(); } @Override public String getMotd() { return VanillaConfiguration.MOTD.getString(); } @Override public String getShutdownMessage() { return null; // TODO } @Override public String getName() { return server.getName(); } @Override public OfflinePlayer getOfflinePlayer(String name) { throw new UnsupportedOperationException(); } @Override public OfflinePlayer[] getOfflinePlayers() { throw new UnsupportedOperationException(); } @Override public boolean getOnlineMode() { return VanillaConfiguration.ONLINE_MODE.getBoolean(); } @Override public Player[] getOnlinePlayers() { org.spout.api.entity.Player[] online = server.getOnlinePlayers(); Player[] copy = new Player[online.length]; for (int i = 0; i < online.length; i++) { copy[i] = EntityFactory.createPlayer(online[i]); } return copy; } @Override public Set<OfflinePlayer> getOperators() { throw new UnsupportedOperationException(); } @Override public Player getPlayer(String arg0) { throw new UnsupportedOperationException(); } @Override public Player getPlayerExact(String arg0) { throw new UnsupportedOperationException(); } @Override public PluginCommand getPluginCommand(String arg0) { throw new UnsupportedOperationException(); } @Override public PluginManager getPluginManager() { return pluginManager; } @Override public int getPort() { throw new UnsupportedOperationException(); } @Override public List<Recipe> getRecipesFor(ItemStack arg0) { throw new UnsupportedOperationException(); } @Override public BukkitScheduler getScheduler() { return scheduler; } @Override public String getServerId() { throw new UnsupportedOperationException(); } @Override public String getServerName() { throw new UnsupportedOperationException(); } @Override public ServicesManager getServicesManager() { return servicesManager; } @Override public int getSpawnRadius() { throw new UnsupportedOperationException(); } @Override public int getTicksPerAnimalSpawns() { throw new UnsupportedOperationException(); } @Override public int getTicksPerMonsterSpawns() { throw new UnsupportedOperationException(); } @Override public String getUpdateFolder() { return "update"; } @Override public File getUpdateFolderFile() { return new File(plugin.getDataFolder(), "update"); } @Override public String getVersion() { return serverVersion; } @Override public int getViewDistance() { throw new UnsupportedOperationException(); } @Override public int getWaterAnimalSpawnLimit() { throw new UnsupportedOperationException(); } @Override public int getAmbientSpawnLimit() { return 0; // TODO } @Override public Set<OfflinePlayer> getWhitelistedPlayers() { HashSet<OfflinePlayer> set = new HashSet<OfflinePlayer>(); for (String name : server.getAccessManager().getWhitelistedPlayers()) { set.add(getOfflinePlayer(name)); } return set; } @Override public BridgeWorld getWorld(String name) { for (World w : getWorlds()) { if (w.getName().equals(name)) { return (BridgeWorld) w; } } return null; } @Override public BridgeWorld getWorld(UUID uid) { for (World w : getWorlds()) { if (w.getUID().equals(uid)) { return (BridgeWorld) w; } } return null; } @Override public File getWorldContainer() { return server.getWorldFolder(); } @Override public String getWorldType() { return "DEFAULT"; } @SuppressWarnings ({"unchecked", "rawtypes"}) @Override public List<World> getWorlds() { return (List<World>) (List) plugin.getWorldListener().getWorlds(); } @Override public boolean hasWhitelist() { return server.getAccessManager().isWhitelistEnabled(); } @Override public boolean isPrimaryThread() { return server.getMainThread() == Thread.currentThread(); } @Override public List<Player> matchPlayer(String arg0) { throw new UnsupportedOperationException(); } @Override public Iterator<Recipe> recipeIterator() { throw new UnsupportedOperationException(); } @Override public void reload() { } @Override public void reloadWhitelist() { server.getAccessManager().load(); } @Override public void resetRecipes() { this.clearRecipes(); VanillaRecipes.initialize(); } @Override public void savePlayers() { for (org.spout.api.entity.Player p : server.getOnlinePlayers()) { p.save(); } } @Override public void setDefaultGameMode(GameMode mode) { WorldConfiguration.NORMAL.GAMEMODE.setValue(mode.name().toLowerCase()); WorldConfiguration.FLAT.GAMEMODE.setValue(mode.name().toLowerCase()); WorldConfiguration.NETHER.GAMEMODE.setValue(mode.name().toLowerCase()); WorldConfiguration.THE_END.GAMEMODE.setValue(mode.name().toLowerCase()); } @Override public void setSpawnRadius(int r) { VanillaConfiguration.SPAWN_PROTECTION_RADIUS.setValue(r); } @Override public void setWhitelist(boolean whitelisted) { server.getAccessManager().setWhitelistEnabled(whitelisted); } @Override public void shutdown() { server.stop(); } @Override public void unbanIP(String ip) { server.getAccessManager().unban(BanType.IP, ip); } @Override public boolean unloadWorld(String name, boolean save) { return unloadWorld(getWorld(name), save); } @Override public boolean unloadWorld(World world, boolean save) { if (world != null) { ((BridgeWorld) world).getHandle().unload(save); return true; } return false; } @Override public boolean useExactLoginLocation() { throw new UnsupportedOperationException(); } @Override public WarningState getWarningState() { return WarningState.DEFAULT; } @Override public ItemFactory getItemFactory() { throw new UnsupportedOperationException(); } @Override public ScoreboardManager getScoreboardManager() { throw new UnsupportedOperationException(); } private static String getPOMVersion() { String result = "Unknown-Version"; InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/org.spout/bukkitbridge/pom.properties"); Properties properties = new Properties(); if (stream != null) { try { properties.load(stream); result = properties.getProperty("version"); } catch (IOException ex) { BukkitBridgePlugin.getInstance().getEngine().getLogger().severe("Could not get Bridge version!\n" + ex); } } return result; } }