blob: 3260d956c8fe7c4a004338704b7e359c8eed67ae [file] [log] [blame] [raw]
package net.glowstone;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import net.glowstone.command.ColorCommand;
import net.glowstone.inventory.CraftingManager;
import net.glowstone.inventory.GlowInventory;
import net.glowstone.inventory.GlowItemFactory;
import net.glowstone.map.GlowMapView;
import net.glowstone.net.GlowNetworkServer;
import net.glowstone.net.SessionRegistry;
import net.glowstone.scheduler.GlowScheduler;
import net.glowstone.scheduler.WorldScheduler;
import net.glowstone.util.*;
import net.glowstone.util.bans.GlowBanList;
import org.bukkit.*;
import org.bukkit.World.Environment;
import org.bukkit.command.*;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.serialization.ConfigurationSerialization;
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.*;
import org.bukkit.permissions.Permissible;
import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionDefault;
import org.bukkit.plugin.*;
import org.bukkit.plugin.java.JavaPluginLoader;
import org.bukkit.plugin.messaging.Messenger;
import org.bukkit.plugin.messaging.StandardMessenger;
import org.bukkit.scoreboard.ScoreboardManager;
import org.bukkit.util.CachedServerIcon;
import org.bukkit.util.permissions.DefaultPermissions;
import java.awt.image.BufferedImage;
import java.io.File;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.security.KeyPair;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* The core class of the Glowstone server.
* @author Graham Edgecombe
*/
public final class GlowServer implements Server {
/**
* The logger for this class.
*/
public static final Logger logger = Logger.getLogger("Minecraft");
/**
* The game version supported by the server.
*/
public static final String GAME_VERSION = "1.7.8";
/**
* The protocol version supported by the server.
*/
public static final int PROTOCOL_VERSION = 5;
/**
* Creates a new server on TCP port 25565 and starts listening for
* connections.
* @param args The command-line arguments.
*/
public static void main(String[] args) {
try {
ConfigurationSerialization.registerClass(GlowOfflinePlayer.class);
File configDir = null;
File configFile = null;
// parse args
for (int i = 0; i < args.length; i += 2) {
String opt = args[i];
if (!opt.startsWith("-")) {
System.err.println("Option specified without -: " + opt);
System.exit(1);
return;
}
while (opt.startsWith("-")) {
opt = opt.substring(1);
}
if (opt.equalsIgnoreCase("version")) {
System.out.println("Glowstone version: " + GlowServer.class.getPackage().getImplementationVersion());
System.out.println("Bukkit version: " + GlowServer.class.getPackage().getSpecificationVersion());
System.out.println("Minecraft version: " + GAME_VERSION + " protocol " + PROTOCOL_VERSION);
return;
} else if (opt.equalsIgnoreCase("help")) {
System.out.println("Available Glowstone command-line options:");
System.out.println(" --configDir <directory> Set the configuration directory.");
System.out.println(" --configFile <file> Set the configuration file.");
System.out.println(" --version Display version information and exit.");
System.out.println(" --help Display this message and exit.");
return;
}
if (i == args.length - 1) {
System.err.println("Option specified without value: " + opt);
System.exit(1);
return;
}
String arg = args[i + 1];
if (opt.equalsIgnoreCase("configDir")) {
configDir = new File(arg);
} else if (opt.equalsIgnoreCase("configFile")) {
configFile = new File(arg);
} else {
System.err.println("Unknown option: " + opt);
}
}
// start server
ServerConfig config = new ServerConfig(configDir, configFile);
GlowServer server = new GlowServer(config);
server.start();
server.bind();
logger.info("Ready for connections.");
} catch (Throwable t) {
logger.log(Level.SEVERE, "Error during server startup.", t);
System.exit(1);
}
}
/**
* A list of all the active {@link net.glowstone.net.GlowSession}s.
*/
private final SessionRegistry sessions = new SessionRegistry();
/**
* The console manager of this server.
*/
private final ConsoleManager consoleManager = new ConsoleManager(this);
/**
* The services manager of this server.
*/
private final SimpleServicesManager servicesManager = new SimpleServicesManager();
/**
* The command map of this server.
*/
private final SimpleCommandMap commandMap = new SimpleCommandMap(this);
/**
* The plugin manager of this server.
*/
private final PluginManager pluginManager = new SimplePluginManager(this, commandMap);
/**
* The plugin channel messenger for the server.
*/
private final Messenger messenger = new StandardMessenger();
/**
* The help map for the server.
*/
private final GlowHelpMap helpMap = new GlowHelpMap(this);
/**
* The scoreboard manager for the server.
*/
private final ScoreboardManager scoreboardManager = null;
/**
* The crafting manager for this server.
*/
private final CraftingManager craftingManager = new CraftingManager();
/**
* The configuration for the server.
*/
private final ServerConfig config;
/**
* The list of OPs on the server.
*/
private final PlayerListFile opsList;
/**
* The list of players whitelisted on the server.
*/
private final PlayerListFile whitelist;
/**
* The BanList for player names.
*/
private final GlowBanList nameBans;
/**
* The BanList for IP addresses.
*/
private final GlowBanList ipBans;
/**
* The world this server is managing.
*/
private final WorldScheduler worlds = new WorldScheduler();
/**
* The task scheduler used by this server.
*/
private final GlowScheduler scheduler = new GlowScheduler(this, worlds);
/**
* The Bukkit UnsafeValues implementation.
*/
private final UnsafeValues unsafeAccess = new GlowUnsafeValues();
/**
* The server's default game mode
*/
private GameMode defaultGameMode = GameMode.CREATIVE;
/**
* The setting for verbose deprecation warnings.
*/
private Warning.WarningState warnState = Warning.WarningState.DEFAULT;
/**
* Whether the server is shutting down
*/
private boolean isShuttingDown = false;
/**
* Whether the whitelist is in effect.
*/
private boolean whitelistEnabled;
/**
* The size of the area to keep protected around the spawn point.
*/
private int spawnRadius;
/**
* The ticks until a player who has not played the game has been kicked, or 0.
*/
private int idleTimeout;
/**
* A cache of existing OfflinePlayers
*/
private final Map<String, OfflinePlayer> offlineCache = new ConcurrentHashMap<>();
/**
* A RSA key pair used for encryption and authentication
*/
private final KeyPair keyPair = SecurityUtils.generateKeyPair();
/**
* The network server used for network communication
*/
private final GlowNetworkServer networkServer = new GlowNetworkServer(this);
/**
* The default icon, usually blank, used for the server list.
*/
private GlowServerIcon defaultIcon;
/**
* Creates a new server.
*/
public GlowServer(ServerConfig config) {
this.config = config;
// stuff based on selected config directory
opsList = new PlayerListFile(config.getFile("ops.txt"));
whitelist = new PlayerListFile(config.getFile("whitelist.txt"));
nameBans = new GlowBanList(this, BanList.Type.NAME);
ipBans = new GlowBanList(this, BanList.Type.IP);
Bukkit.setServer(this);
loadConfig();
}
/**
* Starts this server.
*/
public void start() {
// Determine console mode and start reading input
consoleManager.startConsole(config.getBoolean(ServerConfig.Key.USE_JLINE));
consoleManager.startFile(config.getString(ServerConfig.Key.LOG_FILE));
// Load player lists
opsList.load();
whitelist.load();
nameBans.load();
ipBans.load();
// Start loading plugins
loadPlugins();
enablePlugins(PluginLoadOrder.STARTUP);
// Create worlds
String name = config.getString(ServerConfig.Key.LEVEL_NAME);
String seedString = config.getString(ServerConfig.Key.LEVEL_SEED);
long seed = seedString.isEmpty() ? System.currentTimeMillis() : seedString.hashCode();
boolean structs = getGenerateStructures();
WorldType type = WorldType.getByName(getWorldType());
if (type == null) {
type = WorldType.NORMAL;
}
createWorld(WorldCreator.name(name).environment(Environment.NORMAL).seed(seed).type(type).generateStructures(structs));
if (getAllowNether()) {
createWorld(WorldCreator.name(name + "_nether").environment(Environment.NETHER).seed(seed).type(type).generateStructures(structs));
}
if (getAllowEnd()) {
createWorld(WorldCreator.name(name + "_the_end").environment(Environment.THE_END).seed(seed).type(type).generateStructures(structs));
}
// Finish loading plugins
enablePlugins(PluginLoadOrder.POSTWORLD);
commandMap.registerServerAliases();
scheduler.start();
}
/**
* Binds this server to the address specified in the configuration.
*/
private void bind() {
String ip = getIp();
int port = getPort();
SocketAddress address;
if (ip.length() == 0) {
address = new InetSocketAddress(port);
} else {
address = new InetSocketAddress(ip, port);
}
logger.log(Level.INFO, "Binding to address: {0}...", address);
ChannelFuture future = networkServer.bind(address);
Channel channel = future.awaitUninterruptibly().channel();
if (!channel.isActive()) {
throw new RuntimeException("Failed to bind to address. Maybe it is already in use?");
}
}
/**
* Stops this server.
*/
public void shutdown() {
// Just in case this gets called twice
if (isShuttingDown) return;
isShuttingDown = true;
logger.info("The server is shutting down...");
// Disable plugins
pluginManager.clearPlugins();
// Kick all players (this saves their data too)
for (Player player : getOnlinePlayers()) {
player.kickPlayer("Server shutting down.");
}
// Stop the network server - starts the shutdown process
// It may take a second or two for Netty to totally clean up
networkServer.shutdown();
// Save worlds
for (World world : getWorlds()) {
logger.info("Saving world: " + world.getName());
unloadWorld(world, true);
}
// Stop scheduler and console
scheduler.stop();
consoleManager.stop();
// Wait for a while and terminate any rogue threads
new ShutdownMonitorThread().start();
}
/**
* Load the server configuration.
*/
private void loadConfig() {
config.load();
// modifiable values
spawnRadius = config.getInt(ServerConfig.Key.SPAWN_RADIUS);
whitelistEnabled = config.getBoolean(ServerConfig.Key.WHITELIST);
idleTimeout = config.getInt(ServerConfig.Key.PLAYER_IDLE_TIMEOUT);
craftingManager.initialize();
// special handling
warnState = Warning.WarningState.value(config.getString(ServerConfig.Key.WARNING_STATE));
try {
defaultGameMode = GameMode.valueOf(GameMode.class, config.getString(ServerConfig.Key.GAMEMODE));
} catch (IllegalArgumentException | NullPointerException e) {
defaultGameMode = GameMode.SURVIVAL;
}
// server icon
defaultIcon = new GlowServerIcon();
try {
File file = config.getFile("server-icon.png");
if (file.isFile()) {
defaultIcon = new GlowServerIcon(file);
}
} catch (Exception e) {
logger.log(Level.WARNING, "Failed to load server-icon.png", e);
}
}
/**
* Loads all plugins, calling onLoad, &c.
*/
private void loadPlugins() {
// clear the map
commandMap.clearCommands();
commandMap.setFallbackCommands();
commandMap.register("glowstone", new ColorCommand("colors"));
File folder = new File(config.getString(ServerConfig.Key.PLUGIN_FOLDER));
if (!folder.isDirectory() && !folder.mkdirs()) {
logger.log(Level.SEVERE, "Could not create plugins directory: " + folder);
}
// clear plugins and prepare to load
pluginManager.clearPlugins();
pluginManager.registerInterface(JavaPluginLoader.class);
Plugin[] plugins = pluginManager.loadPlugins(folder);
// call onLoad methods
for (Plugin plugin : plugins) {
try {
plugin.onLoad();
} catch (Exception ex) {
logger.log(Level.SEVERE, "Error loading {0}: {1}", new Object[]{plugin.getDescription().getName(), ex.getMessage()});
ex.printStackTrace();
}
}
}
/**
* Enable all plugins of the given load order type.
* @param type The type of plugin to enable.
*/
private void enablePlugins(PluginLoadOrder type) {
if (type == PluginLoadOrder.STARTUP) {
helpMap.clear();
helpMap.initializeGeneralTopics();
}
// load all the plugins
Plugin[] plugins = pluginManager.getPlugins();
for (Plugin plugin : plugins) {
if (!plugin.isEnabled() && plugin.getDescription().getLoad() == type) {
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);
}
}
try {
pluginManager.enablePlugin(plugin);
} catch (Throwable ex) {
logger.log(Level.SEVERE, "Error loading {0}", plugin.getDescription().getFullName());
ex.printStackTrace();
}
}
}
if (type == PluginLoadOrder.POSTWORLD) {
commandMap.registerServerAliases();
DefaultPermissions.registerCorePermissions();
helpMap.initializeCommands();
// load permissions.yml
ConfigurationSection permConfig = config.getConfigFile(ServerConfig.Key.PERMISSIONS_FILE);
List<Permission> perms = Permission.loadPermissions(permConfig.getValues(false), "Permission node '%s' in permissions config is invalid", PermissionDefault.OP);
for (Permission perm : perms) {
try {
pluginManager.addPermission(perm);
} catch (IllegalArgumentException ex) {
getLogger().log(Level.WARNING, "Permission config tried to register '" + perm.getName() + "' but it's already registered", ex);
}
}
}
}
/**
* Reloads the server, refreshing settings and plugin information
*/
public void reload() {
try {
// Reload relevant configuration
loadConfig();
opsList.load();
whitelist.load();
nameBans.load();
ipBans.load();
// Reset crafting
craftingManager.resetRecipes();
// Load plugins
loadPlugins();
enablePlugins(PluginLoadOrder.STARTUP);
enablePlugins(PluginLoadOrder.POSTWORLD);
} catch (Exception ex) {
logger.log(Level.SEVERE, "Uncaught error while reloading: {0}", ex.getMessage());
ex.printStackTrace();
}
}
@Override
public String toString() {
return "GlowServer{name=" + getName() + ",version=" + getVersion() + ",minecraftVersion=" + GAME_VERSION + "}";
}
////////////////////////////////////////////////////////////////////////////
// Access to internals
/**
* Gets the command map.
* @return The {@link SimpleCommandMap}.
*/
public SimpleCommandMap getCommandMap() {
return commandMap;
}
/**
* Gets the session registry.
* @return The {@link SessionRegistry}.
*/
public SessionRegistry getSessionRegistry() {
return sessions;
}
/**
* Returns the list of OPs on this server.
*/
public PlayerListFile getOpsList() {
return opsList;
}
/**
* Returns the list of OPs on this server.
*/
public PlayerListFile getWhitelist() {
return whitelist;
}
/**
* Returns the folder where configuration files are stored
*/
public File getConfigDir() {
return config.getDirectory();
}
/**
* Return the crafting manager.
* @return The server's crafting manager.
*/
public CraftingManager getCraftingManager() {
return craftingManager;
}
/**
* The key pair generated at server start up
* @return The key pair generated at server start up
*/
public KeyPair getKeyPair() {
return keyPair;
}
////////////////////////////////////////////////////////////////////////////
// Static server properties
public String getName() {
return "Glowstone";
}
public String getVersion() {
return getClass().getPackage().getImplementationVersion();
}
public String getBukkitVersion() {
return getClass().getPackage().getSpecificationVersion();
}
public Logger getLogger() {
return logger;
}
public boolean isPrimaryThread() {
return scheduler.isPrimaryThread();
}
////////////////////////////////////////////////////////////////////////////
// Access to Bukkit API
public PluginManager getPluginManager() {
return pluginManager;
}
public GlowScheduler getScheduler() {
return scheduler;
}
public ServicesManager getServicesManager() {
return servicesManager;
}
public Messenger getMessenger() {
return messenger;
}
public HelpMap getHelpMap() {
return helpMap;
}
public ItemFactory getItemFactory() {
return GlowItemFactory.instance();
}
public ScoreboardManager getScoreboardManager() {
return scoreboardManager;
}
@Deprecated
public UnsafeValues getUnsafe() {
return unsafeAccess;
}
public BanList getBanList(BanList.Type type) {
switch (type) {
case NAME:
return nameBans;
case IP:
return ipBans;
default:
throw new IllegalArgumentException("Unknown BanList type " + type);
}
}
////////////////////////////////////////////////////////////////////////////
// Commands and console
public ConsoleCommandSender getConsoleSender() {
return consoleManager.getSender();
}
public PluginCommand getPluginCommand(String name) {
Command command = commandMap.getCommand(name);
if (command instanceof PluginCommand) {
return (PluginCommand) command;
} else {
return null;
}
}
public Map<String, String[]> getCommandAliases() {
Map<String, String[]> aliases = new HashMap<String, String[]>();
ConfigurationSection section = config.getConfigFile(ServerConfig.Key.COMMANDS_FILE).getConfigurationSection("aliases");
if (section == null) return aliases;
for (String key : section.getKeys(false)) {
List<String> list = section.getStringList(key);
aliases.put(key, list.toArray(new String[list.size()]));
}
return aliases;
}
public boolean dispatchCommand(CommandSender sender, String commandLine) throws CommandException {
if (commandMap.dispatch(sender, commandLine)) {
return true;
}
String firstword = commandLine;
if (firstword.indexOf(' ') >= 0) {
firstword = firstword.substring(0, firstword.indexOf(' '));
}
sender.sendMessage(ChatColor.GRAY + "Unknown command \"" + firstword + "\", try \"help\"");
return false;
}
////////////////////////////////////////////////////////////////////////////
// Player management
public Set<OfflinePlayer> getOperators() {
Set<OfflinePlayer> offlinePlayers = new HashSet<OfflinePlayer>();
for (String name : opsList.getContents()) {
offlinePlayers.add(getOfflinePlayer(name));
}
return offlinePlayers;
}
public Player[] getOnlinePlayers() {
ArrayList<Player> result = new ArrayList<>();
for (World world : getWorlds()) {
for (Player player : world.getPlayers())
result.add(player);
}
return result.toArray(new Player[result.size()]);
}
public OfflinePlayer[] getOfflinePlayers() {
throw new UnsupportedOperationException("Not supported yet.");
}
public Player getPlayer(String name) {
name = name.toLowerCase();
Player bestPlayer = null;
int bestDelta = -1;
for (Player player : getOnlinePlayers()) {
if (player.getName().toLowerCase().startsWith(name)) {
int delta = player.getName().length() - name.length();
if (bestPlayer == null || delta < bestDelta) {
bestPlayer = player;
}
}
}
return bestPlayer;
}
public Player getPlayer(UUID uuid) {
for (Player player : getOnlinePlayers()) {
if (player.getUniqueId().equals(uuid))
return player;
}
return null;
}
public Player getPlayerExact(String name) {
for (Player player : getOnlinePlayers()) {
if (player.getName().equalsIgnoreCase(name))
return player;
}
return null;
}
public List<Player> matchPlayer(String name) {
name = name.toLowerCase();
ArrayList<Player> result = new ArrayList<Player>();
for (Player player : getOnlinePlayers()) {
String lower = player.getName().toLowerCase();
if (lower.equals(name)) {
result.clear();
result.add(player);
break;
} else if (lower.contains(name)) {
result.add(player);
}
}
return result;
}
public OfflinePlayer getOfflinePlayer(String name) {
OfflinePlayer player = getPlayerExact(name);
if (player == null) {
player = offlineCache.get(name);
if (player == null) {
player = new GlowOfflinePlayer(this, name, null);
offlineCache.put(name, player);
// Call creation event here?
}
} else {
offlineCache.remove(name);
}
return player;
}
public OfflinePlayer getOfflinePlayer(UUID uuid) {
OfflinePlayer player = getPlayer(uuid);
if (player == null) {
player = offlineCache.get(uuid.toString());
if (player == null) {
player = new GlowOfflinePlayer(this, null, uuid);
offlineCache.put(uuid.toString(), player);
// Call creation event here?
}
} else {
offlineCache.remove(uuid.toString());
}
return player;
}
public void savePlayers() {
for (Player player : getOnlinePlayers())
player.saveData();
}
public int broadcastMessage(String message) {
return broadcast(message, BROADCAST_CHANNEL_USERS);
}
public int broadcast(String message, String permission) {
int count = 0;
for (Permissible permissible : getPluginManager().getPermissionSubscriptions(permission)) {
if (permissible instanceof CommandSender && permissible.hasPermission(permission)) {
((CommandSender) permissible).sendMessage(message);
++count;
}
}
return count;
}
public Set<OfflinePlayer> getWhitelistedPlayers() {
Set<OfflinePlayer> players = new HashSet<OfflinePlayer>();
for (String name : whitelist.getContents()) {
players.add(getOfflinePlayer(name));
}
return players;
}
public void reloadWhitelist() {
whitelist.load();
}
public Set<String> getIPBans() {
Set<String> result = new HashSet<>();
for (BanEntry entry : ipBans.getBanEntries()) {
result.add(entry.getTarget());
}
return result;
}
public void banIP(String address) {
ipBans.addBan(address, null, null, null);
}
public void unbanIP(String address) {
ipBans.pardon(address);
}
public Set<OfflinePlayer> getBannedPlayers() {
Set<OfflinePlayer> bannedPlayers = new HashSet<>();
for (BanEntry entry : nameBans.getBanEntries()) {
bannedPlayers.add(getOfflinePlayer(entry.getTarget()));
}
return bannedPlayers;
}
////////////////////////////////////////////////////////////////////////////
// World management
public GlowWorld getWorld(String name) {
return worlds.getWorld(name);
}
public GlowWorld getWorld(UUID uid) {
for (GlowWorld world : worlds.getWorlds()) {
if (uid.equals(world.getUID()))
return world;
}
return null;
}
@SuppressWarnings("unchecked")
public List<World> getWorlds() {
// Shenanigans needed to cast List<GlowWorld> to List<World>
return (List) worlds.getWorlds();
}
/**
* Gets the default ChunkGenerator for the given environment and type.
* @return The ChunkGenerator.
*/
private ChunkGenerator getGenerator(String name, Environment environment, WorldType type) {
// find generator based on configuration
ConfigurationSection worlds = config.getWorlds();
if (worlds != null) {
String genName = worlds.getString(name + ".generator", null);
ChunkGenerator generator = WorldCreator.getGeneratorForName(name, genName, getConsoleSender());
if (generator != null) {
return generator;
}
}
// find generator based on environment and world type
if (environment == Environment.NETHER) {
return new net.glowstone.generator.UndergroundGenerator();
} else if (environment == Environment.THE_END) {
return new net.glowstone.generator.CakeTownGenerator();
} else {
return new net.glowstone.generator.SurfaceGenerator();
}
}
public GlowWorld createWorld(WorldCreator creator) {
GlowWorld world = getWorld(creator.name());
if (world != null) {
return world;
}
if (creator.generator() == null) {
creator.generator(getGenerator(creator.name(), creator.environment(), creator.type()));
}
world = new GlowWorld(this, creator);
return worlds.addWorld(world);
}
public boolean unloadWorld(String name, boolean save) {
GlowWorld world = getWorld(name);
return world != null && unloadWorld(world, save);
}
public boolean unloadWorld(World bWorld, boolean save) {
if (!(bWorld instanceof GlowWorld)) {
return false;
}
GlowWorld world = (GlowWorld) bWorld;
if (save) {
world.setAutoSave(false);
world.save(false);
}
if (worlds.removeWorld(world)) {
world.unload();
EventFactory.onWorldUnload(world);
return true;
}
return false;
}
public GlowMapView getMap(short id) {
throw new UnsupportedOperationException("Not supported yet.");
}
public GlowMapView createMap(World world) {
throw new UnsupportedOperationException("Not supported yet.");
}
////////////////////////////////////////////////////////////////////////////
// Inventory and crafting
@Override
public List<Recipe> getRecipesFor(ItemStack result) {
return craftingManager.getRecipesFor(result);
}
@Override
public Iterator<Recipe> recipeIterator() {
return craftingManager.iterator();
}
public boolean addRecipe(Recipe recipe) {
return craftingManager.addRecipe(recipe);
}
@Override
public void clearRecipes() {
craftingManager.clearRecipes();
}
@Override
public void resetRecipes() {
craftingManager.resetRecipes();
}
@Override
public Inventory createInventory(InventoryHolder owner, InventoryType type) {
return new GlowInventory(owner, type);
}
@Override
public Inventory createInventory(InventoryHolder owner, int size) {
return new GlowInventory(owner, InventoryType.CHEST, size);
}
@Override
public Inventory createInventory(InventoryHolder owner, int size, String title) {
return new GlowInventory(owner, InventoryType.CHEST, size, title);
}
////////////////////////////////////////////////////////////////////////////
// Server icons
@Override
public GlowServerIcon getServerIcon() {
return defaultIcon;
}
@Override
public CachedServerIcon loadServerIcon(File file) throws Exception {
return new GlowServerIcon(file);
}
@Override
public CachedServerIcon loadServerIcon(BufferedImage image) throws Exception {
return new GlowServerIcon(image);
}
////////////////////////////////////////////////////////////////////////////
// Plugin messages
@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() {
HashSet<String> result = new HashSet<String>();
for (Player player : getOnlinePlayers()) {
result.addAll(player.getListeningPluginChannels());
}
return result;
}
////////////////////////////////////////////////////////////////////////////
// Configuration with special handling
public GameMode getDefaultGameMode() {
return defaultGameMode;
}
public void setDefaultGameMode(GameMode mode) {
defaultGameMode = mode;
}
public int getSpawnRadius() {
return spawnRadius;
}
public void setSpawnRadius(int value) {
spawnRadius = value;
}
public boolean hasWhitelist() {
return whitelistEnabled;
}
public void setWhitelist(boolean enabled) {
whitelistEnabled = enabled;
}
public Warning.WarningState getWarningState() {
return warnState;
}
public void setIdleTimeout(int timeout) {
idleTimeout = timeout;
}
public int getIdleTimeout() {
return idleTimeout;
}
public void configureDbConfig(com.avaje.ebean.config.ServerConfig dbConfig) {
com.avaje.ebean.config.DataSourceConfig ds = new com.avaje.ebean.config.DataSourceConfig();
ds.setDriver(config.getString(ServerConfig.Key.DB_DRIVER));
ds.setUrl(config.getString(ServerConfig.Key.DB_URL));
ds.setUsername(config.getString(ServerConfig.Key.DB_USERNAME));
ds.setPassword(config.getString(ServerConfig.Key.DB_PASSWORD));
ds.setIsolationLevel(com.avaje.ebeaninternal.server.lib.sql.TransactionIsolation.getLevel(config.getString(ServerConfig.Key.DB_ISOLATION)));
if (ds.getDriver().contains("sqlite")) {
dbConfig.setDatabasePlatform(new com.avaje.ebean.config.dbplatform.SQLitePlatform());
dbConfig.getDatabasePlatform().getDbDdlSyntax().setIdentity("");
}
dbConfig.setDataSourceConfig(ds);
}
////////////////////////////////////////////////////////////////////////////
// Configuration
public String getIp() {
return config.getString(ServerConfig.Key.SERVER_IP);
}
public int getPort() {
return config.getInt(ServerConfig.Key.SERVER_PORT);
}
public String getServerName() {
return config.getString(ServerConfig.Key.SERVER_NAME);
}
public String getServerId() {
return Integer.toHexString(getServerName().hashCode());
}
public int getMaxPlayers() {
return config.getInt(ServerConfig.Key.MAX_PLAYERS);
}
public String getUpdateFolder() {
return config.getString(ServerConfig.Key.UPDATE_FOLDER);
}
public File getUpdateFolderFile() {
return new File(getUpdateFolder());
}
public boolean getOnlineMode() {
return config.getBoolean(ServerConfig.Key.ONLINE_MODE);
}
public boolean getAllowNether() {
return config.getBoolean(ServerConfig.Key.ALLOW_NETHER);
}
public boolean getAllowEnd() {
return config.getBoolean(ServerConfig.Key.ALLOW_END);
}
public int getViewDistance() {
return config.getInt(ServerConfig.Key.VIEW_DISTANCE);
}
public String getMotd() {
return config.getString(ServerConfig.Key.MOTD);
}
public File getWorldContainer() {
return new File(config.getString(ServerConfig.Key.WORLD_FOLDER));
}
public String getWorldType() {
return config.getString(ServerConfig.Key.LEVEL_TYPE);
}
public boolean getGenerateStructures() {
return config.getBoolean(ServerConfig.Key.GENERATE_STRUCTURES);
}
public long getConnectionThrottle() {
return config.getInt(ServerConfig.Key.CONNECTION_THROTTLE);
}
public int getTicksPerAnimalSpawns() {
return config.getInt(ServerConfig.Key.ANIMAL_TICKS);
}
public int getTicksPerMonsterSpawns() {
return config.getInt(ServerConfig.Key.MONSTER_TICKS);
}
public boolean isHardcore() {
return config.getBoolean(ServerConfig.Key.HARDCORE);
}
public boolean useExactLoginLocation() {
return config.getBoolean(ServerConfig.Key.EXACT_LOGIN_LOCATION);
}
public int getMonsterSpawnLimit() {
return config.getInt(ServerConfig.Key.MONSTER_LIMIT);
}
public int getAnimalSpawnLimit() {
return config.getInt(ServerConfig.Key.ANIMAL_LIMIT);
}
public int getWaterAnimalSpawnLimit() {
return config.getInt(ServerConfig.Key.WATER_ANIMAL_LIMIT);
}
public int getAmbientSpawnLimit() {
return config.getInt(ServerConfig.Key.AMBIENT_LIMIT);
}
public String getShutdownMessage() {
return config.getString(ServerConfig.Key.SHUTDOWN_MESSAGE);
}
public boolean getAllowFlight() {
return config.getBoolean(ServerConfig.Key.ALLOW_FLIGHT);
}
}