2020-05-10 01:28:09 +02:00
/ *
* This file is part of BlueMap , licensed under the MIT License ( MIT ) .
*
* Copyright ( c ) Blue ( Lukas Rieger ) < https : //bluecolored.de>
* Copyright ( c ) contributors
*
* Permission is hereby granted , free of charge , to any person obtaining a copy
* of this software and associated documentation files ( the " Software " ) , to deal
* in the Software without restriction , including without limitation the rights
* to use , copy , modify , merge , publish , distribute , sublicense , and / or sell
* copies of the Software , and to permit persons to whom the Software is
* furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software .
*
* THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
* LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING FROM ,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE .
* /
package de.bluecolored.bluemap.common.plugin.commands ;
import com.flowpowered.math.vector.Vector2i ;
import com.flowpowered.math.vector.Vector3d ;
import com.flowpowered.math.vector.Vector3i ;
2021-05-08 23:47:13 +02:00
import com.mojang.brigadier.Command ;
2020-05-10 01:28:09 +02:00
import com.mojang.brigadier.CommandDispatcher ;
import com.mojang.brigadier.arguments.ArgumentType ;
import com.mojang.brigadier.arguments.DoubleArgumentType ;
import com.mojang.brigadier.arguments.IntegerArgumentType ;
import com.mojang.brigadier.arguments.StringArgumentType ;
2021-05-08 23:47:13 +02:00
import com.mojang.brigadier.builder.ArgumentBuilder ;
2020-05-10 01:28:09 +02:00
import com.mojang.brigadier.builder.LiteralArgumentBuilder ;
import com.mojang.brigadier.builder.RequiredArgumentBuilder ;
import com.mojang.brigadier.context.CommandContext ;
import com.mojang.brigadier.tree.LiteralCommandNode ;
2023-05-01 20:41:30 +02:00
import de.bluecolored.bluemap.common.config.ConfigurationException ;
2020-05-10 01:28:09 +02:00
import de.bluecolored.bluemap.common.plugin.Plugin ;
2021-05-23 10:12:34 +02:00
import de.bluecolored.bluemap.common.plugin.PluginState ;
2020-05-10 01:28:09 +02:00
import de.bluecolored.bluemap.common.plugin.text.Text ;
import de.bluecolored.bluemap.common.plugin.text.TextColor ;
2021-04-24 22:11:26 +02:00
import de.bluecolored.bluemap.common.plugin.text.TextFormat ;
2023-05-01 20:41:30 +02:00
import de.bluecolored.bluemap.common.rendermanager.* ;
2022-07-24 12:10:00 +02:00
import de.bluecolored.bluemap.common.serverinterface.CommandSource ;
2021-04-24 22:11:26 +02:00
import de.bluecolored.bluemap.core.BlueMap ;
import de.bluecolored.bluemap.core.MinecraftVersion ;
2021-06-16 20:09:45 +02:00
import de.bluecolored.bluemap.core.debug.StateDumper ;
2020-05-10 01:28:09 +02:00
import de.bluecolored.bluemap.core.logger.Logger ;
2021-04-24 22:11:26 +02:00
import de.bluecolored.bluemap.core.map.BmMap ;
2021-05-08 23:47:13 +02:00
import de.bluecolored.bluemap.core.map.MapRenderState ;
2023-05-01 20:41:30 +02:00
import de.bluecolored.bluemap.core.storage.Storage ;
2024-02-22 12:58:57 +01:00
import de.bluecolored.bluemap.core.world.Chunk ;
2020-05-10 01:28:09 +02:00
import de.bluecolored.bluemap.core.world.World ;
2024-02-22 12:58:57 +01:00
import de.bluecolored.bluemap.core.world.block.Block ;
2024-03-20 23:23:03 +01:00
import de.bluecolored.bluemap.core.world.block.entity.BlockEntity ;
2021-04-24 22:11:26 +02:00
import java.io.IOException ;
2021-05-11 00:34:12 +02:00
import java.nio.file.Path ;
2023-05-01 20:41:30 +02:00
import java.util.* ;
2021-04-24 22:11:26 +02:00
import java.util.function.Function ;
import java.util.function.Predicate ;
2024-02-22 12:58:57 +01:00
import java.util.stream.Stream ;
2020-05-10 01:28:09 +02:00
public class Commands < S > {
2021-09-19 22:15:50 +02:00
public static final String DEFAULT_MARKER_SET_ID = " markers " ;
private final Plugin plugin ;
private final CommandDispatcher < S > dispatcher ;
private final Function < S , CommandSource > commandSourceInterface ;
private final CommandHelper helper ;
public Commands ( Plugin plugin , CommandDispatcher < S > dispatcher , Function < S , CommandSource > commandSourceInterface ) {
this . plugin = plugin ;
this . dispatcher = dispatcher ;
this . commandSourceInterface = commandSourceInterface ;
this . helper = new CommandHelper ( plugin ) ;
init ( ) ;
}
public void init ( ) {
// commands
2023-05-01 20:41:30 +02:00
LiteralCommandNode < S > baseCommand = literal ( " bluemap " )
2021-09-19 22:15:50 +02:00
. requires ( requirementsUnloaded ( " bluemap.status " ) )
. executes ( this : : statusCommand )
. build ( ) ;
2023-05-01 20:41:30 +02:00
LiteralCommandNode < S > versionCommand = literal ( " version " )
2023-01-03 16:03:07 +01:00
. requires ( requirementsUnloaded ( " bluemap.version " ) )
. executes ( this : : versionCommand )
. build ( ) ;
2021-09-19 22:15:50 +02:00
2023-05-01 20:41:30 +02:00
LiteralCommandNode < S > helpCommand = literal ( " help " )
2021-09-19 22:15:50 +02:00
. requires ( requirementsUnloaded ( " bluemap.help " ) )
. executes ( this : : helpCommand )
. build ( ) ;
2023-05-01 20:41:30 +02:00
LiteralCommandNode < S > reloadCommand = literal ( " reload " )
2021-09-19 22:15:50 +02:00
. requires ( requirementsUnloaded ( " bluemap.reload " ) )
2023-01-03 16:03:07 +01:00
. executes ( context - > this . reloadCommand ( context , false ) )
. then ( literal ( " light " )
. executes ( context - > this . reloadCommand ( context , true ) ) )
2021-09-19 22:15:50 +02:00
. build ( ) ;
2023-05-01 20:41:30 +02:00
LiteralCommandNode < S > debugCommand = literal ( " debug " )
2022-12-13 16:54:31 +01:00
. requires ( requirementsUnloaded ( " bluemap.debug " ) )
2021-09-19 22:15:50 +02:00
. then ( literal ( " block " )
2022-12-13 16:54:31 +01:00
. requires ( requirements ( " bluemap.debug " ) )
2021-09-19 22:15:50 +02:00
. executes ( this : : debugBlockCommand )
. then ( argument ( " world " , StringArgumentType . string ( ) ) . suggests ( new WorldSuggestionProvider < > ( plugin ) )
. then ( argument ( " x " , DoubleArgumentType . doubleArg ( ) )
. then ( argument ( " y " , DoubleArgumentType . doubleArg ( ) )
. then ( argument ( " z " , DoubleArgumentType . doubleArg ( ) )
. executes ( this : : debugBlockCommand ) ) ) ) ) )
. then ( literal ( " flush " )
2022-12-13 16:54:31 +01:00
. requires ( requirements ( " bluemap.debug " ) )
2021-09-19 22:15:50 +02:00
. executes ( this : : debugFlushCommand )
. then ( argument ( " world " , StringArgumentType . string ( ) ) . suggests ( new WorldSuggestionProvider < > ( plugin ) )
. executes ( this : : debugFlushCommand ) ) )
. then ( literal ( " cache " )
2022-12-13 16:54:31 +01:00
. requires ( requirements ( " bluemap.debug " ) )
2021-09-19 22:15:50 +02:00
. executes ( this : : debugClearCacheCommand ) )
. then ( literal ( " dump " )
. executes ( this : : debugDumpCommand ) )
. build ( ) ;
2023-05-01 20:41:30 +02:00
LiteralCommandNode < S > stopCommand = literal ( " stop " )
2021-09-19 22:15:50 +02:00
. requires ( requirements ( " bluemap.stop " ) )
. executes ( this : : stopCommand )
. build ( ) ;
2023-05-01 20:41:30 +02:00
LiteralCommandNode < S > startCommand = literal ( " start " )
2021-09-19 22:15:50 +02:00
. requires ( requirements ( " bluemap.start " ) )
. executes ( this : : startCommand )
. build ( ) ;
2023-05-01 20:41:30 +02:00
LiteralCommandNode < S > freezeCommand = literal ( " freeze " )
2021-09-19 22:15:50 +02:00
. requires ( requirements ( " bluemap.freeze " ) )
. then ( argument ( " map " , StringArgumentType . string ( ) ) . suggests ( new MapSuggestionProvider < > ( plugin ) )
. executes ( this : : freezeCommand ) )
. build ( ) ;
2023-05-01 20:41:30 +02:00
LiteralCommandNode < S > unfreezeCommand = literal ( " unfreeze " )
. requires ( requirements ( " bluemap.freeze " ) )
. then ( argument ( " map " , StringArgumentType . string ( ) ) . suggests ( new MapSuggestionProvider < > ( plugin ) )
. executes ( this : : unfreezeCommand ) )
. build ( ) ;
2021-09-19 22:15:50 +02:00
LiteralCommandNode < S > forceUpdateCommand =
addRenderArguments (
literal ( " force-update " )
. requires ( requirements ( " bluemap.update.force " ) ) ,
this : : forceUpdateCommand
) . build ( ) ;
LiteralCommandNode < S > updateCommand =
addRenderArguments (
literal ( " update " )
. requires ( requirements ( " bluemap.update " ) ) ,
this : : updateCommand
) . build ( ) ;
2023-05-01 20:41:30 +02:00
LiteralCommandNode < S > purgeCommand = literal ( " purge " )
. requires ( requirements ( " bluemap.purge " ) )
. then ( argument ( " map " , StringArgumentType . string ( ) ) . suggests ( new MapSuggestionProvider < > ( plugin ) )
. executes ( this : : purgeCommand ) )
. build ( ) ;
2021-09-19 22:15:50 +02:00
2023-05-01 20:41:30 +02:00
LiteralCommandNode < S > cancelCommand = literal ( " cancel " )
2021-09-19 22:15:50 +02:00
. requires ( requirements ( " bluemap.cancel " ) )
. executes ( this : : cancelCommand )
. then ( argument ( " task-ref " , StringArgumentType . string ( ) ) . suggests ( new TaskRefSuggestionProvider < > ( helper ) )
. executes ( this : : cancelCommand ) )
. build ( ) ;
2023-05-01 20:41:30 +02:00
LiteralCommandNode < S > worldsCommand = literal ( " worlds " )
2021-09-19 22:15:50 +02:00
. requires ( requirements ( " bluemap.status " ) )
. executes ( this : : worldsCommand )
. build ( ) ;
2023-05-01 20:41:30 +02:00
LiteralCommandNode < S > mapsCommand = literal ( " maps " )
2021-09-19 22:15:50 +02:00
. requires ( requirements ( " bluemap.status " ) )
. executes ( this : : mapsCommand )
. build ( ) ;
2023-05-01 20:41:30 +02:00
LiteralCommandNode < S > storagesCommand = literal ( " storages " )
. requires ( requirements ( " bluemap.status " ) )
. executes ( this : : storagesCommand )
. then ( argument ( " storage " , StringArgumentType . string ( ) ) . suggests ( new StorageSuggestionProvider < > ( plugin ) )
. executes ( this : : storagesInfoCommand )
. then ( literal ( " delete " )
2023-06-20 22:05:24 +02:00
. requires ( requirements ( " bluemap.delete " ) )
2023-05-01 20:41:30 +02:00
. then ( argument ( " map " , StringArgumentType . string ( ) )
. executes ( this : : storagesDeleteMapCommand ) ) ) )
. build ( ) ;
2021-09-19 22:15:50 +02:00
// command tree
dispatcher . getRoot ( ) . addChild ( baseCommand ) ;
baseCommand . addChild ( versionCommand ) ;
baseCommand . addChild ( helpCommand ) ;
baseCommand . addChild ( reloadCommand ) ;
baseCommand . addChild ( debugCommand ) ;
baseCommand . addChild ( stopCommand ) ;
baseCommand . addChild ( startCommand ) ;
baseCommand . addChild ( freezeCommand ) ;
baseCommand . addChild ( unfreezeCommand ) ;
baseCommand . addChild ( forceUpdateCommand ) ;
baseCommand . addChild ( updateCommand ) ;
baseCommand . addChild ( cancelCommand ) ;
baseCommand . addChild ( purgeCommand ) ;
baseCommand . addChild ( worldsCommand ) ;
baseCommand . addChild ( mapsCommand ) ;
2023-05-01 20:41:30 +02:00
baseCommand . addChild ( storagesCommand ) ;
2021-09-19 22:15:50 +02:00
}
private < B extends ArgumentBuilder < S , B > > B addRenderArguments ( B builder , Command < S > command ) {
return builder
. executes ( command ) // /bluemap render
. then ( argument ( " radius " , IntegerArgumentType . integer ( ) )
. executes ( command ) ) // /bluemap render <radius>
. then ( argument ( " x " , DoubleArgumentType . doubleArg ( ) )
. then ( argument ( " z " , DoubleArgumentType . doubleArg ( ) )
. then ( argument ( " radius " , IntegerArgumentType . integer ( ) )
. executes ( command ) ) ) ) // /bluemap render <x> <z> <radius>
. then ( argument ( " world|map " , StringArgumentType . string ( ) ) . suggests ( new WorldOrMapSuggestionProvider < > ( plugin ) )
. executes ( command ) // /bluemap render <world|map>
. then ( argument ( " x " , DoubleArgumentType . doubleArg ( ) )
. then ( argument ( " z " , DoubleArgumentType . doubleArg ( ) )
. then ( argument ( " radius " , IntegerArgumentType . integer ( ) )
. executes ( command ) ) ) ) ) ; // /bluemap render <world|map> <x> <z> <radius>
}
private Predicate < S > requirements ( String permission ) {
return s - > {
CommandSource source = commandSourceInterface . apply ( s ) ;
return plugin . isLoaded ( ) & & source . hasPermission ( permission ) ;
} ;
}
private Predicate < S > requirementsUnloaded ( String permission ) {
return s - > {
CommandSource source = commandSourceInterface . apply ( s ) ;
return source . hasPermission ( permission ) ;
} ;
}
private LiteralArgumentBuilder < S > literal ( String name ) {
return LiteralArgumentBuilder . literal ( name ) ;
}
private < T > RequiredArgumentBuilder < S , T > argument ( String name , ArgumentType < T > type ) {
return RequiredArgumentBuilder . argument ( name , type ) ;
}
private < T > Optional < T > getOptionalArgument ( CommandContext < S > context , String argumentName , Class < T > type ) {
try {
return Optional . of ( context . getArgument ( argumentName , type ) ) ;
} catch ( IllegalArgumentException ex ) {
return Optional . empty ( ) ;
}
}
2024-02-07 20:43:37 +01:00
private Optional < World > parseWorld ( String worldId ) {
for ( var entry : plugin . getBlueMap ( ) . getWorlds ( ) . entrySet ( ) ) {
if ( entry . getKey ( ) . equals ( worldId ) ) {
return Optional . of ( entry . getValue ( ) ) ;
2021-09-19 22:15:50 +02:00
}
}
return Optional . empty ( ) ;
}
private Optional < BmMap > parseMap ( String mapId ) {
2024-02-07 20:43:37 +01:00
for ( BmMap map : plugin . getBlueMap ( ) . getMaps ( ) . values ( ) ) {
if ( map . getId ( ) . equals ( mapId ) ) {
2021-09-19 22:15:50 +02:00
return Optional . of ( map ) ;
}
}
return Optional . empty ( ) ;
}
// --- COMMANDS ---
public int statusCommand ( CommandContext < S > context ) {
CommandSource source = commandSourceInterface . apply ( context . getSource ( ) ) ;
if ( ! plugin . isLoaded ( ) ) {
source . sendMessage ( Text . of ( TextColor . RED , " BlueMap is not loaded! Try /bluemap reload " ) ) ;
return 0 ;
}
2023-05-15 17:40:47 +02:00
new Thread ( ( ) - > {
source . sendMessages ( helper . createStatusMessage ( ) ) ;
} , " BlueMap-Plugin-StatusCommand " ) . start ( ) ;
2021-09-19 22:15:50 +02:00
return 1 ;
}
public int versionCommand ( CommandContext < S > context ) {
CommandSource source = commandSourceInterface . apply ( context . getSource ( ) ) ;
int renderThreadCount = 0 ;
if ( plugin . isLoaded ( ) ) {
renderThreadCount = plugin . getRenderManager ( ) . getWorkerThreadCount ( ) ;
}
2022-04-20 22:54:27 +02:00
MinecraftVersion minecraftVersion = plugin . getServerInterface ( ) . getMinecraftVersion ( ) ;
2021-09-19 22:15:50 +02:00
source . sendMessage ( Text . of ( TextFormat . BOLD , TextColor . BLUE , " Version: " , TextColor . WHITE , BlueMap . VERSION ) ) ;
2022-07-26 22:04:01 +02:00
source . sendMessage ( Text . of ( TextColor . GRAY , " Commit: " , TextColor . WHITE , BlueMap . GIT_HASH ) ) ;
2021-09-19 22:15:50 +02:00
source . sendMessage ( Text . of ( TextColor . GRAY , " Implementation: " , TextColor . WHITE , plugin . getImplementationType ( ) ) ) ;
source . sendMessage ( Text . of (
2022-04-20 22:54:27 +02:00
TextColor . GRAY , " Minecraft compatibility: " , TextColor . WHITE , minecraftVersion . getVersionString ( ) ,
TextColor . GRAY , " ( " + minecraftVersion . getResource ( ) . getVersion ( ) . getVersionString ( ) + " ) "
2021-09-19 22:15:50 +02:00
) ) ;
source . sendMessage ( Text . of ( TextColor . GRAY , " Render-threads: " , TextColor . WHITE , renderThreadCount ) ) ;
source . sendMessage ( Text . of ( TextColor . GRAY , " Available processors: " , TextColor . WHITE , Runtime . getRuntime ( ) . availableProcessors ( ) ) ) ;
source . sendMessage ( Text . of ( TextColor . GRAY , " Available memory: " , TextColor . WHITE , ( Runtime . getRuntime ( ) . maxMemory ( ) / 1024L / 1024L ) + " MiB " ) ) ;
2022-04-20 22:54:27 +02:00
if ( minecraftVersion . isAtLeast ( new MinecraftVersion ( 1 , 15 ) ) ) {
2021-09-19 22:15:50 +02:00
String clipboardValue =
" Version: " + BlueMap . VERSION + " \ n " +
2022-07-26 22:04:01 +02:00
" Commit: " + BlueMap . GIT_HASH + " \ n " +
2021-09-19 22:15:50 +02:00
" Implementation: " + plugin . getImplementationType ( ) + " \ n " +
2022-04-20 22:54:27 +02:00
" Minecraft compatibility: " + minecraftVersion . getVersionString ( ) + " ( " + minecraftVersion . getResource ( ) . getVersion ( ) . getVersionString ( ) + " ) \ n " +
2021-09-19 22:15:50 +02:00
" Render-threads: " + renderThreadCount + " \ n " +
" Available processors: " + Runtime . getRuntime ( ) . availableProcessors ( ) + " \ n " +
" Available memory: " + Runtime . getRuntime ( ) . maxMemory ( ) / 1024L / 1024L + " MiB " ;
source . sendMessage ( Text . of ( TextColor . DARK_GRAY , " [copy to clipboard] " )
. setClickAction ( Text . ClickAction . COPY_TO_CLIPBOARD , clipboardValue )
. setHoverText ( Text . of ( TextColor . GRAY , " click to copy the above text .. " , TextFormat . ITALIC , TextColor . GRAY , " duh! " ) ) ) ;
}
return 1 ;
}
public int helpCommand ( CommandContext < S > context ) {
CommandSource source = commandSourceInterface . apply ( context . getSource ( ) ) ;
source . sendMessage ( Text . of ( TextColor . BLUE , " BlueMap Commands: " ) ) ;
for ( String usage : dispatcher . getAllUsage ( dispatcher . getRoot ( ) . getChild ( " bluemap " ) , context . getSource ( ) , true ) ) {
Text usageText = Text . of ( TextColor . GREEN , " /bluemap " ) ;
String [ ] arguments = usage . split ( " " ) ;
for ( String arg : arguments ) {
if ( arg . isEmpty ( ) ) continue ;
if ( arg . charAt ( 0 ) = = '<' & & arg . charAt ( arg . length ( ) - 1 ) = = '>' ) {
usageText . addChild ( Text . of ( TextColor . GRAY , " " + arg ) ) ;
} else {
usageText . addChild ( Text . of ( TextColor . WHITE , " " + arg ) ) ;
}
}
source . sendMessage ( usageText ) ;
}
source . sendMessage (
Text . of ( TextColor . BLUE , " \ nOpen this link to get a description for each command: \ n " )
. addChild ( Text . of ( TextColor . GRAY , " https://bluecolo.red/bluemap-commands " ) . setClickAction ( Text . ClickAction . OPEN_URL , " https://bluecolo.red/bluemap-commands " ) )
) ;
return 1 ;
}
2023-01-03 16:03:07 +01:00
public int reloadCommand ( CommandContext < S > context , boolean light ) {
2021-09-19 22:15:50 +02:00
CommandSource source = commandSourceInterface . apply ( context . getSource ( ) ) ;
source . sendMessage ( Text . of ( TextColor . GOLD , " Reloading BlueMap... " ) ) ;
new Thread ( ( ) - > {
try {
2023-01-03 16:03:07 +01:00
if ( light ) {
plugin . lightReload ( ) ;
} else {
plugin . reload ( ) ;
}
2021-09-19 22:15:50 +02:00
if ( plugin . isLoaded ( ) ) {
source . sendMessage ( Text . of ( TextColor . GREEN , " BlueMap reloaded! " ) ) ;
} else {
source . sendMessage ( Text . of ( TextColor . RED , " Could not load BlueMap! See the console for details! " ) ) ;
}
2021-11-14 14:18:31 +01:00
} catch ( Exception ex ) {
2021-09-19 22:15:50 +02:00
Logger . global . logError ( " Failed to reload BlueMap! " , ex ) ;
source . sendMessage ( Text . of ( TextColor . RED , " There was an error reloading BlueMap! See the console for details! " ) ) ;
}
2022-12-13 16:54:31 +01:00
} , " BlueMap-Plugin-ReloadCommand " ) . start ( ) ;
2021-09-19 22:15:50 +02:00
return 1 ;
}
public int debugClearCacheCommand ( CommandContext < S > context ) {
CommandSource source = commandSourceInterface . apply ( context . getSource ( ) ) ;
2024-02-07 20:43:37 +01:00
for ( World world : plugin . getBlueMap ( ) . getWorlds ( ) . values ( ) ) {
2021-09-19 22:15:50 +02:00
world . invalidateChunkCache ( ) ;
}
source . sendMessage ( Text . of ( TextColor . GREEN , " All caches cleared! " ) ) ;
return 1 ;
}
public int debugFlushCommand ( CommandContext < S > context ) {
CommandSource source = commandSourceInterface . apply ( context . getSource ( ) ) ;
// parse arguments
Optional < String > worldName = getOptionalArgument ( context , " world " , String . class ) ;
final World world ;
if ( worldName . isPresent ( ) ) {
world = parseWorld ( worldName . get ( ) ) . orElse ( null ) ;
if ( world = = null ) {
2024-02-07 20:43:37 +01:00
source . sendMessage ( Text . of ( TextColor . RED , " There is no " , helper . worldHelperHover ( ) , " with this id: " , TextColor . WHITE , worldName . get ( ) ) ) ;
2021-09-19 22:15:50 +02:00
return 0 ;
}
} else {
world = source . getWorld ( ) . orElse ( null ) ;
if ( world = = null ) {
source . sendMessage ( Text . of ( TextColor . RED , " Can't detect a location from this command-source, you'll have to define a world! " ) ) ;
return 0 ;
}
}
new Thread ( ( ) - > {
source . sendMessage ( Text . of ( TextColor . GOLD , " Saving world and flushing changes... " ) ) ;
try {
2022-04-20 22:54:27 +02:00
if ( plugin . flushWorldUpdates ( world ) ) {
2021-09-19 22:15:50 +02:00
source . sendMessage ( Text . of ( TextColor . GREEN , " Successfully saved and flushed all changes. " ) ) ;
} else {
source . sendMessage ( Text . of ( TextColor . RED , " This operation is not supported by this implementation ( " + plugin . getImplementationType ( ) + " ) " ) ) ;
}
} catch ( IOException ex ) {
source . sendMessage ( Text . of ( TextColor . RED , " There was an unexpected exception trying to save the world. Please check the console for more details... " ) ) ;
Logger . global . logError ( " Unexpected exception trying to save the world! " , ex ) ;
}
2022-12-13 16:54:31 +01:00
} , " BlueMap-Plugin-DebugFlushCommand " ) . start ( ) ;
2021-09-19 22:15:50 +02:00
return 1 ;
}
public int debugBlockCommand ( CommandContext < S > context ) {
final CommandSource source = commandSourceInterface . apply ( context . getSource ( ) ) ;
// parse arguments
Optional < String > worldName = getOptionalArgument ( context , " world " , String . class ) ;
Optional < Double > x = getOptionalArgument ( context , " x " , Double . class ) ;
Optional < Double > y = getOptionalArgument ( context , " y " , Double . class ) ;
Optional < Double > z = getOptionalArgument ( context , " z " , Double . class ) ;
final World world ;
final Vector3d position ;
if ( worldName . isPresent ( ) & & x . isPresent ( ) & & y . isPresent ( ) & & z . isPresent ( ) ) {
world = parseWorld ( worldName . get ( ) ) . orElse ( null ) ;
position = new Vector3d ( x . get ( ) , y . get ( ) , z . get ( ) ) ;
if ( world = = null ) {
2024-02-07 20:43:37 +01:00
source . sendMessage ( Text . of ( TextColor . RED , " There is no " , helper . worldHelperHover ( ) , " with this id: " , TextColor . WHITE , worldName . get ( ) ) ) ;
2021-09-19 22:15:50 +02:00
return 0 ;
}
} else {
world = source . getWorld ( ) . orElse ( null ) ;
position = source . getPosition ( ) . orElse ( null ) ;
if ( world = = null | | position = = null ) {
source . sendMessage ( Text . of ( TextColor . RED , " Can't detect a location from this command-source, you'll have to define a world and position! " ) ) ;
return 0 ;
}
}
new Thread ( ( ) - > {
// collect and output debug info
Vector3i blockPos = position . floor ( ) . toInt ( ) ;
Block < ? > block = new Block < > ( world , blockPos . getX ( ) , blockPos . getY ( ) , blockPos . getZ ( ) ) ;
2024-02-07 20:43:37 +01:00
Block < ? > blockBelow = new Block < > ( world , blockPos . getX ( ) , blockPos . getY ( ) - 1 , blockPos . getZ ( ) ) ;
2021-09-19 22:15:50 +02:00
source . sendMessages ( Arrays . asList (
2024-02-22 12:58:57 +01:00
Text . of ( TextColor . GOLD , " Block at you: \ n " , formatBlock ( block ) ) ,
Text . of ( TextColor . GOLD , " Block below you: \ n " , formatBlock ( blockBelow ) )
2021-09-19 22:15:50 +02:00
) ) ;
2022-12-13 16:54:31 +01:00
} , " BlueMap-Plugin-DebugBlockCommand " ) . start ( ) ;
2021-09-19 22:15:50 +02:00
return 1 ;
}
2024-02-22 12:58:57 +01:00
private Text formatBlock ( Block < ? > block ) {
World world = block . getWorld ( ) ;
Chunk chunk = block . getChunk ( ) ;
Map < String , Object > lines = new LinkedHashMap < > ( ) ;
lines . put ( " world-id " , world . getId ( ) ) ;
lines . put ( " world-name " , world . getName ( ) ) ;
lines . put ( " chunk-is-generated " , chunk . isGenerated ( ) ) ;
lines . put ( " chunk-has-lightdata " , chunk . hasLightData ( ) ) ;
lines . put ( " chunk-inhabited-time " , chunk . getInhabitedTime ( ) ) ;
lines . put ( " block-state " , block . getBlockState ( ) ) ;
lines . put ( " biome " , block . getBiomeId ( ) ) ;
lines . put ( " position " , block . getX ( ) + " | " + block . getY ( ) + " | " + block . getZ ( ) ) ;
lines . put ( " block-light " , block . getBlockLightLevel ( ) ) ;
lines . put ( " sun-light " , block . getSunLightLevel ( ) ) ;
2024-03-20 23:23:03 +01:00
BlockEntity blockEntity = block . getBlockEntity ( ) ;
if ( blockEntity ! = null ) {
lines . put ( " block-entity " , blockEntity ) ;
}
2024-02-22 12:58:57 +01:00
Object [ ] textElements = lines . entrySet ( ) . stream ( )
. flatMap ( e - > Stream . of ( TextColor . GRAY , e . getKey ( ) , " : " , TextColor . WHITE , e . getValue ( ) , " \ n " ) )
. toArray ( Object [ ] : : new ) ;
textElements [ textElements . length - 1 ] = " " ;
return Text . of ( textElements ) ;
}
2021-09-19 22:15:50 +02:00
public int debugDumpCommand ( CommandContext < S > context ) {
final CommandSource source = commandSourceInterface . apply ( context . getSource ( ) ) ;
try {
2024-02-07 20:43:37 +01:00
Path file = plugin . getBlueMap ( ) . getConfig ( ) . getCoreConfig ( ) . getData ( ) . resolve ( " dump.json " ) ;
2021-09-19 22:15:50 +02:00
StateDumper . global ( ) . dump ( file ) ;
source . sendMessage ( Text . of ( TextColor . GREEN , " Dump created at: " + file ) ) ;
return 1 ;
} catch ( IOException ex ) {
Logger . global . logError ( " Failed to create dump! " , ex ) ;
source . sendMessage ( Text . of ( TextColor . RED , " Exception trying to create dump! See console for details. " ) ) ;
return 0 ;
}
}
public int stopCommand ( CommandContext < S > context ) {
CommandSource source = commandSourceInterface . apply ( context . getSource ( ) ) ;
if ( plugin . getRenderManager ( ) . isRunning ( ) ) {
new Thread ( ( ) - > {
plugin . getPluginState ( ) . setRenderThreadsEnabled ( false ) ;
plugin . getRenderManager ( ) . stop ( ) ;
source . sendMessage ( Text . of ( TextColor . GREEN , " Render-Threads stopped! " ) ) ;
plugin . save ( ) ;
2022-12-13 16:54:31 +01:00
} , " BlueMap-Plugin-StopCommand " ) . start ( ) ;
2021-09-19 22:15:50 +02:00
} else {
source . sendMessage ( Text . of ( TextColor . RED , " Render-Threads are already stopped! " ) ) ;
return 0 ;
}
return 1 ;
}
public int startCommand ( CommandContext < S > context ) {
CommandSource source = commandSourceInterface . apply ( context . getSource ( ) ) ;
if ( ! plugin . getRenderManager ( ) . isRunning ( ) ) {
new Thread ( ( ) - > {
plugin . getPluginState ( ) . setRenderThreadsEnabled ( true ) ;
2024-02-07 20:43:37 +01:00
plugin . getRenderManager ( ) . start ( plugin . getBlueMap ( ) . getConfig ( ) . getCoreConfig ( ) . resolveRenderThreadCount ( ) ) ;
2021-09-19 22:15:50 +02:00
source . sendMessage ( Text . of ( TextColor . GREEN , " Render-Threads started! " ) ) ;
plugin . save ( ) ;
2022-12-13 16:54:31 +01:00
} , " BlueMap-Plugin-StartCommand " ) . start ( ) ;
2021-09-19 22:15:50 +02:00
} else {
source . sendMessage ( Text . of ( TextColor . RED , " Render-Threads are already running! " ) ) ;
return 0 ;
}
return 1 ;
}
public int freezeCommand ( CommandContext < S > context ) {
CommandSource source = commandSourceInterface . apply ( context . getSource ( ) ) ;
// parse map argument
String mapString = context . getArgument ( " map " , String . class ) ;
BmMap map = parseMap ( mapString ) . orElse ( null ) ;
if ( map = = null ) {
2024-02-07 20:43:37 +01:00
source . sendMessage ( Text . of ( TextColor . RED , " There is no " , helper . mapHelperHover ( ) , " with this id: " , TextColor . WHITE , mapString ) ) ;
2021-09-19 22:15:50 +02:00
return 0 ;
}
PluginState . MapState mapState = plugin . getPluginState ( ) . getMapState ( map ) ;
if ( mapState . isUpdateEnabled ( ) ) {
new Thread ( ( ) - > {
mapState . setUpdateEnabled ( false ) ;
plugin . stopWatchingMap ( map ) ;
plugin . getRenderManager ( ) . removeRenderTasksIf ( task - > {
if ( task instanceof MapUpdateTask )
return ( ( MapUpdateTask ) task ) . getMap ( ) . equals ( map ) ;
if ( task instanceof WorldRegionRenderTask )
return ( ( WorldRegionRenderTask ) task ) . getMap ( ) . equals ( map ) ;
return false ;
} ) ;
source . sendMessage ( Text . of ( TextColor . GREEN , " Map " , TextColor . WHITE , mapString , TextColor . GREEN , " is now frozen and will no longer be automatically updated! " ) ) ;
source . sendMessage ( Text . of ( TextColor . GRAY , " Any currently scheduled updates for this map have been cancelled. " ) ) ;
plugin . save ( ) ;
2022-12-13 16:54:31 +01:00
} , " BlueMap-Plugin-FreezeCommand " ) . start ( ) ;
2021-09-19 22:15:50 +02:00
} else {
source . sendMessage ( Text . of ( TextColor . RED , " This map is already frozen! " ) ) ;
return 0 ;
}
return 1 ;
}
public int unfreezeCommand ( CommandContext < S > context ) {
CommandSource source = commandSourceInterface . apply ( context . getSource ( ) ) ;
// parse map argument
String mapString = context . getArgument ( " map " , String . class ) ;
BmMap map = parseMap ( mapString ) . orElse ( null ) ;
if ( map = = null ) {
2024-02-07 20:43:37 +01:00
source . sendMessage ( Text . of ( TextColor . RED , " There is no " , helper . mapHelperHover ( ) , " with this id: " , TextColor . WHITE , mapString ) ) ;
2021-09-19 22:15:50 +02:00
return 0 ;
}
PluginState . MapState mapState = plugin . getPluginState ( ) . getMapState ( map ) ;
if ( ! mapState . isUpdateEnabled ( ) ) {
new Thread ( ( ) - > {
mapState . setUpdateEnabled ( true ) ;
plugin . startWatchingMap ( map ) ;
plugin . getRenderManager ( ) . scheduleRenderTask ( new MapUpdateTask ( map ) ) ;
source . sendMessage ( Text . of ( TextColor . GREEN , " Map " , TextColor . WHITE , mapString , TextColor . GREEN , " is no longer frozen and will be automatically updated! " ) ) ;
plugin . save ( ) ;
2022-12-13 16:54:31 +01:00
} , " BlueMap-Plugin-UnfreezeCommand " ) . start ( ) ;
2021-09-19 22:15:50 +02:00
} else {
source . sendMessage ( Text . of ( TextColor . RED , " This map is not frozen! " ) ) ;
return 0 ;
}
return 1 ;
}
public int forceUpdateCommand ( CommandContext < S > context ) {
return updateCommand ( context , true ) ;
}
public int updateCommand ( CommandContext < S > context ) {
return updateCommand ( context , false ) ;
}
public int updateCommand ( CommandContext < S > context , boolean force ) {
final CommandSource source = commandSourceInterface . apply ( context . getSource ( ) ) ;
// parse world/map argument
Optional < String > worldOrMap = getOptionalArgument ( context , " world|map " , String . class ) ;
final World worldToRender ;
final BmMap mapToRender ;
if ( worldOrMap . isPresent ( ) ) {
worldToRender = parseWorld ( worldOrMap . get ( ) ) . orElse ( null ) ;
if ( worldToRender = = null ) {
mapToRender = parseMap ( worldOrMap . get ( ) ) . orElse ( null ) ;
if ( mapToRender = = null ) {
2024-02-07 20:43:37 +01:00
source . sendMessage ( Text . of ( TextColor . RED , " There is no " , helper . worldHelperHover ( ) , " or " ,
helper . mapHelperHover ( ) , " with this id: " , TextColor . WHITE , worldOrMap . get ( ) ) ) ;
2021-09-19 22:15:50 +02:00
return 0 ;
}
} else {
mapToRender = null ;
}
} else {
worldToRender = source . getWorld ( ) . orElse ( null ) ;
mapToRender = null ;
if ( worldToRender = = null ) {
2024-02-07 20:43:37 +01:00
source . sendMessage ( Text . of ( TextColor . RED , " Can't detect a world from this command-source, you'll have to define a world or a map to update! " )
. setHoverText ( Text . of ( TextColor . GRAY , " /bluemap " + ( force ? " force-update " : " update " ) + " <world|map> " ) ) ) ;
2021-09-19 22:15:50 +02:00
return 0 ;
}
}
// parse radius and center arguments
final int radius = getOptionalArgument ( context , " radius " , Integer . class ) . orElse ( - 1 ) ;
final Vector2i center ;
if ( radius > = 0 ) {
Optional < Double > x = getOptionalArgument ( context , " x " , Double . class ) ;
Optional < Double > z = getOptionalArgument ( context , " z " , Double . class ) ;
if ( x . isPresent ( ) & & z . isPresent ( ) ) {
center = new Vector2i ( x . get ( ) , z . get ( ) ) ;
} else {
Vector3d position = source . getPosition ( ) . orElse ( null ) ;
if ( position = = null ) {
2024-02-07 20:43:37 +01:00
source . sendMessage ( Text . of ( TextColor . RED , " Can't detect a position from this command-source, you'll have to define x,z coordinates to update with a radius! " )
. setHoverText ( Text . of ( TextColor . GRAY , " /bluemap " + ( force ? " force-update " : " update " ) + " <x> <z> " + radius ) ) ) ;
2021-09-19 22:15:50 +02:00
return 0 ;
}
center = position . toVector2 ( true ) . floor ( ) . toInt ( ) ;
}
} else {
center = null ;
}
// execute render
new Thread ( ( ) - > {
try {
List < BmMap > maps = new ArrayList < > ( ) ;
if ( worldToRender ! = null ) {
2024-02-07 20:43:37 +01:00
plugin . flushWorldUpdates ( worldToRender ) ;
for ( BmMap map : plugin . getBlueMap ( ) . getMaps ( ) . values ( ) ) {
if ( map . getWorld ( ) . equals ( worldToRender ) ) maps . add ( map ) ;
2021-09-19 22:15:50 +02:00
}
} else {
2024-02-07 20:43:37 +01:00
plugin . flushWorldUpdates ( mapToRender . getWorld ( ) ) ;
2021-09-19 22:15:50 +02:00
maps . add ( mapToRender ) ;
}
if ( maps . isEmpty ( ) ) {
source . sendMessage ( Text . of ( TextColor . RED , " No map has been found for this world that could be updated! " ) ) ;
return ;
}
for ( BmMap map : maps ) {
MapUpdateTask updateTask = new MapUpdateTask ( map , center , radius ) ;
plugin . getRenderManager ( ) . scheduleRenderTask ( updateTask ) ;
if ( force ) {
MapRenderState state = map . getRenderState ( ) ;
updateTask . getRegions ( ) . forEach ( region - > state . setRenderTime ( region , - 1 ) ) ;
}
2024-02-07 20:43:37 +01:00
source . sendMessage ( Text . of ( TextColor . GREEN , " Created new Update-Task for map ' " + map . getId ( ) + " ' " ,
TextColor . GRAY , " ( " + updateTask . getRegions ( ) . size ( ) + " regions, ~ " + updateTask . getRegions ( ) . size ( ) * 1024L + " chunks) " ) ) ;
2021-09-19 22:15:50 +02:00
}
source . sendMessage ( Text . of ( TextColor . GREEN , " Use " , TextColor . GRAY , " /bluemap " , TextColor . GREEN , " to see the progress. " ) ) ;
} catch ( IOException ex ) {
source . sendMessage ( Text . of ( TextColor . RED , " There was an unexpected exception trying to save the world. Please check the console for more details... " ) ) ;
Logger . global . logError ( " Unexpected exception trying to save the world! " , ex ) ;
}
2022-12-13 16:54:31 +01:00
} , " BlueMap-Plugin-UpdateCommand " ) . start ( ) ;
2021-09-19 22:15:50 +02:00
return 1 ;
}
public int cancelCommand ( CommandContext < S > context ) {
CommandSource source = commandSourceInterface . apply ( context . getSource ( ) ) ;
Optional < String > ref = getOptionalArgument ( context , " task-ref " , String . class ) ;
2022-04-20 22:54:27 +02:00
if ( ref . isEmpty ( ) ) {
2021-09-19 22:15:50 +02:00
plugin . getRenderManager ( ) . removeAllRenderTasks ( ) ;
source . sendMessage ( Text . of ( TextColor . GREEN , " All tasks cancelled! " ) ) ;
source . sendMessage ( Text . of ( TextColor . GRAY , " (Note, that an already started task might not be removed immediately. Some tasks needs to do some tidying-work first) " ) ) ;
return 1 ;
}
Optional < RenderTask > task = helper . getTaskForRef ( ref . get ( ) ) ;
2022-04-20 22:54:27 +02:00
if ( task . isEmpty ( ) ) {
2021-09-19 22:15:50 +02:00
source . sendMessage ( Text . of ( TextColor . RED , " There is no task with this reference ' " + ref . get ( ) + " '! " ) ) ;
return 0 ;
}
if ( plugin . getRenderManager ( ) . removeRenderTask ( task . get ( ) ) ) {
source . sendMessage ( Text . of ( TextColor . GREEN , " Task cancelled! " ) ) ;
source . sendMessage ( Text . of ( TextColor . GRAY , " (Note, that an already started task might not be removed immediately. Some tasks needs to do some tidying-work first) " ) ) ;
return 1 ;
} else {
source . sendMessage ( Text . of ( TextColor . RED , " This task is either completed or got cancelled already! " ) ) ;
return 0 ;
}
}
public int purgeCommand ( CommandContext < S > context ) {
CommandSource source = commandSourceInterface . apply ( context . getSource ( ) ) ;
// parse map argument
2021-11-06 16:14:14 +01:00
String mapString = context . getArgument ( " map " , String . class ) ;
BmMap map = parseMap ( mapString ) . orElse ( null ) ;
if ( map = = null ) {
2024-02-07 20:43:37 +01:00
source . sendMessage ( Text . of ( TextColor . RED , " There is no " , helper . mapHelperHover ( ) , " with this id: " , TextColor . WHITE , mapString ) ) ;
2021-11-06 16:14:14 +01:00
return 0 ;
}
2021-09-19 22:15:50 +02:00
new Thread ( ( ) - > {
try {
// delete map
2023-03-04 12:40:12 +01:00
MapPurgeTask purgeTask = new MapPurgeTask ( map ) ;
2021-09-19 22:15:50 +02:00
plugin . getRenderManager ( ) . scheduleRenderTaskNext ( purgeTask ) ;
2021-11-06 16:14:14 +01:00
source . sendMessage ( Text . of ( TextColor . GREEN , " Created new Task to purge map ' " + map . getId ( ) + " ' " ) ) ;
2021-09-19 22:15:50 +02:00
2022-10-04 20:40:38 +02:00
// cancel task if currently rendering the same map
RenderTask currentRenderTask = plugin . getRenderManager ( ) . getCurrentRenderTask ( ) ;
if ( currentRenderTask instanceof MapUpdateTask & & ( ( MapUpdateTask ) currentRenderTask ) . getMap ( ) . getId ( ) . equals ( map . getId ( ) ) ) {
currentRenderTask . cancel ( ) ;
}
// start updating the map after the purge
if ( plugin . getPluginState ( ) . getMapState ( map ) . isUpdateEnabled ( ) ) {
RenderTask updateTask = new MapUpdateTask ( map ) ;
plugin . getRenderManager ( ) . scheduleRenderTask ( updateTask ) ;
source . sendMessage ( Text . of ( TextColor . GREEN , " Created new Update-Task for map ' " + map . getId ( ) + " ' " ) ) ;
source . sendMessage ( Text . of ( TextColor . GRAY , " If you don't want this map to render again after the purge, use " ,
TextColor . DARK_GRAY , " /bluemap freeze " + map . getId ( ) , TextColor . GRAY , " first! " ) ) ;
}
2021-09-19 22:15:50 +02:00
source . sendMessage ( Text . of ( TextColor . GREEN , " Use " , TextColor . GRAY , " /bluemap " , TextColor . GREEN , " to see the progress. " ) ) ;
2023-03-04 12:40:12 +01:00
} catch ( IllegalArgumentException e ) {
2021-11-06 16:14:14 +01:00
source . sendMessage ( Text . of ( TextColor . RED , " There was an error trying to purge ' " + map . getId ( ) + " ', see console for details. " ) ) ;
Logger . global . logError ( " Failed to purge map ' " + map . getId ( ) + " '! " , e ) ;
2021-09-19 22:15:50 +02:00
}
2022-12-13 16:54:31 +01:00
} , " BlueMap-Plugin-PurgeCommand " ) . start ( ) ;
2021-09-19 22:15:50 +02:00
return 1 ;
}
public int worldsCommand ( CommandContext < S > context ) {
CommandSource source = commandSourceInterface . apply ( context . getSource ( ) ) ;
source . sendMessage ( Text . of ( TextColor . BLUE , " Worlds loaded by BlueMap: " ) ) ;
2024-02-07 20:43:37 +01:00
for ( var entry : plugin . getBlueMap ( ) . getWorlds ( ) . entrySet ( ) ) {
source . sendMessage ( Text . of ( TextColor . GRAY , " - " , TextColor . WHITE , entry . getKey ( ) ) ) ;
2021-09-19 22:15:50 +02:00
}
return 1 ;
}
public int mapsCommand ( CommandContext < S > context ) {
2023-06-18 13:46:41 +02:00
List < Text > lines = new ArrayList < > ( ) ;
lines . add ( Text . of ( TextColor . BLUE , " Maps loaded by BlueMap: " ) ) ;
2021-09-19 22:15:50 +02:00
2024-02-07 20:43:37 +01:00
for ( BmMap map : plugin . getBlueMap ( ) . getMaps ( ) . values ( ) ) {
2023-06-18 13:46:41 +02:00
boolean frozen = ! plugin . getPluginState ( ) . getMapState ( map ) . isUpdateEnabled ( ) ;
lines . add ( Text . of ( TextColor . GRAY , " - " ,
TextColor . WHITE , map . getId ( ) ,
TextColor . GRAY , " ( " + map . getName ( ) + " ) " ) ) ;
lines . add ( Text . of ( TextColor . GRAY , " \ u00A0 \ u00A0 \ u00A0World: " ,
2024-02-07 20:43:37 +01:00
TextColor . DARK_GRAY , map . getWorld ( ) . getId ( ) ) ) ;
2023-06-18 13:46:41 +02:00
lines . add ( Text . of ( TextColor . GRAY , " \ u00A0 \ u00A0 \ u00A0Last Update: " ,
TextColor . DARK_GRAY , helper . formatTime ( map . getRenderState ( ) . getLatestRenderTime ( ) ) ) ) ;
if ( frozen )
2023-08-10 16:09:57 +02:00
lines . add ( Text . of ( TextColor . AQUA , TextFormat . ITALIC , " \ u00A0 \ u00A0 \ u00A0This map is frozen! " ) ) ;
2021-09-19 22:15:50 +02:00
}
2023-06-18 13:46:41 +02:00
CommandSource source = commandSourceInterface . apply ( context . getSource ( ) ) ;
source . sendMessages ( lines ) ;
2021-09-19 22:15:50 +02:00
return 1 ;
}
2023-05-01 20:41:30 +02:00
public int storagesCommand ( CommandContext < S > context ) {
CommandSource source = commandSourceInterface . apply ( context . getSource ( ) ) ;
source . sendMessage ( Text . of ( TextColor . BLUE , " Storages loaded by BlueMap: " ) ) ;
2024-02-07 20:43:37 +01:00
for ( var entry : plugin . getBlueMap ( ) . getConfig ( ) . getStorageConfigs ( ) . entrySet ( ) ) {
2023-05-01 20:41:30 +02:00
source . sendMessage ( Text . of ( TextColor . GRAY , " - " , TextColor . WHITE , entry . getKey ( ) )
2024-02-24 14:11:56 +01:00
. setHoverText ( Text . of ( entry . getValue ( ) . getStorageTypeKey ( ) . getFormatted ( ) ) )
2023-05-01 20:41:30 +02:00
. setClickAction ( Text . ClickAction . RUN_COMMAND , " /bluemap storages " + entry . getKey ( ) )
) ;
}
return 1 ;
}
public int storagesInfoCommand ( CommandContext < S > context ) {
CommandSource source = commandSourceInterface . apply ( context . getSource ( ) ) ;
String storageId = context . getArgument ( " storage " , String . class ) ;
Storage storage ;
try {
2024-02-07 20:43:37 +01:00
storage = plugin . getBlueMap ( ) . getOrLoadStorage ( storageId ) ;
} catch ( ConfigurationException | InterruptedException ex ) {
Logger . global . logError ( " Unexpected exception trying to load storage ' " + storageId + " '! " , ex ) ;
source . sendMessage ( Text . of ( TextColor . RED , " There was an unexpected exception trying to load this storage. Please check the console for more details... " ) ) ;
2023-05-01 20:41:30 +02:00
return 0 ;
}
Collection < String > mapIds ;
try {
mapIds = storage . collectMapIds ( ) ;
} catch ( IOException ex ) {
2023-05-01 20:43:16 +02:00
Logger . global . logError ( " Unexpected exception trying to load mapIds from storage ' " + storageId + " '! " , ex ) ;
2024-02-07 20:43:37 +01:00
source . sendMessage ( Text . of ( TextColor . RED , " There was an unexpected exception trying to access this storage. Please check the console for more details... " ) ) ;
2023-05-01 20:41:30 +02:00
return 0 ;
}
source . sendMessage ( Text . of ( TextColor . BLUE , " Storage ' " , storageId , " ': " ) ) ;
if ( mapIds . isEmpty ( ) ) {
source . sendMessage ( Text . of ( TextColor . GRAY , " <empty storage> " ) ) ;
} else {
for ( String mapId : mapIds ) {
2024-02-07 20:43:37 +01:00
BmMap map = plugin . getBlueMap ( ) . getMaps ( ) . get ( mapId ) ;
2023-05-01 20:41:30 +02:00
boolean isLoaded = map ! = null & & map . getStorage ( ) . equals ( storage ) ;
if ( isLoaded ) {
source . sendMessage ( Text . of ( TextColor . GRAY , " - " , TextColor . WHITE , mapId , TextColor . GREEN , TextFormat . ITALIC , " (loaded) " ) ) ;
} else {
source . sendMessage ( Text . of ( TextColor . GRAY , " - " , TextColor . WHITE , mapId , TextColor . DARK_GRAY , TextFormat . ITALIC , " (unloaded/static/remote) " ) ) ;
}
}
}
return 1 ;
}
public int storagesDeleteMapCommand ( CommandContext < S > context ) {
CommandSource source = commandSourceInterface . apply ( context . getSource ( ) ) ;
String storageId = context . getArgument ( " storage " , String . class ) ;
String mapId = context . getArgument ( " map " , String . class ) ;
Storage storage ;
try {
2024-02-07 20:43:37 +01:00
storage = plugin . getBlueMap ( ) . getOrLoadStorage ( storageId ) ;
} catch ( ConfigurationException | InterruptedException ex ) {
Logger . global . logError ( " Unexpected exception trying to load storage ' " + storageId + " '! " , ex ) ;
source . sendMessage ( Text . of ( TextColor . RED , " There was an unexpected exception trying to load this storage. Please check the console for more details... " ) ) ;
2023-05-01 20:41:30 +02:00
return 0 ;
}
2024-02-07 20:43:37 +01:00
BmMap map = plugin . getBlueMap ( ) . getMaps ( ) . get ( mapId ) ;
2023-05-01 20:41:30 +02:00
boolean isLoaded = map ! = null & & map . getStorage ( ) . equals ( storage ) ;
if ( isLoaded ) {
Text purgeCommand = Text . of ( TextColor . WHITE , " /bluemap purge " + mapId )
. setClickAction ( Text . ClickAction . SUGGEST_COMMAND , " /bluemap purge " + mapId ) ;
source . sendMessage ( Text . of ( TextColor . RED , " Can't delete a loaded map! \ n " +
2023-05-01 20:43:16 +02:00
" Unload the map by removing its config-file first, \ n " +
2023-05-01 20:41:30 +02:00
" or use " , purgeCommand , " if you want to purge it. " ) ) ;
return 0 ;
}
// delete map
StorageDeleteTask deleteTask = new StorageDeleteTask ( storage , mapId ) ;
plugin . getRenderManager ( ) . scheduleRenderTaskNext ( deleteTask ) ;
source . sendMessage ( Text . of ( TextColor . GREEN , " Created new Task to delete map ' " + mapId + " ' from storage ' " + storageId + " ' " ) ) ;
return 1 ;
}
2020-05-10 01:28:09 +02:00
}