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 de.bluecolored.bluemap.common.plugin.Plugin ;
import de.bluecolored.bluemap.common.plugin.text.Text ;
import de.bluecolored.bluemap.common.plugin.text.TextColor ;
2021-09-18 14:04:03 +02:00
import de.bluecolored.bluemap.common.plugin.text.TextFormat ;
2021-05-02 14:51:42 +02:00
import de.bluecolored.bluemap.common.rendermanager.RenderManager ;
import de.bluecolored.bluemap.common.rendermanager.RenderTask ;
2020-05-10 01:28:09 +02:00
import de.bluecolored.bluemap.core.world.World ;
2021-05-08 23:47:13 +02:00
import org.apache.commons.lang3.time.DurationFormatUtils ;
2020-05-10 01:28:09 +02:00
2021-05-11 00:34:12 +02:00
import java.lang.ref.WeakReference ;
2023-06-18 13:46:41 +02:00
import java.time.Instant ;
import java.time.ZoneId ;
import java.time.format.DateTimeFormatter ;
2021-05-11 00:34:12 +02:00
import java.util.* ;
2021-04-24 22:11:26 +02:00
2020-05-10 01:28:09 +02:00
public class CommandHelper {
2023-06-18 13:46:41 +02:00
private static final DateTimeFormatter TIME_FORMAT =
DateTimeFormatter . ofPattern ( " yyyy-MM-dd hh:mm:ss " )
. withLocale ( Locale . ROOT )
. withZone ( ZoneId . systemDefault ( ) ) ;
2021-09-19 22:15:50 +02:00
private final Plugin plugin ;
private final Map < String , WeakReference < RenderTask > > taskRefMap ;
public CommandHelper ( Plugin plugin ) {
this . plugin = plugin ;
this . taskRefMap = new HashMap < > ( ) ;
}
public List < Text > createStatusMessage ( ) {
List < Text > lines = new ArrayList < > ( ) ;
RenderManager renderer = plugin . getRenderManager ( ) ;
List < RenderTask > tasks = renderer . getScheduledRenderTasks ( ) ;
lines . add ( Text . of ( TextColor . BLUE , " BlueMap - Status: " ) ) ;
if ( renderer . isRunning ( ) ) {
Text status ;
if ( tasks . isEmpty ( ) ) {
status = Text . of ( TextColor . GRAY , " idle " ) ;
} else {
status = Text . of ( TextColor . GREEN , " running " ) ;
}
status . setHoverText ( Text . of ( " click to stop rendering " ) ) ;
status . setClickAction ( Text . ClickAction . RUN_COMMAND , " /bluemap stop " ) ;
lines . add ( Text . of ( TextColor . WHITE , " Render-Threads are " , status , TextColor . WHITE , " ! " ) ) ;
2023-06-18 13:46:41 +02:00
if ( tasks . isEmpty ( ) ) {
lines . add ( Text . of ( TextColor . GRAY , " Last time running: " , TextColor . DARK_GRAY , formatTime ( renderer . getLastTimeBusy ( ) ) ) ) ;
} else {
2021-09-19 22:15:50 +02:00
lines . add ( Text . of ( TextColor . WHITE , " Queued Tasks ( " + tasks . size ( ) + " ): " ) ) ;
for ( int i = 0 ; i < tasks . size ( ) ; i + + ) {
if ( i > = 10 ) {
lines . add ( Text . of ( TextColor . GRAY , " ... " ) ) ;
break ;
}
RenderTask task = tasks . get ( i ) ;
2023-06-18 13:46:41 +02:00
lines . add ( Text . of ( TextColor . GRAY , " \ u00A0 \ u00A0[ " + getRefForTask ( task ) + " ] " , TextColor . GOLD , task . getDescription ( ) ) ) ;
2021-09-19 22:15:50 +02:00
if ( i = = 0 ) {
2023-06-18 13:46:41 +02:00
task . getDetail ( ) . ifPresent ( detail - >
lines . add ( Text . of ( TextColor . GRAY , " \ u00A0 \ u00A0 \ u00A0Detail: " , TextColor . WHITE , detail ) ) ) ;
2022-08-14 20:36:50 +02:00
2023-06-18 13:46:41 +02:00
lines . add ( Text . of ( TextColor . GRAY , " \ u00A0 \ u00A0 \ u00A0Progress: " , TextColor . WHITE ,
2021-09-19 22:15:50 +02:00
( Math . round ( task . estimateProgress ( ) * 10000 ) / 100 . 0 ) + " % " ) ) ;
long etaMs = renderer . estimateCurrentRenderTaskTimeRemaining ( ) ;
if ( etaMs > 0 ) {
2023-06-18 13:46:41 +02:00
lines . add ( Text . of ( TextColor . GRAY , " \ u00A0 \ u00A0 \ u00A0ETA: " , TextColor . WHITE , DurationFormatUtils . formatDuration ( etaMs , " HH:mm:ss " ) ) ) ;
2021-09-19 22:15:50 +02:00
}
}
}
}
} else {
if ( plugin . checkPausedByPlayerCount ( ) ) {
lines . add ( Text . of ( TextColor . WHITE , " Render-Threads are " ,
Text . of ( TextColor . GOLD , " paused " ) ) ) ;
2023-06-18 13:46:41 +02:00
lines . add ( Text . of ( TextColor . GRAY , TextFormat . ITALIC , " \ u00A0 \ u00A0 \ u00A0(there are " + plugin . getConfigs ( ) . getPluginConfig ( ) . getPlayerRenderLimit ( ) + " or more players online) " ) ) ;
2021-09-19 22:15:50 +02:00
} else {
lines . add ( Text . of ( TextColor . WHITE , " Render-Threads are " ,
Text . of ( TextColor . RED , " stopped " )
. setHoverText ( Text . of ( " click to start rendering " ) )
. setClickAction ( Text . ClickAction . RUN_COMMAND , " /bluemap start " ) ,
TextColor . GRAY , " ! " ) ) ;
}
if ( ! tasks . isEmpty ( ) ) {
lines . add ( Text . of ( TextColor . WHITE , " Queued Tasks ( " + tasks . size ( ) + " ): " ) ) ;
for ( int i = 0 ; i < tasks . size ( ) ; i + + ) {
if ( i > = 10 ) {
lines . add ( Text . of ( TextColor . GRAY , " ... " ) ) ;
break ;
}
RenderTask task = tasks . get ( i ) ;
lines . add ( Text . of ( TextColor . GRAY , " - " , TextColor . WHITE , task . getDescription ( ) ) ) ;
}
}
}
return lines ;
}
public Text worldHelperHover ( ) {
StringJoiner joiner = new StringJoiner ( " \ n " ) ;
2022-04-20 22:54:27 +02:00
for ( World world : plugin . getWorlds ( ) . values ( ) ) {
2021-09-19 22:15:50 +02:00
joiner . add ( world . getName ( ) ) ;
}
return Text . of ( " world " ) . setHoverText ( Text . of ( TextColor . WHITE , " Available worlds: \ n " , TextColor . GRAY , joiner . toString ( ) ) ) ;
}
public Text mapHelperHover ( ) {
StringJoiner joiner = new StringJoiner ( " \ n " ) ;
2022-04-20 22:54:27 +02:00
for ( String mapId : plugin . getMaps ( ) . keySet ( ) ) {
joiner . add ( mapId ) ;
2021-09-19 22:15:50 +02:00
}
return Text . of ( " map " ) . setHoverText ( Text . of ( TextColor . WHITE , " Available maps: \ n " , TextColor . GRAY , joiner . toString ( ) ) ) ;
}
public synchronized Optional < RenderTask > getTaskForRef ( String ref ) {
return Optional . ofNullable ( taskRefMap . get ( ref ) ) . map ( WeakReference : : get ) ;
}
public synchronized Collection < String > getTaskRefs ( ) {
return new ArrayList < > ( taskRefMap . keySet ( ) ) ;
}
private synchronized String getRefForTask ( RenderTask task ) {
Iterator < Map . Entry < String , WeakReference < RenderTask > > > iterator = taskRefMap . entrySet ( ) . iterator ( ) ;
while ( iterator . hasNext ( ) ) {
Map . Entry < String , WeakReference < RenderTask > > entry = iterator . next ( ) ;
if ( entry . getValue ( ) . get ( ) = = null ) iterator . remove ( ) ;
if ( entry . getValue ( ) . get ( ) = = task ) return entry . getKey ( ) ;
}
String newRef = safeRandomRef ( ) ;
taskRefMap . put ( newRef , new WeakReference < > ( task ) ) ;
return newRef ;
}
private synchronized String safeRandomRef ( ) {
String ref = randomRef ( ) ;
while ( taskRefMap . containsKey ( ref ) ) ref = randomRef ( ) ;
return ref ;
}
private String randomRef ( ) {
StringBuilder ref = new StringBuilder ( Integer . toString ( Math . abs ( new Random ( ) . nextInt ( ) ) , 16 ) ) ;
while ( ref . length ( ) < 4 ) ref . insert ( 0 , " 0 " ) ;
return ref . subSequence ( 0 , 4 ) . toString ( ) ;
}
2021-05-11 00:34:12 +02:00
2023-06-18 13:46:41 +02:00
public String formatTime ( long timestamp ) {
if ( timestamp < 0 ) return " - " ;
return TIME_FORMAT . format ( Instant . ofEpochMilli ( timestamp ) ) ;
}
2020-05-10 01:28:09 +02:00
}