001    import java.io.BufferedReader;
002    import java.io.IOException;
003    import java.io.InputStreamReader;
004    import java.net.URL;
005    import java.sql.Connection;
006    import java.sql.DriverManager;
007    import java.sql.SQLException;
008    import java.util.Arrays;
009    import java.util.Collection;
010    import java.util.HashSet;
011    import java.util.LinkedHashMap;
012    import java.util.Set;
013    import java.util.logging.Level;
014    import java.util.logging.Logger;
015    
016    import net.minecraft.server.MinecraftServer;
017    
018    /**
019     * etc.java - My catch-all class for a bunch of shit. If there's something you
020     * need it's probably in here.
021     * 
022     * @author James
023     */
024    public class etc {
025    
026        private static final Logger log = Logger.getLogger("Minecraft");
027        private static volatile etc instance;
028        private static MinecraftServer server;
029        private String usersLoc = "users.txt", kitsLoc = "kits.txt", homeLoc = "homes.txt", warpLoc = "warps.txt", itemLoc = "items.txt", groupLoc = "groups.txt";
030        private String whitelistLoc = "whitelist.txt", reservelistLoc = "reservelist.txt";
031        private String whitelistMessage = "Not on whitelist.";
032        
033        private Set<Integer> allowedItems = new HashSet<Integer>();
034        private Set<Integer> disallowedItems = new HashSet<Integer>();
035        private Set<Integer> itemSpawnBlacklist = new HashSet<Integer>();
036        
037        private String[] motd = null;
038        private boolean saveHomes = true;
039        private boolean firstLoad = true;
040        private boolean whitelistEnabled = false;
041        private int playerLimit = 20;
042        private int spawnProtectionSize = 16;
043        private LinkedHashMap<String, String> commands = new LinkedHashMap<String, String>();
044        private String dataSourceType;
045        private DataSource dataSource;
046        private PropertiesFile properties;
047        private PluginLoader loader;
048        private boolean logging = false;
049        private boolean enableHealth = true;
050        private PluginLoader.HookResult autoHeal = PluginLoader.HookResult.DEFAULT_ACTION;
051        private boolean showUnknownCommand = true;
052        private String versionStr;
053        private boolean tainted = true;
054        private int version = 1; // Version is meant to be loaded from the file, this stays as 1.
055        private String driver, username, password, db;
056        private String[] animals = new String[] {};
057        private String[] monsters = new String[] {};
058        private int mobSpawnRate = 2;
059    
060        private etc() {
061            commands.put("/help", "[Page] - Shows a list of commands. 7 per page.");
062            commands.put("/playerlist", "- Shows a list of players");
063            commands.put("/reload", "- Reloads config");
064            commands.put("/banlist", "<IP or bans> - Gives a list of bans");
065            commands.put("/banip", "[Player] <Reason> - Bans the player's IP");
066            commands.put("/unbanip", "[IP] - Unbans the IP");
067            commands.put("/ban", "[Player] <Reason> - Bans the player");
068            commands.put("/unban", "[Player] - Unbans the player");
069            commands.put("/mute", "[Player] - Toggles mute on player.");
070            commands.put("/tp", "[Player] - Teleports to player. Credits to Zet from SA");
071            commands.put("/tphere", "[Player] - Teleports the player to you");
072            commands.put("/kick", "[Player] <Reason> - Kicks player");
073            commands.put("/item", "[ID] [Amount] <Player> - Gives items");
074            commands.put("/kit", "[Kit] - Gives a kit. To get a list of kits type /kit");
075            commands.put("/listwarps", "- Gives a list of available warps");
076            commands.put("/home", "- Teleports you home");
077            commands.put("/sethome", "- Sets your home");
078            commands.put("/setspawn", "- Sets the spawn point to your position.");
079            commands.put("/me", "[Message] - * hey0 says hi!");
080            commands.put("/msg", "[Player] [Message] - Sends a message to player");
081            commands.put("/spawn", "- Teleports you to spawn");
082            commands.put("/warp", "[Warp] - Warps to the specified warp.");
083            commands.put("/setwarp", "[Warp] - Sets the warp to your current position.");
084            commands.put("/removewarp", "[Warp] - Removes the specified warp.");
085            commands.put("/getpos", "- Displays your current position.");
086            commands.put("/compass", "- Gives you a compass reading.");
087            commands.put("/time", "[time|'day|night|check|raw'] (rawtime) - Changes or checks the time");
088            commands.put("/lighter", "- Gives you a lighter for lighting furnaces");
089            commands.put("/motd", "- Displays the MOTD");
090            commands.put("/modify", "[player] [key] [value] - Type /modify for more info");
091            commands.put("/whitelist", "[operation (add or remove)] [player]");
092            commands.put("/reservelist", "[operation (add or remove)] [player]");
093            commands.put("/enableplugin", "[plugin] - Enables plugin");
094            commands.put("/disableplugin", "[plugin] - Disables plugin");
095            commands.put("/listplugins", "- Lists all plugins");
096            commands.put("/reloadplugin", "[plugin] - Reloads plugin");
097            commands.put("/clearinventory", "- Clears your inventory");
098    
099            load();
100        }
101    
102        private void loadIds(Collection<Integer> storage, String rawData) {
103            for (String id : rawData.split(",")) {
104                id = id.trim();
105                if (id.length() > 0) {
106                    try {
107                        storage.add(Integer.parseInt(id));
108                    } catch (NumberFormatException e) {
109                        log.log(Level.SEVERE, "While parsing the config: '" + id + "' is not a number");
110                    }
111                }
112            }
113        }
114    
115        /**
116         * Loads or reloads the mod
117         */
118        public final void load() {
119            if (properties == null) {
120                properties = new PropertiesFile("server.properties");
121            } else {
122                try {
123                    properties.load();
124                } catch (IOException e) {
125                    log.log(Level.SEVERE, "Exception while reading from server.properties", e);
126                }
127            }
128    
129            try {
130                dataSourceType = properties.getString("data-source", "flatfile");
131    
132                loadIds( allowedItems, properties.getString("alloweditems", ""));
133                loadIds( disallowedItems, properties.getString("disalloweditems", ""));
134                loadIds( itemSpawnBlacklist, properties.getString("itemspawnblacklist", ""));
135                motd = properties.getString("motd", "Type /help for a list of commands.").split("@");
136                playerLimit = properties.getInt("max-players", 20);
137                saveHomes = properties.getBoolean("save-homes", true);
138                whitelistEnabled = properties.getBoolean("whitelist", false);
139                whitelistMessage = properties.getString("whitelist-message", "Not on whitelist.");
140                if (dataSourceType.equalsIgnoreCase("flatfile")) {
141                    usersLoc = properties.getString("admintxtlocation", "users.txt");
142                    kitsLoc = properties.getString("kitstxtlocation", "kits.txt");
143                    homeLoc = properties.getString("homelocation", "homes.txt");
144                    warpLoc = properties.getString("warplocation", "warps.txt");
145                    itemLoc = properties.getString("itemstxtlocation", "items.txt");
146                    groupLoc = properties.getString("group-txt-location", "groups.txt");
147                    whitelistLoc = properties.getString("whitelist-txt-location", "whitelist.txt");
148                    reservelistLoc = properties.getString("reservelist-txt-location", "reservelist.txt");
149                } else {
150                    PropertiesFile sql = new PropertiesFile("mysql.properties");
151                    driver = sql.getString("driver", "com.mysql.jdbc.Driver");
152                    username = sql.getString("user", "root");
153                    password = sql.getString("pass", "root");
154                    db = sql.getString("db", "jdbc:mysql://localhost:3306/minecraft");
155                }
156                spawnProtectionSize = properties.getInt("spawn-protection-size", 16);
157                logging = properties.getBoolean("logging", false);
158                enableHealth = properties.getBoolean("enable-health", true);
159    
160                animals = properties.getString("natural-animals", "Sheep,Pig,Chicken,Cow").split(",");
161                monsters = properties.getString("natural-monsters", "Spider,Zombie,Skeleton,Creeper").split(",");
162                mobSpawnRate = properties.getInt("natural-spawn-rate", mobSpawnRate);
163    
164                String autoHealString = properties.getString("auto-heal", "default");
165                if (autoHealString.equalsIgnoreCase("true")) {
166                    autoHeal = PluginLoader.HookResult.ALLOW_ACTION;
167                } else if (autoHealString.equalsIgnoreCase("false")) {
168                    autoHeal = PluginLoader.HookResult.PREVENT_ACTION;
169                }
170    
171                showUnknownCommand = properties.getBoolean("show-unknown-command", true);
172                URL url = this.getClass().getResource("/version.txt");
173                if (url != null) {
174                    InputStreamReader ins = new InputStreamReader(url.openStream());
175                    BufferedReader bufferedReader = new BufferedReader(ins);
176                    String versionParam = bufferedReader.readLine();
177                    if (versionParam.startsWith("git-")) { // recommended version.txt for git builds: git-<gituser>-<shorttag>
178                        // example: git-sk89q-591c662cf4afc8e3e09a
179                        version = -1;
180                        versionStr = versionParam;
181                        tainted = true;
182                    } else {
183                        version = Integer.parseInt(versionParam);
184                        versionStr = Integer.toString(version); // and back to a string.
185                        tainted = false; // looks official. We hope.
186                    }
187                } else {
188                    // I'm a tainted build, probably.
189                    version = -1;
190                    versionStr = "Undefined version";
191                    tainted = true;
192                    // If any mods check the version.. #@!$
193                }
194            } catch (Exception e) {
195                log.log(Level.SEVERE, "Exception while reading from server.properties", e);
196                // Just in case...
197                motd = new String[]{"Type /help for a list of commands."};
198            }
199        }
200    
201        /**
202         * Loads or reloads the data source
203         */
204        public void loadData() {
205            if (dataSourceType.equalsIgnoreCase("flatfile") && dataSource == null) {
206                dataSource = new FlatFileSource();
207            } else if (dataSourceType.equalsIgnoreCase("mysql") && dataSource == null) {
208                dataSource = new MySQLSource();
209            }
210    
211            dataSource.initialize();
212        }
213    
214        /**
215         * Returns the instance
216         * 
217         * @return
218         */
219        public static etc getInstance() {
220            if (instance == null) {
221                instance = new etc();
222            }
223    
224            return instance;
225        }
226    
227        /**
228         * Sets the server to be used.
229         * 
230         * @param s
231         */
232        public static void setServer(MinecraftServer s) {
233            server = s;
234        }
235    
236        /**
237         * Returns the minecraft server
238         * 
239         * @return
240         */
241        public static MinecraftServer getMCServer() {
242            return server;
243        }
244    
245        /**
246         * Returns the data source
247         * 
248         * @return
249         */
250        public static DataSource getDataSource() {
251            return etc.getInstance().getSource();
252        }
253    
254        /**
255         * Returns the minecraft server interface
256         * 
257         * @return
258         */
259        public static Server getServer() {
260            return etc.getLoader().getServer();
261        }
262    
263        /**
264         * Returns the plugin loader
265         * 
266         * @return
267         */
268        public static PluginLoader getLoader() {
269            if (instance.loader == null) {
270                instance.loader = new PluginLoader(server);
271                instance.loader.loadPlugins();
272            }
273    
274            return instance.loader;
275        }
276    
277        /**
278         * Returns the default group
279         * 
280         * @return default group
281         */
282        public Group getDefaultGroup() {
283            Group group = dataSource.getDefaultGroup();
284            if (group == null) {
285                log.log(Level.SEVERE, "No default group! Expect lots of errors!");
286            }
287            return group;
288        }
289    
290        /**
291         * Adds or modifies the home.
292         * 
293         * @param home
294         */
295        public void changeHome(Warp home) {
296            if (dataSource.getHome(home.Name) == null) {
297                dataSource.addHome(home);
298            } else {
299                dataSource.changeHome(home);
300            }
301        }
302    
303        /**
304         * Adds or modifies the warp
305         * 
306         * @param warp
307         */
308        public void setWarp(Warp warp) {
309            if (dataSource.getWarp(warp.Name) == null) {
310                dataSource.addWarp(warp);
311            } else {
312                dataSource.changeWarp(warp);
313            }
314        }
315    
316        /**
317         * Returns true if the item is on the blacklist
318         * 
319         * @param id
320         * @return
321         */
322        public boolean isOnItemBlacklist(int id) {
323            return itemSpawnBlacklist.contains(id);
324        }
325    
326        /**
327         * Returns the data source
328         * 
329         * @return
330         */
331        public DataSource getSource() {
332            return dataSource;
333        }
334    
335        /**
336         * Returns true if we're logging commands and such
337         * 
338         * @return
339         */
340        public boolean isLogging() {
341            return logging;
342        }
343    
344        /**
345         * Returns true if we want health to be enabled.
346         *
347         * @return
348         */
349        public boolean isHealthEnabled() {
350            return enableHealth;
351        }
352        
353    
354        /**
355         * Returns the status of auto-heal.
356         *
357         * @return
358         */
359        public PluginLoader.HookResult autoHeal() {
360            return autoHeal;
361        }
362    
363        /**
364         * Adds command to the /help list
365         * 
366         * @param command
367         * @param description
368         */
369        public void addCommand(String command, String description) {
370            commands.put(command, description);
371        }
372    
373        /**
374         * Removes command from /help list
375         * 
376         * @param command
377         */
378        public void removeCommand(String command) {
379            commands.remove(command);
380        }
381    
382        /**
383         * Toggles the whitelist (doesn't persist)
384         * 
385         * @return
386         */
387        public boolean toggleWhitelist() {
388            whitelistEnabled = !whitelistEnabled;
389            return whitelistEnabled;
390        }
391        
392        /**
393         * Callback object for notifications sent by executed ServerCommands.
394         * so that they appear in server log.
395         */
396        private MessageReceiver serverConsole = new MessageReceiver() {
397            @Override
398            public String getName() {
399                return "<Server>";
400            }
401    
402            @Override
403            public void notify(String message) {
404                // Strip the colors.
405                message = message.replaceAll("\\u00A7[a-f0-9]", "");
406                if (message != null)
407                    log.info(message);
408            }
409            
410        };
411    
412        /**
413         * Parses a console command
414         * 
415         * @param command
416         * @param server
417         * @return
418         */
419        public boolean parseConsoleCommand(String command, MinecraftServer server) {
420            if (getMCServer() == null) {
421                setServer(server);
422            }
423            String[] split = command.split(" ");
424            if ((Boolean) getLoader().callHook(PluginLoader.Hook.SERVERCOMMAND, new Object[]{split})) {
425                return true;
426            }
427            if (split.length == 0) {
428                return false;
429            }
430    
431            boolean dontParseRegular = true;
432            if (split[0].equalsIgnoreCase("save-all")) {
433                dontParseRegular = false;
434                getServer().saveInventories();
435            } else if (split[0].equalsIgnoreCase("help") || split[0].equalsIgnoreCase("mod-help")) {
436                if (split[0].equalsIgnoreCase("help")) {
437                    dontParseRegular = false;
438                }
439                log.info("Server mod help:");
440                log.info("help          Displays this mod's and server's help");
441                log.info("mod-help      Displays this mod's help");
442                log.info("version       Displays the server version");
443                log.info("reload        Reloads the config");
444                log.info("modify        Type modify for more info");
445                log.info("whitelist     Type whitelist for more info");
446                log.info("reservelist   Type reservelist for more info");
447                log.info("listplugins   Lists all plugins");
448                log.info("enableplugin  Enables a plugin");
449                log.info("disableplugin Disables a plugin");
450                log.info("reloadplugin  Reloads a plugin");
451            } else {
452                dontParseRegular = ServerConsoleCommands.parseServerConsoleCommand(serverConsole, split[0], split);
453            }
454            
455            return dontParseRegular;
456        }
457    
458        /**
459         * Returns compass direction according to your rotation
460         * 
461         * @param degrees
462         * @return
463         */
464        public static String getCompassPointForDirection(double degrees) {
465            if (0 <= degrees && degrees < 22.5) {
466                return "N";
467            } else if (22.5 <= degrees && degrees < 67.5) {
468                return "NE";
469            } else if (67.5 <= degrees && degrees < 112.5) {
470                return "E";
471            } else if (112.5 <= degrees && degrees < 157.5) {
472                return "SE";
473            } else if (157.5 <= degrees && degrees < 202.5) {
474                return "S";
475            } else if (202.5 <= degrees && degrees < 247.5) {
476                return "SW";
477            } else if (247.5 <= degrees && degrees < 292.5) {
478                return "W";
479            } else if (292.5 <= degrees && degrees < 337.5) {
480                return "NW";
481            } else if (337.5 <= degrees && degrees < 360.0) {
482                return "N";
483            } else {
484                return "ERR";
485            }
486        }
487    
488        /**
489         * Combines the string array into a string at the specified start with the
490         * separator separating each string.
491         * 
492         * @param startIndex
493         * @param string
494         * @param seperator
495         * @return combined string
496         */
497        public static String combineSplit(int startIndex, String[] string, String seperator) {
498            StringBuilder builder = new StringBuilder();
499            for (int i = startIndex; i < string.length; i++) {
500                builder.append(string[i]);
501                builder.append(seperator);
502            }
503            builder.deleteCharAt(builder.length() - seperator.length()); // remove
504            // the
505            // extra
506            // seperator
507            return builder.toString();
508        }
509    
510        /**
511         * Returns a list of allowed items for /item
512         * 
513         * @return list of allowed items
514         */
515        public Set<Integer> getAllowedItems() {
516            return allowedItems;
517        }
518    
519        /**
520         * Returns the list of commands
521         * 
522         * @return
523         */
524        public LinkedHashMap<String, String> getCommands() {
525            return commands;
526        }
527    
528        /**
529         * Returns a list of disallowed items for /item
530         * 
531         * @return
532         */
533        public Set<Integer> getDisallowedItems() {
534            return disallowedItems;
535        }
536    
537        /**
538         * Returns the location of groups.txt
539         * 
540         * @return
541         */
542        public String getGroupLocation() {
543            return groupLoc;
544        }
545    
546        /**
547         * Returns the location of homes.txt
548         * 
549         * @return
550         */
551        public String getHomeLocation() {
552            return homeLoc;
553        }
554    
555        /**
556         * Returns the location of items.txt
557         * 
558         * @return
559         */
560        public String getItemLocation() {
561            return itemLoc;
562        }
563    
564        /**
565         * Returns list of banned blocks
566         * 
567         * @return
568         */
569        public Set<Integer> getItemSpawnBlacklist() {
570            return itemSpawnBlacklist;
571        }
572    
573        /**
574         * Returns the location of kits.txt
575         * 
576         * @return
577         */
578        public String getKitsLocation() {
579            return kitsLoc;
580        }
581    
582        /**
583         * Returns the MOTD.
584         * 
585         * @return
586         */
587        public String[] getMotd() {
588            return motd;
589        }
590    
591        /**
592         * Returns the player limit
593         * 
594         * @return
595         */
596        public int getPlayerLimit() {
597            return playerLimit;
598        }
599    
600        /**
601         * Returns the location of reservelist.txt
602         * 
603         * @return
604         */
605        public String getReservelistLocation() {
606            return reservelistLoc;
607        }
608    
609        /**
610         * Returns true if the server is saving homes
611         * 
612         * @return true if server can save homes
613         */
614        public boolean canSaveHomes() {
615            return saveHomes;
616        }
617    
618        /**
619         * Returns the spawn protection size
620         * 
621         * @return
622         */
623        public int getSpawnProtectionSize() {
624            return spawnProtectionSize;
625        }
626    
627        /**
628         * Returns the location of users.txt
629         * 
630         * @return
631         */
632        public String getUsersLocation() {
633            return usersLoc;
634        }
635    
636        /**
637         * Returns the location of warps.txt
638         * 
639         * @return
640         */
641        public String getWarpLocation() {
642            return warpLoc;
643        }
644    
645        /**
646         * Returns true if the whitelist is enabled
647         * 
648         * @return
649         */
650        public boolean isWhitelistEnabled() {
651            return whitelistEnabled;
652        }
653    
654        /**
655         * Returns the location of whitelist.txt
656         * 
657         * @return
658         */
659        public String getWhitelistLocation() {
660            return whitelistLoc;
661        }
662    
663        /**
664         * Returns the message the kick will show if a player isn't on the whitelist
665         * 
666         * @return
667         */
668        public String getWhitelistMessage() {
669            return whitelistMessage;
670        }
671    
672        /**
673         * Sets the list of allowed items
674         * 
675         * @param allowedItems
676         */
677        public void setAllowedItems(int[] allowedItems) {
678            this.allowedItems.clear();
679            // this.allowedItems.addAll(Arrays.asList(allowedItems)); <-- if only java was smart >.>
680            for (int item: allowedItems) {
681                this.allowedItems.add(item);
682            }
683        }
684    
685        /**
686         * Sets the list of disallowed items
687         * 
688         * @param disallowedItems
689         */
690        public void setDisallowedItems(int[] disallowedItems) {
691            this.disallowedItems.clear();
692            // this.allowedItems.addAll(Arrays.asList(allowedItems)); <-- if only java was smart >.>
693            for (int item: disallowedItems) {
694                this.disallowedItems.add(item);
695            }
696        }
697    
698        /**
699         * Sets the location of groups.txt
700         * 
701         * @param groupLoc
702         */
703        public void setGroupLocation(String groupLoc) {
704            this.groupLoc = groupLoc;
705        }
706    
707        /**
708         * Sets the location of homes.txt
709         * 
710         * @param homeLoc
711         */
712        public void setHomeLocation(String homeLoc) {
713            this.homeLoc = homeLoc;
714        }
715    
716        /**
717         * Sets the location of items.txt
718         * 
719         * @param itemLoc
720         */
721        public void setItemLocation(String itemLoc) {
722            this.itemLoc = itemLoc;
723        }
724    
725        /**
726         * Sets the item spawn blacklist
727         * 
728         * @param itemSpawnBlacklist
729         */
730        public void setItemSpawnBlacklist(int[] itemSpawnBlacklist) {
731            this.itemSpawnBlacklist.clear();
732            // this.allowedItems.addAll(Arrays.asList(allowedItems)); <-- if only java was smart >.>
733            for (int item: itemSpawnBlacklist) {
734                this.itemSpawnBlacklist.add(item);
735            }
736        }
737    
738        /**
739         * Sets the location of kits.txt
740         * 
741         * @param kitsLoc
742         */
743        public void setKitsLocation(String kitsLoc) {
744            this.kitsLoc = kitsLoc;
745        }
746    
747        /**
748         * If set to true the server will log all commands used.
749         * 
750         * @param logging
751         */
752        public void setLogging(boolean logging) {
753            this.logging = logging;
754        }
755    
756        /**
757         * Set the MOTD
758         * 
759         * @param motd
760         */
761        public void setMotd(String[] motd) {
762            this.motd = motd;
763        }
764    
765        /**
766         * Set the player limit
767         * 
768         * @param playerLimit
769         */
770        public void setPlayerLimit(int playerLimit) {
771            this.playerLimit = playerLimit;
772        }
773    
774        /**
775         * Set the location of reservelist.txt
776         * 
777         * @param reservelistLoc
778         */
779        public void setReservelistLocation(String reservelistLoc) {
780            this.reservelistLoc = reservelistLoc;
781        }
782    
783        /**
784         * If true the server will save homes. If false homes won't be saved and
785         * will be wiped the next server restart.
786         * 
787         * @param saveHomes
788         */
789        public void setSaveHomes(boolean saveHomes) {
790            this.saveHomes = saveHomes;
791        }
792    
793        /**
794         * Set the spawn protection size (def: 16)
795         * 
796         * @param spawnProtectionSize
797         */
798        public void setSpawnProtectionSize(int spawnProtectionSize) {
799            this.spawnProtectionSize = spawnProtectionSize;
800        }
801    
802        /**
803         * Sets the location of users.txt
804         * 
805         * @param usersLoc
806         */
807        public void setUsersLocation(String usersLoc) {
808            this.usersLoc = usersLoc;
809        }
810    
811        /**
812         * Sets the location of warps.txt
813         * 
814         * @param warpLoc
815         */
816        public void setWarpLocation(String warpLoc) {
817            this.warpLoc = warpLoc;
818        }
819    
820        /**
821         * If true the whitelist is enabled
822         * 
823         * @param whitelistEnabled
824         */
825        public void setWhitelistEnabled(boolean whitelistEnabled) {
826            this.whitelistEnabled = whitelistEnabled;
827        }
828    
829        /**
830         * Sets the location of whitelist.txt
831         * 
832         * @param whitelistLoc
833         */
834        public void setWhitelistLocation(String whitelistLoc) {
835            this.whitelistLoc = whitelistLoc;
836        }
837    
838        /**
839         * Sets the whitelist message to show when it kicks someone
840         * 
841         * @param whitelistMessage
842         */
843        public void setWhitelistMessage(String whitelistMessage) {
844            this.whitelistMessage = whitelistMessage;
845        }
846    
847        /**
848         * Returns true if "Unknown command" is shown to a player when they enter an
849         * unknown command (For wrappers and such)
850         * 
851         * @return show unknown command
852         */
853        public boolean showUnknownCommand() {
854            return showUnknownCommand;
855        }
856    
857        /**
858         * Sets whether or not to show "Unknown command" to players.
859         * 
860         * @param showUnknownCommand
861         *            whether or not to show it
862         */
863        public void setShowUnknownCommand(boolean showUnknownCommand) {
864            this.showUnknownCommand = showUnknownCommand;
865        }
866    
867        /**
868         * Return the current build of the mod
869         * 
870         * @return build/version
871         */
872        public int getVersion() {
873            return version;
874        }
875    
876        /**
877         * Return whether this build is "tainted"
878         *
879         * @return tainted
880         */
881        public boolean getTainted() {
882            return tainted;
883        }
884    
885        /**
886         * Return the specified string version of the build
887         *
888         * @return build/version
889         */
890        public String getVersionStr() {
891            return versionStr;
892        }
893    
894        /**
895         * Returns a list of animals that are allowed to spawn naturally
896         *
897         * @return a list of animals
898         */
899        public String[] getAnimals() {
900            return animals;
901        }
902    
903        /**
904         * Sets a list of animals that are allowed to spawn naturally
905         *
906         * @param animals a list of animals
907         */
908        public void setAnimals(String[] animals) {
909            this.animals = animals;
910        }
911    
912        /**
913         * Returns a list of mobs that are allowed to spawn naturally
914         *
915         * @return a list of mobs
916         */
917        public String[] getMonsters() {
918            return monsters;
919        }
920    
921        /**
922         * Sets a list of mobs that are allowed to spawn naturally
923         *
924         * @param monsters a list of mobs
925         */
926        public void setMonsters(String[] monsters) {
927            this.monsters = monsters;
928        }
929    
930        /**
931         * Returns the % from 0 to 100 that a mob or animal will spawn
932         *
933         * @return a percentage from 0 to 100
934         */
935        public int getMobSpawnRate() {
936            return mobSpawnRate;
937        }
938    
939        /**
940         * Sets the % from 0 to 100 that a mob or animal will spawn
941         *
942         * @param rate a percentage from 0 to 100
943         */
944        public void setMobSpawnRate(int rate) {
945            this.mobSpawnRate = rate;
946        }
947    
948        private Connection _getSQLConnection() {
949            try {
950                return DriverManager.getConnection(db + "?autoReconnect=true&user=" + username + "&password=" + password);
951            } catch (SQLException ex) {
952                log.log(Level.SEVERE, "Unable to retreive connection", ex);
953            }
954            return null;
955        }
956    
957        /**
958         * Returns a SQL connection
959         * 
960         * @return sql connection
961         */
962        public static Connection getSQLConnection() {
963            return getInstance()._getSQLConnection();
964        }
965    }