2018-08-10 17:53:14 +02:00
package com.github.intellectualsites.plotsquared.plot.commands ;
2015-02-15 11:52:51 +01:00
2018-08-10 17:53:14 +02:00
import com.github.intellectualsites.plotsquared.commands.CommandDeclaration ;
import com.github.intellectualsites.plotsquared.plot.PS ;
import com.github.intellectualsites.plotsquared.plot.object.Plot ;
import com.github.intellectualsites.plotsquared.plot.object.PlotArea ;
import com.github.intellectualsites.plotsquared.plot.object.PlotId ;
import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer ;
import com.github.intellectualsites.plotsquared.plot.util.MainUtil ;
import com.github.intellectualsites.plotsquared.plot.util.MathMan ;
import com.github.intellectualsites.plotsquared.plot.util.TaskManager ;
import com.github.intellectualsites.plotsquared.plot.util.WorldUtil ;
2016-03-29 21:47:59 +02:00
2018-08-10 17:01:10 +02:00
import java.util.* ;
2016-02-14 02:01:18 +01:00
import java.util.Set ;
import java.util.concurrent.atomic.AtomicBoolean ;
2018-08-10 17:01:10 +02:00
@CommandDeclaration ( command = " condense " , permission = " plots.admin " , description = " Condense a plotworld " , category = CommandCategory . ADMINISTRATION , requiredType = RequiredType . CONSOLE )
2015-09-13 06:04:31 +02:00
public class Condense extends SubCommand {
2016-03-22 18:53:17 +01:00
2015-07-27 00:26:19 +02:00
public static boolean TASK = false ;
2016-03-22 18:53:17 +01:00
2018-08-10 17:01:10 +02:00
@Override public boolean onCommand ( final PlotPlayer player , String [ ] args ) {
2016-03-29 23:00:07 +02:00
if ( args . length ! = 2 & & args . length ! = 3 ) {
2016-06-02 17:38:47 +02:00
MainUtil . sendMessage ( player , " /plot condense <area> <start|stop|info> [radius] " ) ;
2015-02-16 04:46:57 +01:00
return false ;
}
2016-02-10 19:59:51 +01:00
PlotArea area = PS . get ( ) . getPlotAreaByString ( args [ 0 ] ) ;
if ( area = = null | | ! WorldUtil . IMP . isWorld ( area . worldname ) ) {
2016-06-02 17:38:47 +02:00
MainUtil . sendMessage ( player , " INVALID AREA " ) ;
2015-02-16 04:46:57 +01:00
return false ;
2015-02-15 11:52:51 +01:00
}
2015-09-13 06:04:31 +02:00
switch ( args [ 1 ] . toLowerCase ( ) ) {
case " start " : {
if ( args . length = = 2 ) {
2018-08-10 17:01:10 +02:00
MainUtil . sendMessage ( player ,
" /plot condense " + area . toString ( ) + " start <radius> " ) ;
2015-02-16 04:46:57 +01:00
return false ;
}
2016-03-29 23:00:07 +02:00
if ( Condense . TASK ) {
2016-06-02 17:38:47 +02:00
MainUtil . sendMessage ( player , " TASK ALREADY STARTED " ) ;
2015-02-16 06:36:47 +01:00
return false ;
}
2015-09-13 06:04:31 +02:00
if ( ! MathMan . isInteger ( args [ 2 ] ) ) {
2016-06-02 17:38:47 +02:00
MainUtil . sendMessage ( player , " INVALID RADIUS " ) ;
2015-02-16 06:36:47 +01:00
return false ;
}
2016-03-23 02:41:37 +01:00
int radius = Integer . parseInt ( args [ 2 ] ) ;
2016-02-10 19:59:51 +01:00
ArrayList < Plot > plots = new ArrayList < > ( PS . get ( ) . getPlots ( area ) ) ;
2015-09-22 15:23:28 +02:00
// remove non base plots
2016-03-29 21:47:59 +02:00
Iterator < Plot > iterator = plots . iterator ( ) ;
2015-09-22 15:23:28 +02:00
int maxSize = 0 ;
ArrayList < Integer > sizes = new ArrayList < > ( ) ;
2016-03-29 21:47:59 +02:00
while ( iterator . hasNext ( ) ) {
Plot plot = iterator . next ( ) ;
2015-09-22 15:23:28 +02:00
if ( ! plot . isBasePlot ( ) ) {
2016-03-29 21:47:59 +02:00
iterator . remove ( ) ;
2015-09-22 15:23:28 +02:00
continue ;
}
int size = plot . getConnectedPlots ( ) . size ( ) ;
if ( size > maxSize ) {
maxSize = size ;
}
sizes . add ( size - 1 ) ;
}
// Sort plots by size (buckets?)]
ArrayList < Plot > [ ] buckets = new ArrayList [ maxSize ] ;
for ( int i = 0 ; i < plots . size ( ) ; i + + ) {
Plot plot = plots . get ( i ) ;
int size = sizes . get ( i ) ;
ArrayList < Plot > array = buckets [ size ] ;
if ( array = = null ) {
2016-03-14 07:18:04 +01:00
array = new ArrayList < > ( ) ;
2015-09-22 15:23:28 +02:00
buckets [ size ] = array ;
}
array . add ( plot ) ;
}
2016-03-14 07:18:04 +01:00
final ArrayList < Plot > allPlots = new ArrayList < > ( plots . size ( ) ) ;
2015-09-22 15:23:28 +02:00
for ( int i = buckets . length - 1 ; i > = 0 ; i - - ) {
ArrayList < Plot > array = buckets [ i ] ;
if ( array ! = null ) {
allPlots . addAll ( array ) ;
}
}
2016-03-23 02:41:37 +01:00
int size = allPlots . size ( ) ;
2016-03-29 23:00:07 +02:00
int minimumRadius = ( int ) Math . ceil ( Math . sqrt ( size ) / 2 + 1 ) ;
2016-03-23 02:41:37 +01:00
if ( radius < minimumRadius ) {
2016-06-02 17:38:47 +02:00
MainUtil . sendMessage ( player , " RADIUS TOO SMALL " ) ;
2015-02-16 06:36:47 +01:00
return false ;
}
2016-03-23 02:41:37 +01:00
List < PlotId > toMove = new ArrayList < > ( getPlots ( allPlots , radius ) ) ;
2015-02-16 06:36:47 +01:00
final List < PlotId > free = new ArrayList < > ( ) ;
2015-02-20 07:34:19 +01:00
PlotId start = new PlotId ( 0 , 0 ) ;
2016-03-29 23:00:07 +02:00
while ( start . x < = minimumRadius & & start . y < = minimumRadius ) {
2016-02-10 19:59:51 +01:00
Plot plot = area . getPlotAbs ( start ) ;
if ( plot ! = null & & ! plot . hasOwner ( ) ) {
2016-01-10 21:00:56 +01:00
free . add ( plot . getId ( ) ) ;
2015-02-16 06:36:47 +01:00
}
2016-02-10 19:59:51 +01:00
start = Auto . getNextPlotId ( start , 1 ) ;
2015-02-16 06:36:47 +01:00
}
2016-03-23 02:41:37 +01:00
if ( free . isEmpty ( ) | | toMove . isEmpty ( ) ) {
2016-06-02 17:38:47 +02:00
MainUtil . sendMessage ( player , " NO FREE PLOTS FOUND " ) ;
2015-03-13 14:29:58 +01:00
return false ;
}
2016-06-02 17:38:47 +02:00
MainUtil . sendMessage ( player , " TASK STARTED... " ) ;
2015-09-22 15:23:28 +02:00
Runnable run = new Runnable ( ) {
2018-08-10 17:01:10 +02:00
@Override public void run ( ) {
2016-03-29 23:00:07 +02:00
if ( ! Condense . TASK ) {
2016-06-02 17:38:47 +02:00
MainUtil . sendMessage ( player , " TASK CANCELLED. " ) ;
2015-09-22 15:23:28 +02:00
}
2016-02-14 02:01:18 +01:00
if ( allPlots . isEmpty ( ) ) {
2016-03-29 23:00:07 +02:00
Condense . TASK = false ;
2018-08-10 17:01:10 +02:00
MainUtil . sendMessage ( player ,
" TASK COMPLETE. PLEASE VERIFY THAT NO NEW PLOTS HAVE BEEN CLAIMED DURING TASK. " ) ;
2015-02-16 06:36:47 +01:00
return ;
}
2015-09-22 15:23:28 +02:00
final Runnable task = this ;
final Plot origin = allPlots . remove ( 0 ) ;
int i = 0 ;
while ( free . size ( ) > i ) {
2016-02-11 02:37:21 +01:00
final Plot possible = origin . getArea ( ) . getPlotAbs ( free . get ( i ) ) ;
2016-02-14 02:01:18 +01:00
if ( possible . hasOwner ( ) ) {
2015-09-22 15:23:28 +02:00
free . remove ( i ) ;
continue ;
2015-02-16 06:36:47 +01:00
}
2015-09-22 15:23:28 +02:00
i + + ;
final AtomicBoolean result = new AtomicBoolean ( false ) ;
2016-02-10 19:59:51 +01:00
result . set ( origin . move ( possible , new Runnable ( ) {
2018-08-10 17:01:10 +02:00
@Override public void run ( ) {
2015-09-22 15:23:28 +02:00
if ( result . get ( ) ) {
2018-08-10 17:01:10 +02:00
MainUtil . sendMessage ( player ,
" Moving: " + origin + " -> " + possible ) ;
2015-09-22 15:23:28 +02:00
TaskManager . runTaskLater ( task , 1 ) ;
}
}
} , false ) ) ;
if ( result . get ( ) ) {
2015-02-16 06:36:47 +01:00
break ;
}
}
2016-02-14 02:01:18 +01:00
if ( free . isEmpty ( ) ) {
2016-03-29 23:00:07 +02:00
Condense . TASK = false ;
2016-06-02 17:38:47 +02:00
MainUtil . sendMessage ( player , " TASK FAILED. NO FREE PLOTS FOUND! " ) ;
2015-02-16 06:36:47 +01:00
return ;
}
2015-09-22 15:23:28 +02:00
if ( i > = free . size ( ) ) {
2016-06-02 17:38:47 +02:00
MainUtil . sendMessage ( player , " SKIPPING COMPLEX PLOT: " + origin ) ;
2015-09-22 15:23:28 +02:00
}
2015-02-16 06:36:47 +01:00
}
2015-09-22 15:23:28 +02:00
} ;
2016-03-29 23:00:07 +02:00
Condense . TASK = true ;
2015-09-22 15:23:28 +02:00
TaskManager . runTaskAsync ( run ) ;
2015-02-16 04:46:57 +01:00
return true ;
}
2016-03-29 23:00:07 +02:00
case " stop " :
if ( ! Condense . TASK ) {
2016-06-02 17:38:47 +02:00
MainUtil . sendMessage ( player , " TASK ALREADY STOPPED " ) ;
2015-02-16 06:36:47 +01:00
return false ;
}
2016-03-29 23:00:07 +02:00
Condense . TASK = false ;
2016-06-02 17:38:47 +02:00
MainUtil . sendMessage ( player , " TASK STOPPED " ) ;
2015-02-16 04:46:57 +01:00
return true ;
2016-03-29 23:00:07 +02:00
case " info " :
2015-09-13 06:04:31 +02:00
if ( args . length = = 2 ) {
2018-08-10 17:01:10 +02:00
MainUtil . sendMessage ( player ,
" /plot condense " + area . toString ( ) + " info <radius> " ) ;
2015-02-16 04:46:57 +01:00
return false ;
}
2015-09-13 06:04:31 +02:00
if ( ! MathMan . isInteger ( args [ 2 ] ) ) {
2016-06-02 17:38:47 +02:00
MainUtil . sendMessage ( player , " INVALID RADIUS " ) ;
2015-02-16 04:46:57 +01:00
return false ;
}
2016-03-23 02:41:37 +01:00
int radius = Integer . parseInt ( args [ 2 ] ) ;
Collection < Plot > plots = area . getPlots ( ) ;
int size = plots . size ( ) ;
2016-03-29 23:00:07 +02:00
int minimumRadius = ( int ) Math . ceil ( Math . sqrt ( size ) / 2 + 1 ) ;
2016-03-23 02:41:37 +01:00
if ( radius < minimumRadius ) {
2016-06-02 17:38:47 +02:00
MainUtil . sendMessage ( player , " RADIUS TOO SMALL " ) ;
2015-02-16 06:36:47 +01:00
return false ;
}
2016-03-23 02:41:37 +01:00
int maxMove = getPlots ( plots , minimumRadius ) . size ( ) ;
int userMove = getPlots ( plots , radius ) . size ( ) ;
2016-06-02 17:38:47 +02:00
MainUtil . sendMessage ( player , " === DEFAULT EVAL === " ) ;
MainUtil . sendMessage ( player , " MINIMUM RADIUS: " + minimumRadius ) ;
MainUtil . sendMessage ( player , " MAXIMUM MOVES: " + maxMove ) ;
MainUtil . sendMessage ( player , " === INPUT EVAL === " ) ;
MainUtil . sendMessage ( player , " INPUT RADIUS: " + radius ) ;
MainUtil . sendMessage ( player , " ESTIMATED MOVES: " + userMove ) ;
2018-08-10 17:01:10 +02:00
MainUtil . sendMessage ( player ,
" ESTIMATED TIME: No idea, times will drastically change based on the system performance and load " ) ;
2016-06-02 17:38:47 +02:00
MainUtil . sendMessage ( player , " &e - Radius is measured in plot width " ) ;
2015-02-16 04:46:57 +01:00
return true ;
2015-02-15 11:52:51 +01:00
}
2018-08-10 17:01:10 +02:00
MainUtil . sendMessage ( player ,
" /plot condense " + area . worldname + " <start|stop|info> [radius] " ) ;
2015-02-16 04:46:57 +01:00
return false ;
2015-02-15 11:52:51 +01:00
}
2016-03-22 18:53:17 +01:00
2016-03-23 02:41:37 +01:00
public Set < PlotId > getPlots ( Collection < Plot > plots , int radius ) {
HashSet < PlotId > outside = new HashSet < > ( ) ;
for ( Plot plot : plots ) {
2018-08-10 17:01:10 +02:00
if ( plot . getId ( ) . x > radius | | plot . getId ( ) . x < - radius | | plot . getId ( ) . y > radius
| | plot . getId ( ) . y < - radius ) {
2016-01-10 21:00:56 +01:00
outside . add ( plot . getId ( ) ) ;
2015-02-16 04:46:57 +01:00
}
}
return outside ;
2015-02-15 11:52:51 +01:00
}
}