refactor permissions and packaging.

This commit is contained in:
Tobias Ottenweller 2017-01-01 10:52:00 +01:00
parent 892f151e38
commit acd96607d4
41 changed files with 544 additions and 723 deletions

View File

@ -1,30 +0,0 @@
/* Craft Inc. Gates
Copyright (C) 2011-2014 Craft Inc. Gates Team (see AUTHORS.txt)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/
package de.craftinc.gates;
import java.util.Map;
public interface GateChangeListener {
String newGate = "GateChangeListener-newGate"; // value will be null
String removedGate = "GateChangeListener-removedGate"; // value will be null
String changedID = "GateChangeListener-changedID"; // value will be the old ID
String changedLocation = "GateChangeListener-changedLocation"; // value will the old location
String changedExit = "GateChangeListener-changedExit"; // value will be the old exit
void gateChangedHandler(final Gate g, final Map<String, Object> changeSet);
}

View File

@ -21,8 +21,10 @@ import java.util.*;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import de.craftinc.gates.controllers.GatesManager;
import de.craftinc.gates.listeners.*; import de.craftinc.gates.listeners.*;
import de.craftinc.gates.models.Gate;
import de.craftinc.gates.controllers.PermissionController;
import de.craftinc.gates.util.ConfigurationUtil; import de.craftinc.gates.util.ConfigurationUtil;
import net.milkbowl.vault.permission.Permission; import net.milkbowl.vault.permission.Permission;
@ -37,50 +39,44 @@ import org.bukkit.plugin.java.JavaPlugin;
import de.craftinc.gates.commands.*; import de.craftinc.gates.commands.*;
import org.mcstats.Metrics; import org.mcstats.Metrics;
public class Plugin extends JavaPlugin { public class Plugin extends JavaPlugin {
public static final String permissionInfo = "craftincgates.info";
public static final String permissionManage = "craftincgates.manage";
public static final String permissionUse = "craftincgates.use";
private static Plugin instance; private static Plugin instance;
private static Permission permission;
private String baseCommand; private String baseCommand;
protected List<BaseCommand> commands = new ArrayList<>(); protected List<BaseCommand> commands = new ArrayList<>();
private GatesManager gatesManager = new GatesManager(); private GatesManager gatesManager = new GatesManager();
private PlayerMoveListener moveListener = new PlayerMoveListener(); private PermissionController permissionController = new PermissionController();
private PlayerMoveListener moveListener;
private PlayerTeleportListener teleportListener = new PlayerTeleportListener(); private PlayerTeleportListener teleportListener = new PlayerTeleportListener();
private PlayerRespawnListener respawnListener = new PlayerRespawnListener(); private PlayerRespawnListener respawnListener = new PlayerRespawnListener();
private PlayerChangedWorldListener worldChangeListener = new PlayerChangedWorldListener(); private PlayerChangedWorldListener worldChangeListener = new PlayerChangedWorldListener();
private PlayerJoinListener joinListener = new PlayerJoinListener(); private PlayerJoinListener joinListener = new PlayerJoinListener();
private BlockBreakListener blockBreakListener = new BlockBreakListener(); private BlockBreakListener blockBreakListener = new BlockBreakListener();
public Plugin() { public Plugin() {
instance = this; instance = this;
moveListener = new PlayerMoveListener(this);
} }
public static Plugin getPlugin() { public static Plugin getPlugin() {
return instance; return instance;
} }
public GatesManager getGatesManager() { public GatesManager getGatesManager() {
return gatesManager; return gatesManager;
} }
@Override @Override
public void onLoad() { public void onLoad() {
ConfigurationSerialization.registerClass(Gate.class); ConfigurationSerialization.registerClass(Gate.class);
} }
private void setupPermissions() { private void setupPermissions() {
if (getServer().getPluginManager().getPlugin("Vault") == null) { if (getServer().getPluginManager().getPlugin("Vault") == null) {
log("Not using setup permission provider provided by Vault.");
return; return;
} }
@ -88,13 +84,12 @@ public class Plugin extends JavaPlugin {
if (rsp != null) { if (rsp != null) {
log("Using permission provider provided by Vault."); log("Using permission provider provided by Vault.");
permission = rsp.getProvider(); permissionController.setPermission(rsp.getProvider());
} else { } else {
log("Not using setup permission provider provided by Vault."); log("Not using setup permission provider provided by Vault.");
} }
} }
@Override @Override
public void onDisable() { public void onDisable() {
// Save gates // Save gates
@ -103,7 +98,6 @@ public class Plugin extends JavaPlugin {
log("Disabled"); log("Disabled");
} }
@Override @Override
public void onEnable() { public void onEnable() {
// Setup Metrics // Setup Metrics
@ -153,6 +147,9 @@ public class Plugin extends JavaPlugin {
} }
} }
public PermissionController getPermissionController() {
return permissionController;
}
private void registerEventListeners() { private void registerEventListeners() {
PluginManager pm = this.getServer().getPluginManager(); PluginManager pm = this.getServer().getPluginManager();
@ -224,9 +221,4 @@ public class Plugin extends JavaPlugin {
public static void log(Level level, String msg) { public static void log(Level level, String msg) {
Logger.getLogger("Minecraft").log(level, "[" + instance.getDescription().getFullName() + "] " + msg); Logger.getLogger("Minecraft").log(level, "[" + instance.getDescription().getFullName() + "] " + msg);
} }
public static Permission getPermission() {
return permission;
}
} }

View File

@ -19,42 +19,48 @@ package de.craftinc.gates.commands;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import de.craftinc.gates.controllers.PermissionController;
import de.craftinc.gates.util.ConfigurationUtil; import de.craftinc.gates.util.ConfigurationUtil;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import de.craftinc.gates.Gate; import de.craftinc.gates.models.Gate;
import de.craftinc.gates.GatesManager; import de.craftinc.gates.controllers.GatesManager;
import de.craftinc.gates.Plugin; import de.craftinc.gates.Plugin;
import de.craftinc.gates.util.TextUtil; import de.craftinc.gates.util.TextUtil;
public abstract class BaseCommand { public abstract class BaseCommand {
PermissionController permissionController;
protected List<String> aliases = new ArrayList<>(); List<String> aliases = new ArrayList<>();
protected List<String> requiredParameters = new ArrayList<>(); List<String> requiredParameters = new ArrayList<>();
List<String> optionalParameters = new ArrayList<>(); List<String> optionalParameters = new ArrayList<>();
protected String helpDescription = "no description"; String helpDescription = "no description";
List<String> parameters; List<String> parameters;
CommandSender sender; CommandSender sender;
protected Player player; Player player;
protected Gate gate; Gate gate;
protected boolean senderMustBePlayer = true; boolean senderMustBePlayer = true;
boolean hasGateParam = true; boolean hasGateParam = true;
protected String requiredPermission; String requiredPermission;
protected boolean needsPermissionAtCurrentLocation; boolean needsPermissionAtCurrentLocation;
protected boolean shouldPersistToDisk; boolean shouldPersistToDisk;
public List<String> getAliases() { public List<String> getAliases() {
return aliases; return aliases;
} }
public BaseCommand() {
permissionController = Plugin.getPlugin().getPermissionController();
}
public void execute(CommandSender sender, List<String> parameters) { public void execute(CommandSender sender, List<String> parameters) {
this.sender = sender; this.sender = sender;
this.parameters = parameters; this.parameters = parameters;
@ -74,23 +80,72 @@ public abstract class BaseCommand {
} }
} }
private boolean getSaveOnChanges() {
FileConfiguration config = Plugin.getPlugin().getConfig();
return config.getBoolean(ConfigurationUtil.confSaveOnChangesKey);
}
abstract protected void perform(); abstract protected void perform();
protected void sendMessage(String message) { void sendMessage(String message) {
sender.sendMessage(message); sender.sendMessage(message);
} }
protected void sendMessage(List<String> messages) { void sendMessage(List<String> messages) {
for (String message : messages) { for (String message : messages) {
this.sendMessage(message); this.sendMessage(message);
} }
} }
boolean setGateUsingParameter(String param) {
GatesManager gateManager = Plugin.getPlugin().getGatesManager();
if (!gateManager.gateExists(param)) {
return false;
} else {
gate = gateManager.getGateWithId(param);
return true;
}
}
/**
* This will return false if a gate is required for this command but this.gate == null.
*/
boolean hasPermission() {
if (needsPermissionAtCurrentLocation) {
return permissionController.hasPermission(sender, requiredPermission);
} else {
return permissionController.hasPermission(sender, gate, requiredPermission);
}
}
/*
Help and usage description
*/
String getUsageTemplate(boolean withDescription) {
String ret = "";
ret += ChatColor.AQUA;
ret += "/" + Plugin.getPlugin().getBaseCommand() + " " + TextUtil.implode(getAliases(), ",") + " ";
List<String> parts = new ArrayList<>();
for (String requiredParameter : requiredParameters) {
parts.add("[" + requiredParameter + "]");
}
for (String optionalParameter : optionalParameters) {
parts.add("*[" + optionalParameter + "]");
}
ret += ChatColor.DARK_AQUA;
ret += TextUtil.implode(parts, " ");
if (withDescription) {
ret += " ";
ret += ChatColor.YELLOW;
ret += helpDescription;
}
return ret;
}
private boolean validateCall() { private boolean validateCall() {
boolean allParametersThere = parameters.size() >= requiredParameters.size(); boolean allParametersThere = parameters.size() >= requiredParameters.size();
boolean senderIsPlayer = this.sender instanceof Player; boolean senderIsPlayer = this.sender instanceof Player;
@ -110,7 +165,7 @@ public abstract class BaseCommand {
if (!allParametersThere) { if (!allParametersThere) {
sendMessage(ChatColor.RED + "Some parameters are missing! " + sendMessage(ChatColor.RED + "Some parameters are missing! " +
ChatColor.AQUA + "Usage: " + ChatColor.AQUA + "Usage: " +
this.getUsageTemplate() getUsageTemplate(false)
); );
valid = false; valid = false;
} else if ((!senderHasPermission && this.hasGateParam) || } else if ((!senderHasPermission && this.hasGateParam) ||
@ -130,110 +185,8 @@ public abstract class BaseCommand {
return valid; return valid;
} }
boolean setGateUsingParameter(String param) { private boolean getSaveOnChanges() {
GatesManager gateManager = Plugin.getPlugin().getGatesManager(); FileConfiguration config = Plugin.getPlugin().getConfig();
return config.getBoolean(ConfigurationUtil.confSaveOnChangesKey);
if (!gateManager.gateExists(param)) {
return false;
} else {
gate = gateManager.getGateWithId(param);
return true;
}
}
/**
* This will return false if a gate is required for this command but this.gate == null.
*/
boolean hasPermission() {
if (Plugin.getPermission() == null) { // fallback - use the standard bukkit permission system
return this.sender.hasPermission(this.requiredPermission);
}
if (!(this.sender instanceof Player)) {
// sender is no player - there is no information about the senders locations
return Plugin.getPermission().has(this.sender, this.requiredPermission);
}
Player p = (Player) this.sender;
boolean hasPermission = false;
switch (this.requiredPermission) {
case Plugin.permissionInfo:
if (this.hasGateParam) {
hasPermission = this.hasPermissionAtGateLocationAndExit(p);
} else {
hasPermission = hasPermissionAtPlayerLocation(p);
}
break;
case Plugin.permissionUse:
hasPermission = this.hasPermissionAtGateLocationAndExit(p);
break;
case Plugin.permissionManage:
if (this.needsPermissionAtCurrentLocation && this.hasGateParam) {
boolean hasPermissionAtCurrentLocation = hasPermissionAtPlayerLocation(p);
hasPermission = hasPermissionAtCurrentLocation && this.hasPermissionAtGateLocationAndExit(p);
} else if (this.needsPermissionAtCurrentLocation) {
hasPermission = hasPermissionAtPlayerLocation(p);
} else {
hasPermission = this.hasPermissionAtGateLocationAndExit(p);
}
break;
}
return hasPermission;
}
private boolean hasPermissionAtGateLocationAndExit(Player p) {
if (this.gate == null || p == null) {
return false;
}
boolean permAtLocation = this.gate.getLocation() == null || Plugin.getPermission().has(this.gate.getLocation().getWorld(), p.getName(), this.requiredPermission);
boolean permAtExit = this.gate.getExit() == null || Plugin.getPermission().has(this.gate.getExit().getWorld(), p.getName(), this.requiredPermission);
return permAtLocation & permAtExit;
}
private boolean hasPermissionAtPlayerLocation(Player p) {
return Plugin.getPermission().has(p.getWorld(), p.getName(), this.requiredPermission);
}
/*
Help and usage description
*/
String getUsageTemplate(boolean withDescription) {
String ret = "";
ret += ChatColor.AQUA;
ret += "/" + Plugin.getPlugin().getBaseCommand() + " " + TextUtil.implode(this.getAliases(), ",") + " ";
List<String> parts = new ArrayList<>();
for (String requiredParameter : this.requiredParameters) {
parts.add("[" + requiredParameter + "]");
}
for (String optionalParameter : this.optionalParameters) {
parts.add("*[" + optionalParameter + "]");
}
ret += ChatColor.DARK_AQUA;
ret += TextUtil.implode(parts, " ");
if (withDescription) {
ret += " ";
ret += ChatColor.YELLOW;
ret += this.helpDescription;
}
return ret;
}
private String getUsageTemplate() {
return getUsageTemplate(false);
} }
} }

View File

@ -16,6 +16,7 @@
*/ */
package de.craftinc.gates.commands; package de.craftinc.gates.commands;
import de.craftinc.gates.Plugin;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;

View File

@ -16,8 +16,7 @@
*/ */
package de.craftinc.gates.commands; package de.craftinc.gates.commands;
import de.craftinc.gates.controllers.PermissionController;
import de.craftinc.gates.Plugin;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
public class CommandAllowRiding extends BaseCommand { public class CommandAllowRiding extends BaseCommand {
@ -29,7 +28,7 @@ public class CommandAllowRiding extends BaseCommand {
requiredParameters.add("id"); requiredParameters.add("id");
helpDescription = "Allow players to travel while riding."; helpDescription = "Allow players to travel while riding.";
requiredPermission = Plugin.permissionManage; requiredPermission = PermissionController.permissionManage;
needsPermissionAtCurrentLocation = false; needsPermissionAtCurrentLocation = false;
shouldPersistToDisk = true; shouldPersistToDisk = true;

View File

@ -18,12 +18,12 @@ package de.craftinc.gates.commands;
import java.util.logging.Level; import java.util.logging.Level;
import de.craftinc.gates.controllers.PermissionController;
import de.craftinc.gates.util.GateBlockChangeSender; import de.craftinc.gates.util.GateBlockChangeSender;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import de.craftinc.gates.Plugin; import de.craftinc.gates.Plugin;
public class CommandClose extends BaseCommand { public class CommandClose extends BaseCommand {
public CommandClose() { public CommandClose() {
@ -32,7 +32,7 @@ public class CommandClose extends BaseCommand {
requiredParameters.add("id"); requiredParameters.add("id");
helpDescription = "Closes a gate to prevent players from using it."; helpDescription = "Closes a gate to prevent players from using it.";
requiredPermission = Plugin.permissionManage; requiredPermission = PermissionController.permissionManage;
needsPermissionAtCurrentLocation = false; needsPermissionAtCurrentLocation = false;
shouldPersistToDisk = true; shouldPersistToDisk = true;
senderMustBePlayer = false; senderMustBePlayer = false;

View File

@ -17,6 +17,7 @@
package de.craftinc.gates.commands; package de.craftinc.gates.commands;
import de.craftinc.gates.Plugin; import de.craftinc.gates.Plugin;
import de.craftinc.gates.controllers.PermissionController;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
public class CommandDenyRiding extends BaseCommand { public class CommandDenyRiding extends BaseCommand {
@ -27,7 +28,7 @@ public class CommandDenyRiding extends BaseCommand {
requiredParameters.add("id"); requiredParameters.add("id");
helpDescription = "Deny players to travel while riding."; helpDescription = "Deny players to travel while riding.";
requiredPermission = Plugin.permissionManage; requiredPermission = PermissionController.permissionManage;
needsPermissionAtCurrentLocation = false; needsPermissionAtCurrentLocation = false;
shouldPersistToDisk = true; shouldPersistToDisk = true;
senderMustBePlayer = false; senderMustBePlayer = false;

View File

@ -18,6 +18,7 @@ package de.craftinc.gates.commands;
import java.util.logging.Level; import java.util.logging.Level;
import de.craftinc.gates.controllers.PermissionController;
import de.craftinc.gates.util.GateBlockChangeSender; import de.craftinc.gates.util.GateBlockChangeSender;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
@ -34,7 +35,7 @@ public class CommandExit extends BaseCommand {
helpDescription = "Change exit of location."; helpDescription = "Change exit of location.";
requiredPermission = Plugin.permissionManage; requiredPermission = PermissionController.permissionManage;
needsPermissionAtCurrentLocation = true; needsPermissionAtCurrentLocation = true;
shouldPersistToDisk = true; shouldPersistToDisk = true;

View File

@ -17,6 +17,7 @@
package de.craftinc.gates.commands; package de.craftinc.gates.commands;
import de.craftinc.gates.controllers.PermissionController;
import de.craftinc.gates.Plugin; import de.craftinc.gates.Plugin;
import de.craftinc.gates.util.GateBlockChangeSender; import de.craftinc.gates.util.GateBlockChangeSender;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
@ -32,7 +33,7 @@ public class CommandExitOpen extends BaseCommand {
requiredParameters.add("id"); requiredParameters.add("id");
helpDescription = "Change exit of location and open that gate afterwards."; helpDescription = "Change exit of location and open that gate afterwards.";
requiredPermission = Plugin.permissionManage; requiredPermission = PermissionController.permissionManage;
needsPermissionAtCurrentLocation = true; needsPermissionAtCurrentLocation = true;
shouldPersistToDisk = true; shouldPersistToDisk = true;
senderMustBePlayer = true; senderMustBePlayer = true;

View File

@ -17,6 +17,7 @@
package de.craftinc.gates.commands; package de.craftinc.gates.commands;
import de.craftinc.gates.Plugin; import de.craftinc.gates.Plugin;
import de.craftinc.gates.controllers.PermissionController;
import de.craftinc.gates.util.TextUtil; import de.craftinc.gates.util.TextUtil;
import java.util.ArrayList; import java.util.ArrayList;
@ -69,7 +70,7 @@ public class CommandHelp extends BaseCommand {
optionalParameters.add("page"); optionalParameters.add("page");
helpDescription = "prints this help page"; helpDescription = "prints this help page";
requiredPermission = Plugin.permissionInfo; requiredPermission = PermissionController.permissionInfo;
hasGateParam = false; hasGateParam = false;
needsPermissionAtCurrentLocation = false; needsPermissionAtCurrentLocation = false;

View File

@ -18,6 +18,7 @@ package de.craftinc.gates.commands;
import java.util.logging.Level; import java.util.logging.Level;
import de.craftinc.gates.controllers.PermissionController;
import de.craftinc.gates.util.GateBlockChangeSender; import de.craftinc.gates.util.GateBlockChangeSender;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
@ -34,7 +35,7 @@ public class CommandHide extends BaseCommand {
helpDescription = "Makes a gate NOT consist of gate blocks while open."; helpDescription = "Makes a gate NOT consist of gate blocks while open.";
requiredPermission = Plugin.permissionManage; requiredPermission = PermissionController.permissionManage;
needsPermissionAtCurrentLocation = false; needsPermissionAtCurrentLocation = false;
shouldPersistToDisk = true; shouldPersistToDisk = true;

View File

@ -16,6 +16,8 @@
*/ */
package de.craftinc.gates.commands; package de.craftinc.gates.commands;
import de.craftinc.gates.models.Gate;
import de.craftinc.gates.controllers.PermissionController;
import de.craftinc.gates.util.GateBlockChangeSender; import de.craftinc.gates.util.GateBlockChangeSender;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
@ -23,6 +25,8 @@ import de.craftinc.gates.Plugin;
import de.craftinc.gates.util.TextUtil; import de.craftinc.gates.util.TextUtil;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.HashSet;
public class CommandInfo extends BaseCommand { public class CommandInfo extends BaseCommand {
public CommandInfo() { public CommandInfo() {
@ -33,7 +37,7 @@ public class CommandInfo extends BaseCommand {
helpDescription = "Print detailed information about a certain or the closest gate."; helpDescription = "Print detailed information about a certain or the closest gate.";
requiredPermission = Plugin.permissionInfo; requiredPermission = PermissionController.permissionInfo;
needsPermissionAtCurrentLocation = false; needsPermissionAtCurrentLocation = false;
shouldPersistToDisk = false; shouldPersistToDisk = false;
@ -106,7 +110,10 @@ public class CommandInfo extends BaseCommand {
if (this.sender instanceof Player) { if (this.sender instanceof Player) {
GateBlockChangeSender.temporaryHighlightGateFrame((Player) this.sender, this.gate); HashSet<Gate> set = new HashSet<>();
set.add(this.gate);
GateBlockChangeSender.temporaryHighlightGatesFrames((Player)this.sender, set);
} }
} }
} }

View File

@ -21,10 +21,10 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import de.craftinc.gates.controllers.PermissionController;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import de.craftinc.gates.Gate; import de.craftinc.gates.models.Gate;
import de.craftinc.gates.Plugin; import de.craftinc.gates.Plugin;
import de.craftinc.gates.util.TextUtil; import de.craftinc.gates.util.TextUtil;
@ -48,7 +48,7 @@ public class CommandList extends BaseCommand {
helpDescription = "lists all availible gates."; helpDescription = "lists all availible gates.";
requiredPermission = Plugin.permissionInfo; requiredPermission = PermissionController.permissionInfo;
shouldPersistToDisk = false; shouldPersistToDisk = false;
senderMustBePlayer = false; senderMustBePlayer = false;
} }
@ -149,31 +149,14 @@ public class CommandList extends BaseCommand {
*/ */
private Collection<Gate> getAllGates() { private Collection<Gate> getAllGates() {
Collection<Gate> gates = Plugin.getPlugin().getGatesManager().allGates(); Collection<Gate> gates = Plugin.getPlugin().getGatesManager().allGates();
// create a copy since we cannot iterate over a collection while modifying it!
Collection<Gate> gatesCopy = new ArrayList<>(gates);
if (this.sender instanceof Player && Plugin.getPermission() != null) { for (Gate gate : gatesCopy) {
Player p = (Player) this.sender; if (!this.permissionController.hasPermission(this.sender, gate, this.requiredPermission)) {
gates.remove(gate);
// create a copy since we cannot iterate over a collection while modifying it!
Collection<Gate> gatesCopy = new ArrayList<>(gates);
for (Gate gate : gatesCopy) {
if (gate.getLocation() != null) {
boolean permissionAtGateLocation = Plugin.getPermission().has(gate.getLocation().getWorld(), p.getName(), this.requiredPermission);
if (!permissionAtGateLocation) {
gates.remove(gate);
continue;
}
}
if (gate.getExit() != null) {
boolean permissionAtGateExit = Plugin.getPermission().has(gate.getExit().getWorld(), p.getName(), this.requiredPermission);
if (!permissionAtGateExit) {
gates.remove(gate);
}
}
} }
} }
return gates; return gates;
} }

View File

@ -18,6 +18,7 @@ package de.craftinc.gates.commands;
import java.util.Set; import java.util.Set;
import de.craftinc.gates.controllers.PermissionController;
import de.craftinc.gates.util.GateBlockChangeSender; import de.craftinc.gates.util.GateBlockChangeSender;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Location; import org.bukkit.Location;
@ -33,7 +34,7 @@ public class CommandLocation extends BaseLocationCommand {
requiredParameters.add("id"); requiredParameters.add("id");
helpDescription = "Set the entrance of the gate to your current location."; helpDescription = "Set the entrance of the gate to your current location.";
requiredPermission = Plugin.permissionManage; requiredPermission = PermissionController.permissionManage;
needsPermissionAtCurrentLocation = true; needsPermissionAtCurrentLocation = true;
shouldPersistToDisk = true; shouldPersistToDisk = true;

View File

@ -1,7 +1,8 @@
package de.craftinc.gates.commands; package de.craftinc.gates.commands;
import de.craftinc.gates.Gate; import de.craftinc.gates.models.Gate;
import de.craftinc.gates.GatesManager; import de.craftinc.gates.controllers.GatesManager;
import de.craftinc.gates.controllers.PermissionController;
import de.craftinc.gates.Plugin; import de.craftinc.gates.Plugin;
import de.craftinc.gates.util.GateBlockChangeSender; import de.craftinc.gates.util.GateBlockChangeSender;
import de.craftinc.gates.util.TextUtil; import de.craftinc.gates.util.TextUtil;
@ -16,7 +17,7 @@ public class CommandNearby extends BaseLocationCommand {
aliases.add("nb"); aliases.add("nb");
helpDescription = "Highlight nearby gates"; helpDescription = "Highlight nearby gates";
requiredPermission = Plugin.permissionInfo; requiredPermission = PermissionController.permissionInfo;
needsPermissionAtCurrentLocation = true; needsPermissionAtCurrentLocation = true;
shouldPersistToDisk = false; shouldPersistToDisk = false;
senderMustBePlayer = true; senderMustBePlayer = true;

View File

@ -16,11 +16,12 @@
*/ */
package de.craftinc.gates.commands; package de.craftinc.gates.commands;
import de.craftinc.gates.controllers.PermissionController;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Location; import org.bukkit.Location;
import de.craftinc.gates.Gate; import de.craftinc.gates.models.Gate;
import de.craftinc.gates.GatesManager; import de.craftinc.gates.controllers.GatesManager;
import de.craftinc.gates.Plugin; import de.craftinc.gates.Plugin;
public class CommandNew extends BaseLocationCommand { public class CommandNew extends BaseLocationCommand {
@ -34,7 +35,7 @@ public class CommandNew extends BaseLocationCommand {
senderMustBePlayer = true; senderMustBePlayer = true;
hasGateParam = false; hasGateParam = false;
helpDescription = "Create a gate at your current location."; helpDescription = "Create a gate at your current location.";
requiredPermission = Plugin.permissionManage; requiredPermission = PermissionController.permissionManage;
needsPermissionAtCurrentLocation = true; needsPermissionAtCurrentLocation = true;
shouldPersistToDisk = true; shouldPersistToDisk = true;
senderMustBePlayer = true; senderMustBePlayer = true;

View File

@ -16,6 +16,7 @@
*/ */
package de.craftinc.gates.commands; package de.craftinc.gates.commands;
import de.craftinc.gates.controllers.PermissionController;
import de.craftinc.gates.util.GateBlockChangeSender; import de.craftinc.gates.util.GateBlockChangeSender;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
@ -29,7 +30,7 @@ public class CommandOpen extends BaseCommand {
requiredParameters.add("id"); requiredParameters.add("id");
helpDescription = "Open a gate so players can use it."; helpDescription = "Open a gate so players can use it.";
requiredPermission = Plugin.permissionManage; requiredPermission = PermissionController.permissionManage;
needsPermissionAtCurrentLocation = false; needsPermissionAtCurrentLocation = false;
shouldPersistToDisk = true; shouldPersistToDisk = true;

View File

@ -16,6 +16,7 @@
*/ */
package de.craftinc.gates.commands; package de.craftinc.gates.commands;
import de.craftinc.gates.controllers.PermissionController;
import de.craftinc.gates.util.GateBlockChangeSender; import de.craftinc.gates.util.GateBlockChangeSender;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
@ -33,7 +34,7 @@ public class CommandRemove extends BaseCommand {
senderMustBePlayer = false; senderMustBePlayer = false;
helpDescription = "Removes the gate from the game."; helpDescription = "Removes the gate from the game.";
requiredPermission = Plugin.permissionManage; requiredPermission = PermissionController.permissionManage;
needsPermissionAtCurrentLocation = false; needsPermissionAtCurrentLocation = false;
shouldPersistToDisk = true; shouldPersistToDisk = true;

View File

@ -16,9 +16,10 @@
*/ */
package de.craftinc.gates.commands; package de.craftinc.gates.commands;
import de.craftinc.gates.controllers.PermissionController;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import de.craftinc.gates.GatesManager; import de.craftinc.gates.controllers.GatesManager;
import de.craftinc.gates.Plugin; import de.craftinc.gates.Plugin;
public class CommandRename extends BaseCommand { public class CommandRename extends BaseCommand {
@ -35,7 +36,7 @@ public class CommandRename extends BaseCommand {
helpDescription = "Changes the id of a gate."; helpDescription = "Changes the id of a gate.";
requiredPermission = Plugin.permissionManage; requiredPermission = PermissionController.permissionManage;
needsPermissionAtCurrentLocation = false; needsPermissionAtCurrentLocation = false;
shouldPersistToDisk = true; shouldPersistToDisk = true;

View File

@ -16,11 +16,10 @@
*/ */
package de.craftinc.gates.commands; package de.craftinc.gates.commands;
import de.craftinc.gates.controllers.PermissionController;
import de.craftinc.gates.util.GateBlockChangeSender; import de.craftinc.gates.util.GateBlockChangeSender;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import de.craftinc.gates.Plugin;
public class CommandUnhide extends BaseCommand { public class CommandUnhide extends BaseCommand {
public CommandUnhide() { public CommandUnhide() {
@ -29,7 +28,7 @@ public class CommandUnhide extends BaseCommand {
requiredParameters.add("id"); requiredParameters.add("id");
helpDescription = "Make that gate visible"; helpDescription = "Make that gate visible";
requiredPermission = Plugin.permissionManage; requiredPermission = PermissionController.permissionManage;
needsPermissionAtCurrentLocation = false; needsPermissionAtCurrentLocation = false;
shouldPersistToDisk = true; shouldPersistToDisk = true;
senderMustBePlayer = false; senderMustBePlayer = false;

View File

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>. along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/ */
package de.craftinc.gates; package de.craftinc.gates.controllers;
import java.io.File; import java.io.File;
import java.io.FileWriter; import java.io.FileWriter;
@ -23,6 +23,8 @@ import java.io.IOException;
import java.util.*; import java.util.*;
import java.util.logging.Level; import java.util.logging.Level;
import de.craftinc.gates.Plugin;
import de.craftinc.gates.models.Gate;
import de.craftinc.gates.persistence.MigrationUtil; import de.craftinc.gates.persistence.MigrationUtil;
import de.craftinc.gates.util.ConfigurationUtil; import de.craftinc.gates.util.ConfigurationUtil;
import org.bukkit.Chunk; import org.bukkit.Chunk;
@ -31,9 +33,8 @@ import org.bukkit.block.Block;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
import de.craftinc.gates.util.SimpleChunk; import de.craftinc.gates.models.SimpleChunk;
import de.craftinc.gates.util.SimpleLocation; import de.craftinc.gates.models.SimpleLocation;
public class GatesManager { public class GatesManager {
protected List<Gate> gates; protected List<Gate> gates;
@ -88,19 +89,16 @@ public class GatesManager {
return nearestGate; return nearestGate;
} }
Gate getGateAtLocation(final Location location) {
public Gate getGateAtLocation(final Location location) {
SimpleLocation simpleLocation = new SimpleLocation(location); SimpleLocation simpleLocation = new SimpleLocation(location);
return gatesByLocation.get(simpleLocation); return gatesByLocation.get(simpleLocation);
} }
public Gate getGateAtFrameLocation(final Location location) { public Gate getGateAtFrameLocation(final Location location) {
SimpleLocation simpleLocation = new SimpleLocation(location); SimpleLocation simpleLocation = new SimpleLocation(location);
return gatesByFrameLocation.get(simpleLocation); return gatesByFrameLocation.get(simpleLocation);
} }
public void saveGatesToDisk() { public void saveGatesToDisk() {
if (storageFileIsInvalid) { if (storageFileIsInvalid) {
Plugin.log(Level.SEVERE, "ERROR: Not saving gates to disk. Storage file is invalid or corrupted!"); Plugin.log(Level.SEVERE, "ERROR: Not saving gates to disk. Storage file is invalid or corrupted!");
@ -121,7 +119,9 @@ public class GatesManager {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
boolean loadGatesFromDisk() { public boolean loadGatesFromDisk() {
// TODO: refactor: move loading/saving logic into persistence package
this.gatesConfigFile = new File(Plugin.getPlugin().getDataFolder(), "gates.yml"); this.gatesConfigFile = new File(Plugin.getPlugin().getDataFolder(), "gates.yml");
if (!this.gatesConfigFile.exists()) { if (!this.gatesConfigFile.exists()) {
@ -289,7 +289,6 @@ public class GatesManager {
if (gateBlocks != null) { if (gateBlocks != null) {
for (Location l : gateBlocks) { for (Location l : gateBlocks) {
SimpleLocation sl = new SimpleLocation(l); SimpleLocation sl = new SimpleLocation(l);
gatesByLocation.remove(sl); gatesByLocation.remove(sl);
@ -311,7 +310,6 @@ public class GatesManager {
private void addGateByLocations(final Gate g) { private void addGateByLocations(final Gate g) {
for (Location l : g.getGateBlockLocations()) { for (Location l : g.getGateBlockLocations()) {
SimpleLocation sl = new SimpleLocation(l); SimpleLocation sl = new SimpleLocation(l);
gatesByLocation.put(sl, g); gatesByLocation.put(sl, g);
@ -368,7 +366,7 @@ public class GatesManager {
Set<Gate> gatesForC = gatesByChunk.get(sc); Set<Gate> gatesForC = gatesByChunk.get(sc);
if (gatesForC == null) { if (gatesForC == null) {
gatesForC = new HashSet<Gate>(); // NOTE: not optimizing size here gatesForC = new HashSet<>(); // NOTE: not optimizing size here
gatesByChunk.put(sc, gatesForC); gatesByChunk.put(sc, gatesForC);
} }
@ -378,7 +376,7 @@ public class GatesManager {
} }
} }
void storeInvalidGate(Map<String, Object> map) { public void storeInvalidGate(Map<String, Object> map) {
File invalidGatesFile = new File(Plugin.getPlugin().getDataFolder(), "invalid_gates.yml"); File invalidGatesFile = new File(Plugin.getPlugin().getDataFolder(), "invalid_gates.yml");
Boolean invalidGatesFileExists = invalidGatesFile.exists(); Boolean invalidGatesFileExists = invalidGatesFile.exists();
@ -428,13 +426,11 @@ public class GatesManager {
} }
} }
public void handleGateIdChange(final Gate g, final String oldId) { public void handleGateIdChange(final Gate g, final String oldId) {
this.removeGateById(oldId); this.removeGateById(oldId);
this.addGateWithId(g); this.addGateWithId(g);
} }
public void handleGateLocationChange(final Gate g, public void handleGateLocationChange(final Gate g,
final Location oldLocation, final Location oldLocation,
final Set<Location> oldGateBlockLocations, final Set<Location> oldGateBlockLocations,
@ -449,12 +445,10 @@ public class GatesManager {
this.addGateByFrameLocations(g); this.addGateByFrameLocations(g);
} }
public void handleGateExitChange(final Gate g, final Location oldExit) { public void handleGateExitChange(final Gate g, final Location oldExit) {
// nothing to do // nothing to do
} }
public void handleNewGate(final Gate g) { public void handleNewGate(final Gate g) {
this.gates.add(g); this.gates.add(g);
@ -464,7 +458,6 @@ public class GatesManager {
this.addGateByFrameLocations(g); this.addGateByFrameLocations(g);
} }
public void handleDeletion(final Gate g) { public void handleDeletion(final Gate g) {
this.gates.remove(g); this.gates.remove(g);
@ -474,12 +467,10 @@ public class GatesManager {
this.removeGateByFrameLocation(g.getGateFrameBlocks()); this.removeGateByFrameLocation(g.getGateFrameBlocks());
} }
public boolean gateExists(final String id) { public boolean gateExists(final String id) {
return gatesById.containsKey(id.toLowerCase()); return gatesById.containsKey(id.toLowerCase());
} }
public List<Gate> allGates() { public List<Gate> allGates() {
return gates; return gates;
} }

View File

@ -0,0 +1,55 @@
package de.craftinc.gates.controllers;
import de.craftinc.gates.Plugin;
import de.craftinc.gates.models.Gate;
import net.milkbowl.vault.permission.Permission;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
public class PermissionController {
public static final String permissionInfo = "craftincgates.info";
public static final String permissionManage = "craftincgates.manage";
public static final String permissionUse = "craftincgates.use";
private Permission permission;
public void setPermission(Permission permission) {
this.permission = permission;
}
public boolean hasPermission(CommandSender sender, Gate gate, String permission) {
assert(sender != null);
assert(permission != null);
final Location location = gate.getLocation();
final Location exit = gate.getExit();
boolean permAtLocation = location == null || hasPermission(sender, location.getWorld(), permission);
boolean permAtExit = exit == null || hasPermission(sender, exit.getWorld(), permission);
return permAtLocation && permAtExit;
}
public boolean hasPermission(CommandSender sender, String permission) {
return hasPermission(sender, (World)null, permission);
}
private boolean hasPermission(CommandSender sender, World world, String permission) {
assert(sender != null);
assert(permission != null);
if (this.permission == null) {
// fallback - use the standard bukkit permission system
return sender.hasPermission(permission);
}
if (!(sender instanceof OfflinePlayer)) {
return this.permission.has(sender, permission);
}
String worldName = world != null ? world.getName() : null;
return this.permission.playerHas(worldName, (OfflinePlayer)sender, permission);
}
}

View File

@ -0,0 +1,126 @@
package de.craftinc.gates.controllers;
import de.craftinc.gates.Plugin;
import de.craftinc.gates.models.Gate;
import de.craftinc.gates.util.ConfigurationUtil;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerTeleportEvent;
import java.util.Calendar;
import java.util.HashMap;
public class TeleportController {
private TeleportMessageUtil messageUtil;
private GatesManager gatesManager;
private PermissionController permissionController;
public TeleportController(Plugin plugin) {
this.gatesManager = plugin.getGatesManager();
this.messageUtil = new TeleportMessageUtil(plugin.getConfig());
this.permissionController = plugin.getPermissionController();
}
/**
* Try teleporting a player at given location.
*/
public void teleport(final Player player, Location toLocation) {
final Gate gateAtLocation = gatesManager.getGateAtLocation(toLocation);
if ((gateAtLocation == null) || !gateAtLocation.isOpen()) {
return;
}
if (!permissionController.hasPermission(player, gateAtLocation, PermissionController.permissionUse)) {
messageUtil.sendNoPermissionMessage(player);
return;
}
this.teleportPlayer(player, gateAtLocation);
}
private void teleportPlayer(final Player player, final Gate gate) {
final Entity vehicle = player.getVehicle();
if (vehicle != null && !gate.getAllowsVehicles()) {
messageUtil.sendVehicleForbiddenMessage(player);
return;
}
final Location destination = calculateDestination(player, gate);
if (vehicle != null) {
vehicle.teleport(destination, PlayerTeleportEvent.TeleportCause.PLUGIN);
vehicle.setPassenger(player);
} else {
player.teleport(destination);
}
messageUtil.sendTeleportMessage(player);
}
private Location calculateDestination(Player player, Gate gate) {
final Location exit = gate.getExit();
final Location pLocation = player.getLocation();
final Float newYaw = exit.getYaw() - gate.getLocation().getYaw() + pLocation.getYaw();
return new Location(exit.getWorld(),
exit.getX(),
exit.getY(),
exit.getZ(),
newYaw,
pLocation.getPitch()
);
}
}
class TeleportMessageUtil {
private HashMap<String, Long> lastNoPermissionMessages = new HashMap<>();
private FileConfiguration config;
TeleportMessageUtil(FileConfiguration config) {
this.config = config;
}
void sendVehicleForbiddenMessage(Player player) {
if (!config.getBoolean(ConfigurationUtil.confShowTeleportNoPermissionMessageKey)) {
return;
}
final String notAllowedMessage = config.getString(ConfigurationUtil.confGateTeleportVehicleNotAllowedMessageKey);
player.sendMessage(ChatColor.DARK_AQUA + notAllowedMessage);
}
void sendNoPermissionMessage(Player player) {
if (!config.getBoolean(ConfigurationUtil.confShowTeleportNoPermissionMessageKey)) {
return;
}
final String playerName = player.getPlayer().getName();
if (playerName == null) {
return;
}
final Long now = Calendar.getInstance().getTimeInMillis();
// do not display messages more often than once per second
if (!this.lastNoPermissionMessages.containsKey(playerName)
|| this.lastNoPermissionMessages.get(playerName) < now - 10000L) {
final String noPermissionString = config.getString(ConfigurationUtil.confGateTeleportNoPermissionMessageKey);
player.sendMessage(ChatColor.RED + noPermissionString);
this.lastNoPermissionMessages.put(playerName, now);
}
}
void sendTeleportMessage(Player player) {
if (!config.getBoolean(ConfigurationUtil.confShowTeleportMessageKey)) {
return;
}
final String teleportMessage = config.getString(ConfigurationUtil.confGateTeleportMessageKey);
player.sendMessage(ChatColor.DARK_AQUA + teleportMessage);
}
}

View File

@ -16,8 +16,7 @@
*/ */
package de.craftinc.gates.listeners; package de.craftinc.gates.listeners;
import de.craftinc.gates.models.Gate;
import de.craftinc.gates.Gate;
import de.craftinc.gates.Plugin; import de.craftinc.gates.Plugin;
import de.craftinc.gates.util.GateBlockChangeSender; import de.craftinc.gates.util.GateBlockChangeSender;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
@ -26,6 +25,7 @@ import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockBreakEvent;
public class BlockBreakListener implements Listener { public class BlockBreakListener implements Listener {
@EventHandler(priority = EventPriority.MONITOR) @EventHandler(priority = EventPriority.MONITOR)
public void onBlockBreak(BlockBreakEvent event) { public void onBlockBreak(BlockBreakEvent event) {
if (event.isCancelled()) { if (event.isCancelled()) {
@ -37,8 +37,7 @@ public class BlockBreakListener implements Listener {
if (gate != null && !gate.isHidden()) { if (gate != null && !gate.isHidden()) {
try { try {
gate.setOpen(false); gate.setOpen(false);
} catch (Exception ignored) { } catch (Exception ignored) {}
}
GateBlockChangeSender.updateGateBlocks(gate); GateBlockChangeSender.updateGateBlocks(gate);
} }

View File

@ -16,17 +16,18 @@
*/ */
package de.craftinc.gates.listeners; package de.craftinc.gates.listeners;
import de.craftinc.gates.util.GateBlockChangeSender; import de.craftinc.gates.util.GateBlockChangeSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerChangedWorldEvent; import org.bukkit.event.player.PlayerChangedWorldEvent;
public class PlayerChangedWorldListener implements Listener { public class PlayerChangedWorldListener implements Listener {
@EventHandler(priority = EventPriority.NORMAL) @EventHandler(priority = EventPriority.NORMAL)
public void onPlayerChangeWorld(PlayerChangedWorldEvent event) { public void onPlayerChangeWorld(PlayerChangedWorldEvent event) {
GateBlockChangeSender.updateGateBlocks(event.getPlayer()); Player p = event.getPlayer();
GateBlockChangeSender.updateGateBlocks(p, p.getLocation());
} }
} }

View File

@ -16,16 +16,18 @@
*/ */
package de.craftinc.gates.listeners; package de.craftinc.gates.listeners;
import de.craftinc.gates.util.GateBlockChangeSender; import de.craftinc.gates.util.GateBlockChangeSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
public class PlayerJoinListener implements Listener { public class PlayerJoinListener implements Listener {
@EventHandler(priority = EventPriority.NORMAL) @EventHandler(priority = EventPriority.NORMAL)
public void onPlayerJoin(PlayerJoinEvent event) { public void onPlayerJoin(PlayerJoinEvent event) {
GateBlockChangeSender.updateGateBlocks(event.getPlayer()); Player p = event.getPlayer();
GateBlockChangeSender.updateGateBlocks(p, p.getLocation());
} }
} }

View File

@ -16,30 +16,20 @@
*/ */
package de.craftinc.gates.listeners; package de.craftinc.gates.listeners;
import java.util.Calendar; import de.craftinc.gates.Plugin;
import java.util.HashMap; import de.craftinc.gates.controllers.TeleportController;
import de.craftinc.gates.util.ConfigurationUtil;
import de.craftinc.gates.util.GateBlockChangeSender; import de.craftinc.gates.util.GateBlockChangeSender;
import de.craftinc.gates.util.VehicleCloner;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Vehicle;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerMoveEvent;
import de.craftinc.gates.Gate;
import de.craftinc.gates.GatesManager;
import de.craftinc.gates.Plugin;
import org.bukkit.scheduler.BukkitScheduler;
public class PlayerMoveListener implements Listener { public class PlayerMoveListener implements Listener {
private HashMap<String, Long> lastNoPermissionMessages = new HashMap<>(); private TeleportController teleportController;
public PlayerMoveListener(Plugin plugin) {
this.teleportController = new TeleportController(plugin);
}
@EventHandler(priority = EventPriority.NORMAL) @EventHandler(priority = EventPriority.NORMAL)
public void onPlayerMove(PlayerMoveEvent event) { public void onPlayerMove(PlayerMoveEvent event) {
@ -51,113 +41,6 @@ public class PlayerMoveListener implements Listener {
GateBlockChangeSender.updateGateBlocks(event.getPlayer(), event.getTo()); GateBlockChangeSender.updateGateBlocks(event.getPlayer(), event.getTo());
} }
final GatesManager gateManager = Plugin.getPlugin().getGatesManager(); teleportController.teleport(event.getPlayer(), event.getTo());
final Gate gateAtLocation = gateManager.getGateAtLocation(event.getTo());
if ((gateAtLocation == null) || !gateAtLocation.isOpen()) {
return;
}
// Check for permission
if (!hasPermission(event.getPlayer(), gateAtLocation)
&& Plugin.getPlugin().getConfig().getBoolean(ConfigurationUtil.confShowTeleportNoPermissionMessageKey)) {
final String playerName = event.getPlayer().getName();
if (playerName == null) {
return;
}
// get the current time
final Long now = Calendar.getInstance().getTimeInMillis();
// do not display messages more often than once per second
if (!this.lastNoPermissionMessages.containsKey(playerName) || this.lastNoPermissionMessages.get(playerName) < now - 10000L) {
final String noPermissionString = Plugin.getPlugin().getConfig().getString(ConfigurationUtil.confGateTeleportNoPermissionMessageKey);
event.getPlayer().sendMessage(ChatColor.RED + noPermissionString);
this.lastNoPermissionMessages.put(playerName, now);
}
} else {
this.teleportPlayer(event.getPlayer(), gateAtLocation);
}
}
/**
* Teleports a player.
*
* @param player The player to teleport.
* @param gate The gate to which exit the player will be teleported.
*/
private void teleportPlayer(final Player player, final Gate gate) {
// Destination
final Float newYaw = gate.getExit().getYaw() - gate.getLocation().getYaw() + player.getLocation().getYaw();
final Location destLocation = new Location(gate.getExit().getWorld(),
gate.getExit().getX(),
gate.getExit().getY(),
gate.getExit().getZ(),
newYaw,
player.getLocation().getPitch()
);
// Riding
final Entity vehicle = player.getVehicle();
final boolean vehicleIsSuitable = (vehicle != null) && (vehicle instanceof Vehicle);
if (vehicle != null && (!vehicleIsSuitable) || !gate.getAllowsVehicles()) {
if (!gate.getAllowsVehicles() && Plugin.getPlugin().getConfig().getBoolean(ConfigurationUtil.confShowTeleportNoPermissionMessageKey)) {
final String notAllowedMessage = Plugin.getPlugin().getConfig().getString(ConfigurationUtil.confGateTeleportVehicleNotAllowedMessageKey);
player.sendMessage(ChatColor.DARK_AQUA + notAllowedMessage);
}
return;
}
// (eject player)
if (vehicleIsSuitable) {
vehicle.eject();
vehicle.remove();
}
// Teleport
player.teleport(destLocation);
// Riding (mount player)
if (vehicleIsSuitable) {
final Plugin plugin = Plugin.getPlugin();
final BukkitScheduler scheduler = plugin.getServer().getScheduler();
destLocation.getChunk().load(); // load the destination chunk, no new entity will be created otherwise
scheduler.scheduleSyncDelayedTask(plugin, new Runnable() {
public void run() {
// FIXME: the code below should be executed after the chunk got loaded and not after a fixed time!
// create a new entity at the destination location
final Vehicle newVehicle = VehicleCloner.clone((Vehicle) vehicle, destLocation);
newVehicle.setPassenger(player);
}
}, 2);
}
// Message
if (Plugin.getPlugin().getConfig().getBoolean(ConfigurationUtil.confShowTeleportMessageKey)) {
final String teleportMessage = Plugin.getPlugin().getConfig().getString(ConfigurationUtil.confGateTeleportMessageKey);
player.sendMessage(ChatColor.DARK_AQUA + teleportMessage);
}
}
private boolean hasPermission(final Player player, final Gate gate) {
if (Plugin.getPermission() == null) { // fallback: use the standard bukkit permission system
return player.hasPermission(Plugin.permissionUse);
} else {
final boolean permAtLocation = Plugin.getPermission().has(gate.getLocation().getWorld(), player.getName(), Plugin.permissionUse);
final boolean permAtExit = Plugin.getPermission().has(gate.getExit().getWorld(), player.getName(), Plugin.permissionUse);
return permAtLocation && permAtExit;
}
} }
} }

View File

@ -16,14 +16,12 @@
*/ */
package de.craftinc.gates.listeners; package de.craftinc.gates.listeners;
import de.craftinc.gates.util.GateBlockChangeSender; import de.craftinc.gates.util.GateBlockChangeSender;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerRespawnEvent; import org.bukkit.event.player.PlayerRespawnEvent;
public class PlayerRespawnListener implements Listener { public class PlayerRespawnListener implements Listener {
@EventHandler(priority = EventPriority.NORMAL) @EventHandler(priority = EventPriority.NORMAL)
public void onPlayerRespawn(PlayerRespawnEvent event) { public void onPlayerRespawn(PlayerRespawnEvent event) {

View File

@ -16,7 +16,6 @@
*/ */
package de.craftinc.gates.listeners; package de.craftinc.gates.listeners;
import de.craftinc.gates.util.GateBlockChangeSender; import de.craftinc.gates.util.GateBlockChangeSender;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
@ -24,6 +23,7 @@ import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.event.player.PlayerTeleportEvent;
public class PlayerTeleportListener implements Listener { public class PlayerTeleportListener implements Listener {
@EventHandler(priority = EventPriority.MONITOR) @EventHandler(priority = EventPriority.MONITOR)
public void onPlayerTeleport(PlayerTeleportEvent event) { public void onPlayerTeleport(PlayerTeleportEvent event) {
if (event.isCancelled()) { if (event.isCancelled()) {

View File

@ -14,37 +14,30 @@
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>. along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/ */
package de.craftinc.gates; package de.craftinc.gates.models;
import de.craftinc.gates.Plugin;
import de.craftinc.gates.util.ConfigurationUtil; import de.craftinc.gates.util.ConfigurationUtil;
import de.craftinc.gates.util.FloodUtil; import de.craftinc.gates.util.FloodUtil;
import de.craftinc.gates.persistence.LocationUtil; import de.craftinc.gates.persistence.LocationUtil;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.configuration.serialization.ConfigurationSerializable;
import java.util.*; import java.util.*;
public class Gate implements ConfigurationSerializable { public class Gate implements ConfigurationSerializable {
protected Location location; /* saving both location and gateBlockLocations is redundant but makes it easy to allow players to reshape gates */ private Location location; /* saving both location and gateBlockLocations is redundant but makes it easy to allow players to reshape gates */
private Set<Location> gateBlockLocations = new HashSet<>(); /* Locations of the blocks inside the gate */ private Set<Location> gateBlockLocations = new HashSet<>(); /* Locations of the blocks inside the gate */
private Set<Block> gateFrameBlocks = new HashSet<>(); private Set<Block> gateFrameBlocks = new HashSet<>();
private Location exit;
protected Location exit;
private boolean isHidden = false; private boolean isHidden = false;
private boolean isOpen = false; private boolean isOpen = false;
private boolean allowsVehicles = true; private boolean allowsVehicles = true;
private String id;
protected String id;
public static String getGateBlocksKey() {
return gateBlocksKey;
}
/** /**
* You should never create two gates with the same 'id'. Also see 'setId(String id)'. * You should never create two gates with the same 'id'. Also see 'setId(String id)'.
@ -55,11 +48,21 @@ public class Gate implements ConfigurationSerializable {
setId(id); setId(id);
} }
public String toString() { public String toString() {
return super.toString() + " " + this.getId(); return super.toString() + " " + this.getId();
} }
public GateDirection getDirection() {
if (gateBlockLocations.isEmpty()) {
return null;
} else {
Block some = ((Location)gateBlockLocations.toArray()[0]).getBlock();
boolean east = gateBlockLocations.contains(some.getRelative(BlockFace.EAST).getLocation());
boolean west = gateBlockLocations.contains(some.getRelative(BlockFace.WEST).getLocation());
return east || west ? GateDirection.EastWest : GateDirection.NorthSouth;
}
}
/** /**
* @return This method might return a 'null' data. * @return This method might return a 'null' data.
@ -68,7 +71,6 @@ public class Gate implements ConfigurationSerializable {
return location; return location;
} }
/** /**
* @param location Supplying 'null' is permitted. * @param location Supplying 'null' is permitted.
* @throws Exception Will throw an exception if the gate is open and an invalid (no gate frame) location is * @throws Exception Will throw an exception if the gate is open and an invalid (no gate frame) location is
@ -186,7 +188,7 @@ public class Gate implements ConfigurationSerializable {
/** /**
* Checks if values attributes do add up; will close gate on wrong values. * Checks if values attributes do add up; will close gate on wrong values.
*/ */
void validate() throws Exception { public void validate() throws Exception {
if (!isOpen) { if (!isOpen) {
return; return;
} }

View File

@ -0,0 +1,6 @@
package de.craftinc.gates.models;
public enum GateDirection {
EastWest,
NorthSouth
}

View File

@ -0,0 +1,106 @@
package de.craftinc.gates.models;
import org.bukkit.Material;
import java.security.InvalidParameterException;
public class GateMaterial {
private Material material;
public GateMaterial(String materialString) throws InvalidParameterException {
Material material;
switch (materialString) {
case "sapling":
material = Material.SAPLING;
break;
case "water":
material = Material.STATIONARY_WATER;
break;
case "lava":
material = Material.STATIONARY_LAVA;
break;
case "cobweb":
material = Material.WEB;
break;
case "grass":
material = Material.LONG_GRASS;
break;
case "dead bush":
material = Material.DEAD_BUSH;
break;
case "dandelion":
material = Material.YELLOW_FLOWER;
break;
case "poppy":
material = Material.RED_ROSE;
break;
case "brown mushroom":
material = Material.BROWN_MUSHROOM;
break;
case "red mushroom":
material = Material.RED_MUSHROOM;
break;
case "torch":
material = Material.TORCH;
break;
case "redstone torch (off)":
material = Material.REDSTONE_TORCH_OFF;
break;
case "redstone torch (on)":
material = Material.REDSTONE_TORCH_ON;
break;
case "fence":
material = Material.FENCE;
break;
case "nether portal":
material = Material.PORTAL;
break;
case "iron bars":
material = Material.IRON_FENCE;
break;
case "glass pane":
material = Material.THIN_GLASS;
break;
case "fence gate":
material = Material.FENCE_GATE;
break;
case "nether brick fence":
material = Material.NETHER_FENCE;
break;
case "nether wart":
material = Material.NETHER_WARTS;
break;
case "end portal":
material = Material.ENDER_PORTAL;
break;
case "cobblestone wall":
material = Material.COBBLE_WALL;
break;
default:
throw new InvalidParameterException();
}
this.material = material;
}
GateMaterial(Material material) {
this.material = material;
}
public Material getMaterial() {
return material;
}
public byte getData(GateDirection direction) {
switch (material) {
case PORTAL:
return direction == GateDirection.EastWest ? (byte)0b0 : (byte)0b10;
case GRASS:
return 1;
default:
return 0;
}
}
}

View File

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>. along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/ */
package de.craftinc.gates.util; package de.craftinc.gates.models;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.World; import org.bukkit.World;

View File

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>. along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/ */
package de.craftinc.gates.util; package de.craftinc.gates.models;
import org.bukkit.Location; import org.bukkit.Location;
@ -24,7 +24,6 @@ public class SimpleLocation {
private int y; private int y;
private int z; private int z;
public SimpleLocation(Location l) { public SimpleLocation(Location l) {
this.world = l.getWorld().getName(); this.world = l.getWorld().getName();
@ -35,7 +34,6 @@ public class SimpleLocation {
this.z = l.getBlockZ(); this.z = l.getBlockZ();
} }
public SimpleLocation(Location l, boolean isHeadPosition) { public SimpleLocation(Location l, boolean isHeadPosition) {
this.world = l.getWorld().getName(); this.world = l.getWorld().getName();
@ -50,13 +48,11 @@ public class SimpleLocation {
} }
} }
@Override @Override
public String toString() { public String toString() {
return super.toString() + " x: " + x + " y: " + y + " z: " + z + " world: " + world; return super.toString() + " x: " + x + " y: " + y + " z: " + z + " world: " + world;
} }
@Override @Override
public boolean equals(final Object o) { public boolean equals(final Object o) {
if (o instanceof SimpleLocation) { if (o instanceof SimpleLocation) {
@ -74,7 +70,6 @@ public class SimpleLocation {
return false; return false;
} }
@Override @Override
public int hashCode() { public int hashCode() {
int hash = 13; int hash = 13;

View File

@ -24,7 +24,6 @@ import org.bukkit.World;
import de.craftinc.gates.Plugin; import de.craftinc.gates.Plugin;
public class LocationUtil { public class LocationUtil {
private final static String worldKey = "world"; private final static String worldKey = "world";
@ -32,7 +31,7 @@ public class LocationUtil {
private final static String yKey = "y"; private final static String yKey = "y";
private final static String zKey = "z"; private final static String zKey = "z";
protected static World getWorld(final String name) throws Exception { private static World getWorld(final String name) throws Exception {
if (name == null) { if (name == null) {
throw new IllegalArgumentException("The name of the world must not be 'null"); throw new IllegalArgumentException("The name of the world must not be 'null");
} }

View File

@ -16,7 +16,7 @@
*/ */
package de.craftinc.gates.persistence; package de.craftinc.gates.persistence;
import de.craftinc.gates.Gate; import de.craftinc.gates.models.Gate;
import de.craftinc.gates.Plugin; import de.craftinc.gates.Plugin;
import org.bukkit.Location; import org.bukkit.Location;

View File

@ -16,13 +16,12 @@
*/ */
package de.craftinc.gates.util; package de.craftinc.gates.util;
import de.craftinc.gates.Plugin; import de.craftinc.gates.Plugin;
import org.bukkit.Material; import de.craftinc.gates.models.GateMaterial;
import java.security.InvalidParameterException;
import java.util.logging.Level; import java.util.logging.Level;
public class ConfigurationUtil { public class ConfigurationUtil {
public static final String confMaxGateBlocksKey = "maxGateBlocks"; public static final String confMaxGateBlocksKey = "maxGateBlocks";
public static final String confPlayerGateBlockUpdateRadiusKey = "playerGateBlockUpdateRadius"; public static final String confPlayerGateBlockUpdateRadiusKey = "playerGateBlockUpdateRadius";
@ -39,88 +38,12 @@ public class ConfigurationUtil {
static GateMaterial getPortalMaterial() { static GateMaterial getPortalMaterial() {
String materialString = Plugin.getPlugin().getConfig().getString(confGateMaterialKey); String materialString = Plugin.getPlugin().getConfig().getString(confGateMaterialKey);
GateMaterial material = new GateMaterial();
switch (materialString) { try {
case "sapling": return new GateMaterial(materialString);
material.material = Material.SAPLING; } catch (InvalidParameterException ignored) {
break; Plugin.log(Level.WARNING, "Gate material invalid! Please check and correct your configuration file!");
case "water": return new GateMaterial("nether portal");
material.material = Material.STATIONARY_WATER;
break;
case "lava":
material.material = Material.STATIONARY_LAVA;
break;
case "cobweb":
material.material = Material.WEB;
break;
case "grass":
material.material = Material.LONG_GRASS;
material.data = 1;
break;
case "dead bush":
material.material = Material.DEAD_BUSH;
break;
case "dandelion":
material.material = Material.YELLOW_FLOWER;
break;
case "poppy":
material.material = Material.RED_ROSE;
break;
case "brown mushroom":
material.material = Material.BROWN_MUSHROOM;
break;
case "red mushroom":
material.material = Material.RED_MUSHROOM;
break;
case "torch":
material.material = Material.TORCH;
break;
case "redstone torch (off)":
material.material = Material.REDSTONE_TORCH_OFF;
break;
case "redstone torch (on)":
material.material = Material.REDSTONE_TORCH_ON;
break;
case "fence":
material.material = Material.FENCE;
break;
case "nether portal":
material.material = Material.PORTAL;
break;
case "iron bars":
material.material = Material.IRON_FENCE;
break;
case "glass pane":
material.material = Material.THIN_GLASS;
break;
case "fence gate":
material.material = Material.FENCE_GATE;
break;
case "nether brick fence":
material.material = Material.NETHER_FENCE;
break;
case "nether wart":
material.material = Material.NETHER_WARTS;
break;
case "end portal":
material.material = Material.ENDER_PORTAL;
break;
case "cobblestone wall":
material.material = Material.COBBLE_WALL;
break;
default: // fallback!
material.material = Material.PORTAL;
Plugin.log(Level.WARNING, "Gate material invalid! Please check and correct your configuration file!");
break;
} }
return material;
} }
} }
class GateMaterial {
public Material material = Material.PORTAL;
public byte data = 0;
}

View File

@ -44,7 +44,6 @@ public class FloodUtil {
exp2.add(BlockFace.SOUTH); exp2.add(BlockFace.SOUTH);
} }
/** /**
* Returns the all frame blocks of an gate. * Returns the all frame blocks of an gate.
* *

View File

@ -16,10 +16,10 @@
*/ */
package de.craftinc.gates.util; package de.craftinc.gates.util;
import de.craftinc.gates.Plugin; import de.craftinc.gates.Plugin;
import de.craftinc.gates.Gate; import de.craftinc.gates.models.Gate;
import de.craftinc.gates.models.GateMaterial;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
@ -31,7 +31,6 @@ import java.util.Set;
import static de.craftinc.gates.util.ConfigurationUtil.*; import static de.craftinc.gates.util.ConfigurationUtil.*;
public class GateBlockChangeSender { public class GateBlockChangeSender {
/** /**
* Replaces gate frame blocks with glowstone for a short period of time. * Replaces gate frame blocks with glowstone for a short period of time.
@ -40,15 +39,12 @@ public class GateBlockChangeSender {
* *
* @param player The player for whom the frame should be highlighted. * @param player The player for whom the frame should be highlighted.
* Must not be null! * Must not be null!
*
* @param gates The gates to highlighting
*/ */
public static void temporaryHighlightGatesFrames(final Player player, final Set<Gate> gates) { public static void temporaryHighlightGatesFrames(final Player player, final Set<Gate> gates) {
if (player == null) { assert(player != null);
throw new IllegalArgumentException("'player' must not be 'null'!"); assert(gates != null);
}
if (gates == null) {
throw new IllegalArgumentException("'gate' must not be 'null!");
}
for (Gate g : gates) { for (Gate g : gates) {
Set<Block> frameBlocks = g.getGateFrameBlocks(); Set<Block> frameBlocks = g.getGateFrameBlocks();
@ -57,66 +53,9 @@ public class GateBlockChangeSender {
player.sendBlockChange(b.getLocation(), Material.GLOWSTONE, (byte) 0); player.sendBlockChange(b.getLocation(), Material.GLOWSTONE, (byte) 0);
} }
} }
scheduleDelighting(player, gates);
Plugin plugin = Plugin.getPlugin();
long highlightDuration = 20 * plugin.getConfig().getLong(confHighlightDurationKey);
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
@Override
public void run() {
dehighlightGatesFrames(player, gates);
}
}, highlightDuration);
} }
public static void temporaryHighlightGateFrame(final Player player, final Gate gate) {
if (gate == null) {
throw new IllegalArgumentException("'gate' must not be 'null!");
}
if (player == null) {
throw new IllegalArgumentException("'player' must not be 'null'!");
}
Set<Block> frameBlocks = gate.getGateFrameBlocks();
for (Block b : frameBlocks) {
player.sendBlockChange(b.getLocation(), Material.GLOWSTONE, (byte) 0);
}
Plugin plugin = Plugin.getPlugin();
long highlightDuration = 20 * plugin.getConfig().getLong(confHighlightDurationKey);
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
@Override
public void run() {
dehighlightGateFrame(player, gate);
}
}, highlightDuration);
}
private static void dehighlightGatesFrames(final Player player, final Set<Gate> gates) {
for (Gate g : gates) {
Set<Block> frameBlocks = g.getGateFrameBlocks();
for (Block b : frameBlocks) {
player.sendBlockChange(b.getLocation(), b.getType(), (byte) 0);
}
}
}
private static void dehighlightGateFrame(final Player player, final Gate gate) {
Set<Block> frameBlocks = gate.getGateFrameBlocks();
for (Block b : frameBlocks) {
player.sendBlockChange(b.getLocation(), b.getType(), (byte) 0);
}
}
/** /**
* Sends gate blocks to player at a given location. Will send the updates either immediately or * Sends gate blocks to player at a given location. Will send the updates either immediately or
* immediately and after a short delay. * immediately and after a short delay.
@ -127,33 +66,20 @@ public class GateBlockChangeSender {
* second delay. * second delay.
*/ */
public static void updateGateBlocks(final Player player, final Location location, boolean sendDelayed) { public static void updateGateBlocks(final Player player, final Location location, boolean sendDelayed) {
if (player == null) { assert(player != null);
throw new IllegalArgumentException("'player' must not be 'null'!"); assert(location != null);
}
if (location == null) {
throw new IllegalArgumentException("'location' must not be 'null'!");
}
Set<Gate> gatesNearby = Plugin.getPlugin().getGatesManager().getNearbyGates(location.getChunk()); Set<Gate> gatesNearby = Plugin.getPlugin().getGatesManager().getNearbyGates(location.getChunk());
GateMaterial gateMaterial = getPortalMaterial();
if (gatesNearby == null) { if (gatesNearby == null) {
return; // no gates nearby return; // no gates nearby
} }
for (Gate g : gatesNearby) { for (Gate g : gatesNearby) {
if (!g.isOpen() || g.isHidden()) { if (!g.isOpen() || g.isHidden()) {
continue; continue;
} }
sendGateBlockChanges(g, true, player);
for (Location l : g.getGateBlockLocations()) {
if (l.getBlock().getType() == Material.AIR) {
player.sendBlockChange(l, gateMaterial.material, gateMaterial.data);
}
}
} }
if (sendDelayed) { if (sendDelayed) {
@ -166,25 +92,10 @@ public class GateBlockChangeSender {
} }
} }
/**
* This method calls: updateGateBlocks(player, location, false);
*/
public static void updateGateBlocks(final Player player, final Location location) { public static void updateGateBlocks(final Player player, final Location location) {
updateGateBlocks(player, location, false); updateGateBlocks(player, location, false);
} }
/**
* This method calls: updateGateBlocks(player, player.getLocation(), false);
*/
public static void updateGateBlocks(final Player player) {
if (player == null) {
throw new IllegalArgumentException("'player' must not be 'null'!");
}
updateGateBlocks(player, player.getLocation(), false);
}
public static void updateGateBlocks(final Gate gate) { public static void updateGateBlocks(final Gate gate) {
updateGateBlocks(gate, false); updateGateBlocks(gate, false);
@ -197,45 +108,66 @@ public class GateBlockChangeSender {
* @param remove Set to true if all visible gate blocks shall be removed. * @param remove Set to true if all visible gate blocks shall be removed.
*/ */
public static void updateGateBlocks(final Gate gate, boolean remove) { public static void updateGateBlocks(final Gate gate, boolean remove) {
if (gate == null) { assert(gate != null);
throw new IllegalArgumentException("'gate must not be 'null'!");
}
Location gateLocation = gate.getLocation(); Location gateLocation = gate.getLocation();
if (gate.getGateBlockLocations().isEmpty()) { if (gate.getGateBlockLocations().isEmpty()) {
return; return;
} }
ArrayList<Player> playersNearby = new ArrayList<>(); ArrayList<Player> playersNearby = new ArrayList<>();
int searchRadius = Plugin.getPlugin().getConfig().getInt(confPlayerGateBlockUpdateRadiusKey); int searchRadius = Plugin.getPlugin().getConfig().getInt(confPlayerGateBlockUpdateRadiusKey);
for (Player p : Plugin.getPlugin().getServer().getOnlinePlayers()) { for (Player p : Plugin.getPlugin().getServer().getOnlinePlayers()) {
if (p.getWorld() == gateLocation.getWorld() && p.getLocation().distance(gateLocation) < searchRadius) { if (p.getWorld() == gateLocation.getWorld() && p.getLocation().distance(gateLocation) < searchRadius) {
playersNearby.add(p); playersNearby.add(p);
} }
} }
GateMaterial gateMaterial = getPortalMaterial(); boolean isVisible = gate.isOpen() && !gate.isHidden() && !remove;
Material material; for (Player p : playersNearby) {
byte data = 0; sendGateBlockChanges(gate, isVisible, p);
}
}
if (gate.isOpen() && !gate.isHidden() && !remove) { private static void scheduleDelighting(final Player player, final Set<Gate> gates) {
material = gateMaterial.material; Plugin plugin = Plugin.getPlugin();
data = gateMaterial.data; long highlightDuration = 20 * plugin.getConfig().getLong(confHighlightDurationKey);
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
@Override
public void run() {
dehighlightGatesFrames(player, gates);
}
}, highlightDuration);
}
private static void dehighlightGatesFrames(final Player player, final Set<Gate> gates) {
for (Gate g : gates) {
Set<Block> frameBlocks = g.getGateFrameBlocks();
for (Block b : frameBlocks) {
player.sendBlockChange(b.getLocation(), b.getType(), (byte) 0);
}
}
}
private static void sendGateBlockChanges(final Gate gate, boolean isVisible, final Player p) {
byte data;
Material material;
if (isVisible) {
GateMaterial gm = getPortalMaterial();
data = gm.getData(gate.getDirection());
material = gm.getMaterial();
} else { } else {
data = 0b0;
material = Material.AIR; material = Material.AIR;
} }
for (Player p : playersNearby) { for (Location l : gate.getGateBlockLocations()) {
if (l.getBlock().getType() == Material.AIR) {
for (Location l : gate.getGateBlockLocations()) { p.sendBlockChange(l, material, data);
if (l.getBlock().getType() == Material.AIR) { // on server-side a gate is always made out of AIR
p.sendBlockChange(l, material, data);
}
} }
} }
} }

View File

@ -46,7 +46,6 @@ public class TextUtil {
return s + repeat(s, times - 1); return s + repeat(s, times - 1);
} }
/** /**
* Joins all elements of list into a single string, separating the original strings with glue. * Joins all elements of list into a single string, separating the original strings with glue.
*/ */
@ -64,5 +63,3 @@ public class TextUtil {
return ret; return ret;
} }
} }

View File

@ -1,108 +0,0 @@
/* Craft Inc. Gates
Copyright (C) 2011-2013 Craft Inc. Gates Team (see AUTHORS.txt)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/
package de.craftinc.gates.util;
import org.bukkit.Location;
import org.bukkit.entity.*;
public class VehicleCloner {
public static Vehicle clone(Vehicle parent, Location cloneLocation) {
Vehicle clone = cloneLocation.getWorld().spawn(cloneLocation, parent.getClass());
clone.setFallDistance(parent.getFallDistance());
clone.setFireTicks(parent.getFireTicks());
clone.setVelocity(parent.getVelocity());
clone.setTicksLived(parent.getTicksLived());
clone.setLastDamageCause(parent.getLastDamageCause());
if (clone instanceof Boat) {
Boat boat = (Boat) clone;
Boat parentBoat = (Boat) parent;
boat.setMaxSpeed(parentBoat.getMaxSpeed());
boat.setOccupiedDeceleration(parentBoat.getOccupiedDeceleration());
boat.setUnoccupiedDeceleration(parentBoat.getUnoccupiedDeceleration());
boat.setWorkOnLand(parentBoat.getWorkOnLand());
boat.setVelocity(parentBoat.getVelocity());
} else if (clone instanceof Animals) {
Animals animal = (Animals) clone;
Animals parentAnimal = (Animals) parent;
animal.setMaxHealth(parentAnimal.getMaxHealth());
animal.setHealth(parentAnimal.getMaxHealth());
animal.setRemainingAir(parentAnimal.getRemainingAir());
animal.setMaximumAir(parentAnimal.getMaximumAir());
animal.setMaximumNoDamageTicks(parentAnimal.getMaximumNoDamageTicks());
animal.setLastDamage(parentAnimal.getLastDamage());
animal.setNoDamageTicks(parentAnimal.getNoDamageTicks());
animal.addPotionEffects(parentAnimal.getActivePotionEffects());
animal.setRemoveWhenFarAway(parentAnimal.getRemoveWhenFarAway());
animal.setCanPickupItems(parentAnimal.getCanPickupItems());
animal.setCustomName(parentAnimal.getCustomName());
animal.setCustomNameVisible(parentAnimal.isCustomNameVisible());
animal.setTarget(parentAnimal.getTarget());
animal.setAge(parentAnimal.getAge());
animal.setAgeLock(parentAnimal.getAgeLock());
if (clone instanceof Horse) {
Horse horse = (Horse) clone;
Horse parentHorse = (Horse) parent;
horse.getInventory().setArmor(parentHorse.getInventory().getArmor());
horse.getInventory().setSaddle(parentHorse.getInventory().getSaddle());
horse.setCarryingChest(parentHorse.isCarryingChest());
horse.getInventory().setContents(parentHorse.getInventory().getContents());
horse.setTamed(parentHorse.isTamed());
horse.setOwner(parentHorse.getOwner());
horse.setJumpStrength(parentHorse.getJumpStrength());
horse.setMaxDomestication(parentHorse.getMaxDomestication());
horse.setDomestication(parentHorse.getDomestication());
horse.setStyle(parentHorse.getStyle());
horse.setColor(parentHorse.getColor());
horse.setVariant(parentHorse.getVariant());
if (parentHorse.isAdult()) {
horse.setAdult();
} else {
horse.setBaby();
}
horse.setBreed(parentHorse.canBreed());
} else if (clone instanceof Pig) {
Pig pig = (Pig) clone;
Pig parentPig = (Pig) parent;
pig.setSaddle(parentPig.hasSaddle());
}
} else if (clone instanceof Minecart) {
Minecart minecart = (Minecart) clone;
Minecart parentMinecart = (Minecart) parent;
minecart.setDerailedVelocityMod(parentMinecart.getDerailedVelocityMod());
minecart.setFlyingVelocityMod(parentMinecart.getFlyingVelocityMod());
minecart.setSlowWhenEmpty(parentMinecart.isSlowWhenEmpty());
minecart.setMaxSpeed(parentMinecart.getMaxSpeed());
minecart.setDamage(parentMinecart.getDamage());
minecart.setVelocity(parentMinecart.getVelocity());
}
return clone;
}
}