PlotSquared/src/main/java/com/plotsquared/sponge/util/SpongeUtil.java

469 lines
17 KiB
Java
Raw Normal View History

2015-07-30 16:25:16 +02:00
package com.plotsquared.sponge.util;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
2015-10-07 08:33:33 +02:00
import java.util.Optional;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.block.BlockState;
import org.spongepowered.api.block.BlockType;
import org.spongepowered.api.block.BlockTypes;
import org.spongepowered.api.block.tileentity.Sign;
import org.spongepowered.api.block.tileentity.TileEntity;
import org.spongepowered.api.data.manipulator.mutable.tileentity.SignData;
import org.spongepowered.api.data.value.mutable.ListValue;
2015-07-30 16:25:16 +02:00
import org.spongepowered.api.entity.Entity;
2015-10-07 08:33:33 +02:00
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.event.cause.Cause;
import org.spongepowered.api.text.Text;
import org.spongepowered.api.text.translation.Translatable;
import org.spongepowered.api.text.translation.Translation;
2015-07-30 16:25:16 +02:00
import org.spongepowered.api.world.World;
import org.spongepowered.api.world.biome.BiomeType;
import org.spongepowered.api.world.biome.BiomeTypes;
2015-07-30 16:25:16 +02:00
import org.spongepowered.api.world.extent.Extent;
import com.flowpowered.math.vector.Vector3d;
import com.flowpowered.math.vector.Vector3i;
import com.intellectualcrafters.plot.PS;
2015-07-30 16:25:16 +02:00
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.PlotBlock;
2015-07-30 16:25:16 +02:00
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.object.RegionWrapper;
import com.intellectualcrafters.plot.object.schematic.PlotItem;
2015-07-30 16:25:16 +02:00
import com.intellectualcrafters.plot.util.MathMan;
import com.intellectualcrafters.plot.util.ReflectionUtils;
import com.intellectualcrafters.plot.util.StringComparison;
import com.intellectualcrafters.plot.util.StringMan;
2015-07-30 16:25:16 +02:00
import com.intellectualcrafters.plot.util.UUIDHandler;
import com.intellectualcrafters.plot.util.WorldUtil;
2015-07-30 16:25:16 +02:00
import com.plotsquared.sponge.SpongeMain;
2015-07-30 19:24:01 +02:00
import com.plotsquared.sponge.object.SpongePlayer;
2015-07-30 16:25:16 +02:00
public class SpongeUtil extends WorldUtil {
2015-09-13 06:04:31 +02:00
public static Location getLocation(final Entity player) {
2015-09-11 12:09:22 +02:00
final String world = player.getWorld().getName();
final org.spongepowered.api.world.Location loc = player.getLocation();
final Vector3i pos = loc.getBlockPosition();
2015-07-30 16:25:16 +02:00
return new Location(world, pos.getX(), pos.getY(), pos.getZ());
}
2015-09-13 06:04:31 +02:00
private static BiomeType[] biomes;
private static HashMap<String, Integer> biomeMap;
public static BiomeType getBiome(String biome) {
if (biomes == null) {
initBiomeCache();
}
return biomes[biomeMap.get(biome.toUpperCase())];
}
public static <T> T getCause(Cause cause, Class<T> clazz) {
Optional<?> root = Optional.of(cause.root());
if (root.isPresent()) {
Object source = root.get();
if (clazz.isInstance(source)) {
return (T) source;
}
}
return null;
}
public static void printCause(String method, Cause cause) {
System.out.println(method + ": " + cause.toString());
System.out.println(method + ": " + cause.getClass());
System.out.println(method + ": " + StringMan.getString(cause.all()));
System.out.println(method + ": " + (cause.root()));
}
public static void initBiomeCache() {
try {
Field[] fields = BiomeTypes.class.getFields();
biomes = new BiomeType[fields.length];
biomeMap = new HashMap<>();
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
String name = field.getName();
biomeMap.put(name, i);
biomes[i] = (BiomeType) field.get(null);
}
} catch (IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
}
}
public static BiomeType getBiome(int index) {
if (biomes == null) {
initBiomeCache();
}
return biomes[index];
}
public static Text text(String m) {
return Text.of(m);
}
public static Translation getTranslation(final String m) {
return new Translatable() {
@Override
public Translation getTranslation() {
return new Translation() {
@Override
public String getId() {
return m;
}
@Override
public String get(final Locale l, final Object... args) {
return m;
}
@Override
public String get(final Locale l) {
return m;
}
};
}
}.getTranslation();
}
private static HashMap<BlockState, PlotBlock> stateMap;
private static BlockState[] stateArray;
private static void initBlockCache() {
try {
PS.debug("Caching block id/data: Please wait...");
stateArray = new BlockState[Character.MAX_VALUE];
stateMap = new HashMap<>();
Class<?> classBlock = Class.forName("net.minecraft.block.Block");
Class<?> classBlockState = Class.forName("net.minecraft.block.state.IBlockState");
Method[] blockMethods = classBlock.getDeclaredMethods();
Method methodGetByCombinedId = null;
for (Method method : blockMethods) {
Class<?> result = method.getReturnType();
Class<?>[] param = method.getParameterTypes();
int paramCount = param.length;
boolean isStatic = Modifier.isStatic(method.getModifiers());
if (methodGetByCombinedId == null) {
if (isStatic && result == classBlockState && paramCount == 1 && param[0] == int.class) {
methodGetByCombinedId = method;
continue;
}
}
}
for (int i = 0; i < Character.MAX_VALUE; i++) {
try {
BlockState state = (BlockState) methodGetByCombinedId.invoke(null, i);
if (state.getType() == BlockTypes.AIR) {
continue;
}
int id = i & 0xFFF;
int data = i >> 12 & 0xF;
PlotBlock plotBlock = new PlotBlock((short) id, (byte) data);
stateArray[i] = state;
stateMap.put(state, plotBlock);
} catch (Throwable e) {}
}
PS.debug("Done!");
} catch (Throwable e) {
e.printStackTrace();
}
}
public static BlockState getBlockState(int id, int data) {
if (stateArray == null) {
initBlockCache();
}
return stateArray[id + (data << 12)];
}
public static PlotBlock getPlotBlock(BlockState state) {
if (stateMap == null) {
initBlockCache();
}
return stateMap.get(state);
}
2015-10-07 08:33:33 +02:00
public static Location getLocation(final org.spongepowered.api.world.Location<World> block) {
return getLocation(block.getExtent().getName(), block);
2015-07-30 16:25:16 +02:00
}
2015-09-13 06:04:31 +02:00
public static Location getLocationFull(final Entity player) {
2015-09-11 12:09:22 +02:00
final String world = player.getWorld().getName();
final Vector3d rot = player.getRotation();
final float[] pitchYaw = MathMan.getPitchAndYaw((float) rot.getX(), (float) rot.getY(), (float) rot.getZ());
final org.spongepowered.api.world.Location loc = player.getLocation();
final Vector3i pos = loc.getBlockPosition();
2015-07-30 16:25:16 +02:00
return new Location(world, pos.getX(), pos.getY(), pos.getZ(), pitchYaw[1], pitchYaw[0]);
}
2015-09-13 06:04:31 +02:00
2015-07-30 16:25:16 +02:00
private static Player lastPlayer = null;
private static PlotPlayer lastPlotPlayer = null;
2015-09-13 06:04:31 +02:00
public static PlotPlayer getPlayer(final Player player) {
if (player == lastPlayer) {
return lastPlotPlayer;
}
2015-09-11 12:09:22 +02:00
final String name = player.getName();
2015-10-19 08:27:51 +02:00
final PlotPlayer pp = UUIDHandler.getPlayer(name);
2015-09-13 06:04:31 +02:00
if (pp != null) {
return pp;
}
2015-07-30 16:25:16 +02:00
lastPlotPlayer = new SpongePlayer(player);
UUIDHandler.getPlayers().put(name, lastPlotPlayer);
lastPlayer = player;
return lastPlotPlayer;
}
2015-09-13 06:04:31 +02:00
public static Player getPlayer(final PlotPlayer player) {
if (player instanceof SpongePlayer) {
return ((SpongePlayer) player).player;
}
2015-07-30 16:25:16 +02:00
return null;
}
2015-09-13 06:04:31 +02:00
2015-08-03 20:20:04 +02:00
private static World lastWorld;
private static String last;
2015-09-13 06:04:31 +02:00
public static World getWorld(final String world) {
if (world == last) {
return lastWorld;
}
final Optional<World> optional = Sponge.getServer().getWorld(world);
2015-09-13 06:04:31 +02:00
if (!optional.isPresent()) {
return null;
}
2015-07-30 16:25:16 +02:00
return optional.get();
}
2015-09-13 06:04:31 +02:00
public static void removePlayer(final String player) {
2015-07-30 16:25:16 +02:00
lastPlayer = null;
lastPlotPlayer = null;
}
2015-09-13 06:04:31 +02:00
public static Location getLocation(final String world, final org.spongepowered.api.world.Location spawn) {
2015-07-30 16:25:16 +02:00
return new Location(world, spawn.getBlockX(), spawn.getBlockY(), spawn.getBlockZ());
}
2015-09-13 06:04:31 +02:00
public static String getWorldName(final org.spongepowered.api.world.Location origin) {
2015-09-11 12:09:22 +02:00
final Extent extent = origin.getExtent();
2015-09-13 06:04:31 +02:00
if (extent == lastWorld) {
return last;
}
if (extent instanceof World) {
lastWorld = (World) extent;
last = ((World) extent).getName();
return last;
}
return null;
}
2015-09-13 06:04:31 +02:00
public static org.spongepowered.api.world.Location getLocation(final Location loc) {
2015-09-11 12:09:22 +02:00
final Optional<World> world = SpongeMain.THIS.getServer().getWorld(loc.getWorld());
2015-09-13 06:04:31 +02:00
if (!world.isPresent()) {
return null;
}
2015-08-14 00:52:31 +02:00
return new org.spongepowered.api.world.Location(world.get(), loc.getX(), loc.getY(), loc.getZ());
}
2015-10-07 08:33:33 +02:00
public static Location getLocation(String world, Vector3i position) {
return new Location(world, position.getX(), position.getY(), position.getZ());
}
public static Location getLocation(String world, Vector3d position) {
return new Location(world, MathMan.roundInt(position.getX()), MathMan.roundInt(position.getY()), MathMan.roundInt(position.getZ()));
}
@Override
public boolean isBlockSolid(final PlotBlock block) {
final BlockState state = SpongeUtil.getBlockState(block.id, block.data);
final BlockType type = state.getType();
// TODO check if solid;
return true;
}
@Override
public StringComparison<PlotBlock>.ComparisonResult getClosestBlock(String name) {
try {
double match;
short id;
byte data;
final String[] split = name.split(":");
if (split.length == 2) {
data = Byte.parseByte(split[1]);
name = split[0];
} else {
data = 0;
}
if (MathMan.isInteger(split[0])) {
id = Short.parseShort(split[0]);
match = 0;
} else {
List<BlockType> types = ReflectionUtils.<BlockType> getStaticFields(BlockTypes.class);
final StringComparison<BlockType>.ComparisonResult comparison = new StringComparison<BlockType>(name, types.toArray(new BlockType[types.size()])) {
@Override
public String getString(final BlockType type) {
return type.getId();
};
}.getBestMatchAdvanced();
match = comparison.match;
id = SpongeUtil.getPlotBlock(comparison.best.getDefaultState()).id;
}
final PlotBlock block = new PlotBlock(id, data);
final StringComparison<PlotBlock> outer = new StringComparison<PlotBlock>();
return outer.new ComparisonResult(match, block);
} catch (final Exception e) {}
return null;
}
@Override
public String getClosestMatchingName(final PlotBlock block) {
// TODO Auto-generated method stub
return null;
}
@Override
public String[] getBiomeList() {
if (biomes == null) {
initBiomeCache();
}
return biomeMap.keySet().toArray(new String[biomeMap.size()]);
}
@Override
public boolean addItems(final String world, final PlotItem items) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("NOT IMPLEMENTED YET");
}
@Override
public int getBiomeFromString(final String biome) {
if (biomes == null) {
initBiomeCache();
}
return biomeMap.get(biome.toUpperCase());
}
@Override
public String getBiome(final String world, final int x, final int z) {
return SpongeUtil.getWorld(world).getBiome(x, z).getName().toUpperCase();
}
@Override
public PlotBlock getBlock(final Location loc) {
final BlockState state = SpongeUtil.getWorld(loc.getWorld()).getBlock(loc.getX(), loc.getY(), loc.getZ());
return SpongeUtil.getPlotBlock(state);
}
@Override
public Location getSpawn(final String world) {
final World worldObj = SpongeUtil.getWorld(world);
worldObj.getSpawnLocation();
final Location result = SpongeUtil.getLocation(world, SpongeUtil.getWorld(world).getSpawnLocation());
result.setY(getHighestBlock(world, result.getX(), result.getZ()));
return result;
}
@Override
public String[] getSign(final Location loc) {
final World world = SpongeUtil.getWorld(loc.getWorld());
final Optional<TileEntity> block = world.getTileEntity(loc.getX(), loc.getY(), loc.getZ());
if (!block.isPresent()) {
return null;
}
final TileEntity tile = block.get();
if (!(tile instanceof Sign)) {
return null;
}
final Sign sign = (Sign) tile;
final Optional<SignData> optional = sign.getOrCreate(SignData.class);
if (!optional.isPresent()) {
return null;
}
final String[] result = new String[4];
ListValue<Text> lines = optional.get().lines();
for (int i = 0; i < 4; i++) {
result[i] = lines.get(i).toString();
}
return result;
}
@Override
public boolean isWorld(final String world) {
return SpongeUtil.getWorld(world) != null;
}
@Override
public String getMainWorld() {
return Sponge.getServer().getWorlds().iterator().next().getName();
}
@Override
public int getHighestBlock(String worldname, int x, int z) {
final World world = SpongeUtil.getWorld(worldname);
if (world == null) {
return 64;
}
for (int y = 255; y > 0; y--) {
final BlockState block = world.getBlock(x, y, z);
if ((block != null) && (block.getType() != BlockTypes.AIR)) {
return y + 1;
}
}
return 64;
}
@Override
public void setSign(String worldname, int x, int y, int z, String[] lines) {
final World world = SpongeUtil.getWorld(worldname);
world.setBlock(x, y, z, BlockTypes.WALL_SIGN.getDefaultState());
final Optional<TileEntity> block = world.getTileEntity(x, y, z);
if (!block.isPresent()) {
return;
}
final TileEntity tile = block.get();
if (!(tile instanceof Sign)) {
return;
}
final Sign sign = (Sign) tile;
final List<Text> text = new ArrayList<>(4);
for (int i = 0; i < 4; i++) {
text.add(Text.of(lines[i]));
}
try {
final Optional<SignData> optional = sign.getOrCreate(SignData.class);
if (optional.isPresent()) {
final SignData offering = optional.get();
offering.lines().set(0, Text.of(lines[0]));
offering.lines().set(1, Text.of(lines[1]));
offering.lines().set(2, Text.of(lines[2]));
offering.lines().set(3, Text.of(lines[3]));
sign.offer(offering);
}
} catch (final NullPointerException e) {
e.printStackTrace();
}
}
@Override
public void setBiomes(String worldname, RegionWrapper region, String biomename) {
final World world = SpongeUtil.getWorld(worldname);
final BiomeType biome = SpongeUtil.getBiome(biomename);
for (int x = region.minX; x <= region.maxX; x++) {
for (int z = region.minZ; z <= region.maxZ; z++) {
world.setBiome(x, z, biome);
}
}
}
2015-07-30 16:25:16 +02:00
}