From 6853baebdd4b65db2afd981e57cf06f2406feb21 Mon Sep 17 00:00:00 2001 From: ZeroEpoch1969 <13510767+ZeroEpoch1969@users.noreply.github.com> Date: Sun, 13 May 2018 12:49:13 -0700 Subject: [PATCH] Master Builder world --- .../totalfreedommod/TotalFreedomMod.java | 6 + .../totalfreedom/totalfreedommod/Updater.java | 9 +- .../command/Command_adminworld.java | 3 +- .../command/Command_masterbuilderworld.java | 174 +++++++++++ .../command/Command_mbconfig.java | 207 ++++++++++++ .../command/Command_saconfig.java | 34 ++ .../totalfreedommod/config/ConfigEntry.java | 2 +- .../masterbuilder/MasterBuilder.java | 157 ++++++++++ .../masterbuilder/MasterBuilderList.java | 295 ++++++++++++++++++ .../MasterBuilderWorldRestrictions.java | 130 ++++++++ .../totalfreedommod/rank/RankManager.java | 13 +- .../totalfreedommod/rank/Title.java | 1 + .../totalfreedommod/util/FUtil.java | 5 + .../world/MasterBuilderWorld.java | 110 +++++++ .../totalfreedommod/world/WorldManager.java | 12 + src/main/resources/config.yml | 4 +- src/main/resources/masterbuilders.yml | 3 + 17 files changed, 1148 insertions(+), 17 deletions(-) create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_masterbuilderworld.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_mbconfig.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/masterbuilder/MasterBuilder.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/masterbuilder/MasterBuilderList.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/masterbuilder/MasterBuilderWorldRestrictions.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/world/MasterBuilderWorld.java create mode 100644 src/main/resources/masterbuilders.yml diff --git a/src/main/java/me/totalfreedom/totalfreedommod/TotalFreedomMod.java b/src/main/java/me/totalfreedom/totalfreedommod/TotalFreedomMod.java index 26f6b12c..a6a1fc38 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/TotalFreedomMod.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/TotalFreedomMod.java @@ -14,6 +14,8 @@ import me.totalfreedom.totalfreedommod.discord.Discord; import me.totalfreedom.totalfreedommod.freeze.Freezer; import me.totalfreedom.totalfreedommod.fun.*; import me.totalfreedom.totalfreedommod.httpd.HTTPDaemon; +import me.totalfreedom.totalfreedommod.masterbuilder.MasterBuilderList; +import me.totalfreedom.totalfreedommod.masterbuilder.MasterBuilderWorldRestrictions; import me.totalfreedom.totalfreedommod.player.PlayerList; import me.totalfreedom.totalfreedommod.playerverification.PlayerVerification; import me.totalfreedom.totalfreedommod.punishments.PunishmentList; @@ -98,6 +100,8 @@ public class TotalFreedomMod extends AeroPlugin public Jumppads jp; public Trailer tr; public HTTPDaemon hd; + public MasterBuilderList mbl; + public MasterBuilderWorldRestrictions mbwr; public SignBlocker snp; public PlayerVerification pv; // @@ -169,6 +173,8 @@ public class TotalFreedomMod extends AeroPlugin lp = services.registerService(LoginProcess.class); nu = services.registerService(AntiNuke.class); as = services.registerService(AntiSpam.class); + mbl = services.registerService(MasterBuilderList.class); + mbwr = services.registerService(MasterBuilderWorldRestrictions.class); pl = services.registerService(PlayerList.class); an = services.registerService(Announcer.class); diff --git a/src/main/java/me/totalfreedom/totalfreedommod/Updater.java b/src/main/java/me/totalfreedom/totalfreedommod/Updater.java index 7330f432..00df8b61 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/Updater.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/Updater.java @@ -75,20 +75,13 @@ public class Updater extends FreedomService output.getChannel().transferFrom(input, 0, Long.MAX_VALUE); input.close(); output.close(); - FLog.info("The latest version has been installed! Restarting server..."); + FLog.info("The latest version has been installed! Restart the server for changes to take effect."); } catch (IOException ex) { FLog.severe(ex); } - - for (Player player : server.getOnlinePlayers()) - { - player.kickPlayer("The server is restarting for a TFM update."); - } - - server.shutdown(); } public String getFilePath() { diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_adminworld.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_adminworld.java index dfbda626..0f2b552e 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_adminworld.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_adminworld.java @@ -18,8 +18,7 @@ public class Command_adminworld extends FreedomCommand private enum CommandMode { - - TELEPORT, GUEST, TIME, WEATHER; + TELEPORT, GUEST, TIME, WEATHER } @Override diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_masterbuilderworld.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_masterbuilderworld.java new file mode 100644 index 00000000..eefdd7d6 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_masterbuilderworld.java @@ -0,0 +1,174 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.world.WorldTime; +import me.totalfreedom.totalfreedommod.world.WorldWeather; +import org.bukkit.World; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.OP, source = SourceType.BOTH) +@CommandParameters(description = "Go to the MasterBuilderWorld.", + usage = "/ [time | weather ]", + aliases = "mbw") +public class Command_masterbuilderworld extends FreedomCommand +{ + + private enum CommandMode + { + TELEPORT, TIME, WEATHER + } + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + CommandMode commandMode = null; + + if (args.length == 0) + { + commandMode = CommandMode.TELEPORT; + } + else if (args.length >= 2) + { + if ("time".equalsIgnoreCase(args[0])) + { + commandMode = CommandMode.TIME; + } + else if ("weather".equalsIgnoreCase(args[0])) + { + commandMode = CommandMode.WEATHER; + } + } + + if (commandMode == null) + { + return false; + } + + try + { + switch (commandMode) + { + case TELEPORT: + { + if (!(sender instanceof Player) || playerSender == null) + { + return true; + } + + World masterBuilderWorld = null; + try + { + masterBuilderWorld = plugin.wm.masterBuilderWorld.getWorld(); + } + catch (Exception ex) + { + } + + if (masterBuilderWorld == null || playerSender.getWorld() == masterBuilderWorld) + { + msg("Going to the main world."); + playerSender.teleport(server.getWorlds().get(0).getSpawnLocation()); + } + else + { + msg("Going to the Master Builder world"); + plugin.wm.masterBuilderWorld.sendToWorld(playerSender); + } + + break; + } + case TIME: + { + assertCommandPerms(sender, playerSender); + + if (args.length == 2) + { + WorldTime timeOfDay = WorldTime.getByAlias(args[1]); + if (timeOfDay != null) + { + plugin.wm.masterBuilderWorld.setTimeOfDay(timeOfDay); + msg("MasterBuilder world time set to: " + timeOfDay.name()); + } + else + { + msg("Invalid time of day. Can be: sunrise, noon, sunset, midnight"); + } + } + else + { + return false; + } + + break; + } + case WEATHER: + { + assertCommandPerms(sender, playerSender); + + if (args.length == 2) + { + WorldWeather weatherMode = WorldWeather.getByAlias(args[1]); + if (weatherMode != null) + { + plugin.wm.masterBuilderWorld.setWeatherMode(weatherMode); + msg("MasterBuilder world weather set to: " + weatherMode.name()); + } + else + { + msg("Invalid weather mode. Can be: off, rain, storm"); + } + } + else + { + return false; + } + + break; + } + default: + { + return false; + } + } + } + catch (PermissionDeniedException ex) + { + if (ex.getMessage().isEmpty()) + { + return noPerms(); + } + sender.sendMessage(ex.getMessage()); + return true; + } + + return true; + } + + // TODO: Redo this properly + private void assertCommandPerms(CommandSender sender, Player playerSender) throws PermissionDeniedException + { + if (!(sender instanceof Player) || playerSender == null || !plugin.al.isSeniorAdmin(playerSender)) + { + throw new PermissionDeniedException(); + } + } + + private class PermissionDeniedException extends Exception + { + + private static final long serialVersionUID = 1L; + + private PermissionDeniedException() + { + super(""); + } + + private PermissionDeniedException(String string) + { + super(string); + } + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_mbconfig.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_mbconfig.java new file mode 100644 index 00000000..5ca93938 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_mbconfig.java @@ -0,0 +1,207 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.masterbuilder.MasterBuilder; +import me.totalfreedom.totalfreedommod.player.FPlayer; +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import net.pravian.aero.util.Ips; +import org.apache.commons.lang3.StringUtils; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.Date; + +@CommandPermissions(level = Rank.OP, source = SourceType.BOTH, blockHostConsole = true) +@CommandParameters(description = "Manage master builders.", usage = "/ >") +public class Command_mbconfig extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length < 1) + { + return false; + } + + switch (args[0]) + { + case "list": + { + msg("Master Builders: " + StringUtils.join(plugin.mbl.getMasterBuilderNames(), ", "), ChatColor.GOLD); + + return true; + } + + case "reload": + { + checkRank(Rank.SENIOR_ADMIN); + + FUtil.adminAction(sender.getName(), "Reloading the Master Builder list", true); + plugin.mbl.load(); + msg("Master Builder list reloaded!"); + return true; + } + + case "info": + { + if (args.length < 2) + { + return false; + } + + checkRank(Rank.SUPER_ADMIN); + + MasterBuilder masterBuilder = plugin.mbl.getEntryByName(args[1]); + + if (masterBuilder == null) + { + final Player player = getPlayer(args[1]); + if (player != null) + { + masterBuilder = plugin.mbl.getMasterBuilder(player); + } + } + + if (masterBuilder == null) + { + msg("Master Builder not found: " + args[1]); + } + else + { + msg(masterBuilder.toString()); + } + + return true; + } + + case "add": + { + if (args.length < 2) + { + return false; + } + + checkConsole(); + checkRank(Rank.SENIOR_ADMIN); + if (!FUtil.isExecutive(sender.getName())) + { + noPerms(); + } + + // Player already on the list? + final Player player = getPlayer(args[1]); + if (player != null && plugin.mbl.isMasterBuilder(player)) + { + msg("That player is already on the Master Builder list."); + return true; + } + + // Find the entry + String name = player != null ? player.getName() : args[1]; + MasterBuilder masterBuilder = null; + for (MasterBuilder loopMasterBuilder : plugin.mbl.getAllMasterBuilders().values()) + { + if (loopMasterBuilder.getName().equalsIgnoreCase(name)) + { + masterBuilder = loopMasterBuilder; + break; + } + } + + if (masterBuilder == null) // New entry + { + if (player == null) + { + msg(FreedomCommand.PLAYER_NOT_FOUND); + return true; + } + + FUtil.adminAction(sender.getName(), "Adding " + player.getName() + " to the Master Builder list", true); + plugin.mbl.addMasterBuilder(new MasterBuilder(player)); + if (player != null) + { + plugin.rm.updateDisplay(player); + } + } + else // Existing admin + { + FUtil.adminAction(sender.getName(), "Readding " + masterBuilder.getName() + " to the Master Builder list", true); + + if (player != null) + { + masterBuilder.setName(player.getName()); + masterBuilder.addIp(Ips.getIp(player)); + } + + masterBuilder.setLastLogin(new Date()); + + plugin.mbl.save(); + plugin.mbl.updateTables(); + if (player != null) + { + plugin.rm.updateDisplay(player); + } + } + + if (player != null) + { + final FPlayer fPlayer = plugin.pl.getPlayer(player); + if (fPlayer.getFreezeData().isFrozen()) + { + fPlayer.getFreezeData().setFrozen(false); + msg(player.getPlayer(), "You have been unfrozen."); + } + + if (!player.isOp()) + { + player.setOp(true); + player.sendMessage(YOU_ARE_OP); + } + plugin.pv.removeEntry(player.getName()); // master builders can't have player verification entries + } + return true; + } + + case "remove": + { + if (args.length < 2) + { + return false; + } + + checkConsole(); + checkRank(Rank.SENIOR_ADMIN); + if (!FUtil.isExecutive(sender.getName())) + { + noPerms(); + } + + Player player = getPlayer(args[1]); + MasterBuilder masterBuilder = player != null ? plugin.mbl.getMasterBuilder(player) : plugin.mbl.getEntryByName(args[1]); + + if (masterBuilder == null) + { + msg("Matser Builder not found: " + args[1]); + return true; + } + + FUtil.adminAction(sender.getName(), "Removing " + masterBuilder.getName() + " from the Master Builder list", true); + plugin.mbl.removeMasterBuilder(masterBuilder); + if (player != null) + { + plugin.rm.updateDisplay(player); + } + return true; + } + + default: + { + return false; + } + } + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_saconfig.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_saconfig.java index b4fc9c9d..688eedeb 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_saconfig.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_saconfig.java @@ -1,6 +1,7 @@ package me.totalfreedom.totalfreedommod.command; import me.totalfreedom.totalfreedommod.admin.Admin; +import me.totalfreedom.totalfreedommod.masterbuilder.MasterBuilder; import me.totalfreedom.totalfreedommod.player.FPlayer; import me.totalfreedom.totalfreedommod.rank.Rank; import me.totalfreedom.totalfreedommod.util.FUtil; @@ -173,6 +174,11 @@ public class Command_saconfig extends FreedomCommand if (admin == null) // New admin { + if (plugin.mbl.isMasterBuilderImpostor(player)) + { + msg("This player was labeled as a Master Builder imposter and is not an admin, therefore they can not be added to the admin list.", ChatColor.RED); + return true; + } if (player == null) { msg(FreedomCommand.PLAYER_NOT_FOUND); @@ -196,6 +202,34 @@ public class Command_saconfig extends FreedomCommand admin.addIp(Ips.getIp(player)); } + // Handle master builders + if (!plugin.mbl.isMasterBuilder(player)) + { + MasterBuilder masterBuilder = null; + for (MasterBuilder loopMasterBuilder : plugin.mbl.getAllMasterBuilders().values()) + { + if (loopMasterBuilder.getName().equalsIgnoreCase(name)) + { + masterBuilder = loopMasterBuilder; + break; + } + } + + if (masterBuilder != null) + { + if (player != null) + { + masterBuilder.setName(player.getName()); + masterBuilder.addIp(Ips.getIp(player)); + } + + masterBuilder.setLastLogin(new Date()); + + plugin.mbl.save(); + plugin.mbl.updateTables(); + } + } + admin.setActive(true); admin.setLastLogin(new Date()); diff --git a/src/main/java/me/totalfreedom/totalfreedommod/config/ConfigEntry.java b/src/main/java/me/totalfreedom/totalfreedommod/config/ConfigEntry.java index 4c37e0c8..b7a1b0c7 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/config/ConfigEntry.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/config/ConfigEntry.java @@ -43,7 +43,7 @@ public enum ConfigEntry SERVER_ADDRESS(String.class, "server.address"), SERVER_MOTD(String.class, "server.motd"), SERVER_OWNERS(List.class, "server.owners"), - MASTER_BUILDERS(List.class, "server.master_builders"), + SERVER_EXECUTIVES(List.class, "server.executives"), SERVER_BAN_URL(String.class, "server.ban_url"), SERVER_PERMBAN_URL(String.class, "server.permban_url"), // diff --git a/src/main/java/me/totalfreedom/totalfreedommod/masterbuilder/MasterBuilder.java b/src/main/java/me/totalfreedom/totalfreedommod/masterbuilder/MasterBuilder.java new file mode 100644 index 00000000..3d90f370 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/masterbuilder/MasterBuilder.java @@ -0,0 +1,157 @@ +package me.totalfreedom.totalfreedommod.masterbuilder; + +import com.google.common.collect.Lists; +import java.util.Date; +import java.util.List; +import lombok.Getter; +import lombok.Setter; +import me.totalfreedom.totalfreedommod.util.FUtil; +import net.pravian.aero.base.ConfigLoadable; +import net.pravian.aero.base.ConfigSavable; +import net.pravian.aero.base.Validatable; +import net.pravian.aero.util.Ips; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; + +public class MasterBuilder implements ConfigLoadable, ConfigSavable, Validatable +{ + + @Getter + private String configKey; + @Getter + @Setter + private String name; + @Getter + private final List ips = Lists.newArrayList(); + @Getter + @Setter + private Date lastLogin = new Date(); + @Getter + @Setter + private String discordID = null; + + public static final String CONFIG_FILENAME = "masterbuilders.yml"; + + public MasterBuilder(Player player) + { + this.configKey = player.getName().toLowerCase(); + this.name = player.getName(); + this.ips.add(Ips.getIp(player)); + } + + public MasterBuilder(String configKey) + { + this.configKey = configKey; + } + + @Override + public String toString() + { + final StringBuilder output = new StringBuilder(); + + output.append("MasterBuilder: ").append(name).append("\n") + .append("- IPs: ").append(StringUtils.join(ips, ", ")).append("\n") + .append("- Last Login: ").append(FUtil.dateToString(lastLogin)).append("\n"); + //.append("- Discord ID: ").append(discordID).append("\n"); (Reserved for future usage) + + return output.toString(); + } + + public void loadFrom(Player player) + { + configKey = player.getName().toLowerCase(); + name = player.getName(); + ips.clear(); + ips.add(Ips.getIp(player)); + } + + @Override + public void loadFrom(ConfigurationSection cs) + { + name = cs.getString("username", configKey); + ips.clear(); + ips.addAll(cs.getStringList("ips")); + lastLogin = FUtil.stringToDate(cs.getString("last_login")); + discordID = cs.getString("discord_id", null); + } + + @Override + public void saveTo(ConfigurationSection cs) + { + Validate.isTrue(isValid(), "Could not save master builder entry: " + name + ". Entry not valid!"); + cs.set("username", name); + cs.set("ips", Lists.newArrayList(ips)); + cs.set("last_login", FUtil.dateToString(lastLogin)); + cs.set("discord_id", discordID); + } + + public void addIp(String ip) + { + if (!ips.contains(ip)) + { + ips.add(ip); + } + } + + public void addIps(List ips) + { + for (String ip : ips) + { + addIp(ip); + } + } + + public void removeIp(String ip) + { + if (ips.contains(ip)) + { + ips.remove(ip); + } + } + + public void clearIPs() + { + ips.clear(); + } + + @Override + public boolean isValid() + { + return configKey != null + && name != null + && !ips.isEmpty() + && lastLogin != null; + } + + public String getConfigKey() + { + return this.configKey; + } + + public String getName() + { + return this.name; + } + + public void setName(final String name) + { + this.name = name; + } + + public List getIps() + { + return this.ips; + } + + public Date getLastLogin() + { + return this.lastLogin; + } + + public void setLastLogin(final Date lastLogin) + { + this.lastLogin = lastLogin; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/masterbuilder/MasterBuilderList.java b/src/main/java/me/totalfreedom/totalfreedommod/masterbuilder/MasterBuilderList.java new file mode 100644 index 00000000..3041c894 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/masterbuilder/MasterBuilderList.java @@ -0,0 +1,295 @@ +package me.totalfreedom.totalfreedommod.masterbuilder; + +import com.google.common.base.Function; +import com.google.common.collect.Maps; +import java.util.Date; +import java.util.Map; +import java.util.Set; +import lombok.Getter; +import me.totalfreedom.totalfreedommod.FreedomService; +import me.totalfreedom.totalfreedommod.TotalFreedomMod; +import me.totalfreedom.totalfreedommod.util.FLog; +import me.totalfreedom.totalfreedommod.util.FUtil; +import net.pravian.aero.config.YamlConfig; +import net.pravian.aero.util.Ips; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; +import org.bukkit.plugin.ServicePriority; + +public class MasterBuilderList extends FreedomService +{ + + public static final String CONFIG_FILENAME = "masterbuilders.yml"; + + @Getter + private final Map masterBuilders = Maps.newHashMap(); + private final Map nameTable = Maps.newHashMap(); + private final Map ipTable = Maps.newHashMap(); + // + private final YamlConfig config; + + public MasterBuilderList(TotalFreedomMod plugin) + { + super(plugin); + + this.config = new YamlConfig(plugin, CONFIG_FILENAME, true); + } + + @Override + protected void onStart() + { + load(); + + server.getServicesManager().register(Function.class, new Function() + { + @Override + public Boolean apply(Player player) + { + return isMasterBuilder(player); + } + }, plugin, ServicePriority.Normal); + } + + @Override + protected void onStop() + { + save(); + } + + public void load() + { + config.load(); + + masterBuilders.clear(); + for (String key : config.getKeys(false)) + { + ConfigurationSection section = config.getConfigurationSection(key); + if (section == null) + { + logger.warning("Invalid master builder list format: " + key); + continue; + } + + MasterBuilder masterBuilder = new MasterBuilder(key); + masterBuilder.loadFrom(section); + + if (!masterBuilder.isValid()) + { + FLog.warning("Could not load master builder: " + key + ". Missing details!"); + continue; + } + + masterBuilders.put(key, masterBuilder); + } + + updateTables(); + FLog.info("Loaded " + masterBuilders.size() + " master builders with " + ipTable.size() + " IPs)"); + } + + public void save() + { + // Clear the config + for (String key : config.getKeys(false)) + { + config.set(key, null); + } + + for (MasterBuilder masterBuilder : masterBuilders.values()) + { + masterBuilder.saveTo(config.createSection(masterBuilder.getConfigKey())); + } + + config.save(); + } + + public synchronized boolean isMasterbuilderSync(CommandSender sender) + { + return isMasterBuilder(sender); + } + + public boolean isMasterBuilder(CommandSender sender) + { + if (!(sender instanceof Player)) + { + return true; + } + + MasterBuilder masterBuilder = getMasterBuilder((Player) sender); + + return masterBuilder != null; + } + + public Map getAllMasterBuilders() + { + return this.masterBuilders; + } + + public MasterBuilder getMasterBuilder(CommandSender sender) + { + if (sender instanceof Player) + { + return getMasterBuilder((Player) sender); + } + + return getEntryByName(sender.getName()); + } + + public MasterBuilder getMasterBuilder(Player player) + { + String ip = Ips.getIp(player); + MasterBuilder masterBuilder = getEntryByName(player.getName()); + + // By name + if (masterBuilder != null) + { + // Check if we're in online mode or if we have a matching IP + if (server.getOnlineMode() || masterBuilder.getIps().contains(ip)) + { + if (!masterBuilder.getIps().contains(ip)) + { + // Add the new IP if needed + masterBuilder.addIp(ip); + save(); + updateTables(); + } + return masterBuilder; + } + } + + // By ip + masterBuilder = getEntryByIp(ip); + if (masterBuilder != null) + { + // Set the new username + masterBuilder.setName(player.getName()); + save(); + updateTables(); + } + + return null; + } + + public MasterBuilder getEntryByName(String name) + { + return nameTable.get(name.toLowerCase()); + } + + public MasterBuilder getEntryByIp(String ip) + { + return ipTable.get(ip); + } + + public MasterBuilder getEntryByIpFuzzy(String needleIp) + { + final MasterBuilder directMasterBuilder = getEntryByIp(needleIp); + if (directMasterBuilder != null) + { + return directMasterBuilder; + } + + for (String ip : ipTable.keySet()) + { + if (FUtil.fuzzyIpMatch(needleIp, ip, 3)) + { + return ipTable.get(ip); + } + } + + return null; + } + + public void updateLastLogin(Player player) + { + final MasterBuilder masterBuilder = getMasterBuilder(player); + if (masterBuilder == null) + { + return; + } + + masterBuilder.setLastLogin(new Date()); + masterBuilder.setName(player.getName()); + save(); + } + + public boolean isMasterBuilderImpostor(Player player) + { + return getEntryByName(player.getName()) != null && !isMasterBuilder(player); + } + + public boolean isIdentityMatched(Player player) + { + if (server.getOnlineMode()) + { + return true; + } + + MasterBuilder masterBuilder = getMasterBuilder(player); + return masterBuilder != null && masterBuilder.getName().equalsIgnoreCase(player.getName()); + } + + public boolean addMasterBuilder(MasterBuilder masterBuilder) + { + if (!masterBuilder.isValid()) + { + logger.warning("Could not add master builder: " + masterBuilder.getConfigKey() + " master builder is missing details!"); + return false; + } + + final String key = masterBuilder.getConfigKey(); + + // Store master builder, update views + masterBuilders.put(key, masterBuilder); + updateTables(); + + // Save master builder + masterBuilder.saveTo(config.createSection(key)); + config.save(); + + return true; + } + + public boolean removeMasterBuilder(MasterBuilder masterBuilder) + { + // Remove master builder, update views + if (masterBuilders.remove(masterBuilder.getConfigKey()) == null) + { + return false; + } + updateTables(); + + // 'Unsave' master builder + config.set(masterBuilder.getConfigKey(), null); + config.save(); + + return true; + } + + public void updateTables() + { + nameTable.clear(); + ipTable.clear(); + + for (MasterBuilder masterBuilder : masterBuilders.values()) + { + nameTable.put(masterBuilder.getName().toLowerCase(), masterBuilder); + + for (String ip : masterBuilder.getIps()) + { + ipTable.put(ip, masterBuilder); + } + + } + } + + public Set getMasterBuilderNames() + { + return nameTable.keySet(); + } + + public Set getMasterBuilderIps() + { + return ipTable.keySet(); + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/masterbuilder/MasterBuilderWorldRestrictions.java b/src/main/java/me/totalfreedom/totalfreedommod/masterbuilder/MasterBuilderWorldRestrictions.java new file mode 100644 index 00000000..115158e5 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/masterbuilder/MasterBuilderWorldRestrictions.java @@ -0,0 +1,130 @@ +package me.totalfreedom.totalfreedommod.masterbuilder; + +import me.totalfreedom.totalfreedommod.FreedomService; +import me.totalfreedom.totalfreedommod.TotalFreedomMod; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerArmorStandManipulateEvent; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; + +import java.util.Arrays; +import java.util.List; + +public class MasterBuilderWorldRestrictions extends FreedomService +{ + + private final List BLOCKED_WORLDEDIT_COMMANDS = Arrays.asList( + "green", "fixlava", "fixwater", "br", "brush", "tool", "mat", "range", "cs"); + + public MasterBuilderWorldRestrictions(TotalFreedomMod plugin) + { + super(plugin); + } + + @Override + protected void onStart() + { + } + + @Override + protected void onStop() + { + } + + public boolean doRestrict(Player player) + { + if (!plugin.mbl.isMasterBuilder(player) && !FUtil.isExecutive(player.getName()) && player.getWorld().equals(plugin.wm.masterBuilderWorld.getWorld())) + { + return true; + } + + return false; + } + + @EventHandler(priority = EventPriority.NORMAL) + public void onBlockPlace(BlockPlaceEvent event) + { + final Player player = event.getPlayer(); + + if (doRestrict(player)) + { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onBlockBreak(BlockBreakEvent event) + { + final Player player = event.getPlayer(); + + if (doRestrict(player)) + { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.NORMAL) + public void onPlayerInteract(PlayerInteractEvent event) + { + final Player player = event.getPlayer(); + + if (doRestrict(player)) + { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.NORMAL) + public void onArmorStandManipulate(PlayerArmorStandManipulateEvent event) + { + final Player player = event.getPlayer(); + + if (doRestrict(player)) + { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.NORMAL) + public void onEntityDamageByEntity(EntityDamageByEntityEvent event) + { + if (event.getDamager() instanceof Player) + { + Player player = (Player) event.getDamager(); + + if (doRestrict(player)) + { + event.setCancelled(true); + } + } + } + + @EventHandler(priority = EventPriority.NORMAL) + public void onCommandPreprocess(PlayerCommandPreprocessEvent event) + { + final Player player = event.getPlayer(); + if (doRestrict(player)) + { + // This is a very poor way of blocking WorldEdit commands, all the methods I know of + // obtaining a list of a plugin's commands are returning null for world edit. + String message = event.getMessage(); + if (message.startsWith("//") || BLOCKED_WORLDEDIT_COMMANDS.contains(message.split("\\s+")[0].replace("/", ""))) + { + player.sendMessage(ChatColor.RED + "Only Master Builders are allowed to use this WorldEdit command in the Master Builder world."); + event.setCancelled(true); + } + + if (plugin.al.isAdmin(player) && !plugin.al.isSeniorAdmin(player) && message.startsWith("/co")) + { + player.sendMessage(ChatColor.RED + "Only Senior Admins are allowed to use CoreProtect in the Master Builder world."); + } + } + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/rank/RankManager.java b/src/main/java/me/totalfreedom/totalfreedommod/rank/RankManager.java index 6c466d99..aea9df60 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/rank/RankManager.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/rank/RankManager.java @@ -50,7 +50,7 @@ public class RankManager extends FreedomService } // Master builders show up if they are not admins - if (ConfigEntry.MASTER_BUILDERS.getList().contains(player.getName()) && !plugin.al.isAdmin(player)) + if (plugin.mbl.isMasterBuilder(player) && !plugin.al.isAdmin(player)) { return Title.MASTER_BUILDER; } @@ -61,6 +61,11 @@ public class RankManager extends FreedomService return Title.DEVELOPER; } + if (ConfigEntry.SERVER_EXECUTIVES.getList().contains(player.getName()) && plugin.al.isAdmin(player)) + { + return Title.EXECUTIVE; + } + // If the player's an owner, display that if (ConfigEntry.SERVER_OWNERS.getList().contains(player.getName())) { @@ -104,7 +109,7 @@ public class RankManager extends FreedomService public Rank getRank(Player player) { - if (plugin.al.isAdminImpostor(player) || plugin.pv.isPlayerImpostor(player)) + if (plugin.al.isAdminImpostor(player) || plugin.pv.isPlayerImpostor(player) || plugin.mbl.isMasterBuilderImpostor(player)) { return Rank.IMPOSTOR; } @@ -164,7 +169,7 @@ public class RankManager extends FreedomService } // Handle impostors - Boolean isImposter = plugin.al.isAdminImpostor(player) || plugin.pv.isPlayerImpostor(player); + Boolean isImposter = plugin.al.isAdminImpostor(player) || plugin.pv.isPlayerImpostor(player) || plugin.mbl.isMasterBuilderImpostor(player); if (isImposter) { FUtil.bcastMsg(ChatColor.AQUA + player.getName() + " is " + Rank.IMPOSTOR.getColoredLoginMessage()); @@ -183,7 +188,7 @@ public class RankManager extends FreedomService } // Set display - if (isAdmin || FUtil.DEVELOPERS.contains(player.getName()) || ConfigEntry.MASTER_BUILDERS.getList().contains(player.getName().toLowerCase())) + if (isAdmin || FUtil.DEVELOPERS.contains(player.getName()) || plugin.mbl.isMasterBuilder(player)) { final Displayable display = getDisplay(player); String loginMsg = display.getColoredLoginMessage(); diff --git a/src/main/java/me/totalfreedom/totalfreedommod/rank/Title.java b/src/main/java/me/totalfreedom/totalfreedommod/rank/Title.java index 53255ea5..fa795f66 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/rank/Title.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/rank/Title.java @@ -7,6 +7,7 @@ public enum Title implements Displayable { MASTER_BUILDER("a", "Master Builder", ChatColor.DARK_AQUA, "Master-Builder"), + EXECUTIVE("an", "Executive", ChatColor.DARK_RED, "Executive"), DEVELOPER("a", "Developer", ChatColor.DARK_PURPLE, "Dev"), OWNER("the", "Owner", ChatColor.BLUE, "Owner"); diff --git a/src/main/java/me/totalfreedom/totalfreedommod/util/FUtil.java b/src/main/java/me/totalfreedom/totalfreedommod/util/FUtil.java index 47f27389..85286e43 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/util/FUtil.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/util/FUtil.java @@ -79,6 +79,11 @@ public class FUtil } } + public static boolean isExecutive(String name) + { + return (ConfigEntry.SERVER_OWNERS.getList().contains(name) || ConfigEntry.SERVER_EXECUTIVES.getList().contains(name)); + } + public static void bcastMsg(String message, ChatColor color) { FLog.info(message, true); diff --git a/src/main/java/me/totalfreedom/totalfreedommod/world/MasterBuilderWorld.java b/src/main/java/me/totalfreedom/totalfreedommod/world/MasterBuilderWorld.java new file mode 100644 index 00000000..0bd6dcea --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/world/MasterBuilderWorld.java @@ -0,0 +1,110 @@ +package me.totalfreedom.totalfreedommod.world; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import me.totalfreedom.totalfreedommod.config.ConfigEntry; +import me.totalfreedom.totalfreedommod.util.FLog; +import org.apache.commons.lang3.StringUtils; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.WorldCreator; +import org.bukkit.WorldType; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerMoveEvent; + +public final class MasterBuilderWorld extends CustomWorld +{ + + private static final String GENERATION_PARAMETERS = ConfigEntry.FLATLANDS_GENERATE_PARAMS.getString();; + // + private WorldWeather weather = WorldWeather.OFF; + private WorldTime time = WorldTime.INHERIT; + + public MasterBuilderWorld() + { + super("masterbuilderworld"); + } + + @Override + public void sendToWorld(Player player) + { + super.sendToWorld(player); + } + + @Override + protected World generateWorld() + { + final WorldCreator worldCreator = new WorldCreator(getName()); + worldCreator.generateStructures(false); + worldCreator.type(WorldType.NORMAL); + worldCreator.environment(World.Environment.NORMAL); + worldCreator.generator(new CleanroomChunkGenerator(GENERATION_PARAMETERS)); + + final World world = server.createWorld(worldCreator); + + world.setSpawnFlags(false, false); + world.setSpawnLocation(0, 50, 0); + + final Block welcomeSignBlock = world.getBlockAt(0, 50, 0); + welcomeSignBlock.setType(Material.SIGN_POST); + org.bukkit.block.Sign welcomeSign = (org.bukkit.block.Sign) welcomeSignBlock.getState(); + + org.bukkit.material.Sign signData = (org.bukkit.material.Sign) welcomeSign.getData(); + signData.setFacingDirection(BlockFace.NORTH); + + welcomeSign.setLine(0, ChatColor.GREEN + "MB World"); + welcomeSign.setLine(1, ChatColor.DARK_GRAY + "---"); + welcomeSign.setLine(2, ChatColor.YELLOW + "Spawn Point"); + welcomeSign.setLine(3, ChatColor.DARK_GRAY + "---"); + welcomeSign.update(); + + plugin.gr.commitGameRules(); + return world; + } + + public WorldWeather getWeatherMode() + { + return weather; + } + + public void setWeatherMode(final WorldWeather weatherMode) + { + this.weather = weatherMode; + + try + { + weatherMode.setWorldToWeather(getWorld()); + } + catch (Exception ex) + { + } + } + + public WorldTime getTimeOfDay() + { + return time; + } + + public void setTimeOfDay(final WorldTime timeOfDay) + { + this.time = timeOfDay; + + try + { + timeOfDay.setWorldToTime(getWorld()); + } + catch (Exception ex) + { + } + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/world/WorldManager.java b/src/main/java/me/totalfreedom/totalfreedommod/world/WorldManager.java index d56a448e..e4d0152e 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/world/WorldManager.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/world/WorldManager.java @@ -22,6 +22,7 @@ public class WorldManager extends FreedomService public Flatlands flatlands; public AdminWorld adminworld; + public MasterBuilderWorld masterBuilderWorld; public WorldManager(TotalFreedomMod plugin) { @@ -29,6 +30,7 @@ public class WorldManager extends FreedomService this.flatlands = new Flatlands(); this.adminworld = new AdminWorld(); + this.masterBuilderWorld = new MasterBuilderWorld(); } @Override @@ -36,6 +38,7 @@ public class WorldManager extends FreedomService { flatlands.getWorld(); adminworld.getWorld(); + masterBuilderWorld.getWorld(); // Disable weather if (ConfigEntry.DISABLE_WEATHER.getBoolean()) @@ -55,6 +58,7 @@ public class WorldManager extends FreedomService { flatlands.getWorld().save(); adminworld.getWorld().save(); + masterBuilderWorld.getWorld().save(); } @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) @@ -101,6 +105,10 @@ public class WorldManager extends FreedomService { return; } + else if (event.getWorld().equals(masterBuilderWorld.getWorld()) && masterBuilderWorld.getWeatherMode() != WorldWeather.OFF) + { + return; + } } catch (Exception ex) { @@ -121,6 +129,10 @@ public class WorldManager extends FreedomService { return; } + else if (event.getWorld().equals(masterBuilderWorld.getWorld()) && masterBuilderWorld.getWeatherMode() != WorldWeather.OFF) + { + return; + } } catch (Exception ex) { diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 9d4a94ae..70457fd4 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -21,8 +21,8 @@ server: owners: - TheMinecraft - # All players who show up as Master Builder - master_builders: [] + # All players who show up as executive + executives: [] # URL players should appeal for bans at ban_url: http://totalfreedom.boards.net/ diff --git a/src/main/resources/masterbuilders.yml b/src/main/resources/masterbuilders.yml new file mode 100644 index 00000000..786cb3c3 --- /dev/null +++ b/src/main/resources/masterbuilders.yml @@ -0,0 +1,3 @@ +# +# TotalFreedomMod 5.0 Master Builder List +#