mirror of
				https://e.coding.net/circlecloud/YumCore.git
				synced 2025-11-03 23:06:02 +00:00 
			
		
		
		
	
							
								
								
									
										423
									
								
								src/main/java/pw/yumc/YumCore/kit/EntityKit.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										423
									
								
								src/main/java/pw/yumc/YumCore/kit/EntityKit.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,423 @@
 | 
			
		||||
package pw.yumc.YumCore.kit;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Field;
 | 
			
		||||
import java.lang.reflect.Method;
 | 
			
		||||
import java.lang.reflect.Modifier;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.Location;
 | 
			
		||||
import org.bukkit.Material;
 | 
			
		||||
import org.bukkit.World;
 | 
			
		||||
import org.bukkit.entity.Entity;
 | 
			
		||||
import org.bukkit.entity.EntityType;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
import org.bukkit.util.Vector;
 | 
			
		||||
 | 
			
		||||
import com.comphenix.protocol.utility.MinecraftFields;
 | 
			
		||||
import com.comphenix.protocol.utility.MinecraftReflection;
 | 
			
		||||
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
 | 
			
		||||
 | 
			
		||||
import pw.yumc.YumCore.utils.ReflectUtil;
 | 
			
		||||
 | 
			
		||||
public class EntityKit {
 | 
			
		||||
 | 
			
		||||
    private static Method _mGetNavigation;
 | 
			
		||||
    private static Method _mA3 = null;
 | 
			
		||||
    private static Method _mA2 = null;
 | 
			
		||||
    private static Method _mA1 = null;
 | 
			
		||||
 | 
			
		||||
    private static Field _fgoalSelector;
 | 
			
		||||
    private static Field _ftargetSelector;
 | 
			
		||||
 | 
			
		||||
    private final static Class<?> _cControllerMove = MinecraftReflection.getMinecraftClass("ControllerMove");
 | 
			
		||||
    private final static Class<?> _cPathEntity = MinecraftReflection.getMinecraftClass("PathEntity");
 | 
			
		||||
    private final static Class<?> _cEntityInsentient = MinecraftReflection.getMinecraftClass("EntityInsentient");
 | 
			
		||||
    private final static Class<?> _cPathfinderGoalSelector = MinecraftReflection.getMinecraftClass("PathfinderGoalSelector");
 | 
			
		||||
 | 
			
		||||
    private static Method _mPlayerList_MoveToWorld = null;
 | 
			
		||||
    private static Method _mPlayerConnection_Teleport = null;
 | 
			
		||||
    private static Field _fWorldServer_dimension = null;
 | 
			
		||||
 | 
			
