From 366bd7ff79202eb162e36d16b25589809c25c6b9 Mon Sep 17 00:00:00 2001 From: Jeremy Wood Date: Thu, 8 Oct 2020 02:41:48 -0400 Subject: [PATCH 01/53] Kick off the new base branch. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6b7ee34..9812bfa 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,4 @@ Copyright (c) 2011, The Multiverse Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the The Multiverse Team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file +Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the The Multiverse Team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. From 1a22ae9b257f080856a63ba34f99803028e20424 Mon Sep 17 00:00:00 2001 From: Kermina Awad Date: Thu, 8 Oct 2020 02:44:08 -0400 Subject: [PATCH 02/53] add missing condition needed for world links to function --- .../listeners/MVNPEntityListener.java | 44 ++++++++++--------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java index 874c86e..479b207 100644 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java @@ -140,29 +140,33 @@ private Location getLocation(Entity e, Location currentLocation, PortalType type Location newTo = null; if (!currentWorld.equalsIgnoreCase(linkedWorld)) { - String destinationWorld = ""; - - if (this.nameChecker.isValidEndName(currentWorld)) { - if (type == PortalType.ENDER) { - destinationWorld = this.nameChecker.getNormalName(currentWorld, type); - } else if (type == PortalType.NETHER) { - destinationWorld = this.nameChecker.getNetherName(this.nameChecker.getNormalName(currentWorld, type)); - } - } else if (this.nameChecker.isValidNetherName(currentWorld)) { - if (type == PortalType.ENDER) { - destinationWorld = this.nameChecker.getEndName(this.nameChecker.getNormalName(currentWorld, type)); - } else if (type == PortalType.NETHER) { - destinationWorld = this.nameChecker.getNormalName(currentWorld, type); - } + if (linkedWorld != null) { + newTo = this.linkChecker.findNewTeleportLocation(currentLocation, linkedWorld, e); } else { - if (type == PortalType.ENDER) { - destinationWorld = this.nameChecker.getEndName(currentWorld); - } else if (type == PortalType.NETHER) { - destinationWorld = this.nameChecker.getNetherName(currentWorld); + String destinationWorld = ""; + + if (this.nameChecker.isValidEndName(currentWorld)) { + if (type == PortalType.ENDER) { + destinationWorld = this.nameChecker.getNormalName(currentWorld, type); + } else if (type == PortalType.NETHER) { + destinationWorld = this.nameChecker.getNetherName(this.nameChecker.getNormalName(currentWorld, type)); + } + } else if (this.nameChecker.isValidNetherName(currentWorld)) { + if (type == PortalType.ENDER) { + destinationWorld = this.nameChecker.getEndName(this.nameChecker.getNormalName(currentWorld, type)); + } else if (type == PortalType.NETHER) { + destinationWorld = this.nameChecker.getNormalName(currentWorld, type); + } + } else { + if (type == PortalType.ENDER) { + destinationWorld = this.nameChecker.getEndName(currentWorld); + } else if (type == PortalType.NETHER) { + destinationWorld = this.nameChecker.getNetherName(currentWorld); + } } - } - newTo = this.linkChecker.findNewTeleportLocation(currentLocation, destinationWorld, e); + newTo = this.linkChecker.findNewTeleportLocation(currentLocation, destinationWorld, e); + } } return newTo; From c39560db5cc7a521ea39a35a3a8f8c67d127b0c7 Mon Sep 17 00:00:00 2001 From: Jeremy Wood Date: Thu, 8 Oct 2020 02:52:04 -0400 Subject: [PATCH 03/53] Release version 4.2.1. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3140b23..96cb299 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.onarandombox.multiversenetherportals Multiverse-NetherPortals - 4.2.1-SNAPSHOT + 4.2.1 Multiverse-NetherPortals Multiverse Nether Portals module From e0f5cbe4c89b9f872636f867dee50e9a565dff0e Mon Sep 17 00:00:00 2001 From: Jeremy Wood Date: Thu, 8 Oct 2020 02:53:16 -0400 Subject: [PATCH 04/53] Bump version to 4.2.2-SNAPSHOT for continued development. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 96cb299..ba56add 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.onarandombox.multiversenetherportals Multiverse-NetherPortals - 4.2.1 + 4.2.2-SNAPSHOT Multiverse-NetherPortals Multiverse Nether Portals module From e96117cb89b69cce359ca145bcd00eb1ed8c9f3a Mon Sep 17 00:00:00 2001 From: Ben Woo <30431861+benwoo1110@users.noreply.github.com> Date: Tue, 27 Oct 2020 23:58:19 +0800 Subject: [PATCH 05/53] Update issue template to use paste.gg (#196) * Update issue template to use paste.gg * Update to show paste.gg as link --- .github/ISSUE_TEMPLATE/help.md | 2 +- .github/ISSUE_TEMPLATE/report-a-bug.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/help.md b/.github/ISSUE_TEMPLATE/help.md index 96ddaec..9e32bb1 100644 --- a/.github/ISSUE_TEMPLATE/help.md +++ b/.github/ISSUE_TEMPLATE/help.md @@ -40,7 +40,7 @@ If you're happy to wait (or you were sent here from Discord), read on: * **Server version:** -* **Full output of `/mv version -b`:** +* **Full output of `/mv version -p`:** * **Server log:** diff --git a/.github/ISSUE_TEMPLATE/report-a-bug.md b/.github/ISSUE_TEMPLATE/report-a-bug.md index e4e6cb3..a1b6abd 100644 --- a/.github/ISSUE_TEMPLATE/report-a-bug.md +++ b/.github/ISSUE_TEMPLATE/report-a-bug.md @@ -39,7 +39,7 @@ If you are reporting a bug, please follow the following steps: * **Server version:** -* **Full output of `/mv version -b`:** +* **Full output of `/mv version -p`:** * **Server log:** From fe48a8768ad928f716ddd781db42ad1573a15eef Mon Sep 17 00:00:00 2001 From: benwoo1110 <30431861+benwoo1110@users.noreply.github.com> Date: Thu, 10 Dec 2020 11:21:26 +0800 Subject: [PATCH 06/53] Add allow nether and end to version dump. --- .../MultiverseNetherPortals/MultiverseNetherPortals.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/MultiverseNetherPortals.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/MultiverseNetherPortals.java index 4337e67..662e329 100644 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/MultiverseNetherPortals.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/MultiverseNetherPortals.java @@ -374,6 +374,8 @@ public String getVersionInfo() { + "[Multiverse-NetherPortals] Teleport Entities: " + this.isTeleportingEntities() + '\n' + "[Multiverse-NetherPortals] Send Disabled Portal Message: " + this.isSendingDisabledPortalMessage() + '\n' + "[Multiverse-NetherPortals] Send No Destination Message: " + this.isSendingNoDestinationMessage() + '\n' + + "[Multiverse-NetherPortals] Server Allow Nether: " + this.getServer().getAllowNether() + '\n' + + "[Multiverse-NetherPortals] Server Allow End: " + this.getServer().getAllowEnd() + '\n' + "[Multiverse-NetherPortals] Special Code: " + "FRN001" + '\n'; } } From 2598005da6eb00a3484b4f308c6ce0a895ba1180 Mon Sep 17 00:00:00 2001 From: benwoo1110 <30431861+benwoo1110@users.noreply.github.com> Date: Fri, 11 Dec 2020 10:11:42 +0800 Subject: [PATCH 07/53] Fix end links not working after restart. --- .../MultiverseNetherPortals.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/MultiverseNetherPortals.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/MultiverseNetherPortals.java index 4337e67..f07bcf1 100644 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/MultiverseNetherPortals.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/MultiverseNetherPortals.java @@ -126,8 +126,8 @@ public void loadConfig() { Set worldKeys = this.MVNPconfiguration.getConfigurationSection("worlds").getKeys(false); if (worldKeys != null) { for (String worldString : worldKeys) { - String nether = this.MVNPconfiguration.getString("worlds." + worldString + ".portalgoesto.NETHER", null); - String ender = this.MVNPconfiguration.getString("worlds." + worldString + ".portalgoesto.END", null); + String nether = this.MVNPconfiguration.getString("worlds." + worldString + ".portalgoesto." + PortalType.NETHER, null); + String ender = this.MVNPconfiguration.getString("worlds." + worldString + ".portalgoesto." + PortalType.ENDER, null); if (nether != null) { this.linkMap.put(worldString, nether); } @@ -135,6 +135,17 @@ public void loadConfig() { this.endLinkMap.put(worldString, ender); } + // Convert from old version enum which used END not ENDER + String oldEnder = this.MVNPconfiguration.getString("worlds." + worldString + ".portalgoesto.END", null); + if (oldEnder != null) { + if (this.addWorldLink(worldString, oldEnder, PortalType.ENDER)) { + this.MVNPconfiguration.set("worlds." + worldString + ".portalgoesto.END", null); + } + else { + Logging.warning("Error converting old end link of '%s' to '%s'", worldString, oldEnder); + } + } + } } this.saveMVNPConfig(); From daa76bab23c4986029feb2b8df0a5ceca99d7a3e Mon Sep 17 00:00:00 2001 From: benwoo1110 <30431861+benwoo1110@users.noreply.github.com> Date: Fri, 11 Dec 2020 18:47:18 +0800 Subject: [PATCH 08/53] Add config values for prefix and suffix for nether and end. --- .../MultiverseNetherPortals.java | 90 ++++++++++--------- 1 file changed, 48 insertions(+), 42 deletions(-) diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/MultiverseNetherPortals.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/MultiverseNetherPortals.java index 662e329..f232b21 100644 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/MultiverseNetherPortals.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/MultiverseNetherPortals.java @@ -35,23 +35,22 @@ public class MultiverseNetherPortals extends JavaPlugin implements MVPlugin { - private static final String NETEHR_PORTALS_CONFIG = "config.yml"; + private static final String NETHER_PORTALS_CONFIG = "config.yml"; + private static final String DEFAULT_NETHER_PREFIX = ""; + private static final String DEFAULT_NETHER_SUFFIX = "_nether"; + private static final String DEFAULT_END_PREFIX = ""; + private static final String DEFAULT_END_SUFFIX = "_the_end"; + private final static int requiresProtocol = 24; + protected MultiverseCore core; protected Plugin multiversePortals; protected MVNPPluginListener pluginListener; protected MVNPPlayerListener playerListener; protected MVNPCoreListener customListener; - protected FileConfiguration MVNPconfiguration; - private static final String DEFAULT_NETHER_SUFFIX = "_nether"; - private static final String DEFAULT_END_SUFFIX = "_the_end"; - private String netherPrefix = ""; - private String netherSuffix = DEFAULT_NETHER_SUFFIX; - private String endPrefix = ""; - private String endSuffix = DEFAULT_END_SUFFIX; + protected FileConfiguration MVNPConfiguration; private Map linkMap; private Map endLinkMap; protected CommandHandler commandHandler; - private final static int requiresProtocol = 24; private MVNPEntityListener entityListener; @Override @@ -98,13 +97,13 @@ public void onEnable() { } public void loadConfig() { - this.MVNPconfiguration = new YamlConfiguration(); + this.MVNPConfiguration = new YamlConfiguration(); try { - this.MVNPconfiguration.load(new File(this.getDataFolder(), NETEHR_PORTALS_CONFIG)); + this.MVNPConfiguration.load(new File(this.getDataFolder(), NETHER_PORTALS_CONFIG)); } catch (IOException e) { - this.log(Level.SEVERE, "Could not load " + NETEHR_PORTALS_CONFIG); + this.log(Level.SEVERE, "Could not load " + NETHER_PORTALS_CONFIG); } catch (InvalidConfigurationException e) { - this.log(Level.SEVERE, NETEHR_PORTALS_CONFIG + " contained INVALID YAML. Please look at the file."); + this.log(Level.SEVERE, NETHER_PORTALS_CONFIG + " contained INVALID YAML. Please look at the file."); } this.linkMap = new HashMap(); this.endLinkMap = new HashMap(); @@ -113,21 +112,20 @@ public void loadConfig() { this.setTeleportingEntities(this.isTeleportingEntities()); this.setSendingNoDestinationMessage(this.isSendingNoDestinationMessage()); this.setSendingDisabledPortalMessage(this.isSendingDisabledPortalMessage()); - this.setNetherPrefix(this.MVNPconfiguration.getString("netherportals.name.prefix", this.getNetherPrefix())); - this.setNetherSuffix(this.MVNPconfiguration.getString("netherportals.name.suffix", this.getNetherSuffix())); - if (this.getNetherPrefix().length() == 0 && this.getNetherSuffix().length() == 0) { - Logging.warning("I didn't find a prefix OR a suffix defined! I made the suffix \"" + DEFAULT_NETHER_SUFFIX + "\" for you."); - this.setNetherSuffix(this.MVNPconfiguration.getString("netherportals.name.suffix", this.getNetherSuffix())); - } - if (this.MVNPconfiguration.getConfigurationSection("worlds") == null) { - this.MVNPconfiguration.createSection("worlds"); + this.setNetherPrefix(this.getNetherPrefix()); + this.setNetherSuffix(this.getNetherSuffix()); + this.setEndPrefix(this.getEndPrefix()); + this.setEndSuffix(this.getEndSuffix()); + + if (this.MVNPConfiguration.getConfigurationSection("worlds") == null) { + this.MVNPConfiguration.createSection("worlds"); } - Set worldKeys = this.MVNPconfiguration.getConfigurationSection("worlds").getKeys(false); + Set worldKeys = this.MVNPConfiguration.getConfigurationSection("worlds").getKeys(false); if (worldKeys != null) { for (String worldString : worldKeys) { - String nether = this.MVNPconfiguration.getString("worlds." + worldString + ".portalgoesto.NETHER", null); - String ender = this.MVNPconfiguration.getString("worlds." + worldString + ".portalgoesto.END", null); + String nether = this.MVNPConfiguration.getString("worlds." + worldString + ".portalgoesto.NETHER", null); + String ender = this.MVNPConfiguration.getString("worlds." + worldString + ".portalgoesto.END", null); if (nether != null) { this.linkMap.put(worldString, nether); } @@ -187,27 +185,35 @@ private String getAuthors() { } public void setNetherPrefix(String netherPrefix) { - this.netherPrefix = netherPrefix; + this.MVNPConfiguration.set("portal-auto-link-when.nether.prefix", netherPrefix); } public String getNetherPrefix() { - return this.netherPrefix; + return this.MVNPConfiguration.getString("portal-auto-link-when.nether.prefix", DEFAULT_NETHER_PREFIX); } public void setNetherSuffix(String netherSuffix) { - this.netherSuffix = netherSuffix; + this.MVNPConfiguration.set("portal-auto-link-when.nether.suffix", netherSuffix); } public String getNetherSuffix() { - return this.netherSuffix; + return this.MVNPConfiguration.getString("portal-auto-link-when.nether.suffix", DEFAULT_NETHER_SUFFIX); + } + + public void setEndPrefix(String endPrefix) { + this.MVNPConfiguration.set("portal-auto-link-when.end.prefix", endPrefix); } public String getEndPrefix() { - return this.endPrefix; + return this.MVNPConfiguration.getString("portal-auto-link-when.end.prefix", DEFAULT_END_PREFIX); + } + + public void setEndSuffix(String endSuffix) { + this.MVNPConfiguration.set("portal-auto-link-when.end.suffix", endSuffix); } public String getEndSuffix() { - return this.endSuffix; + return this.MVNPConfiguration.getString("portal-auto-link-when.end.suffix", DEFAULT_END_SUFFIX); } public String getWorldLink(String fromWorld, PortalType type) { @@ -237,7 +243,7 @@ public boolean addWorldLink(String from, String to, PortalType type) { return false; } - this.MVNPconfiguration.set("worlds." + from + ".portalgoesto." + type, to); + this.MVNPConfiguration.set("worlds." + from + ".portalgoesto." + type, to); this.saveMVNPConfig(); return true; } @@ -251,50 +257,50 @@ public void removeWorldLink(String from, String to, PortalType type) { return; } - this.MVNPconfiguration.set("worlds." + from + ".portalgoesto." + type, null); + this.MVNPConfiguration.set("worlds." + from + ".portalgoesto." + type, null); this.saveMVNPConfig(); } public boolean saveMVNPConfig() { try { - this.MVNPconfiguration.save(new File(this.getDataFolder(), NETEHR_PORTALS_CONFIG)); + this.MVNPConfiguration.save(new File(this.getDataFolder(), NETHER_PORTALS_CONFIG)); return true; } catch (IOException e) { - this.log(Level.SEVERE, "Could not save " + NETEHR_PORTALS_CONFIG); + this.log(Level.SEVERE, "Could not save " + NETHER_PORTALS_CONFIG); } return false; } public boolean isUsingBounceBack() { - return this.MVNPconfiguration.getBoolean("bounceback", true); + return this.MVNPConfiguration.getBoolean("bounceback", true); } public void setUsingBounceBack(boolean useBounceBack) { - this.MVNPconfiguration.set("bounceback", useBounceBack); + this.MVNPConfiguration.set("bounceback", useBounceBack); } public boolean isTeleportingEntities() { - return this.MVNPconfiguration.getBoolean("teleport_entities", true); + return this.MVNPConfiguration.getBoolean("teleport_entities", true); } public void setTeleportingEntities(boolean teleportingEntities) { - this.MVNPconfiguration.set("teleport_entities", teleportingEntities); + this.MVNPConfiguration.set("teleport_entities", teleportingEntities); } public boolean isSendingDisabledPortalMessage() { - return this.MVNPconfiguration.getBoolean("send_disabled_portal_message", true); + return this.MVNPConfiguration.getBoolean("send_disabled_portal_message", true); } public void setSendingDisabledPortalMessage(boolean sendDisabledPortalMessage) { - this.MVNPconfiguration.set("send_disabled_portal_message", sendDisabledPortalMessage); + this.MVNPConfiguration.set("send_disabled_portal_message", sendDisabledPortalMessage); } public boolean isSendingNoDestinationMessage() { - return this.MVNPconfiguration.getBoolean("send_no_destination_message", true); + return this.MVNPConfiguration.getBoolean("send_no_destination_message", true); } public void setSendingNoDestinationMessage(boolean sendNoDestinationMessage) { - this.MVNPconfiguration.set("send_no_destination_message", sendNoDestinationMessage); + this.MVNPConfiguration.set("send_no_destination_message", sendNoDestinationMessage); } public boolean isHandledByNetherPortals(Location l) { From 453751a5ef741040b849abafc3d8f028c192259b Mon Sep 17 00:00:00 2001 From: Ben Woo <30431861+benwoo1110@users.noreply.github.com> Date: Sat, 12 Dec 2020 00:09:57 +0800 Subject: [PATCH 09/53] Fix some code typos. (#206) --- .../MultiverseNetherPortals.java | 49 ++++++++++--------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/MultiverseNetherPortals.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/MultiverseNetherPortals.java index 46f6cb7..a821223 100644 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/MultiverseNetherPortals.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/MultiverseNetherPortals.java @@ -35,13 +35,13 @@ public class MultiverseNetherPortals extends JavaPlugin implements MVPlugin { - private static final String NETEHR_PORTALS_CONFIG = "config.yml"; + private static final String NETHER_PORTALS_CONFIG = "config.yml"; protected MultiverseCore core; protected Plugin multiversePortals; protected MVNPPluginListener pluginListener; protected MVNPPlayerListener playerListener; protected MVNPCoreListener customListener; - protected FileConfiguration MVNPconfiguration; + protected FileConfiguration MVNPConfiguration; private static final String DEFAULT_NETHER_SUFFIX = "_nether"; private static final String DEFAULT_END_SUFFIX = "_the_end"; private String netherPrefix = ""; @@ -98,13 +98,13 @@ public void onEnable() { } public void loadConfig() { - this.MVNPconfiguration = new YamlConfiguration(); + this.MVNPConfiguration = new YamlConfiguration(); try { - this.MVNPconfiguration.load(new File(this.getDataFolder(), NETEHR_PORTALS_CONFIG)); + this.MVNPConfiguration.load(new File(this.getDataFolder(), NETHER_PORTALS_CONFIG)); } catch (IOException e) { - this.log(Level.SEVERE, "Could not load " + NETEHR_PORTALS_CONFIG); + this.log(Level.SEVERE, "Could not load " + NETHER_PORTALS_CONFIG); } catch (InvalidConfigurationException e) { - this.log(Level.SEVERE, NETEHR_PORTALS_CONFIG + " contained INVALID YAML. Please look at the file."); + this.log(Level.SEVERE, NETHER_PORTALS_CONFIG + " contained INVALID YAML. Please look at the file."); } this.linkMap = new HashMap(); this.endLinkMap = new HashMap(); @@ -113,21 +113,22 @@ public void loadConfig() { this.setTeleportingEntities(this.isTeleportingEntities()); this.setSendingNoDestinationMessage(this.isSendingNoDestinationMessage()); this.setSendingDisabledPortalMessage(this.isSendingDisabledPortalMessage()); - this.setNetherPrefix(this.MVNPconfiguration.getString("netherportals.name.prefix", this.getNetherPrefix())); - this.setNetherSuffix(this.MVNPconfiguration.getString("netherportals.name.suffix", this.getNetherSuffix())); + this.setNetherPrefix(this.MVNPConfiguration.getString("netherportals.name.prefix", this.getNetherPrefix())); + this.setNetherSuffix(this.MVNPConfiguration.getString("netherportals.name.suffix", this.getNetherSuffix())); if (this.getNetherPrefix().length() == 0 && this.getNetherSuffix().length() == 0) { Logging.warning("I didn't find a prefix OR a suffix defined! I made the suffix \"" + DEFAULT_NETHER_SUFFIX + "\" for you."); - this.setNetherSuffix(this.MVNPconfiguration.getString("netherportals.name.suffix", this.getNetherSuffix())); + this.setNetherSuffix(this.MVNPConfiguration.getString("netherportals.name.suffix", this.getNetherSuffix())); } - if (this.MVNPconfiguration.getConfigurationSection("worlds") == null) { - this.MVNPconfiguration.createSection("worlds"); + if (this.MVNPConfiguration.getConfigurationSection("worlds") == null) { + this.MVNPConfiguration.createSection("worlds"); } - Set worldKeys = this.MVNPconfiguration.getConfigurationSection("worlds").getKeys(false); + Set worldKeys = this.MVNPConfiguration.getConfigurationSection("worlds").getKeys(false); if (worldKeys != null) { for (String worldString : worldKeys) { String nether = this.MVNPconfiguration.getString("worlds." + worldString + ".portalgoesto." + PortalType.NETHER, null); String ender = this.MVNPconfiguration.getString("worlds." + worldString + ".portalgoesto." + PortalType.ENDER, null); + if (nether != null) { this.linkMap.put(worldString, nether); } @@ -248,7 +249,7 @@ public boolean addWorldLink(String from, String to, PortalType type) { return false; } - this.MVNPconfiguration.set("worlds." + from + ".portalgoesto." + type, to); + this.MVNPConfiguration.set("worlds." + from + ".portalgoesto." + type, to); this.saveMVNPConfig(); return true; } @@ -262,50 +263,50 @@ public void removeWorldLink(String from, String to, PortalType type) { return; } - this.MVNPconfiguration.set("worlds." + from + ".portalgoesto." + type, null); + this.MVNPConfiguration.set("worlds." + from + ".portalgoesto." + type, null); this.saveMVNPConfig(); } public boolean saveMVNPConfig() { try { - this.MVNPconfiguration.save(new File(this.getDataFolder(), NETEHR_PORTALS_CONFIG)); + this.MVNPConfiguration.save(new File(this.getDataFolder(), NETHER_PORTALS_CONFIG)); return true; } catch (IOException e) { - this.log(Level.SEVERE, "Could not save " + NETEHR_PORTALS_CONFIG); + this.log(Level.SEVERE, "Could not save " + NETHER_PORTALS_CONFIG); } return false; } public boolean isUsingBounceBack() { - return this.MVNPconfiguration.getBoolean("bounceback", true); + return this.MVNPConfiguration.getBoolean("bounceback", true); } public void setUsingBounceBack(boolean useBounceBack) { - this.MVNPconfiguration.set("bounceback", useBounceBack); + this.MVNPConfiguration.set("bounceback", useBounceBack); } public boolean isTeleportingEntities() { - return this.MVNPconfiguration.getBoolean("teleport_entities", true); + return this.MVNPConfiguration.getBoolean("teleport_entities", true); } public void setTeleportingEntities(boolean teleportingEntities) { - this.MVNPconfiguration.set("teleport_entities", teleportingEntities); + this.MVNPConfiguration.set("teleport_entities", teleportingEntities); } public boolean isSendingDisabledPortalMessage() { - return this.MVNPconfiguration.getBoolean("send_disabled_portal_message", true); + return this.MVNPConfiguration.getBoolean("send_disabled_portal_message", true); } public void setSendingDisabledPortalMessage(boolean sendDisabledPortalMessage) { - this.MVNPconfiguration.set("send_disabled_portal_message", sendDisabledPortalMessage); + this.MVNPConfiguration.set("send_disabled_portal_message", sendDisabledPortalMessage); } public boolean isSendingNoDestinationMessage() { - return this.MVNPconfiguration.getBoolean("send_no_destination_message", true); + return this.MVNPConfiguration.getBoolean("send_no_destination_message", true); } public void setSendingNoDestinationMessage(boolean sendNoDestinationMessage) { - this.MVNPconfiguration.set("send_no_destination_message", sendNoDestinationMessage); + this.MVNPConfiguration.set("send_no_destination_message", sendNoDestinationMessage); } public boolean isHandledByNetherPortals(Location l) { From 9246b6944da1200dd8789ac1b217770506c5ae48 Mon Sep 17 00:00:00 2001 From: benwoo1110 <30431861+benwoo1110@users.noreply.github.com> Date: Sat, 12 Dec 2020 00:20:16 +0800 Subject: [PATCH 10/53] Fix some code typos. (again) --- .../MultiverseNetherPortals/MultiverseNetherPortals.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/MultiverseNetherPortals.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/MultiverseNetherPortals.java index a821223..6e8cf84 100644 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/MultiverseNetherPortals.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/MultiverseNetherPortals.java @@ -126,8 +126,8 @@ public void loadConfig() { Set worldKeys = this.MVNPConfiguration.getConfigurationSection("worlds").getKeys(false); if (worldKeys != null) { for (String worldString : worldKeys) { - String nether = this.MVNPconfiguration.getString("worlds." + worldString + ".portalgoesto." + PortalType.NETHER, null); - String ender = this.MVNPconfiguration.getString("worlds." + worldString + ".portalgoesto." + PortalType.ENDER, null); + String nether = this.MVNPConfiguration.getString("worlds." + worldString + ".portalgoesto." + PortalType.NETHER, null); + String ender = this.MVNPConfiguration.getString("worlds." + worldString + ".portalgoesto." + PortalType.ENDER, null); if (nether != null) { this.linkMap.put(worldString, nether); @@ -137,10 +137,10 @@ public void loadConfig() { } // Convert from old version enum which used END not ENDER - String oldEnder = this.MVNPconfiguration.getString("worlds." + worldString + ".portalgoesto.END", null); + String oldEnder = this.MVNPConfiguration.getString("worlds." + worldString + ".portalgoesto.END", null); if (oldEnder != null) { if (this.addWorldLink(worldString, oldEnder, PortalType.ENDER)) { - this.MVNPconfiguration.set("worlds." + worldString + ".portalgoesto.END", null); + this.MVNPConfiguration.set("worlds." + worldString + ".portalgoesto.END", null); } else { Logging.warning("Error converting old end link of '%s' to '%s'", worldString, oldEnder); From 4b83adeffc10cbd2b58dd1b4dc6325096b15b861 Mon Sep 17 00:00:00 2001 From: Kermina Awad Date: Fri, 11 Dec 2020 13:18:19 -0500 Subject: [PATCH 11/53] add .travis.yml --- .travis.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..2e7dbb3 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,6 @@ +language: java +jdk: + - oraclejdk8 +notifications: + email: false +dist: trusty From 0d14271531050f5f18b57fc13c62c2a7e503b815 Mon Sep 17 00:00:00 2001 From: benwoo1110 <30431861+benwoo1110@users.noreply.github.com> Date: Sat, 12 Dec 2020 17:08:23 +0800 Subject: [PATCH 12/53] Create config file if not present. --- .../MultiverseNetherPortals.java | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/MultiverseNetherPortals.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/MultiverseNetherPortals.java index 6e8cf84..5f49f40 100644 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/MultiverseNetherPortals.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/MultiverseNetherPortals.java @@ -98,14 +98,8 @@ public void onEnable() { } public void loadConfig() { - this.MVNPConfiguration = new YamlConfiguration(); - try { - this.MVNPConfiguration.load(new File(this.getDataFolder(), NETHER_PORTALS_CONFIG)); - } catch (IOException e) { - this.log(Level.SEVERE, "Could not load " + NETHER_PORTALS_CONFIG); - } catch (InvalidConfigurationException e) { - this.log(Level.SEVERE, NETHER_PORTALS_CONFIG + " contained INVALID YAML. Please look at the file."); - } + initMVNPConfig(); + this.linkMap = new HashMap(); this.endLinkMap = new HashMap(); @@ -152,6 +146,24 @@ public void loadConfig() { this.saveMVNPConfig(); } + private void initMVNPConfig() { + this.MVNPConfiguration = new YamlConfiguration(); + try { + File configFile = new File(this.getDataFolder(), NETHER_PORTALS_CONFIG); + if (!configFile.isFile()) { + Logging.info("Creating new %s", NETHER_PORTALS_CONFIG); + configFile.createNewFile(); + } + this.MVNPConfiguration.load(configFile); + } + catch (IOException e) { + this.log(Level.SEVERE, "Could not load " + NETHER_PORTALS_CONFIG); + } + catch (InvalidConfigurationException e) { + this.log(Level.SEVERE, NETHER_PORTALS_CONFIG + " contained INVALID YAML. Please look at the file."); + } + } + /** Register commands to Multiverse's CommandHandler so we get a super sexy single menu */ private void registerCommands() { this.commandHandler = this.core.getCommandHandler(); From 2dde5f06c97df4f0afe89a85bb29c5dd2e9e4d1a Mon Sep 17 00:00:00 2001 From: benwoo1110 <30431861+benwoo1110@users.noreply.github.com> Date: Mon, 14 Dec 2020 09:50:54 +0800 Subject: [PATCH 13/53] Change tab to spaces in MVNameChecker class. --- .../utils/MVNameChecker.java | 108 +++++++++--------- 1 file changed, 53 insertions(+), 55 deletions(-) diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/MVNameChecker.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/MVNameChecker.java index 2dbf61a..4ee3c1c 100644 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/MVNameChecker.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/MVNameChecker.java @@ -3,29 +3,27 @@ import com.onarandombox.MultiverseNetherPortals.MultiverseNetherPortals; import org.bukkit.PortalType; -import java.util.logging.Level; - public class MVNameChecker { - private MultiverseNetherPortals plugin; + private MultiverseNetherPortals plugin; - public MVNameChecker(MultiverseNetherPortals plugin) { - this.plugin = plugin; - } - /** - * Returns true if the world meets the naming criteria for a nether world. It is NOT checked against the actual worlds here! - * - * @param world The world name to check - * @return True if the world has the correct - */ - public boolean isValidNetherName(String world) { - try { - if (world.matches("^" + this.plugin.getNetherPrefix() + ".+" + this.plugin.getNetherSuffix() + "$")) { - return true; - } - } catch (IndexOutOfBoundsException e) { - } - return false; - } + public MVNameChecker(MultiverseNetherPortals plugin) { + this.plugin = plugin; + } + /** + * Returns true if the world meets the naming criteria for a nether world. It is NOT checked against the actual worlds here! + * + * @param world The world name to check + * @return True if the world has the correct + */ + public boolean isValidNetherName(String world) { + try { + if (world.matches("^" + this.plugin.getNetherPrefix() + ".+" + this.plugin.getNetherSuffix() + "$")) { + return true; + } + } catch (IndexOutOfBoundsException e) { + } + return false; + } /** * Returns true if the world meets the naming criteria for an end world. It is NOT checked against the actual worlds here! @@ -42,44 +40,44 @@ public boolean isValidEndName(String world) { } return false; } - - /** - * Takes a given normal name and adds the nether prefix and suffix onto it! - * - * @param normalName - * @return - */ - public String getNetherName(String normalName) { + + /** + * Takes a given normal name and adds the nether prefix and suffix onto it! + * + * @param normalName + * @return + */ + public String getNetherName(String normalName) { final String netherName = this.plugin.getNetherPrefix() + normalName + this.plugin.getNetherSuffix(); if (plugin.getCore().getMVWorldManager().isMVWorld(netherName)) { - this.plugin.log(Level.FINEST, "Selected nether world '" + netherName + "' for normal '" + normalName + "'"); + Logging.finest("Selected nether world '" + netherName + "' for normal '" + normalName + "'"); } - return netherName; - } - - /** - * Takes a given normal name and adds the end prefix and suffix onto it! - * - * @param normalName - * @return - */ - public String getEndName(String normalName) { + return netherName; + } + + /** + * Takes a given normal name and adds the end prefix and suffix onto it! + * + * @param normalName + * @return + */ + public String getEndName(String normalName) { final String endName = this.plugin.getEndPrefix() + normalName + this.plugin.getEndSuffix(); if (plugin.getCore().getMVWorldManager().isMVWorld(endName)) { - this.plugin.log(Level.FINEST, "Selected end world '" + endName + "' for normal '" + normalName + "'"); + Logging.finest("Selected end world '" + endName + "' for normal '" + normalName + "'"); } - return endName; - } - - /** - * Takes a given normal name chops the suffix and prefix off! - * - * @return - */ - public String getNormalName(String netherName, PortalType type) { - // Start by copying the nether name, we're going to transform it into a normal name! - String normalName = netherName; - // Chop off the prefix + return endName; + } + + /** + * Takes a given normal name chops the suffix and prefix off! + * + * @return + */ + public String getNormalName(String netherName, PortalType type) { + // Start by copying the nether name, we're going to transform it into a normal name! + String normalName = netherName; + // Chop off the prefix if (type == PortalType.NETHER) { if (this.plugin.getNetherPrefix().length() > 0) { String[] split = normalName.split(this.plugin.getNetherPrefix()); @@ -105,6 +103,6 @@ public String getNormalName(String netherName, PortalType type) { this.plugin.log(Level.FINEST, "Selected normal world '" + normalName + "' for " + type + " '" + netherName + "'"); } // All we're left with is the normal world. Don't worry if it exists, the method below will handle that! - return normalName; - } + return normalName; + } } From 0f34bb87dea74ebd9c5025af11bd13347066a210 Mon Sep 17 00:00:00 2001 From: benwoo1110 <30431861+benwoo1110@users.noreply.github.com> Date: Mon, 14 Dec 2020 09:51:08 +0800 Subject: [PATCH 14/53] Move all logging to use static Logging class. --- .../MultiverseNetherPortals.java | 4 +-- .../listeners/MVNPEntityListener.java | 27 ++++++++++--------- .../listeners/MVNPPlayerListener.java | 11 ++++---- .../utils/MVLinkChecker.java | 9 ++++--- .../utils/MVNameChecker.java | 3 ++- 5 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/MultiverseNetherPortals.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/MultiverseNetherPortals.java index 5f49f40..018c9ed 100644 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/MultiverseNetherPortals.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/MultiverseNetherPortals.java @@ -157,10 +157,10 @@ private void initMVNPConfig() { this.MVNPConfiguration.load(configFile); } catch (IOException e) { - this.log(Level.SEVERE, "Could not load " + NETHER_PORTALS_CONFIG); + Logging.severe("Could not load " + NETHER_PORTALS_CONFIG); } catch (InvalidConfigurationException e) { - this.log(Level.SEVERE, NETHER_PORTALS_CONFIG + " contained INVALID YAML. Please look at the file."); + Logging.severe(NETHER_PORTALS_CONFIG + " contained INVALID YAML. Please look at the file."); } } diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java index 479b207..9deaa25 100644 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java @@ -1,5 +1,6 @@ package com.onarandombox.MultiverseNetherPortals.listeners; +import com.dumptruckman.minecraft.util.Logging; import com.onarandombox.MultiverseCore.api.LocationManipulation; import com.onarandombox.MultiverseCore.api.MVWorldManager; import com.onarandombox.MultiverseCore.api.MultiverseMessaging; @@ -75,7 +76,7 @@ public MVNPEntityListener(MultiverseNetherPortals plugin) { */ protected boolean shootPlayer(Player p, Block block, PortalType type) { if (!plugin.isUsingBounceBack()) { - this.plugin.log(Level.FINEST, "Bounceback is disabled. The player is free to walk into the portal!"); + Logging.finest("Bounceback is disabled. The player is free to walk into the portal!"); return false; } @@ -121,7 +122,7 @@ protected boolean shootPlayer(Player p, Block block, PortalType type) { debugMessage.append(" entered an Unsupported Portal Type (").append(type).append(")."); } - this.plugin.log(Level.FINER, debugMessage.toString()); + Logging.finer(debugMessage.toString()); return playerBounced; } @@ -213,10 +214,10 @@ public void onEntityPortalEnter(EntityPortalEnterEvent event) { eventRecord.removeFromRecord(type, p.getUniqueId()); } - this.plugin.log(Level.FINEST, "Someone requested that this player be bounced back!"); + Logging.finest("Someone requested that this player be bounced back!"); } if (playerTouchedPortalEvent.isCancelled()) { - this.plugin.log(Level.FINEST, "Someone cancelled the enter Event for NetherPortals!"); + Logging.finest("Someone cancelled the enter Event for NetherPortals!"); return; } @@ -264,7 +265,7 @@ public void onEntityPortalEnter(EntityPortalEnterEvent event) { if (fromWorld.getCBWorld().equals(toWorld.getCBWorld())) { // The player is Portaling to the same world. - this.plugin.log(Level.FINER, "Player '" + p.getName() + "' is portaling to the same world."); + Logging.finer("Player '" + p.getName() + "' is portaling to the same world."); return; } if (!pt.playerHasMoneyToEnter(fromWorld, toWorld, p, p, false)) { @@ -272,7 +273,7 @@ public void onEntityPortalEnter(EntityPortalEnterEvent event) { eventRecord.removeFromRecord(type, p.getUniqueId()); } - this.plugin.log(Level.FINE, "Player '" + p.getName() + "' was DENIED ACCESS to '" + toWorld.getCBWorld().getName() + + Logging.fine("Player '" + p.getName() + "' was DENIED ACCESS to '" + toWorld.getCBWorld().getName() + "' because they don't have the FUNDS required to enter."); return; } @@ -283,18 +284,18 @@ public void onEntityPortalEnter(EntityPortalEnterEvent event) { eventRecord.removeFromRecord(type, p.getUniqueId()); } - this.plugin.log(Level.FINE, "Player '" + p.getName() + "' was DENIED ACCESS to '" + toWorld.getCBWorld().getName() + + Logging.fine("Player '" + p.getName() + "' was DENIED ACCESS to '" + toWorld.getCBWorld().getName() + "' because they don't have: multiverse.access." + toWorld.getCBWorld().getName()); } } else { - this.plugin.log(Level.FINE, "Player '" + p.getName() + "' was allowed to go to '" + toWorld.getCBWorld().getName() + "' because enforceaccess is off."); + Logging.fine("Player '" + p.getName() + "' was allowed to go to '" + toWorld.getCBWorld().getName() + "' because enforceaccess is off."); } } @EventHandler public void onEntityPortal(EntityPortalEvent event) { if (event.isCancelled()) { - this.plugin.log(Level.FINEST, "EntityPortalEvent was cancelled! NOT teleporting!"); + Logging.finest("EntityPortalEvent was cancelled! NOT teleporting!"); return; } @@ -327,7 +328,7 @@ public void onEntityPortal(EntityPortalEvent event) { Class.forName("org.bukkit.TravelAgent"); event.useTravelAgent(true); } catch (ClassNotFoundException ignore) { - plugin.log(Level.FINE, "TravelAgent not available for EntityPortalEvent for " + e.getName()); + Logging.fine("TravelAgent not available for EntityPortalEvent for " + e.getName()); } } @@ -347,12 +348,12 @@ public void onEntityPortal(EntityPortalEvent event) { if (!event.isCancelled()) { if (fromWorld.getEnvironment() == World.Environment.THE_END && type == PortalType.ENDER) { - this.plugin.log(Level.FINE, "Entity '" + e.getName() + "' will be teleported to the spawn of '" + toWorld.getName() + "' since they used an end exit portal."); + Logging.fine("Entity '" + e.getName() + "' will be teleported to the spawn of '" + toWorld.getName() + "' since they used an end exit portal."); try { Class.forName("org.bukkit.TravelAgent"); event.getPortalTravelAgent().setCanCreatePortal(false); } catch (ClassNotFoundException ignore) { - plugin.log(Level.FINE, "TravelAgent not available for EntityPortalEvent for " + e.getName() + ". There may be a portal created at spawn."); + Logging.fine("TravelAgent not available for EntityPortalEvent for " + e.getName() + ". There may be a portal created at spawn."); } event.setTo(toWorld.getSpawnLocation()); @@ -362,7 +363,7 @@ public void onEntityPortal(EntityPortalEvent event) { event.getPortalTravelAgent().setCanCreatePortal(true); event.setTo(event.getPortalTravelAgent().findOrCreate(event.getTo())); } catch (ClassNotFoundException ignore) { - plugin.log(Level.FINE, "TravelAgent not available for EntityPortalEvent for " + e.getName() + ". Their destination may not be correct."); + Logging.fine("TravelAgent not available for EntityPortalEvent for " + e.getName() + ". Their destination may not be correct."); event.setTo(event.getTo()); } } else if (toWorld.getEnvironment() == World.Environment.THE_END && type == PortalType.ENDER) { diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPPlayerListener.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPPlayerListener.java index bed4065..6de0c11 100644 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPPlayerListener.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPPlayerListener.java @@ -2,6 +2,7 @@ import java.util.logging.Level; +import com.dumptruckman.minecraft.util.Logging; import com.onarandombox.MultiverseCore.api.MVWorldManager; import com.onarandombox.MultiverseCore.api.MultiverseWorld; import com.onarandombox.MultiverseCore.utils.PermissionTools; @@ -39,7 +40,7 @@ public MVNPPlayerListener(MultiverseNetherPortals plugin) { @EventHandler public void onPlayerPortal(PlayerPortalEvent event) { if (event.isCancelled()) { - this.plugin.log(Level.FINEST, "PlayerPortalEvent was cancelled! NOT teleporting!"); + Logging.finest("PlayerPortalEvent was cancelled! NOT teleporting!"); return; } @@ -62,7 +63,7 @@ public void onPlayerPortal(PlayerPortalEvent event) { Class.forName("org.bukkit.TravelAgent"); event.useTravelAgent(true); } catch (ClassNotFoundException ignore) { - plugin.log(Level.FINE, "TravelAgent not available for PlayerPortalEvent for " + event.getPlayer().getName()); + Logging.fine("TravelAgent not available for PlayerPortalEvent for " + event.getPlayer().getName()); } } @@ -105,12 +106,12 @@ public void onPlayerPortal(PlayerPortalEvent event) { if (!event.isCancelled()) { if (fromWorld.getEnvironment() == World.Environment.THE_END && type == PortalType.ENDER) { - this.plugin.log(Level.FINE, "Player '" + event.getPlayer().getName() + "' will be teleported to the spawn of '" + toWorld.getName() + "' since they used an end exit portal."); + Logging.fine("Player '" + event.getPlayer().getName() + "' will be teleported to the spawn of '" + toWorld.getName() + "' since they used an end exit portal."); try { Class.forName("org.bukkit.TravelAgent"); event.getPortalTravelAgent().setCanCreatePortal(false); } catch (ClassNotFoundException ignore) { - plugin.log(Level.FINE, "TravelAgent not available for PlayerPortalEvent for " + event.getPlayer().getName() + ". There may be a portal created at spawn."); + Logging.fine("TravelAgent not available for PlayerPortalEvent for " + event.getPlayer().getName() + ". There may be a portal created at spawn."); } if (toWorld.getBedRespawn() && event.getPlayer().getBedSpawnLocation() != null @@ -125,7 +126,7 @@ public void onPlayerPortal(PlayerPortalEvent event) { event.getPortalTravelAgent().setCanCreatePortal(true); event.setTo(event.getPortalTravelAgent().findOrCreate(event.getTo())); } catch (ClassNotFoundException ignore) { - plugin.log(Level.FINE, "TravelAgent not available for PlayerPortalEvent for " + event.getPlayer().getName() + ". Their destination may not be correct."); + Logging.fine("TravelAgent not available for PlayerPortalEvent for " + event.getPlayer().getName() + ". Their destination may not be correct."); event.setTo(event.getTo()); } } else if (toWorld.getEnvironment() == World.Environment.THE_END && type == PortalType.ENDER) { diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/MVLinkChecker.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/MVLinkChecker.java index d257a98..00a7d50 100755 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/MVLinkChecker.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/MVLinkChecker.java @@ -1,5 +1,6 @@ package com.onarandombox.MultiverseNetherPortals.utils; +import com.dumptruckman.minecraft.util.Logging; import com.onarandombox.MultiverseCore.api.MVWorldManager; import com.onarandombox.MultiverseCore.api.MultiverseWorld; import com.onarandombox.MultiverseNetherPortals.MultiverseNetherPortals; @@ -22,14 +23,14 @@ public Location findNewTeleportLocation(Location fromLocation, String worldStrin MultiverseWorld tpTo = this.worldManager.getMVWorld(worldString); if (tpTo == null) { - this.plugin.log(Level.FINE, "Can't find world " + worldString); + Logging.fine("Can't find world " + worldString); } else if (e instanceof Player && !this.plugin.getCore().getMVPerms().canEnterWorld((Player) e, tpTo)) { - this.plugin.log(Level.WARNING, "Player " + e.getName() + " can't enter world " + worldString); + Logging.warning("Player " + e.getName() + " can't enter world " + worldString); } else if (!this.worldManager.isMVWorld(fromLocation.getWorld().getName())) { - this.plugin.log(Level.WARNING, "World " + fromLocation.getWorld().getName() + " is not a Multiverse world"); + Logging.warning("World " + fromLocation.getWorld().getName() + " is not a Multiverse world"); } else { String entityType = (e instanceof Player) ? " player " : " entity "; - this.plugin.log(Level.FINE, "Finding new teleport location for" + entityType + e.getName() + " to world " + worldString); + Logging.fine("Finding new teleport location for" + entityType + e.getName() + " to world " + worldString); // Set the output location to the same XYZ coords but different world MultiverseWorld tpFrom = this.worldManager.getMVWorld(fromLocation.getWorld().getName()); diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/MVNameChecker.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/MVNameChecker.java index 4ee3c1c..f4d7eb3 100644 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/MVNameChecker.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/MVNameChecker.java @@ -1,5 +1,6 @@ package com.onarandombox.MultiverseNetherPortals.utils; +import com.dumptruckman.minecraft.util.Logging; import com.onarandombox.MultiverseNetherPortals.MultiverseNetherPortals; import org.bukkit.PortalType; @@ -100,7 +101,7 @@ public String getNormalName(String netherName, PortalType type) { } } if (!normalName.equals(netherName) && plugin.getCore().getMVWorldManager().isMVWorld(normalName)) { - this.plugin.log(Level.FINEST, "Selected normal world '" + normalName + "' for " + type + " '" + netherName + "'"); + Logging.finest("Selected normal world '" + normalName + "' for " + type + " '" + netherName + "'"); } // All we're left with is the normal world. Don't worry if it exists, the method below will handle that! return normalName; From c16fa79f232926258233c54dd57d932a82cfa9ca Mon Sep 17 00:00:00 2001 From: Kermina Awad Date: Sun, 7 Feb 2021 20:39:58 -0500 Subject: [PATCH 15/53] compare environment instead of name --- .../MultiverseNetherPortals/listeners/MVNPEntityListener.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java index 9deaa25..20ec33a 100644 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java @@ -313,10 +313,10 @@ public void onEntityPortal(EntityPortalEvent event) { } PortalType type; - if (this.nameChecker.isValidNetherName(originalTo.getWorld().getName()) + if (originalTo.getWorld().getEnvironment() == World.Environment.NETHER || (currentLocation.getWorld().getEnvironment() == World.Environment.NETHER && originalTo.getWorld().getEnvironment() == World.Environment.NORMAL)) { type = PortalType.NETHER; - } else if (this.nameChecker.isValidEndName(originalTo.getWorld().getName()) + } else if (originalTo.getWorld().getEnvironment() == World.Environment.THE_END || (currentLocation.getWorld().getEnvironment() == World.Environment.THE_END && originalTo.getWorld().getEnvironment() == World.Environment.NORMAL)) { type = PortalType.ENDER; } else { From 532bc754aa6116b64db15e942788825c353ffd46 Mon Sep 17 00:00:00 2001 From: benwoo1110 <30431861+benwoo1110@users.noreply.github.com> Date: Mon, 8 Feb 2021 11:46:48 +0800 Subject: [PATCH 16/53] Fix bug where config isnt updated on reload. --- .../MultiverseNetherPortals/listeners/MVNPCoreListener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPCoreListener.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPCoreListener.java index 10eec48..469d429 100644 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPCoreListener.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPCoreListener.java @@ -24,7 +24,7 @@ public MVNPCoreListener(MultiverseNetherPortals plugin) { */ @EventHandler public void configReloadEvent(MVConfigReloadEvent event) { - this.plugin.reloadConfig(); + this.plugin.loadConfig(); event.addConfig("Multiverse-NetherPortals - config.yml"); } From e31f91a9fe686b9dc1bf3344ab07dab105e31b86 Mon Sep 17 00:00:00 2001 From: benwoo1110 <30431861+benwoo1110@users.noreply.github.com> Date: Mon, 8 Feb 2021 11:52:57 +0800 Subject: [PATCH 17/53] Put final notation where applicable. --- .../MultiverseNetherPortals/listeners/MVNPCoreListener.java | 3 ++- .../MultiverseNetherPortals/listeners/MVNPPluginListener.java | 2 +- .../MultiverseNetherPortals/utils/MVLinkChecker.java | 4 ++-- .../MultiverseNetherPortals/utils/MVNameChecker.java | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPCoreListener.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPCoreListener.java index 10eec48..fa0753e 100644 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPCoreListener.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPCoreListener.java @@ -11,7 +11,8 @@ import java.io.File; public class MVNPCoreListener implements Listener { - private MultiverseNetherPortals plugin; + + private final MultiverseNetherPortals plugin; public MVNPCoreListener(MultiverseNetherPortals plugin) { this.plugin = plugin; diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPPluginListener.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPPluginListener.java index 7840226..07c19f1 100644 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPPluginListener.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPPluginListener.java @@ -10,7 +10,7 @@ public class MVNPPluginListener implements Listener { - private MultiverseNetherPortals plugin; + private final MultiverseNetherPortals plugin; public MVNPPluginListener(MultiverseNetherPortals plugin) { this.plugin = plugin; diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/MVLinkChecker.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/MVLinkChecker.java index 00a7d50..5aa854f 100755 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/MVLinkChecker.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/MVLinkChecker.java @@ -11,8 +11,8 @@ import java.util.logging.Level; public class MVLinkChecker { - private MultiverseNetherPortals plugin; - private MVWorldManager worldManager; + private final MultiverseNetherPortals plugin; + private final MVWorldManager worldManager; public MVLinkChecker(MultiverseNetherPortals plugin) { this.plugin = plugin; diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/MVNameChecker.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/MVNameChecker.java index f4d7eb3..5fbdeaf 100644 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/MVNameChecker.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/MVNameChecker.java @@ -5,7 +5,7 @@ import org.bukkit.PortalType; public class MVNameChecker { - private MultiverseNetherPortals plugin; + private final MultiverseNetherPortals plugin; public MVNameChecker(MultiverseNetherPortals plugin) { this.plugin = plugin; From 34b2f4681313e00e32ad5404af5a51842e1b51df Mon Sep 17 00:00:00 2001 From: benwoo1110 <30431861+benwoo1110@users.noreply.github.com> Date: Mon, 8 Feb 2021 12:10:54 +0800 Subject: [PATCH 18/53] Have common instance for MVLinkChecker and MVNameChecker. --- .../MultiverseNetherPortals.java | 15 +++++++++++++++ .../listeners/MVNPEntityListener.java | 4 ++-- .../listeners/MVNPPlayerListener.java | 4 ++-- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/MultiverseNetherPortals.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/MultiverseNetherPortals.java index 018c9ed..f7d608a 100644 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/MultiverseNetherPortals.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/MultiverseNetherPortals.java @@ -20,6 +20,8 @@ import com.onarandombox.MultiverseNetherPortals.listeners.MVNPEntityListener; import com.onarandombox.MultiverseNetherPortals.listeners.MVNPPlayerListener; import com.onarandombox.MultiverseNetherPortals.listeners.MVNPPluginListener; +import com.onarandombox.MultiverseNetherPortals.utils.MVLinkChecker; +import com.onarandombox.MultiverseNetherPortals.utils.MVNameChecker; import com.onarandombox.MultiversePortals.MultiversePortals; import com.onarandombox.commandhandler.CommandHandler; import org.bukkit.Location; @@ -53,6 +55,8 @@ public class MultiverseNetherPortals extends JavaPlugin implements MVPlugin { protected CommandHandler commandHandler; private final static int requiresProtocol = 24; private MVNPEntityListener entityListener; + private MVLinkChecker linkChecker; + private MVNameChecker nameChecker; @Override public void onEnable() { @@ -81,6 +85,9 @@ public void onEnable() { this.core.incrementPluginCount(); // As soon as we know MVCore was found, we can use the debug log! + this.linkChecker = new MVLinkChecker(this); + this.nameChecker = new MVNameChecker(this); + this.pluginListener = new MVNPPluginListener(this); this.playerListener = new MVNPPlayerListener(this); this.entityListener = new MVNPEntityListener(this); @@ -336,6 +343,14 @@ public boolean isHandledByNetherPortals(Location l) { return true; } + public MVLinkChecker getLinkChecker() { + return linkChecker; + } + + public MVNameChecker getNameChecker() { + return nameChecker; + } + public void setPortals(Plugin multiversePortals) { this.multiversePortals = multiversePortals; } diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java index 9deaa25..78f657c 100644 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java @@ -52,8 +52,8 @@ public class MVNPEntityListener implements Listener { public MVNPEntityListener(MultiverseNetherPortals plugin) { this.plugin = plugin; - this.nameChecker = new MVNameChecker(this.plugin); - this.linkChecker = new MVLinkChecker(this.plugin); + this.nameChecker = this.plugin.getNameChecker(); + this.linkChecker = this.plugin.getLinkChecker(); this.worldManager = this.plugin.getCore().getMVWorldManager(); this.pt = new PermissionTools(this.plugin.getCore()); this.playerErrors = new HashMap(); diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPPlayerListener.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPPlayerListener.java index 6de0c11..7ed108f 100644 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPPlayerListener.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPPlayerListener.java @@ -31,10 +31,10 @@ public class MVNPPlayerListener implements Listener { public MVNPPlayerListener(MultiverseNetherPortals plugin) { this.plugin = plugin; - this.nameChecker = new MVNameChecker(plugin); + this.nameChecker = this.plugin.getNameChecker(); this.worldManager = this.plugin.getCore().getMVWorldManager(); this.pt = new PermissionTools(this.plugin.getCore()); - this.linkChecker = new MVLinkChecker(this.plugin); + this.linkChecker = this.plugin.getLinkChecker(); } @EventHandler From 431077fb0e36e6580198b9f30271a1f5246337dc Mon Sep 17 00:00:00 2001 From: benwoo1110 <30431861+benwoo1110@users.noreply.github.com> Date: Tue, 9 Feb 2021 17:09:52 +0800 Subject: [PATCH 19/53] Fix advancement not triggering for entering nether/end worlds. --- .../listeners/MVNPPlayerListener.java | 45 +++++++++++++++++-- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPPlayerListener.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPPlayerListener.java index 6de0c11..def885c 100644 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPPlayerListener.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPPlayerListener.java @@ -1,7 +1,5 @@ package com.onarandombox.MultiverseNetherPortals.listeners; -import java.util.logging.Level; - import com.dumptruckman.minecraft.util.Logging; import com.onarandombox.MultiverseCore.api.MVWorldManager; import com.onarandombox.MultiverseCore.api.MultiverseWorld; @@ -11,12 +9,15 @@ import com.onarandombox.MultiverseNetherPortals.utils.MVNameChecker; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.NamespacedKey; import org.bukkit.PortalType; import org.bukkit.World; +import org.bukkit.advancement.Advancement; +import org.bukkit.advancement.AdvancementProgress; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerPortalEvent; import org.bukkit.event.player.PlayerTeleportEvent; @@ -28,6 +29,11 @@ public class MVNPPlayerListener implements Listener { private final MVLinkChecker linkChecker; private final MVWorldManager worldManager; private final PermissionTools pt; + private final Advancement enterNetherAdvancement; + private final Advancement enterEndAdvancement; + + private static final String ENTER_NETHER_CRITERIA = "entered_nether"; + private static final String ENTER_END_CRITERIA = "entered_end"; public MVNPPlayerListener(MultiverseNetherPortals plugin) { this.plugin = plugin; @@ -35,6 +41,8 @@ public MVNPPlayerListener(MultiverseNetherPortals plugin) { this.worldManager = this.plugin.getCore().getMVWorldManager(); this.pt = new PermissionTools(this.plugin.getCore()); this.linkChecker = new MVLinkChecker(this.plugin); + this.enterNetherAdvancement = this.plugin.getServer().getAdvancement(NamespacedKey.minecraft("story/enter_the_nether")); + this.enterEndAdvancement = this.plugin.getServer().getAdvancement(NamespacedKey.minecraft("story/enter_the_end")); } @EventHandler @@ -148,6 +156,37 @@ public void onPlayerPortal(PlayerPortalEvent event) { } } } + + // Advancements need to be triggered manually + if (type == PortalType.NETHER && event.getTo().getWorld().getEnvironment() == World.Environment.NETHER) { + awardAdvancement(event.getPlayer(), enterNetherAdvancement, ENTER_NETHER_CRITERIA); + } else if (type == PortalType.ENDER && event.getTo().getWorld().getEnvironment() == World.Environment.THE_END) { + awardAdvancement(event.getPlayer(), enterEndAdvancement, ENTER_END_CRITERIA); + } + } + } + + /** + * Award an advancement criteria to a player if not already awarded. + * + * @param player Target player to award the advancement criteria to. + * @param advancement {@link Advancement} the criteria belongs to. + * @param criteria Criteria to award the player. + */ + private void awardAdvancement(Player player, Advancement advancement, String criteria) { + if (advancement == null) { + Logging.warning("No advancement found for target criteria: %s", criteria); + return; + } + AdvancementProgress advancementProgress = player.getAdvancementProgress(advancement); + if (advancementProgress.isDone()) { + Logging.fine("%s has already been awarded advancement criteria %s.", player.getName(), criteria); + return; + } + if (!advancementProgress.awardCriteria(criteria)) { + Logging.warning("Unable to award advancement criteria %s to %s.", criteria, player.getName()); + return; } + Logging.fine("Awarded advancement criteria %s to %s.", criteria, player.getName()); } } From 2b5b36bd1edfff06afb981b5c81e80b48d9e9910 Mon Sep 17 00:00:00 2001 From: benwoo1110 <30431861+benwoo1110@users.noreply.github.com> Date: Sat, 13 Feb 2021 09:38:09 +0800 Subject: [PATCH 20/53] Change no advancement logging to fine. --- .../MultiverseNetherPortals/listeners/MVNPPlayerListener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPPlayerListener.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPPlayerListener.java index def885c..1315011 100644 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPPlayerListener.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPPlayerListener.java @@ -175,7 +175,7 @@ public void onPlayerPortal(PlayerPortalEvent event) { */ private void awardAdvancement(Player player, Advancement advancement, String criteria) { if (advancement == null) { - Logging.warning("No advancement found for target criteria: %s", criteria); + Logging.fine("No advancement found for target criteria: %s", criteria); return; } AdvancementProgress advancementProgress = player.getAdvancementProgress(advancement); From 5ad968de941b017ec5fa31cf113f6b0ef76475ac Mon Sep 17 00:00:00 2001 From: benwoo1110 <30431861+benwoo1110@users.noreply.github.com> Date: Mon, 1 Mar 2021 23:58:38 +0800 Subject: [PATCH 21/53] Update issue template tags. --- .github/ISSUE_TEMPLATE/help.md | 2 +- .github/ISSUE_TEMPLATE/report-a-bug.md | 2 +- .github/ISSUE_TEMPLATE/request-a-feature.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/help.md b/.github/ISSUE_TEMPLATE/help.md index 9e32bb1..f6f7b91 100644 --- a/.github/ISSUE_TEMPLATE/help.md +++ b/.github/ISSUE_TEMPLATE/help.md @@ -2,7 +2,7 @@ name: ❓ Help! about: Encountered a problem with Multiverse-NetherPortals? Not sure how to fix it? title: '' -labels: 'Assistance' +labels: 'Type: Assistance' assignees: '' --- diff --git a/.github/ISSUE_TEMPLATE/report-a-bug.md b/.github/ISSUE_TEMPLATE/report-a-bug.md index a1b6abd..2170c00 100644 --- a/.github/ISSUE_TEMPLATE/report-a-bug.md +++ b/.github/ISSUE_TEMPLATE/report-a-bug.md @@ -2,7 +2,7 @@ name: 🐛 Report a Bug about: Report a Multiverse-NetherPortals bug. Only use this if you're 100% sure it's something wrong with Multiverse-NetherPortals - otherwise, try "Help!". title: '' -labels: 'Bug' +labels: 'Bug: Unconfirmed' assignees: '' --- diff --git a/.github/ISSUE_TEMPLATE/request-a-feature.md b/.github/ISSUE_TEMPLATE/request-a-feature.md index aae4b94..3f46983 100644 --- a/.github/ISSUE_TEMPLATE/request-a-feature.md +++ b/.github/ISSUE_TEMPLATE/request-a-feature.md @@ -2,7 +2,7 @@ name: 💡 Request a Feature about: Suggest a feature you want to see in Multiverse-NetherPortals! title: '' -labels: 'Suggestion' +labels: 'Type: Idea' assignees: '' --- From 6743fa22f9eb1e41dff6a4f6e1402adc9d7de558 Mon Sep 17 00:00:00 2001 From: Ben Woo <30431861+benwoo1110@users.noreply.github.com> Date: Sun, 18 Jul 2021 10:41:22 +0800 Subject: [PATCH 22/53] Remove use of Travis. --- .travis.yml | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 2e7dbb3..0000000 --- a/.travis.yml +++ /dev/null @@ -1,6 +0,0 @@ -language: java -jdk: - - oraclejdk8 -notifications: - email: false -dist: trusty From 1620f0815de2c38fb10994e29d96da2a4fc3e077 Mon Sep 17 00:00:00 2001 From: Ben Woo <30431861+benwoo1110@users.noreply.github.com> Date: Sun, 18 Jul 2021 10:41:32 +0800 Subject: [PATCH 23/53] Add github action build. --- .github/workflows/build.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..983d12c --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,22 @@ +name: Maven CI/CD + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + build_and_test: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Set up JDK 8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + + - name: Build with Maven + run: mvn -B package --file pom.xml From b7020ef9aaa25a40e9aa6f2d0dbe3c49f7b39c37 Mon Sep 17 00:00:00 2001 From: Ben Woo <30431861+benwoo1110@users.noreply.github.com> Date: Sun, 18 Jul 2021 10:46:38 +0800 Subject: [PATCH 24/53] Use https for dependency. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ba56add..9a95fca 100644 --- a/pom.xml +++ b/pom.xml @@ -18,7 +18,7 @@ OnARandomBox - http://repo.onarandombox.com/content/groups/public/ + https://repo.onarandombox.com/content/groups/public/ From b499ac2da66be004ac203a3e54cfe9715ccb185a Mon Sep 17 00:00:00 2001 From: Kermina Awad Date: Thu, 10 Feb 2022 01:16:59 -0500 Subject: [PATCH 25/53] remove unnecessary import --- .../MultiverseNetherPortals/utils/MVLinkChecker.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/MVLinkChecker.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/MVLinkChecker.java index 5aa854f..ad3a690 100755 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/MVLinkChecker.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/MVLinkChecker.java @@ -8,8 +8,6 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.Player; -import java.util.logging.Level; - public class MVLinkChecker { private final MultiverseNetherPortals plugin; private final MVWorldManager worldManager; From a410c94de8cfb9345ef565a090a5c48c1be30b21 Mon Sep 17 00:00:00 2001 From: Kermina Awad Date: Thu, 10 Feb 2022 02:02:26 -0500 Subject: [PATCH 26/53] remove y-value scaling --- .../MultiverseNetherPortals/utils/MVLinkChecker.java | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/MVLinkChecker.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/MVLinkChecker.java index ad3a690..6f59649 100755 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/MVLinkChecker.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/MVLinkChecker.java @@ -31,13 +31,10 @@ public Location findNewTeleportLocation(Location fromLocation, String worldStrin Logging.fine("Finding new teleport location for" + entityType + e.getName() + " to world " + worldString); // Set the output location to the same XYZ coords but different world - MultiverseWorld tpFrom = this.worldManager.getMVWorld(fromLocation.getWorld().getName()); + double fromScaling = this.worldManager.getMVWorld(fromLocation.getWorld().getName()).getScaling(); + double toScaling = tpTo.getScaling(); - double fromScaling = tpFrom.getScaling(); - double toScaling = this.worldManager.getMVWorld(tpTo.getName()).getScaling(); - double yScaling = 1d * tpFrom.getCBWorld().getMaxHeight() / tpTo.getCBWorld().getMaxHeight(); - - this.scaleLocation(fromLocation, fromScaling / toScaling, yScaling); + this.scaleLocation(fromLocation, fromScaling / toScaling); fromLocation.setWorld(tpTo.getCBWorld()); return fromLocation; } @@ -45,9 +42,8 @@ public Location findNewTeleportLocation(Location fromLocation, String worldStrin return null; } - private void scaleLocation(Location fromLocation, double scaling, double yScaling) { + private void scaleLocation(Location fromLocation, double scaling) { fromLocation.setX(fromLocation.getX() * scaling); fromLocation.setZ(fromLocation.getZ() * scaling); - fromLocation.setY(fromLocation.getY() * yScaling); } } From b9e124324d4484abd21890f22df4b0615d3644ab Mon Sep 17 00:00:00 2001 From: Jeremy Wood Date: Sat, 12 Mar 2022 21:55:02 -0500 Subject: [PATCH 27/53] Release version 4.2.2. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9a95fca..6294b0f 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.onarandombox.multiversenetherportals Multiverse-NetherPortals - 4.2.2-SNAPSHOT + 4.2.2 Multiverse-NetherPortals Multiverse Nether Portals module From 10736da3876bbb6dceb25a6e98416bb23e91831e Mon Sep 17 00:00:00 2001 From: Jeremy Wood Date: Sat, 12 Mar 2022 22:14:16 -0500 Subject: [PATCH 28/53] Bump version to 4.2.3-SNAPSHOT. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6294b0f..15bccbc 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.onarandombox.multiversenetherportals Multiverse-NetherPortals - 4.2.2 + 4.2.3-SNAPSHOT Multiverse-NetherPortals Multiverse Nether Portals module From 93f1d38bde6440c1a5071078dad49b15cca07fbf Mon Sep 17 00:00:00 2001 From: zax71 Date: Tue, 22 Aug 2023 12:59:21 +0100 Subject: [PATCH 29/53] Update README.md and add LICENSE.md --- LICENSE.md | 5 +++++ README.md | 50 +++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 LICENSE.md diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..9812bfa --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,5 @@ +Copyright (c) 2011, The Multiverse Team All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the The Multiverse Team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md index 9812bfa..b89324a 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,49 @@ -Copyright (c) 2011, The Multiverse Team All rights reserved. +

+Multiverse Logo +

-Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +# Multiverse Nether portals -Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the The Multiverse Team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +[![Modrinth](https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/cozy/available/modrinth_vector.svg)](https://modrinth.com/plugin/multiverse-NetherPortals) +[![hangar](https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/cozy/available/hangar_vector.svg)](https://hangar.papermc.io/Multiverse/Multiverse-NetherPortals) +[![bukkit](https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/cozy/supported/bukkit_vector.svg)](https://dev.bukkit.org/projects/multiverse-NetherPortals) + +![GitHub release (with filter)](https://img.shields.io/github/v/release/multiverse/multiverse-netherportals) +[![Discord](https://img.shields.io/discord/325459248047980545?label=discord&logo=discord)](https://discord.gg/NZtfKky) +[![Support us on Patreon](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fshieldsio-patreon.vercel.app%2Fapi%3Fusername%3Ddumptruckman%26type%3Dpatrons&style=flat)](https://patreon.com/dumptruckman) + + +## About + +[Multiverse Nether Portals](https://dev.bukkit.org/projects/multiverse-NetherPortals) is an add-on Plugin for [Multiverse core](https://dev.bukkit.org/projects/multiverse-core) that makes nether and end portals work **just like vanilla** with minimal setup. + +Now it's time to create your very own server with Multiverse Inventories, do check out our [Wiki](https://github.com/Multiverse/Multiverse-Core/wiki/Home-(Inventories)) and [Usage Guide](https://github.com/Multiverse/Multiverse-Core/wiki/Basics-(Inventories)) to get started. Feel free to hop onto our [Discord](https://discord.gg/NZtfKky) if you have any questions or just want to have a chat with us! + +## Our other amazing sub-modules: + +With just [Multiverse Core](https://github.com/multiverse/multiverse) and any of the below plugins, you can access all of these other related features in the Multiverse ecosystem. + +* [Multiverse-NetherInventories](https://github.com/Multiverse/Multiverse-Inventories) -> Have separate nether and end worlds for each of your overworlds! +* [Multiverse-Portals](https://github.com/Multiverse/Multiverse-Portals) -> Make custom portals to go to any destination! +* [Multiverse-SignPortals](https://github.com/Multiverse/Multiverse-SignPortals) -> Signs as teleporters! + +## Building +Simply build the source with Gradle: +``` +./gradlew build +``` + +## Contributing + +**Want to help improve Multiverse Nether Portals?** There are several ways you can support and contribute to the project. +* Take a look at our "Bug: Unconfirmed" issues, where you can find issues that need extra testing and investigation. +* Want others to love Multiverse too? You can join the [Multiverse Discord community](https://discord.gg/NZtfKky) and help others with issues and setup! +* A Multiverse guru? You can update our [Wiki](https://github.com/Multiverse/Multiverse-Core/wiki) with your latest tips, tricks and guides! The wiki open for all to edit and improve. +* Love coding? You could look at ["State: Open to PR"](https://github.com/Multiverse/Multiverse-NetherPortals/labels/State%3A%20Open%20to%20PR) and ["Resolution: Accepted"](https://github.com/Multiverse/Multiverse-NetherPortals/labels/Resolution%3A%20Accepted) issues. We're always happy to receive bug fixes and feature additions as [pull requests](https://www.freecodecamp.org/news/how-to-make-your-first-pull-request-on-github-3/). +* If you'd like to make a financial contribution to the project, do consider joining our [Patreon](https://www.patreon.com/dumptruckman) or make a one-time donation [here](https://paypal.me/dumptruckman)! + +Additionally, we would like to give a big thanks to everyone that has supported Multiverse over the years, as well as those in the years to come. Thank you! + +## License + +Multiverse-Core is licensed under BSD-3-Clause License. Please see [LICENSE.md](LICENSE.md) for more info. \ No newline at end of file From 1e79b3d54fbde14394ae1482d24305f20d670007 Mon Sep 17 00:00:00 2001 From: Zax71 <67716263+zax71@users.noreply.github.com> Date: Tue, 22 Aug 2023 13:08:37 +0100 Subject: [PATCH 30/53] Multiverse NetherInventories doesn't exist! (yet) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b89324a..9a3f1d9 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Now it's time to create your very own server with Multiverse Inventories, do che With just [Multiverse Core](https://github.com/multiverse/multiverse) and any of the below plugins, you can access all of these other related features in the Multiverse ecosystem. -* [Multiverse-NetherInventories](https://github.com/Multiverse/Multiverse-Inventories) -> Have separate nether and end worlds for each of your overworlds! +* [Multiverse-Inventories](https://github.com/Multiverse/Multiverse-Inventories) -> Have separate nether and end worlds for each of your overworlds! * [Multiverse-Portals](https://github.com/Multiverse/Multiverse-Portals) -> Make custom portals to go to any destination! * [Multiverse-SignPortals](https://github.com/Multiverse/Multiverse-SignPortals) -> Signs as teleporters! @@ -46,4 +46,4 @@ Additionally, we would like to give a big thanks to everyone that has supported ## License -Multiverse-Core is licensed under BSD-3-Clause License. Please see [LICENSE.md](LICENSE.md) for more info. \ No newline at end of file +Multiverse-Core is licensed under BSD-3-Clause License. Please see [LICENSE.md](LICENSE.md) for more info. From c2f1312df9d65c3301eafe01327d2a75281b3b7a Mon Sep 17 00:00:00 2001 From: Zax71 <67716263+zax71@users.noreply.github.com> Date: Tue, 22 Aug 2023 13:10:37 +0100 Subject: [PATCH 31/53] Oops, forgot to change something else --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9a3f1d9..6589b9e 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ [Multiverse Nether Portals](https://dev.bukkit.org/projects/multiverse-NetherPortals) is an add-on Plugin for [Multiverse core](https://dev.bukkit.org/projects/multiverse-core) that makes nether and end portals work **just like vanilla** with minimal setup. -Now it's time to create your very own server with Multiverse Inventories, do check out our [Wiki](https://github.com/Multiverse/Multiverse-Core/wiki/Home-(Inventories)) and [Usage Guide](https://github.com/Multiverse/Multiverse-Core/wiki/Basics-(Inventories)) to get started. Feel free to hop onto our [Discord](https://discord.gg/NZtfKky) if you have any questions or just want to have a chat with us! +Now it's time to create your very own server with Multiverse Nether Portals, do check out our [Wiki](https://github.com/Multiverse/Multiverse-Core/wiki/Home-(Inventories)) and [Usage Guide](https://github.com/Multiverse/Multiverse-Core/wiki/Basics-(Inventories)) to get started. Feel free to hop onto our [Discord](https://discord.gg/NZtfKky) if you have any questions or just want to have a chat with us! ## Our other amazing sub-modules: From cc4b6415030f525a94af2393e6cbb021c30c20b7 Mon Sep 17 00:00:00 2001 From: Zax71 <67716263+zax71@users.noreply.github.com> Date: Tue, 22 Aug 2023 13:12:01 +0100 Subject: [PATCH 32/53] Forgot to change even more stuff! --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6589b9e..863bf30 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ [Multiverse Nether Portals](https://dev.bukkit.org/projects/multiverse-NetherPortals) is an add-on Plugin for [Multiverse core](https://dev.bukkit.org/projects/multiverse-core) that makes nether and end portals work **just like vanilla** with minimal setup. -Now it's time to create your very own server with Multiverse Nether Portals, do check out our [Wiki](https://github.com/Multiverse/Multiverse-Core/wiki/Home-(Inventories)) and [Usage Guide](https://github.com/Multiverse/Multiverse-Core/wiki/Basics-(Inventories)) to get started. Feel free to hop onto our [Discord](https://discord.gg/NZtfKky) if you have any questions or just want to have a chat with us! +Now it's time to create your very own server with Multiverse Nether Portals, do check out our [Wiki](https://github.com/Multiverse/Multiverse-Core/wiki/Home-(NetherPortals)) and [Usage Guide](https://github.com/Multiverse/Multiverse-Core/wiki/Basics-(NetherPortals)) to get started. Feel free to hop onto our [Discord](https://discord.gg/NZtfKky) if you have any questions or just want to have a chat with us! ## Our other amazing sub-modules: From e6362c3874a4b5ba959e8a0236fe6e6e2000c337 Mon Sep 17 00:00:00 2001 From: Zax71 <67716263+zax71@users.noreply.github.com> Date: Tue, 22 Aug 2023 13:14:49 +0100 Subject: [PATCH 33/53] Forgot to change the copyright too --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 863bf30..e7486b1 100644 --- a/README.md +++ b/README.md @@ -46,4 +46,4 @@ Additionally, we would like to give a big thanks to everyone that has supported ## License -Multiverse-Core is licensed under BSD-3-Clause License. Please see [LICENSE.md](LICENSE.md) for more info. +Multiverse-NetherPortals is licensed under BSD-3-Clause License. Please see [LICENSE.md](LICENSE.md) for more info. From d7a3ba83589aade84d65cc2396c5bac0d3ef2beb Mon Sep 17 00:00:00 2001 From: Ben Woo <30431861+benwoo1110@users.noreply.github.com> Date: Thu, 24 Aug 2023 23:44:25 +0800 Subject: [PATCH 34/53] feat: Implement gradle build --- .gitignore | 3 + build.gradle | 125 ++++++++++++ config/mv_checks.xml | 141 +++++++++++++ gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 61574 bytes gradle/wrapper/gradle-wrapper.properties | 6 + gradlew | 244 +++++++++++++++++++++++ gradlew.bat | 92 +++++++++ pom.xml | 187 ----------------- settings.gradle | 5 + src/main/resources/plugin.yml | 2 +- 10 files changed, 617 insertions(+), 188 deletions(-) create mode 100644 build.gradle create mode 100644 config/mv_checks.xml create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 gradlew create mode 100644 gradlew.bat delete mode 100644 pom.xml create mode 100644 settings.gradle diff --git a/.gitignore b/.gitignore index 4a3f598..8a593e0 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,6 @@ debug.log # Doxygen /docs/html debug.txt + +# Gradle +.gradle diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..901029c --- /dev/null +++ b/build.gradle @@ -0,0 +1,125 @@ +plugins { + id 'java-library' + id 'maven-publish' + id 'checkstyle' + id 'com.github.johnrengelman.shadow' version '7.1.2' +} + +version = System.getenv('GITHUB_VERSION') ?: 'local' +group = 'com.onarandombox.multiversenetherportals' +description = 'Multiverse-NetherPortals' + +java.sourceCompatibility = JavaVersion.VERSION_11 + +repositories { + mavenLocal() + mavenCentral() + + maven { + name = 'spigotmc' + url = uri('https://hub.spigotmc.org/nexus/content/repositories/snapshots/') + } + + maven { + name = 'onarandombox' + url = uri('https://repo.onarandombox.com/content/groups/public') + } +} + +dependencies { + // Spigot + implementation 'org.bukkit:bukkit:1.13.2-R0.1-SNAPSHOT' + + // Multiverse-Core + implementation 'com.onarandombox.multiversecore:multiverse-core:4.3.9' + + // Multiverse-Portals + implementation 'com.onarandombox.multiverseportals:multiverse-portals:4.2.2' + + // Utils + api('com.dumptruckman.minecraft:Logging:1.1.1') { + exclude group: 'org.bukkit', module: 'bukkit' + } +} + + +java { + withSourcesJar() + withJavadocJar() +} + +tasks.withType(JavaCompile).configureEach { + options.encoding = 'UTF-8' +} + +tasks.withType(Javadoc).configureEach { + options.encoding = 'UTF-8' +} + + +configurations { + [apiElements, runtimeElements].each { + it.outgoing.artifacts.removeIf { it.buildDependencies.getDependencies(null).contains(jar) } + it.outgoing.artifact(shadowJar) + } +} + +publishing { + publications { + maven(MavenPublication) { + from components.java + } + } + repositories { + maven { + name = "GitHubPackages" + url = "https://maven.pkg.github.com/Multiverse/Multiverse-NetherPortals" + credentials { + username = System.getenv("GITHUB_ACTOR") + password = System.getenv("GITHUB_TOKEN") + } + } + } +} + + +processResources { + def props = [version: "${project.version}"] + inputs.properties props + filteringCharset 'UTF-8' + filesMatching('plugin.yml') { + expand props + } + + // This task should never be skipped. The tests depend on this having been run but we want the new version number + // that is created after tests are run and before we run again to publish. + outputs.upToDateWhen { false } +} + + +checkstyle { + toolVersion = '6.1.1' + configFile file('config/mv_checks.xml') + ignoreFailures = true +} + + +javadoc { + source = sourceSets.main.allJava + classpath = configurations.compileClasspath +} + + +project.configurations.api.canBeResolved = true + +shadowJar { + relocate 'com.dumptruckman.minecraft.util.Logging', 'com.onarandombox.multiverseportals.util.MVPLogging' + relocate 'com.dumptruckman.minecraft.util.DebugLog', 'com.onarandombox.multiverseportals.util.DebugFileLogger' + + configurations = [project.configurations.api] + + archiveFileName = "$baseName-$version.$extension" +} + +build.dependsOn shadowJar +jar.enabled = false diff --git a/config/mv_checks.xml b/config/mv_checks.xml new file mode 100644 index 0000000..0c660d8 --- /dev/null +++ b/config/mv_checks.xml @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..943f0cbfa754578e88a3dae77fce6e3dea56edbf GIT binary patch literal 61574 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 ScNgau(U?ep-K_E5zy1%ZQTdPn literal 0 HcmV?d00001 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..f398c33 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip +networkTimeout=10000 +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..65dcd68 --- /dev/null +++ b/gradlew @@ -0,0 +1,244 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..93e3f59 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/pom.xml b/pom.xml deleted file mode 100644 index 15bccbc..0000000 --- a/pom.xml +++ /dev/null @@ -1,187 +0,0 @@ - - 4.0.0 - com.onarandombox.multiversenetherportals - Multiverse-NetherPortals - 4.2.3-SNAPSHOT - Multiverse-NetherPortals - Multiverse Nether Portals module - - UTF-8 - UNKNOWN - - - - - spigot-repo - https://hub.spigotmc.org/nexus/content/repositories/snapshots/ - - - OnARandomBox - https://repo.onarandombox.com/content/groups/public/ - - - - - - - jenkins - - - env.BUILD_NUMBER - - - - ${env.BUILD_NUMBER} - - - - - - clean package - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.7.0 - - 1.8 - 1.8 - - - - com.google.code.maven-replacer-plugin - maven-replacer-plugin - 1.4.1 - - - prepare-package - - replace - - - - - target/classes/plugin.yml - - - maven-version-number - ${project.version}-b${project.build.number} - - - - - - - org.apache.maven.plugins - maven-jar-plugin - 3.0.2 - - - - - - - - - org.apache.maven.plugins - maven-source-plugin - 3.0.1 - - - attach-sources - package - - jar-no-fork - - - - - - maven-javadoc-plugin - 2.10.4 - - - javadoc-jar - verify - - jar - - - - - - org.apache.maven.plugins - maven-shade-plugin - 2.4.3 - - - package - - shade - - - - - com.dumptruckman.minecraft:Logging - - - - - com.dumptruckman.minecraft.util.Logging - com.onarandombox.MultiverseNetherPortals.utils.MVNPLogging - - - - com.dumptruckman.minecraft.util.DebugLog - com.onarandombox.MultiverseNetherPortals.utils.DebugFileLogger - - - - - - - - - - - org.bukkit - bukkit - 1.13.2-R0.1-SNAPSHOT - provided - - - com.onarandombox.multiversecore - Multiverse-Core - 4.2.2 - jar - provided - - - com.onarandombox.multiverseportals - Multiverse-Portals - 4.1.0 - jar - provided - - - com.dumptruckman.minecraft - Logging - 1.1.1 - jar - compile - - - - - OnARandomBox - http://repo.onarandombox.com/content/repositories/multiverse - - - OnARandomBox - http://repo.onarandombox.com/content/repositories/multiverse-snapshots/ - - - diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..1922444 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,5 @@ +/* + * This file was generated by the Gradle 'init' task. + */ + +rootProject.name = 'multiverse-netherportals' diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 927569a..4b9059d 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,7 +1,7 @@ name: Multiverse-NetherPortals main: com.onarandombox.MultiverseNetherPortals.MultiverseNetherPortals authors: ['Rigby', 'fernferret'] -version: maven-version-number +version: ${version} api-version: 1.13 depend: ['Multiverse-Core'] softdepend: ['Multiverse-Portals'] From 7a18630572c244237f12d28cea53e4d8f75748bf Mon Sep 17 00:00:00 2001 From: Ben Woo <30431861+benwoo1110@users.noreply.github.com> Date: Thu, 24 Aug 2023 23:55:18 +0800 Subject: [PATCH 35/53] feat: implement new github actions release --- .github/workflows/build.yml | 22 ------ .github/workflows/call.github_release.yml | 34 +++++++++ .github/workflows/call.platform_uploads.yml | 75 +++++++++++++++++++ .../workflows/dispatch.platform_uploads.yml | 31 ++++++++ .../workflows/dispatch.promote_release.yml | 38 ++++++++++ .github/workflows/main.prerelease.yml | 24 ++++++ .github/workflows/pr.require_label.yml | 18 +++++ .github/workflows/pr.test.yml | 36 +++++++++ 8 files changed, 256 insertions(+), 22 deletions(-) delete mode 100644 .github/workflows/build.yml create mode 100644 .github/workflows/call.github_release.yml create mode 100644 .github/workflows/call.platform_uploads.yml create mode 100644 .github/workflows/dispatch.platform_uploads.yml create mode 100644 .github/workflows/dispatch.promote_release.yml create mode 100644 .github/workflows/main.prerelease.yml create mode 100644 .github/workflows/pr.require_label.yml create mode 100644 .github/workflows/pr.test.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index 983d12c..0000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: Maven CI/CD - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - -jobs: - build_and_test: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 8 - uses: actions/setup-java@v1 - with: - java-version: 1.8 - - - name: Build with Maven - run: mvn -B package --file pom.xml diff --git a/.github/workflows/call.github_release.yml b/.github/workflows/call.github_release.yml new file mode 100644 index 0000000..f53234b --- /dev/null +++ b/.github/workflows/call.github_release.yml @@ -0,0 +1,34 @@ +name: 'Call: GitHub Release' + +on: + workflow_call: + inputs: + release_mode: + description: 'Release mode' + required: true + type: string + version_bump: + description: 'Version bump' + required: false + type: string + promote_from: + description: 'Promote from' + required: false + type: string + outputs: + release_created: + description: 'Release created' + value: ${{ jobs.github_release.outputs.release_created }} + tag_name: + description: 'Tag name' + value: ${{ jobs.github_release.outputs.tag_name }} + +jobs: + github_release: + uses: Multiverse/Multiverse-Core/.github/workflows/generic.github_release.yml@main + secrets: inherit + with: + plugin_name: multiverse-netherportals + release_mode: ${{ inputs.release_mode }} + version_bump: ${{ inputs.version_bump }} + promote_from: ${{ inputs.promote_from }} diff --git a/.github/workflows/call.platform_uploads.yml b/.github/workflows/call.platform_uploads.yml new file mode 100644 index 0000000..21773d3 --- /dev/null +++ b/.github/workflows/call.platform_uploads.yml @@ -0,0 +1,75 @@ +name: 'Call: Platform Uploads' + +on: + workflow_call: + inputs: + target_tag: + description: 'Version to upload' + required: true + type: string + upload_modrinth: + description: 'Upload to modrinth.com' + required: true + type: string + upload_dbo: + description: 'Upload to dev.bukkit.org' + required: true + type: string + upload_hangar: + description: 'Upload to hangar.papermc.io' + required: true + type: string + secrets: + MODRINTH_TOKEN: + required: true + DBO_UPLOAD_API_TOKEN: + required: true + HANGAR_UPLOAD_TOKEN: + required: true + +jobs: + platform_uploads: + uses: Multiverse/Multiverse-Core/.github/workflows/generic.platform_uploads.yml@main + secrets: inherit + with: + plugin_name: multiverse-netherportals + + modrinth_project_id: vtawPsTo + modrinth_dependencies: > + [ + {"project_id": "3wmN97b8", "dependency_type": "required"} + {"slug": "8VMk6P0I", "type": "optional"} + ] + + dbo_project_id: 30783 + dbo_project_relations: > + [ + {"slug": "multiverse-core", "type": "requiredDependency"}, + {"slug": "multiverse-portals", "type": "optionalDependency"} + ] + + hangar_slug: Multiverse-NetherPortals + hangar_plugin_dependencies: > + { "PAPER": [ + { + "name": "Multiverse-Core", + "required": true, + "namespace": { + "owner": "Multiverse", + "slug": "Multiverse-Core" + } + }, + { + "name": "Multiverse-Portals", + "required": false, + "namespace": { + "owner": "Multiverse", + "slug": "Multiverse-Portals" + } + } + ]} + + target_tag: ${{ inputs.target_tag }} + upload_modrinth: ${{ inputs.upload_modrinth }} + upload_dbo: ${{ inputs.upload_dbo }} + upload_hangar: ${{ inputs.upload_hangar }} diff --git a/.github/workflows/dispatch.platform_uploads.yml b/.github/workflows/dispatch.platform_uploads.yml new file mode 100644 index 0000000..2eb99cb --- /dev/null +++ b/.github/workflows/dispatch.platform_uploads.yml @@ -0,0 +1,31 @@ +name: 'Dispatch: Platform Uploads' + +on: + workflow_dispatch: + inputs: + target_tag: + description: 'Version to upload' + required: true + type: string + upload_modrinth: + description: 'Upload to modrinth.com' + required: true + type: boolean + upload_dbo: + description: 'Upload to dev.bukkit.org' + required: true + type: boolean + upload_hangar: + description: 'Upload to hangar.papermc.io' + required: true + type: boolean + +jobs: + dispatch_platform_uploads: + uses: ./.github/workflows/call.platform_uploads.yml + secrets: inherit + with: + target_tag: ${{ github.event.inputs.target_tag }} + upload_modrinth: ${{ github.event.inputs.upload_modrinth }} + upload_dbo: ${{ github.event.inputs.upload_dbo }} + upload_hangar: ${{ github.event.inputs.upload_hangar }} diff --git a/.github/workflows/dispatch.promote_release.yml b/.github/workflows/dispatch.promote_release.yml new file mode 100644 index 0000000..0a59ca4 --- /dev/null +++ b/.github/workflows/dispatch.promote_release.yml @@ -0,0 +1,38 @@ +name: 'Dispatch: Promote Release' + +on: + workflow_dispatch: + inputs: + target_tag: + description: 'Version to promote' + required: true + +jobs: + check_version: + runs-on: ubuntu-latest + steps: + - name: Verify input version is prerelease + run: | + if [[ "${{ github.event.inputs.target_tag }}" != *"pre"* ]]; then + echo "Version must be a prerelease" + exit 1 + fi + + github_release: + needs: check_version + uses: ./.github/workflows/call.github_release.yml + secrets: inherit + with: + release_mode: promote + promote_from: ${{ github.event.inputs.target_tag }} + + platform_uploads: + needs: github_release + if: needs.github_release.outputs.release_created == 'true' + uses: ./.github/workflows/call.platform_uploads.yml + secrets: inherit + with: + target_tag: ${{ needs.github_release.outputs.tag_name }} + upload_modrinth: 'true' + upload_dbo: 'true' + upload_hangar: 'true' diff --git a/.github/workflows/main.prerelease.yml b/.github/workflows/main.prerelease.yml new file mode 100644 index 0000000..a3b474b --- /dev/null +++ b/.github/workflows/main.prerelease.yml @@ -0,0 +1,24 @@ +name: 'Main: Prerelease' + +on: + push: + branches: [main] + +jobs: + github_release_on_push: + uses: ./.github/workflows/call.github_release.yml + secrets: inherit + with: + release_mode: prerelease + version_bump: prlabel + + platform_uploads_on_push: + needs: github_release_on_push + if: needs.github_release_on_push.outputs.release_created == 'true' + uses: ./.github/workflows/call.platform_uploads.yml + secrets: inherit + with: + target_tag: ${{ needs.github_release_on_push.outputs.tag_name }} + upload_modrinth: 'true' + upload_dbo: 'false' + upload_hangar: 'false' diff --git a/.github/workflows/pr.require_label.yml b/.github/workflows/pr.require_label.yml new file mode 100644 index 0000000..b731584 --- /dev/null +++ b/.github/workflows/pr.require_label.yml @@ -0,0 +1,18 @@ +name: 'PR: Require Label' + +on: + pull_request: + types: [opened, labeled, unlabeled, synchronize] + branches: [main] + +jobs: + require_label: + runs-on: ubuntu-latest + steps: + - uses: mheap/github-action-required-labels@v2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + mode: exactly + count: 1 + labels: "release:major, release:minor, release:patch, no release" diff --git a/.github/workflows/pr.test.yml b/.github/workflows/pr.test.yml new file mode 100644 index 0000000..69a174f --- /dev/null +++ b/.github/workflows/pr.test.yml @@ -0,0 +1,36 @@ +name: 'PR: Test' + +on: + pull_request: + types: [opened, synchronize] + +jobs: + test: + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - uses: actions/checkout@v3 + + - uses: actions/setup-java@v3 + with: + java-version: '11' + distribution: 'adopt' + cache: gradle + + - name: Validate Gradle wrapper + uses: gradle/wrapper-validation-action@v1 + + - name: Run unit tests + uses: gradle/gradle-build-action@v2 + with: + arguments: build + env: + GITHUB_VERSION: pr${{ github.event.pull_request.number }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Artifact output + uses: actions/upload-artifact@v3 + with: + name: multiverse-core-pr${{ github.event.pull_request.number }} + path: build/libs/multiverse-core-pr${{ github.event.pull_request.number }}.jar From 556d1aefda5dc2470924912b82ae9363d3dacfd7 Mon Sep 17 00:00:00 2001 From: Ben Woo <30431861+benwoo1110@users.noreply.github.com> Date: Fri, 25 Aug 2023 00:02:25 +0800 Subject: [PATCH 36/53] Remove gradlew --- gradlew | 244 -------------------------------------------------------- 1 file changed, 244 deletions(-) delete mode 100644 gradlew diff --git a/gradlew b/gradlew deleted file mode 100644 index 65dcd68..0000000 --- a/gradlew +++ /dev/null @@ -1,244 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -# This is normally unused -# shellcheck disable=SC2034 -APP_BASE_NAME=${0##*/} -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" From fd6448ec5a65bffa5982014e26a59c8685ad263c Mon Sep 17 00:00:00 2001 From: Ben Woo <30431861+benwoo1110@users.noreply.github.com> Date: Fri, 25 Aug 2023 00:02:59 +0800 Subject: [PATCH 37/53] fix: Readd gradlew with exec permission --- gradlew | 244 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 244 insertions(+) create mode 100755 gradlew diff --git a/gradlew b/gradlew new file mode 100755 index 0000000..65dcd68 --- /dev/null +++ b/gradlew @@ -0,0 +1,244 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" From 524267afb1eb2b4e331f87d9e619912aef91586d Mon Sep 17 00:00:00 2001 From: Ben Woo <30431861+benwoo1110@users.noreply.github.com> Date: Fri, 25 Aug 2023 00:10:00 +0800 Subject: [PATCH 38/53] deps: Bump to mv-core 4.3.10 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 901029c..e3c3e75 100644 --- a/build.gradle +++ b/build.gradle @@ -31,7 +31,7 @@ dependencies { implementation 'org.bukkit:bukkit:1.13.2-R0.1-SNAPSHOT' // Multiverse-Core - implementation 'com.onarandombox.multiversecore:multiverse-core:4.3.9' + implementation 'com.onarandombox.multiversecore:multiverse-core:4.3.10' // Multiverse-Portals implementation 'com.onarandombox.multiverseportals:multiverse-portals:4.2.2' From b76aa576b7013f2c9bedb77c94ba005380ea741c Mon Sep 17 00:00:00 2001 From: Ben Woo <30431861+benwoo1110@users.noreply.github.com> Date: Fri, 25 Aug 2023 00:14:50 +0800 Subject: [PATCH 39/53] deps: Use older mv-core version --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index e3c3e75..e5e778c 100644 --- a/build.gradle +++ b/build.gradle @@ -31,7 +31,7 @@ dependencies { implementation 'org.bukkit:bukkit:1.13.2-R0.1-SNAPSHOT' // Multiverse-Core - implementation 'com.onarandombox.multiversecore:multiverse-core:4.3.10' + implementation 'com.onarandombox.multiversecore:Multiverse-Core:4.2.2' // Multiverse-Portals implementation 'com.onarandombox.multiverseportals:multiverse-portals:4.2.2' From a5f60427cecb73d162193d557819e46670aa4a1a Mon Sep 17 00:00:00 2001 From: Ben Woo <30431861+benwoo1110@users.noreply.github.com> Date: Fri, 25 Aug 2023 10:07:11 +0800 Subject: [PATCH 40/53] deps: Bump multiverse-core to 4.3.11-SNAPSHOT --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index e5e778c..3103932 100644 --- a/build.gradle +++ b/build.gradle @@ -31,7 +31,7 @@ dependencies { implementation 'org.bukkit:bukkit:1.13.2-R0.1-SNAPSHOT' // Multiverse-Core - implementation 'com.onarandombox.multiversecore:Multiverse-Core:4.2.2' + implementation 'com.onarandombox.multiversecore:multiverse-core:4.3.11-SNAPSHOT' // Multiverse-Portals implementation 'com.onarandombox.multiverseportals:multiverse-portals:4.2.2' From 7a3c8818424c3e6377035e53222bc42665ac1a62 Mon Sep 17 00:00:00 2001 From: Ben Woo <30431861+benwoo1110@users.noreply.github.com> Date: Fri, 25 Aug 2023 10:10:09 +0800 Subject: [PATCH 41/53] fix: Bump mv-core to 4.3.11 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 3103932..831e5f2 100644 --- a/build.gradle +++ b/build.gradle @@ -31,7 +31,7 @@ dependencies { implementation 'org.bukkit:bukkit:1.13.2-R0.1-SNAPSHOT' // Multiverse-Core - implementation 'com.onarandombox.multiversecore:multiverse-core:4.3.11-SNAPSHOT' + implementation 'com.onarandombox.multiversecore:multiverse-core:4.3.11' // Multiverse-Portals implementation 'com.onarandombox.multiverseportals:multiverse-portals:4.2.2' From c918adee80012aeea6dff1ce75e9b9b5984c6852 Mon Sep 17 00:00:00 2001 From: Ben Woo <30431861+benwoo1110@users.noreply.github.com> Date: Fri, 25 Aug 2023 10:54:59 +0800 Subject: [PATCH 42/53] ci: Fix modrinth dependencies --- .github/workflows/call.platform_uploads.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/call.platform_uploads.yml b/.github/workflows/call.platform_uploads.yml index 21773d3..0b14a05 100644 --- a/.github/workflows/call.platform_uploads.yml +++ b/.github/workflows/call.platform_uploads.yml @@ -37,8 +37,8 @@ jobs: modrinth_project_id: vtawPsTo modrinth_dependencies: > [ - {"project_id": "3wmN97b8", "dependency_type": "required"} - {"slug": "8VMk6P0I", "type": "optional"} + {"project_id": "3wmN97b8", "dependency_type": "required"}, + {"project_id": "8VMk6P0I", "type": "optional"} ] dbo_project_id: 30783 From da5aa475cb800c68d5cfd99522d9261280227219 Mon Sep 17 00:00:00 2001 From: Ben Woo <30431861+benwoo1110@users.noreply.github.com> Date: Fri, 25 Aug 2023 10:55:31 +0800 Subject: [PATCH 43/53] ci: Use generic workflow for test --- .github/workflows/pr.test.yml | 31 +++---------------------------- 1 file changed, 3 insertions(+), 28 deletions(-) diff --git a/.github/workflows/pr.test.yml b/.github/workflows/pr.test.yml index 69a174f..6feb66f 100644 --- a/.github/workflows/pr.test.yml +++ b/.github/workflows/pr.test.yml @@ -6,31 +6,6 @@ on: jobs: test: - runs-on: ubuntu-latest - permissions: - contents: read - steps: - - uses: actions/checkout@v3 - - - uses: actions/setup-java@v3 - with: - java-version: '11' - distribution: 'adopt' - cache: gradle - - - name: Validate Gradle wrapper - uses: gradle/wrapper-validation-action@v1 - - - name: Run unit tests - uses: gradle/gradle-build-action@v2 - with: - arguments: build - env: - GITHUB_VERSION: pr${{ github.event.pull_request.number }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Artifact output - uses: actions/upload-artifact@v3 - with: - name: multiverse-core-pr${{ github.event.pull_request.number }} - path: build/libs/multiverse-core-pr${{ github.event.pull_request.number }}.jar + uses: Multiverse/Multiverse-Core/.github/workflows/generic.test.yml@main + with: + plugin_name: multiverse-netherportals From cbb5f7e8e7f983d1f3a322603b1b1b0bf9503d69 Mon Sep 17 00:00:00 2001 From: Ben Woo <30431861+benwoo1110@users.noreply.github.com> Date: Fri, 25 Aug 2023 11:15:43 +0800 Subject: [PATCH 44/53] ci: Fix dependency type for modrinth --- .github/workflows/call.platform_uploads.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/call.platform_uploads.yml b/.github/workflows/call.platform_uploads.yml index 0b14a05..7951d3a 100644 --- a/.github/workflows/call.platform_uploads.yml +++ b/.github/workflows/call.platform_uploads.yml @@ -38,7 +38,7 @@ jobs: modrinth_dependencies: > [ {"project_id": "3wmN97b8", "dependency_type": "required"}, - {"project_id": "8VMk6P0I", "type": "optional"} + {"project_id": "8VMk6P0I", "dependency_type": "optional"} ] dbo_project_id: 30783 From 1e7c5d50086e9c4762372dc973221300e2fd8882 Mon Sep 17 00:00:00 2001 From: Ben Woo <30431861+benwoo1110@users.noreply.github.com> Date: Sun, 27 Aug 2023 23:33:05 +0800 Subject: [PATCH 45/53] Update hangar plugin deps bcu they changed the API --- .github/workflows/call.platform_uploads.yml | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/.github/workflows/call.platform_uploads.yml b/.github/workflows/call.platform_uploads.yml index 0b14a05..7acdd9d 100644 --- a/.github/workflows/call.platform_uploads.yml +++ b/.github/workflows/call.platform_uploads.yml @@ -54,18 +54,12 @@ jobs: { "name": "Multiverse-Core", "required": true, - "namespace": { - "owner": "Multiverse", - "slug": "Multiverse-Core" - } + "platforms": ["PAPER"] }, { "name": "Multiverse-Portals", "required": false, - "namespace": { - "owner": "Multiverse", - "slug": "Multiverse-Portals" - } + "platforms": ["PAPER"] } ]} From 6c2c896bfcd516d9b6b6112154f3a7b9f215fdb7 Mon Sep 17 00:00:00 2001 From: Zax71 Date: Fri, 23 Aug 2024 11:59:27 +0100 Subject: [PATCH 46/53] Refactor code and make end portal generation drop blocks --- .../listeners/MVNPEntityListener.java | 106 ++++++++++-------- .../listeners/MVNPPlayerListener.java | 24 +--- .../utils/EndPlatformCreator.java | 66 +++++++++++ 3 files changed, 127 insertions(+), 69 deletions(-) create mode 100644 src/main/java/com/onarandombox/MultiverseNetherPortals/utils/EndPlatformCreator.java diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java index 9ac0d9f..a5ee87b 100644 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java @@ -8,6 +8,7 @@ import com.onarandombox.MultiverseCore.event.MVPlayerTouchedPortalEvent; import com.onarandombox.MultiverseCore.utils.PermissionTools; import com.onarandombox.MultiverseNetherPortals.MultiverseNetherPortals; +import com.onarandombox.MultiverseNetherPortals.utils.EndPlatformCreator; import com.onarandombox.MultiverseNetherPortals.utils.MVEventRecord; import com.onarandombox.MultiverseNetherPortals.utils.MVLinkChecker; import com.onarandombox.MultiverseNetherPortals.utils.MVNameChecker; @@ -31,7 +32,6 @@ import java.util.Date; import java.util.HashMap; import java.util.Map; -import java.util.logging.Level; public class MVNPEntityListener implements Listener { @@ -299,14 +299,25 @@ public void onEntityPortal(EntityPortalEvent event) { return; } - Entity e = event.getEntity(); - Location originalTo = this.locationManipulation.getBlockLocation(event.getTo()); - Location currentLocation = this.locationManipulation.getBlockLocation(event.getFrom()); + // Some shortcuts for later + Entity entity = event.getEntity(); + Location toLocation = event.getTo(); + Location fromLocation = event.getFrom(); + + MultiverseWorld fromWorld = this.worldManager.getMVWorld(fromLocation.getWorld().getName()); + MultiverseWorld toWorld = this.worldManager.getMVWorld(toLocation.getWorld().getName()); + + Location originalTo = this.locationManipulation.getBlockLocation(toLocation); + Location currentLocation = this.locationManipulation.getBlockLocation(fromLocation); + + + // Don't mess with other people's stuff if (!plugin.isHandledByNetherPortals(currentLocation)) { return; } + // This is the entity event, don't teleport entities if we're not supposed to if (!this.plugin.isTeleportingEntities()) { event.setCancelled(true); return; @@ -323,18 +334,19 @@ public void onEntityPortal(EntityPortalEvent event) { return; } + // Are we allowed to use the nether portal travel agent? if (type == PortalType.NETHER) { try { Class.forName("org.bukkit.TravelAgent"); event.useTravelAgent(true); } catch (ClassNotFoundException ignore) { - Logging.fine("TravelAgent not available for EntityPortalEvent for " + e.getName()); + Logging.fine("TravelAgent not available for EntityPortalEvent for " + entity.getName()); } } String currentWorld = currentLocation.getWorld().getName(); String linkedWorld = this.plugin.getWorldLink(currentWorld, type); - Location newTo = getLocation(e, currentLocation, type, currentWorld, linkedWorld); + Location newTo = getLocation(entity, currentLocation, type, currentWorld, linkedWorld); // Gets the player spawn location from the portal spawn location if (newTo != null) { event.setTo(newTo); @@ -343,57 +355,53 @@ public void onEntityPortal(EntityPortalEvent event) { return; } - MultiverseWorld fromWorld = this.worldManager.getMVWorld(event.getFrom().getWorld().getName()); - MultiverseWorld toWorld = this.worldManager.getMVWorld(event.getTo().getWorld().getName()); - - if (!event.isCancelled()) { - if (fromWorld.getEnvironment() == World.Environment.THE_END && type == PortalType.ENDER) { - Logging.fine("Entity '" + e.getName() + "' will be teleported to the spawn of '" + toWorld.getName() + "' since they used an end exit portal."); - try { - Class.forName("org.bukkit.TravelAgent"); - event.getPortalTravelAgent().setCanCreatePortal(false); - } catch (ClassNotFoundException ignore) { - Logging.fine("TravelAgent not available for EntityPortalEvent for " + e.getName() + ". There may be a portal created at spawn."); - } + if (event.isCancelled()) { // Superfluous? + return; + } - event.setTo(toWorld.getSpawnLocation()); - } else if (fromWorld.getEnvironment() == World.Environment.NETHER && type == PortalType.NETHER) { - try { - Class.forName("org.bukkit.TravelAgent"); - event.getPortalTravelAgent().setCanCreatePortal(true); - event.setTo(event.getPortalTravelAgent().findOrCreate(event.getTo())); - } catch (ClassNotFoundException ignore) { - Logging.fine("TravelAgent not available for EntityPortalEvent for " + e.getName() + ". Their destination may not be correct."); - event.setTo(event.getTo()); - } - } else if (toWorld.getEnvironment() == World.Environment.THE_END && type == PortalType.ENDER) { - Location loc = new Location(event.getTo().getWorld(), 100, 50, 0); // This is the vanilla location for obsidian platform. - event.setTo(loc); - Block block = loc.getBlock(); - for (int x = block.getX() - 2; x <= block.getX() + 2; x++) { - for (int z = block.getZ() - 2; z <= block.getZ() + 2; z++) { - Block platformBlock = loc.getWorld().getBlockAt(x, block.getY() - 1, z); - if (platformBlock.getType() != Material.OBSIDIAN) { - platformBlock.setType(Material.OBSIDIAN); - } - for (int yMod = 1; yMod <= 3; yMod++) { - Block b = platformBlock.getRelative(BlockFace.UP, yMod); - if (b.getType() != Material.AIR) { - b.setType(Material.AIR); - } - } - } - } + // If we are going to the overworld from the end + if (fromWorld.getEnvironment() == World.Environment.THE_END && type == PortalType.ENDER) { + Logging.fine("Entity '" + entity.getName() + "' will be teleported to the spawn of '" + toWorld.getName() + "' since they used an end exit portal."); + try { + Class.forName("org.bukkit.TravelAgent"); + event.getPortalTravelAgent().setCanCreatePortal(false); + } catch (ClassNotFoundException ignore) { + Logging.fine("TravelAgent not available for EntityPortalEvent for " + entity.getName() + ". There may be a portal created at spawn."); } + + event.setTo(toWorld.getSpawnLocation()); + return; + } + + // If we are going to the overworld from the nether + if (fromWorld.getEnvironment() == World.Environment.NETHER && type == PortalType.NETHER) { + try { + Class.forName("org.bukkit.TravelAgent"); + event.getPortalTravelAgent().setCanCreatePortal(true); + event.setTo(event.getPortalTravelAgent().findOrCreate(toLocation)); + } catch (ClassNotFoundException ignore) { + Logging.fine("TravelAgent not available for EntityPortalEvent for " + entity.getName() + ". Their destination may not be correct."); + event.setTo(toLocation); + } + + return; + } + + // If we are going to the end from anywhere + if (toWorld.getEnvironment() == World.Environment.THE_END && type == PortalType.ENDER) { + Location spawnLocation = EndPlatformCreator.getVanillaLocation(toWorld); + event.setTo(spawnLocation); + EndPlatformCreator.createEndPlatform(spawnLocation); + return; } } @EventHandler public void onEntityPortalExit(EntityPortalExitEvent event) { if (event.getEntity() instanceof Player) { - Player p = (Player) event.getEntity(); - eventRecord.removeFromRecord(PortalType.ENDER, p.getUniqueId()); - eventRecord.removeFromRecord(PortalType.NETHER, p.getUniqueId()); + Player player = (Player) event.getEntity(); + eventRecord.removeFromRecord(PortalType.ENDER, player.getUniqueId()); + eventRecord.removeFromRecord(PortalType.NETHER, player.getUniqueId()); } } } diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPPlayerListener.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPPlayerListener.java index afaf1c0..76f90ab 100644 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPPlayerListener.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPPlayerListener.java @@ -5,17 +5,15 @@ import com.onarandombox.MultiverseCore.api.MultiverseWorld; import com.onarandombox.MultiverseCore.utils.PermissionTools; import com.onarandombox.MultiverseNetherPortals.MultiverseNetherPortals; +import com.onarandombox.MultiverseNetherPortals.utils.EndPlatformCreator; import com.onarandombox.MultiverseNetherPortals.utils.MVLinkChecker; import com.onarandombox.MultiverseNetherPortals.utils.MVNameChecker; import org.bukkit.Location; -import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.PortalType; import org.bukkit.World; import org.bukkit.advancement.Advancement; import org.bukkit.advancement.AdvancementProgress; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -138,23 +136,9 @@ public void onPlayerPortal(PlayerPortalEvent event) { event.setTo(event.getTo()); } } else if (toWorld.getEnvironment() == World.Environment.THE_END && type == PortalType.ENDER) { - Location loc = new Location(event.getTo().getWorld(), 100, 50, 0); // This is the vanilla location for obsidian platform. - event.setTo(loc); - Block block = loc.getBlock(); - for (int x = block.getX() - 2; x <= block.getX() + 2; x++) { - for (int z = block.getZ() - 2; z <= block.getZ() + 2; z++) { - Block platformBlock = loc.getWorld().getBlockAt(x, block.getY() - 1, z); - if (platformBlock.getType() != Material.OBSIDIAN) { - platformBlock.setType(Material.OBSIDIAN); - } - for (int yMod = 1; yMod <= 3; yMod++) { - Block b = platformBlock.getRelative(BlockFace.UP, yMod); - if (b.getType() != Material.AIR) { - b.setType(Material.AIR); - } - } - } - } + Location spawnLocation = EndPlatformCreator.getVanillaLocation(event.getTo().getWorld()); + event.setTo(spawnLocation); + EndPlatformCreator.createEndPlatform(spawnLocation); } // Advancements need to be triggered manually diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/EndPlatformCreator.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/EndPlatformCreator.java new file mode 100644 index 0000000..60bda9f --- /dev/null +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/EndPlatformCreator.java @@ -0,0 +1,66 @@ +package com.onarandombox.MultiverseNetherPortals.utils; + +import com.dumptruckman.minecraft.util.Logging; +import com.onarandombox.MultiverseCore.api.MultiverseWorld; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; + +public class EndPlatformCreator { + + /** + * Creates an end platform at the specified {@code Block} + * @param spawnLocation The {@code Block} that the player will spawn at. + */ + public static void createEndPlatform(Block spawnLocation) { + Logging.fine("Creating an end platform at " + spawnLocation.toString()); + + // Is this code even required?! - Past self + for (int x = spawnLocation.getX() - 2; x <= spawnLocation.getX() + 2; x++) { + for (int z = spawnLocation.getZ() - 2; z <= spawnLocation.getZ() + 2; z++) { + Block platformBlock = spawnLocation.getWorld().getBlockAt(x, spawnLocation.getY() - 1, z); + Logging.finest("Placing blocks at " + platformBlock); + + // Create platform + if (platformBlock.getType() != Material.OBSIDIAN) { + platformBlock.setType(Material.OBSIDIAN); + Logging.finest("Placing obsidian at " + platformBlock); + } + + // Clear space above platform + for (int yMod = 1; yMod <= 3; yMod++) { + Block b = platformBlock.getRelative(BlockFace.UP, yMod); + if (b.getType() != Material.AIR) { + b.breakNaturally(); + Logging.warning("Breaking block at " + platformBlock); + } + } + } + } + } + + + /** + * Creates an end platform at the specified {@code Location} + * @param spawnLocation The {@code Location} that the player will spawn at. + */ + public static void createEndPlatform(Location spawnLocation) { + createEndPlatform(spawnLocation.getBlock()); + } + + /** + * The default vanilla location for the end platform + */ + public static Location getVanillaLocation(World world) { + return new Location(world, 100, 49, 0, 90, 0); + } + + /** + * The default vanilla location for the end platform + */ + public static Location getVanillaLocation(MultiverseWorld world) { + return getVanillaLocation(world.getCBWorld()); + } +} From 1180c9652e582f74531c7c183755ce56f37b127a Mon Sep 17 00:00:00 2001 From: Zax71 Date: Fri, 23 Aug 2024 13:11:06 +0100 Subject: [PATCH 47/53] Change warning to finest & remove nonsensical comment --- .../MultiverseNetherPortals/utils/EndPlatformCreator.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/EndPlatformCreator.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/EndPlatformCreator.java index 60bda9f..37c1fdd 100644 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/EndPlatformCreator.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/EndPlatformCreator.java @@ -17,7 +17,6 @@ public class EndPlatformCreator { public static void createEndPlatform(Block spawnLocation) { Logging.fine("Creating an end platform at " + spawnLocation.toString()); - // Is this code even required?! - Past self for (int x = spawnLocation.getX() - 2; x <= spawnLocation.getX() + 2; x++) { for (int z = spawnLocation.getZ() - 2; z <= spawnLocation.getZ() + 2; z++) { Block platformBlock = spawnLocation.getWorld().getBlockAt(x, spawnLocation.getY() - 1, z); @@ -34,7 +33,7 @@ public static void createEndPlatform(Block spawnLocation) { Block b = platformBlock.getRelative(BlockFace.UP, yMod); if (b.getType() != Material.AIR) { b.breakNaturally(); - Logging.warning("Breaking block at " + platformBlock); + Logging.finest("Breaking block at " + platformBlock); } } } From 6a09b698eb9cc3539199606e4464a5cda21282ca Mon Sep 17 00:00:00 2001 From: Zax71 Date: Fri, 23 Aug 2024 13:17:15 +0100 Subject: [PATCH 48/53] Remove superfluous `isCancelled() check --- .../MultiverseNetherPortals/listeners/MVNPEntityListener.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java index a5ee87b..70b4c49 100644 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java @@ -355,10 +355,6 @@ public void onEntityPortal(EntityPortalEvent event) { return; } - if (event.isCancelled()) { // Superfluous? - return; - } - // If we are going to the overworld from the end if (fromWorld.getEnvironment() == World.Environment.THE_END && type == PortalType.ENDER) { Logging.fine("Entity '" + entity.getName() + "' will be teleported to the spawn of '" + toWorld.getName() + "' since they used an end exit portal."); From 44da5208db983107aa59ebfcd98a264c200c662d Mon Sep 17 00:00:00 2001 From: Zax71 Date: Fri, 23 Aug 2024 13:47:04 +0100 Subject: [PATCH 49/53] Add config option for the end platform dropping blocks & warn if getTo is null --- .../MultiverseNetherPortals.java | 10 ++++++++++ .../listeners/MVNPEntityListener.java | 9 +++++++-- .../listeners/MVNPPlayerListener.java | 2 +- .../utils/EndPlatformCreator.java | 20 +++++++++++++------ 4 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/MultiverseNetherPortals.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/MultiverseNetherPortals.java index 80ac620..af4066e 100644 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/MultiverseNetherPortals.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/MultiverseNetherPortals.java @@ -113,6 +113,7 @@ public void loadConfig() { this.setTeleportingEntities(this.isTeleportingEntities()); this.setSendingNoDestinationMessage(this.isSendingNoDestinationMessage()); this.setSendingDisabledPortalMessage(this.isSendingDisabledPortalMessage()); + this.setEndPlatformDropBlocks(this.isEndPlatformDropBlocks()); this.setNetherPrefix(this.getNetherPrefix()); this.setNetherSuffix(this.getNetherSuffix()); @@ -334,6 +335,14 @@ public void setSendingNoDestinationMessage(boolean sendNoDestinationMessage) { this.MVNPConfiguration.set("send_no_destination_message", sendNoDestinationMessage); } + public boolean isEndPlatformDropBlocks() { + return this.MVNPConfiguration.getBoolean("end_platform_drop_blocks", true); + } + + public void setEndPlatformDropBlocks(boolean endPlatformDropBlocks) { + this.MVNPConfiguration.set("end_platform_drop_blocks", endPlatformDropBlocks); + } + public boolean isHandledByNetherPortals(Location l) { if (multiversePortals != null) { // Catch errors which could occur if classes aren't present or are missing methods. @@ -398,6 +407,7 @@ public String dumpVersionInfo(String buffer) { buffer += logAndAddToPasteBinBuffer("Teleport Entities: " + this.isTeleportingEntities()); buffer += logAndAddToPasteBinBuffer("Send Disabled Portal Message: " + this.isSendingDisabledPortalMessage()); buffer += logAndAddToPasteBinBuffer("Send No Destination Message: " + this.isSendingNoDestinationMessage()); + buffer += logAndAddToPasteBinBuffer("End platform drops blocks: " + this.isEndPlatformDropBlocks()); buffer += logAndAddToPasteBinBuffer("Special Code: FRN001"); return buffer; } diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java index 70b4c49..d74e8e2 100644 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java @@ -302,9 +302,14 @@ public void onEntityPortal(EntityPortalEvent event) { // Some shortcuts for later Entity entity = event.getEntity(); - Location toLocation = event.getTo(); + @Nullable Location toLocation = event.getTo(); Location fromLocation = event.getFrom(); + if (toLocation == null) { + Logging.warning("ToLocation in EntityPortalEvent is null."); + return; + } + MultiverseWorld fromWorld = this.worldManager.getMVWorld(fromLocation.getWorld().getName()); MultiverseWorld toWorld = this.worldManager.getMVWorld(toLocation.getWorld().getName()); @@ -387,7 +392,7 @@ public void onEntityPortal(EntityPortalEvent event) { if (toWorld.getEnvironment() == World.Environment.THE_END && type == PortalType.ENDER) { Location spawnLocation = EndPlatformCreator.getVanillaLocation(toWorld); event.setTo(spawnLocation); - EndPlatformCreator.createEndPlatform(spawnLocation); + EndPlatformCreator.createEndPlatform(spawnLocation, plugin.isEndPlatformDropBlocks()); return; } } diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPPlayerListener.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPPlayerListener.java index 76f90ab..9c04e70 100644 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPPlayerListener.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPPlayerListener.java @@ -138,7 +138,7 @@ public void onPlayerPortal(PlayerPortalEvent event) { } else if (toWorld.getEnvironment() == World.Environment.THE_END && type == PortalType.ENDER) { Location spawnLocation = EndPlatformCreator.getVanillaLocation(event.getTo().getWorld()); event.setTo(spawnLocation); - EndPlatformCreator.createEndPlatform(spawnLocation); + EndPlatformCreator.createEndPlatform(spawnLocation, plugin.isEndPlatformDropBlocks()); } // Advancements need to be triggered manually diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/EndPlatformCreator.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/EndPlatformCreator.java index 37c1fdd..face112 100644 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/EndPlatformCreator.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/EndPlatformCreator.java @@ -2,6 +2,7 @@ import com.dumptruckman.minecraft.util.Logging; import com.onarandombox.MultiverseCore.api.MultiverseWorld; +import com.onarandombox.MultiverseNetherPortals.MultiverseNetherPortals; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; @@ -12,9 +13,11 @@ public class EndPlatformCreator { /** * Creates an end platform at the specified {@code Block} + * * @param spawnLocation The {@code Block} that the player will spawn at. + * @param dropEndBlocks If the platform should drop the broken blocks or delete them */ - public static void createEndPlatform(Block spawnLocation) { + public static void createEndPlatform(Block spawnLocation, boolean dropEndBlocks) { Logging.fine("Creating an end platform at " + spawnLocation.toString()); for (int x = spawnLocation.getX() - 2; x <= spawnLocation.getX() + 2; x++) { @@ -30,9 +33,14 @@ public static void createEndPlatform(Block spawnLocation) { // Clear space above platform for (int yMod = 1; yMod <= 3; yMod++) { - Block b = platformBlock.getRelative(BlockFace.UP, yMod); - if (b.getType() != Material.AIR) { - b.breakNaturally(); + Block block = platformBlock.getRelative(BlockFace.UP, yMod); + if (block.getType() != Material.AIR) { + if (dropEndBlocks) { + block.breakNaturally(); + } else { + block.setType(Material.AIR); + } + Logging.finest("Breaking block at " + platformBlock); } } @@ -45,8 +53,8 @@ public static void createEndPlatform(Block spawnLocation) { * Creates an end platform at the specified {@code Location} * @param spawnLocation The {@code Location} that the player will spawn at. */ - public static void createEndPlatform(Location spawnLocation) { - createEndPlatform(spawnLocation.getBlock()); + public static void createEndPlatform(Location spawnLocation, boolean dropEndBlocks) { + createEndPlatform(spawnLocation.getBlock(), dropEndBlocks); } /** From 88b932646a5e7988932afaab75e8bf36c166b9dc Mon Sep 17 00:00:00 2001 From: Ben Woo <30431861+benwoo1110@users.noreply.github.com> Date: Tue, 27 Aug 2024 21:39:41 +0800 Subject: [PATCH 50/53] Fix wrong destination for entity portal teleport and make variables clearer --- .../listeners/MVNPEntityListener.java | 77 +++++++++---------- 1 file changed, 37 insertions(+), 40 deletions(-) diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java index d74e8e2..4b7927e 100644 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java @@ -1,6 +1,7 @@ package com.onarandombox.MultiverseNetherPortals.listeners; import com.dumptruckman.minecraft.util.Logging; +import com.onarandombox.MultiverseCore.MVWorld; import com.onarandombox.MultiverseCore.api.LocationManipulation; import com.onarandombox.MultiverseCore.api.MVWorldManager; import com.onarandombox.MultiverseCore.api.MultiverseMessaging; @@ -299,26 +300,13 @@ public void onEntityPortal(EntityPortalEvent event) { return; } - // Some shortcuts for later - Entity entity = event.getEntity(); - - @Nullable Location toLocation = event.getTo(); - Location fromLocation = event.getFrom(); - - if (toLocation == null) { - Logging.warning("ToLocation in EntityPortalEvent is null."); + if (event.getTo() == null) { + Logging.warning("getTo() location in EntityPortalEvent is null."); return; } - MultiverseWorld fromWorld = this.worldManager.getMVWorld(fromLocation.getWorld().getName()); - MultiverseWorld toWorld = this.worldManager.getMVWorld(toLocation.getWorld().getName()); - - Location originalTo = this.locationManipulation.getBlockLocation(toLocation); - Location currentLocation = this.locationManipulation.getBlockLocation(fromLocation); - - // Don't mess with other people's stuff - if (!plugin.isHandledByNetherPortals(currentLocation)) { + if (!plugin.isHandledByNetherPortals(event.getFrom())) { return; } @@ -328,12 +316,26 @@ public void onEntityPortal(EntityPortalEvent event) { return; } + // Some shortcuts for later + Entity entity = event.getEntity(); + + Location fromLocation = this.locationManipulation.getBlockLocation(event.getFrom()); + Location originalToLocation = this.locationManipulation.getBlockLocation(event.getTo()); + + World fromWorld = fromLocation.getWorld(); + World originalToWorld = originalToLocation.getWorld(); + + if (fromWorld == null || originalToWorld == null) { + Logging.warning("from/to world is null in EntityPortalEvent for %s", entity.getName()); + return; + } + PortalType type; - if (originalTo.getWorld().getEnvironment() == World.Environment.NETHER - || (currentLocation.getWorld().getEnvironment() == World.Environment.NETHER && originalTo.getWorld().getEnvironment() == World.Environment.NORMAL)) { + if (fromWorld.getEnvironment() == World.Environment.NETHER + || (fromWorld.getEnvironment() == World.Environment.NETHER && originalToWorld.getEnvironment() == World.Environment.NORMAL)) { type = PortalType.NETHER; - } else if (originalTo.getWorld().getEnvironment() == World.Environment.THE_END - || (currentLocation.getWorld().getEnvironment() == World.Environment.THE_END && originalTo.getWorld().getEnvironment() == World.Environment.NORMAL)) { + } else if (fromWorld.getEnvironment() == World.Environment.THE_END + || (fromWorld.getEnvironment() == World.Environment.THE_END && originalToWorld.getEnvironment() == World.Environment.NORMAL)) { type = PortalType.ENDER; } else { return; @@ -349,51 +351,46 @@ public void onEntityPortal(EntityPortalEvent event) { } } - String currentWorld = currentLocation.getWorld().getName(); - String linkedWorld = this.plugin.getWorldLink(currentWorld, type); - Location newTo = getLocation(entity, currentLocation, type, currentWorld, linkedWorld); // Gets the player spawn location from the portal spawn location + String fromWorldName = fromWorld.getName(); + String linkedWorldName = this.plugin.getWorldLink(fromWorldName, type); + Location newToLocation = getLocation(entity, fromLocation, type, fromWorldName, linkedWorldName); // Gets the player spawn location from the portal spawn location - if (newTo != null) { - event.setTo(newTo); - } else { + // If we can't get a valid location, cancel the event + if (newToLocation == null) { event.setCancelled(true); return; } + event.setTo(newToLocation); + MultiverseWorld newToWorld = this.worldManager.getMVWorld(newToLocation.getWorld()); + // If we are going to the overworld from the end if (fromWorld.getEnvironment() == World.Environment.THE_END && type == PortalType.ENDER) { - Logging.fine("Entity '" + entity.getName() + "' will be teleported to the spawn of '" + toWorld.getName() + "' since they used an end exit portal."); + Logging.fine("Entity '" + entity.getName() + "' will be teleported to the spawn of '" + newToWorld.getName() + "' since they used an end exit portal."); try { Class.forName("org.bukkit.TravelAgent"); event.getPortalTravelAgent().setCanCreatePortal(false); } catch (ClassNotFoundException ignore) { Logging.fine("TravelAgent not available for EntityPortalEvent for " + entity.getName() + ". There may be a portal created at spawn."); } - - event.setTo(toWorld.getSpawnLocation()); - return; + event.setTo(newToWorld.getSpawnLocation()); } - // If we are going to the overworld from the nether - if (fromWorld.getEnvironment() == World.Environment.NETHER && type == PortalType.NETHER) { + else if (fromWorld.getEnvironment() == World.Environment.NETHER && type == PortalType.NETHER) { try { Class.forName("org.bukkit.TravelAgent"); event.getPortalTravelAgent().setCanCreatePortal(true); - event.setTo(event.getPortalTravelAgent().findOrCreate(toLocation)); + event.setTo(event.getPortalTravelAgent().findOrCreate(newToLocation)); } catch (ClassNotFoundException ignore) { Logging.fine("TravelAgent not available for EntityPortalEvent for " + entity.getName() + ". Their destination may not be correct."); - event.setTo(toLocation); + event.setTo(newToLocation); } - - return; } - // If we are going to the end from anywhere - if (toWorld.getEnvironment() == World.Environment.THE_END && type == PortalType.ENDER) { - Location spawnLocation = EndPlatformCreator.getVanillaLocation(toWorld); + else if (newToWorld.getEnvironment() == World.Environment.THE_END && type == PortalType.ENDER) { + Location spawnLocation = EndPlatformCreator.getVanillaLocation(newToWorld); event.setTo(spawnLocation); EndPlatformCreator.createEndPlatform(spawnLocation, plugin.isEndPlatformDropBlocks()); - return; } } From c5e53ad1af962a2d2ebf337d3c4a7776cb145db0 Mon Sep 17 00:00:00 2001 From: Ben Woo <30431861+benwoo1110@users.noreply.github.com> Date: Tue, 27 Aug 2024 21:50:50 +0800 Subject: [PATCH 51/53] Fix portal type checking logic --- .../MultiverseNetherPortals/listeners/MVNPEntityListener.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java index 4b7927e..8db94c4 100644 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java @@ -331,10 +331,10 @@ public void onEntityPortal(EntityPortalEvent event) { } PortalType type; - if (fromWorld.getEnvironment() == World.Environment.NETHER + if (originalToWorld.getEnvironment() == World.Environment.NETHER || (fromWorld.getEnvironment() == World.Environment.NETHER && originalToWorld.getEnvironment() == World.Environment.NORMAL)) { type = PortalType.NETHER; - } else if (fromWorld.getEnvironment() == World.Environment.THE_END + } else if (originalToWorld.getEnvironment() == World.Environment.THE_END || (fromWorld.getEnvironment() == World.Environment.THE_END && originalToWorld.getEnvironment() == World.Environment.NORMAL)) { type = PortalType.ENDER; } else { From caab0667dff46bb291b639a6b797cee46937fdda Mon Sep 17 00:00:00 2001 From: Ben Woo <30431861+benwoo1110@users.noreply.github.com> Date: Sat, 31 Aug 2024 15:49:36 +0800 Subject: [PATCH 52/53] Fix entity location when going through end portal --- .../listeners/MVNPEntityListener.java | 7 ++-- .../listeners/MVNPPlayerListener.java | 36 ++++++++++--------- .../utils/EndPlatformCreator.java | 13 ++++--- 3 files changed, 30 insertions(+), 26 deletions(-) diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java index 8db94c4..af1f6df 100644 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java @@ -316,11 +316,10 @@ public void onEntityPortal(EntityPortalEvent event) { return; } - // Some shortcuts for later Entity entity = event.getEntity(); - Location fromLocation = this.locationManipulation.getBlockLocation(event.getFrom()); - Location originalToLocation = this.locationManipulation.getBlockLocation(event.getTo()); + Location fromLocation = event.getFrom(); + Location originalToLocation = event.getTo(); World fromWorld = fromLocation.getWorld(); World originalToWorld = originalToLocation.getWorld(); @@ -388,7 +387,7 @@ else if (fromWorld.getEnvironment() == World.Environment.NETHER && type == Porta } // If we are going to the end from anywhere else if (newToWorld.getEnvironment() == World.Environment.THE_END && type == PortalType.ENDER) { - Location spawnLocation = EndPlatformCreator.getVanillaLocation(newToWorld); + Location spawnLocation = EndPlatformCreator.getVanillaLocation(entity, newToWorld); event.setTo(spawnLocation); EndPlatformCreator.createEndPlatform(spawnLocation, plugin.isEndPlatformDropBlocks()); } diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPPlayerListener.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPPlayerListener.java index 9c04e70..c63433e 100644 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPPlayerListener.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPPlayerListener.java @@ -64,12 +64,14 @@ public void onPlayerPortal(PlayerPortalEvent event) { return; } + Player player = event.getPlayer(); + if (type == PortalType.NETHER) { try { Class.forName("org.bukkit.TravelAgent"); event.useTravelAgent(true); } catch (ClassNotFoundException ignore) { - Logging.fine("TravelAgent not available for PlayerPortalEvent for " + event.getPlayer().getName()); + Logging.fine("TravelAgent not available for PlayerPortalEvent for " + player.getName()); } } @@ -79,24 +81,24 @@ public void onPlayerPortal(PlayerPortalEvent event) { if (currentWorld.equalsIgnoreCase(linkedWorld)) { newTo = null; } else if (linkedWorld != null) { - newTo = this.linkChecker.findNewTeleportLocation(currentLocation, linkedWorld, event.getPlayer()); + newTo = this.linkChecker.findNewTeleportLocation(currentLocation, linkedWorld, player); } else if (this.nameChecker.isValidNetherName(currentWorld)) { if (type == PortalType.NETHER) { - newTo = this.linkChecker.findNewTeleportLocation(currentLocation, this.nameChecker.getNormalName(currentWorld, PortalType.NETHER), event.getPlayer()); + newTo = this.linkChecker.findNewTeleportLocation(currentLocation, this.nameChecker.getNormalName(currentWorld, PortalType.NETHER), player); } else { - newTo = this.linkChecker.findNewTeleportLocation(currentLocation, this.nameChecker.getEndName(this.nameChecker.getNormalName(currentWorld, PortalType.NETHER)), event.getPlayer()); + newTo = this.linkChecker.findNewTeleportLocation(currentLocation, this.nameChecker.getEndName(this.nameChecker.getNormalName(currentWorld, PortalType.NETHER)), player); } } else if (this.nameChecker.isValidEndName(currentWorld)) { if (type == PortalType.NETHER) { - newTo = this.linkChecker.findNewTeleportLocation(currentLocation, this.nameChecker.getNetherName(this.nameChecker.getNormalName(currentWorld, PortalType.ENDER)), event.getPlayer()); + newTo = this.linkChecker.findNewTeleportLocation(currentLocation, this.nameChecker.getNetherName(this.nameChecker.getNormalName(currentWorld, PortalType.ENDER)), player); } else { - newTo = this.linkChecker.findNewTeleportLocation(currentLocation, this.nameChecker.getNormalName(currentWorld, PortalType.ENDER), event.getPlayer()); + newTo = this.linkChecker.findNewTeleportLocation(currentLocation, this.nameChecker.getNormalName(currentWorld, PortalType.ENDER), player); } } else { if (type == PortalType.ENDER) { - newTo = this.linkChecker.findNewTeleportLocation(currentLocation, this.nameChecker.getEndName(currentWorld), event.getPlayer()); + newTo = this.linkChecker.findNewTeleportLocation(currentLocation, this.nameChecker.getEndName(currentWorld), player); } else { - newTo = this.linkChecker.findNewTeleportLocation(currentLocation, this.nameChecker.getNetherName(currentWorld), event.getPlayer()); + newTo = this.linkChecker.findNewTeleportLocation(currentLocation, this.nameChecker.getNetherName(currentWorld), player); } } @@ -112,17 +114,17 @@ public void onPlayerPortal(PlayerPortalEvent event) { if (!event.isCancelled()) { if (fromWorld.getEnvironment() == World.Environment.THE_END && type == PortalType.ENDER) { - Logging.fine("Player '" + event.getPlayer().getName() + "' will be teleported to the spawn of '" + toWorld.getName() + "' since they used an end exit portal."); + Logging.fine("Player '" + player.getName() + "' will be teleported to the spawn of '" + toWorld.getName() + "' since they used an end exit portal."); try { Class.forName("org.bukkit.TravelAgent"); event.getPortalTravelAgent().setCanCreatePortal(false); } catch (ClassNotFoundException ignore) { - Logging.fine("TravelAgent not available for PlayerPortalEvent for " + event.getPlayer().getName() + ". There may be a portal created at spawn."); + Logging.fine("TravelAgent not available for PlayerPortalEvent for " + player.getName() + ". There may be a portal created at spawn."); } if (toWorld.getBedRespawn() - && event.getPlayer().getBedSpawnLocation() != null - && event.getPlayer().getBedSpawnLocation().getWorld().getUID() == toWorld.getCBWorld().getUID()) { - event.setTo(event.getPlayer().getBedSpawnLocation()); + && player.getBedSpawnLocation() != null + && player.getBedSpawnLocation().getWorld().getUID() == toWorld.getCBWorld().getUID()) { + event.setTo(player.getBedSpawnLocation()); } else { event.setTo(toWorld.getSpawnLocation()); } @@ -132,20 +134,20 @@ public void onPlayerPortal(PlayerPortalEvent event) { event.getPortalTravelAgent().setCanCreatePortal(true); event.setTo(event.getPortalTravelAgent().findOrCreate(event.getTo())); } catch (ClassNotFoundException ignore) { - Logging.fine("TravelAgent not available for PlayerPortalEvent for " + event.getPlayer().getName() + ". Their destination may not be correct."); + Logging.fine("TravelAgent not available for PlayerPortalEvent for " + player.getName() + ". Their destination may not be correct."); event.setTo(event.getTo()); } } else if (toWorld.getEnvironment() == World.Environment.THE_END && type == PortalType.ENDER) { - Location spawnLocation = EndPlatformCreator.getVanillaLocation(event.getTo().getWorld()); + Location spawnLocation = EndPlatformCreator.getVanillaLocation(player, event.getTo().getWorld()); event.setTo(spawnLocation); EndPlatformCreator.createEndPlatform(spawnLocation, plugin.isEndPlatformDropBlocks()); } // Advancements need to be triggered manually if (type == PortalType.NETHER && event.getTo().getWorld().getEnvironment() == World.Environment.NETHER) { - awardAdvancement(event.getPlayer(), enterNetherAdvancement, ENTER_NETHER_CRITERIA); + awardAdvancement(player, enterNetherAdvancement, ENTER_NETHER_CRITERIA); } else if (type == PortalType.ENDER && event.getTo().getWorld().getEnvironment() == World.Environment.THE_END) { - awardAdvancement(event.getPlayer(), enterEndAdvancement, ENTER_END_CRITERIA); + awardAdvancement(player, enterEndAdvancement, ENTER_END_CRITERIA); } } } diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/EndPlatformCreator.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/EndPlatformCreator.java index face112..1ea9854 100644 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/EndPlatformCreator.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/EndPlatformCreator.java @@ -2,12 +2,13 @@ import com.dumptruckman.minecraft.util.Logging; import com.onarandombox.MultiverseCore.api.MultiverseWorld; -import com.onarandombox.MultiverseNetherPortals.MultiverseNetherPortals; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; public class EndPlatformCreator { @@ -60,14 +61,16 @@ public static void createEndPlatform(Location spawnLocation, boolean dropEndBloc /** * The default vanilla location for the end platform */ - public static Location getVanillaLocation(World world) { - return new Location(world, 100, 49, 0, 90, 0); + public static Location getVanillaLocation(Entity entity, World world) { + return entity instanceof Player + ? new Location(world, 100, 49, 0, 90, 0) + : new Location(world, 100.5, 50, 0.5, 90, 0); } /** * The default vanilla location for the end platform */ - public static Location getVanillaLocation(MultiverseWorld world) { - return getVanillaLocation(world.getCBWorld()); + public static Location getVanillaLocation(Entity entity, MultiverseWorld world) { + return getVanillaLocation(entity, world.getCBWorld()); } } From 386fe87db4d6f90c525f7c032fddefc3a0984414 Mon Sep 17 00:00:00 2001 From: Ben Woo <30431861+benwoo1110@users.noreply.github.com> Date: Sat, 31 Aug 2024 19:32:03 +0800 Subject: [PATCH 53/53] Make end portal teleport closer to vanilla behavior --- .../listeners/MVNPEntityListener.java | 2 +- .../listeners/MVNPPlayerListener.java | 2 +- .../utils/EndPlatformCreator.java | 23 +++++-------------- 3 files changed, 8 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java index af1f6df..e44a28f 100644 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPEntityListener.java @@ -389,7 +389,7 @@ else if (fromWorld.getEnvironment() == World.Environment.NETHER && type == Porta else if (newToWorld.getEnvironment() == World.Environment.THE_END && type == PortalType.ENDER) { Location spawnLocation = EndPlatformCreator.getVanillaLocation(entity, newToWorld); event.setTo(spawnLocation); - EndPlatformCreator.createEndPlatform(spawnLocation, plugin.isEndPlatformDropBlocks()); + EndPlatformCreator.createEndPlatform(spawnLocation.getWorld(), plugin.isEndPlatformDropBlocks()); } } diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPPlayerListener.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPPlayerListener.java index c63433e..297541d 100644 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPPlayerListener.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/listeners/MVNPPlayerListener.java @@ -140,7 +140,7 @@ public void onPlayerPortal(PlayerPortalEvent event) { } else if (toWorld.getEnvironment() == World.Environment.THE_END && type == PortalType.ENDER) { Location spawnLocation = EndPlatformCreator.getVanillaLocation(player, event.getTo().getWorld()); event.setTo(spawnLocation); - EndPlatformCreator.createEndPlatform(spawnLocation, plugin.isEndPlatformDropBlocks()); + EndPlatformCreator.createEndPlatform(spawnLocation.getWorld(), plugin.isEndPlatformDropBlocks()); } // Advancements need to be triggered manually diff --git a/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/EndPlatformCreator.java b/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/EndPlatformCreator.java index 1ea9854..628fc43 100644 --- a/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/EndPlatformCreator.java +++ b/src/main/java/com/onarandombox/MultiverseNetherPortals/utils/EndPlatformCreator.java @@ -15,11 +15,12 @@ public class EndPlatformCreator { /** * Creates an end platform at the specified {@code Block} * - * @param spawnLocation The {@code Block} that the player will spawn at. + * @param world The world to create the platform in * @param dropEndBlocks If the platform should drop the broken blocks or delete them */ - public static void createEndPlatform(Block spawnLocation, boolean dropEndBlocks) { - Logging.fine("Creating an end platform at " + spawnLocation.toString()); + public static void createEndPlatform(World world, boolean dropEndBlocks) { + Block spawnLocation = new Location(world, 100, 49, 0).getBlock(); + Logging.fine("Creating an end platform at " + spawnLocation); for (int x = spawnLocation.getX() - 2; x <= spawnLocation.getX() + 2; x++) { for (int z = spawnLocation.getZ() - 2; z <= spawnLocation.getZ() + 2; z++) { @@ -36,28 +37,16 @@ public static void createEndPlatform(Block spawnLocation, boolean dropEndBlocks) for (int yMod = 1; yMod <= 3; yMod++) { Block block = platformBlock.getRelative(BlockFace.UP, yMod); if (block.getType() != Material.AIR) { - if (dropEndBlocks) { - block.breakNaturally(); - } else { + if (!dropEndBlocks || !block.breakNaturally()) { block.setType(Material.AIR); } - - Logging.finest("Breaking block at " + platformBlock); + Logging.finest("Breaking block at " + block); } } } } } - - /** - * Creates an end platform at the specified {@code Location} - * @param spawnLocation The {@code Location} that the player will spawn at. - */ - public static void createEndPlatform(Location spawnLocation, boolean dropEndBlocks) { - createEndPlatform(spawnLocation.getBlock(), dropEndBlocks); - } - /** * The default vanilla location for the end platform */