Skip to content

Commit 4a40155

Browse files
authored
Merge pull request #699 from Multiverse/v5.2
V5.2
2 parents ccc7e5b + 339a511 commit 4a40155

35 files changed

+1595
-578
lines changed

build.gradle

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ repositories {
1515
name = 'benthecat'
1616
url = uri('https://repo.c0ding.party/multiverse-beta')
1717
}
18+
maven {
19+
name = "helpchatRepoReleases"
20+
url = uri("https://repo.helpch.at/releases/")
21+
}
1822
}
1923

2024
configure(apiDependencies) {
@@ -32,6 +36,9 @@ dependencies {
3236
exclude group: 'org.bukkit', module: 'bukkit'
3337
}
3438

39+
// PlaceholderAPI
40+
externalPlugin 'me.clip:placeholderapi:2.11.6'
41+
3542
// Utils
3643
shadowed('com.dumptruckman.minecraft:Logging:1.1.1') {
3744
exclude group: 'junit', module: 'junit'

src/main/java/org/mvplugins/multiverse/portals/MVPortal.java

Lines changed: 139 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,23 @@
99

1010
import java.util.Arrays;
1111
import java.util.Collection;
12+
import java.util.Date;
1213
import java.util.HashSet;
1314
import java.util.List;
15+
import java.util.Objects;
1416
import java.util.Set;
1517
import java.util.Stack;
1618
import java.util.regex.Pattern;
1719

1820
import com.dumptruckman.minecraft.util.Logging;
21+
import org.bukkit.Bukkit;
22+
import org.bukkit.command.CommandSender;
1923
import org.bukkit.configuration.ConfigurationSection;
24+
import org.bukkit.entity.Entity;
2025
import org.jetbrains.annotations.ApiStatus;
26+
import org.jetbrains.annotations.NotNull;
2127
import org.jetbrains.annotations.Nullable;
28+
import org.mvplugins.multiverse.core.command.MVCommandManager;
2229
import org.mvplugins.multiverse.core.config.handle.MemoryConfigurationHandle;
2330
import org.mvplugins.multiverse.core.config.handle.StringPropertyHandle;
2431
import org.mvplugins.multiverse.core.config.migration.ConfigMigrator;
@@ -27,9 +34,16 @@
2734
import org.mvplugins.multiverse.core.destination.DestinationInstance;
2835
import org.mvplugins.multiverse.core.destination.DestinationsProvider;
2936
import org.mvplugins.multiverse.core.teleportation.BlockSafety;
37+
import org.mvplugins.multiverse.core.utils.result.Attempt;
38+
import org.mvplugins.multiverse.core.utils.text.ChatTextFormatter;
3039
import org.mvplugins.multiverse.core.world.LoadedMultiverseWorld;
3140
import org.mvplugins.multiverse.core.world.WorldManager;
41+
import org.mvplugins.multiverse.external.vavr.control.Option;
3242
import org.mvplugins.multiverse.external.vavr.control.Try;
43+
import org.mvplugins.multiverse.portals.action.ActionFailureReason;
44+
import org.mvplugins.multiverse.portals.action.ActionHandler;
45+
import org.mvplugins.multiverse.portals.action.ActionHandlerProvider;
46+
import org.mvplugins.multiverse.portals.action.ActionHandlerType;
3347
import org.mvplugins.multiverse.portals.config.PortalsConfig;
3448
import org.mvplugins.multiverse.portals.enums.PortalType;
3549
import org.bukkit.Location;
@@ -62,6 +76,8 @@ public static MVPortal loadMVPortalFromConfig(MultiversePortals instance, String
6276
private final WorldManager worldManager;
6377
private final DestinationsProvider destinationsProvider;
6478
private final BlockSafety blockSafety;
79+
private final ActionHandlerProvider actionHandlerProvider;
80+
private final MVCommandManager commandManager;
6581

6682
private final String name;
6783
private final MVPortalNodes configNodes;
@@ -94,16 +110,24 @@ private MVPortal(MultiversePortals plugin, String name) {
94110
this.worldManager = this.plugin.getServiceLocator().getService(WorldManager.class);
95111
this.destinationsProvider = this.plugin.getServiceLocator().getService(DestinationsProvider.class);
96112
this.blockSafety = this.plugin.getServiceLocator().getService(BlockSafety.class);
113+
this.actionHandlerProvider = this.plugin.getServiceLocator().getService(ActionHandlerProvider.class);
114+
this.commandManager = this.plugin.getServiceLocator().getService(MVCommandManager.class);
97115

98116
this.name = name;
99117

100118
var config = this.plugin.getPortalsConfig();
101119
this.configNodes = new MVPortalNodes(plugin, this);
102-
var portalSection = config.getConfigurationSection("portals." + this.name);
103-
if (portalSection == null) {
104-
portalSection = config.createSection("portals." + this.name);
105-
}
106-
this.configHandle = MemoryConfigurationHandle.builder(portalSection, configNodes.getNodes())
120+
var portalSection = Option.of(config.getConfigurationSection("portals." + this.name))
121+
.getOrElse(() -> config.createSection("portals." + this.name));
122+
this.configHandle = setUpConfigHandle(portalSection);
123+
this.stringPropertyHandle = new StringPropertyHandle(this.configHandle);
124+
configHandle.load();
125+
126+
setUpPermissions();
127+
}
128+
129+
private MemoryConfigurationHandle setUpConfigHandle(ConfigurationSection portalSection) {
130+
return MemoryConfigurationHandle.builder(portalSection, configNodes.getNodes())
107131
.migrator(ConfigMigrator.builder(configNodes.version)
108132
.addVersionMigrator(VersionMigrator.builder(1.0)
109133
.addAction(MoveMigratorAction.of("safeteleport", "safe-teleport"))
@@ -119,11 +143,14 @@ private MVPortal(MultiversePortals plugin, String name) {
119143
}
120144
})
121145
.build())
146+
.addVersionMigrator(VersionMigrator.builder(1.2)
147+
.addAction(MoveMigratorAction.of("destination", "action"))
148+
.build())
122149
.build())
123150
.build();
124-
this.stringPropertyHandle = new StringPropertyHandle(this.configHandle);
125-
configHandle.load();
151+
}
126152

153+
private void setUpPermissions() {
127154
this.permission = this.plugin.getServer().getPluginManager().getPermission("multiverse.portal.access." + this.name);
128155
if (this.permission == null) {
129156
this.permission = new Permission("multiverse.portal.access." + this.name, "Allows access to the " + this.name + " portal", PermissionDefault.OP);
@@ -142,6 +169,10 @@ private MVPortal(MultiversePortals plugin, String name) {
142169
}
143170
}
144171

172+
/**
173+
*
174+
* @return
175+
*/
145176
public String getName() {
146177
return this.name;
147178
}
@@ -271,24 +302,61 @@ public PortalLocation getPortalLocation() {
271302
return this.location;
272303
}
273304

274-
public boolean setDestination(String destinationString) {
275-
DestinationInstance<?, ?> newDestination = this.destinationsProvider.parseDestination(destinationString).getOrNull();
276-
return setDestination(newDestination);
305+
@ApiStatus.AvailableSince("5.2")
306+
public Try<Void> setActionType(@NotNull ActionHandlerType<?, ?> actionType) {
307+
Objects.requireNonNull(actionType, "actionType cannot be null");
308+
return configHandle.set(configNodes.actionType, actionType.getName());
277309
}
278310

279-
public boolean setDestination(DestinationInstance<?, ?> newDestination) {
280-
if (newDestination == null) {
281-
Logging.warning("Portal " + this.name + " has an invalid DESTINATION!");
282-
return false;
283-
}
284-
return this.configHandle.set(configNodes.destination, newDestination.toString()).isSuccess();
311+
@ApiStatus.AvailableSince("5.2")
312+
public Try<Void> setActionType(String actionType) {
313+
return configHandle.set(configNodes.actionType, actionType);
285314
}
286315

287-
public DestinationInstance<?, ?> getDestination() {
288-
return this.destinationsProvider.parseDestination(this.configHandle.get(configNodes.destination))
289-
.onFailure(f ->
290-
Logging.warning("Portal " + this.name + " has an invalid DESTINATION! " + f.getFailureMessage().formatted()))
291-
.getOrNull();
316+
@ApiStatus.AvailableSince("5.2")
317+
public String getActionType() {
318+
return this.configHandle.get(configNodes.actionType);
319+
}
320+
321+
@ApiStatus.AvailableSince("5.2")
322+
public Try<Void> setAction(String action) {
323+
return configHandle.set(configNodes.action, action);
324+
}
325+
326+
@ApiStatus.AvailableSince("5.2")
327+
public String getAction() {
328+
return configHandle.get(configNodes.action);
329+
}
330+
331+
@ApiStatus.AvailableSince("5.2")
332+
public Try<Void> setActionHandler(@NotNull ActionHandler<?, ?> action) {
333+
Objects.requireNonNull(action, "action cannot be null");
334+
return setActionType(action.getHandlerType())
335+
.flatMap(v -> setAction(action.serialise()));
336+
}
337+
338+
@ApiStatus.AvailableSince("5.2")
339+
public @NotNull Attempt<? extends ActionHandler<?, ?>, ActionFailureReason> getActionHandler() {
340+
return actionHandlerProvider.parseHandler(getActionType(), getAction());
341+
}
342+
343+
@ApiStatus.AvailableSince("5.2")
344+
public @NotNull Attempt<? extends ActionHandler<?, ?>, ActionFailureReason> getActionHandler(@NotNull CommandSender sender) {
345+
return actionHandlerProvider.parseHandler(sender, getActionType(), getAction());
346+
}
347+
348+
@ApiStatus.AvailableSince("5.2")
349+
public @NotNull Attempt<Void, ActionFailureReason> runActionFor(Entity entity) {
350+
return getActionHandler(entity)
351+
.mapAttempt(actionHandler -> actionHandler.runAction(this, entity))
352+
.onSuccess(() -> {
353+
if (entity instanceof Player player) {
354+
plugin.getPortalSession(player).setTeleportTime(new Date());
355+
}
356+
})
357+
.onFailure(failure ->
358+
Logging.warning(ChatTextFormatter.removeColor("Invalid Portal Action: " +
359+
failure.getFailureMessage().formatted(commandManager.getCommandIssuer(Bukkit.getConsoleSender())))));
292360
}
293361

294362
/**
@@ -598,4 +666,54 @@ public boolean isExempt(Player player) {
598666
public PortalLocation getLocation() {
599667
return getPortalLocation();
600668
}
669+
670+
/**
671+
* @deprecated Portals now have new types of action. Hence, the portal's destination (now called action) may not
672+
* always be a multiverse destination. It can be a command or server name as well.
673+
* Please see {@link MVPortal#getActionHandler()} instead.
674+
*/
675+
@Deprecated(since = "5.2", forRemoval = true)
676+
@ApiStatus.ScheduledForRemoval(inVersion = "6.0")
677+
public boolean setDestination(String destinationString) {
678+
DestinationInstance<?, ?> newDestination = this.destinationsProvider.parseDestination(destinationString).getOrNull();
679+
return setDestination(newDestination);
680+
}
681+
682+
/**
683+
* @deprecated Portals now have new types of action. Hence, the portal's destination (now called action) may not
684+
* always be a multiverse destination. For example, it can be a command or server name as well.
685+
* Please see {@link MVPortal#getActionHandler()} instead.
686+
*/
687+
@Deprecated(since = "5.2", forRemoval = true)
688+
@ApiStatus.ScheduledForRemoval(inVersion = "6.0")
689+
public boolean setDestination(DestinationInstance<?, ?> newDestination) {
690+
if (newDestination == null) {
691+
Logging.warning("Portal " + this.name + " has an invalid DESTINATION!");
692+
return false;
693+
}
694+
if (!Objects.equals(getActionType(), "multiverse-destination")) {
695+
Logging.warning("Portal " + this.name + " is not set to use multiverse destination!");
696+
return false;
697+
}
698+
return setActionType("multiverse-destination")
699+
.flatMap(ignore -> setAction(newDestination.toString()))
700+
.isSuccess();
701+
}
702+
703+
/**
704+
* @deprecated Portals now have new types of action. Hence, the portal's destination (now called action) may not
705+
* always be a multiverse destination. For example, it can be a command or server name as well.
706+
* Please see {@link MVPortal#getActionHandler()} instead.
707+
*/
708+
@Deprecated(since = "5.2", forRemoval = true)
709+
@ApiStatus.ScheduledForRemoval(inVersion = "6.0")
710+
public @Nullable DestinationInstance<?, ?> getDestination() {
711+
return this.destinationsProvider.parseDestination(getAction())
712+
.onFailure(f -> {
713+
if (getAction().equals("multiverse-destination")) {
714+
Logging.warning("Portal " + this.name + " has an invalid DESTINATION! " + f.getFailureMessage().formatted());
715+
}
716+
})
717+
.getOrNull();
718+
}
601719
}

src/main/java/org/mvplugins/multiverse/portals/MVPortalNodes.java

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@
66
import org.mvplugins.multiverse.core.config.node.ConfigNode;
77
import org.mvplugins.multiverse.core.config.node.Node;
88
import org.mvplugins.multiverse.core.config.node.NodeGroup;
9-
import org.mvplugins.multiverse.core.destination.DestinationInstance;
109
import org.mvplugins.multiverse.core.destination.DestinationsProvider;
1110
import org.mvplugins.multiverse.core.exceptions.MultiverseException;
1211
import org.mvplugins.multiverse.external.vavr.control.Try;
12+
import org.mvplugins.multiverse.portals.action.ActionHandler;
13+
import org.mvplugins.multiverse.portals.action.ActionHandlerProvider;
1314
import org.mvplugins.multiverse.portals.utils.MultiverseRegion;
1415

1516
import java.util.Collections;
@@ -21,12 +22,12 @@ final class MVPortalNodes {
2122

2223
private MultiversePortals plugin;
2324
private MVPortal portal;
24-
private DestinationsProvider destinationsProvider;
25+
private ActionHandlerProvider actionHandlerProvider;
2526

2627
MVPortalNodes(MultiversePortals plugin, MVPortal portal) {
2728
this.plugin = plugin;
2829
this.portal = portal;
29-
this.destinationsProvider = MultiverseCoreApi.get().getDestinationsProvider();
30+
this.actionHandlerProvider = plugin.getServiceLocator().getService(ActionHandlerProvider.class);
3031
}
3132

3233
NodeGroup getNodes() {
@@ -90,13 +91,23 @@ private <N extends Node> N node(N node) {
9091
.onSetValue((oldValue, newValue) -> portal.setPortalLocationInternal(PortalLocation.parseLocation(newValue)))
9192
.build());
9293

93-
final ConfigNode<String> destination = node(ConfigNode.builder("destination", String.class)
94+
final ConfigNode<String> actionType = node(ConfigNode.builder("action-type", String.class)
95+
.suggester(input -> actionHandlerProvider.getAllHandlerTypeNames())
96+
.defaultValue("multiverse-destination")
97+
.build());
98+
99+
final ConfigNode<String> action = node(ConfigNode.builder("action", String.class)
94100
.defaultValue("")
95-
.aliases("dest")
96-
.suggester((sender, input) -> destinationsProvider.suggestDestinationStrings(sender, input))
97-
.stringParser((sender, input, type) -> destinationsProvider.parseDestination(sender, input)
98-
.map(DestinationInstance::toString)
99-
.toTry())
101+
.aliases("destination", "dest")
102+
.suggester((sender, input) -> actionHandlerProvider.getHandlerType(portal.getActionType())
103+
.map(actionHandlerType -> actionHandlerType.suggestActions(sender, input))
104+
.getOrElse(Collections.emptyList()))
105+
.stringParser((sender, input, type) ->
106+
Try.of(() -> actionHandlerProvider.getHandlerType(portal.getActionType())
107+
.mapAttempt(actionHandlerType -> actionHandlerType.parseHandler(sender, input))
108+
.map(ActionHandler::serialise)
109+
.getOrThrow(failure ->
110+
new MultiverseException(failure.getFailureMessage()))))
100111
.build());
101112

102113
final ConfigNode<Boolean> checkDestinationSafety = node(ConfigNode.builder("check-destination-safety", Boolean.class)

0 commit comments

Comments
 (0)