1
0
mirror of https://e.coding.net/circlecloud/YumCore.git synced 2024-12-25 07:08:52 +00:00

feat: 更新工具包

Signed-off-by: 502647092 <admin@yumc.pw>
This commit is contained in:
502647092 2016-09-27 15:12:04 +08:00
parent 2d55b7085f
commit 9213170601
6 changed files with 1182 additions and 141 deletions

View 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();
}
}
}

View 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();
}
}

View 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;
}
}
}

View File

@ -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);
}
}

View 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();
}
}

View File

@ -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();
}
}