2014-04-03 03:03:52 +00:00
/ *
2014-04-04 22:03:18 +00:00
* WorldEdit , a Minecraft world manipulation toolkit
* Copyright ( C ) sk89q < http : //www.sk89q.com>
* Copyright ( C ) WorldEdit team and contributors
2014-04-03 03:03:52 +00:00
*
2014-04-04 22:03:18 +00:00
* This program is free software : you can redistribute it and / or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation , either version 3 of the License , or
2014-04-03 03:03:52 +00:00
* ( at your option ) any later version .
*
2014-04-04 22:03:18 +00:00
* This program is distributed in the hope that it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE . See the GNU Lesser General Public License
* for more details .
2014-04-03 03:03:52 +00:00
*
2014-04-04 22:03:18 +00:00
* You should have received a copy of the GNU Lesser General Public License
2014-04-03 03:03:52 +00:00
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
2014-04-04 22:03:18 +00:00
* /
2014-04-03 03:03:52 +00:00
package com.sk89q.worldedit.bukkit ;
2019-09-14 03:05:16 +00:00
2018-08-12 14:03:07 +00:00
import com.boydti.fawe.Fawe ;
import com.boydti.fawe.bukkit.FaweBukkit ;
2019-11-20 03:40:52 +00:00
import com.sk89q.worldedit.bukkit.adapter.impl.FAWE_Spigot_v1_14_R4 ;
2019-09-14 03:05:16 +00:00
import com.boydti.fawe.util.MainUtil ;
2014-06-28 23:30:02 +00:00
import com.google.common.base.Joiner ;
2014-04-03 03:03:52 +00:00
import com.sk89q.util.yaml.YAMLProcessor ;
import com.sk89q.wepif.PermissionsResolverManager ;
2014-07-14 19:10:38 +00:00
import com.sk89q.worldedit.EditSession ;
import com.sk89q.worldedit.LocalSession ;
import com.sk89q.worldedit.WorldEdit ;
import com.sk89q.worldedit.bukkit.adapter.AdapterLoadException ;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter ;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplLoader ;
2019-12-19 16:33:08 +00:00
import com.sk89q.worldedit.bukkit.adapter.impl.FAWE_Spigot_v1_15_R1 ;
2020-02-02 01:11:02 +00:00
import com.sk89q.worldedit.bukkit.adapter.impl.FAWE_Spigot_v1_15_R2 ;
2014-06-28 00:55:39 +00:00
import com.sk89q.worldedit.event.platform.CommandEvent ;
2019-07-06 00:46:48 +00:00
import com.sk89q.worldedit.event.platform.CommandSuggestionEvent ;
2014-06-27 08:11:35 +00:00
import com.sk89q.worldedit.event.platform.PlatformReadyEvent ;
2014-06-28 00:55:39 +00:00
import com.sk89q.worldedit.extension.platform.Actor ;
2014-07-19 00:37:03 +00:00
import com.sk89q.worldedit.extension.platform.Capability ;
import com.sk89q.worldedit.extension.platform.Platform ;
2014-04-03 03:03:52 +00:00
import com.sk89q.worldedit.extent.inventory.BlockBag ;
2019-08-18 01:09:09 +00:00
import com.sk89q.worldedit.internal.command.CommandUtil ;
2020-01-31 22:44:50 +00:00
import com.sk89q.worldedit.internal.anvil.ChunkDeleter ;
2019-04-05 04:15:10 +00:00
import com.sk89q.worldedit.world.biome.BiomeType ;
2019-02-17 03:30:40 +00:00
import com.sk89q.worldedit.world.block.BlockCategory ;
2019-04-05 04:15:10 +00:00
import com.sk89q.worldedit.world.entity.EntityType ;
2019-08-26 04:45:03 +00:00
import com.sk89q.worldedit.world.gamemode.GameModes ;
2019-02-17 03:30:40 +00:00
import com.sk89q.worldedit.world.item.ItemCategory ;
2019-08-26 04:45:03 +00:00
import com.sk89q.worldedit.world.weather.WeatherTypes ;
2019-07-06 00:46:48 +00:00
import io.papermc.lib.PaperLib ;
2019-09-14 03:05:16 +00:00
import java.lang.reflect.Field ;
import java.util.ArrayList ;
import java.util.concurrent.ConcurrentHashMap ;
import org.bstats.bukkit.Metrics ;
2018-08-12 14:03:07 +00:00
import org.bukkit.Bukkit ;
import org.bukkit.Material ;
2019-02-17 03:30:40 +00:00
import org.bukkit.Tag ;
2019-04-05 04:15:10 +00:00
import org.bukkit.block.Biome ;
2019-08-18 01:09:09 +00:00
import org.bukkit.command.BlockCommandSender ;
2014-06-28 23:30:02 +00:00
import org.bukkit.command.Command ;
2014-04-03 03:03:52 +00:00
import org.bukkit.command.CommandSender ;
import org.bukkit.entity.Player ;
2019-07-06 00:46:48 +00:00
import org.bukkit.event.EventHandler ;
2019-09-14 03:05:16 +00:00
import org.bukkit.event.EventPriority ;
2019-07-06 00:46:48 +00:00
import org.bukkit.event.Listener ;
2019-09-14 03:05:16 +00:00
import org.bukkit.event.world.WorldInitEvent ;
2019-10-23 04:23:52 +00:00
import org.bukkit.metadata.FixedMetadataValue ;
import org.bukkit.metadata.MetadataValue ;
2019-04-02 22:21:02 +00:00
import org.bukkit.plugin.Plugin ;
import org.bukkit.plugin.PluginDescriptionFile ;
2019-04-05 06:51:42 +00:00
import org.bukkit.plugin.PluginManager ;
2014-04-03 03:03:52 +00:00
import org.bukkit.plugin.java.JavaPlugin ;
2018-08-12 14:03:07 +00:00
import org.bukkit.plugin.java.JavaPluginLoader ;
2019-06-06 22:39:51 +00:00
import org.jetbrains.annotations.NotNull ;
2019-03-14 02:51:48 +00:00
import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;
2014-04-03 03:03:52 +00:00
2020-01-31 22:44:50 +00:00
import javax.annotation.Nullable ;
import java.io.File ;
import java.io.FileNotFoundException ;
import java.io.FileOutputStream ;
import java.io.IOException ;
import java.io.InputStream ;
import java.nio.file.Files ;
import java.nio.file.Path ;
import java.nio.file.Paths ;
import java.util.List ;
import java.util.Locale ;
import java.util.Map ;
import java.util.Optional ;
import java.util.logging.Level ;
import static com.google.common.base.Preconditions.checkNotNull ;
import static com.sk89q.worldedit.internal.anvil.ChunkDeleter.DELCHUNKS_FILE_NAME ;
2014-04-03 03:03:52 +00:00
/ * *
* Plugin for Bukkit .
* /
2019-04-02 22:21:02 +00:00
public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
2014-04-03 03:03:52 +00:00
2019-03-14 02:51:48 +00:00
private static final Logger log = LoggerFactory . getLogger ( WorldEditPlugin . class ) ;
2018-08-14 02:07:11 +00:00
public static final String CUI_PLUGIN_CHANNEL = " worldedit:cui " ;
2014-07-14 19:10:38 +00:00
private static WorldEditPlugin INSTANCE ;
2020-01-31 22:44:50 +00:00
///The BSTATS_ID needs to be modified for FAWE to prevent contaminating WorldEdit stats
2020-02-05 21:27:50 +00:00
private static final int BSTATS_PLUGIN_ID = 1403 ;
2014-04-03 03:03:52 +00:00
2014-07-14 19:10:38 +00:00
private BukkitImplAdapter bukkitAdapter ;
2014-04-03 03:03:52 +00:00
private BukkitServerInterface server ;
private BukkitConfiguration config ;
2018-08-12 14:03:07 +00:00
private static Map < String , Plugin > lookupNames ;
2019-04-04 14:24:47 +00:00
static {
2019-06-25 13:00:44 +00:00
// Disable AWE as otherwise both fail to load
PluginManager manager = Bukkit . getPluginManager ( ) ;
try {
Field pluginsField = manager . getClass ( ) . getDeclaredField ( " plugins " ) ;
Field lookupNamesField = manager . getClass ( ) . getDeclaredField ( " lookupNames " ) ;
pluginsField . setAccessible ( true ) ;
lookupNamesField . setAccessible ( true ) ;
List < Plugin > plugins = ( List < Plugin > ) pluginsField . get ( manager ) ;
lookupNames = ( Map < String , Plugin > ) lookupNamesField . get ( manager ) ;
pluginsField . set ( manager , new ArrayList < Plugin > ( plugins ) {
@Override
public boolean add ( Plugin plugin ) {
if ( plugin . getName ( ) . startsWith ( " AsyncWorldEdit " ) ) {
2019-11-11 21:02:28 +00:00
log . debug ( " Disabling ` " + plugin . getName ( ) + " ` as it is incompatible " ) ;
2019-06-25 13:00:44 +00:00
} else {
return super . add ( plugin ) ;
2019-04-04 14:24:47 +00:00
}
2019-06-25 13:00:44 +00:00
return false ;
}
} ) ;
lookupNamesField . set ( manager , lookupNames = new ConcurrentHashMap < String , Plugin > ( lookupNames ) {
@Override
public Plugin put ( @NotNull String key , @NotNull Plugin plugin ) {
2020-01-31 22:44:50 +00:00
if ( plugin . getName ( ) . startsWith ( " AsyncWorldEdit " ) ) {
2019-06-25 13:00:44 +00:00
return null ;
2019-04-04 14:24:47 +00:00
}
2019-06-25 13:00:44 +00:00
return super . put ( key , plugin ) ;
}
} ) ;
} catch ( Throwable ignore ) { }
2019-04-04 14:24:47 +00:00
}
2018-08-12 14:03:07 +00:00
public WorldEditPlugin ( ) {
2018-08-16 13:21:39 +00:00
init ( ) ;
2018-08-12 14:03:07 +00:00
}
public WorldEditPlugin ( JavaPluginLoader loader , PluginDescriptionFile desc , File dataFolder , File jarFile ) {
2018-08-17 08:27:48 +00:00
super ( loader , desc , dataFolder , jarFile ) ;
2018-08-16 13:21:39 +00:00
init ( ) ;
}
private void init ( ) {
if ( lookupNames ! = null ) {
2019-07-18 06:56:57 +00:00
lookupNames . putIfAbsent ( " FastAsyncWorldEdit " . toLowerCase ( Locale . ROOT ) , this ) ;
lookupNames . putIfAbsent ( " WorldEdit " . toLowerCase ( Locale . ROOT ) , this ) ;
2018-08-16 17:30:55 +00:00
lookupNames . putIfAbsent ( " FastAsyncWorldEdit " , this ) ;
lookupNames . putIfAbsent ( " WorldEdit " , this ) ;
2018-08-16 13:21:39 +00:00
rename ( ) ;
}
setEnabled ( true ) ;
2018-08-12 14:03:07 +00:00
}
2014-04-03 03:03:52 +00:00
@Override
2019-03-15 22:20:12 +00:00
public void onLoad ( ) {
2019-04-05 04:15:10 +00:00
if ( INSTANCE ! = null ) return ;
2019-04-03 05:53:34 +00:00
rename ( ) ;
2019-06-06 22:39:51 +00:00
INSTANCE = this ;
2018-08-12 14:03:07 +00:00
FaweBukkit imp = new FaweBukkit ( this ) ;
2014-04-03 03:03:52 +00:00
2014-07-29 18:04:04 +00:00
//noinspection ResultOfMethodCallIgnored
2014-07-18 23:47:57 +00:00
getDataFolder ( ) . mkdirs ( ) ;
2014-07-14 19:10:38 +00:00
WorldEdit worldEdit = WorldEdit . getInstance ( ) ;
2014-04-03 03:03:52 +00:00
2014-07-14 19:10:38 +00:00
// Setup platform
2014-04-03 03:03:52 +00:00
server = new BukkitServerInterface ( this , getServer ( ) ) ;
2014-07-14 19:10:38 +00:00
worldEdit . getPlatformManager ( ) . register ( server ) ;
2018-07-17 14:42:09 +00:00
2019-09-14 03:05:16 +00:00
Path delChunks = Paths . get ( getDataFolder ( ) . getPath ( ) , DELCHUNKS_FILE_NAME ) ;
if ( Files . exists ( delChunks ) ) {
ChunkDeleter . runFromFile ( delChunks , true ) ;
}
2019-11-19 21:23:47 +00:00
fail ( ( ) - > PermissionsResolverManager . initialize ( INSTANCE ) , " Failed to initialize permissions resolver " ) ;
2019-03-15 22:20:12 +00:00
}
/ * *
* Called on plugin enable .
* /
@Override
public void onEnable ( ) {
2019-04-05 04:15:10 +00:00
if ( INSTANCE ! = null ) return ;
onLoad ( ) ;
2019-03-16 02:38:38 +00:00
2018-07-17 14:42:09 +00:00
PermissionsResolverManager . initialize ( this ) ; // Setup permission resolver
2014-07-14 19:10:38 +00:00
// Register CUI
2019-06-28 17:10:47 +00:00
fail ( ( ) - > {
2019-06-25 13:00:44 +00:00
getServer ( ) . getMessenger ( ) . registerIncomingPluginChannel ( this , CUI_PLUGIN_CHANNEL , new CUIChannelListener ( this ) ) ;
getServer ( ) . getMessenger ( ) . registerOutgoingPluginChannel ( this , CUI_PLUGIN_CHANNEL ) ;
2019-06-28 17:10:47 +00:00
} , " Failed to register CUI " ) ;
2014-07-14 19:10:38 +00:00
// Now we can register events
2014-06-27 08:11:35 +00:00
getServer ( ) . getPluginManager ( ) . registerEvents ( new WorldEditListener ( this ) , this ) ;
2019-07-06 00:46:48 +00:00
// register async tab complete, if available
if ( PaperLib . isPaper ( ) ) {
getServer ( ) . getPluginManager ( ) . registerEvents ( new AsyncTabCompleteListener ( ) , this ) ;
}
2014-06-27 08:11:35 +00:00
2019-09-14 03:05:16 +00:00
initializeRegistries ( ) ; // this creates the objects matching Bukkit's enums - but doesn't fill them with data yet
if ( Bukkit . getWorlds ( ) . isEmpty ( ) ) {
setupPreWorldData ( ) ;
// register this so we can load world-dependent data right as the first world is loading
getServer ( ) . getPluginManager ( ) . registerEvents ( new WorldInitListener ( ) , this ) ;
} else {
getLogger ( ) . warning ( " Server reload detected. This may cause various issues with WorldEdit and dependent plugins. " ) ;
try {
setupPreWorldData ( ) ;
// since worlds are loaded already, we can do this now
setupWorldData ( ) ;
} catch ( Throwable ignored ) {
}
}
2018-08-12 14:03:07 +00:00
2019-09-14 03:05:16 +00:00
// Enable metrics
2020-02-05 21:27:50 +00:00
new Metrics ( this , BSTATS_PLUGIN_ID ) ;
2019-07-06 00:46:48 +00:00
PaperLib . suggestPaper ( this ) ;
2014-04-03 03:03:52 +00:00
}
2019-09-14 03:05:16 +00:00
private void setupPreWorldData ( ) {
loadAdapter ( ) ;
loadConfig ( ) ;
WorldEdit . getInstance ( ) . loadMappings ( ) ;
}
private void setupWorldData ( ) {
setupTags ( ) ; // datapacks aren't loaded until just before the world is, and bukkit has no event for this
// so the earliest we can do this is in WorldInit
WorldEdit . getInstance ( ) . getEventBus ( ) . post ( new PlatformReadyEvent ( ) ) ;
}
private void initializeRegistries ( ) {
2019-04-05 04:15:10 +00:00
// Biome
for ( Biome biome : Biome . values ( ) ) {
2019-07-22 02:49:08 +00:00
String lowerCaseBiomeName = biome . name ( ) . toLowerCase ( Locale . ROOT ) ;
2019-11-24 00:57:29 +00:00
BiomeType biomeType = BiomeType . REGISTRY . register ( " minecraft: " + lowerCaseBiomeName , new BiomeType ( " minecraft: " + lowerCaseBiomeName ) ) ;
if ( bukkitAdapter ! = null ) biomeType . setLegacyId ( bukkitAdapter . getInternalBiomeId ( biomeType ) ) ;
2019-04-05 04:15:10 +00:00
}
2020-02-05 21:27:50 +00:00
// Block & Item
/ * for ( Material material : Material . values ( ) ) {
2019-06-06 22:39:51 +00:00
if ( material . isBlock ( ) & & ! material . isLegacy ( ) ) {
BlockType . REGISTRY . register ( material . getKey ( ) . toString ( ) , new BlockType ( material . getKey ( ) . toString ( ) , blockState - > {
// TODO Use something way less hacky than this.
ParserContext context = new ParserContext ( ) ;
context . setPreferringWildcard ( true ) ;
context . setTryLegacy ( false ) ;
context . setRestricted ( false ) ;
try {
FuzzyBlockState state = ( FuzzyBlockState ) WorldEdit . getInstance ( ) . getBlockFactory ( ) . parseFromInput (
BukkitAdapter . adapt ( blockState . getBlockType ( ) ) . createBlockData ( ) . getAsString ( ) , context
) . toImmutableState ( ) ;
BlockState defaultState = blockState . getBlockType ( ) . getAllStates ( ) . get ( 0 ) ;
for ( Map . Entry < Property < ? > , Object > propertyObjectEntry : state . getStates ( ) . entrySet ( ) ) {
2019-07-06 00:46:48 +00:00
//noinspection unchecked
defaultState = defaultState . with ( ( Property < Object > ) propertyObjectEntry . getKey ( ) , propertyObjectEntry . getValue ( ) ) ;
2019-06-06 22:39:51 +00:00
}
return defaultState ;
} catch ( InputParseException e ) {
2019-07-06 00:46:48 +00:00
getLogger ( ) . log ( Level . WARNING , " Error loading block state for " + material . getKey ( ) , e ) ;
2019-06-06 22:39:51 +00:00
return blockState ;
}
} ) ) ;
}
2019-04-05 04:15:10 +00:00
if ( material . isItem ( ) & & ! material . isLegacy ( ) ) {
ItemType . REGISTRY . register ( material . getKey ( ) . toString ( ) , new ItemType ( material . getKey ( ) . toString ( ) ) ) ;
}
}
2019-11-19 04:40:40 +00:00
* /
2019-04-05 04:15:10 +00:00
// Entity
for ( org . bukkit . entity . EntityType entityType : org . bukkit . entity . EntityType . values ( ) ) {
String mcid = entityType . getName ( ) ;
if ( mcid ! = null ) {
2019-07-22 02:49:08 +00:00
String lowerCaseMcId = mcid . toLowerCase ( Locale . ROOT ) ;
EntityType . REGISTRY . register ( " minecraft: " + lowerCaseMcId , new EntityType ( " minecraft: " + lowerCaseMcId ) ) ;
2019-04-05 04:15:10 +00:00
}
}
2019-08-26 04:45:03 +00:00
// ... :|
GameModes . get ( " " ) ;
WeatherTypes . get ( " " ) ;
2019-04-05 04:15:10 +00:00
}
2019-03-16 02:38:38 +00:00
private void setupTags ( ) {
2019-02-17 03:30:40 +00:00
// Tags
try {
2019-03-16 02:38:38 +00:00
for ( Tag < Material > blockTag : Bukkit . getTags ( Tag . REGISTRY_BLOCKS , Material . class ) ) {
2019-02-17 03:30:40 +00:00
BlockCategory . REGISTRY . register ( blockTag . getKey ( ) . toString ( ) , new BlockCategory ( blockTag . getKey ( ) . toString ( ) ) ) ;
}
2019-03-16 02:38:38 +00:00
for ( Tag < Material > itemTag : Bukkit . getTags ( Tag . REGISTRY_ITEMS , Material . class ) ) {
2019-02-17 03:30:40 +00:00
ItemCategory . REGISTRY . register ( itemTag . getKey ( ) . toString ( ) , new ItemCategory ( itemTag . getKey ( ) . toString ( ) ) ) ;
}
2019-07-06 00:46:48 +00:00
} catch ( NoSuchMethodError ignored ) {
2019-02-17 03:30:40 +00:00
getLogger ( ) . warning ( " The version of Spigot/Paper you are using doesn't support Tags. The usage of tags with WorldEdit will not work until you update. " ) ;
}
2019-02-16 09:35:13 +00:00
}
2018-08-16 13:21:39 +00:00
private void rename ( ) {
2019-06-25 13:00:44 +00:00
File dir = new File ( getDataFolder ( ) . getParentFile ( ) , " FastAsyncWorldEdit " ) ;
2019-06-06 22:39:51 +00:00
try {
Field descriptionField = JavaPlugin . class . getDeclaredField ( " dataFolder " ) ;
descriptionField . setAccessible ( true ) ;
descriptionField . set ( this , dir ) ;
2019-10-23 04:23:52 +00:00
} catch ( Throwable e ) {
e . printStackTrace ( ) ;
2019-06-06 22:39:51 +00:00
}
2019-10-23 04:23:52 +00:00
try {
File pluginsFolder = MainUtil . getJarFile ( ) . getParentFile ( ) ;
for ( File file : pluginsFolder . listFiles ( ) ) {
2020-01-22 00:09:07 +00:00
if ( file . length ( ) = = 2052 ) return ;
2019-10-23 04:23:52 +00:00
}
Plugin plugin = Bukkit . getPluginManager ( ) . getPlugin ( " FastAsyncWorldEdit " ) ;
File dummy = MainUtil . copyFile ( MainUtil . getJarFile ( ) , " DummyFawe.src " , pluginsFolder , " DummyFawe.jar " ) ;
if ( dummy ! = null & & dummy . exists ( ) & & plugin = = this ) {
try {
Bukkit . getPluginManager ( ) . loadPlugin ( dummy ) ;
} catch ( Throwable e ) {
if ( Bukkit . getUpdateFolderFile ( ) . mkdirs ( ) ) {
MainUtil . copyFile ( MainUtil . getJarFile ( ) , " DummyFawe.src " , pluginsFolder , Bukkit . getUpdateFolder ( ) + File . separator + " DummyFawe.jar " ) ;
} else {
getLogger ( ) . info ( " Please delete DummyFawe.jar and restart " ) ;
}
2019-08-29 12:57:03 +00:00
}
2019-10-23 04:23:52 +00:00
getLogger ( ) . info ( " Please restart the server if you have any plugins which depend on FAWE. " ) ;
} else if ( dummy = = null ) {
MainUtil . copyFile ( MainUtil . getJarFile ( ) , " DummyFawe.src " , pluginsFolder , " update " + File . separator + " DummyFawe.jar " ) ;
2018-08-21 18:18:10 +00:00
}
2019-10-23 04:23:52 +00:00
} catch ( Throwable e ) {
e . printStackTrace ( ) ;
2018-08-16 13:21:39 +00:00
}
}
2018-08-12 14:03:07 +00:00
private void fail ( Runnable run , String message ) {
try {
run . run ( ) ;
} catch ( Throwable e ) {
2019-04-02 22:21:02 +00:00
getLogger ( ) . severe ( message ) ;
2018-08-12 14:03:07 +00:00
e . printStackTrace ( ) ;
}
}
2014-07-14 19:10:38 +00:00
2018-08-12 14:03:07 +00:00
private void loadConfig ( ) {
createDefaultConfiguration ( " config-legacy.yml " ) ; // Create the default configuration file
2019-09-19 18:56:03 +00:00
2019-09-14 03:05:16 +00:00
config = new BukkitConfiguration ( new YAMLProcessor ( new File ( getDataFolder ( ) , " config-legacy.yml " ) , true ) , this ) ;
config . load ( ) ;
2018-08-17 12:48:33 +00:00
// Create schematics folder
WorldEdit worldEdit = WorldEdit . getInstance ( ) ;
File dir = worldEdit . getWorkingDirectoryFile ( worldEdit . getConfiguration ( ) . saveDir ) ;
dir . mkdirs ( ) ;
2014-07-14 19:10:38 +00:00
}
private void loadAdapter ( ) {
2014-07-19 00:37:03 +00:00
WorldEdit worldEdit = WorldEdit . getInstance ( ) ;
2014-07-14 19:10:38 +00:00
// Attempt to load a Bukkit adapter
BukkitImplLoader adapterLoader = new BukkitImplLoader ( ) ;
2018-08-27 16:56:28 +00:00
try {
2019-11-19 04:40:40 +00:00
adapterLoader . addClass ( FAWE_Spigot_v1_14_R4 . class ) ;
2019-12-19 16:33:08 +00:00
adapterLoader . addClass ( FAWE_Spigot_v1_15_R1 . class ) ;
2020-02-02 01:11:02 +00:00
adapterLoader . addClass ( FAWE_Spigot_v1_15_R2 . class ) ;
2019-04-02 22:21:02 +00:00
} catch ( Throwable throwable ) {
throwable . printStackTrace ( ) ;
2018-08-27 16:56:28 +00:00
}
2014-07-14 19:10:38 +00:00
2014-04-03 03:03:52 +00:00
try {
2014-07-14 19:10:38 +00:00
adapterLoader . addFromPath ( getClass ( ) . getClassLoader ( ) ) ;
} catch ( IOException e ) {
2019-03-14 02:51:48 +00:00
log . warn ( " Failed to search path for Bukkit adapters " ) ;
2014-07-14 19:10:38 +00:00
}
try {
adapterLoader . addFromJar ( getFile ( ) ) ;
} catch ( IOException e ) {
2019-03-14 02:51:48 +00:00
log . warn ( " Failed to search " + getFile ( ) + " for Bukkit adapters " , e ) ;
2014-07-14 19:10:38 +00:00
}
try {
bukkitAdapter = adapterLoader . loadAdapter ( ) ;
2019-03-14 02:51:48 +00:00
log . info ( " Using " + bukkitAdapter . getClass ( ) . getCanonicalName ( ) + " as the Bukkit adapter " ) ;
2014-07-14 19:10:38 +00:00
} catch ( AdapterLoadException e ) {
2019-04-02 22:21:02 +00:00
Platform platform = worldEdit . getPlatformManager ( ) . queryCapability ( Capability . WORLD_EDITING ) ;
if ( platform instanceof BukkitServerInterface ) {
log . warn ( e . getMessage ( ) ) ;
} else {
log . info ( " WorldEdit could not find a Bukkit adapter for this MC version, " +
" but it seems that you have another implementation of WorldEdit installed ( " + platform . getPlatformName ( ) + " ) " +
" that handles the world editing. " ) ;
}
2014-07-14 19:10:38 +00:00
}
2014-04-03 03:03:52 +00:00
}
/ * *
* Called on plugin disable .
* /
@Override
public void onDisable ( ) {
2018-08-12 14:03:07 +00:00
Fawe . get ( ) . onDisable ( ) ;
2014-07-14 19:10:38 +00:00
WorldEdit worldEdit = WorldEdit . getInstance ( ) ;
2019-09-14 03:05:16 +00:00
worldEdit . getSessionManager ( ) . unload ( ) ;
2014-07-14 19:10:38 +00:00
worldEdit . getPlatformManager ( ) . unregister ( server ) ;
if ( config ! = null ) {
2014-06-29 08:43:30 +00:00
config . unload ( ) ;
2014-07-14 19:10:38 +00:00
}
if ( server ! = null ) {
2014-06-29 08:43:30 +00:00
server . unregisterCommands ( ) ;
}
2014-04-03 03:03:52 +00:00
this . getServer ( ) . getScheduler ( ) . cancelTasks ( this ) ;
}
/ * *
* Loads and reloads all configuration .
* /
protected void loadConfiguration ( ) {
config . unload ( ) ;
config . load ( ) ;
getPermissionsResolver ( ) . load ( ) ;
}
/ * *
* Create a default configuration file from the . jar .
*
2014-07-14 19:10:38 +00:00
* @param name the filename
2014-04-03 03:03:52 +00:00
* /
protected void createDefaultConfiguration ( String name ) {
File actual = new File ( getDataFolder ( ) , name ) ;
if ( ! actual . exists ( ) ) {
2020-03-11 05:35:37 +00:00
try ( InputStream stream = getResource ( " defaults/ " + name ) ) {
if ( stream = = null ) throw new FileNotFoundException ( ) ;
copyDefaultConfig ( stream , actual , name ) ;
2014-04-03 03:03:52 +00:00
} catch ( IOException e ) {
getLogger ( ) . severe ( " Unable to read default configuration: " + name ) ;
}
2018-12-27 00:50:24 +00:00
}
}
2014-04-03 03:03:52 +00:00
2018-12-27 00:50:24 +00:00
private void copyDefaultConfig ( InputStream input , File actual , String name ) {
try ( FileOutputStream output = new FileOutputStream ( actual ) ) {
byte [ ] buf = new byte [ 8192 ] ;
int length ;
while ( ( length = input . read ( buf ) ) > 0 ) {
output . write ( buf , 0 , length ) ;
2014-04-03 03:03:52 +00:00
}
2018-12-27 00:50:24 +00:00
getLogger ( ) . info ( " Default configuration file written: " + name ) ;
} catch ( IOException e ) {
getLogger ( ) . log ( Level . WARNING , " Failed to write default config file " , e ) ;
2014-04-03 03:03:52 +00:00
}
}
@Override
2014-06-28 23:30:02 +00:00
public boolean onCommand ( CommandSender sender , Command cmd , String commandLabel , String [ ] args ) {
2020-02-07 01:26:04 +00:00
// Add the command to the array because the underlying command handling
// code of WorldEdit expects it
String [ ] split = new String [ args . length + 1 ] ;
System . arraycopy ( args , 0 , split , 1 , args . length ) ;
split [ 0 ] = commandLabel ;
2014-04-03 03:03:52 +00:00
2020-02-07 01:26:04 +00:00
CommandEvent event = new CommandEvent ( wrapCommandSender ( sender ) , Joiner . on ( " " ) . join ( split ) ) ;
2014-06-28 00:55:39 +00:00
getWorldEdit ( ) . getEventBus ( ) . post ( event ) ;
2014-04-03 03:03:52 +00:00
return true ;
}
2020-01-31 22:44:50 +00:00
/ *
@Override
public List < String > onTabComplete ( CommandSender sender , Command cmd , String commandLabel , String [ ] args ) {
int plSep = commandLabel . indexOf ( " : " ) ;
if ( plSep > = 0 & & plSep < commandLabel . length ( ) + 1 ) {
commandLabel = commandLabel . substring ( plSep + 1 ) ;
}
StringBuilder sb = new StringBuilder ( " / " ) . append ( commandLabel ) ;
if ( args . length > 0 ) {
sb . append ( " " ) ;
}
String arguments = Joiner . on ( " " ) . appendTo ( sb , args ) . toString ( ) ;
CommandSuggestionEvent event = new CommandSuggestionEvent ( wrapCommandSender ( sender ) , arguments ) ;
getWorldEdit ( ) . getEventBus ( ) . post ( event ) ;
return CommandUtil . fixSuggestions ( arguments , event . getSuggestions ( ) ) ;
}
* /
2014-04-03 03:03:52 +00:00
/ * *
* Gets the session for the player .
*
2014-07-29 18:04:04 +00:00
* @param player a player
* @return a session
2014-04-03 03:03:52 +00:00
* /
public LocalSession getSession ( Player player ) {
2018-06-16 06:36:55 +00:00
return WorldEdit . getInstance ( ) . getSessionManager ( ) . get ( wrapPlayer ( player ) ) ;
2014-04-03 03:03:52 +00:00
}
/ * *
* Gets the session for the player .
*
2014-07-29 18:04:04 +00:00
* @param player a player
* @return a session
2014-04-03 03:03:52 +00:00
* /
public EditSession createEditSession ( Player player ) {
2018-06-16 05:29:48 +00:00
com . sk89q . worldedit . entity . Player wePlayer = wrapPlayer ( player ) ;
LocalSession session = WorldEdit . getInstance ( ) . getSessionManager ( ) . get ( wePlayer ) ;
2014-04-03 03:03:52 +00:00
BlockBag blockBag = session . getBlockBag ( wePlayer ) ;
2014-07-14 19:10:38 +00:00
EditSession editSession = WorldEdit . getInstance ( ) . getEditSessionFactory ( )
2014-04-03 03:03:52 +00:00
. getEditSession ( wePlayer . getWorld ( ) , session . getBlockChangeLimit ( ) , blockBag , wePlayer ) ;
2018-10-04 17:37:58 +00:00
editSession . enableStandardMode ( ) ;
2014-04-03 03:03:52 +00:00
return editSession ;
}
/ * *
* Remember an edit session .
*
2014-07-29 18:04:04 +00:00
* @param player a player
* @param editSession an edit session
2014-04-03 03:03:52 +00:00
* /
public void remember ( Player player , EditSession editSession ) {
2018-06-16 05:29:48 +00:00
com . sk89q . worldedit . entity . Player wePlayer = wrapPlayer ( player ) ;
LocalSession session = WorldEdit . getInstance ( ) . getSessionManager ( ) . get ( wePlayer ) ;
2014-04-03 03:03:52 +00:00
session . remember ( editSession ) ;
2018-10-21 01:54:58 +00:00
editSession . flushSession ( ) ;
2014-04-03 03:03:52 +00:00
2014-07-14 19:10:38 +00:00
WorldEdit . getInstance ( ) . flushBlockBag ( wePlayer , editSession ) ;
2014-04-03 03:03:52 +00:00
}
/ * *
* Returns the configuration used by WorldEdit .
*
2014-07-29 18:04:04 +00:00
* @return the configuration
2014-04-03 03:03:52 +00:00
* /
public BukkitConfiguration getLocalConfiguration ( ) {
return config ;
}
/ * *
* Get the permissions resolver in use .
*
2014-07-29 18:04:04 +00:00
* @return the permissions resolver
2014-04-03 03:03:52 +00:00
* /
public PermissionsResolverManager getPermissionsResolver ( ) {
return PermissionsResolverManager . getInstance ( ) ;
}
/ * *
2018-06-16 05:29:48 +00:00
* Used to wrap a Bukkit Player as a WorldEdit Player .
2014-04-03 03:03:52 +00:00
*
2014-07-29 18:04:04 +00:00
* @param player a player
* @return a wrapped player
2014-04-03 03:03:52 +00:00
* /
public BukkitPlayer wrapPlayer ( Player player ) {
2019-10-30 11:26:52 +00:00
BukkitPlayer wePlayer = getCachedPlayer ( player ) ;
if ( wePlayer = = null ) {
synchronized ( player ) {
wePlayer = getCachedPlayer ( player ) ;
if ( wePlayer = = null ) {
wePlayer = new BukkitPlayer ( this , player ) ;
player . setMetadata ( " WE " , new FixedMetadataValue ( this , wePlayer ) ) ;
return wePlayer ;
}
2019-10-23 04:23:52 +00:00
}
}
2019-10-30 11:26:52 +00:00
return wePlayer ;
2014-04-03 03:03:52 +00:00
}
2020-01-23 19:41:57 +00:00
public BukkitPlayer getCachedPlayer ( Player player ) {
2019-10-26 13:21:49 +00:00
List < MetadataValue > meta = player . getMetadata ( " WE " ) ;
2020-01-29 22:10:59 +00:00
if ( meta . isEmpty ( ) ) {
2019-10-26 13:21:49 +00:00
return null ;
}
return ( BukkitPlayer ) meta . get ( 0 ) . value ( ) ;
}
2014-06-28 00:55:39 +00:00
public Actor wrapCommandSender ( CommandSender sender ) {
2014-04-03 03:03:52 +00:00
if ( sender instanceof Player ) {
return wrapPlayer ( ( Player ) sender ) ;
2019-09-14 03:05:16 +00:00
} else if ( config . commandBlockSupport & & sender instanceof BlockCommandSender ) {
2019-08-06 15:28:12 +00:00
return new BukkitBlockCommandSender ( this , ( BlockCommandSender ) sender ) ;
2014-04-03 03:03:52 +00:00
}
2014-06-27 20:14:44 +00:00
return new BukkitCommandSender ( this , sender ) ;
2014-04-03 03:03:52 +00:00
}
2018-08-27 16:56:28 +00:00
public BukkitServerInterface getInternalPlatform ( ) {
2014-06-27 08:11:35 +00:00
return server ;
}
2014-04-03 03:03:52 +00:00
/ * *
* Get WorldEdit .
*
2014-07-29 18:04:04 +00:00
* @return an instance
2014-04-03 03:03:52 +00:00
* /
public WorldEdit getWorldEdit ( ) {
2014-07-14 19:10:38 +00:00
return WorldEdit . getInstance ( ) ;
2014-04-03 03:03:52 +00:00
}
2014-07-14 19:10:38 +00:00
/ * *
* Gets the instance of this plugin .
*
* @return an instance of the plugin
* @throws NullPointerException if the plugin hasn ' t been enabled
* /
2018-08-12 14:03:07 +00:00
public static WorldEditPlugin getInstance ( ) {
2014-07-14 19:10:38 +00:00
return checkNotNull ( INSTANCE ) ;
}
/ * *
* Get the Bukkit implementation adapter .
*
* @return the adapter
* /
@Nullable
2018-08-12 14:03:07 +00:00
public BukkitImplAdapter getBukkitImplAdapter ( ) {
2014-07-14 19:10:38 +00:00
return bukkitAdapter ;
}
2019-09-14 03:05:16 +00:00
private class WorldInitListener implements Listener {
private boolean loaded = false ;
@EventHandler ( priority = EventPriority . LOWEST )
public void onWorldInit ( @SuppressWarnings ( " unused " ) WorldInitEvent event ) {
if ( loaded ) return ;
loaded = true ;
setupWorldData ( ) ;
}
}
2019-07-06 00:46:48 +00:00
private class AsyncTabCompleteListener implements Listener {
AsyncTabCompleteListener ( ) {
}
@SuppressWarnings ( " UnnecessaryFullyQualifiedName " )
@EventHandler ( ignoreCancelled = true )
public void onAsyncTabComplete ( com . destroystokyo . paper . event . server . AsyncTabCompleteEvent event ) {
if ( ! event . isCommand ( ) ) return ;
String buffer = event . getBuffer ( ) ;
2019-08-26 04:45:03 +00:00
int firstSpace = buffer . indexOf ( ' ' ) ;
if ( firstSpace < 0 ) return ;
2020-02-07 01:26:04 +00:00
String label = buffer . substring ( 0 , firstSpace ) ;
2020-03-19 22:23:11 +00:00
// Strip leading slash, if present.
label = label . startsWith ( " / " ) ? label . substring ( 1 ) : label ;
2019-07-06 00:46:48 +00:00
final Optional < org . enginehub . piston . Command > command
= WorldEdit . getInstance ( ) . getPlatformManager ( ) . getPlatformCommandManager ( ) . getCommandManager ( ) . getCommand ( label ) ;
if ( ! command . isPresent ( ) ) return ;
2020-03-19 17:08:25 +00:00
CommandSuggestionEvent suggestEvent = new CommandSuggestionEvent ( wrapCommandSender ( event . getSender ( ) ) , buffer ) ;
2019-07-06 00:46:48 +00:00
getWorldEdit ( ) . getEventBus ( ) . post ( suggestEvent ) ;
2019-07-22 02:49:08 +00:00
2020-03-19 17:08:25 +00:00
event . setCompletions ( CommandUtil . fixSuggestions ( buffer , suggestEvent . getSuggestions ( ) ) ) ;
2019-07-22 02:49:08 +00:00
event . setHandled ( true ) ;
2019-07-06 00:46:48 +00:00
}
}
2014-04-03 03:03:52 +00:00
}