Fork of Poseidon providing Bukkit #1060 to older Beta versions (b1.0-b1.7.3)
1package org.bukkit.craftbukkit;
2
3import com.avaje.ebean.config.DataSourceConfig;
4import com.avaje.ebean.config.ServerConfig;
5import com.avaje.ebean.config.dbplatform.SQLitePlatform;
6import com.avaje.ebeaninternal.server.lib.sql.TransactionIsolation;
7import com.legacyminecraft.poseidon.Poseidon;
8import com.legacyminecraft.poseidon.PoseidonServer;
9import jline.ConsoleReader;
10import net.minecraft.server.*;
11import org.bukkit.Bukkit;
12import org.bukkit.OfflinePlayer;
13import org.bukkit.Server;
14import org.bukkit.World;
15import org.bukkit.World.Environment;
16import org.bukkit.command.Command;
17import org.bukkit.command.CommandSender;
18import org.bukkit.command.PluginCommand;
19import org.bukkit.command.SimpleCommandMap;
20import org.bukkit.craftbukkit.inventory.CraftFurnaceRecipe;
21import org.bukkit.craftbukkit.inventory.CraftRecipe;
22import org.bukkit.craftbukkit.inventory.CraftShapedRecipe;
23import org.bukkit.craftbukkit.inventory.CraftShapelessRecipe;
24import org.bukkit.craftbukkit.map.CraftMapView;
25import org.bukkit.craftbukkit.scheduler.CraftScheduler;
26import org.bukkit.entity.Player;
27import org.bukkit.event.world.WorldInitEvent;
28import org.bukkit.event.world.WorldLoadEvent;
29import org.bukkit.event.world.WorldSaveEvent;
30import org.bukkit.event.world.WorldUnloadEvent;
31import org.bukkit.generator.ChunkGenerator;
32import org.bukkit.inventory.FurnaceRecipe;
33import org.bukkit.inventory.Recipe;
34import org.bukkit.inventory.ShapedRecipe;
35import org.bukkit.inventory.ShapelessRecipe;
36import org.bukkit.permissions.Permission;
37import org.bukkit.plugin.*;
38import org.bukkit.plugin.java.JavaPluginLoader;
39import org.bukkit.scheduler.BukkitScheduler;
40import org.bukkit.scheduler.BukkitWorker;
41import org.bukkit.util.config.Configuration;
42import org.bukkit.util.config.ConfigurationNode;
43import org.bukkit.util.permissions.DefaultPermissions;
44import org.yaml.snakeyaml.Yaml;
45import org.yaml.snakeyaml.constructor.SafeConstructor;
46import org.yaml.snakeyaml.error.MarkedYAMLException;
47
48import java.io.File;
49import java.io.FileInputStream;
50import java.io.FileNotFoundException;
51import java.io.IOException;
52import java.util.*;
53import java.util.logging.Level;
54import java.util.logging.Logger;
55
56public final class CraftServer implements Server {
57 private final String serverName = "Project Poseidon Craftbukkit";
58 //Poseidon Versions
59 private final String serverEnvironment = "POSEIDON";
60 private final String serverVersion = "1.1.10";
61 private final String releaseType = "DEVELOPMENT";
62 private final String protocolVersion = "1.7.3";
63 private final String GameVersion = "b1.7.3";
64 private final ServicesManager servicesManager = new SimpleServicesManager();
65 private final BukkitScheduler scheduler = new CraftScheduler(this);
66 private final SimpleCommandMap commandMap = new SimpleCommandMap(this);
67 private final PluginManager pluginManager = new SimplePluginManager(this, commandMap);
68 protected final MinecraftServer console;
69 protected final ServerConfigurationManager server;
70 private final Map<String, World> worlds = new LinkedHashMap<String, World>();
71 private final Configuration configuration;
72 private final Yaml yaml = new Yaml(new SafeConstructor());
73 private boolean shuttingdown = false;
74 private final List<String> hiddenCommands = new ArrayList<>(); //Project Poseidon - Create variable
75
76 public CraftServer(MinecraftServer console, ServerConfigurationManager server) {
77 this.console = console;
78 this.server = server;
79 //this.serverVersion = CraftServer.class.getPackage().getImplementationVersion(); //Poseidon Replace
80
81 Bukkit.setServer(this);
82
83 //Project Poseidon Start
84 PoseidonServer poseidonServer = new PoseidonServer(console, this);
85 Poseidon.setServer(poseidonServer);
86 //Project Poseidon End
87
88 configuration = new Configuration((File) console.options.valueOf("bukkit-settings"));
89 loadConfig();
90 loadPlugins();
91 enablePlugins(PluginLoadOrder.STARTUP);
92
93 ChunkCompressionThread.startThread();
94 }
95
96 private void loadConfig() {
97 configuration.load();
98 configuration.getString("database.url", "jdbc:sqlite:{DIR}{NAME}.db");
99 configuration.getString("database.username", "bukkit");
100 configuration.getString("database.password", "walrus");
101 configuration.getString("database.driver", "org.sqlite.JDBC");
102 configuration.getString("database.isolation", "SERIALIZABLE");
103
104 configuration.getString("settings.update-folder", "update");
105 configuration.getInt("settings.spawn-radius", 16);
106
107 configuration.getString("settings.permissions-file", "permissions.yml");
108
109 if (configuration.getNode("aliases") == null) {
110 List<String> icanhasbukkit = new ArrayList<String>();
111 icanhasbukkit.add("version");
112 configuration.setProperty("aliases.icanhasbukkit", icanhasbukkit);
113 }
114 configuration.save();
115 }
116
117 public void loadPlugins() {
118 pluginManager.registerInterface(JavaPluginLoader.class);
119
120 File pluginFolder = (File) console.options.valueOf("plugins");
121
122 if (pluginFolder.exists()) {
123 Plugin[] plugins = pluginManager.loadPlugins(pluginFolder);
124 for (Plugin plugin : plugins) {
125 try {
126 plugin.onLoad();
127 } catch (Throwable ex) {
128 Logger.getLogger(CraftServer.class.getName()).log(Level.SEVERE, ex.getMessage() + " initializing " + plugin.getDescription().getFullName() + " (Is it up to date?)", ex);
129 }
130 }
131 } else {
132 pluginFolder.mkdir();
133 }
134 }
135
136 public void enablePlugins(PluginLoadOrder type) {
137 Plugin[] plugins = pluginManager.getPlugins();
138
139 for (Plugin plugin : plugins) {
140 if ((!plugin.isEnabled()) && (plugin.getDescription().getLoad() == type)) {
141 loadPlugin(plugin);
142 }
143 }
144
145 if (type == PluginLoadOrder.POSTWORLD) {
146 commandMap.registerServerAliases();
147 loadCustomPermissions();
148 DefaultPermissions.registerCorePermissions();
149 }
150 }
151
152 public void disablePlugins() {
153 pluginManager.disablePlugins();
154 }
155
156 private void loadPlugin(Plugin plugin) {
157 try {
158 pluginManager.enablePlugin(plugin);
159
160 List<Permission> perms = plugin.getDescription().getPermissions();
161
162 for (Permission perm : perms) {
163 try {
164 pluginManager.addPermission(perm);
165 } catch (IllegalArgumentException ex) {
166 getLogger().log(Level.WARNING, "Plugin " + plugin.getDescription().getFullName() + " tried to register permission '" + perm.getName() + "' but it's already registered", ex);
167 }
168 }
169 } catch (Throwable ex) {
170 Logger.getLogger(CraftServer.class.getName()).log(Level.SEVERE, ex.getMessage() + " loading " + plugin.getDescription().getFullName() + " (Is it up to date?)", ex);
171 }
172 }
173
174 @Override
175 public String getGameVersion() {
176 return getGameVersion();
177 }
178
179 @Override
180 public String getName() {
181 return serverName;
182 }
183
184 public String getPoseidonVersion() {
185 return serverVersion;
186 }
187
188 public String getPoseidonReleaseType() {
189 return releaseType;
190 }
191
192 public String getServerEnvironment() {
193 return serverEnvironment;
194 }
195
196 public String getVersion() {
197 return serverVersion + " (MC: " + protocolVersion + ")";
198 }
199
200 @SuppressWarnings("unchecked")
201 public Player[] getOnlinePlayers() {
202 List<EntityPlayer> online = server.players;
203 Player[] players = new Player[online.size()];
204
205 for (int i = 0; i < players.length; i++) {
206 players[i] = online.get(i).netServerHandler.getPlayer();
207 }
208
209 return players;
210 }
211
212 public Player getPlayer(final String name) {
213 Player[] players = getOnlinePlayers();
214
215 Player found = null;
216 String lowerName = name.toLowerCase();
217 int delta = Integer.MAX_VALUE;
218 for (Player player : players) {
219 if (player.getName().toLowerCase().startsWith(lowerName)) {
220 int curDelta = player.getName().length() - lowerName.length();
221 if (curDelta < delta) {
222 found = player;
223 delta = curDelta;
224 }
225 if (curDelta == 0) break;
226 }
227 }
228 return found;
229 }
230
231 //Project Poseidon Start
232 @Override
233 public Player getPlayer(final UUID uuid) {
234 for (Player p : Bukkit.getOnlinePlayers()) {
235 if (p.getUniqueId().equals(uuid)) {
236 return p;
237 }
238 }
239 return null;
240 }
241
242 //Project Poseidon End
243
244
245 public Player getPlayerExact(String name) {
246 String lname = name.toLowerCase();
247
248 for (Player player : getOnlinePlayers()) {
249 if (player.getName().equalsIgnoreCase(lname)) {
250 return player;
251 }
252 }
253
254 return null;
255 }
256
257 public int broadcastMessage(String message) {
258 return broadcast(message, BROADCAST_CHANNEL_USERS);
259 }
260
261 public Player getPlayer(final EntityPlayer entity) {
262 return entity.netServerHandler.getPlayer();
263 }
264
265 public List<Player> matchPlayer(String partialName) {
266 List<Player> matchedPlayers = new ArrayList<Player>();
267
268 for (Player iterPlayer : this.getOnlinePlayers()) {
269 String iterPlayerName = iterPlayer.getName();
270
271 if (partialName.equalsIgnoreCase(iterPlayerName)) {
272 // Exact match
273 matchedPlayers.clear();
274 matchedPlayers.add(iterPlayer);
275 break;
276 }
277 if (iterPlayerName.toLowerCase().indexOf(partialName.toLowerCase()) != -1) {
278 // Partial match
279 matchedPlayers.add(iterPlayer);
280 }
281 }
282
283 return matchedPlayers;
284 }
285
286 public int getMaxPlayers() {
287 return server.maxPlayers;
288 }
289
290 // NOTE: These are dependent on the corrisponding call in MinecraftServer
291 // so if that changes this will need to as well
292 public int getPort() {
293 return this.getConfigInt("server-port", 25565);
294 }
295
296 public int getViewDistance() {
297 return this.getConfigInt("view-distance", 10);
298 }
299
300 public String getIp() {
301 return this.getConfigString("server-ip", "");
302 }
303
304 public String getServerName() {
305 return this.getConfigString("server-name", "Unknown Server");
306 }
307
308 public String getServerId() {
309 return this.getConfigString("server-id", "unnamed");
310 }
311
312 public boolean getAllowNether() {
313 return this.getConfigBoolean("allow-nether", true);
314 }
315
316 public boolean hasWhitelist() {
317 return this.getConfigBoolean("white-list", false);
318 }
319
320 // NOTE: Temporary calls through to server.properies until its replaced
321 private String getConfigString(String variable, String defaultValue) {
322 return this.console.propertyManager.getString(variable, defaultValue);
323 }
324
325 private int getConfigInt(String variable, int defaultValue) {
326 return this.console.propertyManager.getInt(variable, defaultValue);
327 }
328
329 private boolean getConfigBoolean(String variable, boolean defaultValue) {
330 return this.console.propertyManager.getBoolean(variable, defaultValue);
331 }
332
333 // End Temporary calls
334
335 public String getUpdateFolder() {
336 return this.configuration.getString("settings.update-folder", "update");
337 }
338
339 public PluginManager getPluginManager() {
340 return pluginManager;
341 }
342
343 public BukkitScheduler getScheduler() {
344 return scheduler;
345 }
346
347 public ServicesManager getServicesManager() {
348 return servicesManager;
349 }
350
351 public List<World> getWorlds() {
352 return new ArrayList<World>(worlds.values());
353 }
354
355 public ServerConfigurationManager getHandle() {
356 return server;
357 }
358
359
360 // NOTE: Should only be called from MinecraftServer.b()
361 public boolean dispatchCommand(CommandSender sender, ServerCommand serverCommand) {
362 return dispatchCommand(sender, serverCommand.command);
363 }
364
365 public boolean dispatchCommand(CommandSender sender, String commandLine) {
366 if (commandMap.dispatch(sender, commandLine)) {
367 return true;
368 }
369
370 sender.sendMessage("Unknown command. Type \"help\" for help.");
371
372 return false;
373 }
374
375 public void reload() {
376 loadConfig();
377 PropertyManager config = new PropertyManager(console.options);
378
379 console.propertyManager = config;
380
381 boolean animals = config.getBoolean("spawn-animals", console.spawnAnimals);
382 boolean monsters = config.getBoolean("spawn-monsters", console.worlds.get(0).spawnMonsters > 0);
383
384 console.onlineMode = config.getBoolean("online-mode", console.onlineMode);
385 console.spawnAnimals = config.getBoolean("spawn-animals", console.spawnAnimals);
386 console.pvpMode = config.getBoolean("pvp", console.pvpMode);
387 console.allowFlight = config.getBoolean("allow-flight", console.allowFlight);
388
389 for (WorldServer world : console.worlds) {
390 world.spawnMonsters = monsters ? 1 : 0;
391 world.setSpawnFlags(monsters, animals);
392 }
393
394 pluginManager.clearPlugins();
395 commandMap.clearCommands();
396
397 int pollCount = 0;
398
399 // Wait for at most 2.5 seconds for plugins to close their threads
400 while (pollCount < 50 && getScheduler().getActiveWorkers().size() > 0) {
401 try {
402 Thread.sleep(50);
403 } catch (InterruptedException e) {
404 }
405 pollCount++;
406 }
407
408 List<BukkitWorker> overdueWorkers = getScheduler().getActiveWorkers();
409 for (BukkitWorker worker : overdueWorkers) {
410 Plugin plugin = worker.getOwner();
411 String author = "<NoAuthorGiven>";
412 if (plugin.getDescription().getAuthors().size() > 0) {
413 author = plugin.getDescription().getAuthors().get(0);
414 }
415 getLogger().log(Level.SEVERE, String.format("Nag author: '%s' of '%s' about the following: %s", author, plugin.getDescription().getName(), "This plugin is not properly shutting down its async tasks when it is being reloaded. This may cause conflicts with the newly loaded version of the plugin"));
416 }
417 loadPlugins();
418 enablePlugins(PluginLoadOrder.STARTUP);
419 enablePlugins(PluginLoadOrder.POSTWORLD);
420 }
421
422 private void loadCustomPermissions() {
423 File file = new File(configuration.getString("settings.permissions-file"));
424 FileInputStream stream;
425
426 try {
427 stream = new FileInputStream(file);
428 } catch (FileNotFoundException ex) {
429 try {
430 file.createNewFile();
431 } finally {
432 return;
433 }
434 }
435
436 Map<String, Map<String, Object>> perms;
437
438 try {
439 perms = (Map<String, Map<String, Object>>) yaml.load(stream);
440 } catch (MarkedYAMLException ex) {
441 getLogger().log(Level.WARNING, "Server permissions file " + file + " is not valid YAML: " + ex.toString());
442 return;
443 } catch (Throwable ex) {
444 getLogger().log(Level.WARNING, "Server permissions file " + file + " is not valid YAML.", ex);
445 return;
446 } finally {
447 try {
448 stream.close();
449 } catch (IOException ex) {
450 }
451 }
452
453 if (perms == null) {
454 getLogger().log(Level.INFO, "Server permissions file " + file + " is empty, ignoring it");
455 return;
456 }
457
458 Set<String> keys = perms.keySet();
459
460 for (String name : keys) {
461 try {
462 pluginManager.addPermission(Permission.loadPermission(name, perms.get(name)));
463 } catch (Throwable ex) {
464 Bukkit.getServer().getLogger().log(Level.SEVERE, "Permission node '" + name + "' in server config is invalid", ex);
465 }
466 }
467 }
468
469 @Override
470 public String toString() {
471 return "CraftServer{" + "serverName=" + serverName + ",serverVersion=" + serverVersion + ",protocolVersion=" + protocolVersion + '}';
472 }
473
474 public World createWorld(String name, World.Environment environment) {
475 return createWorld(name, environment, (new Random()).nextLong());
476 }
477
478 public World createWorld(String name, World.Environment environment, long seed) {
479 return createWorld(name, environment, seed, null);
480 }
481
482 public World createWorld(String name, Environment environment, ChunkGenerator generator) {
483 return createWorld(name, environment, (new Random()).nextLong(), generator);
484 }
485
486 public World createWorld(String name, Environment environment, long seed, ChunkGenerator generator) {
487 File folder = new File(name);
488 World world = getWorld(name);
489
490 if (world != null) {
491 return world;
492 }
493
494 if ((folder.exists()) && (!folder.isDirectory())) {
495 throw new IllegalArgumentException("File exists with the name '" + name + "' and isn't a folder");
496 }
497
498 if (generator == null) {
499 generator = getGenerator(name);
500 }
501
502 Convertable converter = new WorldLoaderServer(folder);
503 if (converter.isConvertable(name)) {
504 getLogger().info("Converting world '" + name + "'");
505 converter.convert(name, new ConvertProgressUpdater(console));
506 }
507
508 int dimension = 10 + console.worlds.size();
509 WorldServer internal = new WorldServer(console, new ServerNBTManager(new File("."), name, true), name, dimension, seed, environment, generator);
510
511 if (!(worlds.containsKey(name.toLowerCase()))) {
512 return null;
513 }
514
515 internal.worldMaps = console.worlds.get(0).worldMaps;
516
517 internal.tracker = new EntityTracker(console, dimension);
518 internal.addIWorldAccess((IWorldAccess) new WorldManager(console, internal));
519 internal.spawnMonsters = 1;
520 internal.setSpawnFlags(true, true);
521 console.worlds.add(internal);
522
523 if (generator != null) {
524 internal.getWorld().getPopulators().addAll(generator.getDefaultPopulators(internal.getWorld()));
525 }
526
527 pluginManager.callEvent(new WorldInitEvent(internal.getWorld()));
528 System.out.print("Preparing start region for level " + (console.worlds.size() - 1) + " (Seed: " + internal.getSeed() + ")");
529
530 if (internal.getWorld().getKeepSpawnInMemory()) {
531 short short1 = 196;
532 long i = System.currentTimeMillis();
533 for (int j = -short1; j <= short1; j += 16) {
534 for (int k = -short1; k <= short1; k += 16) {
535 long l = System.currentTimeMillis();
536
537 if (l < i) {
538 i = l;
539 }
540
541 if (l > i + 1000L) {
542 int i1 = (short1 * 2 + 1) * (short1 * 2 + 1);
543 int j1 = (j + short1) * (short1 * 2 + 1) + k + 1;
544
545 System.out.println("Preparing spawn area for " + name + ", " + (j1 * 100 / i1) + "%");
546 i = l;
547 }
548
549 ChunkCoordinates chunkcoordinates = internal.getSpawn();
550 internal.chunkProviderServer.getChunkAt(chunkcoordinates.x + j >> 4, chunkcoordinates.z + k >> 4);
551
552 while (internal.doLighting()) {
553 ;
554 }
555 }
556 }
557 }
558 pluginManager.callEvent(new WorldLoadEvent(internal.getWorld()));
559 return internal.getWorld();
560 }
561
562 public boolean unloadWorld(String name, boolean save) {
563 return unloadWorld(getWorld(name), save);
564 }
565
566 public boolean unloadWorld(World world, boolean save) {
567 if (world == null) {
568 return false;
569 }
570
571 WorldServer handle = ((CraftWorld) world).getHandle();
572
573 if (!(console.worlds.contains(handle))) {
574 return false;
575 }
576
577 if (!(handle.dimension > 1)) {
578 return false;
579 }
580
581 if (handle.players.size() > 0) {
582 return false;
583 }
584
585 WorldUnloadEvent e = new WorldUnloadEvent(handle.getWorld());
586
587 if (e.isCancelled()) {
588 return false;
589 }
590
591 if (save) {
592 handle.save(true, (IProgressUpdate) null);
593 handle.saveLevel();
594 WorldSaveEvent event = new WorldSaveEvent(handle.getWorld());
595 getPluginManager().callEvent(event);
596 }
597
598 worlds.remove(world.getName().toLowerCase());
599 console.worlds.remove(console.worlds.indexOf(handle));
600
601 return true;
602 }
603
604 public MinecraftServer getServer() {
605 return console;
606 }
607
608 public World getWorld(String name) {
609 return worlds.get(name.toLowerCase());
610 }
611
612 public World getWorld(UUID uid) {
613 for (World world : worlds.values()) {
614 if (world.getUID().equals(uid)) {
615 return world;
616 }
617 }
618 return null;
619 }
620
621 public void addWorld(World world) {
622 // Check if a World already exists with the UID.
623 if (getWorld(world.getUID()) != null) {
624 System.out.println("World " + world.getName() + " is a duplicate of another world and has been prevented from loading. Please delete the uid.dat file from " + world.getName() + "'s world directory if you want to be able to load the duplicate world.");
625 return;
626 }
627 worlds.put(world.getName().toLowerCase(), world);
628 }
629
630 public Logger getLogger() {
631 return MinecraftServer.log;
632 }
633
634 public ConsoleReader getReader() {
635 return console.reader;
636 }
637
638 public PluginCommand getPluginCommand(String name) {
639 Command command = commandMap.getCommand(name);
640
641 if (command instanceof PluginCommand) {
642 return (PluginCommand) command;
643 } else {
644 return null;
645 }
646 }
647
648 public void savePlayers() {
649 server.savePlayers();
650 }
651
652 public void configureDbConfig(ServerConfig config) {
653 DataSourceConfig ds = new DataSourceConfig();
654 ds.setDriver(configuration.getString("database.driver"));
655 ds.setUrl(configuration.getString("database.url"));
656 ds.setUsername(configuration.getString("database.username"));
657 ds.setPassword(configuration.getString("database.password"));
658 ds.setIsolationLevel(TransactionIsolation.getLevel(configuration.getString("database.isolation")));
659
660 if (ds.getDriver().contains("sqlite")) {
661 config.setDatabasePlatform(new SQLitePlatform());
662 config.getDatabasePlatform().getDbDdlSyntax().setIdentity("");
663 }
664
665 config.setDataSourceConfig(ds);
666 }
667
668 public boolean addRecipe(Recipe recipe) {
669 CraftRecipe toAdd;
670 if (recipe instanceof CraftRecipe) {
671 toAdd = (CraftRecipe) recipe;
672 } else {
673 if (recipe instanceof ShapedRecipe) {
674 toAdd = CraftShapedRecipe.fromBukkitRecipe((ShapedRecipe) recipe);
675 } else if (recipe instanceof ShapelessRecipe) {
676 toAdd = CraftShapelessRecipe.fromBukkitRecipe((ShapelessRecipe) recipe);
677 } else if (recipe instanceof FurnaceRecipe) {
678 toAdd = CraftFurnaceRecipe.fromBukkitRecipe((FurnaceRecipe) recipe);
679 } else {
680 return false;
681 }
682 }
683 toAdd.addToCraftingManager();
684 return true;
685 }
686
687 public Map<String, String[]> getCommandAliases() {
688 ConfigurationNode node = configuration.getNode("aliases");
689 Map<String, String[]> result = new LinkedHashMap<String, String[]>();
690
691 if (node != null) {
692 for (String key : node.getKeys()) {
693 List<String> commands = new ArrayList<String>();
694
695 if (node.getProperty(key) instanceof List) {
696 commands = node.getStringList(key, null);
697 } else {
698 commands.add(node.getString(key));
699 }
700
701 result.put(key, commands.toArray(new String[0]));
702 }
703 }
704
705 return result;
706 }
707
708 public int getSpawnRadius() {
709 return configuration.getInt("settings.spawn-radius", 16);
710 }
711
712 public void setSpawnRadius(int value) {
713 configuration.setProperty("settings.spawn-radius", value);
714 configuration.save();
715 }
716
717 public boolean getOnlineMode() {
718 return this.console.onlineMode;
719 }
720
721 public boolean getAllowFlight() {
722 return this.console.allowFlight;
723 }
724
725 public ChunkGenerator getGenerator(String world) {
726 ConfigurationNode node = configuration.getNode("worlds");
727 ChunkGenerator result = null;
728
729 if (node != null) {
730 node = node.getNode(world);
731
732 if (node != null) {
733 String name = node.getString("generator");
734
735 if ((name != null) && (!name.equals(""))) {
736 String[] split = name.split(":", 2);
737 String id = (split.length > 1) ? split[1] : null;
738 Plugin plugin = pluginManager.getPlugin(split[0]);
739
740 if (plugin == null) {
741 getLogger().severe("Could not set generator for default world '" + world + "': Plugin '" + split[0] + "' does not exist");
742 } else if (!plugin.isEnabled()) {
743 getLogger().severe("Could not set generator for default world '" + world + "': Plugin '" + split[0] + "' is not enabled yet (is it load:STARTUP?)");
744 } else {
745 result = plugin.getDefaultWorldGenerator(world, id);
746 }
747 }
748 }
749 }
750
751 return result;
752 }
753
754 public CraftMapView getMap(short id) {
755 WorldMapCollection collection = console.worlds.get(0).worldMaps;
756 WorldMap worldmap = (WorldMap) collection.a(WorldMap.class, "map_" + id);
757 if (worldmap == null) {
758 return null;
759 }
760 return worldmap.mapView;
761 }
762
763 public CraftMapView createMap(World world) {
764 ItemStack stack = new ItemStack(Item.MAP, 1, -1);
765 WorldMap worldmap = Item.MAP.a(stack, ((CraftWorld) world).getHandle());
766 return worldmap.mapView;
767 }
768
769 public void shutdown() {
770 console.a();
771 }
772
773 public int broadcast(String message, String permission) {
774// int count = 0;
775// Set<Permissible> permissibles = getPluginManager().getPermissionSubscriptions(permission);
776//
777// for (Permissible permissible : permissibles) {
778// if (permissible instanceof CommandSender) {
779// CommandSender user = (CommandSender)permissible;
780// user.sendMessage(message);
781// count++;
782// }
783// }
784//
785// return count;
786 Player[] players = getOnlinePlayers();
787
788 for (Player player : players) {
789 player.sendMessage(message);
790 }
791
792 return players.length;
793 }
794
795 public OfflinePlayer getOfflinePlayer(String name) {
796 OfflinePlayer result = getPlayerExact(name);
797
798 if (result == null) {
799 result = new CraftOfflinePlayer(this, name);
800 }
801
802 return result;
803 }
804
805 public Set<String> getIPBans() {
806 return new HashSet(server.banByIP);
807 }
808
809 public void banIP(String address) {
810 server.c(address);
811 }
812
813 public void unbanIP(String address) {
814 server.d(address);
815 }
816
817 public Set<OfflinePlayer> getBannedPlayers() {
818 Set<OfflinePlayer> result = new HashSet<OfflinePlayer>();
819
820 for (Object name : server.banByName) {
821 result.add(getOfflinePlayer((String) name));
822 }
823
824 return result;
825 }
826
827 public void setWhitelist(boolean value) {
828 server.o = value;
829 console.propertyManager.b("white-list", value);
830 console.propertyManager.savePropertiesFile();
831 }
832
833 public Set<OfflinePlayer> getWhitelistedPlayers() {
834 Set<OfflinePlayer> result = new HashSet<OfflinePlayer>();
835
836 for (Object name : server.e()) {
837 result.add(getOfflinePlayer((String) name));
838 }
839
840 return result;
841 }
842
843 public void reloadWhitelist() {
844 server.f();
845 }
846
847 public boolean isShuttingdown() {
848 return shuttingdown;
849 }
850
851 public void setShuttingdown(boolean shuttingdown) {
852 this.shuttingdown = shuttingdown;
853 }
854
855// public GameMode getDefaultGameMode() {
856// return GameMode.SURVIVAL;
857// }
858//
859// public void setDefaultGameMode(GameMode mode) {
860// throw new UnsupportedOperationException("Not supported yet.");
861// }
862}