Makes portal names and networks case and color-insensitive and increases length limit to 13. #17

Ignores &[0-9a-f] color codes when counting towards the name and network string limits
Makes portal lists store cleaned portal and network names to ignore case and color
Names and networks will now match regardless of case and color
Increases portal name/network limit to 13 characters
This commit is contained in:
Kristian Knarvik 2021-11-12 15:33:15 +01:00
parent 42e02eb141
commit 2c53b7d2a6
10 changed files with 87 additions and 40 deletions

View File

@ -244,7 +244,7 @@ public class PlayerEventListener implements Listener {
* @return <p>True if the player should be denied</p> * @return <p>True if the player should be denied</p>
*/ */
private boolean cannotAccessPortal(Player player, Portal portal) { private boolean cannotAccessPortal(Player player, Portal portal) {
boolean deny = PermissionHelper.cannotAccessNetwork(player, portal.getNetwork()); boolean deny = PermissionHelper.cannotAccessNetwork(player, portal.getCleanNetwork());
if (PermissionHelper.portalAccessDenied(player, portal, deny)) { if (PermissionHelper.portalAccessDenied(player, portal, deny)) {
if (!portal.getOptions().isSilent()) { if (!portal.getOptions().isSilent()) {

View File

@ -8,6 +8,7 @@ import net.knarcraft.stargate.portal.property.PortalOptions;
import net.knarcraft.stargate.portal.property.PortalOwner; import net.knarcraft.stargate.portal.property.PortalOwner;
import net.knarcraft.stargate.portal.property.PortalStructure; import net.knarcraft.stargate.portal.property.PortalStructure;
import net.knarcraft.stargate.portal.property.gate.Gate; import net.knarcraft.stargate.portal.property.gate.Gate;
import org.bukkit.ChatColor;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -19,7 +20,10 @@ import java.util.Map;
public class Portal { public class Portal {
private final String name; private final String name;
private final String cleanName;
private final String network; private final String network;
private final String cleanNetwork;
private final PortalOwner portalOwner; private final PortalOwner portalOwner;
private boolean isRegistered; private boolean isRegistered;
@ -53,6 +57,8 @@ public class Portal {
this.portalOpener = new PortalOpener(this, destination); this.portalOpener = new PortalOpener(this, destination);
this.structure = new PortalStructure(this, gate, button); this.structure = new PortalStructure(this, gate, button);
this.portalActivator = portalOpener.getPortalActivator(); this.portalActivator = portalOpener.getPortalActivator();
this.cleanName = cleanString(name);
this.cleanNetwork = cleanString(network);
} }
/** /**
@ -149,6 +155,15 @@ public class Portal {
return network; return network;
} }
/**
* Gets the clean name of the network this portal belongs to
*
* @return <p>The clean network name</p>
*/
public String getCleanNetwork() {
return cleanNetwork;
}
/** /**
* Gets the time this portal was triggered (activated/opened) * Gets the time this portal was triggered (activated/opened)
* *
@ -170,6 +185,15 @@ public class Portal {
return name; return name;
} }
/**
* Gets the clean name of this portal
*
* @return <p>The clean name of this portal</p>
*/
public String getCleanName() {
return cleanName;
}
/** /**
* Gets the portal opener used by this portal * Gets the portal opener used by this portal
* *
@ -273,6 +297,17 @@ public class Portal {
return getTopLeft().getRelativeLocation(vector, getYaw()); return getTopLeft().getRelativeLocation(vector, getYaw());
} }
/**
* Cleans a string by removing color codes, lower-casing and replacing spaces with underscores
*
* @param string <p>The string to clean</p>
* @return <p>The clean string</p>
*/
public static String cleanString(String string) {
string = ChatColor.stripColor(ChatColor.translateAlternateColorCodes('&', string));
return string.toLowerCase().replace(' ', '_');
}
@Override @Override
public String toString() { public String toString() {
return String.format("Portal [id=%s, network=%s name=%s, type=%s]", getSignLocation(), network, name, return String.format("Portal [id=%s, network=%s name=%s, type=%s]", getSignLocation(), network, name,
@ -283,8 +318,8 @@ public class Portal {
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;
int result = 1; int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + ((cleanName == null) ? 0 : cleanName.hashCode());
result = prime * result + ((network == null) ? 0 : network.hashCode()); result = prime * result + ((cleanNetwork == null) ? 0 : cleanNetwork.hashCode());
return result; return result;
} }
@ -297,18 +332,18 @@ public class Portal {
return false; return false;
} }
Portal other = (Portal) object; Portal other = (Portal) object;
if (name == null) { if (cleanName == null) {
if (other.name != null) { if (other.cleanName != null) {
return false; return false;
} }
} else if (!name.equalsIgnoreCase(other.name)) { } else if (!cleanName.equalsIgnoreCase(other.cleanName)) {
return false; return false;
} }
//If none of the portals have a name, check if the network is the same //If none of the portals have a name, check if the network is the same
if (network == null) { if (cleanNetwork == null) {
return other.network == null; return other.cleanNetwork == null;
} else { } else {
return network.equalsIgnoreCase(other.network); return cleanNetwork.equalsIgnoreCase(other.cleanNetwork);
} }
} }
} }

View File

@ -64,7 +64,7 @@ public class PortalActivator {
* @return <p>The destination portal the player should teleport to</p> * @return <p>The destination portal the player should teleport to</p>
*/ */
public Portal getDestination(Player player) { public Portal getDestination(Player player) {
String portalNetwork = portal.getNetwork(); String portalNetwork = portal.getCleanNetwork();
if (portal.getOptions().isRandom()) { if (portal.getOptions().isRandom()) {
//Find possible destinations //Find possible destinations
List<String> destinations = PortalHandler.getDestinations(portal, player, portalNetwork); List<String> destinations = PortalHandler.getDestinations(portal, player, portalNetwork);
@ -73,10 +73,10 @@ public class PortalActivator {
} }
//Get one random destination //Get one random destination
String destination = destinations.get((new Random()).nextInt(destinations.size())); String destination = destinations.get((new Random()).nextInt(destinations.size()));
return PortalHandler.getByName(destination, portalNetwork); return PortalHandler.getByName(Portal.cleanString(destination), portalNetwork);
} else { } else {
//Just return the normal fixed destination //Just return the normal fixed destination
return PortalHandler.getByName(destination, portalNetwork); return PortalHandler.getByName(Portal.cleanString(destination), portalNetwork);
} }
} }
@ -98,7 +98,7 @@ public class PortalActivator {
* @param destination <p>The new destination of this portal activator's portal</p> * @param destination <p>The new destination of this portal activator's portal</p>
*/ */
public void setDestination(Portal destination) { public void setDestination(Portal destination) {
setDestination(destination.getName()); setDestination(destination.getCleanName());
} }
/** /**
@ -136,7 +136,7 @@ public class PortalActivator {
//Set the given player as the active player //Set the given player as the active player
activePlayer = player; activePlayer = player;
String network = portal.getNetwork(); String network = portal.getCleanNetwork();
destinations = PortalHandler.getDestinations(portal, player, network); destinations = PortalHandler.getDestinations(portal, player, network);
//Sort destinations if enabled //Sort destinations if enabled
@ -242,7 +242,7 @@ public class PortalActivator {
activate = true; activate = true;
Stargate.debug("cycleDestination", "Network Size: " + Stargate.debug("cycleDestination", "Network Size: " +
PortalHandler.getNetwork(portal.getNetwork()).size()); PortalHandler.getNetwork(portal.getCleanNetwork()).size());
Stargate.debug("cycleDestination", "Player has access to: " + destinations.size()); Stargate.debug("cycleDestination", "Player has access to: " + destinations.size());
} }

View File

@ -228,7 +228,7 @@ public class PortalCreator {
*/ */
private boolean checkIfNewPortalIsValid(int cost, String portalName) { private boolean checkIfNewPortalIsValid(int cost, String portalName) {
//Check if the portal name can fit on the sign with padding (>name<) //Check if the portal name can fit on the sign with padding (>name<)
if (portal.getName().length() < 1 || portal.getName().length() > 11) { if (portal.getCleanName().length() < 1 || portal.getCleanName().length() > 13) {
Stargate.debug("createPortal", "Name length error"); Stargate.debug("createPortal", "Name length error");
Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("createNameLength")); Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("createNameLength"));
return false; return false;
@ -236,21 +236,21 @@ public class PortalCreator {
if (portal.getOptions().isBungee()) { if (portal.getOptions().isBungee()) {
//Check if the bungee portal's name has been duplicated //Check if the bungee portal's name has been duplicated
if (PortalHandler.getBungeePortals().get(portal.getName().toLowerCase()) != null) { if (PortalHandler.getBungeePortals().get(portal.getCleanName()) != null) {
Stargate.debug("createPortal::Bungee", "Gate name duplicate"); Stargate.debug("createPortal::Bungee", "Gate name duplicate");
Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("createExists")); Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("createExists"));
return false; return false;
} }
} else { } else {
//Check if the portal name has been duplicated on the network //Check if the portal name has been duplicated on the network
if (PortalHandler.getByName(portal.getName(), portal.getNetwork()) != null) { if (PortalHandler.getByName(portal.getCleanName(), portal.getCleanNetwork()) != null) {
Stargate.debug("createPortal", "Gate name duplicate"); Stargate.debug("createPortal", "Gate name duplicate");
Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("createExists")); Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("createExists"));
return false; return false;
} }
//Check if the number of portals in the network has been surpassed //Check if the number of portals in the network has been surpassed
List<String> networkList = PortalHandler.getAllPortalNetworks().get(portal.getNetwork().toLowerCase()); List<String> networkList = PortalHandler.getAllPortalNetworks().get(portal.getCleanNetwork());
int maxGates = Stargate.getGateConfig().maxGatesEachNetwork(); int maxGates = Stargate.getGateConfig().maxGatesEachNetwork();
if (maxGates > 0 && networkList != null && networkList.size() >= maxGates) { if (maxGates > 0 && networkList != null && networkList.size() >= maxGates) {
Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("createFull")); Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("createFull"));
@ -283,7 +283,7 @@ public class PortalCreator {
portal.getPortalOpener().openPortal(true); portal.getPortalOpener().openPortal(true);
} else if (portal.getOptions().isAlwaysOn()) { } else if (portal.getOptions().isAlwaysOn()) {
//For a normal always-on portal, open both the portal and the destination //For a normal always-on portal, open both the portal and the destination
Portal destinationPortal = PortalHandler.getByName(destinationName, portal.getNetwork()); Portal destinationPortal = PortalHandler.getByName(destinationName, portal.getCleanNetwork());
if (destinationPortal != null) { if (destinationPortal != null) {
portal.getPortalOpener().openPortal(true); portal.getPortalOpener().openPortal(true);
destinationPortal.drawSign(); destinationPortal.drawSign();

View File

@ -66,7 +66,7 @@ public class PortalHandler {
*/ */
public static List<String> getDestinations(Portal entrancePortal, Player player, String network) { public static List<String> getDestinations(Portal entrancePortal, Player player, String network) {
List<String> destinations = new ArrayList<>(); List<String> destinations = new ArrayList<>();
for (String destination : PortalRegistry.getAllPortalNetworks().get(network.toLowerCase())) { for (String destination : PortalRegistry.getAllPortalNetworks().get(network)) {
Portal portal = getByName(destination, network); Portal portal = getByName(destination, network);
if (portal == null) { if (portal == null) {
continue; continue;
@ -80,11 +80,12 @@ public class PortalHandler {
continue; continue;
} }
//Check if destination is this portal //Check if destination is this portal
if (destination.equalsIgnoreCase(entrancePortal.getName())) { if (destination.equals(entrancePortal.getCleanName())) {
continue; continue;
} }
//Check if destination is a fixed portal not pointing to this portal //Check if destination is a fixed portal not pointing to this portal
if (portal.getOptions().isFixed() && !portal.getDestinationName().equalsIgnoreCase(entrancePortal.getName())) { if (portal.getOptions().isFixed() &&
!Portal.cleanString(portal.getDestinationName()).equals(entrancePortal.getCleanName())) {
continue; continue;
} }
//Allow random use by non-players (Minecarts) //Allow random use by non-players (Minecarts)
@ -182,10 +183,10 @@ public class PortalHandler {
* @param portal <p>The newly created portal</p> * @param portal <p>The newly created portal</p>
*/ */
static void updatePortalsPointingAtNewPortal(Portal portal) { static void updatePortalsPointingAtNewPortal(Portal portal) {
for (String originName : PortalRegistry.getAllPortalNetworks().get(portal.getNetwork().toLowerCase())) { for (String originName : PortalRegistry.getAllPortalNetworks().get(portal.getCleanNetwork())) {
Portal origin = getByName(originName, portal.getNetwork()); Portal origin = getByName(originName, portal.getCleanNetwork());
if (origin == null || if (origin == null ||
!origin.getDestinationName().equalsIgnoreCase(portal.getName()) || !Portal.cleanString(origin.getDestinationName()).equals(portal.getCleanName()) ||
!origin.getStructure().isVerified()) { !origin.getStructure().isVerified()) {
continue; continue;
} }

View File

@ -126,7 +126,7 @@ public class PortalOpener {
return; return;
} }
boolean thisIsDestination = destination.getDestinationName().equalsIgnoreCase(portal.getName()); boolean thisIsDestination = Portal.cleanString(destination.getDestinationName()).equals(portal.getCleanName());
//Only open destination if it's not-fixed or points at this portal, and is not already open //Only open destination if it's not-fixed or points at this portal, and is not already open
if (!options.isRandom() && (!destination.getOptions().isFixed() || thisIsDestination) && !destination.isOpen()) { if (!options.isRandom() && (!destination.getOptions().isFixed() || thisIsDestination) && !destination.isOpen()) {
//Open the destination portal //Open the destination portal

View File

@ -63,7 +63,7 @@ public class PortalRegistry {
private static void clearPortals(List<Portal> portalsToRemove) { private static void clearPortals(List<Portal> portalsToRemove) {
//Store the names of the portals to remove as some maps require the name, not the object //Store the names of the portals to remove as some maps require the name, not the object
List<String> portalNames = new ArrayList<>(); List<String> portalNames = new ArrayList<>();
portalsToRemove.forEach((portal) -> portalNames.add(portal.getName())); portalsToRemove.forEach((portal) -> portalNames.add(portal.getCleanName()));
//Clear all the lookup locations for the portals //Clear all the lookup locations for the portals
lookupBlocks.keySet().removeIf((key) -> portalsToRemove.contains(lookupBlocks.get(key))); lookupBlocks.keySet().removeIf((key) -> portalsToRemove.contains(lookupBlocks.get(key)));
@ -165,8 +165,8 @@ public class PortalRegistry {
portal.getPortalActivator().deactivate(); portal.getPortalActivator().deactivate();
portal.getPortalOpener().closePortal(true); portal.getPortalOpener().closePortal(true);
String portalName = portal.getName().toLowerCase(); String portalName = portal.getCleanName();
String networkName = portal.getNetwork().toLowerCase(); String networkName = portal.getCleanNetwork();
//Remove portal from lookup blocks //Remove portal from lookup blocks
for (BlockLocation block : portal.getStructure().getFrame()) { for (BlockLocation block : portal.getStructure().getFrame()) {
@ -203,7 +203,7 @@ public class PortalRegistry {
//Update all portals in the same network with this portal as its destination //Update all portals in the same network with this portal as its destination
for (String originName : allPortalNetworks.get(networkName)) { for (String originName : allPortalNetworks.get(networkName)) {
Portal origin = PortalHandler.getByName(originName, portal.getNetwork()); Portal origin = PortalHandler.getByName(originName, portal.getCleanNetwork());
if (origin == null || !origin.getDestinationName().equalsIgnoreCase(portalName) || if (origin == null || !origin.getDestinationName().equalsIgnoreCase(portalName) ||
!origin.getStructure().isVerified()) { !origin.getStructure().isVerified()) {
continue; continue;
@ -235,8 +235,8 @@ public class PortalRegistry {
portal.getOptions().setFixed(portal.getDestinationName().length() > 0 || portal.getOptions().isRandom() || portal.getOptions().setFixed(portal.getDestinationName().length() > 0 || portal.getOptions().isRandom() ||
portal.getOptions().isBungee()); portal.getOptions().isBungee());
String portalName = portal.getName().toLowerCase(); String portalName = portal.getCleanName();
String networkName = portal.getNetwork().toLowerCase(); String networkName = portal.getCleanNetwork();
//Bungee portals are stored in their own list //Bungee portals are stored in their own list
if (portal.getOptions().isBungee()) { if (portal.getOptions().isBungee()) {

View File

@ -4,6 +4,7 @@ import net.knarcraft.stargate.Stargate;
import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.Portal;
import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.portal.PortalHandler;
import net.knarcraft.stargate.portal.teleporter.PlayerTeleporter; import net.knarcraft.stargate.portal.teleporter.PlayerTeleporter;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerMoveEvent;
@ -71,7 +72,7 @@ public final class BungeeHelper {
//Build the message data and send it over the SGBungee BungeeCord channel //Build the message data and send it over the SGBungee BungeeCord channel
dataOutputStream.writeUTF("Forward"); dataOutputStream.writeUTF("Forward");
//Send the message to the server defined in the entrance portal's network line //Send the message to the server defined in the entrance portal's network line
dataOutputStream.writeUTF(entrancePortal.getNetwork()); dataOutputStream.writeUTF(stripColor(entrancePortal.getNetwork()));
//Specify the sub-channel/tag to make it recognizable on arrival //Specify the sub-channel/tag to make it recognizable on arrival
dataOutputStream.writeUTF(bungeeSubChannel); dataOutputStream.writeUTF(bungeeSubChannel);
//Write the length of the message //Write the length of the message
@ -102,7 +103,7 @@ public final class BungeeHelper {
//Send a connect-message to connect the player to the server defined in the entrance portal's network line //Send a connect-message to connect the player to the server defined in the entrance portal's network line
dataOutputStream.writeUTF("Connect"); dataOutputStream.writeUTF("Connect");
dataOutputStream.writeUTF(entrancePortal.getNetwork()); dataOutputStream.writeUTF(stripColor(entrancePortal.getNetwork()));
//Send the plugin message //Send the plugin message
player.sendPluginMessage(Stargate.getInstance(), bungeeChannel, byteArrayOutputStream.toByteArray()); player.sendPluginMessage(Stargate.getInstance(), bungeeChannel, byteArrayOutputStream.toByteArray());
@ -207,4 +208,14 @@ public final class BungeeHelper {
return true; return true;
} }
/**
* Strips all color tags from a string
*
* @param string <p>The string to strip color from</p>
* @return <p>The string without color codes</p>
*/
private static String stripColor(String string) {
return ChatColor.stripColor(ChatColor.translateAlternateColorCodes('&', string));
}
} }

View File

@ -105,12 +105,12 @@ public final class PermissionHelper {
boolean deny = false; boolean deny = false;
if (entrancePortal.getOptions().isBungee()) { if (entrancePortal.getOptions().isBungee()) {
if (!PermissionHelper.canAccessServer(player, entrancePortal.getNetwork())) { if (!PermissionHelper.canAccessServer(player, entrancePortal.getCleanNetwork())) {
//If the portal is a bungee portal, and the player cannot access the server, deny //If the portal is a bungee portal, and the player cannot access the server, deny
Stargate.debug("cannotAccessPortal", "Cannot access server"); Stargate.debug("cannotAccessPortal", "Cannot access server");
deny = true; deny = true;
} }
} else if (PermissionHelper.cannotAccessNetwork(player, entrancePortal.getNetwork())) { } else if (PermissionHelper.cannotAccessNetwork(player, entrancePortal.getCleanNetwork())) {
//If the player does not have access to the network, deny //If the player does not have access to the network, deny
Stargate.debug("cannotAccessPortal", "Cannot access network"); Stargate.debug("cannotAccessPortal", "Cannot access network");
deny = true; deny = true;
@ -345,7 +345,7 @@ public final class PermissionHelper {
* @return <p>True if the player is allowed to destroy the portal</p> * @return <p>True if the player is allowed to destroy the portal</p>
*/ */
public static boolean canDestroyPortal(Player player, Portal portal) { public static boolean canDestroyPortal(Player player, Portal portal) {
String network = portal.getNetwork(); String network = portal.getCleanNetwork();
//Use a special check for bungee portals //Use a special check for bungee portals
if (portal.getOptions().isBungee()) { if (portal.getOptions().isBungee()) {

View File

@ -22,7 +22,7 @@ import java.util.UUID;
public final class UUIDMigrationHelper { public final class UUIDMigrationHelper {
private UUIDMigrationHelper() { private UUIDMigrationHelper() {
} }
private static Map<String, List<Portal>> playerNamesToMigrate; private static Map<String, List<Portal>> playerNamesToMigrate;
@ -68,7 +68,7 @@ public final class UUIDMigrationHelper {
//Get the real portal from the copy and set UUID //Get the real portal from the copy and set UUID
for (Portal portalCopy : portals) { for (Portal portalCopy : portals) {
Portal portal = PortalHandler.getByName(portalCopy.getName(), portalCopy.getNetwork()); Portal portal = PortalHandler.getByName(portalCopy.getCleanName(), portalCopy.getCleanNetwork());
if (portal != null) { if (portal != null) {
portal.getOwner().setUUID(uniqueId); portal.getOwner().setUUID(uniqueId);
worldsToSave.add(portal.getWorld()); worldsToSave.add(portal.getWorld());