99
1010import java .util .Arrays ;
1111import java .util .Collection ;
12+ import java .util .Date ;
1213import java .util .HashSet ;
1314import java .util .List ;
15+ import java .util .Objects ;
1416import java .util .Set ;
1517import java .util .Stack ;
1618import java .util .regex .Pattern ;
1719
1820import com .dumptruckman .minecraft .util .Logging ;
21+ import org .bukkit .Bukkit ;
22+ import org .bukkit .command .CommandSender ;
1923import org .bukkit .configuration .ConfigurationSection ;
24+ import org .bukkit .entity .Entity ;
2025import org .jetbrains .annotations .ApiStatus ;
2126import org .jetbrains .annotations .Nullable ;
27+ import org .mvplugins .multiverse .core .command .MVCommandManager ;
2228import org .mvplugins .multiverse .core .config .handle .MemoryConfigurationHandle ;
2329import org .mvplugins .multiverse .core .config .handle .StringPropertyHandle ;
2430import org .mvplugins .multiverse .core .config .migration .ConfigMigrator ;
2733import org .mvplugins .multiverse .core .destination .DestinationInstance ;
2834import org .mvplugins .multiverse .core .destination .DestinationsProvider ;
2935import org .mvplugins .multiverse .core .teleportation .BlockSafety ;
36+ import org .mvplugins .multiverse .core .utils .result .Attempt ;
37+ import org .mvplugins .multiverse .core .utils .text .ChatTextFormatter ;
3038import org .mvplugins .multiverse .core .world .LoadedMultiverseWorld ;
3139import org .mvplugins .multiverse .core .world .WorldManager ;
40+ import org .mvplugins .multiverse .external .vavr .control .Option ;
3241import org .mvplugins .multiverse .external .vavr .control .Try ;
42+ import org .mvplugins .multiverse .portals .action .ActionFailureReason ;
43+ import org .mvplugins .multiverse .portals .action .ActionHandler ;
44+ import org .mvplugins .multiverse .portals .action .ActionHandlerProvider ;
45+ import org .mvplugins .multiverse .portals .action .ActionHandlerType ;
3346import org .mvplugins .multiverse .portals .config .PortalsConfig ;
3447import org .mvplugins .multiverse .portals .enums .PortalType ;
3548import org .bukkit .Location ;
@@ -62,6 +75,8 @@ public static MVPortal loadMVPortalFromConfig(MultiversePortals instance, String
6275 private final WorldManager worldManager ;
6376 private final DestinationsProvider destinationsProvider ;
6477 private final BlockSafety blockSafety ;
78+ private final ActionHandlerProvider actionHandlerProvider ;
79+ private final MVCommandManager commandManager ;
6580
6681 private final String name ;
6782 private final MVPortalNodes configNodes ;
@@ -94,16 +109,24 @@ private MVPortal(MultiversePortals plugin, String name) {
94109 this .worldManager = this .plugin .getServiceLocator ().getService (WorldManager .class );
95110 this .destinationsProvider = this .plugin .getServiceLocator ().getService (DestinationsProvider .class );
96111 this .blockSafety = this .plugin .getServiceLocator ().getService (BlockSafety .class );
112+ this .actionHandlerProvider = this .plugin .getServiceLocator ().getService (ActionHandlerProvider .class );
113+ this .commandManager = this .plugin .getServiceLocator ().getService (MVCommandManager .class );
97114
98115 this .name = name ;
99116
100117 var config = this .plugin .getPortalsConfig ();
101118 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 ())
119+ var portalSection = Option .of (config .getConfigurationSection ("portals." + this .name ))
120+ .getOrElse (() -> config .createSection ("portals." + this .name ));
121+ this .configHandle = setUpConfigHandle (portalSection );
122+ this .stringPropertyHandle = new StringPropertyHandle (this .configHandle );
123+ configHandle .load ();
124+
125+ setUpPermissions ();
126+ }
127+
128+ private MemoryConfigurationHandle setUpConfigHandle (ConfigurationSection portalSection ) {
129+ return MemoryConfigurationHandle .builder (portalSection , configNodes .getNodes ())
107130 .migrator (ConfigMigrator .builder (configNodes .version )
108131 .addVersionMigrator (VersionMigrator .builder (1.0 )
109132 .addAction (MoveMigratorAction .of ("safeteleport" , "safe-teleport" ))
@@ -119,11 +142,14 @@ private MVPortal(MultiversePortals plugin, String name) {
119142 }
120143 })
121144 .build ())
145+ .addVersionMigrator (VersionMigrator .builder (1.2 )
146+ .addAction (MoveMigratorAction .of ("destination" , "action" ))
147+ .build ())
122148 .build ())
123149 .build ();
124- this .stringPropertyHandle = new StringPropertyHandle (this .configHandle );
125- configHandle .load ();
150+ }
126151
152+ private void setUpPermissions () {
127153 this .permission = this .plugin .getServer ().getPluginManager ().getPermission ("multiverse.portal.access." + this .name );
128154 if (this .permission == null ) {
129155 this .permission = new Permission ("multiverse.portal.access." + this .name , "Allows access to the " + this .name + " portal" , PermissionDefault .OP );
@@ -142,6 +168,10 @@ private MVPortal(MultiversePortals plugin, String name) {
142168 }
143169 }
144170
171+ /**
172+ *
173+ * @return
174+ */
145175 public String getName () {
146176 return this .name ;
147177 }
@@ -271,24 +301,53 @@ public PortalLocation getPortalLocation() {
271301 return this .location ;
272302 }
273303
274- public boolean setDestination ( String destinationString ) {
275- DestinationInstance <?, ?> newDestination = this . destinationsProvider . parseDestination ( destinationString ). getOrNull ();
276- return setDestination ( newDestination );
304+ @ ApiStatus . AvailableSince ( "5.2" )
305+ public Try < Void > setActionType ( ActionHandlerType <?, ?> actionType ) {
306+ return configHandle . set ( configNodes . actionType , actionType . getName () );
277307 }
278308
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 ();
309+ @ ApiStatus .AvailableSince ("5.2" )
310+ public Try <Void > setActionType (String actionType ) {
311+ return configHandle .set (configNodes .actionType , actionType );
285312 }
286313
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 ();
314+ @ ApiStatus .AvailableSince ("5.2" )
315+ public String getActionType () {
316+ return this .configHandle .get (configNodes .actionType );
317+ }
318+
319+ @ ApiStatus .AvailableSince ("5.2" )
320+ public Try <Void > setAction (String action ) {
321+ return configHandle .set (configNodes .action , action );
322+ }
323+
324+ @ ApiStatus .AvailableSince ("5.2" )
325+ public String getAction () {
326+ return configHandle .get (configNodes .action );
327+ }
328+
329+ @ ApiStatus .AvailableSince ("5.2" )
330+ public Attempt <? extends ActionHandler <?, ?>, ActionFailureReason > getActionHandler () {
331+ return actionHandlerProvider .parseHandler (getActionType (), getAction ());
332+ }
333+
334+ @ ApiStatus .AvailableSince ("5.2" )
335+ public Attempt <? extends ActionHandler <?, ?>, ActionFailureReason > getActionHandler (CommandSender sender ) {
336+ return actionHandlerProvider .parseHandler (sender , getActionType (), getAction ());
337+ }
338+
339+ @ ApiStatus .AvailableSince ("5.2" )
340+ public Attempt <Void , ActionFailureReason > runActionFor (Entity entity ) {
341+ return getActionHandler (entity )
342+ .mapAttempt (actionHandler -> actionHandler .runAction (this , entity ))
343+ .onSuccess (() -> {
344+ if (entity instanceof Player player ) {
345+ plugin .getPortalSession (player ).setTeleportTime (new Date ());
346+ }
347+ })
348+ .onFailure (failure ->
349+ Logging .warning (ChatTextFormatter .removeColor ("Invalid Portal Action: " +
350+ failure .getFailureMessage ().formatted (commandManager .getCommandIssuer (Bukkit .getConsoleSender ())))));
292351 }
293352
294353 /**
@@ -598,4 +657,52 @@ public boolean isExempt(Player player) {
598657 public PortalLocation getLocation () {
599658 return getPortalLocation ();
600659 }
660+
661+ /**
662+ * @deprecated Portals now have new types of action. Hence, the portal's destination (now called action) may not
663+ * always be a multiverse destination. It can be a command or server name as well.
664+ * Please see {@link MVPortal#getActionHandler()} instead.
665+ */
666+ @ Deprecated (since = "5.2" , forRemoval = true )
667+ @ ApiStatus .ScheduledForRemoval (inVersion = "6.0" )
668+ public boolean setDestination (String destinationString ) {
669+ DestinationInstance <?, ?> newDestination = this .destinationsProvider .parseDestination (destinationString ).getOrNull ();
670+ return setDestination (newDestination );
671+ }
672+
673+ /**
674+ * @deprecated Portals now have new types of action. Hence, the portal's destination (now called action) may not
675+ * always be a multiverse destination. It can be a command or server name as well.
676+ * Please see {@link MVPortal#getActionHandler()} instead.
677+ */
678+ @ Deprecated (since = "5.2" , forRemoval = true )
679+ @ ApiStatus .ScheduledForRemoval (inVersion = "6.0" )
680+ public boolean setDestination (DestinationInstance <?, ?> newDestination ) {
681+ if (newDestination == null ) {
682+ Logging .warning ("Portal " + this .name + " has an invalid DESTINATION!" );
683+ return false ;
684+ }
685+ if (!Objects .equals (getActionType (), "multiverse-destination" )) {
686+ Logging .warning ("Portal " + this .name + " is not set to use multiverse destination!" );
687+ return false ;
688+ }
689+ return this .configHandle .set (configNodes .action , newDestination .toString ()).isSuccess ();
690+ }
691+
692+ /**
693+ * @deprecated Portals now have new types of action. Hence, the portal's destination (now called action) may not
694+ * always be a multiverse destination. It can be a command or server name as well.
695+ * Please see {@link MVPortal#getActionHandler()} instead.
696+ */
697+ @ Deprecated (since = "5.2" , forRemoval = true )
698+ @ ApiStatus .ScheduledForRemoval (inVersion = "6.0" )
699+ public DestinationInstance <?, ?> getDestination () {
700+ return this .destinationsProvider .parseDestination (getAction ())
701+ .onFailure (f -> {
702+ if (getAction ().equals ("multiverse-destination" )) {
703+ Logging .warning ("Portal " + this .name + " has an invalid DESTINATION! " + f .getFailureMessage ().formatted ());
704+ }
705+ })
706+ .getOrNull ();
707+ }
601708}
0 commit comments