blue.lapis.pore.impl.PoreServer.java Source code

Java tutorial

Introduction

Here is the source code for blue.lapis.pore.impl.PoreServer.java

Source

/*
 * Pore
 * Copyright (c) 2014-2015, Lapis <https://github.com/LapisBlue>
 *
 * The MIT License
 *
 * 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 blue.lapis.pore.impl;

import blue.lapis.pore.PoreVersion;
import blue.lapis.pore.converter.wrapper.WrapperConverter;
import blue.lapis.pore.impl.command.PoreCommandMap;
import blue.lapis.pore.impl.command.PoreConsoleCommandSender;
import blue.lapis.pore.impl.entity.PorePlayer;
import blue.lapis.pore.impl.help.PoreHelpMap;
import blue.lapis.pore.impl.scheduler.PoreBukkitScheduler;
import blue.lapis.pore.impl.util.PoreCachedServerIcon;
import blue.lapis.pore.util.PoreCollections;
import blue.lapis.pore.util.PoreWrapper;

import com.avaje.ebean.config.ServerConfig;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.NotImplementedException;
import org.bukkit.BanList;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.OfflinePlayer;
import org.bukkit.Server;
import org.bukkit.UnsafeValues;
import org.bukkit.Warning;
import org.bukkit.World;
import org.bukkit.WorldCreator;
import org.bukkit.command.Command;
import org.bukkit.command.CommandException;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.command.PluginCommand;
import org.bukkit.command.SimpleCommandMap;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.generator.ChunkGenerator;
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.Permissible;
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.SimplePluginManager;
import org.bukkit.plugin.SimpleServicesManager;
import org.bukkit.plugin.java.JavaPluginLoader;
import org.bukkit.plugin.messaging.Messenger;
import org.bukkit.plugin.messaging.StandardMessenger;
import org.bukkit.scheduler.BukkitScheduler;
import org.bukkit.scoreboard.ScoreboardManager;
import org.bukkit.util.CachedServerIcon;
import org.bukkit.util.StringUtil;
import org.bukkit.util.permissions.DefaultPermissions;
import org.spongepowered.api.Game;
import org.spongepowered.api.text.Texts;
import org.spongepowered.api.util.command.source.ConsoleSource;

import java.awt.image.BufferedImage;
import java.io.File;
import java.net.InetSocketAddress;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;

public class PoreServer extends PoreWrapper<org.spongepowered.api.Server> implements Server {

    private final Game game;
    private final Logger logger;
    private final SimpleCommandMap commandMap;
    private final PluginManager pluginManager;
    private final ServicesManager servicesManager;
    private final Messenger messenger = new StandardMessenger();
    private final Warning.WarningState warnState = Warning.WarningState.DEFAULT;
    private final HelpMap helpMap = new PoreHelpMap();
    private final File pluginsDir = new File(".", "bukkit-plugins");
    //TODO: use actual server directory, currently set to working directory

    private final BukkitScheduler scheduler = new PoreBukkitScheduler();

    public PoreServer(org.spongepowered.api.Game handle, org.slf4j.Logger logger) {
        super(handle.getServer());
        this.game = handle;
        this.logger = Logger.getLogger(logger.getName());
        this.commandMap = new PoreCommandMap(this);
        this.pluginManager = new SimplePluginManager(this, commandMap);
        this.servicesManager = new SimpleServicesManager();
        Bukkit.setServer(this);
    }

    public Game getGame() {
        return game;
    }

    public void loadPlugins() {
        if (pluginsDir.isDirectory()) {
            // Clear plugins and prepare to load
            pluginManager.clearPlugins();
            pluginManager.registerInterface(JavaPluginLoader.class);

            // Call onLoad methods
            for (Plugin plugin : pluginManager.loadPlugins(pluginsDir)) {
                try {
                    getLogger().info(String.format("Loading %s", plugin.getDescription().getFullName()));
                    plugin.onLoad();
                } catch (RuntimeException ex) {
                    getLogger().log(Level.SEVERE, ex.getMessage() + " initializing "
                            + plugin.getDescription().getFullName() + " (Is it up to date?)", ex);
                }
            }
        } else {
            if (!pluginsDir.mkdir()) {
                logger.log(Level.SEVERE, "Could not create plugins directory: " + pluginsDir);
            }
        }
    }

    private void loadPlugin(Plugin plugin) {
        for (Permission perm : plugin.getDescription().getPermissions()) {
            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);
            }
        }

        try {
            pluginManager.enablePlugin(plugin);
        } catch (Throwable ex) {
            getLogger().log(Level.SEVERE,
                    ex.getMessage() + " loading " + plugin.getDescription().getFullName() + " (Is it up to date?)");
        }
    }

    public void enablePlugins(PluginLoadOrder type) {
        if (type == PluginLoadOrder.STARTUP) {
            // TODO
            //helpMap.clear();
        }

        // Load all the plugins
        for (Plugin plugin : pluginManager.getPlugins()) {
            if (!plugin.isEnabled() && plugin.getDescription().getLoad() == type) {
                loadPlugin(plugin);
            }
        }

        if (type == PluginLoadOrder.POSTWORLD) {
            commandMap.setFallbackCommands();
            //commandMap.registerServerAliases();
            DefaultPermissions.registerCorePermissions();
            //helpMap.initializeCommands();
        }
    }

    public void disablePlugins() {
        pluginManager.disablePlugins();
    }

    @Override
    public String getName() {
        return PoreVersion.NAME;
    }

    @Override
    public String getVersion() {
        return PoreVersion.VERSION + '@' + game.getPlatform().getVersion();
    }

    @Override
    public String getBukkitVersion() {
        return PoreVersion.API_VERSION + '@' + game.getPlatform().getApiVersion();
    }

    @Override
    public Player[] _INVALID_getOnlinePlayers() {
        Collection<? extends Player> online = getOnlinePlayers();
        return online.toArray(new Player[online.size()]);
    }

    @Override
    public Collection<? extends Player> getOnlinePlayers() {
        return PoreCollections.transform(getHandle().getOnlinePlayers(),
                WrapperConverter.<org.spongepowered.api.entity.player.Player, PorePlayer>getConverter());
    }

    @Override
    public int getMaxPlayers() {
        return getHandle().getMaxPlayers();
    }

    @Override
    public int getPort() {
        Optional<InetSocketAddress> address = getHandle().getBoundAddress();
        if (address.isPresent()) {
            return address.get().getPort();
        } else {
            return -1;
        }
    }

    @Override
    public int getViewDistance() {
        throw new NotImplementedException("TODO");
    }

    @Override
    public String getIp() {
        Optional<InetSocketAddress> address = getHandle().getBoundAddress();
        if (address.isPresent()) {
            return address.get().getHostName();
        } else {
            return "Unknown";
        }
    }

    @Override
    public String getServerName() {
        throw new NotImplementedException("TODO");
    }

    @Override
    public String getServerId() {
        throw new NotImplementedException("TODO");
    }

    @Override
    public String getWorldType() {
        throw new NotImplementedException("TODO");
    }

    @Override
    public boolean getGenerateStructures() {
        throw new NotImplementedException("TODO");
    }

    @Override
    public boolean getAllowEnd() {
        throw new NotImplementedException("TODO");
    }

    @Override
    public boolean getAllowNether() {
        throw new NotImplementedException("TODO");
    }

    @Override
    public boolean hasWhitelist() {
        return getHandle().hasWhitelist();
    }

    @Override
    public void setWhitelist(boolean value) {
        getHandle().setHasWhitelist(value);
    }

    @Override
    public Set<OfflinePlayer> getWhitelistedPlayers() {
        throw new NotImplementedException("TODO");
    }

    @Override
    public void reloadWhitelist() {
        throw new NotImplementedException("TODO");
    }

    @Override
    public int broadcastMessage(String message) {
        return broadcast(message, BROADCAST_CHANNEL_USERS);
    }

    @Override
    public String getUpdateFolder() {
        return "update";
    }

    @Override
    public File getUpdateFolderFile() {
        return new File(pluginsDir, getUpdateFolder());
    }

    @Override
    public long getConnectionThrottle() {
        throw new NotImplementedException("TODO");
    }

    @Override
    public int getTicksPerAnimalSpawns() {
        throw new NotImplementedException("TODO");
    }

    @Override
    public int getTicksPerMonsterSpawns() {
        throw new NotImplementedException("TODO");
    }

    @Override
    public Player getPlayer(String name) {
        Preconditions.checkNotNull(name, "name");

        org.spongepowered.api.entity.player.Player result = null;
        int delta = Integer.MAX_VALUE;
        for (org.spongepowered.api.entity.player.Player player : getHandle().getOnlinePlayers()) {
            if (StringUtil.startsWithIgnoreCase(player.getName(), name)) {
                int newDelta = player.getName().length() - name.length();
                if (newDelta < delta) {
                    result = player;
                    delta = newDelta;
                }

                if (newDelta == 0) {
                    break;
                }
            }
        }

        return result != null ? PorePlayer.of(result) : null;
    }

    @Override
    public Player getPlayerExact(String name) {
        Optional<org.spongepowered.api.entity.player.Player> player = getHandle().getPlayer(name);
        return player.isPresent() ? PorePlayer.of(player.get()) : null;
    }

    @Override
    public List<Player> matchPlayer(String name) {
        Preconditions.checkNotNull(name, "name");
        name = name.toLowerCase();

        List<Player> result = Lists.newArrayList();
        for (org.spongepowered.api.entity.player.Player player : getHandle().getOnlinePlayers()) {
            String playerName = player.getName().toLowerCase();

            if (name.equals(playerName)) {
                // Exact match
                return ImmutableList.<Player>of(PorePlayer.of(player));
            }

            if (playerName.contains(name)) {
                // Partial match
                result.add(PorePlayer.of(player));
            }
        }

        return result;
    }

    @Override
    public Player getPlayer(UUID id) {
        Optional<org.spongepowered.api.entity.player.Player> player = getHandle().getPlayer(id);
        return player.isPresent() ? PorePlayer.of(player.get()) : null;
    }

    @Override
    public PluginManager getPluginManager() {
        return pluginManager;
    }

    @Override
    public BukkitScheduler getScheduler() {
        return scheduler;
    }

    @Override
    public ServicesManager getServicesManager() {
        return servicesManager;
    }

    @Override
    public List<World> getWorlds() {
        return PoreCollections.<org.spongepowered.api.world.World, World>transformToList(getHandle().getWorlds(),
                WrapperConverter.<org.spongepowered.api.world.World, PoreWorld>getConverter());
    }

    @Override
    public World createWorld(WorldCreator creator) {
        throw new NotImplementedException("TODO");
    }

    @Override
    public boolean unloadWorld(String name, boolean save) {
        Optional<org.spongepowered.api.world.World> world = getHandle().getWorld(name);
        return world.isPresent() && getHandle().unloadWorld(world.get());
    }

    @Override
    public boolean unloadWorld(World world, boolean save) {
        return getHandle().unloadWorld(((PoreWorld) world).getHandle());
    }

    @Override
    public World getWorld(String name) {
        Optional<org.spongepowered.api.world.World> world = getHandle().getWorld(name);
        return world.isPresent() ? PoreWorld.of(world.get()) : null;
    }

    @Override
    public World getWorld(UUID uid) {
        Optional<org.spongepowered.api.world.World> world = getHandle().getWorld(uid);
        return world.isPresent() ? PoreWorld.of(world.get()) : null;
    }

    @Override
    public MapView getMap(short id) {
        throw new NotImplementedException("TODO");
    }

    @Override
    public MapView createMap(World world) {
        throw new NotImplementedException("TODO");
    }

    @Override
    public void reload() {
        throw new UnsupportedOperationException("Sponge does not support server reloads");
    }

    @Override
    public Logger getLogger() {
        return logger;
    }

    @Override
    public PluginCommand getPluginCommand(String name) {
        Command command = commandMap.getCommand(name);

        if (command instanceof PluginCommand) {
            return (PluginCommand) command;
        } else {
            return null;
        }
    }

    @Override
    public void savePlayers() {
        throw new NotImplementedException("TODO");
    }

    @Override
    public boolean dispatchCommand(CommandSender sender, String commandLine) throws CommandException {
        Preconditions.checkNotNull(sender, "sender");
        Preconditions.checkNotNull(commandLine, "commandLine");

        return commandMap.dispatch(sender, commandLine);
    }

    @Override
    public void configureDbConfig(ServerConfig config) {
        throw new NotImplementedException("TODO");
    }

    @Override
    public boolean addRecipe(Recipe recipe) {
        throw new NotImplementedException("TODO");
    }

    @Override
    public List<Recipe> getRecipesFor(ItemStack result) {
        throw new NotImplementedException("TODO");
    }

    @Override
    public Iterator<Recipe> recipeIterator() {
        throw new NotImplementedException("TODO");
    }

    @Override
    public void clearRecipes() {
        throw new NotImplementedException("TODO");
    }

    @Override
    public void resetRecipes() {
        throw new NotImplementedException("TODO");
    }

    @Override
    public Map<String, String[]> getCommandAliases() {
        throw new NotImplementedException("TODO");
    }

    @Override
    public int getSpawnRadius() {
        throw new NotImplementedException("TODO");
    }

    @Override
    public void setSpawnRadius(int value) {
        throw new NotImplementedException("TODO");
    }

    @Override
    public boolean getOnlineMode() {
        return getHandle().getOnlineMode();
    }

    @Override
    public boolean getAllowFlight() {
        throw new NotImplementedException("TODO");
    }

    @Override
    public boolean isHardcore() {
        throw new NotImplementedException("TODO");
    }

    @Override
    public boolean useExactLoginLocation() {
        throw new NotImplementedException("TODO");
    }

    @Override
    public void shutdown() {
        throw new NotImplementedException("TODO");
    }

    @Override
    public int broadcast(String message, String permission) {
        int count = 0;
        Set<Permissible> permissibles = getPluginManager().getPermissionSubscriptions(permission);

        for (Permissible permissible : permissibles) {
            if (permissible instanceof CommandSender && permissible.hasPermission(permission)) {
                CommandSender user = (CommandSender) permissible;
                user.sendMessage(message);
                count++;
            }
        }

        return count;
    }

    @Override
    public OfflinePlayer getOfflinePlayer(String name) {
        throw new NotImplementedException("TODO");
    }

    @Override
    public OfflinePlayer getOfflinePlayer(UUID id) {
        throw new NotImplementedException("TODO");
    }

    @Override
    public Set<String> getIPBans() {
        throw new NotImplementedException("TODO");
    }

    @Override
    public void banIP(String address) {
        throw new NotImplementedException("TODO");
    }

    @Override
    public void unbanIP(String address) {
        throw new NotImplementedException("TODO");
    }

    @Override
    public Set<OfflinePlayer> getBannedPlayers() {
        throw new NotImplementedException("TODO");
    }

    @Override
    public BanList getBanList(BanList.Type type) {
        throw new NotImplementedException("TODO");
    }

    @Override
    public Set<OfflinePlayer> getOperators() {
        throw new NotImplementedException("TODO");
    }

    @Override
    public GameMode getDefaultGameMode() {
        throw new NotImplementedException("TODO");
    }

    @Override
    public void setDefaultGameMode(GameMode mode) {
        throw new NotImplementedException("TODO");
    }

    @Override
    public ConsoleCommandSender getConsoleSender() {
        return PoreConsoleCommandSender.of((ConsoleSource) getHandle());
    }

    @Override
    public File getWorldContainer() {
        throw new NotImplementedException("TODO");
    }

    @Override
    public PoreOfflinePlayer[] getOfflinePlayers() {
        throw new NotImplementedException("TODO");
    }

    @Override
    public Messenger getMessenger() {
        return messenger;
    }

    @Override
    public HelpMap getHelpMap() {
        return helpMap;
    }

    @Override
    public Inventory createInventory(InventoryHolder owner, InventoryType type) {
        throw new NotImplementedException("TODO");
    }

    @Override
    public Inventory createInventory(InventoryHolder owner, InventoryType type, String title) {
        throw new NotImplementedException("TODO");
    }

    @Override
    public Inventory createInventory(InventoryHolder owner, int size) throws IllegalArgumentException {
        throw new NotImplementedException("TODO");
    }

    @Override
    public Inventory createInventory(InventoryHolder owner, int size, String title)
            throws IllegalArgumentException {
        throw new NotImplementedException("TODO");
    }

    @Override
    public int getMonsterSpawnLimit() {
        throw new NotImplementedException("TODO");
    }

    @Override
    public int getAnimalSpawnLimit() {
        throw new NotImplementedException("TODO");
    }

    @Override
    public int getWaterAnimalSpawnLimit() {
        throw new NotImplementedException("TODO");
    }

    @Override
    public int getAmbientSpawnLimit() {
        throw new NotImplementedException("TODO");
    }

    @Override
    public boolean isPrimaryThread() {
        throw new NotImplementedException("TODO");
    }

    @Override
    @SuppressWarnings("deprecation")
    public String getMotd() {
        return Texts.legacy().to(getHandle().getMotd());
    }

    @Override
    public String getShutdownMessage() {
        throw new NotImplementedException("TODO");
    }

    @Override
    public Warning.WarningState getWarningState() {
        return warnState;
    }

    @Override
    public ItemFactory getItemFactory() {
        throw new NotImplementedException("TODO");
    }

    @Override
    public ScoreboardManager getScoreboardManager() {
        throw new NotImplementedException("TODO");
    }

    @Override
    public CachedServerIcon getServerIcon() {
        throw new NotImplementedException("TODO");
    }

    @Override
    public CachedServerIcon loadServerIcon(File file) throws Exception {
        return PoreCachedServerIcon.of(game.getRegistry().loadFavicon(file));
    }

    @Override
    public CachedServerIcon loadServerIcon(BufferedImage image) throws Exception {
        return PoreCachedServerIcon.of(game.getRegistry().loadFavicon(image));
    }

    @Override
    public void setIdleTimeout(int threshold) {
        throw new NotImplementedException("TODO");
    }

    @Override
    public int getIdleTimeout() {
        throw new NotImplementedException("TODO");
    }

    @Override
    public ChunkGenerator.ChunkData createChunkData(World world) {
        throw new NotImplementedException("TODO");
    }

    @Deprecated
    @Override
    @SuppressWarnings("deprecation")
    public UnsafeValues getUnsafe() {
        return PoreUnsafeValues.INSTANCE;
    }

    @Override
    public void sendPluginMessage(Plugin source, String channel, byte[] message) {
        StandardMessenger.validatePluginMessage(getMessenger(), source, channel, message);

        for (Player player : getOnlinePlayers()) {
            player.sendPluginMessage(source, channel, message);
        }
    }

    @Override
    public Set<String> getListeningPluginChannels() {
        Set<String> result = new HashSet<String>();

        for (Player player : getOnlinePlayers()) {
            result.addAll(player.getListeningPluginChannels());
        }

        return result;
    }
}