From 9b8da819426b85e78745b415652e87b1b6c53474 Mon Sep 17 00:00:00 2001 From: Torrie Fischer Date: Sun, 22 Apr 2012 18:41:46 -0400 Subject: [PATCH] Initial commit --- .gitignore | 1 + README.md | 1 + pom.xml | 56 +++++++ .../java/us/camin/regions/PlayerWatcher.java | 70 +++++++++ src/main/java/us/camin/regions/Plugin.java | 83 ++++++++++ src/main/java/us/camin/regions/Region.java | 39 +++++ .../java/us/camin/regions/RegionCommand.java | 71 +++++++++ .../java/us/camin/regions/RegionManager.java | 147 ++++++++++++++++++ src/main/resources/plugin.yml | 22 +++ 9 files changed, 490 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 pom.xml create mode 100644 src/main/java/us/camin/regions/PlayerWatcher.java create mode 100644 src/main/java/us/camin/regions/Plugin.java create mode 100644 src/main/java/us/camin/regions/Region.java create mode 100644 src/main/java/us/camin/regions/RegionCommand.java create mode 100644 src/main/java/us/camin/regions/RegionManager.java create mode 100644 src/main/resources/plugin.yml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..eb5a316 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +target diff --git a/README.md b/README.md new file mode 100644 index 0000000..99053d9 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +A plugin to carve up your minecraft world into named regions. diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..1e30d5e --- /dev/null +++ b/pom.xml @@ -0,0 +1,56 @@ + + + 4.0.0 + us.camin.regions + Regions + jar + 0.1 + bukkitplugin + http://maven.apache.org + + UTF-8 + + + + org.bukkit + bukkit + 1.2.2-R0.1-SNAPSHOT + provided + + + commons-codec + commons-codec + 1.4 + + + junit + junit + 4.10 + test + + + + + + src/main/resources + true + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.6 + 1.6 + + + + + + + bukkit-repo + http://repo.bukkit.org/service/local/repositories/snapshots/content/ + + + diff --git a/src/main/java/us/camin/regions/PlayerWatcher.java b/src/main/java/us/camin/regions/PlayerWatcher.java new file mode 100644 index 0000000..d741e5e --- /dev/null +++ b/src/main/java/us/camin/regions/PlayerWatcher.java @@ -0,0 +1,70 @@ +package us.camin.regions; + +/** + * This file is part of Regions + * + * Regions is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Regions is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Regions. If not, see . + * + */ + +import java.lang.Runnable; +import java.util.logging.Logger; +import org.bukkit.entity.Player; +import org.bukkit.Location; +import java.util.Map; +import java.util.HashMap; +import java.util.List; +import java.util.ArrayList; + +public class PlayerWatcher implements Runnable { + Logger log = Logger.getLogger("Regions.PlayerWatcher"); + private Plugin m_plugin; + private Map m_lastKnownRegions; + + public PlayerWatcher(Plugin p) { + m_plugin = p; + m_lastKnownRegions = new HashMap(); + } + + public void run() { + log.finest("poll"); + Player[] allPlayers = m_plugin.getServer().getOnlinePlayers(); + RegionManager manager = m_plugin.regionManager(); + Map> newPlayers = new HashMap>(); + for (Player p : allPlayers) { + Location loc = p.getLocation(); + Region nearest = manager.nearestRegion(loc); + if (nearest != null) { + log.finest("Current region for "+p.getName()+": "+nearest.name()); + if (nearest != m_lastKnownRegions.get(p)) { + p.sendMessage("Now entering region: "+nearest.name()); + log.fine("Player "+p.getName()+" entered region "+nearest.name()); + m_lastKnownRegions.put(p, nearest); + if (!newPlayers.containsKey(nearest)) + newPlayers.put(nearest, new ArrayList()); + newPlayers.get(nearest).add(p); + } + } + } + for (Region r : newPlayers.keySet()) { + for (Player newPlayer : newPlayers.get(r)) { + for (Player oldPlayer : manager.filterPlayersInRegion(r, allPlayers)) { + if (oldPlayer != newPlayer) { + oldPlayer.sendMessage(newPlayer.getName()+" has entered the region"); + } + } + } + } + } +} diff --git a/src/main/java/us/camin/regions/Plugin.java b/src/main/java/us/camin/regions/Plugin.java new file mode 100644 index 0000000..6cb6c12 --- /dev/null +++ b/src/main/java/us/camin/regions/Plugin.java @@ -0,0 +1,83 @@ +package us.camin.regions; + +/** + * This file is part of Regions + * + * Regions is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Regions is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Regions. If not, see . + * + */ + +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.Location; +import org.bukkit.plugin.PluginManager; +import org.bukkit.World; +import org.bukkit.command.CommandExecutor; +import org.bukkit.configuration.ConfigurationSection; + +import java.util.logging.Logger; + +import java.util.Random; + +public class Plugin extends JavaPlugin { + Logger log = Logger.getLogger("Regions"); + RegionManager m_regions; + PlayerWatcher m_playerWatcher; + + public RegionManager regionManager() { + return m_regions; + } + + public void onEnable() { + log.info("[Regions] Enabling Regions"); + m_regions = new RegionManager(); + loadRegions(); + + m_playerWatcher = new PlayerWatcher(this); + + getServer().getScheduler().scheduleAsyncRepeatingTask(this, m_playerWatcher, 0, 5*20); + + CommandExecutor regionCommand = new RegionCommand(this); + getCommand("region").setExecutor(regionCommand); + } + + private void loadTestRegions() { + log.info("[Regions] Loading test regions for development"); + String[] regionNames = {"Redstone", "Lapis", "Dwarf City"}; + Random rand = new Random(); + for(World w : getServer().getWorlds()) { + for(String name : regionNames) { + Location loc = new Location(w, rand.nextInt(30), 64, rand.nextInt(30)); + Region r = new Region(name, loc); + m_regions.addRegion(r); + } + } + } + + public void loadRegions() { + reloadConfig(); + ConfigurationSection section = getConfig().getConfigurationSection("regions"); + if (section != null) + m_regions.loadRegions(section, getServer()); + } + + public void saveRegions() { + m_regions.saveRegions(getConfig().createSection("regions")); + saveConfig(); + } + + public void onDisable() { + saveRegions(); + log.info("[Regions] Plugin disabled"); + } +} diff --git a/src/main/java/us/camin/regions/Region.java b/src/main/java/us/camin/regions/Region.java new file mode 100644 index 0000000..b3dee74 --- /dev/null +++ b/src/main/java/us/camin/regions/Region.java @@ -0,0 +1,39 @@ +package us.camin.regions; + +/** + * This file is part of Regions + * + * Regions is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Regions is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Regions. If not, see . + * + */ + +import org.bukkit.Location; + +public class Region { + private Location m_location; + private String m_name; + + public Region(String name, Location location) { + m_location = location; + m_name = name; + } + + public Location location() { + return m_location; + } + + public String name() { + return m_name; + } +} diff --git a/src/main/java/us/camin/regions/RegionCommand.java b/src/main/java/us/camin/regions/RegionCommand.java new file mode 100644 index 0000000..778cd56 --- /dev/null +++ b/src/main/java/us/camin/regions/RegionCommand.java @@ -0,0 +1,71 @@ +package us.camin.regions; + +/** + * This file is part of Regions + * + * Regions is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Regions is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Regions. If not, see . + * + */ + +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.Command; +import org.bukkit.entity.Player; + +public class RegionCommand implements CommandExecutor { + + Plugin m_plugin; + + public RegionCommand(Plugin p) { + m_plugin = p; + } + + public boolean onCommand(CommandSender sender, Command command, String label, String[] split) { + if (!(sender instanceof Player)) { + sender.sendMessage("Region command is only available to players."); + return true; + } + Player p = (Player)sender; + if (split.length == 0) { + Region r = m_plugin.regionManager().nearestRegion(p.getLocation()); + if (r == null) { + p.sendMessage("There are no regions in this world."); + return true; + } + p.sendMessage("Current region: "+r.name()); + return true; + } + String subCommand = split[0]; + if (subCommand.equals("create") && p.hasPermission("regions.create")) { + StringBuilder regionName = new StringBuilder(); + for(int i = 1;i. + * + */ + +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.Bukkit; +import org.bukkit.Server; +import org.bukkit.entity.Player; + +import java.util.logging.Logger; +import java.util.Map; +import java.util.List; +import java.util.HashMap; +import java.util.Collection; +import java.util.Collections; +import java.util.ArrayList; +import java.util.Set; + +public class RegionManager { + Logger log = Logger.getLogger("Regions.RegionManager"); + private Map> m_regions; + + public RegionManager() { + m_regions = new HashMap>(); + } + + public void clear() { + m_regions = new HashMap>(); + } + + public void renameWorld(String oldName, String newName) { + log.fine("Renaming "+oldName+" to "+newName); + m_regions.put(newName, m_regions.remove(oldName)); + } + + public boolean addRegion(Region r) { + String worldName = r.location().getWorld().getName(); + log.fine("Adding new region "+r.name()+" at "+r.location()); + if (!m_regions.containsKey(worldName)) + m_regions.put(worldName, new ArrayList()); + return m_regions.get(worldName).add(r); + } + + public boolean removeRegion(Region r) { + String worldName = r.location().getWorld().getName(); + log.fine("Removing region "+r.name()+" from "+r.location()); + if (m_regions.containsKey(worldName)) { + return m_regions.get(worldName).remove(r); + } + return false; + } + + public Collection regionsForWorld(World world) { + return regionsForWorld(world.getName()); + } + + public Collection regionsForWorld(String worldName) { + if (m_regions.containsKey(worldName)) + return Collections.unmodifiableCollection(m_regions.get(worldName)); + else + return Collections.unmodifiableCollection(new ArrayList()); + } + + public List filterPlayersInRegion(Region r, Player[] players) { + ArrayList ret = new ArrayList(); + for (Player p : players) { + Region nearest = nearestRegion(p.getLocation()); + if (nearest == r) + ret.add(p); + } + return ret; + } + + public Region nearestRegion(Location loc) { + Collection regions = regionsForWorld(loc.getWorld()); + Region nearest = null; + int minDistance = -1; + for(Region r : regions) { + int check = distance(loc, r.location()); + if (minDistance == -1) { + nearest = r; + minDistance = check; + } else if (check < minDistance) { + nearest = r; + minDistance = check; + } + } + return nearest; + } + + public void saveRegions(ConfigurationSection section) { + for(String worldName : m_regions.keySet()) { + ConfigurationSection worldSection = section.createSection(worldName); + for(Region r : regionsForWorld(worldName)) { + ConfigurationSection regionSection = worldSection.createSection(r.name()); + regionSection.set("x", r.location().getBlockX()); + regionSection.set("z", r.location().getBlockZ()); + } + } + } + + public void loadRegions(ConfigurationSection section, Server server) { + Set worldNames = section.getKeys(false); + for(String worldName : worldNames) { + ConfigurationSection worldSection = section.getConfigurationSection(worldName); + Set regionNames = worldSection.getKeys(false); + World world = server.getWorld(worldName); + if (world == null) { + log.warning("Could not find world: "+worldName); + continue; + } + for(String regionName : regionNames) { + ConfigurationSection regionSection = worldSection.getConfigurationSection(regionName); + int x = regionSection.getInt("x"); + int z = regionSection.getInt("z"); + Location loc = new Location(world, x, 64, z); + Region r = new Region(regionName, loc); + addRegion(r); + } + } + } + + /** + * An alternative to Location.distance() which doesn't use floating point math. + */ + private static int distance(Location l1, Location l2) { + return Math.abs((l1.getBlockX()-l2.getBlockX())+Math.abs(l1.getBlockZ()-l2.getBlockZ())); + } +} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml new file mode 100644 index 0000000..10068b7 --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,22 @@ +name: Regions +main: us.camin.regions.Plugin +author: Trever Fischer +website: http://camin.us/ +version: ${version} +commands: + region: + description: Interface to the region system + usage: / [args...] +permissions: + regions.*: + default: op + description: Allows use of all regions permissions + children: + regions.create: true + regions.remove: true + regions.create: + default: op + description: Create a region + regions.remove: + default: op + description: Remove a region