		||||
    static {
 | 
			
		||||
        try {
 | 
			
		||||
            _mGetNavigation = _cEntityInsentient.getMethod("getNavigation");
 | 
			
		||||
            _fgoalSelector = _cEntityInsentient.getDeclaredField("goalSelector");
 | 
			
		||||
            _fgoalSelector.setAccessible(true);
 | 
			
		||||
            _ftargetSelector = _cEntityInsentient.getDeclaredField("targetSelector");
 | 
			
		||||
            _ftargetSelector.setAccessible(true);
 | 
			
		||||
 | 
			
		||||
            ReflectUtil.getMethodByNameAndParams(_cEntityInsentient, "getControllerMove");
 | 
			
		||||
            ReflectUtil.getDeclaredMethodByParams(_cControllerMove, double.class, double.class, double.class, double.class).get(0);
 | 
			
		||||
 | 
			
		||||
            final Class<?> cc = MinecraftReflection.getMinecraftClass("NavigationAbstract");
 | 
			
		||||
            for (final Method method : cc.getDeclaredMethods()) {
 | 
			
		||||
                final Class<?>[] parmeters = method.getParameterTypes();
 | 
			
		||||
                switch (parmeters.length) {
 | 
			
		||||
                case 1: {
 | 
			
		||||
                    if (parmeters[0] == double.class) {
 | 
			
		||||
                        _mA1 = method;
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                case 2: {
 | 
			
		||||
                    if (parmeters[0] == _cPathEntity.getClass() && parmeters[1] == double.class) {
 | 
			
		||||
                        _mA2 = method;
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                case 3: {
 | 
			
		||||
                    if (parmeters[0] == double.class && parmeters[1] == double.class && parmeters[2] == double.class) {
 | 
			
		||||
                        _mA3 = method;
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } catch (final Exception ex) {
 | 
			
		||||
            ex.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
        try {
 | 
			
		||||
            _mPlayerList_MoveToWorld = ReflectUtil
 | 
			
		||||
                    .getDeclaredMethodByParamsAndType(MinecraftReflection.getPlayerListClass(),
 | 
			
		||||
                            MinecraftReflection.getEntityPlayerClass(),
 | 
			
		||||
                            MinecraftReflection.getEntityPlayerClass(),
 | 
			
		||||
                            Integer.TYPE,
 | 
			
		||||
                            Boolean.TYPE,
 | 
			
		||||
                            Location.class,
 | 
			
		||||
                            Boolean.TYPE)
 | 
			
		||||
                    .get(0);
 | 
			
		||||
        } catch (final Exception ex) {
 | 
			
		||||
            ex.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 通过ID获取实体
 | 
			
		||||
     *
 | 
			
		||||
     * @param entityId
 | 
			
		||||
     *            实体ID
 | 
			
		||||
     * @return 实体
 | 
			
		||||
     */
 | 
			
		||||
    public static Entity getEntityById(final int entityId) {
 | 
			
		||||
        for (final World world : Bukkit.getWorlds()) {
 | 
			
		||||
            for (final Entity entity : world.getEntities()) {
 | 
			
		||||
                if (entity.getEntityId() == entityId) {
 | 
			
		||||
                    return entity;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 判断实体是否在水里
 | 
			
		||||
     *
 | 
			
		||||
     * @param ent
 | 
			
		||||
     *            实体
 | 
			
		||||
     * @return 结果
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean inWater(final Entity ent) {
 | 
			
		||||
        return ent.getLocation().getBlock().getTypeId() == 8 || ent.getLocation().getBlock().getTypeId() == 9;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 判断实体是否隐藏
 | 
			
		||||
     *
 | 
			
		||||
     * @param entity
 | 
			
		||||
     *            实体
 | 
			
		||||
     * @return 是否隐藏
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean isInvisible(final Entity entity) {
 | 
			
		||||
        final Object ent = ReflectUtil.getHandle(entity);
 | 
			
		||||
        try {
 | 
			
		||||
            return (boolean) ent.getClass().getMethod("isInvisible").invoke(ent);
 | 
			
		||||
        } catch (final Exception e) {
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 实体是否在地上
 | 
			
		||||
     *
 | 
			
		||||
     * @param ent
 | 
			
		||||
     *            实体
 | 
			
		||||
     * @return 结果
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean isOnGround(final Entity ent) {
 | 
			
		||||
        return ent.isOnGround();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 判断是否为禁摩状态
 | 
			
		||||
     *
 | 
			
		||||
     * @param entity
 | 
			
		||||
     *            实体
 | 
			
		||||
     * @return 结果
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean isSilence(final Entity entity) {
 | 
			
		||||
        return WrappedDataWatcher.getEntityWatcher(entity).getByte(4) == 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 判断实体是否在方块上
 | 
			
		||||
     *
 | 
			
		||||
     * @param entity
 | 
			
		||||
     *            实体
 | 
			
		||||
     * @return 结果
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean onBlock(final Entity entity) {
 | 
			
		||||
        // Side Standing
 | 
			
		||||
        double xMod = entity.getLocation().getX() % 1;
 | 
			
		||||
        if (entity.getLocation().getX() < 0) {
 | 
			
		||||
            xMod += 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        double zMod = entity.getLocation().getZ() % 1;
 | 
			
		||||
        if (entity.getLocation().getZ() < 0) {
 | 
			
		||||
            zMod += 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        int xMin = 0;
 | 
			
		||||
        int xMax = 0;
 | 
			
		||||
        int zMin = 0;
 | 
			
		||||
        int zMax = 0;
 | 
			
		||||
 | 
			
		||||
        if (xMod < 0.3) {
 | 
			
		||||
            xMin = -1;
 | 
			
		||||
        }
 | 
			
		||||
        if (xMod > 0.7) {
 | 
			
		||||
            xMax = 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (zMod < 0.3) {
 | 
			
		||||
            zMin = -1;
 | 
			
		||||
        }
 | 
			
		||||
        if (zMod > 0.7) {
 | 
			
		||||
            zMax = 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (int x = xMin; x <= xMax; x++) {
 | 
			
		||||
            for (int z = zMin; z <= zMax; z++) {
 | 
			
		||||
                // Standing on SOMETHING
 | 
			
		||||
                if (entity.getLocation().add(x, -0.5, z).getBlock().getType() != Material.AIR && !entity.getLocation().add(x, -0.5, z).getBlock().isLiquid()) {
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Inside a Lillypad
 | 
			
		||||
                if (entity.getLocation().add(x, 0, z).getBlock().getType() == Material.WATER_LILY) {
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Fences/Walls
 | 
			
		||||
                final Material beneath = entity.getLocation().add(x, -1.5, z).getBlock().getType();
 | 
			
		||||
                if (entity.getLocation().getY() % 0.5 == 0 && (beneath == Material.FENCE || beneath == Material.FENCE_GATE || beneath == Material.NETHER_FENCE || beneath == Material.COBBLE_WALL)) {
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 解析实体类型
 | 
			
		||||
     *
 | 
			
		||||
     * @param str
 | 
			
		||||
     *            实体名称
 | 
			
		||||
     * @return {@link EntityType}
 | 
			
		||||
     */
 | 
			
		||||
    public static EntityType parseEntityType(final String str) {
 | 
			
		||||
        EntityType type = null;
 | 
			
		||||
        if (str != null) {
 | 
			
		||||
            type = EntityType.fromName(str);
 | 
			
		||||
            if (type == null) {
 | 
			
		||||
                try {
 | 
			
		||||
                    type = EntityType.valueOf(str.toUpperCase());
 | 
			
		||||
                } catch (final Exception e) {
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return type;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 移除全局选择器
 | 
			
		||||
     *
 | 
			
		||||
     * @param entity
 | 
			
		||||
     *            实体
 | 
			
		||||
     */
 | 
			
		||||
    public static void removeGoalSelectors(final Entity entity) {
 | 
			
		||||
        try {
 | 
			
		||||
            if (_fgoalSelector == null) {
 | 
			
		||||
                _fgoalSelector = _cEntityInsentient.getDeclaredField("goalSelector");
 | 
			
		||||
                _fgoalSelector.setAccessible(true);
 | 
			
		||||
            }
 | 
			
		||||
            final Object creature = ReflectUtil.getHandle(entity);
 | 
			
		||||
            if (_cEntityInsentient.isInstance(creature)) {
 | 
			
		||||
                final Object world = ReflectUtil.getHandle(entity.getWorld());
 | 
			
		||||
                final Object methodProfiler = world.getClass().getField("methodProfiler").get(world);
 | 
			
		||||
                final Object goalSelector = _cPathfinderGoalSelector.getConstructor(methodProfiler.getClass()).newInstance(methodProfiler);
 | 
			
		||||
                _fgoalSelector.set(creature, goalSelector);
 | 
			
		||||
            }
 | 
			
		||||
        } catch (final Exception e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 隐藏实体
 | 
			
		||||
     *
 | 
			
		||||
     * @param entity
 | 
			
		||||
     *            实体
 | 
			
		||||
     * @param invisible
 | 
			
		||||
     *            是否隐藏
 | 
			
		||||
     */
 | 
			
		||||
    public static void setInvisible(final Entity entity, final boolean invisible) {
 | 
			
		||||
        final Object ent = ReflectUtil.getHandle(entity);
 | 
			
		||||
        try {
 | 
			
		||||
            ent.getClass().getMethod("setInvisible", boolean.class).invoke(ent, invisible);
 | 
			
		||||
        } catch (final Exception e) {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 设置实体为静默状态
 | 
			
		||||
     *
 | 
			
		||||
     * @param entity
 | 
			
		||||
     *            实体
 | 
			
		||||
     * @param silence
 | 
			
		||||
     *            是否静默
 | 
			
		||||
     */
 | 
			
		||||
    public static void setSilence(final Entity entity, final boolean silence) {
 | 
			
		||||
        final byte value = (byte) (silence ? 1 : 0);
 | 
			
		||||
        final WrappedDataWatcher watcher = WrappedDataWatcher.getEntityWatcher(entity);
 | 
			
		||||
        watcher.setObject(4, value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 静默传送, 不触发事件
 | 
			
		||||
     *
 | 
			
		||||
     * @param entity
 | 
			
		||||
     * @param to
 | 
			
		||||
     */
 | 
			
		||||
    public static void teleportQuietly(final Entity entity, final Location to) {
 | 
			
		||||
        if (!(entity instanceof Player)) {
 | 
			
		||||
            entity.teleport(to);
 | 
			
		||||
        } else {
 | 
			
		||||
            if (entity.getWorld().equals(to.getWorld())) {
 | 
			
		||||
                final Object playerConnection = MinecraftFields.getPlayerConnection((Player) entity);
 | 
			
		||||
                if (_mPlayerConnection_Teleport == null) {
 | 
			
		||||
                    _mPlayerConnection_Teleport = ReflectUtil.getMethodByNameAndParams(playerConnection.getClass(), "teleport", Location.class);
 | 
			
		||||
                }
 | 
			
		||||
                try {
 | 
			
		||||
                    _mPlayerConnection_Teleport.invoke(playerConnection, to);
 | 
			
		||||
                } catch (final Exception ex) {
 | 
			
		||||
                    ex.printStackTrace();
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                final Object toWorldServer = ReflectUtil.getHandle(to.getWorld());
 | 
			
		||||
                final Object server = ReflectUtil.getHandle(Bukkit.getServer());
 | 
			
		||||
                if (_fWorldServer_dimension == null) {
 | 
			
		||||
                    for (final Field field : ReflectUtil.getFieldByType(toWorldServer.getClass(), Integer.TYPE)) {
 | 
			
		||||
                        final int modifier = field.getModifiers();
 | 
			
		||||
                        if (Modifier.isFinal(modifier) && Modifier.isPublic(modifier)) {
 | 
			
		||||
                            _fWorldServer_dimension = field;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                try {
 | 
			
		||||
                    _mPlayerList_MoveToWorld.invoke(server, ReflectUtil.getHandle(entity), (int) _fWorldServer_dimension.get(toWorldServer), true, to, true);
 | 
			
		||||
                } catch (final Exception e) {
 | 
			
		||||
                    e.printStackTrace();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 让实体升高/降低
 | 
			
		||||
     *
 | 
			
		||||
     * @param ent
 | 
			
		||||
     * @param speed
 | 
			
		||||
     *            速度
 | 
			
		||||
     * @param yAdd
 | 
			
		||||
     *            Y轴加减
 | 
			
		||||
     * @param yMax
 | 
			
		||||
     *            Y轴最大值
 | 
			
		||||
     * @param groundBoost
 | 
			
		||||
     *            当实体在地上的时候,会稍微抬起一些
 | 
			
		||||
     */
 | 
			
		||||
    public static void velocity(final Entity ent, final double speed, final double yAdd, final double yMax, final boolean groundBoost) {
 | 
			
		||||
        velocity(ent, ent.getLocation().getDirection(), speed, false, 0.0D, yAdd, yMax, groundBoost);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 让实体升高/降低
 | 
			
		||||
     *
 | 
			
		||||
     * @param ent
 | 
			
		||||
     * @param vec
 | 
			
		||||
     *            坐标
 | 
			
		||||
     * @param speed
 | 
			
		||||
     *            速度
 | 
			
		||||
     * @param ySet
 | 
			
		||||
     *            是否设置Y轴初始值
 | 
			
		||||
     * @param yBase
 | 
			
		||||
     *            Y轴初始值
 | 
			
		||||
     * @param yAdd
 | 
			
		||||
     *            Y轴加减
 | 
			
		||||
     * @param yMax
 | 
			
		||||
     *            Y轴最大值
 | 
			
		||||
     * @param groundBoost
 | 
			
		||||
     *            当实体在地上的时候,会稍微抬起一些
 | 
			
		||||
     */
 | 
			
		||||
    public static void velocity(final Entity ent, final Vector vec, final double speed, final boolean ySet, final double yBase, final double yAdd, final double yMax, final boolean groundBoost) {
 | 
			
		||||
        if ((Double.isNaN(vec.getX())) || (Double.isNaN(vec.getY())) || (Double.isNaN(vec.getZ())) || (vec.length() == 0.0D)) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (ySet) {
 | 
			
		||||
            vec.setY(yBase);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        vec.normalize();
 | 
			
		||||
        vec.multiply(speed);
 | 
			
		||||
 | 
			
		||||
        vec.setY(vec.getY() + yAdd);
 | 
			
		||||
 | 
			
		||||
        if (vec.getY() > yMax) {
 | 
			
		||||
            vec.setY(yMax);
 | 
			
		||||
        }
 | 
			
		||||
        if ((groundBoost) && (ent.isOnGround())) {
 | 
			
		||||
            vec.setY(vec.getY() + 0.2D);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ent.setFallDistance(0.0F);
 | 
			
		||||
        ent.setVelocity(vec);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void walkTo(final Entity entity, final Location location) {
 | 
			
		||||
        if (entity == null || location == null) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        final Object nmsEntityEntity = ReflectUtil.getHandle(entity);
 | 
			
		||||
        if (!_cEntityInsentient.isInstance(nmsEntityEntity)) {
 | 
			
		||||
            entity.teleport(location);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        try {
 | 
			
		||||
            final Object oFollowerNavigation = _mGetNavigation.invoke(nmsEntityEntity);
 | 
			
		||||
 | 
			
		||||
            final Object path = _mA3.invoke(oFollowerNavigation, location.getX(), location.getY(), location.getZ());
 | 
			
		||||
            if (path != null) {
 | 
			
		||||
                _mA2.invoke(oFollowerNavigation, path, 1D);
 | 
			
		||||
                _mA1.invoke(oFollowerNavigation, 2D);
 | 
			
		||||
            }
 | 
			
		||||
            if (location.distance(entity.getLocation()) > 20) {
 | 
			
		||||
                entity.teleport(location);
 | 
			
		||||
            }
 | 
			
		||||
        } catch (final Exception e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										149
									
								
								src/main/java/pw/yumc/YumCore/kit/HashKit.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								src/main/java/pw/yumc/YumCore/kit/HashKit.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,149 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package pw.yumc.YumCore.kit;
 | 
			
		||||
 | 
			
		||||
import java.security.MessageDigest;
 | 
			
		||||
 | 
			
		||||
public class HashKit {
 | 
			
		||||
 | 
			
		||||
    private static java.security.SecureRandom random = new java.security.SecureRandom();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 生成种子
 | 
			
		||||
     * <p>
 | 
			
		||||
     * md5 128bit 16bytes
 | 
			
		||||
     * <p>
 | 
			
		||||
     * sha1 160bit 20bytes
 | 
			
		||||
     * <p>
 | 
			
		||||
     * sha256 256bit 32bytes
 | 
			
		||||
     * <p>
 | 
			
		||||
     * sha384 384bit 48bites
 | 
			
		||||
     * <p>
 | 
			
		||||
     * sha512 512bit 64bites
 | 
			
		||||
     * <p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param numberOfBytes
 | 
			
		||||
     *            数字比特
 | 
			
		||||
     * @return 种子字串
 | 
			
		||||
     */
 | 
			
		||||
    public static String generateSalt(final int numberOfBytes) {
 | 
			
		||||
        final byte[] salt = new byte[numberOfBytes];
 | 
			
		||||
        random.nextBytes(salt);
 | 
			
		||||
        return toHex(salt);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 字符串加密
 | 
			
		||||
     *
 | 
			
		||||
     * @param algorithm
 | 
			
		||||
     *            算法
 | 
			
		||||
     * @param srcStr
 | 
			
		||||
     *            字符串
 | 
			
		||||
     * @return 加密后的字符串
 | 
			
		||||
     */
 | 
			
		||||
    public static String hash(final String algorithm, final String srcStr) {
 | 
			
		||||
        try {
 | 
			
		||||
            final StringBuilder result = new StringBuilder();
 | 
			
		||||
            final MessageDigest md = MessageDigest.getInstance(algorithm);
 | 
			
		||||
            final byte[] bytes = md.digest(srcStr.getBytes("utf-8"));
 | 
			
		||||
            for (final byte b : bytes) {
 | 
			
		||||
                final String hex = Integer.toHexString(b & 0xFF);
 | 
			
		||||
                if (hex.length() == 1) {
 | 
			
		||||
                    result.append("0");
 | 
			
		||||
                }
 | 
			
		||||
                result.append(hex);
 | 
			
		||||
            }
 | 
			
		||||
            return result.toString();
 | 
			
		||||
        } catch (final Exception e) {
 | 
			
		||||
            throw new RuntimeException(e);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * MD5加密
 | 
			
		||||
     *
 | 
			
		||||
     * @param srcStr
 | 
			
		||||
     *            字符串
 | 
			
		||||
     * @return 加密后的字符串
 | 
			
		||||
     */
 | 
			
		||||
    public static String md5(final String srcStr) {
 | 
			
		||||
        return hash("MD5", srcStr);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * sha1加密
 | 
			
		||||
     *
 | 
			
		||||
     * @param srcStr
 | 
			
		||||
     *            字符串
 | 
			
		||||
     * @return 加密后的字符串
 | 
			
		||||
     */
 | 
			
		||||
    public static String sha1(final String srcStr) {
 | 
			
		||||
        return hash("SHA-1", srcStr);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * sha256加密
 | 
			
		||||
     *
 | 
			
		||||
     * @param srcStr
 | 
			
		||||
     *            字符串
 | 
			
		||||
     * @return 加密后的字符串
 | 
			
		||||
     */
 | 
			
		||||
    public static String sha256(final String srcStr) {
 | 
			
		||||
        return hash("SHA-256", srcStr);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * sha384加密
 | 
			
		||||
     *
 | 
			
		||||
     * @param srcStr
 | 
			
		||||
     *            字符串
 | 
			
		||||
     * @return 加密后的字符串
 | 
			
		||||
     */
 | 
			
		||||
    public static String sha384(final String srcStr) {
 | 
			
		||||
        return hash("SHA-384", srcStr);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * sha512加密
 | 
			
		||||
     *
 | 
			
		||||
     * @param srcStr
 | 
			
		||||
     *            字符串
 | 
			
		||||
     * @return 加密后的字符串
 | 
			
		||||
     */
 | 
			
		||||
    public static String sha512(final String srcStr) {
 | 
			
		||||
        return hash("SHA-512", srcStr);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Byte转字符串
 | 
			
		||||
     *
 | 
			
		||||
     * @param bytes
 | 
			
		||||
     *            Byte数组
 | 
			
		||||
     * @return 字符串
 | 
			
		||||
     */
 | 
			
		||||
    private static String toHex(final byte[] bytes) {
 | 
			
		||||
        final StringBuilder result = new StringBuilder();
 | 
			
		||||
        for (final byte b : bytes) {
 | 
			
		||||
            final String hex = Integer.toHexString(b & 0xFF);
 | 
			
		||||
            if (hex.length() == 1) {
 | 
			
		||||
                result.append("0");
 | 
			
		||||
            }
 | 
			
		||||
            result.append(hex);
 | 
			
		||||
        }
 | 
			
		||||
        return result.toString();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										354
									
								
								src/main/java/pw/yumc/YumCore/kit/HttpKit.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										354
									
								
								src/main/java/pw/yumc/YumCore/kit/HttpKit.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,354 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package pw.yumc.YumCore.kit;
 | 
			
		||||
 | 
			
		||||
import java.io.BufferedReader;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.io.InputStreamReader;
 | 
			
		||||
import java.io.OutputStream;
 | 
			
		||||
import java.io.UnsupportedEncodingException;
 | 
			
		||||
import java.net.HttpURLConnection;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
import java.net.URLEncoder;
 | 
			
		||||
import java.security.KeyManagementException;
 | 
			
		||||
import java.security.NoSuchAlgorithmException;
 | 
			
		||||
import java.security.NoSuchProviderException;
 | 
			
		||||
import java.security.cert.CertificateException;
 | 
			
		||||
import java.security.cert.X509Certificate;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Map.Entry;
 | 
			
		||||
 | 
			
		||||
import javax.net.ssl.HostnameVerifier;
 | 
			
		||||
import javax.net.ssl.HttpsURLConnection;
 | 
			
		||||
import javax.net.ssl.SSLContext;
 | 
			
		||||
import javax.net.ssl.SSLSession;
 | 
			
		||||
import javax.net.ssl.SSLSocketFactory;
 | 
			
		||||
import javax.net.ssl.TrustManager;
 | 
			
		||||
import javax.net.ssl.X509TrustManager;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * HttpKit
 | 
			
		||||
 */
 | 
			
		||||
public class HttpKit {
 | 
			
		||||
 | 
			
		||||
    private static final String GET = "GET";
 | 
			
		||||
 | 
			
		||||
    private static final String POST = "POST";
 | 
			
		||||
 | 
			
		||||
    private static final String CHARSET = "UTF-8";
 | 
			
		||||
 | 
			
		||||
    private static final SSLSocketFactory sslSocketFactory = initSSLSocketFactory();
 | 
			
		||||
    private static final TrustAnyHostnameVerifier trustAnyHostnameVerifier = new HttpKit.TrustAnyHostnameVerifier();
 | 
			
		||||
 | 
			
		||||
    private HttpKit() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get 方法获取HTML
 | 
			
		||||
     *
 | 
			
		||||
     * @param url
 | 
			
		||||
     *            网址
 | 
			
		||||
     * @return 网页HTML
 | 
			
		||||
     */
 | 
			
		||||
    public static String get(final String url) {
 | 
			
		||||
        return get(url, null, null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get 方法获取HTML
 | 
			
		||||
     *
 | 
			
		||||
     * @param url
 | 
			
		||||
     *            网址
 | 
			
		||||
     * @param queryParas
 | 
			
		||||
     *            查询参数
 | 
			
		||||
     * @return 网页HTML
 | 
			
		||||
     */
 | 
			
		||||
    public static String get(final String url, final Map<String, String> queryParas) {
 | 
			
		||||
        return get(url, queryParas, null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get 方法获取HTML
 | 
			
		||||
     *
 | 
			
		||||
     * @param url
 | 
			
		||||
     *            网址
 | 
			
		||||
     * @param queryParas
 | 
			
		||||
     *            查询参数
 | 
			
		||||
     * @param headers
 | 
			
		||||
     *            头信息
 | 
			
		||||
     * @return 网页HTML
 | 
			
		||||
     */
 | 
			
		||||
    public static String get(final String url, final Map<String, String> queryParas, final Map<String, String> headers) {
 | 
			
		||||
        HttpURLConnection conn = null;
 | 
			
		||||
        try {
 | 
			
		||||
            conn = getHttpConnection(buildUrlWithQueryString(url, queryParas), GET, headers);
 | 
			
		||||
            conn.connect();
 | 
			
		||||
            return readResponseString(conn);
 | 
			
		||||
        } catch (final Exception e) {
 | 
			
		||||
            throw new RuntimeException(e);
 | 
			
		||||
        } finally {
 | 
			
		||||
            if (conn != null) {
 | 
			
		||||
                conn.disconnect();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Post 获取网页
 | 
			
		||||
     *
 | 
			
		||||
     * @param url
 | 
			
		||||
     *            网址
 | 
			
		||||
     * @param queryParas
 | 
			
		||||
     *            参数
 | 
			
		||||
     * @param data
 | 
			
		||||
     *            数据
 | 
			
		||||
     * @return 网页HTML
 | 
			
		||||
     */
 | 
			
		||||
    public static String post(final String url, final Map<String, String> queryParas, final String data) {
 | 
			
		||||
        return post(url, queryParas, data, null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Post 获取网页
 | 
			
		||||
     *
 | 
			
		||||
     * @param url
 | 
			
		||||
     *            网址
 | 
			
		||||
     * @param queryParas
 | 
			
		||||
     *            参数
 | 
			
		||||
     * @param data
 | 
			
		||||
     *            数据
 | 
			
		||||
     * @param headers
 | 
			
		||||
     *            头信息
 | 
			
		||||
     * @return 网页HTML
 | 
			
		||||
     */
 | 
			
		||||
    public static String post(final String url, final Map<String, String> queryParas, final String data, final Map<String, String> headers) {
 | 
			
		||||
        HttpURLConnection conn = null;
 | 
			
		||||
        try {
 | 
			
		||||
            conn = getHttpConnection(buildUrlWithQueryString(url, queryParas), POST, headers);
 | 
			
		||||
            conn.connect();
 | 
			
		||||
 | 
			
		||||
            final OutputStream out = conn.getOutputStream();
 | 
			
		||||
            out.write(data.getBytes(CHARSET));
 | 
			
		||||
            out.flush();
 | 
			
		||||
            out.close();
 | 
			
		||||
 | 
			
		||||
            return readResponseString(conn);
 | 
			
		||||
        } catch (final Exception e) {
 | 
			
		||||
            throw new RuntimeException(e);
 | 
			
		||||
        } finally {
 | 
			
		||||
            if (conn != null) {
 | 
			
		||||
                conn.disconnect();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get 方法获取HTML
 | 
			
		||||
     *
 | 
			
		||||
     * @param url
 | 
			
		||||
     *            网址
 | 
			
		||||
     * @param data
 | 
			
		||||
     *            查询参数
 | 
			
		||||
     * @return 网页HTML
 | 
			
		||||
     */
 | 
			
		||||
    public static String post(final String url, final String data) {
 | 
			
		||||
        return post(url, null, data, null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get 方法获取HTML
 | 
			
		||||
     *
 | 
			
		||||
     * @param url
 | 
			
		||||
     *            网址
 | 
			
		||||
     * @param data
 | 
			
		||||
     *            查询参数
 | 
			
		||||
     * @param headers
 | 
			
		||||
     *            头信息
 | 
			
		||||
     * @return 网页HTML
 | 
			
		||||
     */
 | 
			
		||||
    public static String post(final String url, final String data, final Map<String, String> headers) {
 | 
			
		||||
        return post(url, null, data, headers);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 构建查询串为字符串
 | 
			
		||||
     *
 | 
			
		||||
     * @param url
 | 
			
		||||
     *            网址
 | 
			
		||||
     * @param queryParas
 | 
			
		||||
     *            参数
 | 
			
		||||
     * @return 构建后的地址
 | 
			
		||||
     */
 | 
			
		||||
    private static String buildUrlWithQueryString(final String url, final Map<String, String> queryParas) {
 | 
			
		||||
        if (queryParas == null || queryParas.isEmpty()) {
 | 
			
		||||
            return url;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        final StringBuilder sb = new StringBuilder(url);
 | 
			
		||||
        boolean isFirst;
 | 
			
		||||
        if (url.indexOf("?") == -1) {
 | 
			
		||||
            isFirst = true;
 | 
			
		||||
            sb.append("?");
 | 
			
		||||
        } else {
 | 
			
		||||
            isFirst = false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (final Entry<String, String> entry : queryParas.entrySet()) {
 | 
			
		||||
            if (isFirst) {
 | 
			
		||||
                isFirst = false;
 | 
			
		||||
            } else {
 | 
			
		||||
                sb.append("&");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            final String key = entry.getKey();
 | 
			
		||||
            String value = entry.getValue();
 | 
			
		||||
            if (StrKit.notBlank(value)) {
 | 
			
		||||
                try {
 | 
			
		||||
                    value = URLEncoder.encode(value, CHARSET);
 | 
			
		||||
                } catch (final UnsupportedEncodingException e) {
 | 
			
		||||
                    throw new RuntimeException(e);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            sb.append(key).append("=").append(value);
 | 
			
		||||
        }
 | 
			
		||||
        return sb.toString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获得HTTP链接
 | 
			
		||||
     *
 | 
			
		||||
     * @param url
 | 
			
		||||
     *            地址
 | 
			
		||||
     * @param method
 | 
			
		||||
     *            方法
 | 
			
		||||
     * @param headers
 | 
			
		||||
     *            头信息
 | 
			
		||||
     * @return HTTP链接
 | 
			
		||||
     * @throws IOException
 | 
			
		||||
     * @throws NoSuchAlgorithmException
 | 
			
		||||
     * @throws NoSuchProviderException
 | 
			
		||||
     * @throws KeyManagementException
 | 
			
		||||
     */
 | 
			
		||||
    private static HttpURLConnection getHttpConnection(final String url, final String method, final Map<String, String> headers) throws IOException, NoSuchAlgorithmException, NoSuchProviderException, KeyManagementException {
 | 
			
		||||
        final URL _url = new URL(url);
 | 
			
		||||
        final HttpURLConnection conn = (HttpURLConnection) _url.openConnection();
 | 
			
		||||
        if (conn instanceof HttpsURLConnection) {
 | 
			
		||||
            ((HttpsURLConnection) conn).setSSLSocketFactory(sslSocketFactory);
 | 
			
		||||
            ((HttpsURLConnection) conn).setHostnameVerifier(trustAnyHostnameVerifier);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        conn.setRequestMethod(method);
 | 
			
		||||
        conn.setDoOutput(true);
 | 
			
		||||
        conn.setDoInput(true);
 | 
			
		||||
 | 
			
		||||
        conn.setConnectTimeout(19000);
 | 
			
		||||
        conn.setReadTimeout(19000);
 | 
			
		||||
 | 
			
		||||
        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
 | 
			
		||||
        conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36");
 | 
			
		||||
 | 
			
		||||
        if (headers != null && !headers.isEmpty()) {
 | 
			
		||||
            for (final Entry<String, String> entry : headers.entrySet()) {
 | 
			
		||||
                conn.setRequestProperty(entry.getKey(), entry.getValue());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return conn;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获得SSL安全套接字
 | 
			
		||||
     *
 | 
			
		||||
     * @return 安全套接字工厂
 | 
			
		||||
     */
 | 
			
		||||
    private static SSLSocketFactory initSSLSocketFactory() {
 | 
			
		||||
        try {
 | 
			
		||||
            final TrustManager[] tm = { new HttpKit.TrustAnyTrustManager() };
 | 
			
		||||
            final SSLContext sslContext = SSLContext.getInstance("TLS", "SunJSSE");
 | 
			
		||||
            sslContext.init(null, tm, new java.security.SecureRandom());
 | 
			
		||||
            return sslContext.getSocketFactory();
 | 
			
		||||
        } catch (final Exception e) {
 | 
			
		||||
            throw new RuntimeException(e);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 从连接读取HTML
 | 
			
		||||
     *
 | 
			
		||||
     * @param conn
 | 
			
		||||
     *            HTTP连接
 | 
			
		||||
     * @return 字符串
 | 
			
		||||
     */
 | 
			
		||||
    private static String readResponseString(final HttpURLConnection conn) {
 | 
			
		||||
        final StringBuilder sb = new StringBuilder();
 | 
			
		||||
        InputStream inputStream = null;
 | 
			
		||||
        try {
 | 
			
		||||
            inputStream = conn.getInputStream();
 | 
			
		||||
            final BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, CHARSET));
 | 
			
		||||
            String line = null;
 | 
			
		||||
            while ((line = reader.readLine()) != null) {
 | 
			
		||||
                sb.append(line).append("\n");
 | 
			
		||||
            }
 | 
			
		||||
            return sb.toString();
 | 
			
		||||
        } catch (final Exception e) {
 | 
			
		||||
            throw new RuntimeException(e);
 | 
			
		||||
        } finally {
 | 
			
		||||
            if (inputStream != null) {
 | 
			
		||||
                try {
 | 
			
		||||
                    inputStream.close();
 | 
			
		||||
                } catch (final IOException e) {
 | 
			
		||||
                    e.printStackTrace();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * https 域名校验
 | 
			
		||||
     *
 | 
			
		||||
     * @author 喵♂呜
 | 
			
		||||
     * @since 2016年4月1日 下午10:36:01
 | 
			
		||||
     */
 | 
			
		||||
    private static class TrustAnyHostnameVerifier implements HostnameVerifier {
 | 
			
		||||
        @Override
 | 
			
		||||
        public boolean verify(final String hostname, final SSLSession session) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * https 证书管理
 | 
			
		||||
     *
 | 
			
		||||
     * @author 喵♂呜
 | 
			
		||||
     * @since 2016年4月1日 下午10:36:05
 | 
			
		||||
     */
 | 
			
		||||
    private static class TrustAnyTrustManager implements X509TrustManager {
 | 
			
		||||
        @Override
 | 
			
		||||
        public void checkClientTrusted(final X509Certificate[] chain, final String authType) throws CertificateException {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void checkServerTrusted(final X509Certificate[] chain, final String authType) throws CertificateException {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public X509Certificate[] getAcceptedIssuers() {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,5 +1,10 @@
 | 
			
		||||
package pw.yumc.YumCore.kit;
 | 
			
		||||
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.lang.Validate;
 | 
			
		||||
import org.bukkit.ChatColor;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 字符串工具类
 | 
			
		||||
 *
 | 
			
		||||
@@ -7,9 +12,20 @@ package pw.yumc.YumCore.kit;
 | 
			
		||||
 * @since 2016年9月14日 上午1:02:23
 | 
			
		||||
 */
 | 
			
		||||
public class StrKit {
 | 
			
		||||
    private static final String EMPTY = "";
 | 
			
		||||
 | 
			
		||||
    private StrKit() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param string
 | 
			
		||||
     *            源字串
 | 
			
		||||
     * @return 颜色转化后的字串
 | 
			
		||||
     */
 | 
			
		||||
    public static String color(final String string) {
 | 
			
		||||
        return ChatColor.translateAlternateColorCodes('&', string);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 转移数组后获取字符串
 | 
			
		||||
     *
 | 
			
		||||
@@ -29,6 +45,44 @@ public class StrKit {
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Copies all elements from the iterable collection of originals to the
 | 
			
		||||
     * collection provided.
 | 
			
		||||
     *
 | 
			
		||||
     * @param <T>
 | 
			
		||||
     *            the collection of strings
 | 
			
		||||
     * @param token
 | 
			
		||||
     *            String to search for
 | 
			
		||||
     * @param originals
 | 
			
		||||
     *            An iterable collection of strings to filter.
 | 
			
		||||
     * @param collection
 | 
			
		||||
     *            The collection to add matches to
 | 
			
		||||
     * @return the collection provided that would have the elements copied
 | 
			
		||||
     *         into
 | 
			
		||||
     * @throws UnsupportedOperationException
 | 
			
		||||
     *             if the collection is immutable
 | 
			
		||||
     *             and originals contains a string which starts with the specified
 | 
			
		||||
     *             search string.
 | 
			
		||||
     * @throws IllegalArgumentException
 | 
			
		||||
     *             if any parameter is is null
 | 
			
		||||
     * @throws IllegalArgumentException
 | 
			
		||||
     *             if originals contains a null element.
 | 
			
		||||
     *             <b>Note: the collection may be modified before this is thrown</b>
 | 
			
		||||
     */
 | 
			
		||||
    public static <T extends Collection<? super String>> T copyPartialMatches(final String token, final Iterable<String> originals, final T collection) throws UnsupportedOperationException, IllegalArgumentException {
 | 
			
		||||
        Validate.notNull(token, "Search token cannot be null");
 | 
			
		||||
        Validate.notNull(collection, "Collection cannot be null");
 | 
			
		||||
        Validate.notNull(originals, "Originals cannot be null");
 | 
			
		||||
 | 
			
		||||
        for (final String string : originals) {
 | 
			
		||||
            if (startsWithIgnoreCase(string, token)) {
 | 
			
		||||
                collection.add(string);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return collection;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param str
 | 
			
		||||
     *            字串
 | 
			
		||||
@@ -38,6 +92,35 @@ public class StrKit {
 | 
			
		||||
        return str == null || str.isEmpty();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 转化数组为字符串
 | 
			
		||||
     *
 | 
			
		||||
     * @param arr
 | 
			
		||||
     *            数组
 | 
			
		||||
     * @return 字符串
 | 
			
		||||
     */
 | 
			
		||||
    public static String join(final Object[] arr) {
 | 
			
		||||
        return join(arr, EMPTY);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 转化数组为字符串
 | 
			
		||||
     *
 | 
			
		||||
     * @param arr
 | 
			
		||||
     *            数组
 | 
			
		||||
     * @param split
 | 
			
		||||
     *            分割符
 | 
			
		||||
     * @return 字符串
 | 
			
		||||
     */
 | 
			
		||||
    public static String join(final Object[] arr, final String split) {
 | 
			
		||||
        final StringBuffer str = new StringBuffer();
 | 
			
		||||
        for (final Object s : arr) {
 | 
			
		||||
            str.append(s.toString());
 | 
			
		||||
            str.append(split);
 | 
			
		||||
        }
 | 
			
		||||
        return str.length() > split.length() ? str.toString().substring(0, str.length() - split.length()) : str.toString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param str
 | 
			
		||||
     *            字串
 | 
			
		||||
@@ -46,4 +129,107 @@ public class StrKit {
 | 
			
		||||
    public static boolean notBlank(final String str) {
 | 
			
		||||
        return str != null && !str.isEmpty();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method uses a region to check case-insensitive equality. This
 | 
			
		||||
     * means the internal array does not need to be copied like a
 | 
			
		||||
     * toLowerCase() call would.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string
 | 
			
		||||
     *            String to check
 | 
			
		||||
     * @param prefix
 | 
			
		||||
     *            Prefix of string to compare
 | 
			
		||||
     * @return true if provided string starts with, ignoring case, the prefix
 | 
			
		||||
     *         provided
 | 
			
		||||
     * @throws NullPointerException
 | 
			
		||||
     *             if prefix is null
 | 
			
		||||
     * @throws IllegalArgumentException
 | 
			
		||||
     *             if string is null
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean startsWithIgnoreCase(final String string, final String prefix) throws IllegalArgumentException, NullPointerException {
 | 
			
		||||
        Validate.notNull(string, "Cannot check a null string for a match");
 | 
			
		||||
        if (string.length() < prefix.length()) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        return string.regionMatches(true, 0, prefix, 0, prefix.length());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * <p>
 | 
			
		||||
     * Gets a substring from the specified String avoiding exceptions.
 | 
			
		||||
     * </p>
 | 
			
		||||
     *
 | 
			
		||||
     * <p>
 | 
			
		||||
     * A negative start position can be used to start/end <code>n</code>
 | 
			
		||||
     * characters from the end of the String.
 | 
			
		||||
     * </p>
 | 
			
		||||
     *
 | 
			
		||||
     * <p>
 | 
			
		||||
     * The returned substring starts with the character in the <code>start</code>
 | 
			
		||||
     * position and ends before the <code>end</code> position. All position counting is
 | 
			
		||||
     * zero-based -- i.e., to start at the beginning of the string use
 | 
			
		||||
     * <code>start = 0</code>. Negative start and end positions can be used to
 | 
			
		||||
     * specify offsets relative to the end of the String.
 | 
			
		||||
     * </p>
 | 
			
		||||
     *
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If <code>start</code> is not strictly to the left of <code>end</code>, ""
 | 
			
		||||
     * is returned.
 | 
			
		||||
     * </p>
 | 
			
		||||
     *
 | 
			
		||||
     * <pre>
 | 
			
		||||
     * StringUtils.substring(null, *, *)    = null
 | 
			
		||||
     * StringUtils.substring("", * ,  *)    = "";
 | 
			
		||||
     * StringUtils.substring("abc", 0, 2)   = "ab"
 | 
			
		||||
     * StringUtils.substring("abc", 2, 0)   = ""
 | 
			
		||||
     * StringUtils.substring("abc", 2, 4)   = "c"
 | 
			
		||||
     * StringUtils.substring("abc", 4, 6)   = ""
 | 
			
		||||
     * StringUtils.substring("abc", 2, 2)   = ""
 | 
			
		||||
     * StringUtils.substring("abc", -2, -1) = "b"
 | 
			
		||||
     * StringUtils.substring("abc", -4, 2)  = "ab"
 | 
			
		||||
     * </pre>
 | 
			
		||||
     *
 | 
			
		||||
     * @param str
 | 
			
		||||
     *            the String to get the substring from, may be null
 | 
			
		||||
     * @param start
 | 
			
		||||
     *            the position to start from, negative means
 | 
			
		||||
     *            count back from the end of the String by this many characters
 | 
			
		||||
     * @param end
 | 
			
		||||
     *            the position to end at (exclusive), negative means
 | 
			
		||||
     *            count back from the end of the String by this many characters
 | 
			
		||||
     * @return substring from start position to end positon,
 | 
			
		||||
     *         <code>null</code> if null String input
 | 
			
		||||
     */
 | 
			
		||||
    public static String substring(final String str, int start, int end) {
 | 
			
		||||
        if (str == null) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // handle negatives
 | 
			
		||||
        if (end < 0) {
 | 
			
		||||
            end = str.length() + end; // remember end is negative
 | 
			
		||||
        }
 | 
			
		||||
        if (start < 0) {
 | 
			
		||||
            start = str.length() + start; // remember start is negative
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // check length next
 | 
			
		||||
        if (end > str.length()) {
 | 
			
		||||
            end = str.length();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // if start is greater than end, return ""
 | 
			
		||||
        if (start > end) {
 | 
			
		||||
            return EMPTY;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (start < 0) {
 | 
			
		||||
            start = 0;
 | 
			
		||||
        }
 | 
			
		||||
        if (end < 0) {
 | 
			
		||||
            end = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return str.substring(start, end);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										70
									
								
								src/main/java/pw/yumc/YumCore/kit/ZipKit.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								src/main/java/pw/yumc/YumCore/kit/ZipKit.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,70 @@
 | 
			
		||||
package pw.yumc.YumCore.kit;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.nio.file.Files;
 | 
			
		||||
import java.nio.file.StandardCopyOption;
 | 
			
		||||
import java.util.Enumeration;
 | 
			
		||||
import java.util.zip.ZipEntry;
 | 
			
		||||
import java.util.zip.ZipException;
 | 
			
		||||
import java.util.zip.ZipFile;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * ZIP操作类
 | 
			
		||||
 *
 | 
			
		||||
 * @since 2016年7月19日 上午10:24:06
 | 
			
		||||
 * @author 喵♂呜
 | 
			
		||||
 */
 | 
			
		||||
public class ZipKit {
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取文件真实名称
 | 
			
		||||
     *
 | 
			
		||||
     * @param name
 | 
			
		||||
     *            名称
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public static String getRealName(final String name) {
 | 
			
		||||
        return new File(name).getName();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param zipFile
 | 
			
		||||
     *            zip文件
 | 
			
		||||
     * @param destPath
 | 
			
		||||
     *            解压目录
 | 
			
		||||
     * @throws ZipException
 | 
			
		||||
     *             ZIP操作异常
 | 
			
		||||
     * @throws IOException
 | 
			
		||||
     *             IO异常
 | 
			
		||||
     */
 | 
			
		||||
    public static void unzip(final File zipFile, final File destPath) throws ZipException, IOException {
 | 
			
		||||
        unzip(zipFile, destPath, null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param zipFile
 | 
			
		||||
     *            zip文件
 | 
			
		||||
     * @param destPath
 | 
			
		||||
     *            解压目录
 | 
			
		||||
     * @param ext
 | 
			
		||||
     *            解压后缀
 | 
			
		||||
     * @throws ZipException
 | 
			
		||||
     *             ZIP操作异常
 | 
			
		||||
     * @throws IOException
 | 
			
		||||
     *             IO异常
 | 
			
		||||
     */
 | 
			
		||||
    public static void unzip(final File zipFile, final File destPath, final String ext) throws ZipException, IOException {
 | 
			
		||||
        final ZipFile zipObj = new ZipFile(zipFile);
 | 
			
		||||
        final Enumeration<? extends ZipEntry> e = zipObj.entries();
 | 
			
		||||
        while (e.hasMoreElements()) {
 | 
			
		||||
            final ZipEntry entry = e.nextElement();
 | 
			
		||||
            final File destinationFilePath = new File(destPath, getRealName(entry.getName()));
 | 
			
		||||
            if (entry.isDirectory() || (ext != null && !destinationFilePath.getName().endsWith(ext))) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            destinationFilePath.getParentFile().mkdirs();
 | 
			
		||||
            Files.copy(zipObj.getInputStream(entry), destinationFilePath.toPath(), StandardCopyOption.REPLACE_EXISTING);
 | 
			
		||||
        }
 | 
			
		||||
        zipObj.close();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,141 +0,0 @@
 | 
			
		||||
package pw.yumc.YumCore.misc;
 | 
			
		||||
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.Material;
 | 
			
		||||
import org.bukkit.inventory.ItemStack;
 | 
			
		||||
import org.bukkit.material.SpawnEgg;
 | 
			
		||||
 | 
			
		||||
import pw.yumc.YumCore.bukkit.Log;
 | 
			
		||||
import pw.yumc.YumCore.config.FileConfig;
 | 
			
		||||
import pw.yumc.YumCore.config.YumConfig;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 本地化工具类
 | 
			
		||||
 *
 | 
			
		||||
 * @since 2015年12月14日 下午1:33:52
 | 
			
		||||
 * @author 喵♂呜
 | 
			
		||||
 */
 | 
			
		||||
public class L10N {
 | 
			
		||||
    private static String CONFIG_NAME = "Item_zh_CN.yml";
 | 
			
		||||
    private static FileConfig custom;
 | 
			
		||||
    private static Map<String, String> content;
 | 
			
		||||
 | 
			
		||||
    static {
 | 
			
		||||
        content = new HashMap<>();
 | 
			
		||||
        Log.info("异步初始化本地化工具...");
 | 
			
		||||
        load();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private L10N() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取物品完整汉化名称(包括原版)
 | 
			
		||||
     *
 | 
			
		||||
     * @param i
 | 
			
		||||
     *            物品实体
 | 
			
		||||
     * @return 物品名称
 | 
			
		||||
     */
 | 
			
		||||
    public static final String getFullName(final ItemStack i) {
 | 
			
		||||
        return getItemName(getItemType(i)) + (i.hasItemMeta() && i.getItemMeta().hasDisplayName() ? "§r(" + i.getItemMeta().getDisplayName() + "§r)" : "");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取物品汉化名称
 | 
			
		||||
     *
 | 
			
		||||
     * @param i
 | 
			
		||||
     *            物品实体
 | 
			
		||||
     * @return 物品名称
 | 
			
		||||
     */
 | 
			
		||||
    public static final String getItemName(final ItemStack i) {
 | 
			
		||||
        return getItemName(getItemType(i));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取物品汉化名称(优先显示名称)
 | 
			
		||||
     *
 | 
			
		||||
     * @param i
 | 
			
		||||
     *            物品实体
 | 
			
		||||
     * @return 物品名称
 | 
			
		||||
     */
 | 
			
		||||
    public static final String getName(final ItemStack i) {
 | 
			
		||||
        return i.hasItemMeta() && i.getItemMeta().hasDisplayName() ? i.getItemMeta().getDisplayName() : getItemName(getItemType(i));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 重载LocalUtil
 | 
			
		||||
     */
 | 
			
		||||
    public static void reload() {
 | 
			
		||||
        Log.info("异步重载本地化工具...");
 | 
			
		||||
        content.clear();
 | 
			
		||||
        load();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取物品汉化名称
 | 
			
		||||
     *
 | 
			
		||||
     * @param iname
 | 
			
		||||
     *            物品类型名称
 | 
			
		||||
     * @return 物品名称
 | 
			
		||||
     */
 | 
			
		||||
    private static final String getItemName(final String iname) {
 | 
			
		||||
        String aname = content.get(iname);
 | 
			
		||||
        if (aname == null) {
 | 
			
		||||
            aname = iname;
 | 
			
		||||
            if (custom != null) {
 | 
			
		||||
                custom.set(iname, iname);
 | 
			
		||||
                custom.save();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return aname;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取物品类型名称
 | 
			
		||||
     *
 | 
			
		||||
     * @param i
 | 
			
		||||
     *            物品实体
 | 
			
		||||
     * @return 物品类型
 | 
			
		||||
     */
 | 
			
		||||
    private static final String getItemType(final ItemStack i) {
 | 
			
		||||
        String name = i.getType().name();
 | 
			
		||||
        String dura = "";
 | 
			
		||||
        if (i.getType() == Material.MONSTER_EGG) {
 | 
			
		||||
            name = ((SpawnEgg) i.getData()).getSpawnedType().name();
 | 
			
		||||
        } else {
 | 
			
		||||
            final int dur = i.getDurability();
 | 
			
		||||
            dura = (i.getMaxStackSize() != 1 && dur != 0) ? Integer.toString(dur) : "";
 | 
			
		||||
        }
 | 
			
		||||
        return (name + (dura.isEmpty() ? "" : "-" + dura)).toUpperCase();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 载入数据
 | 
			
		||||
     */
 | 
			
		||||
    private static void load() {
 | 
			
		||||
        new Thread(new Runnable() {
 | 
			
		||||
            @SuppressWarnings("unchecked")
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
                try {
 | 
			
		||||
                    final Map<String, String> local = YumConfig.getLocal(CONFIG_NAME).getContentMap();
 | 
			
		||||
                    final Map<String, String> remote = YumConfig.getRemote(CONFIG_NAME).getContentMap();
 | 
			
		||||
                    if (local != null) {
 | 
			
		||||
                        Log.info("本地汉化文件词条数量: " + local.size());
 | 
			
		||||
                        content.putAll(local);
 | 
			
		||||
                    }
 | 
			
		||||
                    if (remote != null) {
 | 
			
		||||
                        Log.info("远程汉化文件词条数量: " + remote.size());
 | 
			
		||||
                        content.putAll(remote);
 | 
			
		||||
                    }
 | 
			
		||||
                    Log.info("本地化工具初始化完毕...");
 | 
			
		||||
                } catch (final Exception e) {
 | 
			
		||||
                    Log.warning(String.format("本地化工具初始化失败: %s %s", e.getClass().getName(), e.getMessage()));
 | 
			
		||||
                    Log.debug(CONFIG_NAME, e);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }).start();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user