From 008b053e27fcdf7b48c3ab35de8de7f724d7b205 Mon Sep 17 00:00:00 2001 From: u2g Date: Wed, 11 Jan 2017 22:12:05 +0800 Subject: [PATCH 01/16] =?UTF-8?q?=E7=8E=A9=E5=AE=B6=20MoonLakePlayer=20?= =?UTF-8?q?=E6=96=B0=E7=9A=84=E4=BE=9D=E8=B5=96=20WorldEditPlayer=20?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 +- config.yml | 4 +- plugin.yml | 4 +- .../minecraft/moonlake/MoonLakePlugin.java | 4 +- .../moonlake/api/player/AbstractPlayer.java | 16 + .../api/player/DependWorldEditPlayer.java | 95 ++++++ ...endWorldEditPlayerSelectionExpression.java | 128 ++++++++ .../api/player/PlayerLibraryFactorys.java | 48 +++ .../api/player/depend/DependPlayer.java | 3 +- .../api/player/depend/WorldEditPlayer.java | 42 +++ .../api/player/depend/WorldEditSelection.java | 117 ++++++++ .../api/player/depend/WorldEditVector.java | 284 ++++++++++++++++++ 12 files changed, 740 insertions(+), 9 deletions(-) create mode 100644 src/com/minecraft/moonlake/api/player/DependWorldEditPlayer.java create mode 100644 src/com/minecraft/moonlake/api/player/DependWorldEditPlayerSelectionExpression.java create mode 100644 src/com/minecraft/moonlake/api/player/depend/WorldEditPlayer.java create mode 100644 src/com/minecraft/moonlake/api/player/depend/WorldEditSelection.java create mode 100644 src/com/minecraft/moonlake/api/player/depend/WorldEditVector.java diff --git a/README.md b/README.md index ab625a8e..e789002b 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -# MoonLake [![GitHub version](https://d25lcipzij17d.cloudfront.net/badge.svg?id=gh&type=6&v=1.8-final&x2=0)](https://github.com/u2g/MoonLake) [![Open Source Love](https://badges.frapsoft.com/os/v1/open-source.svg?v=102)](https://github.com/u2g/MoonLake) [![Open Source Love](https://badges.frapsoft.com/os/gpl/gpl.svg?v=102)](https://github.com/u2g/MoonLake) +# MoonLake [![GitHub version](https://d25lcipzij17d.cloudfront.net/badge.svg?id=gh&type=6&v=1.9-alpha&x2=0)](https://github.com/u2g/MoonLake) [![Open Source Love](https://badges.frapsoft.com/os/v1/open-source.svg?v=102)](https://github.com/u2g/MoonLake) [![Open Source Love](https://badges.frapsoft.com/os/gpl/gpl.svg?v=102)](https://github.com/u2g/MoonLake) Minecraft MoonLake Core API Plugin -By Month_Light Ver: 1.8-final +By Month_Light Ver: 1.9-alpha ## 简介 这个插件提供了大量的 API 功能,实现了一些 Bukkit 无法做到的 NMS 功能
diff --git a/config.yml b/config.yml index 77dda444..126a153e 100644 --- a/config.yml +++ b/config.yml @@ -1,10 +1,10 @@ ################################ # MoonLake Core API Plugin # -# By Month_Light Ver: 1.8-final # +# By Month_Light Ver: 1.9-alpha # ################################ # 插件版本号: 此项请勿修改! -version: '1.8-final' +version: '1.9-alpha' # 数据包通道监听器 # 此项可设置是否开启这个功能 diff --git a/plugin.yml b/plugin.yml index 5ea4f246..9b1de075 100644 --- a/plugin.yml +++ b/plugin.yml @@ -1,9 +1,9 @@ name: MoonLake main: com.minecraft.moonlake.MoonLakePlugin -version: 1.8-final +version: 1.9-alpha prefix: MoonLake description: Minecraft MoonLake Core API Plugin website: http://www.mcyszh.com/ author: Month_Light authors: [Month_Light, MoonLake] -softdepend: [MoonLakeEconomy, PermissionsEx, Vault] +softdepend: [MoonLakeEconomy, PermissionsEx, Vault, WorldEdit] diff --git a/src/com/minecraft/moonlake/MoonLakePlugin.java b/src/com/minecraft/moonlake/MoonLakePlugin.java index acf7674e..1db537f4 100644 --- a/src/com/minecraft/moonlake/MoonLakePlugin.java +++ b/src/com/minecraft/moonlake/MoonLakePlugin.java @@ -34,7 +34,7 @@ *
*
*

Minecraft MoonLake Core API Plugin

- *

By Month_Light Ver: 1.8-final

+ *

By Month_Light Ver: 1.9-alpha

*

Website: MoonLake Website

*

QQ Group: 377607025 -> Jump

*
@@ -69,7 +69,7 @@ *

修改操作请您遵守 GPLv3 协议,您必须公开修改过的所有代码!

*
* - * @version 1.8-final + * @version 1.9-alpha * @author Month_Light */ public class MoonLakePlugin extends JavaPlugin implements MoonLake { diff --git a/src/com/minecraft/moonlake/api/player/AbstractPlayer.java b/src/com/minecraft/moonlake/api/player/AbstractPlayer.java index abc68e51..2a7c91f0 100644 --- a/src/com/minecraft/moonlake/api/player/AbstractPlayer.java +++ b/src/com/minecraft/moonlake/api/player/AbstractPlayer.java @@ -22,6 +22,7 @@ import com.minecraft.moonlake.api.fancy.FancyMessage; import com.minecraft.moonlake.api.player.depend.EconomyPlayerData; import com.minecraft.moonlake.api.player.depend.EconomyVaultPlayerResponse; +import com.minecraft.moonlake.api.player.depend.WorldEditSelection; import com.minecraft.moonlake.exception.CannotDependException; import com.minecraft.moonlake.exception.PlayerNotOnlineException; import com.minecraft.moonlake.manager.PlayerManager; @@ -52,6 +53,7 @@ import org.bukkit.scoreboard.Scoreboard; import org.bukkit.util.Vector; +import javax.annotation.Nullable; import java.net.InetAddress; import java.net.InetSocketAddress; import java.util.*; @@ -1806,4 +1808,18 @@ public EconomyVaultPlayerResponse depositEconomyVaultBalance(double amount, Stri throw new CannotDependException("The call 'Vault' plugin 'Economy' method 'depositEconomyVaultBalance' exception.", e); } } + + @Nullable + @Override + public WorldEditSelection getWorldEditSelection() throws CannotDependException { + + try { + + return PlayerLibraryFactorys.worldEditPlayer().getSelection(this); + } + catch (Exception e) { + + throw new CannotDependException("The call 'WorldEdit plugin method 'getWorldEditSelection' exception.", e); + } + } } diff --git a/src/com/minecraft/moonlake/api/player/DependWorldEditPlayer.java b/src/com/minecraft/moonlake/api/player/DependWorldEditPlayer.java new file mode 100644 index 00000000..581071ff --- /dev/null +++ b/src/com/minecraft/moonlake/api/player/DependWorldEditPlayer.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2017 The MoonLake Authors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +package com.minecraft.moonlake.api.player; + +import com.minecraft.moonlake.MoonLakeAPI; +import com.minecraft.moonlake.api.player.depend.WorldEditSelection; +import com.minecraft.moonlake.exception.CannotDependException; +import com.minecraft.moonlake.exception.CannotDependVersionException; +import com.sk89q.worldedit.bukkit.WorldEditPlugin; +import com.sk89q.worldedit.bukkit.selections.Selection; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; + +/** + *

DependWorldEditPlayer

+ * 依赖创世神插件玩家实现类 # 依赖 WorldEdit 插件 + * + * @version 1.0 + * @author Month_Light + */ +class DependWorldEditPlayer { + + private WorldEditPlugin worldEdit; + + public DependWorldEditPlayer() throws CannotDependException, CannotDependVersionException { + + Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin("WorldEdit"); + + if(plugin == null) { + + throw new CannotDependException("The cannot depend 'WorldEdit' plugin exception."); + } + // 检查 WorldEdit 插件版本, 本依赖最低需要 6.0 版本 + String version = plugin.getDescription().getVersion(); + + if(version.compareTo("6.0") < 0) { + // 服务端加载的 WorldEdit 插件版本小于 6.0 则抛出异常 + throw new CannotDependVersionException("The depend 'WorldEdit' plugin, but version less than 6.0 exception."); + } + this.worldEdit = ((WorldEditPlugin) plugin); + + MoonLakeAPI.getMLogger().info("Success hook 'WorldEdit' plugin, 'WorldEditPlayer' interface be use."); + } + + /** + * 获取指定玩家的 WorldEdit 选择区域对象 + * + * @param player 玩家 + * @return Selection + */ + protected Selection getSelection0(Player player) { + + return worldEdit.getSelection(player); + } + + /** + * 获取指定玩家的 WorldEdit 选择区域包装对象 + * + * @param player 玩家 + * @return WorldEditSelection + */ + public WorldEditSelection getSelection(Player player) { + + Selection selection = getSelection0(player); + return selection != null ? new DependWorldEditPlayerSelectionExpression(selection) : null; + } + + /** + * 获取指定玩家的 WorldEdit 选择区域包装对象 + * + * @param player 月色之湖玩家 + * @return WorldEditSelection + */ + public WorldEditSelection getSelection(MoonLakePlayer player) { + + return getSelection(player.getBukkitPlayer()); + } +} diff --git a/src/com/minecraft/moonlake/api/player/DependWorldEditPlayerSelectionExpression.java b/src/com/minecraft/moonlake/api/player/DependWorldEditPlayerSelectionExpression.java new file mode 100644 index 00000000..b75e7120 --- /dev/null +++ b/src/com/minecraft/moonlake/api/player/DependWorldEditPlayerSelectionExpression.java @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2017 The MoonLake Authors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +package com.minecraft.moonlake.api.player; + +import com.minecraft.moonlake.api.player.depend.WorldEditSelection; +import com.minecraft.moonlake.api.player.depend.WorldEditVector; +import com.minecraft.moonlake.validate.Validate; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.bukkit.selections.Selection; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Entity; + +import javax.annotation.Nullable; + +/** + *

DependWorldEditPlayerSelectionExpression

+ * 创世神选择区域接口实现类 + * + * @version 1.0 + * @author Month_Light + */ +class DependWorldEditPlayerSelectionExpression implements WorldEditSelection { + + private final Selection handler; + + /** + * 创世神选择区域接口实现类构造函数 + * + * @param handler 创世神选择区域对象 + */ + public DependWorldEditPlayerSelectionExpression(Selection handler) { + + this.handler = handler; + } + + @Override + public Location getMinimumPoint() { + + return handler.getMinimumPoint(); + } + + @Override + public Location getMaximumPoint() { + + return handler.getMaximumPoint(); + } + + @Override + public WorldEditVector getNativeMinimumPoint() { + + return asVector(handler.getNativeMinimumPoint()); + } + + @Override + public WorldEditVector getNativeMaximumPoint() { + + return asVector(handler.getNativeMaximumPoint()); + } + + protected final WorldEditVector asVector(Vector vector) { + + return vector != null ? new WorldEditVector(vector.getX(), vector.getY(), vector.getZ()) : null; + } + + @Nullable + @Override + public World getWorld() { + + return handler.getWorld(); + } + + @Override + public int getArea() { + + return handler.getArea(); + } + + @Override + public int getWidth() { + + return handler.getWidth(); + } + + @Override + public int getHeight() { + + return handler.getHeight(); + } + + @Override + public int getLength() { + + return handler.getLength(); + } + + @Override + public boolean contains(Location location) { + + Validate.notNull(location, "The location object is null."); + + return handler.contains(location); + } + + @Override + public boolean contains(Entity entity) { + + Validate.notNull(entity, "The entity object is null."); + + return handler.contains(entity.getLocation()); + } +} diff --git a/src/com/minecraft/moonlake/api/player/PlayerLibraryFactorys.java b/src/com/minecraft/moonlake/api/player/PlayerLibraryFactorys.java index 3fd9dd02..88c9d5e3 100644 --- a/src/com/minecraft/moonlake/api/player/PlayerLibraryFactorys.java +++ b/src/com/minecraft/moonlake/api/player/PlayerLibraryFactorys.java @@ -45,6 +45,8 @@ public class PlayerLibraryFactorys { private static Boolean dependPermissionsExPlayerHook = null; private static DependEconomyVaultPlayer dependEconomyVaultPlayer; private static Boolean dependEconomyVaultPlayerHook = null; + private static DependWorldEditPlayer dependWorldEditPlayer; + private static Boolean dependWorldEditPlayerHook = null; static { @@ -74,6 +76,10 @@ else if(pluginName.equals("Vault") && dependEconomyVaultPlayerHook == null) { // Hook Vault Economy economyVaultPlayer(); } + else if(pluginName.equals("WorldEdit") && dependWorldEditPlayerHook == null) { + // Hook WorldEdit + worldEditPlayer(); + } } catch (Exception e) { @@ -110,6 +116,13 @@ else if(pluginName.equals("Vault") && dependEconomyVaultPlayerHook != null) { MoonLakeAPI.getMLogger().warn("The unhook 'Vault' plugin 'Economy' module, now 'EconomyVaultPlayer' interface is unavailable."); } + else if(pluginName.equals("WorldEdit") && dependWorldEditPlayerHook != null) { + // Unhook WorldEdit + dependWorldEditPlayer = null; + dependWorldEditPlayerHook = null; + + MoonLakeAPI.getMLogger().warn("The unhook 'WorldEdit' plugin, now 'WorldEditPlayer' interface is unavailable."); + } } }, MoonLakeAPI.getMoonLake()); /// @@ -251,4 +264,39 @@ public static boolean isDependEconomyVaultPlayerHook() { return dependEconomyVaultPlayerHook; } + + /** + * 获取依赖传送书插件玩家 DependWorldEditPlayer 对象 + * + * @return DependWorldEditPlayer + * @throws CannotDependException 如果无法加载依赖插件则抛出异常 + */ + public static DependWorldEditPlayer worldEditPlayer() throws CannotDependException { + + if(dependWorldEditPlayer == null && dependWorldEditPlayerHook == null) { + + try { + + dependWorldEditPlayer = new DependWorldEditPlayer(); + dependWorldEditPlayerHook = true; + } + catch (Exception e) { + + dependWorldEditPlayerHook = false; + + throw new CannotDependException("The hook 'WorldEdit' plugin failed exception.", e); + } + } + return dependWorldEditPlayer; + } + + /** + * 获取是否成功依赖 WorldEdit 创世神插件玩家 + * + * @return 是否成功依赖 + */ + public static boolean isDependWorldEditPlayerHook() { + + return dependWorldEditPlayerHook; + } } diff --git a/src/com/minecraft/moonlake/api/player/depend/DependPlayer.java b/src/com/minecraft/moonlake/api/player/depend/DependPlayer.java index c58f28b2..0e6be353 100644 --- a/src/com/minecraft/moonlake/api/player/depend/DependPlayer.java +++ b/src/com/minecraft/moonlake/api/player/depend/DependPlayer.java @@ -27,6 +27,7 @@ * @see EconomyPlayer * @see EconomyVaultPlayer * @see PermissionsExPlayer + * @see WorldEditPlayer */ -public interface DependPlayer extends EconomyPlayer, EconomyVaultPlayer, PermissionsExPlayer { +public interface DependPlayer extends EconomyPlayer, EconomyVaultPlayer, PermissionsExPlayer, WorldEditPlayer { } diff --git a/src/com/minecraft/moonlake/api/player/depend/WorldEditPlayer.java b/src/com/minecraft/moonlake/api/player/depend/WorldEditPlayer.java new file mode 100644 index 00000000..c4dfad24 --- /dev/null +++ b/src/com/minecraft/moonlake/api/player/depend/WorldEditPlayer.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2017 The MoonLake Authors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +package com.minecraft.moonlake.api.player.depend; + +import com.minecraft.moonlake.exception.CannotDependException; + +import javax.annotation.Nullable; + +/** + *

WorldEditPlayer

+ * 创世神玩家接口 # 依赖 WorldEdit 插件 + * + * @version 1.0 + * @author Month_Light + */ +public interface WorldEditPlayer { + + /** + * 获取此玩家的创世神选择区域 + * + * @return 创世神选择区域 + * @throws CannotDependException 如果无法加载依赖插件则抛出异常 + */ + @Nullable + WorldEditSelection getWorldEditSelection() throws CannotDependException; +} diff --git a/src/com/minecraft/moonlake/api/player/depend/WorldEditSelection.java b/src/com/minecraft/moonlake/api/player/depend/WorldEditSelection.java new file mode 100644 index 00000000..5c9eae61 --- /dev/null +++ b/src/com/minecraft/moonlake/api/player/depend/WorldEditSelection.java @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2017 The MoonLake Authors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +package com.minecraft.moonlake.api.player.depend; + +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Entity; + +import javax.annotation.Nullable; + +/** + *

WorldEditSelection

+ * 创世神选择区域接口(详细doc待补充...) + * + * @version 1.0 + * @author Month_Light + */ +public interface WorldEditSelection { + + /** + * 获取此选择区域的最低点位置 + * + * @return 最低点位置 + */ + Location getMinimumPoint(); + + /** + * 获取此选择区域的最高点位置 + * + * @return 最高点位置 + */ + Location getMaximumPoint(); + + /** + * 获取此选择区域的本机最低点矢量 + * + * @return 本机最低点矢量 + */ + WorldEditVector getNativeMinimumPoint(); + + /** + * 获取此选择区域的本机最高点矢量 + * + * @return 本机最高点矢量 + */ + WorldEditVector getNativeMaximumPoint(); + + /** + * 获取此选择区域的世界 + * + * @return 世界 + */ + @Nullable + World getWorld(); + + /** + * 获取此选择区域的面积 + * + * @return 面积 + */ + int getArea(); + + /** + * 获取此选择区域的宽度 + * + * @return 宽度 + */ + int getWidth(); + + /** + * 获取此选择区域的高度 + * + * @return 高度 + */ + int getHeight(); + + /** + * 获取此选择区域的长度 + * + * @return 长度 + */ + int getLength(); + + /** + * 获取此选择区域是否包含指定位置 + * + * @param location 位置 + * @return 包含位置则返回 true + * @throws IllegalArgumentException 如果位置对象为 {@code null} 则抛出异常 + */ + boolean contains(Location location); + + /** + * 获取此选择区域是否包含指定实体位置 + * + * @param entity 实体 + * @return 包含实体位置则返回 true + * @throws IllegalArgumentException 如果实体对象为 {@code null} 则抛出异常 + */ + boolean contains(Entity entity); +} diff --git a/src/com/minecraft/moonlake/api/player/depend/WorldEditVector.java b/src/com/minecraft/moonlake/api/player/depend/WorldEditVector.java new file mode 100644 index 00000000..145b6e8c --- /dev/null +++ b/src/com/minecraft/moonlake/api/player/depend/WorldEditVector.java @@ -0,0 +1,284 @@ +/* + * Copyright (C) 2017 The MoonLake Authors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +package com.minecraft.moonlake.api.player.depend; + +public class WorldEditVector implements Comparable { + + public final static WorldEditVector ZERO = new WorldEditVector(0d, 0d, 0d); + + protected final double x; + protected final double y; + protected final double z; + + public WorldEditVector(double x, double y, double z) { + + this.x = x; + this.y = y; + this.z = z; + } + + public WorldEditVector(float x, float y, float z) { + + this.x = x; + this.y = y; + this.z = z; + } + + public WorldEditVector(int x, int y, int z) { + + this.x = x; + this.y = y; + this.z = z; + } + + public WorldEditVector(WorldEditVector other) { + + this.x = other.x; + this.y = other.y; + this.z = other.z; + } + + public WorldEditVector() { + + this.x = 0d; + this.y = 0d; + this.z = 0d; + } + + public double getX() { + + return x; + } + + public double getY() { + + return y; + } + + public double getZ() { + + return z; + } + + public int getBlockX() { + + return (int) Math.round(x); + } + + public int getBlockY() { + + return (int) Math.round(y); + } + + public int getBlockZ() { + + return (int) Math.round(z); + } + + public WorldEditVector setX(double x) { + + return new WorldEditVector(x, y, z); + } + + public WorldEditVector setY(double y) { + + return new WorldEditVector(x, y, z); + } + + public WorldEditVector setZ(double z) { + + return new WorldEditVector(x, y, z); + } + + public WorldEditVector setX(int x) { + + return new WorldEditVector(x, y, z); + } + + public WorldEditVector setY(int y) { + + return new WorldEditVector(x, y, z); + } + + public WorldEditVector setZ(int z) { + + return new WorldEditVector(x, y, z); + } + + public WorldEditVector add(WorldEditVector vector) { + + return new WorldEditVector(x + vector.x, y + vector.y, z + vector.z); + } + + public WorldEditVector add(double x, double y, double z) { + + return new WorldEditVector(this.x + x, this.y + y, this.z + z); + } + + public WorldEditVector add(int x, int y, int z) { + + return new WorldEditVector(this.x + x, this.y + y, this.z + z); + } + + public WorldEditVector subtract(WorldEditVector vector) { + + return new WorldEditVector(x - vector.x, y - vector.y, z - vector.z); + } + + public WorldEditVector subtract(double x, double y, double z) { + + return new WorldEditVector(this.x - x, this.y - y, this.z - z); + } + + public WorldEditVector subtract(int x, int y, int z) { + + return new WorldEditVector(this.x - x, this.y - y, this.z - z); + } + + public WorldEditVector multiply(WorldEditVector vector) { + + return new WorldEditVector(x * vector.x, y * vector.y, z * vector.z); + } + + public WorldEditVector multiply(double x, double y, double z) { + + return new WorldEditVector(this.x * x, this.y * y, this.z * z); + } + + public WorldEditVector multiply(int x, int y, int z) { + + return new WorldEditVector(this.x * x, this.y * y, this.z * z); + } + + public WorldEditVector multiply(double n) { + + return new WorldEditVector(this.x * n, this.y * n, this.z * n); + } + + public WorldEditVector multiply(float n) { + + return new WorldEditVector(this.x * n, this.y * n, this.z * n); + } + + public WorldEditVector multiply(int n) { + + return new WorldEditVector(this.x * n, this.y * n, this.z * n); + } + + public WorldEditVector divide(WorldEditVector vector) { + + return new WorldEditVector(x / vector.x, y / vector.y, z / vector.z); + } + + public WorldEditVector divide(double x, double y, double z) { + + return new WorldEditVector(this.x / x, this.y / y, this.z / z); + } + + public WorldEditVector divide(int x, int y, int z) { + + return new WorldEditVector(this.x / x, this.y / y, this.z / z); + } + + public WorldEditVector divide(double n) { + + return new WorldEditVector(this.x / n, this.y / n, this.z / n); + } + + public WorldEditVector divide(float n) { + + return new WorldEditVector(this.x / n, this.y / n, this.z / n); + } + + public WorldEditVector divide(int n) { + + return new WorldEditVector(this.x / n, this.y / n, this.z / n); + } + + public double length() { + + return Math.sqrt(lengthSq()); + } + + public double lengthSq() { + + return x * x + y * y + z * z; + } + + public double distance(WorldEditVector vector) { + + return Math.sqrt(distanceSq(vector)); + } + + public double distanceSq(WorldEditVector vector) { + + return Math.pow(x - vector.x, 2d) + Math.pow(y - vector.y, 2d) + Math.pow(z - vector.z, 2d); + } + + public WorldEditVector normalize() { + + return divide(length()); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + WorldEditVector that = (WorldEditVector) o; + + if (Double.compare(that.x, x) != 0) return false; + if (Double.compare(that.y, y) != 0) return false; + return Double.compare(that.z, z) == 0; + } + + @Override + public int hashCode() { + int result; + long temp; + temp = Double.doubleToLongBits(x); + result = (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(y); + result = 31 * result + (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(z); + result = 31 * result + (int) (temp ^ (temp >>> 32)); + return result; + } + + @Override + public String toString() { + return "WorldEditVector{" + + "x=" + x + + ", y=" + y + + ", z=" + z + + '}'; + } + + @Override + public int compareTo(WorldEditVector o) { + + if(x != o.x) + return Double.compare(x, o.x); + if(y != o.y) + return Double.compare(y, o.y); + if(z != o.z) + return Double.compare(z, o.z); + return 0; + } +} From eddc50ce86ae45b08b20a28778b95ab85df4857f Mon Sep 17 00:00:00 2001 From: u2g Date: Fri, 13 Jan 2017 21:02:49 +0800 Subject: [PATCH 02/16] =?UTF-8?q?=E5=8C=BA=E5=9F=9F=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E5=9F=BA=E7=A1=80=E4=BB=A3=E7=A0=81=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../moonlake/api/VectorConvertible.java | 35 ++ .../api/player/depend/WorldEditVector.java | 60 ++- .../moonlake/api/region/AbstractRegion.java | 111 ++++++ .../moonlake/api/region/CuboidRegion.java | 227 ++++++++++++ .../moonlake/api/region/FlatRegion.java | 26 ++ .../minecraft/moonlake/api/region/Region.java | 59 +++ .../api/region/RegionBlockVector.java | 66 ++++ .../moonlake/api/region/RegionVector.java | 346 ++++++++++++++++++ .../moonlake/api/region/RegionVector2D.java | 290 +++++++++++++++ 9 files changed, 1219 insertions(+), 1 deletion(-) create mode 100644 src/com/minecraft/moonlake/api/VectorConvertible.java create mode 100644 src/com/minecraft/moonlake/api/region/AbstractRegion.java create mode 100644 src/com/minecraft/moonlake/api/region/CuboidRegion.java create mode 100644 src/com/minecraft/moonlake/api/region/FlatRegion.java create mode 100644 src/com/minecraft/moonlake/api/region/Region.java create mode 100644 src/com/minecraft/moonlake/api/region/RegionBlockVector.java create mode 100644 src/com/minecraft/moonlake/api/region/RegionVector.java create mode 100644 src/com/minecraft/moonlake/api/region/RegionVector2D.java diff --git a/src/com/minecraft/moonlake/api/VectorConvertible.java b/src/com/minecraft/moonlake/api/VectorConvertible.java new file mode 100644 index 00000000..ec0b574b --- /dev/null +++ b/src/com/minecraft/moonlake/api/VectorConvertible.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2017 The MoonLake Authors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +package com.minecraft.moonlake.api; + +import com.minecraft.moonlake.api.player.depend.WorldEditVector; +import com.minecraft.moonlake.api.region.RegionBlockVector; +import com.minecraft.moonlake.api.region.RegionVector; +import org.bukkit.util.Vector; + +public interface VectorConvertible { + + Vector asBukkitVector(); + + WorldEditVector asWorldEditVector(); + + RegionVector asRegionVector(); + + RegionBlockVector asRegionBlockVector(); +} diff --git a/src/com/minecraft/moonlake/api/player/depend/WorldEditVector.java b/src/com/minecraft/moonlake/api/player/depend/WorldEditVector.java index 145b6e8c..52d5e5b4 100644 --- a/src/com/minecraft/moonlake/api/player/depend/WorldEditVector.java +++ b/src/com/minecraft/moonlake/api/player/depend/WorldEditVector.java @@ -18,10 +18,26 @@ package com.minecraft.moonlake.api.player.depend; -public class WorldEditVector implements Comparable { +import com.minecraft.moonlake.api.VectorConvertible; +import com.minecraft.moonlake.api.region.RegionBlockVector; +import com.minecraft.moonlake.api.region.RegionVector; +import com.minecraft.moonlake.util.StringUtil; +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.configuration.serialization.ConfigurationSerialization; +import org.bukkit.util.Vector; + +import java.util.LinkedHashMap; +import java.util.Map; + +public class WorldEditVector implements VectorConvertible, ConfigurationSerializable, Comparable { public final static WorldEditVector ZERO = new WorldEditVector(0d, 0d, 0d); + static { + + ConfigurationSerialization.registerClass(WorldEditVector.class); + } + protected final double x; protected final double y; protected final double z; @@ -281,4 +297,46 @@ public int compareTo(WorldEditVector o) { return Double.compare(z, o.z); return 0; } + + @Override + public Map serialize() { + + Map result = new LinkedHashMap<>(); + result.put("x", x); + result.put("y", y); + result.put("z", z); + return result; + } + + public static WorldEditVector deserialize(Map args) { + + double x = StringUtil.parseDouble(args.get("x")); + double y = StringUtil.parseDouble(args.get("y")); + double z = StringUtil.parseDouble(args.get("z")); + return new WorldEditVector(x, y, z); + } + + @Override + public Vector asBukkitVector() { + + return new Vector(x, y, z); + } + + @Override + public WorldEditVector asWorldEditVector() { + + return new WorldEditVector(this); + } + + @Override + public RegionVector asRegionVector() { + + return new RegionVector(x, y, z); + } + + @Override + public RegionBlockVector asRegionBlockVector() { + + return new RegionBlockVector(x, y, z); + } } diff --git a/src/com/minecraft/moonlake/api/region/AbstractRegion.java b/src/com/minecraft/moonlake/api/region/AbstractRegion.java new file mode 100644 index 00000000..d0e61e61 --- /dev/null +++ b/src/com/minecraft/moonlake/api/region/AbstractRegion.java @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2017 The MoonLake Authors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +package com.minecraft.moonlake.api.region; + +import com.minecraft.moonlake.exception.MoonLakeException; +import com.minecraft.moonlake.validate.Validate; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; + +public abstract class AbstractRegion implements Region { + + protected final World world; + + public AbstractRegion(World world) { + + this.world = world; + } + + @Override + public World getWorld() { + + return world; + } + + @Override + public RegionVector getCenter() { + + return getMinimumPoint().add(getMaximumPoint()).divide(2); + } + + @Override + public int getArea() { + + RegionVector min = getMinimumPoint(); + RegionVector max = getMaximumPoint(); + return (int) ((max.getX() - min.getX() + 1d) * (max.getY() - min.getY() + 1d) * (max.getZ() - min.getZ() + 1d)); + } + + @Override + public int getWidth() { + + RegionVector min = getMinimumPoint(); + RegionVector max = getMaximumPoint(); + return (int) (max.getX() - min.getX() + 1d); + } + + @Override + public int getHeight() { + + RegionVector min = getMinimumPoint(); + RegionVector max = getMaximumPoint(); + return (int) (max.getY() - min.getY() + 1d); + } + + @Override + public int getLength() { + + RegionVector min = getMinimumPoint(); + RegionVector max = getMaximumPoint(); + return (int) (max.getZ() - min.getZ() + 1d); + } + + @Override + public boolean contains(Location location) { + + return location != null && location.getWorld().equals(world) && contains(new RegionVector(location.getX(), location.getY(), location.getZ())); + } + + @Override + public boolean contains(Entity entity) { + + return contains(Validate.checkNotNull(entity).getLocation()); + } + + @Override + public boolean contains(Block block) { + + return contains(Validate.checkNotNull(block).getLocation()); + } + + @Override + public AbstractRegion clone() { + + try { + + return (AbstractRegion) super.clone(); + } + catch (CloneNotSupportedException e) { + + throw new MoonLakeException(e.getMessage(), e); + } + } +} diff --git a/src/com/minecraft/moonlake/api/region/CuboidRegion.java b/src/com/minecraft/moonlake/api/region/CuboidRegion.java new file mode 100644 index 00000000..e4e817d8 --- /dev/null +++ b/src/com/minecraft/moonlake/api/region/CuboidRegion.java @@ -0,0 +1,227 @@ +/* + * Copyright (C) 2017 The MoonLake Authors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +package com.minecraft.moonlake.api.region; + +import com.minecraft.moonlake.validate.Validate; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.configuration.serialization.ConfigurationSerialization; + +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.NoSuchElementException; + +public class CuboidRegion extends AbstractRegion implements FlatRegion { + + static { + + ConfigurationSerialization.registerClass(CuboidRegion.class); + } + + private RegionVector pos1; + private RegionVector pos2; + + public CuboidRegion(World world, RegionVector pos1, RegionVector pos2) { + + super(world); + + this.pos1 = pos1; + this.pos2 = pos2; + } + + public CuboidRegion(World world, Location pos1, Location pos2) { + + super(world); + + Validate.isTrue(pos1.getWorld().equals(world), "The pos1 location world not equals argument world object."); + Validate.isTrue(pos2.getWorld().equals(world), "The pos2 location world not equals argument world object."); + + this.pos1 = new RegionVector(pos1.getX(), pos1.getY(), pos1.getZ()); + this.pos2 = new RegionVector(pos2.getX(), pos2.getY(), pos2.getZ()); + } + + public RegionVector getPos1() { + + return pos1; + } + + public void setPos1(RegionVector pos1) { + + this.pos1 = pos1; + } + + public RegionVector getPos2() { + + return pos2; + } + + public void setPos2(RegionVector pos2) { + + this.pos2 = pos2; + } + + @Override + public RegionVector getMinimumPoint() { + + return new RegionVector(Math.min(pos1.getX(), pos2.getX()), Math.min(pos1.getY(), pos2.getY()), Math.min(pos1.getZ(), pos2.getZ())); + } + + @Override + public RegionVector getMaximumPoint() { + + return new RegionVector(Math.max(pos1.getX(), pos2.getX()), Math.max(pos1.getY(), pos2.getY()), Math.max(pos1.getZ(), pos2.getZ())); + } + + @Override + public boolean contains(RegionVector vector) { + + Validate.notNull(vector, "The vector object is null."); + + double x = vector.getX(); + double y = vector.getY(); + double z = vector.getZ(); + + RegionVector min = getMinimumPoint(); + RegionVector max = getMaximumPoint(); + + return x >= min.getBlockX() && x <= max.getBlockX() && y >= min.getBlockY() && y <= max.getBlockY() && z >= min.getBlockZ() && z <= max.getBlockZ(); + } + + @Override + public int getMinimumY() { + + return Math.min(pos1.getBlockY(), pos2.getBlockY()); + } + + @Override + public int getMaximumY() { + + return Math.max(pos1.getBlockY(), pos2.getBlockY()); + } + + @Override + public Iterator iterator() { + + return new Iterator() { + + private RegionVector min = getMinimumPoint(); + private RegionVector max = getMaximumPoint(); + private int nextX = min.getBlockX(); + private int nextY = min.getBlockY(); + private int nextZ = min.getBlockZ(); + + @Override + public boolean hasNext() { + + return nextX != 0x7fffffff; + } + + @Override + public RegionBlockVector next() { + + if(!hasNext()) + throw new NoSuchElementException(); + + RegionBlockVector answer = new RegionBlockVector(nextX, nextY, nextZ); + + if(++nextX > max.getBlockX()) { + + nextX = min.getBlockX(); + + if(++nextY > max.getBlockY()) { + + nextY = min.getBlockY(); + + if(++nextZ > max.getBlockZ()) { + + nextX = 0x7fffffff; + } + } + } + return answer; + } + + @Override + public void remove() { + + throw new UnsupportedOperationException(); + } + }; + } + + @Override + public CuboidRegion clone() { + + return (CuboidRegion) super.clone(); + } + + @Override + public Map serialize() { + + Map result = new LinkedHashMap<>(); + result.put("world", world.getName()); + result.put("pos1", pos1.serialize()); + result.put("pos2", pos2.serialize()); + return result; + } + + @SuppressWarnings("unchecked") + public static CuboidRegion deserialize(Map args) { + + World world = Bukkit.getServer().getWorld((String) args.get("world")); + + if(world == null) + throw new IllegalArgumentException("unknown world"); + + RegionVector pos1 = RegionVector.deserialize((Map) args.get("pos1")); + RegionVector pos2 = RegionVector.deserialize((Map) args.get("pos2")); + return new CuboidRegion(world, pos1, pos2); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + CuboidRegion that = (CuboidRegion) o; + + if (pos1 != null ? !pos1.equals(that.pos1) : that.pos1 != null) return false; + return pos2 != null ? pos2.equals(that.pos2) : that.pos2 == null; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + (pos1 != null ? pos1.hashCode() : 0); + result = 31 * result + (pos2 != null ? pos2.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "CuboidRegion{" + + "world=" + world + + ", pos1=" + pos1 + + ", pos2=" + pos2 + + '}'; + } +} diff --git a/src/com/minecraft/moonlake/api/region/FlatRegion.java b/src/com/minecraft/moonlake/api/region/FlatRegion.java new file mode 100644 index 00000000..b3655446 --- /dev/null +++ b/src/com/minecraft/moonlake/api/region/FlatRegion.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2017 The MoonLake Authors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +package com.minecraft.moonlake.api.region; + +public interface FlatRegion extends Region { + + int getMinimumY(); + + int getMaximumY(); +} diff --git a/src/com/minecraft/moonlake/api/region/Region.java b/src/com/minecraft/moonlake/api/region/Region.java new file mode 100644 index 00000000..60102483 --- /dev/null +++ b/src/com/minecraft/moonlake/api/region/Region.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2017 The MoonLake Authors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +package com.minecraft.moonlake.api.region; + +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.entity.Entity; + +import java.util.Iterator; + +public interface Region extends Iterable, ConfigurationSerializable, Cloneable { + + World getWorld(); + + RegionVector getMinimumPoint(); + + RegionVector getMaximumPoint(); + + RegionVector getCenter(); + + int getArea(); + + int getWidth(); + + int getHeight(); + + int getLength(); + + boolean contains(RegionVector vector); + + boolean contains(Location location); + + boolean contains(Entity entity); + + boolean contains(Block block); + + @Override + Iterator iterator(); + + Region clone(); +} diff --git a/src/com/minecraft/moonlake/api/region/RegionBlockVector.java b/src/com/minecraft/moonlake/api/region/RegionBlockVector.java new file mode 100644 index 00000000..7ab28d48 --- /dev/null +++ b/src/com/minecraft/moonlake/api/region/RegionBlockVector.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2017 The MoonLake Authors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +package com.minecraft.moonlake.api.region; + +public class RegionBlockVector extends RegionVector { + + public final static RegionBlockVector ZERO = new RegionBlockVector(0d, 0d, 0d); + + public RegionBlockVector(double x, double y, double z) { + + super(x, y, z); + } + + public RegionBlockVector(float x, float y, float z) { + + super(x, y, z); + } + + public RegionBlockVector(int x, int y, int z) { + + super(x, y, z); + } + + public RegionBlockVector(RegionVector vector) { + + super(vector); + } + + @Override + public boolean equals(Object o) { + if(!(o instanceof RegionVector)) + return false; + RegionVector vector = (RegionVector) o; + return ((int) vector.x == x) && ((int) vector.y == y) && ((int) vector.z == z); + } + + @Override + public int hashCode() { + return (int) x << 19 ^ (int) y << 12 ^ (int) z; + } + + @Override + public String toString() { + return "RegionBlockVector{" + + "x=" + x + + ", y=" + y + + ", z=" + z + + '}'; + } +} diff --git a/src/com/minecraft/moonlake/api/region/RegionVector.java b/src/com/minecraft/moonlake/api/region/RegionVector.java new file mode 100644 index 00000000..d81b0691 --- /dev/null +++ b/src/com/minecraft/moonlake/api/region/RegionVector.java @@ -0,0 +1,346 @@ +/* + * Copyright (C) 2017 The MoonLake Authors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +package com.minecraft.moonlake.api.region; + +import com.minecraft.moonlake.api.VectorConvertible; +import com.minecraft.moonlake.api.player.depend.WorldEditVector; +import com.minecraft.moonlake.util.StringUtil; +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.configuration.serialization.ConfigurationSerialization; +import org.bukkit.util.Vector; + +import java.util.LinkedHashMap; +import java.util.Map; + +public class RegionVector implements VectorConvertible, ConfigurationSerializable, Comparable { + + public final static RegionVector ZERO = new RegionVector(0d, 0d, 0d); + + static { + + ConfigurationSerialization.registerClass(RegionVector.class); + } + + protected final double x; + protected final double y; + protected final double z; + + public RegionVector(double x, double y, double z) { + + this.x = x; + this.y = y; + this.z = z; + } + + public RegionVector(float x, float y, float z) { + + this.x = x; + this.y = y; + this.z = z; + } + + public RegionVector(int x, int y, int z) { + + this.x = x; + this.y = y; + this.z = z; + } + + public RegionVector(RegionVector other) { + + this.x = other.x; + this.y = other.y; + this.z = other.z; + } + + public RegionVector() { + + this.x = 0d; + this.y = 0d; + this.z = 0d; + } + + public double getX() { + + return x; + } + + public double getY() { + + return y; + } + + public double getZ() { + + return z; + } + + public int getBlockX() { + + return (int) Math.round(x); + } + + public int getBlockY() { + + return (int) Math.round(y); + } + + public int getBlockZ() { + + return (int) Math.round(z); + } + + public RegionVector setX(double x) { + + return new RegionVector(x, y, z); + } + + public RegionVector setY(double y) { + + return new RegionVector(x, y, z); + } + + public RegionVector setZ(double z) { + + return new RegionVector(x, y, z); + } + + public RegionVector setX(int x) { + + return new RegionVector(x, y, z); + } + + public RegionVector setY(int y) { + + return new RegionVector(x, y, z); + } + + public RegionVector setZ(int z) { + + return new RegionVector(x, y, z); + } + + public RegionVector add(RegionVector vector) { + + return new RegionVector(x + vector.x, y + vector.y, z + vector.z); + } + + public RegionVector add(double x, double y, double z) { + + return new RegionVector(this.x + x, this.y + y, this.z + z); + } + + public RegionVector add(int x, int y, int z) { + + return new RegionVector(this.x + x, this.y + y, this.z + z); + } + + public RegionVector subtract(RegionVector vector) { + + return new RegionVector(x - vector.x, y - vector.y, z - vector.z); + } + + public RegionVector subtract(double x, double y, double z) { + + return new RegionVector(this.x - x, this.y - y, this.z - z); + } + + public RegionVector subtract(int x, int y, int z) { + + return new RegionVector(this.x - x, this.y - y, this.z - z); + } + + public RegionVector multiply(RegionVector vector) { + + return new RegionVector(x * vector.x, y * vector.y, z * vector.z); + } + + public RegionVector multiply(double x, double y, double z) { + + return new RegionVector(this.x * x, this.y * y, this.z * z); + } + + public RegionVector multiply(int x, int y, int z) { + + return new RegionVector(this.x * x, this.y * y, this.z * z); + } + + public RegionVector multiply(double n) { + + return new RegionVector(this.x * n, this.y * n, this.z * n); + } + + public RegionVector multiply(float n) { + + return new RegionVector(this.x * n, this.y * n, this.z * n); + } + + public RegionVector multiply(int n) { + + return new RegionVector(this.x * n, this.y * n, this.z * n); + } + + public RegionVector divide(RegionVector vector) { + + return new RegionVector(x / vector.x, y / vector.y, z / vector.z); + } + + public RegionVector divide(double x, double y, double z) { + + return new RegionVector(this.x / x, this.y / y, this.z / z); + } + + public RegionVector divide(int x, int y, int z) { + + return new RegionVector(this.x / x, this.y / y, this.z / z); + } + + public RegionVector divide(double n) { + + return new RegionVector(this.x / n, this.y / n, this.z / n); + } + + public RegionVector divide(float n) { + + return new RegionVector(this.x / n, this.y / n, this.z / n); + } + + public RegionVector divide(int n) { + + return new RegionVector(this.x / n, this.y / n, this.z / n); + } + + public double length() { + + return Math.sqrt(lengthSq()); + } + + public double lengthSq() { + + return x * x + y * y + z * z; + } + + public double distance(RegionVector vector) { + + return Math.sqrt(distanceSq(vector)); + } + + public double distanceSq(RegionVector vector) { + + return Math.pow(x - vector.x, 2d) + Math.pow(y - vector.y, 2d) + Math.pow(z - vector.z, 2d); + } + + public RegionVector normalize() { + + return divide(length()); + } + + public RegionVector2D toRegionVector2D() { + + return new RegionVector2D(x, z); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + RegionVector that = (RegionVector) o; + + if (Double.compare(that.x, x) != 0) return false; + if (Double.compare(that.y, y) != 0) return false; + return Double.compare(that.z, z) == 0; + } + + @Override + public int hashCode() { + int result; + long temp; + temp = Double.doubleToLongBits(x); + result = (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(y); + result = 31 * result + (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(z); + result = 31 * result + (int) (temp ^ (temp >>> 32)); + return result; + } + + @Override + public String toString() { + return "RegionVector{" + + "x=" + x + + ", y=" + y + + ", z=" + z + + '}'; + } + + @Override + public int compareTo(RegionVector o) { + + if(x != o.x) + return Double.compare(x, o.x); + if(y != o.y) + return Double.compare(y, o.y); + if(z != o.z) + return Double.compare(z, o.z); + return 0; + } + + @Override + public Map serialize() { + + Map result = new LinkedHashMap<>(); + result.put("x", x); + result.put("y", y); + result.put("z", z); + return result; + } + + public static RegionVector deserialize(Map args) { + + double x = StringUtil.parseDouble(args.get("x")); + double y = StringUtil.parseDouble(args.get("y")); + double z = StringUtil.parseDouble(args.get("z")); + return new RegionVector(x, y, z); + } + + @Override + public Vector asBukkitVector() { + + return new Vector(x, y, z); + } + + @Override + public WorldEditVector asWorldEditVector() { + + return new WorldEditVector(x, y, z); + } + + @Override + public RegionVector asRegionVector() { + + return new RegionVector(this); + } + + @Override + public RegionBlockVector asRegionBlockVector() { + + return new RegionBlockVector(this); + } +} diff --git a/src/com/minecraft/moonlake/api/region/RegionVector2D.java b/src/com/minecraft/moonlake/api/region/RegionVector2D.java new file mode 100644 index 00000000..834282d4 --- /dev/null +++ b/src/com/minecraft/moonlake/api/region/RegionVector2D.java @@ -0,0 +1,290 @@ +/* + * Copyright (C) 2017 The MoonLake Authors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +package com.minecraft.moonlake.api.region; + +import com.minecraft.moonlake.util.StringUtil; +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.configuration.serialization.ConfigurationSerialization; + +import java.util.LinkedHashMap; +import java.util.Map; + +public class RegionVector2D implements ConfigurationSerializable, Comparable { + + public final static RegionVector2D ZERO = new RegionVector2D(0d, 0d); + + static { + + ConfigurationSerialization.registerClass(RegionVector2D.class); + } + + protected final double x; + protected final double z; + + public RegionVector2D(double x, double z) { + + this.x = x; + this.z = z; + } + + public RegionVector2D(float x, float z) { + + this.x = x; + this.z = z; + } + + public RegionVector2D(int x, int z) { + + this.x = x; + this.z = z; + } + + public RegionVector2D(RegionVector2D other) { + + this.x = other.x; + this.z = other.z; + } + + public RegionVector2D() { + + this.x = 0d; + this.z = 0d; + } + + public double getX() { + + return x; + } + + public double getZ() { + + return z; + } + + public int getBlockX() { + + return (int) Math.round(x); + } + + public int getBlockZ() { + + return (int) Math.round(z); + } + + public RegionVector2D setX(double x) { + + return new RegionVector2D(x, z); + } + + public RegionVector2D setZ(double z) { + + return new RegionVector2D(x, z); + } + + public RegionVector2D setX(int x) { + + return new RegionVector2D(x, z); + } + + public RegionVector2D setZ(int z) { + + return new RegionVector2D(x, z); + } + + public RegionVector2D add(RegionVector2D vector) { + + return new RegionVector2D(x + vector.x, z + vector.z); + } + + public RegionVector2D add(double x, double z) { + + return new RegionVector2D(this.x + x, this.z + z); + } + + public RegionVector2D add(int x, int z) { + + return new RegionVector2D(this.x + x, this.z + z); + } + + public RegionVector2D subtract(RegionVector2D vector) { + + return new RegionVector2D(x - vector.x, z - vector.z); + } + + public RegionVector2D subtract(double x, double z) { + + return new RegionVector2D(this.x - x, this.z - z); + } + + public RegionVector2D subtract(int x, int z) { + + return new RegionVector2D(this.x - x, this.z - z); + } + + public RegionVector2D multiply(RegionVector2D vector) { + + return new RegionVector2D(x * vector.x, z * vector.z); + } + + public RegionVector2D multiply(double x, double z) { + + return new RegionVector2D(this.x * x, this.z * z); + } + + public RegionVector2D multiply(int x, int z) { + + return new RegionVector2D(this.x * x, this.z * z); + } + + public RegionVector2D multiply(double n) { + + return new RegionVector2D(this.x * n, this.z * n); + } + + public RegionVector2D multiply(float n) { + + return new RegionVector2D(this.x * n, this.z * n); + } + + public RegionVector2D multiply(int n) { + + return new RegionVector2D(this.x * n, this.z * n); + } + + public RegionVector2D divide(RegionVector2D vector) { + + return new RegionVector2D(x / vector.x, z / vector.z); + } + + public RegionVector2D divide(double x, double z) { + + return new RegionVector2D(this.x / x, this.z / z); + } + + public RegionVector2D divide(int x, int z) { + + return new RegionVector2D(this.x / x, this.z / z); + } + + public RegionVector2D divide(double n) { + + return new RegionVector2D(this.x / n, this.z / n); + } + + public RegionVector2D divide(float n) { + + return new RegionVector2D(this.x / n, this.z / n); + } + + public RegionVector2D divide(int n) { + + return new RegionVector2D(this.x / n, this.z / n); + } + + public double length() { + + return Math.sqrt(lengthSq()); + } + + public double lengthSq() { + + return x * x + z * z; + } + + public double distance(RegionVector2D vector) { + + return Math.sqrt(distanceSq(vector)); + } + + public double distanceSq(RegionVector2D vector) { + + return Math.pow(x - vector.x, 2d) + Math.pow(z - vector.z, 2d); + } + + public RegionVector2D normalize() { + + return divide(length()); + } + + public RegionVector toRegionVector() { + + return toRegionVector(0d); + } + + public RegionVector toRegionVector(double y) { + + return new RegionVector(x, y, z); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + RegionVector2D that = (RegionVector2D) o; + + if (Double.compare(that.x, x) != 0) return false; + return Double.compare(that.z, z) == 0; + } + + @Override + public int hashCode() { + int result; + long temp; + temp = Double.doubleToLongBits(x); + result = (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(z); + result = 31 * result + (int) (temp ^ (temp >>> 32)); + return result; + } + + @Override + public String toString() { + return "RegionVector2D{" + + "x=" + x + + ", z=" + z + + '}'; + } + + @Override + public int compareTo(RegionVector2D o) { + + if(x != o.x) + return Double.compare(x, o.x); + if(z != o.z) + return Double.compare(z, o.z); + return 0; + } + + @Override + public Map serialize() { + + Map result = new LinkedHashMap<>(); + result.put("x", x); + result.put("z", z); + return result; + } + + public static RegionVector2D deserialize(Map args) { + + double x = StringUtil.parseDouble(args.get("x")); + double z = StringUtil.parseDouble(args.get("z")); + return new RegionVector2D(x, z); + } +} From e7192f99e146572b57608850bdfa2dd0fcfdfe7d Mon Sep 17 00:00:00 2001 From: u2g Date: Sat, 14 Jan 2017 22:32:08 +0800 Subject: [PATCH 03/16] =?UTF-8?q?=E6=96=B0=E7=9A=84=E5=8C=BA=E5=9F=9F:=20C?= =?UTF-8?q?ylinderRegion=20(=E5=9C=86=E6=9F=B1=E5=8C=BA=E5=9F=9F)=20?= =?UTF-8?q?=E5=9F=BA=E7=A1=80=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../moonlake/api/region/AbstractRegion.java | 9 + .../moonlake/api/region/CuboidRegion.java | 80 +++++ .../moonlake/api/region/CylinderRegion.java | 275 ++++++++++++++++++ .../moonlake/api/region/FlatRegion.java | 2 + .../region/iterator/FlatRegion3DIterator.java | 96 ++++++ .../region/iterator/FlatRegionIterator.java | 100 +++++++ .../api/region/iterator/RegionIterator.java | 106 +++++++ .../minecraft/moonlake/util/StringUtil.java | 71 ++++- 8 files changed, 735 insertions(+), 4 deletions(-) create mode 100644 src/com/minecraft/moonlake/api/region/CylinderRegion.java create mode 100644 src/com/minecraft/moonlake/api/region/iterator/FlatRegion3DIterator.java create mode 100644 src/com/minecraft/moonlake/api/region/iterator/FlatRegionIterator.java create mode 100644 src/com/minecraft/moonlake/api/region/iterator/RegionIterator.java diff --git a/src/com/minecraft/moonlake/api/region/AbstractRegion.java b/src/com/minecraft/moonlake/api/region/AbstractRegion.java index d0e61e61..8baac3de 100644 --- a/src/com/minecraft/moonlake/api/region/AbstractRegion.java +++ b/src/com/minecraft/moonlake/api/region/AbstractRegion.java @@ -18,6 +18,7 @@ package com.minecraft.moonlake.api.region; +import com.minecraft.moonlake.api.region.iterator.RegionIterator; import com.minecraft.moonlake.exception.MoonLakeException; import com.minecraft.moonlake.validate.Validate; import org.bukkit.Location; @@ -25,6 +26,8 @@ import org.bukkit.block.Block; import org.bukkit.entity.Entity; +import java.util.Iterator; + public abstract class AbstractRegion implements Region { protected final World world; @@ -96,6 +99,12 @@ public boolean contains(Block block) { return contains(Validate.checkNotNull(block).getLocation()); } + @Override + public Iterator iterator() { + + return new RegionIterator(this); + } + @Override public AbstractRegion clone() { diff --git a/src/com/minecraft/moonlake/api/region/CuboidRegion.java b/src/com/minecraft/moonlake/api/region/CuboidRegion.java index e4e817d8..a6f46e6f 100644 --- a/src/com/minecraft/moonlake/api/region/CuboidRegion.java +++ b/src/com/minecraft/moonlake/api/region/CuboidRegion.java @@ -18,6 +18,7 @@ package com.minecraft.moonlake.api.region; +import com.google.common.collect.Iterators; import com.minecraft.moonlake.validate.Validate; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -173,6 +174,85 @@ public CuboidRegion clone() { return (CuboidRegion) super.clone(); } + public Iterable asFlatRegion() { + + return new Iterable() { + + @Override + public Iterator iterator() { + + return new Iterator() { + + private RegionVector min = getMinimumPoint(); + private RegionVector max = getMinimumPoint(); + private int nextX = min.getBlockX(); + private int nextZ = min.getBlockZ(); + + @Override + public boolean hasNext() { + + return nextX != 0x7fffffff; + } + + @Override + public RegionVector2D next() { + + if(!hasNext()) + throw new NoSuchElementException(); + + RegionVector2D answer = new RegionVector2D(nextX, nextZ); + + if(++nextX > max.getBlockX()) { + + nextX = min.getBlockX(); + + if(++nextZ > max.getBlockZ()) { + + nextX = 0x7fffffff; + } + } + return answer; + } + + @Override + public void remove() { + + throw new UnsupportedOperationException(); + } + }; + } + }; + } + + public Iterable getFaces() { + + return new Iterable() { + + private RegionVector min = getMinimumPoint(); + private RegionVector max = getMaximumPoint(); + private Region[] faceRegions = { + + new CuboidRegion(world, pos1.setX(min.getX()), pos2.setX(min.getX())), + new CuboidRegion(world, pos1.setX(max.getX()), pos2.setX(max.getX())), + new CuboidRegion(world, pos1.setZ(min.getZ()), pos2.setZ(min.getZ())), + new CuboidRegion(world, pos1.setZ(max.getZ()), pos2.setZ(max.getZ())), + new CuboidRegion(world, pos1.setY(min.getY()), pos2.setY(min.getY())), + new CuboidRegion(world, pos1.setY(max.getY()), pos2.setY(max.getY())) + }; + + @Override + public Iterator iterator() { + + Iterator[] iterators = new Iterator[faceRegions.length]; + + for(int i = 0; i < faceRegions.length; i++) + iterators[i] = faceRegions[i].iterator(); + + return Iterators.concat(iterators); + } + }; + } + @Override public Map serialize() { diff --git a/src/com/minecraft/moonlake/api/region/CylinderRegion.java b/src/com/minecraft/moonlake/api/region/CylinderRegion.java new file mode 100644 index 00000000..109642e5 --- /dev/null +++ b/src/com/minecraft/moonlake/api/region/CylinderRegion.java @@ -0,0 +1,275 @@ +/* + * Copyright (C) 2017 The MoonLake Authors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +package com.minecraft.moonlake.api.region; + +import com.minecraft.moonlake.api.region.iterator.FlatRegion3DIterator; +import com.minecraft.moonlake.api.region.iterator.FlatRegionIterator; +import com.minecraft.moonlake.util.StringUtil; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.configuration.serialization.ConfigurationSerialization; + +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; + +public class CylinderRegion extends AbstractRegion implements FlatRegion { + + static { + + ConfigurationSerialization.registerClass(CylinderRegion.class); + } + + private RegionVector2D center; + private RegionVector2D radius; + private int minY = 0, maxY = 0; + private boolean hasY = false; + + public CylinderRegion(World world, RegionVector2D center, RegionVector2D radius, int minY, int maxY) { + + super(world); + + this.setCenter(center); + this.setRadius(radius); + this.minY = minY; + this.maxY = maxY; + this.hasY = true; + } + + public CylinderRegion(World world, RegionVector2D center, RegionVector2D radius) { + + this(world, center, radius, 0, 0); + } + + public CylinderRegion(World world, RegionVector center, RegionVector2D radius, int minY, int maxY) { + + super(world); + + this.setCenter(center.toRegionVector2D()); + this.setRadius(radius); + this.minY = minY; + this.maxY = maxY; + this.hasY = true; + } + + public CylinderRegion(World world, RegionVector center, RegionVector2D radius) { + + this(world, center, radius, 0, 0); + } + + @Override + public int getMinimumY() { + + return minY; + } + + @Override + public int getMaximumY() { + + return maxY; + } + + public void setMinimumY(int minY) { + + this.minY = minY; + this.hasY = true; + } + + public void setMaximumY(int maxY) { + + this.maxY = maxY; + this.hasY = true; + } + + @Override + public RegionVector getCenter() { + + return center.toRegionVector((maxY + minY) / 2); + } + + public void setCenter(RegionVector2D center) { + + this.center = center; + } + + public RegionVector2D getRadius() { + + return radius.subtract(0.5d, 0.5d); + } + + public void setRadius(RegionVector2D radius) { + + this.radius = radius.add(0.5d, 0.5d); + } + + public boolean setY(int y) { + + if(!hasY) { + + maxY = minY = y; + return hasY = true; + } + if(y < minY) { + + minY = y; + return true; + } + if(y > maxY) { + + maxY = y; + return true; + } + return false; + } + + @Override + public RegionVector getMinimumPoint() { + + return center.subtract(getRadius()).toRegionVector(minY); + } + + @Override + public RegionVector getMaximumPoint() { + + return center.add(getRadius()).toRegionVector(maxY); + } + + @Override + public int getArea() { + + return (int) Math.floor(radius.getX() * radius.getZ() * Math.PI * getHeight()); + } + + @Override + public int getWidth() { + + return (int) (radius.getX() * 2d); + } + + @Override + public int getHeight() { + + return maxY - minY + 1; + } + + @Override + public int getLength() { + + return (int) (radius.getZ() * 2d); + } + + @Override + public CylinderRegion clone() { + + return (CylinderRegion) super.clone(); + } + + @Override + public boolean contains(RegionVector vector) { + + int blockY = vector.getBlockY(); + + if(blockY < minY || blockY > maxY) + return false; + + return vector.toRegionVector2D().subtract(center).divide(radius).lengthSq() <= 1d; + } + + @Override + public Iterator iterator() { + + return new FlatRegion3DIterator(this); + } + + @Override + public Iterable asFlatRegion() { + + return new Iterable() { + + @Override + public Iterator iterator() { + + return new FlatRegionIterator(CylinderRegion.this); + } + }; + } + + @Override + public Map serialize() { + + Map result = new LinkedHashMap<>(); + result.put("world", world.getName()); + result.put("center", center.serialize()); + result.put("radius", radius.serialize()); + result.put("minY", minY); + result.put("maxY", maxY); + return result; + } + + @SuppressWarnings("unchecked") + public static CylinderRegion deserialize(Map args) { + + World world = Bukkit.getServer().getWorld((String) args.get("world")); + + if(world == null) + throw new IllegalArgumentException("unknown world"); + + RegionVector2D center = RegionVector2D.deserialize((Map) args.get("center")); + RegionVector2D radius = RegionVector2D.deserialize((Map) args.get("radius")); + int minY = StringUtil.parseInt(args.get("minY")); + int maxY = StringUtil.parseInt(args.get("maxY")); + return new CylinderRegion(world, center, radius, minY, maxY); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + CylinderRegion that = (CylinderRegion) o; + + if (minY != that.minY) return false; + if (maxY != that.maxY) return false; + if (hasY != that.hasY) return false; + if (center != null ? !center.equals(that.center) : that.center != null) return false; + return radius != null ? radius.equals(that.radius) : that.radius == null; + } + + @Override + public int hashCode() { + int result = center != null ? center.hashCode() : 0; + result = 31 * result + (radius != null ? radius.hashCode() : 0); + result = 31 * result + minY; + result = 31 * result + maxY; + result = 31 * result + (hasY ? 1 : 0); + return result; + } + + @Override + public String toString() { + return "CylinderRegion{" + + "world=" + world + + ", center=" + center + + ", radius=" + radius + + ", minY=" + minY + + ", maxY=" + maxY + + ", hasY=" + hasY + + '}'; + } +} diff --git a/src/com/minecraft/moonlake/api/region/FlatRegion.java b/src/com/minecraft/moonlake/api/region/FlatRegion.java index b3655446..c1e7f6a8 100644 --- a/src/com/minecraft/moonlake/api/region/FlatRegion.java +++ b/src/com/minecraft/moonlake/api/region/FlatRegion.java @@ -23,4 +23,6 @@ public interface FlatRegion extends Region { int getMinimumY(); int getMaximumY(); + + Iterable asFlatRegion(); } diff --git a/src/com/minecraft/moonlake/api/region/iterator/FlatRegion3DIterator.java b/src/com/minecraft/moonlake/api/region/iterator/FlatRegion3DIterator.java new file mode 100644 index 00000000..d2fe5bbf --- /dev/null +++ b/src/com/minecraft/moonlake/api/region/iterator/FlatRegion3DIterator.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2017 The MoonLake Authors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +package com.minecraft.moonlake.api.region.iterator; + +import com.minecraft.moonlake.api.region.FlatRegion; +import com.minecraft.moonlake.api.region.RegionBlockVector; +import com.minecraft.moonlake.api.region.RegionVector2D; +import com.minecraft.moonlake.validate.Validate; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +public class FlatRegion3DIterator implements Iterator { + + private Iterator flatIterator; + private int minY; + private int maxY; + private RegionVector2D next2D; + private int nextY; + + public FlatRegion3DIterator(FlatRegion region, Iterator flatIterator) { + + Validate.notNull(region); + + this.flatIterator = Validate.checkNotNull(flatIterator); + this.minY = region.getMinimumY(); + this.maxY = region.getMaximumY(); + + if (flatIterator.hasNext()) { + + this.next2D = flatIterator.next(); + } + else { + + this.next2D = null; + } + this.nextY = this.minY; + } + + public FlatRegion3DIterator(FlatRegion region) { + + this(region, region.asFlatRegion().iterator()); + } + + @Override + public boolean hasNext() { + + return next2D != null; + } + + @Override + public RegionBlockVector next() { + + if (!hasNext()) + throw new NoSuchElementException(); + + RegionBlockVector current = new RegionBlockVector(next2D.getBlockX(), nextY, next2D.getBlockZ()); + + if (nextY < maxY) { + + nextY += 1; + } + else if (flatIterator.hasNext()) { + + next2D = flatIterator.next(); + nextY = minY; + } + else { + + next2D = null; + } + return current; + } + + @Override + public void remove() { + + throw new UnsupportedOperationException(); + } +} diff --git a/src/com/minecraft/moonlake/api/region/iterator/FlatRegionIterator.java b/src/com/minecraft/moonlake/api/region/iterator/FlatRegionIterator.java new file mode 100644 index 00000000..226a2c17 --- /dev/null +++ b/src/com/minecraft/moonlake/api/region/iterator/FlatRegionIterator.java @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2017 The MoonLake Authors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +package com.minecraft.moonlake.api.region.iterator; + +import com.minecraft.moonlake.api.region.Region; +import com.minecraft.moonlake.api.region.RegionVector; +import com.minecraft.moonlake.api.region.RegionVector2D; +import com.minecraft.moonlake.validate.Validate; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +public class FlatRegionIterator implements Iterator { + + private Region region; + private int y; + private int minX; + private int nextX; + private int nextZ; + private int maxX; + private int maxZ; + + public FlatRegionIterator(Region region) { + + this.region = Validate.checkNotNull(region); + + RegionVector min = region.getMinimumPoint(); + RegionVector max = region.getMaximumPoint(); + + this.y = min.getBlockY(); + this.minX = min.getBlockX(); + this.nextX = minX; + this.nextZ = min.getBlockZ(); + this.maxX = max.getBlockX(); + this.maxZ = max.getBlockZ(); + + this.forward(); + } + + private void forward() { + + while (hasNext() && !region.contains(new RegionVector(nextX, y, nextZ))) + forwardOne(); + } + + private void forwardOne() { + + if(++nextX <= maxX) + return; + + nextX = minX; + + if(++nextZ <= maxZ) + return; + + nextX = 0x7fffffff; + } + + @Override + public boolean hasNext() { + + return nextX != 0x7fffffff; + } + + @Override + public RegionVector2D next() { + + if(!hasNext()) + throw new NoSuchElementException(); + + RegionVector2D answer = new RegionVector2D(nextX, nextZ); + + forwardOne(); + forward(); + + return answer; + } + + @Override + public void remove() { + + throw new UnsupportedOperationException(); + } +} diff --git a/src/com/minecraft/moonlake/api/region/iterator/RegionIterator.java b/src/com/minecraft/moonlake/api/region/iterator/RegionIterator.java new file mode 100644 index 00000000..c5c87f4f --- /dev/null +++ b/src/com/minecraft/moonlake/api/region/iterator/RegionIterator.java @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2017 The MoonLake Authors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +package com.minecraft.moonlake.api.region.iterator; + +import com.minecraft.moonlake.api.region.Region; +import com.minecraft.moonlake.api.region.RegionBlockVector; +import com.minecraft.moonlake.api.region.RegionVector; +import com.minecraft.moonlake.validate.Validate; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +public class RegionIterator implements Iterator { + + private final Region region; + private final int maxX; + private final int maxY; + private final int maxZ; + private final RegionVector min; + private int nextX; + private int nextY; + private int nextZ; + + public RegionIterator(Region region) { + + this.region = Validate.checkNotNull(region); + + RegionVector max = region.getMaximumPoint(); + + this.maxX = max.getBlockX(); + this.maxY = max.getBlockY(); + this.maxZ = max.getBlockZ(); + this.min = region.getMinimumPoint(); + this.nextX = this.min.getBlockX(); + this.nextY = this.min.getBlockY(); + this.nextZ = this.min.getBlockZ(); + + this.forward(); + } + + private void forward() { + + while(hasNext() && !region.contains(new RegionVector(nextX, nextY, nextZ))) + forwardOne(); + } + + private void forwardOne() { + + if (++this.nextX <= this.maxX) + return; + + this.nextX = this.min.getBlockX(); + + if (++this.nextY <= this.maxY) + return; + + this.nextY = this.min.getBlockY(); + + if (++this.nextZ <= this.maxZ) + return; + + this.nextX = 0x7fffffff; + } + + @Override + public boolean hasNext() { + + return nextX != 0x7fffffff; + } + + @Override + public RegionBlockVector next() { + + if(!hasNext()) + throw new NoSuchElementException(); + + RegionBlockVector answer = new RegionBlockVector(nextX, nextY, nextZ); + + forwardOne(); + forward(); + + return answer; + } + + @Override + public void remove() { + + throw new UnsupportedOperationException(); + } +} diff --git a/src/com/minecraft/moonlake/util/StringUtil.java b/src/com/minecraft/moonlake/util/StringUtil.java index fee653fd..888381ba 100644 --- a/src/com/minecraft/moonlake/util/StringUtil.java +++ b/src/com/minecraft/moonlake/util/StringUtil.java @@ -18,16 +18,17 @@ package com.minecraft.moonlake.util; +import com.minecraft.moonlake.exception.MoonLakeException; import com.minecraft.moonlake.validate.Validate; import org.bukkit.ChatColor; +import org.bukkit.configuration.Configuration; +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import java.lang.reflect.Method; import java.math.BigDecimal; import java.text.MessageFormat; import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.List; +import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -758,4 +759,66 @@ public static String collectionMerge(Collection strCollection, return arrayMerge(collectionToArray(strCollection), mergeChar); } + + /** + * 获取指定配置对象的指定 Bukkit 配置序列化类指定键的对象 + * + * @param clazz 类 + * @param configuration 配置对象 + * @param key 键 + * @param 类型 + * @return 类对象 + * @throws IllegalArgumentException 如果类对象为 {@code null} 则抛出异常 + * @throws IllegalArgumentException 如果配置对象为 {@code null} 则抛出异常 + * @throws IllegalArgumentException 如果键对象为 {@code null} 则抛出异常 + * @throws MoonLakeException 如果配置序列化类没有被注册获取 Map 后没有 {@code deserialize | valueOf} 函数则抛出异常 + */ + public static T deserializeConfigurationClass(Class clazz, Configuration configuration, String key) { + + return deserializeConfigurationClass(clazz, configuration, key, null); + } + + /** + * 获取指定配置对象的指定 Bukkit 配置序列化类指定键的对象 + * + * @param clazz 类 + * @param configuration 配置对象 + * @param key 键 + * @param def 默认值 + * @param 类型 + * @return 类对象 + * @throws IllegalArgumentException 如果类对象为 {@code null} 则抛出异常 + * @throws IllegalArgumentException 如果配置对象为 {@code null} 则抛出异常 + * @throws IllegalArgumentException 如果键对象为 {@code null} 则抛出异常 + * @throws MoonLakeException 如果配置序列化类没有被注册获取 Map 后没有 {@code deserialize | valueOf} 函数则抛出异常 + */ + @SuppressWarnings("unchecked") + public static T deserializeConfigurationClass(Class clazz, Configuration configuration, String key, T def) { + + Validate.notNull(clazz, "The class object is null."); + Validate.notNull(configuration, "The configuration object is null."); + Validate.notNull(key, "The configuration key object is null."); + + Object obj = configuration.get(key, null); + + if(obj == null) + return def; + + if(clazz.isInstance(obj)) + return (T) obj; + else if(obj instanceof Map) { + // map deserialize + try { + Method method = clazz.getMethod("deserialize"); + if(method == null) clazz.getMethod("valueOf"); + if(method == null) throw new MoonLakeException("The value is map, but class not exists 'deserialize' or 'valueOf' method."); + // deserialize + return (T) method.invoke(null, obj); + } catch (Exception e) { + throw new MoonLakeException(e.getMessage(), e); + } + } else { + return def; + } + } } From 0604dbc3a3218f8c3dc134557ec47fa5e20bad47 Mon Sep 17 00:00:00 2001 From: u2g Date: Wed, 18 Jan 2017 22:21:45 +0800 Subject: [PATCH 04/16] =?UTF-8?q?=E5=88=9B=E4=B8=96=E7=A5=9E=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E4=BB=A5=E5=8F=8A=E5=8C=BA=E5=9F=9F=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E7=9A=84=E4=BB=A3=E7=A0=81=E8=B0=83=E6=95=B4=E4=BB=A5=E5=8F=8A?= =?UTF-8?q?javadoc=E7=9A=84=E6=B7=BB=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../moonlake/api/VectorConvertible.java | 27 ++ .../api/player/depend/WorldEditVector.java | 236 +++++++++++++++++ .../moonlake/api/region/AbstractRegion.java | 20 +- .../moonlake/api/region/CuboidRegion.java | 57 ++++ .../moonlake/api/region/CylinderRegion.java | 89 +++++++ .../moonlake/api/region/FlatRegion.java | 25 ++ .../minecraft/moonlake/api/region/README.md | 6 + .../minecraft/moonlake/api/region/Region.java | 79 ++++++ .../api/region/RegionBlockVector.java | 38 +++ .../moonlake/api/region/RegionVector.java | 243 ++++++++++++++++- .../moonlake/api/region/RegionVector2D.java | 245 +++++++++++++++++- .../region/iterator/FlatRegion3DIterator.java | 20 ++ .../region/iterator/FlatRegionIterator.java | 13 + .../api/region/iterator/RegionIterator.java | 13 + 14 files changed, 1106 insertions(+), 5 deletions(-) create mode 100644 src/com/minecraft/moonlake/api/region/README.md diff --git a/src/com/minecraft/moonlake/api/VectorConvertible.java b/src/com/minecraft/moonlake/api/VectorConvertible.java index ec0b574b..a8dd8f27 100644 --- a/src/com/minecraft/moonlake/api/VectorConvertible.java +++ b/src/com/minecraft/moonlake/api/VectorConvertible.java @@ -23,13 +23,40 @@ import com.minecraft.moonlake.api.region.RegionVector; import org.bukkit.util.Vector; +/** + *

VectorConvertible

+ * 矢量可转换接口(详细doc待补充...) + * + * @version 1.0 + * @author Month_Light + */ public interface VectorConvertible { + /** + * 转换为 Bukkit 的矢量对象 + * + * @return Vector + */ Vector asBukkitVector(); + /** + * 转换为 WorldEdit 的矢量对象 + * + * @return WorldEditVector + */ WorldEditVector asWorldEditVector(); + /** + * 转换为区域矢量对象 + * + * @return RegionVector + */ RegionVector asRegionVector(); + /** + * 转换为区域方块矢量对象 + * + * @return RegionBlockVector + */ RegionBlockVector asRegionBlockVector(); } diff --git a/src/com/minecraft/moonlake/api/player/depend/WorldEditVector.java b/src/com/minecraft/moonlake/api/player/depend/WorldEditVector.java index 52d5e5b4..73984ed1 100644 --- a/src/com/minecraft/moonlake/api/player/depend/WorldEditVector.java +++ b/src/com/minecraft/moonlake/api/player/depend/WorldEditVector.java @@ -22,6 +22,7 @@ import com.minecraft.moonlake.api.region.RegionBlockVector; import com.minecraft.moonlake.api.region.RegionVector; import com.minecraft.moonlake.util.StringUtil; +import com.minecraft.moonlake.validate.Validate; import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.configuration.serialization.ConfigurationSerialization; import org.bukkit.util.Vector; @@ -29,8 +30,18 @@ import java.util.LinkedHashMap; import java.util.Map; +/** + *

WorldEditVector

+ * 创世神矢量(详细doc待补充...) + * + * @version 1.0 + * @author Month_Light + */ public class WorldEditVector implements VectorConvertible, ConfigurationSerializable, Comparable { + /** + * 创世神矢量 ZERO 值 + */ public final static WorldEditVector ZERO = new WorldEditVector(0d, 0d, 0d); static { @@ -42,6 +53,13 @@ public class WorldEditVector implements VectorConvertible, ConfigurationSerializ protected final double y; protected final double z; + /** + * 创世神矢量构造函数 + * + * @param x X + * @param y Y + * @param z Z + */ public WorldEditVector(double x, double y, double z) { this.x = x; @@ -49,6 +67,13 @@ public WorldEditVector(double x, double y, double z) { this.z = z; } + /** + * 创世神矢量构造函数 + * + * @param x X + * @param y Y + * @param z Z + */ public WorldEditVector(float x, float y, float z) { this.x = x; @@ -56,6 +81,13 @@ public WorldEditVector(float x, float y, float z) { this.z = z; } + /** + * 创世神矢量构造函数 + * + * @param x X + * @param y Y + * @param z Z + */ public WorldEditVector(int x, int y, int z) { this.x = x; @@ -63,13 +95,24 @@ public WorldEditVector(int x, int y, int z) { this.z = z; } + /** + * 创世神矢量构造函数 + * + * @param other 创世神矢量 + * @throws IllegalArgumentException 如果创世神矢量对象为 {@code null} 则抛出异常 + */ public WorldEditVector(WorldEditVector other) { + Validate.notNull(other, "The other vector object is null."); + this.x = other.x; this.y = other.y; this.z = other.z; } + /** + * 创世神矢量构造函数 + */ public WorldEditVector() { this.x = 0d; @@ -77,176 +120,369 @@ public WorldEditVector() { this.z = 0d; } + /** + * 获取此创世神矢量的 X + * + * @return X + */ public double getX() { return x; } + /** + * 获取此创世神矢量的 Y + * + * @return Y + */ public double getY() { return y; } + /** + * 获取此创世神矢量的 Z + * + * @return Z + */ public double getZ() { return z; } + /** + * 获取此创世神矢量的方块 X + * + * @return 方块 X + */ public int getBlockX() { return (int) Math.round(x); } + /** + * 获取此创世神矢量的方块 Y + * + * @return 方块 Y + */ public int getBlockY() { return (int) Math.round(y); } + /** + * 获取此创世神矢量的方块 Z + * + * @return 方块 Z + */ public int getBlockZ() { return (int) Math.round(z); } + /** + * 设置此创世神矢量的 X + * + * @param x X + */ public WorldEditVector setX(double x) { return new WorldEditVector(x, y, z); } + /** + * 设置此创世神矢量的 Y + * + * @param y Y + */ public WorldEditVector setY(double y) { return new WorldEditVector(x, y, z); } + /** + * 设置此创世神矢量的 Z + * + * @param z Z + */ public WorldEditVector setZ(double z) { return new WorldEditVector(x, y, z); } + /** + * 设置此创世神矢量的 X + * + * @param x X + */ public WorldEditVector setX(int x) { return new WorldEditVector(x, y, z); } + /** + * 设置此创世神矢量的 Y + * + * @param y Y + */ public WorldEditVector setY(int y) { return new WorldEditVector(x, y, z); } + /** + * 设置此创世神矢量的 Z + * + * @param z Z + */ public WorldEditVector setZ(int z) { return new WorldEditVector(x, y, z); } + /** + * 将指定创世神矢量和此创世神矢量相加 + * + * @param vector 创世神矢量 + */ public WorldEditVector add(WorldEditVector vector) { return new WorldEditVector(x + vector.x, y + vector.y, z + vector.z); } + /** + * 将指定 X Y Z 和此创世神矢量相加 + * + * @param x X + * @param y Y + * @param z Z + */ public WorldEditVector add(double x, double y, double z) { return new WorldEditVector(this.x + x, this.y + y, this.z + z); } + /** + * 将指定 X Y Z 和此创世神矢量相加 + * + * @param x X + * @param y Y + * @param z Z + */ public WorldEditVector add(int x, int y, int z) { return new WorldEditVector(this.x + x, this.y + y, this.z + z); } + /** + * 将指定创世神矢量和此创世神矢量相减 + * + * @param vector 创世神矢量 + */ public WorldEditVector subtract(WorldEditVector vector) { return new WorldEditVector(x - vector.x, y - vector.y, z - vector.z); } + /** + * 将指定 X Y Z 和此创世神矢量相减 + * + * @param x X + * @param y Y + * @param z Z + */ public WorldEditVector subtract(double x, double y, double z) { return new WorldEditVector(this.x - x, this.y - y, this.z - z); } + /** + * 将指定 X Y Z 和此创世神矢量相减 + * + * @param x X + * @param y Y + * @param z Z + */ public WorldEditVector subtract(int x, int y, int z) { return new WorldEditVector(this.x - x, this.y - y, this.z - z); } + /** + * 将指定创世神矢量和此创世神矢量相乘 + * + * @param vector 创世神矢量 + */ public WorldEditVector multiply(WorldEditVector vector) { return new WorldEditVector(x * vector.x, y * vector.y, z * vector.z); } + /** + * 将指定 X Y Z 和此创世神矢量相乘 + * + * @param x X + * @param y Y + * @param z Z + */ public WorldEditVector multiply(double x, double y, double z) { return new WorldEditVector(this.x * x, this.y * y, this.z * z); } + /** + * 将指定 X Y Z 和此创世神矢量相乘 + * + * @param x X + * @param y Y + * @param z Z + */ public WorldEditVector multiply(int x, int y, int z) { return new WorldEditVector(this.x * x, this.y * y, this.z * z); } + /** + * 将指定 N 和此创世神矢量相乘 + * + * @param n N + */ public WorldEditVector multiply(double n) { return new WorldEditVector(this.x * n, this.y * n, this.z * n); } + /** + * 将指定 N 和此创世神矢量相乘 + * + * @param n N + */ public WorldEditVector multiply(float n) { return new WorldEditVector(this.x * n, this.y * n, this.z * n); } + /** + * 将指定 N 和此创世神矢量相乘 + * + * @param n N + */ public WorldEditVector multiply(int n) { return new WorldEditVector(this.x * n, this.y * n, this.z * n); } + /** + * 将指定创世神矢量和此创世神矢量相除 + * + * @param vector 创世神矢量 + */ public WorldEditVector divide(WorldEditVector vector) { return new WorldEditVector(x / vector.x, y / vector.y, z / vector.z); } + /** + * 将指定 X Y Z 和此创世神矢量相除 + * + * @param x X + * @param y Y + * @param z Z + */ public WorldEditVector divide(double x, double y, double z) { return new WorldEditVector(this.x / x, this.y / y, this.z / z); } + /** + * 将指定 X Y Z 和此创世神矢量相除 + * + * @param x X + * @param y Y + * @param z Z + */ public WorldEditVector divide(int x, int y, int z) { return new WorldEditVector(this.x / x, this.y / y, this.z / z); } + /** + * 将指定 N 和此创世神矢量相除 + * + * @param n N + */ public WorldEditVector divide(double n) { return new WorldEditVector(this.x / n, this.y / n, this.z / n); } + /** + * 将指定 N 和此创世神矢量相除 + * + * @param n N + */ public WorldEditVector divide(float n) { return new WorldEditVector(this.x / n, this.y / n, this.z / n); } + /** + * 将指定 N 和此创世神矢量相除 + * + * @param n N + */ public WorldEditVector divide(int n) { return new WorldEditVector(this.x / n, this.y / n, this.z / n); } + /** + * 获取此创世神矢量的长度 + * + * @return 长度 + */ public double length() { return Math.sqrt(lengthSq()); } + /** + * 获取此创世神矢量的长度平方 + * + * @return 长度平方 + */ public double lengthSq() { return x * x + y * y + z * z; } + /** + * 获取指定创世神矢量和此创世神矢量的距离 + * + * @param vector 创世神矢量 + * @return 距离 + */ public double distance(WorldEditVector vector) { return Math.sqrt(distanceSq(vector)); } + /** + * 获取指定创世神矢量和此创世神矢量的距离平方 + * + * @param vector 创世神矢量 + * @return 距离平方 + */ public double distanceSq(WorldEditVector vector) { return Math.pow(x - vector.x, 2d) + Math.pow(y - vector.y, 2d) + Math.pow(z - vector.z, 2d); } + /** + * 获取此创世神矢量的归一化 + * + * @return 使归一化的创世神矢量 + */ public WorldEditVector normalize() { return divide(length()); diff --git a/src/com/minecraft/moonlake/api/region/AbstractRegion.java b/src/com/minecraft/moonlake/api/region/AbstractRegion.java index 8baac3de..2832233a 100644 --- a/src/com/minecraft/moonlake/api/region/AbstractRegion.java +++ b/src/com/minecraft/moonlake/api/region/AbstractRegion.java @@ -20,7 +20,6 @@ import com.minecraft.moonlake.api.region.iterator.RegionIterator; import com.minecraft.moonlake.exception.MoonLakeException; -import com.minecraft.moonlake.validate.Validate; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.block.Block; @@ -28,10 +27,25 @@ import java.util.Iterator; +/** + *

AbstractRegion

+ * 区域抽象实现类 + * + * @version 1.0 + * @author Month_Light + * @see Region + * @see CuboidRegion + * @see CylinderRegion + */ public abstract class AbstractRegion implements Region { protected final World world; + /** + * 区域抽象实现类构造函数 + * + * @param world 世界 + */ public AbstractRegion(World world) { this.world = world; @@ -90,13 +104,13 @@ public boolean contains(Location location) { @Override public boolean contains(Entity entity) { - return contains(Validate.checkNotNull(entity).getLocation()); + return entity != null && contains(entity.getLocation()); } @Override public boolean contains(Block block) { - return contains(Validate.checkNotNull(block).getLocation()); + return block != null && contains(block.getLocation()); } @Override diff --git a/src/com/minecraft/moonlake/api/region/CuboidRegion.java b/src/com/minecraft/moonlake/api/region/CuboidRegion.java index a6f46e6f..b4963188 100644 --- a/src/com/minecraft/moonlake/api/region/CuboidRegion.java +++ b/src/com/minecraft/moonlake/api/region/CuboidRegion.java @@ -30,6 +30,15 @@ import java.util.Map; import java.util.NoSuchElementException; +/** + *

CuboidRegion

+ * 长方体区域(详细doc待补充...) + * + * @version 1.0 + * @author Month_Light + * @see Region + * @see FlatRegion + */ public class CuboidRegion extends AbstractRegion implements FlatRegion { static { @@ -40,6 +49,13 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion { private RegionVector pos1; private RegionVector pos2; + /** + * 长方体区域构造函数 + * + * @param world 世界 + * @param pos1 点 1 + * @param pos2 点 2 + */ public CuboidRegion(World world, RegionVector pos1, RegionVector pos2) { super(world); @@ -48,6 +64,15 @@ public CuboidRegion(World world, RegionVector pos1, RegionVector pos2) { this.pos2 = pos2; } + /** + * 长方体区域构造函数 + * + * @param world 世界 + * @param pos1 点 1 + * @param pos2 点 2 + * @throws IllegalArgumentException 如果点1的世界对象不符合参数世界则抛出异常 + * @throws IllegalArgumentException 如果点2的世界对象不符合参数世界则抛出异常 + */ public CuboidRegion(World world, Location pos1, Location pos2) { super(world); @@ -59,23 +84,49 @@ public CuboidRegion(World world, Location pos1, Location pos2) { this.pos2 = new RegionVector(pos2.getX(), pos2.getY(), pos2.getZ()); } + /** + * 获取此长方体区域的点 1 矢量 + * + * @return 点 1 矢量 + */ public RegionVector getPos1() { return pos1; } + /** + * 设置此长方体区域的点 1 矢量 + * + * @param pos1 点 1 矢量 + * @throws IllegalArgumentException 如果点1矢量对象为 {@code null} 则抛出异常 + */ public void setPos1(RegionVector pos1) { + Validate.notNull(pos1, "The pos1 vector object is null."); + this.pos1 = pos1; } + /** + * 获取此长方体区域的点 2 矢量 + * + * @return 点 2 矢量 + */ public RegionVector getPos2() { return pos2; } + /** + * 设置此长方体区域的点 2 矢量 + * + * @param pos2 点 2 矢量 + * @throws IllegalArgumentException 如果点2矢量对象为 {@code null} 则抛出异常 + */ public void setPos2(RegionVector pos2) { + Validate.notNull(pos2, "The pos2 vector object is null."); + this.pos2 = pos2; } @@ -174,6 +225,7 @@ public CuboidRegion clone() { return (CuboidRegion) super.clone(); } + @Override public Iterable asFlatRegion() { return new Iterable() { @@ -224,6 +276,11 @@ public void remove() { }; } + /** + * 获取此长方体区域的所有面的迭代区域方块矢量 + * + * @return 迭代区域方块矢量 + */ public Iterable getFaces() { return new Iterable() { diff --git a/src/com/minecraft/moonlake/api/region/CylinderRegion.java b/src/com/minecraft/moonlake/api/region/CylinderRegion.java index 109642e5..6432e0e7 100644 --- a/src/com/minecraft/moonlake/api/region/CylinderRegion.java +++ b/src/com/minecraft/moonlake/api/region/CylinderRegion.java @@ -21,6 +21,7 @@ import com.minecraft.moonlake.api.region.iterator.FlatRegion3DIterator; import com.minecraft.moonlake.api.region.iterator.FlatRegionIterator; import com.minecraft.moonlake.util.StringUtil; +import com.minecraft.moonlake.validate.Validate; import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.configuration.serialization.ConfigurationSerialization; @@ -29,6 +30,15 @@ import java.util.LinkedHashMap; import java.util.Map; +/** + *

CylinderRegion

+ * 圆柱区域(详细doc待补充...) + * + * @version 1.0 + * @author Month_Light + * @see Region + * @see FlatRegion + */ public class CylinderRegion extends AbstractRegion implements FlatRegion { static { @@ -41,6 +51,15 @@ public class CylinderRegion extends AbstractRegion implements FlatRegion { private int minY = 0, maxY = 0; private boolean hasY = false; + /** + * 圆柱区域构造函数 + * + * @param world 世界 + * @param center 中心点 + * @param radius 半径 + * @param minY 最小 Y + * @param maxY 最大 Y + */ public CylinderRegion(World world, RegionVector2D center, RegionVector2D radius, int minY, int maxY) { super(world); @@ -52,11 +71,27 @@ public CylinderRegion(World world, RegionVector2D center, RegionVector2D radius, this.hasY = true; } + /** + * 圆柱区域构造函数 + * + * @param world 世界 + * @param center 中心点 + * @param radius 半径 + */ public CylinderRegion(World world, RegionVector2D center, RegionVector2D radius) { this(world, center, radius, 0, 0); } + /** + * 圆柱区域构造函数 + * + * @param world 世界 + * @param center 中心点 + * @param radius 半径 + * @param minY 最小 Y + * @param maxY 最大 Y + */ public CylinderRegion(World world, RegionVector center, RegionVector2D radius, int minY, int maxY) { super(world); @@ -68,29 +103,56 @@ public CylinderRegion(World world, RegionVector center, RegionVector2D radius, i this.hasY = true; } + /** + * 圆柱区域构造函数 + * + * @param world 世界 + * @param center 中心点 + * @param radius 半径 + */ public CylinderRegion(World world, RegionVector center, RegionVector2D radius) { this(world, center, radius, 0, 0); } + /** + * 获取此圆柱区域的最小 Y + * + * @return 最小 Y + */ @Override public int getMinimumY() { return minY; } + /** + * 获取此圆柱区域的最大 Y + * + * @return 最大 Y + */ @Override public int getMaximumY() { return maxY; } + /** + * 设置此圆柱区域的最小 Y + * + * @param minY 最小 Y + */ public void setMinimumY(int minY) { this.minY = minY; this.hasY = true; } + /** + * 设置此圆柱区域的最大 Y + * + * @param maxY + */ public void setMaximumY(int maxY) { this.maxY = maxY; @@ -103,21 +165,48 @@ public RegionVector getCenter() { return center.toRegionVector((maxY + minY) / 2); } + /** + * 设置此圆柱区域的中心点 + * + * @param center 中心点 + * @throws IllegalArgumentException 如果中心点对象为 {@code null} 则抛出异常 + */ public void setCenter(RegionVector2D center) { + Validate.notNull(center, "The center vector object is null."); + this.center = center; } + /** + * 获取此圆柱区域的半径矢量 2D + * + * @return 半径矢量 2D + */ public RegionVector2D getRadius() { return radius.subtract(0.5d, 0.5d); } + /** + * 设置此圆柱区域的半径 + * + * @param radius 半径矢量 2D + * @throws IllegalArgumentException 如果半径矢量2D对象为 {@code null} 则抛出异常 + */ public void setRadius(RegionVector2D radius) { + Validate.notNull(radius, "The radius vector object is null."); + this.radius = radius.add(0.5d, 0.5d); } + /** + * 设置此圆柱区域的 Y + * + * @param y Y + * @return 是否成功 + */ public boolean setY(int y) { if(!hasY) { diff --git a/src/com/minecraft/moonlake/api/region/FlatRegion.java b/src/com/minecraft/moonlake/api/region/FlatRegion.java index c1e7f6a8..92176d89 100644 --- a/src/com/minecraft/moonlake/api/region/FlatRegion.java +++ b/src/com/minecraft/moonlake/api/region/FlatRegion.java @@ -18,11 +18,36 @@ package com.minecraft.moonlake.api.region; +/** + *

FlatRegion

+ * 平面区域接口(详细doc待补充...) + * + * @version 1.0 + * @author Month_Light + * @see Region + * @see CuboidRegion + * @see CylinderRegion + */ public interface FlatRegion extends Region { + /** + * 获取此平面区域的最小 Y + * + * @return 最小 Y + */ int getMinimumY(); + /** + * 获取此平面区域的最大 Y + * + * @return 最大 Y + */ int getMaximumY(); + /** + * 获取此平面区域的区域迭代矢量 2D + * + * @return 迭代矢量 2D + */ Iterable asFlatRegion(); } diff --git a/src/com/minecraft/moonlake/api/region/README.md b/src/com/minecraft/moonlake/api/region/README.md new file mode 100644 index 00000000..3ef05162 --- /dev/null +++ b/src/com/minecraft/moonlake/api/region/README.md @@ -0,0 +1,6 @@ +# MoonLake Region Library +## 简介 +月色之湖区域支持库 +## 协议 (LICENSE) +By sk89q [WorldEdit](https://github.com/sk89q/worldedit)
+Modify u2g [MoonLake](https://github.com/u2g/MoonLake) diff --git a/src/com/minecraft/moonlake/api/region/Region.java b/src/com/minecraft/moonlake/api/region/Region.java index 60102483..80c4b42e 100644 --- a/src/com/minecraft/moonlake/api/region/Region.java +++ b/src/com/minecraft/moonlake/api/region/Region.java @@ -26,34 +26,113 @@ import java.util.Iterator; +/** + *

Region

+ * 区域接口(详细doc待补充...) + * + * @version 1.0 + * @author Month_Light + * @see FlatRegion + * @see CuboidRegion + * @see CylinderRegion + */ public interface Region extends Iterable, ConfigurationSerializable, Cloneable { + /** + * 获取此区域的世界 + * + * @return 世界 + */ World getWorld(); + /** + * 获取此区域的最小点矢量 + * + * @return 最小点矢量 + */ RegionVector getMinimumPoint(); + /** + * 获取此区域的最大点矢量 + * + * @return 最大点矢量 + */ RegionVector getMaximumPoint(); + /** + * 获取此区域的中心点矢量 + * + * @return 中心点矢量 + */ RegionVector getCenter(); + /** + * 获取此区域的面积 (总方块数) + * + * @return 面积 + */ int getArea(); + /** + * 获取此区域的宽度 + * + * @return 宽度 + */ int getWidth(); + /** + * 获取此区域的高度 + * + * @return 高度 + */ int getHeight(); + /** + * 获取此区域的长度 + * + * @return 长度 + */ int getLength(); + /** + * 判断指定区域矢量是否存在此区域 + * + * @param vector 区域矢量 + * @return true 则存在 + */ boolean contains(RegionVector vector); + /** + * 判断指定位置是否存在此区域 + * + * @param location 位置 + * @return true 则存在 + */ boolean contains(Location location); + /** + * 判断指定实体的位置是否存在此区域 + * + * @param entity 实体 + * @return true 则存在 + */ boolean contains(Entity entity); + /** + * 判断指定方块的位置是否存在此区域 + * + * @param block 方块 + * @return true 则存在 + */ boolean contains(Block block); @Override Iterator iterator(); + /** + * 克隆此区域对象 + * + * @return 区域 + */ Region clone(); } diff --git a/src/com/minecraft/moonlake/api/region/RegionBlockVector.java b/src/com/minecraft/moonlake/api/region/RegionBlockVector.java index 7ab28d48..2585a44a 100644 --- a/src/com/minecraft/moonlake/api/region/RegionBlockVector.java +++ b/src/com/minecraft/moonlake/api/region/RegionBlockVector.java @@ -18,25 +18,63 @@ package com.minecraft.moonlake.api.region; +/** + *

RegionBlockVector

+ * 区域方块矢量(详细doc待补充...) + * + * @version 1.0 + * @author Month_Light + * @see RegionVector + */ public class RegionBlockVector extends RegionVector { + /** + * 区域方块矢量 ZERO 值 + */ public final static RegionBlockVector ZERO = new RegionBlockVector(0d, 0d, 0d); + /** + * 区域方块矢量构造函数 + * + * @param x X + * @param y Y + * @param z Z + */ public RegionBlockVector(double x, double y, double z) { super(x, y, z); } + /** + * 区域方块矢量构造函数 + * + * @param x X + * @param y Y + * @param z Z + */ public RegionBlockVector(float x, float y, float z) { super(x, y, z); } + /** + * 区域方块矢量构造函数 + * + * @param x X + * @param y Y + * @param z Z + */ public RegionBlockVector(int x, int y, int z) { super(x, y, z); } + /** + * 区域方块矢量构造函数 + * + * @param vector 区域矢量 + * @throws IllegalArgumentException 如果区域矢量对象为 {@code null} 则抛出异常 + */ public RegionBlockVector(RegionVector vector) { super(vector); diff --git a/src/com/minecraft/moonlake/api/region/RegionVector.java b/src/com/minecraft/moonlake/api/region/RegionVector.java index d81b0691..2161f4bd 100644 --- a/src/com/minecraft/moonlake/api/region/RegionVector.java +++ b/src/com/minecraft/moonlake/api/region/RegionVector.java @@ -21,6 +21,7 @@ import com.minecraft.moonlake.api.VectorConvertible; import com.minecraft.moonlake.api.player.depend.WorldEditVector; import com.minecraft.moonlake.util.StringUtil; +import com.minecraft.moonlake.validate.Validate; import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.configuration.serialization.ConfigurationSerialization; import org.bukkit.util.Vector; @@ -28,8 +29,18 @@ import java.util.LinkedHashMap; import java.util.Map; -public class RegionVector implements VectorConvertible, ConfigurationSerializable, Comparable { +/** + *

RegionVector

+ * 区域矢量(详细doc待补充...) + * + * @version 1.0 + * @author Month_Light + */ +public class RegionVector implements VectorConvertible, ConfigurationSerializable, Comparable { + /** + * 区域矢量 ZERO 值 + */ public final static RegionVector ZERO = new RegionVector(0d, 0d, 0d); static { @@ -41,6 +52,13 @@ public class RegionVector implements VectorConvertible, ConfigurationSerializab protected final double y; protected final double z; + /** + * 区域矢量构造函数 + * + * @param x X + * @param y Y + * @param z Z + */ public RegionVector(double x, double y, double z) { this.x = x; @@ -48,6 +66,13 @@ public RegionVector(double x, double y, double z) { this.z = z; } + /** + * 区域矢量构造函数 + * + * @param x X + * @param y Y + * @param z Z + */ public RegionVector(float x, float y, float z) { this.x = x; @@ -55,6 +80,13 @@ public RegionVector(float x, float y, float z) { this.z = z; } + /** + * 区域矢量构造函数 + * + * @param x X + * @param y Y + * @param z Z + */ public RegionVector(int x, int y, int z) { this.x = x; @@ -62,13 +94,24 @@ public RegionVector(int x, int y, int z) { this.z = z; } + /** + * 区域矢量构造函数 + * + * @param other 区域矢量 + * @throws IllegalArgumentException 如果区域矢量对象为 {@code null} 则抛出异常 + */ public RegionVector(RegionVector other) { + Validate.notNull(other, "The other vector object is null."); + this.x = other.x; this.y = other.y; this.z = other.z; } + /** + * 区域矢量构造函数 + */ public RegionVector() { this.x = 0d; @@ -76,181 +119,379 @@ public RegionVector() { this.z = 0d; } + /** + * 获取此区域矢量的 X + * + * @return X + */ public double getX() { return x; } + /** + * 获取此区域矢量的 Y + * + * @return Y + */ public double getY() { return y; } + /** + * 获取此区域矢量的 Z + * + * @return Z + */ public double getZ() { return z; } + /** + * 获取此区域矢量的方块 X + * + * @return 方块 X + */ public int getBlockX() { return (int) Math.round(x); } + /** + * 获取此区域矢量的方块 Y + * + * @return 方块 Y + */ public int getBlockY() { return (int) Math.round(y); } + /** + * 获取此区域矢量的方块 Z + * + * @return 方块 Z + */ public int getBlockZ() { return (int) Math.round(z); } + /** + * 设置此区域矢量的 X + * + * @param x X + */ public RegionVector setX(double x) { return new RegionVector(x, y, z); } + /** + * 设置此区域矢量的 Y + * + * @param y Y + */ public RegionVector setY(double y) { return new RegionVector(x, y, z); } + /** + * 设置此区域矢量的 Z + * + * @param z Z + */ public RegionVector setZ(double z) { return new RegionVector(x, y, z); } + /** + * 设置此区域矢量的 X + * + * @param x X + */ public RegionVector setX(int x) { return new RegionVector(x, y, z); } + /** + * 设置此区域矢量的 Y + * + * @param y Y + */ public RegionVector setY(int y) { return new RegionVector(x, y, z); } + /** + * 设置此区域矢量的 Z + * + * @param z Z + */ public RegionVector setZ(int z) { return new RegionVector(x, y, z); } + /** + * 将指定区域矢量和此区域矢量相加 + * + * @param vector 区域矢量 + */ public RegionVector add(RegionVector vector) { return new RegionVector(x + vector.x, y + vector.y, z + vector.z); } + /** + * 将指定 X Y Z 和此区域矢量相加 + * + * @param x X + * @param y Y + * @param z Z + */ public RegionVector add(double x, double y, double z) { return new RegionVector(this.x + x, this.y + y, this.z + z); } + /** + * 将指定 X Y Z 和此区域矢量相加 + * + * @param x X + * @param y Y + * @param z Z + */ public RegionVector add(int x, int y, int z) { return new RegionVector(this.x + x, this.y + y, this.z + z); } + /** + * 将指定区域矢量和此区域矢量相减 + * + * @param vector 区域矢量 + */ public RegionVector subtract(RegionVector vector) { return new RegionVector(x - vector.x, y - vector.y, z - vector.z); } + /** + * 将指定 X Y Z 和此区域矢量相减 + * + * @param x X + * @param y Y + * @param z Z + */ public RegionVector subtract(double x, double y, double z) { return new RegionVector(this.x - x, this.y - y, this.z - z); } + /** + * 将指定 X Y Z 和此区域矢量相减 + * + * @param x X + * @param y Y + * @param z Z + */ public RegionVector subtract(int x, int y, int z) { return new RegionVector(this.x - x, this.y - y, this.z - z); } + /** + * 将指定区域矢量和此区域矢量相乘 + * + * @param vector 区域矢量 + */ public RegionVector multiply(RegionVector vector) { return new RegionVector(x * vector.x, y * vector.y, z * vector.z); } + /** + * 将指定 X Y Z 和此区域矢量相乘 + * + * @param x X + * @param y Y + * @param z Z + */ public RegionVector multiply(double x, double y, double z) { return new RegionVector(this.x * x, this.y * y, this.z * z); } + /** + * 将指定 X Y Z 和此区域矢量相乘 + * + * @param x X + * @param y Y + * @param z Z + */ public RegionVector multiply(int x, int y, int z) { return new RegionVector(this.x * x, this.y * y, this.z * z); } + /** + * 将指定 N 和此区域矢量相乘 + * + * @param n N + */ public RegionVector multiply(double n) { return new RegionVector(this.x * n, this.y * n, this.z * n); } + /** + * 将指定 N 和此区域矢量相乘 + * + * @param n N + */ public RegionVector multiply(float n) { return new RegionVector(this.x * n, this.y * n, this.z * n); } + /** + * 将指定 N 和此区域矢量相乘 + * + * @param n N + */ public RegionVector multiply(int n) { return new RegionVector(this.x * n, this.y * n, this.z * n); } + /** + * 将指定区域矢量和此区域矢量相除 + * + * @param vector 区域矢量 + */ public RegionVector divide(RegionVector vector) { return new RegionVector(x / vector.x, y / vector.y, z / vector.z); } + /** + * 将指定 X Y Z 和此区域矢量相除 + * + * @param x X + * @param y Y + * @param z Z + */ public RegionVector divide(double x, double y, double z) { return new RegionVector(this.x / x, this.y / y, this.z / z); } + /** + * 将指定 X Y Z 和此区域矢量相除 + * + * @param x X + * @param y Y + * @param z Z + */ public RegionVector divide(int x, int y, int z) { return new RegionVector(this.x / x, this.y / y, this.z / z); } + /** + * 将指定 N 和此区域矢量相除 + * + * @param n N + */ public RegionVector divide(double n) { return new RegionVector(this.x / n, this.y / n, this.z / n); } + /** + * 将指定 N 和此区域矢量相除 + * + * @param n N + */ public RegionVector divide(float n) { return new RegionVector(this.x / n, this.y / n, this.z / n); } + /** + * 将指定 N 和此区域矢量相除 + * + * @param n N + */ public RegionVector divide(int n) { return new RegionVector(this.x / n, this.y / n, this.z / n); } + /** + * 获取此区域矢量的长度 + * + * @return 长度 + */ public double length() { return Math.sqrt(lengthSq()); } + /** + * 获取此区域矢量的长度平方 + * + * @return 长度平方 + */ public double lengthSq() { return x * x + y * y + z * z; } + /** + * 获取指定区域矢量和此区域矢量的距离 + * + * @param vector 区域矢量 + * @return 距离 + */ public double distance(RegionVector vector) { return Math.sqrt(distanceSq(vector)); } + /** + * 获取指定区域矢量和此区域矢量的距离平方 + * + * @param vector 区域矢量 + * @return 距离平方 + */ public double distanceSq(RegionVector vector) { return Math.pow(x - vector.x, 2d) + Math.pow(y - vector.y, 2d) + Math.pow(z - vector.z, 2d); } + /** + * 获取此区域矢量的归一化 + * + * @return 使归一化的区域矢量 + */ public RegionVector normalize() { return divide(length()); } + /** + * 将此区域矢量转换为区域矢量 2D + * + * @return 区域矢量 2D + */ public RegionVector2D toRegionVector2D() { return new RegionVector2D(x, z); diff --git a/src/com/minecraft/moonlake/api/region/RegionVector2D.java b/src/com/minecraft/moonlake/api/region/RegionVector2D.java index 834282d4..be0ec080 100644 --- a/src/com/minecraft/moonlake/api/region/RegionVector2D.java +++ b/src/com/minecraft/moonlake/api/region/RegionVector2D.java @@ -18,15 +18,29 @@ package com.minecraft.moonlake.api.region; +import com.minecraft.moonlake.api.VectorConvertible; +import com.minecraft.moonlake.api.player.depend.WorldEditVector; import com.minecraft.moonlake.util.StringUtil; +import com.minecraft.moonlake.validate.Validate; import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.configuration.serialization.ConfigurationSerialization; +import org.bukkit.util.Vector; import java.util.LinkedHashMap; import java.util.Map; -public class RegionVector2D implements ConfigurationSerializable, Comparable { +/** + *

RegionVector2D

+ * 区域矢量 2D(详细doc待补充...) + * + * @version 1.0 + * @author Month_Light + */ +public class RegionVector2D implements VectorConvertible, ConfigurationSerializable, Comparable { + /** + * 区域矢量 2D ZERO 值 + */ public final static RegionVector2D ZERO = new RegionVector2D(0d, 0d); static { @@ -37,196 +51,401 @@ public class RegionVector2D implements ConfigurationSerializable, Comparable args) { double z = StringUtil.parseDouble(args.get("z")); return new RegionVector2D(x, z); } + + @Override + public Vector asBukkitVector() { + + return new Vector(x, 0d, z); + } + + @Override + public WorldEditVector asWorldEditVector() { + + return new WorldEditVector(x, 0d, z); + } + + @Override + public RegionVector asRegionVector() { + + return new RegionVector(x, 0d, z); + } + + @Override + public RegionBlockVector asRegionBlockVector() { + + return new RegionBlockVector(x, 0d, z); + } } diff --git a/src/com/minecraft/moonlake/api/region/iterator/FlatRegion3DIterator.java b/src/com/minecraft/moonlake/api/region/iterator/FlatRegion3DIterator.java index d2fe5bbf..454d275d 100644 --- a/src/com/minecraft/moonlake/api/region/iterator/FlatRegion3DIterator.java +++ b/src/com/minecraft/moonlake/api/region/iterator/FlatRegion3DIterator.java @@ -26,6 +26,13 @@ import java.util.Iterator; import java.util.NoSuchElementException; +/** + *

FlatRegion3DIterator

+ * 平面区域方块矢量迭代器 + * + * @version 1.0 + * @author Month_Light + */ public class FlatRegion3DIterator implements Iterator { private Iterator flatIterator; @@ -34,6 +41,13 @@ public class FlatRegion3DIterator implements Iterator { private RegionVector2D next2D; private int nextY; + /** + * 平面区域方块矢量迭代器构造函数 + * + * @param region 区域对象 + * @param flatIterator 平面区域矢量 2D 迭代器对象 + * @throws IllegalArgumentException 如果区域对象为 {@code null} 则抛出异常 + */ public FlatRegion3DIterator(FlatRegion region, Iterator flatIterator) { Validate.notNull(region); @@ -53,6 +67,12 @@ public FlatRegion3DIterator(FlatRegion region, Iterator flatIter this.nextY = this.minY; } + /** + * 平面区域方块矢量迭代器构造函数 + * + * @param region 区域对象 + * @throws IllegalArgumentException 如果区域对象为 {@code null} 则抛出异常 + */ public FlatRegion3DIterator(FlatRegion region) { this(region, region.asFlatRegion().iterator()); diff --git a/src/com/minecraft/moonlake/api/region/iterator/FlatRegionIterator.java b/src/com/minecraft/moonlake/api/region/iterator/FlatRegionIterator.java index 226a2c17..cef774b4 100644 --- a/src/com/minecraft/moonlake/api/region/iterator/FlatRegionIterator.java +++ b/src/com/minecraft/moonlake/api/region/iterator/FlatRegionIterator.java @@ -26,6 +26,13 @@ import java.util.Iterator; import java.util.NoSuchElementException; +/** + *

FlatRegionIterator

+ * 平面区域矢量 2D 迭代器 + * + * @version 1.0 + * @author Month_Light + */ public class FlatRegionIterator implements Iterator { private Region region; @@ -36,6 +43,12 @@ public class FlatRegionIterator implements Iterator { private int maxX; private int maxZ; + /** + * 平面区域矢量 2D 迭代器构造函数 + * + * @param region 区域对象 + * @throws IllegalArgumentException 如果区域对象为 {@code null} 则抛出异常 + */ public FlatRegionIterator(Region region) { this.region = Validate.checkNotNull(region); diff --git a/src/com/minecraft/moonlake/api/region/iterator/RegionIterator.java b/src/com/minecraft/moonlake/api/region/iterator/RegionIterator.java index c5c87f4f..2da4b858 100644 --- a/src/com/minecraft/moonlake/api/region/iterator/RegionIterator.java +++ b/src/com/minecraft/moonlake/api/region/iterator/RegionIterator.java @@ -26,6 +26,13 @@ import java.util.Iterator; import java.util.NoSuchElementException; +/** + *

RegionIterator

+ * 区域方块矢量迭代器 + * + * @version 1.0 + * @author Month_Light + */ public class RegionIterator implements Iterator { private final Region region; @@ -37,6 +44,12 @@ public class RegionIterator implements Iterator { private int nextY; private int nextZ; + /** + * 区域方块矢量迭代器构造函数 + * + * @param region 区域 + * @throws IllegalArgumentException 如果区域对象为 {@code null} 则抛出异常 + */ public RegionIterator(Region region) { this.region = Validate.checkNotNull(region); From 02d8264ef006e19222065ba9385afc0595f0f6e7 Mon Sep 17 00:00:00 2001 From: u2g Date: Thu, 19 Jan 2017 00:38:17 +0800 Subject: [PATCH 05/16] =?UTF-8?q?=E4=B8=80=E4=BA=9B=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=8C=85=E7=9A=84=E5=85=BC=E5=AE=B9=E6=80=A7=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E5=92=8C=E6=9B=B4=E6=94=B9,=20=E4=BB=A5=E5=8F=8A=20InventoryPl?= =?UTF-8?q?ayer=20=E6=96=B0=E5=A2=9E=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/player/SimpleMoonLakePlayer.java | 6 + .../api/player/SimpleMoonLakePlayer_v1_8.java | 7 ++ .../api/player/SimpleMoonLakePlayer_v1_9.java | 6 + .../api/player/inventory/InventoryPlayer.java | 7 ++ .../nms/packet/PacketPlayOutAbilities.java | 36 ++++++ .../packet/PacketPlayOutEntityEquipment.java | 109 +++++++++++++++--- .../nms/packet/PacketPlayOutHeldItemSlot.java | 10 ++ .../nms/packet/PacketPlayOutRespawn.java | 63 ++++++++++ 8 files changed, 229 insertions(+), 15 deletions(-) diff --git a/src/com/minecraft/moonlake/api/player/SimpleMoonLakePlayer.java b/src/com/minecraft/moonlake/api/player/SimpleMoonLakePlayer.java index 1778803f..0a2f6711 100644 --- a/src/com/minecraft/moonlake/api/player/SimpleMoonLakePlayer.java +++ b/src/com/minecraft/moonlake/api/player/SimpleMoonLakePlayer.java @@ -148,6 +148,12 @@ public void setSpectatorTarget(Entity entity) { } + @Override + public ItemStack getItemInHand() { + + return null; + } + @Override public ItemStack getItemInMainHand() { diff --git a/src/com/minecraft/moonlake/api/player/SimpleMoonLakePlayer_v1_8.java b/src/com/minecraft/moonlake/api/player/SimpleMoonLakePlayer_v1_8.java index 8857cd3a..b1c54280 100644 --- a/src/com/minecraft/moonlake/api/player/SimpleMoonLakePlayer_v1_8.java +++ b/src/com/minecraft/moonlake/api/player/SimpleMoonLakePlayer_v1_8.java @@ -157,6 +157,13 @@ public void setSpectatorTarget(Entity entity) { throw new IllegalBukkitVersionException("The method not support 1.8 and old version."); } + @Override + @SuppressWarnings("deprecation") // 移除过期警告, 1.8 版本此函数没有警告 + public ItemStack getItemInHand() { + + return getBukkitPlayer().getItemInHand(); + } + @Override public ItemStack getItemInMainHand() { diff --git a/src/com/minecraft/moonlake/api/player/SimpleMoonLakePlayer_v1_9.java b/src/com/minecraft/moonlake/api/player/SimpleMoonLakePlayer_v1_9.java index eec24d8d..1882aff8 100644 --- a/src/com/minecraft/moonlake/api/player/SimpleMoonLakePlayer_v1_9.java +++ b/src/com/minecraft/moonlake/api/player/SimpleMoonLakePlayer_v1_9.java @@ -158,6 +158,12 @@ public void setSpectatorTarget(Entity entity) { getBukkitPlayer().setSpectatorTarget(entity); } + @Override + public ItemStack getItemInHand() { + + return getItemInMainHand(); + } + @Override public ItemStack getItemInMainHand() { diff --git a/src/com/minecraft/moonlake/api/player/inventory/InventoryPlayer.java b/src/com/minecraft/moonlake/api/player/inventory/InventoryPlayer.java index 46895b9e..c740bb4a 100644 --- a/src/com/minecraft/moonlake/api/player/inventory/InventoryPlayer.java +++ b/src/com/minecraft/moonlake/api/player/inventory/InventoryPlayer.java @@ -52,6 +52,13 @@ public interface InventoryPlayer extends InventoryHolder { */ void closeInventory(); + /** + * 获取此玩家的手中物品 (注: 如果 Bukkit 版本为 1.9 或更高不建议使用此函数) + * + * @return 手中物品 + */ + ItemStack getItemInHand(); + /** * 获取此玩家的主手中物品 * diff --git a/src/com/minecraft/moonlake/nms/packet/PacketPlayOutAbilities.java b/src/com/minecraft/moonlake/nms/packet/PacketPlayOutAbilities.java index aa07f784..3ef64be6 100644 --- a/src/com/minecraft/moonlake/nms/packet/PacketPlayOutAbilities.java +++ b/src/com/minecraft/moonlake/nms/packet/PacketPlayOutAbilities.java @@ -18,12 +18,14 @@ package com.minecraft.moonlake.nms.packet; +import com.minecraft.moonlake.exception.MoonLakeException; import com.minecraft.moonlake.nms.packet.exception.PacketException; import com.minecraft.moonlake.nms.packet.exception.PacketInitializeException; import com.minecraft.moonlake.property.BooleanProperty; import com.minecraft.moonlake.property.FloatProperty; import com.minecraft.moonlake.property.SimpleBooleanProperty; import com.minecraft.moonlake.property.SimpleFloatProperty; +import com.minecraft.moonlake.validate.Validate; import org.bukkit.entity.Player; import java.lang.reflect.Field; @@ -41,6 +43,8 @@ public class PacketPlayOutAbilities extends PacketAbstract CLASS_PACKETPLAYOUTABILITIES; private final static Class CLASS_PLAYERABILITIES; + private final static Class CLASS_ENTITYHUMAN; + private final static Field FIELD_ABILITIES; private final static Field FIELD_ISINVULNERABLE; private final static Field FIELD_ISFLYING; private final static Field FIELD_CANFLY; @@ -55,6 +59,8 @@ public class PacketPlayOutAbilities extends PacketAbstract= 9 ? PackageType.MINECRAFT_SERVER.getClass("EnumItemSlot") : null; // 1.8 没有这个类 CLASS_ITEMSTACK = PackageType.MINECRAFT_SERVER.getClass("ItemStack"); METHOD_ASNMSCOPY = getMethod(CLASS_CRAFTITEMSTACK, "asNMSCopy", ItemStack.class); METHOD_VALUEOF = getMethod(CLASS_ENUMITEMSLOT, "valueOf", String.class); @@ -67,7 +72,7 @@ public class PacketPlayOutEntityEquipment extends PacketAbstract equipmentSolt; + private ObjectProperty equipmentSlot; private ObjectProperty itemStack; /** @@ -104,7 +109,7 @@ public PacketPlayOutEntityEquipment(Entity entity, EquipmentSlot equipmentSlot, public PacketPlayOutEntityEquipment(int entityId, EquipmentSlot equipmentSlot, ItemStack itemStack) { this.entityId = new SimpleIntegerProperty(entityId); - this.equipmentSolt = new SimpleObjectProperty<>(equipmentSlot); + this.equipmentSlot = new SimpleObjectProperty<>(equipmentSlot); this.itemStack = new SimpleObjectProperty<>(itemStack); } @@ -125,7 +130,7 @@ public IntegerProperty getEntityId() { */ public ObjectProperty getEquipmentSlot() { - return equipmentSolt; + return equipmentSlot; } /** @@ -145,13 +150,33 @@ public void send(Player... players) throws PacketException { try { - Object enumItemSolt = METHOD_VALUEOF.invoke(null, equipmentSolt.get().name()); - Object nmsItemStack = METHOD_ASNMSCOPY.invoke(null, itemStack.get()); + if(getServerVersionNumber() >= 9) { + // 1.9 以及更高的发送 + Object enumItemSolt = METHOD_VALUEOF.invoke(null, equipmentSlot.get().name()); + Object nmsItemStack = METHOD_ASNMSCOPY.invoke(null, itemStack.get()); - Constructor packetConstructor = getConstructor(CLASS_PACKETPLAYOUTENTITYEQUIPMENT, int.class, CLASS_ENUMITEMSLOT, CLASS_ITEMSTACK); - Object packet = packetConstructor.newInstance(entityId.get(), enumItemSolt, nmsItemStack); + Constructor packetConstructor = getConstructor(CLASS_PACKETPLAYOUTENTITYEQUIPMENT, int.class, CLASS_ENUMITEMSLOT, CLASS_ITEMSTACK); + Object packet = packetConstructor.newInstance(entityId.get(), enumItemSolt, nmsItemStack); - PacketReflect.get().send(players, packet); + PacketReflect.get().send(players, packet); + } else { + // 由于 1.8 是没有 EnumItemSlot 的所以不处理副手 + EquipmentSlot slot = equipmentSlot.get(); + if(slot == EquipmentSlot.OFFHAND) return; + + // 低版本的发送 + Object nmsItemStack = METHOD_ASNMSCOPY.invoke(null, itemStack.get()); + + // 获取最终的装备槽位 Id + // 如果槽位不为主手的话, 那么由于 1.8 没有副手, 这个枚举占用一个值, 则减去 1 + int slotId = slot != EquipmentSlot.MAINHAND ? slot.getId() - 1 : slot.getId(); + + // 低版本第二个参数是 int 类型, 装备槽位的 Id + Constructor packetConstructor = getConstructor(CLASS_PACKETPLAYOUTENTITYEQUIPMENT, int.class, int.class, CLASS_ITEMSTACK); + Object packet = packetConstructor.newInstance(entityId.get(), slotId, nmsItemStack); + + PacketReflect.get().send(players, packet); + } } catch (Exception e) { @@ -159,6 +184,38 @@ public void send(Player... players) throws PacketException { } } + /** + * 更新并发送指定玩家的所有装备数据包 + * + * @param player 玩家 + * @param recipients 接收者 + * @throws IllegalArgumentException 如果玩家对象为 {@code null} 则抛出异常 + * @throws IllegalArgumentException 如果接收者对象为 {@code null} 则抛出异常 + */ + public static void updateEquipments(Player player, Player[] recipients) { + + Validate.notNull(player, "The player object is null."); + Validate.notNull(recipients, "The recipient players object is null."); + + // 转换为 MoonLakePlayer 好做兼容性工作 23333 + MoonLakePlayer moonLakePlayer = PlayerManager.adapter(player); + List ppoeeList = new ArrayList<>(); + + ppoeeList.add(new PacketPlayOutEntityEquipment(player, EquipmentSlot.MAINHAND, moonLakePlayer.getItemInHand())); + + if(getServerVersionNumber() >= 9) // 1.9+ 可以发送副手 + ppoeeList.add(new PacketPlayOutEntityEquipment(player, EquipmentSlot.OFFHAND, moonLakePlayer.getItemInOffHand())); + + ppoeeList.add(new PacketPlayOutEntityEquipment(player, EquipmentSlot.HEAD, moonLakePlayer.getInventory().getHelmet())); + ppoeeList.add(new PacketPlayOutEntityEquipment(player, EquipmentSlot.CHEST, moonLakePlayer.getInventory().getChestplate())); + ppoeeList.add(new PacketPlayOutEntityEquipment(player, EquipmentSlot.LEGS, moonLakePlayer.getInventory().getLeggings())); + ppoeeList.add(new PacketPlayOutEntityEquipment(player, EquipmentSlot.FEET, moonLakePlayer.getInventory().getBoots())); + + // 最后发送 + for(Packet packet : ppoeeList) + packet.send(recipients); + } + /** *

EquipmentSlot

* 装备槽位类型 @@ -171,27 +228,49 @@ public enum EquipmentSlot { /** * 装备槽位类型: 主手 */ - MAINHAND, + MAINHAND(0), /** * 装备槽位类型: 副手 */ - OFFHAND, + OFFHAND(1), /** * 装备槽位类型: 脚 */ - FEET, + FEET(2), /** * 装备槽位类型: 腿 */ - LEGS, + LEGS(3), /** * 装备槽位类型: 胸 */ - CHEST, + CHEST(4), /** * 装备槽位类型: 头 */ - HEAD, + HEAD(5), ; + + private int id; + + /** + * 装备槽位类型构造函数 + * + * @param id Id + */ + EquipmentSlot(int id) { + + this.id = id; + } + + /** + * 获取此装备槽位类型的 Id + * + * @return Id + */ + public int getId() { + + return id; + } } } diff --git a/src/com/minecraft/moonlake/nms/packet/PacketPlayOutHeldItemSlot.java b/src/com/minecraft/moonlake/nms/packet/PacketPlayOutHeldItemSlot.java index c1ae4d5b..b85a1d72 100644 --- a/src/com/minecraft/moonlake/nms/packet/PacketPlayOutHeldItemSlot.java +++ b/src/com/minecraft/moonlake/nms/packet/PacketPlayOutHeldItemSlot.java @@ -73,6 +73,16 @@ public PacketPlayOutHeldItemSlot(int heldItemSlot) { this.heldItemSlot = new SimpleIntegerProperty(heldItemSlot); } + /** + * 数据包输出手持物品槽位构造函数 + * + * @param player 玩家 + */ + public PacketPlayOutHeldItemSlot(Player player) { + + this.heldItemSlot = new SimpleIntegerProperty(player.getInventory().getHeldItemSlot()); + } + /** * 获取此数据包输出手持物品槽位的槽位 * diff --git a/src/com/minecraft/moonlake/nms/packet/PacketPlayOutRespawn.java b/src/com/minecraft/moonlake/nms/packet/PacketPlayOutRespawn.java index 1f6ca047..81905292 100644 --- a/src/com/minecraft/moonlake/nms/packet/PacketPlayOutRespawn.java +++ b/src/com/minecraft/moonlake/nms/packet/PacketPlayOutRespawn.java @@ -25,6 +25,7 @@ import com.minecraft.moonlake.property.SimpleIntegerProperty; import com.minecraft.moonlake.property.SimpleObjectProperty; import org.bukkit.GameMode; +import org.bukkit.World; import org.bukkit.entity.Player; import java.lang.reflect.Field; @@ -94,6 +95,68 @@ public PacketPlayOutRespawn() { this(WorldDimension.OVERWORLD, WorldDifficulty.PEACEFUL, GameMode.SURVIVAL, WorldType.NORMAL); } + /** + * 数据包输出重生类构造函数 + * + * @param world 世界 + * @param gameMode 游戏模式 + */ + public PacketPlayOutRespawn(World world, GameMode gameMode) { + + WorldDimension worldDimension; + WorldDifficulty worldDifficulty; + WorldType worldType; + + // dimension + switch (world.getEnvironment()) { + case NORMAL: + worldDimension = WorldDimension.OVERWORLD; break; + case NETHER: + worldDimension = WorldDimension.NETHER; break; + case THE_END: + worldDimension = WorldDimension.THE_END; break; + default: + worldDimension = WorldDimension.OVERWORLD; break; + } + + // difficulty + switch (world.getDifficulty()) { + case PEACEFUL: + worldDifficulty = WorldDifficulty.PEACEFUL; break; + case EASY: + worldDifficulty = WorldDifficulty.EASY; break; + case NORMAL: + worldDifficulty = WorldDifficulty.NORMAL; break; + case HARD: + worldDifficulty = WorldDifficulty.HARD; break; + default: + worldDifficulty = WorldDifficulty.EASY; break; + } + + // worldtype + switch (world.getWorldType()) { + case NORMAL: + worldType = WorldType.NORMAL; break; + case AMPLIFIED: + worldType = WorldType.AMPLIFIED; break; + case CUSTOMIZED: + worldType = WorldType.CUSTOMIZED; break; + case FLAT: + worldType = WorldType.FLAT; break; + case LARGE_BIOMES: + worldType = WorldType.LARGE_BIOMES; break; + case VERSION_1_1: + worldType = WorldType.NORMAL_1_1; break; + default: + worldType = WorldType.NORMAL; break; + } + + this.worldDimensionId = new SimpleIntegerProperty(worldDimension.getId()); + this.worldDifficulty = new SimpleObjectProperty<>(worldDifficulty); + this.worldGameMode = new SimpleObjectProperty<>(gameMode); + this.worldType = new SimpleObjectProperty<>(worldType); + } + /** * 数据包输出重生类构造函数 * From c0d3a6d0d31cf59f3553e795b474e39a5710480c Mon Sep 17 00:00:00 2001 From: u2g Date: Thu, 19 Jan 2017 16:20:43 +0800 Subject: [PATCH 06/16] =?UTF-8?q?=E9=83=A8=E5=88=86=E7=B1=BB=E7=9A=84?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=94=B9=E5=8A=A8=E3=80=81=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E3=80=81=E4=BF=AE=E5=A4=8D=E7=AD=89,=20=E4=BB=A5=E5=8F=8A?= =?UTF-8?q?=E4=B8=80=E4=BA=9B=E6=96=B0=E5=87=BD=E6=95=B0=E7=9A=84=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/com/minecraft/moonlake/MoonLakeAPI.java | 28 ++++++- .../minecraft/moonlake/MoonLakePlugin.java | 14 +--- src/com/minecraft/moonlake/api/MoonLake.java | 5 +- .../api/anvil/AnvilWindowClickEvent.java | 6 +- .../api/item/firework/FireworkBuilder.java | 4 +- .../api/player/DependEconomyPlayer.java | 2 +- .../api/player/DependEconomyVaultPlayer.java | 2 +- .../api/player/DependPermissionsExPlayer.java | 2 +- .../api/player/DependWorldEditPlayer.java | 2 +- .../api/player/PlayerExpressionWrapped.java | 6 +- .../api/player/PlayerLibraryFactorys.java | 16 ++-- .../minecraft/moonlake/enums/Enchantment.java | 13 ---- .../minecraft/moonlake/event/EventHelper.java | 37 ++++++++++ .../minecraft/moonlake/logger/MLogger.java | 2 + .../moonlake/logger/MLoggerWrapped.java | 3 + .../moonlake/manager/ItemManager.java | 73 ++++++++++++++++++- 16 files changed, 164 insertions(+), 51 deletions(-) diff --git a/src/com/minecraft/moonlake/MoonLakeAPI.java b/src/com/minecraft/moonlake/MoonLakeAPI.java index 6748fcbe..e859da4d 100644 --- a/src/com/minecraft/moonlake/MoonLakeAPI.java +++ b/src/com/minecraft/moonlake/MoonLakeAPI.java @@ -45,7 +45,6 @@ import com.minecraft.moonlake.event.EventHelper; import com.minecraft.moonlake.exception.MoonLakeException; import com.minecraft.moonlake.execute.Consumer; -import com.minecraft.moonlake.logger.MLogger; import com.minecraft.moonlake.mysql.MySQLConnection; import com.minecraft.moonlake.mysql.MySQLFactory; import com.minecraft.moonlake.mysql.exception.MySQLInitializeException; @@ -79,6 +78,7 @@ import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.Future; +import java.util.logging.Logger; /** *

MoonLakeAPI

@@ -118,9 +118,9 @@ public static MoonLakePlugin getMoonLake() { * * @return 日志对象 */ - public static MLogger getMLogger() { + public static Logger getLogger() { - return moonlake.getMLogger(); + return moonlake.getLogger(); } /** @@ -1622,6 +1622,28 @@ public static void callEvent(MoonLakeEvent event) { EventHelper.callEvent(event); } + /** + * 调用事件帮助器异步触发指定事件 + * + * @param plugin 插件 + * @param event 事件 + */ + public static void callEventAsync(Plugin plugin, Event event) { + + EventHelper.callEventAsync(plugin, event); + } + + /** + * 调用事件帮助器异步触发指定事件 + * + * @param plugin 插件 + * @param event 事件 + */ + public static void callEventAsync(Plugin plugin, MoonLakeEvent event) { + + EventHelper.callEventAsync(plugin, event); + } + /** * 调用事件帮助器注册事件监听器 * diff --git a/src/com/minecraft/moonlake/MoonLakePlugin.java b/src/com/minecraft/moonlake/MoonLakePlugin.java index 1db537f4..cf856ea3 100644 --- a/src/com/minecraft/moonlake/MoonLakePlugin.java +++ b/src/com/minecraft/moonlake/MoonLakePlugin.java @@ -22,8 +22,6 @@ import com.minecraft.moonlake.api.packet.listener.PacketListenerFactory; import com.minecraft.moonlake.api.player.PlayerLibraryFactorys; import com.minecraft.moonlake.exception.MoonLakeException; -import com.minecraft.moonlake.logger.MLogger; -import com.minecraft.moonlake.logger.MLoggerWrapped; import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.java.JavaPlugin; @@ -74,7 +72,6 @@ */ public class MoonLakePlugin extends JavaPlugin implements MoonLake { - private final MLogger mLogger; private final PluginDescriptionFile description; private MoonLakePluginConfig configuration; @@ -86,7 +83,6 @@ public class MoonLakePlugin extends JavaPlugin implements MoonLake { public MoonLakePlugin() { this.description = getDescription(); - this.mLogger = new MLoggerWrapped("MoonLake"); } @Override @@ -103,7 +99,7 @@ public void onEnable() { // load class this.loadClass(); - this.getMLogger().info("月色之湖核心 API 插件 v" + getPluginVersion() + " 成功加载."); + this.getLogger().info("月色之湖核心 API 插件 v" + getPluginVersion() + " 成功加载."); } private void loadClass() { @@ -113,7 +109,7 @@ private void loadClass() { // load PacketListenerFactory class Class.forName(PacketListenerFactory.class.getName()); - this.getMLogger().info("月色之湖数据包通道监听器(PCL)成功加载."); + this.getLogger().info("月色之湖数据包通道监听器(PCL)成功加载."); } // load PlayerLibraryFactorys class to register listener Class.forName(PlayerLibraryFactorys.class.getName()); @@ -143,12 +139,6 @@ public static MoonLake getInstances() { return MAIN; } - @Override - public MLogger getMLogger() { - - return mLogger; - } - @Override public MoonLakePlugin getPlugin() { diff --git a/src/com/minecraft/moonlake/api/MoonLake.java b/src/com/minecraft/moonlake/api/MoonLake.java index b8af45fe..69e76434 100644 --- a/src/com/minecraft/moonlake/api/MoonLake.java +++ b/src/com/minecraft/moonlake/api/MoonLake.java @@ -20,7 +20,8 @@ import com.minecraft.moonlake.MoonLakePlugin; import com.minecraft.moonlake.MoonLakePluginConfig; -import com.minecraft.moonlake.logger.MLogger; + +import java.util.logging.Logger; /** *
@@ -40,7 +41,7 @@ public interface MoonLake extends MoonLakeCore, MoonLakeInfo, BukkitInfo { * * @return 日志对象 */ - MLogger getMLogger(); + Logger getLogger(); /** * 获取月色之湖插件对象 diff --git a/src/com/minecraft/moonlake/api/anvil/AnvilWindowClickEvent.java b/src/com/minecraft/moonlake/api/anvil/AnvilWindowClickEvent.java index 66228276..776b901f 100644 --- a/src/com/minecraft/moonlake/api/anvil/AnvilWindowClickEvent.java +++ b/src/com/minecraft/moonlake/api/anvil/AnvilWindowClickEvent.java @@ -40,14 +40,14 @@ public class AnvilWindowClickEvent extends AnvilWindowAbstractEvent implements C * * @param clicked 点击者玩家 * @param anvilWindow 铁砧窗口对象 - * @param clickSolt 点击的槽位 + * @param clickSlot 点击的槽位 * @param clickItemStack 点击的物品栈 */ - public AnvilWindowClickEvent(Player clicked, AnvilWindow anvilWindow, AnvilWindowSlot clickSolt, ItemStack clickItemStack) { + public AnvilWindowClickEvent(Player clicked, AnvilWindow anvilWindow, AnvilWindowSlot clickSlot, ItemStack clickItemStack) { super(clicked, anvilWindow); - this.clickSlot = clickSolt; + this.clickSlot = clickSlot; this.clickItemStack = clickItemStack; } diff --git a/src/com/minecraft/moonlake/api/item/firework/FireworkBuilder.java b/src/com/minecraft/moonlake/api/item/firework/FireworkBuilder.java index 306a2e35..94e0919b 100644 --- a/src/com/minecraft/moonlake/api/item/firework/FireworkBuilder.java +++ b/src/com/minecraft/moonlake/api/item/firework/FireworkBuilder.java @@ -19,6 +19,7 @@ package com.minecraft.moonlake.api.item.firework; import com.minecraft.moonlake.builder.Builder; +import com.minecraft.moonlake.builder.UncertainParamBuilder; import org.bukkit.Color; import org.bukkit.Location; import org.bukkit.inventory.ItemStack; @@ -46,7 +47,7 @@ * @version 1.0 * @author Month_Light */ -public interface FireworkBuilder extends Builder { +public interface FireworkBuilder extends Builder, UncertainParamBuilder { /** * 构建并获取物品栈对象 @@ -62,6 +63,7 @@ public interface FireworkBuilder extends Builder { * @param join 烟花构建器 * @return ItemStack */ + @Override ItemStack build(FireworkBuilder... join); /** diff --git a/src/com/minecraft/moonlake/api/player/DependEconomyPlayer.java b/src/com/minecraft/moonlake/api/player/DependEconomyPlayer.java index 566f26da..9d59a989 100644 --- a/src/com/minecraft/moonlake/api/player/DependEconomyPlayer.java +++ b/src/com/minecraft/moonlake/api/player/DependEconomyPlayer.java @@ -54,7 +54,7 @@ public DependEconomyPlayer() throws CannotDependException { } this.moonLakeEconomy = ((EconomyPlugin) plugin).getEconomy(); - MoonLakeAPI.getMLogger().info("Success hook 'MoonLakeEconomy' plugin, 'EconomyPlayer' interface be use."); + MoonLakeAPI.getLogger().info("Success hook 'MoonLakeEconomy' plugin, 'EconomyPlayer' interface be use."); } /** diff --git a/src/com/minecraft/moonlake/api/player/DependEconomyVaultPlayer.java b/src/com/minecraft/moonlake/api/player/DependEconomyVaultPlayer.java index 200d574d..b39d5945 100644 --- a/src/com/minecraft/moonlake/api/player/DependEconomyVaultPlayer.java +++ b/src/com/minecraft/moonlake/api/player/DependEconomyVaultPlayer.java @@ -62,7 +62,7 @@ public DependEconomyVaultPlayer() throws CannotDependException { throw new CannotDependException("The depend 'Vault' plugin 'Economy' service provider object is null."); } - MoonLakeAPI.getMLogger().info("Success hook 'Vault' plugin 'Economy' service provider, 'EconomyVaultPlayer' interface be use."); + MoonLakeAPI.getLogger().info("Success hook 'Vault' plugin 'Economy' service provider, 'EconomyVaultPlayer' interface be use."); } /** diff --git a/src/com/minecraft/moonlake/api/player/DependPermissionsExPlayer.java b/src/com/minecraft/moonlake/api/player/DependPermissionsExPlayer.java index 404d86a5..2c59b206 100644 --- a/src/com/minecraft/moonlake/api/player/DependPermissionsExPlayer.java +++ b/src/com/minecraft/moonlake/api/player/DependPermissionsExPlayer.java @@ -66,7 +66,7 @@ public DependPermissionsExPlayer() throws CannotDependException, CannotDependVer } this.permissionManager = ((PermissionsEx) plugin).getPermissionsManager(); - MoonLakeAPI.getMLogger().info("Success hook 'PermissionsEx' plugin, 'PermissionsExPlayer' interface be use."); + MoonLakeAPI.getLogger().info("Success hook 'PermissionsEx' plugin, 'PermissionsExPlayer' interface be use."); } /** diff --git a/src/com/minecraft/moonlake/api/player/DependWorldEditPlayer.java b/src/com/minecraft/moonlake/api/player/DependWorldEditPlayer.java index 581071ff..36040aeb 100644 --- a/src/com/minecraft/moonlake/api/player/DependWorldEditPlayer.java +++ b/src/com/minecraft/moonlake/api/player/DependWorldEditPlayer.java @@ -56,7 +56,7 @@ public DependWorldEditPlayer() throws CannotDependException, CannotDependVersion } this.worldEdit = ((WorldEditPlugin) plugin); - MoonLakeAPI.getMLogger().info("Success hook 'WorldEdit' plugin, 'WorldEditPlayer' interface be use."); + MoonLakeAPI.getLogger().info("Success hook 'WorldEdit' plugin, 'WorldEditPlayer' interface be use."); } /** diff --git a/src/com/minecraft/moonlake/api/player/PlayerExpressionWrapped.java b/src/com/minecraft/moonlake/api/player/PlayerExpressionWrapped.java index 316b7045..375a5f44 100644 --- a/src/com/minecraft/moonlake/api/player/PlayerExpressionWrapped.java +++ b/src/com/minecraft/moonlake/api/player/PlayerExpressionWrapped.java @@ -18,9 +18,11 @@ package com.minecraft.moonlake.api.player; -import com.minecraft.moonlake.MoonLakePlugin; +import com.minecraft.moonlake.MoonLakeAPI; import org.bukkit.Material; +import java.util.logging.Level; + /** *

PlayerExpressionWrapped

* 玩家支持库实现包装类 @@ -47,7 +49,7 @@ public PlayerExpressionWrapped() { } catch (Exception e) { - MoonLakePlugin.getInstances().getMLogger().error("The player library nms or item cooldown exception: " + e.getMessage()); + MoonLakeAPI.getLogger().log(Level.SEVERE, "The player library nms or item cooldown exception: ", e); e.printStackTrace(); } diff --git a/src/com/minecraft/moonlake/api/player/PlayerLibraryFactorys.java b/src/com/minecraft/moonlake/api/player/PlayerLibraryFactorys.java index 88c9d5e3..94e2714d 100644 --- a/src/com/minecraft/moonlake/api/player/PlayerLibraryFactorys.java +++ b/src/com/minecraft/moonlake/api/player/PlayerLibraryFactorys.java @@ -28,6 +28,8 @@ import org.bukkit.event.server.PluginEnableEvent; import org.bukkit.plugin.Plugin; +import java.util.logging.Level; + /** *

PlayerLibraryFactorys

* 玩家支持库静态工厂类 @@ -83,9 +85,7 @@ else if(pluginName.equals("WorldEdit") && dependWorldEditPlayerHook == null) { } catch (Exception e) { - MoonLakeAPI.getMLogger().error("The hook '" + pluginName + "' plugin failed, exception info: "); - - e.printStackTrace(); + MoonLakeAPI.getLogger().log(Level.SEVERE, "The hook '" + pluginName + "' plugin failed, exception info: ", e); } } @@ -100,33 +100,33 @@ public void onDisable(PluginDisableEvent event) { dependEconomyPlayer = null; dependEconomyPlayerHook = null; - MoonLakeAPI.getMLogger().warn("The unhook 'MoonLakeEconomy' plugin, now 'EconomyPlayer' interface is unavailable."); + MoonLakeAPI.getLogger().warning("The unhook 'MoonLakeEconomy' plugin, now 'EconomyPlayer' interface is unavailable."); } else if(pluginName.equals("PermissionsEx") && dependPermissionsExPlayerHook != null) { // Unhook PermissionsEx dependPermissionsExPlayer = null; dependPermissionsExPlayerHook = null; - MoonLakeAPI.getMLogger().warn("The unhook 'PermissionsEx' plugin, now 'PermissionsExPlayer' interface is unavailable."); + MoonLakeAPI.getLogger().warning("The unhook 'PermissionsEx' plugin, now 'PermissionsExPlayer' interface is unavailable."); } else if(pluginName.equals("Vault") && dependEconomyVaultPlayerHook != null) { // Unhook Vault Economy dependEconomyVaultPlayer = null; dependEconomyVaultPlayerHook = null; - MoonLakeAPI.getMLogger().warn("The unhook 'Vault' plugin 'Economy' module, now 'EconomyVaultPlayer' interface is unavailable."); + MoonLakeAPI.getLogger().warning("The unhook 'Vault' plugin 'Economy' module, now 'EconomyVaultPlayer' interface is unavailable."); } else if(pluginName.equals("WorldEdit") && dependWorldEditPlayerHook != null) { // Unhook WorldEdit dependWorldEditPlayer = null; dependWorldEditPlayerHook = null; - MoonLakeAPI.getMLogger().warn("The unhook 'WorldEdit' plugin, now 'WorldEditPlayer' interface is unavailable."); + MoonLakeAPI.getLogger().warning("The unhook 'WorldEdit' plugin, now 'WorldEditPlayer' interface is unavailable."); } } }, MoonLakeAPI.getMoonLake()); /// - MoonLakeAPI.getMLogger().info("月色之湖玩家支持库的依赖监听器成功加载."); + MoonLakeAPI.getLogger().info("月色之湖玩家支持库的依赖监听器成功加载."); } /** diff --git a/src/com/minecraft/moonlake/enums/Enchantment.java b/src/com/minecraft/moonlake/enums/Enchantment.java index 5f8de3e5..1ba2e717 100644 --- a/src/com/minecraft/moonlake/enums/Enchantment.java +++ b/src/com/minecraft/moonlake/enums/Enchantment.java @@ -240,19 +240,6 @@ public org.bukkit.enchantments.Enchantment as() { throw new IllegalBukkitVersionException("The bukkit version not support enchantment: " + id); } } - // - // 貌似这两个 1.11 新增加的附魔效果用 getByName 获取到的是 null - // 看了底层代码 switch case 没有这两个 name 的判断, 所以暂时这样 - if(id == 10) { - - return org.bukkit.enchantments.Enchantment.BINDING_CURSE; - } - else if(id == 71) { - - return org.bukkit.enchantments.Enchantment.VANISHING_CURSE; - } - /// - //return org.bukkit.enchantments.Enchantment.getById(id); return org.bukkit.enchantments.Enchantment.getByName(name); } diff --git a/src/com/minecraft/moonlake/event/EventHelper.java b/src/com/minecraft/moonlake/event/EventHelper.java index bdfd9515..5bb620a8 100644 --- a/src/com/minecraft/moonlake/event/EventHelper.java +++ b/src/com/minecraft/moonlake/event/EventHelper.java @@ -20,6 +20,7 @@ import com.minecraft.moonlake.api.event.MoonLakeEvent; import com.minecraft.moonlake.api.event.MoonLakeListener; +import com.minecraft.moonlake.task.TaskHelper; import org.bukkit.Bukkit; import org.bukkit.event.Event; import org.bukkit.event.EventPriority; @@ -63,6 +64,42 @@ public static void callEvent(MoonLakeEvent event) { Bukkit.getServer().getPluginManager().callEvent(event); } + /** + * 调用事件帮助器异步触发指定事件 + * + * @param plugin 插件 + * @param event 事件 + */ + public static void callEventAsync(Plugin plugin, Event event) { + + TaskHelper.runTaskAsync(plugin, new Runnable() { + + @Override + public void run() { + + callEvent(event); + } + }); + } + + /** + * 调用事件帮助器异步触发指定事件 + * + * @param plugin 插件 + * @param event 事件 + */ + public static void callEventAsync(Plugin plugin, MoonLakeEvent event) { + + TaskHelper.runTaskAsync(plugin, new Runnable() { + + @Override + public void run() { + + callEvent(event); + } + }); + } + /** * 调用事件帮助器注册事件监听器 * diff --git a/src/com/minecraft/moonlake/logger/MLogger.java b/src/com/minecraft/moonlake/logger/MLogger.java index 5d548af4..c394c87c 100644 --- a/src/com/minecraft/moonlake/logger/MLogger.java +++ b/src/com/minecraft/moonlake/logger/MLogger.java @@ -24,7 +24,9 @@ * * @version 1.0 * @author Month_Light + * @deprecated 已过时, 将于 v2.0 删除. */ +@Deprecated public interface MLogger { /** diff --git a/src/com/minecraft/moonlake/logger/MLoggerWrapped.java b/src/com/minecraft/moonlake/logger/MLoggerWrapped.java index abcd439a..85f0caff 100644 --- a/src/com/minecraft/moonlake/logger/MLoggerWrapped.java +++ b/src/com/minecraft/moonlake/logger/MLoggerWrapped.java @@ -30,7 +30,10 @@ * * @version 1.0 * @author Month_Light + * @deprecated 已过时, 将于 v2.0 删除. */ +@Deprecated +@SuppressWarnings("deprecation") public final class MLoggerWrapped implements MLogger { private final ReadOnlyStringProperty prefixProperty; diff --git a/src/com/minecraft/moonlake/manager/ItemManager.java b/src/com/minecraft/moonlake/manager/ItemManager.java index 9e2320c8..e5c6041d 100644 --- a/src/com/minecraft/moonlake/manager/ItemManager.java +++ b/src/com/minecraft/moonlake/manager/ItemManager.java @@ -21,6 +21,7 @@ import com.minecraft.moonlake.MoonLakeAPI; import com.minecraft.moonlake.api.item.AttributeModify; import com.minecraft.moonlake.api.item.ItemBuilder; +import com.minecraft.moonlake.api.item.ItemLibraryFactorys; import com.minecraft.moonlake.api.nbt.NBTCompound; import com.minecraft.moonlake.api.nbt.NBTFactory; import com.minecraft.moonlake.data.Conversions; @@ -273,6 +274,72 @@ public static boolean compareNull(ItemStack source, ItemStack target) { return source == null && target == null; } + /** + * 判断指定物品栈是否为工具类型 + * + * @param itemStack 物品栈 + * @return true 则物品栈类型为工具 + */ + public static boolean isTool(ItemStack itemStack) { + + return !isAir(itemStack) && ItemLibraryFactorys.item().isTool(itemStack); + } + + /** + * 判断指定物品栈是否为武器类型 + * + * @param itemStack 物品栈 + * @return true 则物品栈类型为武器 + */ + public static boolean isWeapon(ItemStack itemStack) { + + return !isAir(itemStack) && ItemLibraryFactorys.item().isWeapon(itemStack); + } + + /** + * 判断指定物品栈是否为护甲类型 + * + * @param itemStack 物品栈 + * @return true 则物品栈类型为护甲 + */ + public static boolean isArmor(ItemStack itemStack) { + + return !isAir(itemStack) && ItemLibraryFactorys.item().isArmor(itemStack); + } + + /** + * 判断指定物品栈是否为皮革护甲类型 + * + * @param itemStack 物品栈 + * @return true 则物品栈类型为皮革护甲 + */ + public static boolean isLeatherArmor(ItemStack itemStack) { + + return !isAir(itemStack) && ItemLibraryFactorys.item().isLeatherArmor(itemStack); + } + + /** + * 判断指定物品栈是否为药水类型 + * + * @param itemStack 物品栈 + * @return true 则物品栈类型为药水 + */ + public static boolean isPotion(ItemStack itemStack) { + + return !isAir(itemStack) && ItemLibraryFactorys.item().isPotion(itemStack); + } + + /** + * 判断指定物品栈是否为书类型 + * + * @param itemStack 物品栈 + * @return true 则物品栈类型为书 + */ + public static boolean isWrittenBook(ItemStack itemStack) { + + return !isAir(itemStack) && ItemLibraryFactorys.item().isWrittenBook(itemStack); + } + /** * 将物品栈对象数据序列化为字符串数据 * @@ -644,7 +711,7 @@ public static ItemStack deserializeFromFile(File file) { enchantment = Enchantment.getByName(key.toUpperCase()); if(enchantment == null) - MoonLakeAPI.getMLogger().error("The deserialize from file '" + file.getName() + "' key 'Enchantment' error enchantment: " + key); + MoonLakeAPI.getLogger().warning("The deserialize from file '" + file.getName() + "' key 'Enchantment' error enchantment: " + key); else itemBuilder.addEnchantment(enchantment, level); } @@ -670,7 +737,7 @@ public static ItemStack deserializeFromFile(File file) { } if(itemFlag == null) - MoonLakeAPI.getMLogger().error("The deserialize from file '" + file.getName() + "' key 'HideFlag' error flag: " + hideFlag); + MoonLakeAPI.getLogger().warning("The deserialize from file '" + file.getName() + "' key 'HideFlag' error flag: " + hideFlag); else itemBuilder.addFlags(itemFlag); } @@ -700,7 +767,7 @@ public static ItemStack deserializeFromFile(File file) { if(attType == null) { - MoonLakeAPI.getMLogger().error("The deserialize from file '" + file.getName() + "' key 'AttributeModifiers' error type: " + key); + MoonLakeAPI.getLogger().warning("The deserialize from file '" + file.getName() + "' key 'AttributeModifiers' error type: " + key); continue; } double value = yml.getDouble("AttributeModifiers." + key + ".Value", -1d); From 2af0947c2fc507eebe5d818ee11560a1a90e40fe Mon Sep 17 00:00:00 2001 From: u2g Date: Thu, 19 Jan 2017 17:05:14 +0800 Subject: [PATCH 07/16] =?UTF-8?q?=E5=8C=BA=E5=9F=9F=E7=9A=84=E5=87=BD?= =?UTF-8?q?=E6=95=B0=20contains=20=E8=B0=83=E6=95=B4=E4=BB=A5=E5=8F=8A?= =?UTF-8?q?=E6=96=B0=E7=9A=84=E5=8C=BA=E5=9F=9F=20Ellipsoid=20(=E6=A4=AD?= =?UTF-8?q?=E5=9C=86)=20=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../moonlake/api/region/CuboidRegion.java | 2 +- .../moonlake/api/region/CylinderRegion.java | 2 + .../moonlake/api/region/EllipsoidRegion.java | 201 ++++++++++++++++++ 3 files changed, 204 insertions(+), 1 deletion(-) create mode 100644 src/com/minecraft/moonlake/api/region/EllipsoidRegion.java diff --git a/src/com/minecraft/moonlake/api/region/CuboidRegion.java b/src/com/minecraft/moonlake/api/region/CuboidRegion.java index b4963188..6e847691 100644 --- a/src/com/minecraft/moonlake/api/region/CuboidRegion.java +++ b/src/com/minecraft/moonlake/api/region/CuboidRegion.java @@ -145,7 +145,7 @@ public RegionVector getMaximumPoint() { @Override public boolean contains(RegionVector vector) { - Validate.notNull(vector, "The vector object is null."); + if(vector == null) return false; double x = vector.getX(); double y = vector.getY(); diff --git a/src/com/minecraft/moonlake/api/region/CylinderRegion.java b/src/com/minecraft/moonlake/api/region/CylinderRegion.java index 6432e0e7..c8e32619 100644 --- a/src/com/minecraft/moonlake/api/region/CylinderRegion.java +++ b/src/com/minecraft/moonlake/api/region/CylinderRegion.java @@ -272,6 +272,8 @@ public CylinderRegion clone() { @Override public boolean contains(RegionVector vector) { + if(vector == null) return false; + int blockY = vector.getBlockY(); if(blockY < minY || blockY > maxY) diff --git a/src/com/minecraft/moonlake/api/region/EllipsoidRegion.java b/src/com/minecraft/moonlake/api/region/EllipsoidRegion.java new file mode 100644 index 00000000..0f13ff7c --- /dev/null +++ b/src/com/minecraft/moonlake/api/region/EllipsoidRegion.java @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2017 The MoonLake Authors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +package com.minecraft.moonlake.api.region; + +import com.minecraft.moonlake.validate.Validate; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.configuration.serialization.ConfigurationSerialization; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + *

EllipsoidRegion

+ * 椭圆区域(详细doc待补充...) + * + * @version 1.0 + * @author Month_Light + * @see Region + */ +public class EllipsoidRegion extends AbstractRegion { + + static { + + ConfigurationSerialization.registerClass(EllipsoidRegion.class); + } + + private RegionVector center; + private RegionVector radius; + + /** + * 椭圆区域构造函数 + * + * @param world 世界 + * @param center 中心点 + * @param radius 半径 + */ + public EllipsoidRegion(World world, RegionVector center, RegionVector radius) { + + super(world); + + this.setCenter(center); + this.setRadius(radius); + } + + @Override + public RegionVector getMinimumPoint() { + + return center.subtract(getRadius()); + } + + @Override + public RegionVector getMaximumPoint() { + + return center.add(getRadius()); + } + + @Override + public boolean contains(RegionVector vector) { + + return vector != null && vector.subtract(center).divide(radius).lengthSq() <= 1d; + } + + @Override + public int getArea() { + + return (int) Math.floor(4.1887902047863905d * radius.getX() * radius.getY() * radius.getZ()); + } + + @Override + public int getWidth() { + + return (int) (radius.getX() * 2d); + } + + @Override + public int getHeight() { + + return (int) (radius.getY() * 2d); + } + + @Override + public int getLength() { + + return (int) (radius.getZ() * 2d); + } + + @Override + public RegionVector getCenter() { + + return center; + } + + @Override + public EllipsoidRegion clone() { + + return (EllipsoidRegion) super.clone(); + } + + /** + * 设置此椭圆区域的中心点 + * + * @param center 中心点 + * @throws IllegalArgumentException 如果中心点对象为 {@code null} 则抛出异常 + */ + public void setCenter(RegionVector center) { + + Validate.notNull(center, "The center vector object is null."); + + this.center = center; + } + + /** + * 获取此椭圆区域的半径矢量 + * + * @return 半径矢量 + */ + public RegionVector getRadius() { + + return radius.subtract(0.5d, 0.5d, 0.5d); + } + + /** + * 设置此椭圆区域的半径矢量 + * + * @param radius 半径矢量 + * @throws IllegalArgumentException 如果半径矢量对象为 {@code null} 则抛出异常 + */ + public void setRadius(RegionVector radius) { + + Validate.notNull(radius, "The radius vector object is null."); + + this.radius = radius.add(0.5d, 0.5d, 0.5d); + } + + @Override + public Map serialize() { + + Map result = new LinkedHashMap<>(); + result.put("world", world.getName()); + result.put("center", center.serialize()); + result.put("radius", radius.serialize()); + return result; + } + + @SuppressWarnings("unchecked") + public static EllipsoidRegion deserialize(Map args) { + + World world = Bukkit.getServer().getWorld((String) args.get("world")); + + if(world == null) + throw new IllegalArgumentException("unknown world"); + + RegionVector center = RegionVector.deserialize((Map) args.get("center")); + RegionVector radius = RegionVector.deserialize((Map) args.get("radius")); + return new EllipsoidRegion(world, center, radius); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + EllipsoidRegion that = (EllipsoidRegion) o; + + if (!center.equals(that.center)) return false; + return radius.equals(that.radius); + } + + @Override + public int hashCode() { + int result = center.hashCode(); + result = 31 * result + radius.hashCode(); + return result; + } + + @Override + public String toString() { + return "EllipsoidRegion{" + + "world=" + world + + ", center=" + center + + ", radius=" + radius + + '}'; + } +} From f227a3e77ee5583694f05b0bb45b598ac7a9050d Mon Sep 17 00:00:00 2001 From: u2g Date: Sun, 22 Jan 2017 20:52:46 +0800 Subject: [PATCH 08/16] =?UTF-8?q?=E6=96=B0=E7=9A=84=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=8C=85=20PacketPlayOutBlockChange=20=E5=AE=8C=E6=88=90?= =?UTF-8?q?=E4=BB=A5=E5=8F=8A=E6=96=B9=E5=9D=97=E4=BD=8D=E7=BD=AE=E7=9A=84?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nms/packet/PacketPlayOutBlockChange.java | 101 ++++++++++++++++++ .../nms/packet/wrapped/BlockPosition.java | 58 +++++++++- 2 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 src/com/minecraft/moonlake/nms/packet/PacketPlayOutBlockChange.java diff --git a/src/com/minecraft/moonlake/nms/packet/PacketPlayOutBlockChange.java b/src/com/minecraft/moonlake/nms/packet/PacketPlayOutBlockChange.java new file mode 100644 index 00000000..60371fb9 --- /dev/null +++ b/src/com/minecraft/moonlake/nms/packet/PacketPlayOutBlockChange.java @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2017 The MoonLake Authors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +package com.minecraft.moonlake.nms.packet; + +import com.minecraft.moonlake.nms.packet.exception.PacketException; +import com.minecraft.moonlake.nms.packet.exception.PacketInitializeException; +import com.minecraft.moonlake.nms.packet.wrapped.BlockPosition; +import com.minecraft.moonlake.property.ObjectProperty; +import com.minecraft.moonlake.property.SimpleObjectProperty; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; + +import java.lang.reflect.Method; + +import static com.minecraft.moonlake.reflect.Reflect.*; + +public class PacketPlayOutBlockChange extends PacketAbstract { + + private final static Class CLASS_PACKETPLAYOUTBLOCKCHANGE; + private final static Class CLASS_CRAFTWORLD; + private final static Method METHOD_GETHANDLER; + + static { + + try { + + CLASS_PACKETPLAYOUTBLOCKCHANGE = PackageType.MINECRAFT_SERVER.getClass("PacketPlayOutBlockChange"); + CLASS_CRAFTWORLD = PackageType.CRAFTBUKKIT.getClass("CraftWorld"); + METHOD_GETHANDLER = getMethod(CLASS_CRAFTWORLD, "getHandle"); + } + catch (Exception e) { + + throw new PacketInitializeException("The nms packet play out block change reflect raw initialize exception.", e); + } + } + + private ObjectProperty world; + private ObjectProperty blockPosition; + + public PacketPlayOutBlockChange() { + + this(Bukkit.getServer().getWorlds().get(0), BlockPosition.ZERO); + } + + public PacketPlayOutBlockChange(Block block) { + + this(block.getWorld(), new BlockPosition(block.getX(), block.getY(), block.getZ())); + } + + public PacketPlayOutBlockChange(World world, BlockPosition blockPosition) { + + this.world = new SimpleObjectProperty<>(world); + this.blockPosition = new SimpleObjectProperty<>(blockPosition); + } + + public ObjectProperty getWorld() { + + return world; + } + + public ObjectProperty getBlockPosition() { + + return blockPosition; + } + + @Override + public void send(Player... players) throws PacketException { + + if(super.fireEvent(this, players)) return; + + try { + + Object nmsWorld = METHOD_GETHANDLER.invoke(world.get()); + Object packet = instantiateObject(CLASS_PACKETPLAYOUTBLOCKCHANGE, nmsWorld, blockPosition.get().asNMS()); + + PacketReflect.get().send(players, packet); + } + catch (Exception e) { + + throw new PacketException("The nms packet play out block change send exception.", e); + } + } +} diff --git a/src/com/minecraft/moonlake/nms/packet/wrapped/BlockPosition.java b/src/com/minecraft/moonlake/nms/packet/wrapped/BlockPosition.java index 4a04e816..ffec8cc3 100644 --- a/src/com/minecraft/moonlake/nms/packet/wrapped/BlockPosition.java +++ b/src/com/minecraft/moonlake/nms/packet/wrapped/BlockPosition.java @@ -21,6 +21,11 @@ import com.minecraft.moonlake.nms.exception.NMSException; import com.minecraft.moonlake.property.ReadOnlyIntegerProperty; import com.minecraft.moonlake.property.SimpleIntegerProperty; +import com.minecraft.moonlake.validate.Validate; +import org.bukkit.World; +import org.bukkit.block.Block; + +import java.lang.reflect.Method; import static com.minecraft.moonlake.reflect.Reflect.*; @@ -28,18 +33,26 @@ *

BlockPosition

* 方块位置封装类(详细doc待补充...) * - * @version 1.0 + * @version 1.1 * @author Month_Light */ public class BlockPosition { private final static Class CLASS_BLOCKPOSITION; + private final static Class CLASS_BASEBLOCKPOSITION; + private final static Method METHOD_GETX; + private final static Method METHOD_GETY; + private final static Method METHOD_GETZ; static { try { CLASS_BLOCKPOSITION = PackageType.MINECRAFT_SERVER.getClass("BlockPosition"); + CLASS_BASEBLOCKPOSITION = PackageType.MINECRAFT_SERVER.getClass("BaseBlockPosition"); + METHOD_GETX = getMethod(CLASS_BASEBLOCKPOSITION, "getX"); + METHOD_GETY = getMethod(CLASS_BASEBLOCKPOSITION, "getY"); + METHOD_GETZ = getMethod(CLASS_BASEBLOCKPOSITION, "getZ"); } catch (Exception e) { @@ -47,6 +60,11 @@ public class BlockPosition { } } + /** + * Zero Block Position + */ + public final static BlockPosition ZERO = new BlockPosition(0, 0, 0); + private final ReadOnlyIntegerProperty x; private final ReadOnlyIntegerProperty y; private final ReadOnlyIntegerProperty z; @@ -115,6 +133,18 @@ public int getZ() { return z.get(); } + /** + * 获取此方块位置在指定世界的方块对象 + * + * @param world 世界 + * @return Block + * @throws IllegalArgumentException 如果世界对象为 {@code null} 则抛出异常 + */ + public Block getBlock(World world) { + + return Validate.checkNotNull(world).getBlockAt(getX(), getY(), getZ()); + } + @Override public String toString() { @@ -142,4 +172,30 @@ public Object asNMS() throws NMSException { throw new NMSException(); } } + + /** + * 将指定 NMS 的 BlockPosition 对象转换到此 BlockPosition 对象 + * + * @param nmsBlockPosition NMS BlockPosition + * @return BlockPosition + * @throws IllegalArgumentException 如果 NMS BlockPosition 对象为 {@code null} 或不是实例则抛出异常 + * @throws NMSException 如果转换错误则抛出异常 + */ + public static BlockPosition fromNMS(Object nmsBlockPosition) throws NMSException { + + Validate.notNull(nmsBlockPosition, "The nms block position object is null."); + Validate.isTrue(CLASS_BASEBLOCKPOSITION.isInstance(nmsBlockPosition), "The nms block position object is not instance."); + + try { + + int x = (int) METHOD_GETX.invoke(nmsBlockPosition); + int y = (int) METHOD_GETY.invoke(nmsBlockPosition); + int z = (int) METHOD_GETZ.invoke(nmsBlockPosition); + return new BlockPosition(x, y, z); + } + catch (Exception e) { + + throw new NMSException(); + } + } } From f2cd93b726108688242a0adc0a40948335d7dd86 Mon Sep 17 00:00:00 2001 From: u2g Date: Wed, 25 Jan 2017 14:23:08 +0800 Subject: [PATCH 09/16] =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=8C=85=20PacketPlayO?= =?UTF-8?q?utBlockChange=20=E7=9A=84=20javadoc=20=E6=B7=BB=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nms/packet/PacketPlayOutBlockChange.java | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/com/minecraft/moonlake/nms/packet/PacketPlayOutBlockChange.java b/src/com/minecraft/moonlake/nms/packet/PacketPlayOutBlockChange.java index 60371fb9..0432d1ef 100644 --- a/src/com/minecraft/moonlake/nms/packet/PacketPlayOutBlockChange.java +++ b/src/com/minecraft/moonlake/nms/packet/PacketPlayOutBlockChange.java @@ -32,6 +32,13 @@ import static com.minecraft.moonlake.reflect.Reflect.*; +/** + *

PacketPlayOutBlockChange

+ * 数据包输出方块改变类(详细doc待补充...) + * + * @version 1.0 + * @author Month_Light + */ public class PacketPlayOutBlockChange extends PacketAbstract { private final static Class CLASS_PACKETPLAYOUTBLOCKCHANGE; @@ -55,27 +62,54 @@ public class PacketPlayOutBlockChange extends PacketAbstract world; private ObjectProperty blockPosition; + /** + * 数据包输出方块改变类构造函数 + * + * @deprecated 已过时, 请使用 {@link #PacketPlayOutBlockChange(World, BlockPosition)} + */ + @Deprecated public PacketPlayOutBlockChange() { this(Bukkit.getServer().getWorlds().get(0), BlockPosition.ZERO); } + /** + * 数据包输出方块改变类构造函数 + * + * @param block 方块 + */ public PacketPlayOutBlockChange(Block block) { this(block.getWorld(), new BlockPosition(block.getX(), block.getY(), block.getZ())); } + /** + * 数据包输出方块改变类构造函数 + * + * @param world 世界 + * @param blockPosition 方块位置 + */ public PacketPlayOutBlockChange(World world, BlockPosition blockPosition) { this.world = new SimpleObjectProperty<>(world); this.blockPosition = new SimpleObjectProperty<>(blockPosition); } + /** + * 获取此数据包输出方块改变的世界 + * + * @return 世界 + */ public ObjectProperty getWorld() { return world; } + /** + * 获取此数据包输出方块改变的方块位置 + * + * @return 方块位置 + */ public ObjectProperty getBlockPosition() { return blockPosition; From 806c233600323360e2fc1f685eb31a09ef28623c Mon Sep 17 00:00:00 2001 From: u2g Date: Wed, 25 Jan 2017 17:37:42 +0800 Subject: [PATCH 10/16] =?UTF-8?q?=E5=8E=BB=E9=99=A4=20MoonLakePlayerJoinEv?= =?UTF-8?q?ent=20=E5=8A=9F=E8=83=BD=E4=BB=A5=E5=8F=8A=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=8C=85=E7=9B=91=E5=90=AC=E5=99=A8=E5=B7=A5=E5=8E=82=E7=B1=BB?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../event/player/MoonLakePlayerJoinEvent.java | 245 ------------------ .../listener/PacketListenerFactory.java | 96 ++----- 2 files changed, 21 insertions(+), 320 deletions(-) delete mode 100644 src/com/minecraft/moonlake/api/event/player/MoonLakePlayerJoinEvent.java diff --git a/src/com/minecraft/moonlake/api/event/player/MoonLakePlayerJoinEvent.java b/src/com/minecraft/moonlake/api/event/player/MoonLakePlayerJoinEvent.java deleted file mode 100644 index 60b5a57d..00000000 --- a/src/com/minecraft/moonlake/api/event/player/MoonLakePlayerJoinEvent.java +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright (C) 2016 The MoonLake Authors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -package com.minecraft.moonlake.api.event.player; - -import org.bukkit.entity.Player; -import org.bukkit.event.HandlerList; - -import java.util.HashMap; -import java.util.Map; - -/** - *

MoonLakePlayerJoinEvent

- * 月色之湖玩家加入事件类(详细doc待补充...) - * - * @version 1.0 - * @author Month_Light - * @see MoonLakePlayerEvent - */ -public class MoonLakePlayerJoinEvent extends MoonLakePlayerEvent { - - private final static HandlerList handlerList = new HandlerList(); - private final ProtocolVersion protocolVersion; - private String joinMessage; - - /** - * 月色之湖玩家加入事件类构造函数 - * - * @param player Bukkit 玩家 - * @param joinMessage 加入消息 - * @param protocolVersion 客户端版本 - * @throws IllegalArgumentException 如果玩家对象为 {@code null} 则抛出异常 - */ - public MoonLakePlayerJoinEvent(Player player, String joinMessage, ProtocolVersion protocolVersion) throws IllegalArgumentException { - - super(player); - - this.joinMessage = joinMessage; - this.protocolVersion = protocolVersion; - } - - /*/** - * 月色之湖玩家加入事件类构造函数 - * - * @param moonLakePlayer MoonLake 玩家 - * @param joinMessage 加入消息 - * @param protocolVersion 客户端版本 - * @throws IllegalArgumentException 如果玩家对象为 {@code null} 则抛出异常 - */ - /*public MoonLakePlayerJoinEvent(MoonLakePlayer moonLakePlayer, String joinMessage, ProtocolVersion protocolVersion) throws IllegalArgumentException { - - super(moonLakePlayer); - - this.joinMessage = joinMessage; - this.protocolVersion = protocolVersion; - }*/ - - @Override - public HandlerList getHandlers() { - - return handlerList; - } - - public static HandlerList getHandlerList() { - - return handlerList; - } - - /** - * 获取此玩家的客户端版本号 - * - * @return 客户端版本 - */ - public ProtocolVersion getProtocolVersion() { - - return protocolVersion; - } - - /** - * 设置此玩家的加入消息 - * - * @param joinMessage 加入消息 - */ - public void setJoinMessage(String joinMessage) { - - this.joinMessage = joinMessage; - } - - /** - * 获取此玩家的加入消息 - * - * @return 加入消息 - */ - public String getJoinMessage() { - - return joinMessage; - } - - /** - *

ProtocolVersion

- * 客户端协议版本号(详细doc待补充...) - * - * @version 1.0 - * @author Month_Light - */ - public enum ProtocolVersion { - - // - // 均来自 wiki.vg 链接: http://wiki.vg/Protocol_version_numbers#Versions_after_the_Netty_rewrite - // 注意: 不包括快照版, 并且是新版协议号, 最低只有 1.7 - /// - - UNKNOWN(-1), - v1_7_2(4), - v1_7_4(4), - v1_7_5(4), - v1_7_6(5), - v1_7_7(5), - v1_7_8(5), - v1_7_9(5), - v1_7_10(5), - v1_8(47), - v1_8_1(47), - v1_8_2(47), - v1_8_3(47), - v1_8_4(47), - v1_8_5(47), - v1_8_6(47), - v1_8_7(47), - v1_8_8(47), - v1_8_9(47), - v1_9(107), - v1_9_1(108), - v1_9_2(109), - v1_9_3(110), - v1_9_4(110), - v1_10(210), - v1_10_1(210), - v1_10_2(210), - v1_11(315), - v1_11_1(316), - v1_11_2(316), - ; - - private final int protocol; - private final static Map ID_MAP; - - static { - - ID_MAP = new HashMap<>(); - - for(final ProtocolVersion protocolVersion : values()) { - - ID_MAP.put(protocolVersion.protocol, protocolVersion); - } - } - - /** - * 客户端协议版本号类构造函数 - * - * @param protocol 协议号 - */ - ProtocolVersion(int protocol) { - - this.protocol = protocol; - } - - /** - * 获取此客户端协议版本的协议号 - * - * @return 协议号 - */ - public int getProtocol() { - - return protocol; - } - - /** - * 获取此客户端协议版本是否在指定协议版本之前 - * - * @param protocolVersion 协议版本号 - * @return 是否参数协议版本之前 - */ - public boolean olderThan(ProtocolVersion protocolVersion) { - - return protocol < protocolVersion.getProtocol(); - } - - /** - * 获取此客户端协议版本是否在指定协议版本之后 - * - * @param protocolVersion 协议版本号 - * @return 是否参数协议版本之后 - */ - public boolean newerThan(ProtocolVersion protocolVersion) { - - return protocol >= protocolVersion.getProtocol(); - } - - /** - * 获取此客户端协议版本是否在指定范围 - * - * @param oldProtocolVersion 旧协议版本号 - * @param newProtocolVersion 新协议版本号 - * @return 是否在指定范围 - */ - public boolean isRange(ProtocolVersion oldProtocolVersion, ProtocolVersion newProtocolVersion) { - - return newerThan(oldProtocolVersion) && olderThan(newProtocolVersion); - } - - @Override - public String toString() { - - return name(); - } - - /** - * 将指定协议号转换到协议版本号类型 - * - * @param protocol 协议号 - * @return ProtocolVersion - */ - public static ProtocolVersion fromProtocol(int protocol) { - - ProtocolVersion protocolVersion = ID_MAP.get(protocol); - return protocolVersion == null ? UNKNOWN : protocolVersion; - } - } -} diff --git a/src/com/minecraft/moonlake/api/packet/listener/PacketListenerFactory.java b/src/com/minecraft/moonlake/api/packet/listener/PacketListenerFactory.java index 48d3c40a..f4181c12 100644 --- a/src/com/minecraft/moonlake/api/packet/listener/PacketListenerFactory.java +++ b/src/com/minecraft/moonlake/api/packet/listener/PacketListenerFactory.java @@ -20,7 +20,6 @@ import com.minecraft.moonlake.MoonLakeAPI; import com.minecraft.moonlake.api.event.MoonLakeListener; -import com.minecraft.moonlake.api.event.player.MoonLakePlayerJoinEvent; import com.minecraft.moonlake.api.packet.listener.channel.PacketChannel; import com.minecraft.moonlake.api.packet.listener.channel.PacketChannelWrapped; import com.minecraft.moonlake.api.packet.listener.handler.PacketHandler; @@ -28,7 +27,6 @@ import com.minecraft.moonlake.api.packet.listener.handler.PacketSent; import com.minecraft.moonlake.event.EventHelper; import com.minecraft.moonlake.exception.MoonLakeException; -import com.minecraft.moonlake.task.TaskHelper; import com.minecraft.moonlake.validate.Validate; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -36,14 +34,10 @@ import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.plugin.Plugin; -import org.spigotmc.SpigotConfig; import java.net.InetSocketAddress; -import java.net.SocketAddress; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; /** *

PacketListenerFactory

@@ -56,9 +50,7 @@ public final class PacketListenerFactory { private final static PacketChannel PACKET_CHANNEL; private final static List PACKET_HANDLERS; - private final static long PROTOCOL_VERSION_MAP_TIMEOUT; private final static MoonLakeListener PACKET_CHANNEL_PLAYER_LISTENER; - private final static Map PROTOCOL_VERSION_MAP; static { @@ -67,8 +59,6 @@ public final class PacketListenerFactory { throw new MoonLakeException("The config.yml 'PacketChannelListener' value not is 'true', this api unavailable."); } PACKET_HANDLERS = new ArrayList<>(); - PROTOCOL_VERSION_MAP_TIMEOUT = 60L; - PROTOCOL_VERSION_MAP = new HashMap<>(); PACKET_CHANNEL = new PacketINCChannel(new PacketListener() { @Override @@ -106,52 +96,6 @@ public Object onPacketReceive(Object sender, Object packet, Cancellable cancella packetReceived = new PacketReceivedExpression(packet, cancellable, (PacketChannelWrapped) sender); } - // - // MoonLakePlayerJoinEvent 玩家客户端协议版本获取 - if(packetReceived.hasChannel() && packetReceived.getPacketName().equals("PacketHandshakingInSetProtocol")) { - - SocketAddress address = packetReceived.getChannel().getRemoteAddress(); - int protocol = (int) packetReceived.getPacketValue("a"); - String hostname = null; - - try { - - if(SpigotConfig.bungee) { - - hostname = (String) packetReceived.getPacketValue("hostname"); - } - } - catch (Exception e) { - } - if(hostname != null) { - - String[] split = hostname.split("\000"); - - if(split.length >= 3) { - - address = new InetSocketAddress(split[1], ((InetSocketAddress) address).getPort()); - } - } - final String addressString = address.toString().substring(1); - MoonLakePlayerJoinEvent.ProtocolVersion protocolVersion = MoonLakePlayerJoinEvent.ProtocolVersion.fromProtocol(protocol); - - if(!PROTOCOL_VERSION_MAP.containsKey(addressString)) { - - PROTOCOL_VERSION_MAP.put(addressString, protocolVersion); - } - TaskHelper.runTaskLater(MoonLakeAPI.getMoonLake(), new Runnable() { - - @Override - public void run() { - - if(PROTOCOL_VERSION_MAP.containsKey(addressString)) { - - PROTOCOL_VERSION_MAP.remove(addressString); - } - } - }, PROTOCOL_VERSION_MAP_TIMEOUT); - } - /// notifyHandlers(packetReceived); if(packetReceived.getPacket() != null) { @@ -168,25 +112,6 @@ public void run() { public void onJoin(PlayerJoinEvent event) { PACKET_CHANNEL.addChannel(event.getPlayer()); - - // - // 触发 MoonLakePlayerJoinEvent 并获取客户端协议版本 - MoonLakePlayerJoinEvent mpje = null; - String address = toAddress(event.getPlayer().getAddress()); - - if(!PROTOCOL_VERSION_MAP.containsKey(address)) { - - mpje = new MoonLakePlayerJoinEvent(event.getPlayer(), event.getJoinMessage(), MoonLakePlayerJoinEvent.ProtocolVersion.UNKNOWN); - } - else { - - MoonLakePlayerJoinEvent.ProtocolVersion protocolVersion = PROTOCOL_VERSION_MAP.remove(address); - mpje = new MoonLakePlayerJoinEvent(event.getPlayer(), event.getJoinMessage(), protocolVersion); - } - EventHelper.callEvent(mpje); - - event.setJoinMessage(mpje.getJoinMessage()); - /// } @EventHandler(priority = EventPriority.HIGHEST) @@ -230,6 +155,27 @@ public static boolean removeHandler(PacketHandler handler) { return PACKET_HANDLERS.remove(handler); } + /** + * 将指定插件的所有数据包通道监听器处理器删除 + * + * @param plugin 插件 + */ + public static void removeHandler(Plugin plugin) { + + if(plugin != null) { + + PACKET_HANDLERS.removeAll(getHandlersFromPlugin(plugin)); + } + } + + /** + * 清除所有的数据包通道监听器处理器 + */ + public static void removeAll() { + + PACKET_HANDLERS.clear(); + } + /** * 通知所有的数据包处理器触发数据包发送 * From 85596d4c6bc706264b7a396bdba88fd0899de76c Mon Sep 17 00:00:00 2001 From: u2g Date: Wed, 25 Jan 2017 22:45:45 +0800 Subject: [PATCH 11/16] =?UTF-8?q?=E6=A8=A1=E7=B3=8A=E5=8F=8D=E5=B0=84=20Fu?= =?UTF-8?q?zzyReflect=20=E5=9F=BA=E7=A1=80=E5=8C=85=E8=A3=85=E5=AE=8C?= =?UTF-8?q?=E6=88=90,=20=E5=BE=85=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../moonlake/reflect/fuzzy/FuzzyField.java | 100 +++++ .../moonlake/reflect/fuzzy/FuzzyMethod.java | 83 ++++ .../moonlake/reflect/fuzzy/FuzzyReflect.java | 417 ++++++++++++++++++ 3 files changed, 600 insertions(+) create mode 100644 src/com/minecraft/moonlake/reflect/fuzzy/FuzzyField.java create mode 100644 src/com/minecraft/moonlake/reflect/fuzzy/FuzzyMethod.java create mode 100644 src/com/minecraft/moonlake/reflect/fuzzy/FuzzyReflect.java diff --git a/src/com/minecraft/moonlake/reflect/fuzzy/FuzzyField.java b/src/com/minecraft/moonlake/reflect/fuzzy/FuzzyField.java new file mode 100644 index 00000000..3e1ad159 --- /dev/null +++ b/src/com/minecraft/moonlake/reflect/fuzzy/FuzzyField.java @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2017 The MoonLake Authors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +package com.minecraft.moonlake.reflect.fuzzy; + +import com.minecraft.moonlake.exception.MoonLakeException; + +import java.lang.reflect.Field; + +public class FuzzyField { + + private Field field; + private boolean forceAccess; + + public FuzzyField(Field field, boolean forceAccess) { + + this.field = field; + this.setForceAccess(forceAccess); + } + + public FuzzyField(Field field) { + + this(field, false); + } + + public FuzzyField(FuzzyReflect fuzzy, Field field) { + + this(field, fuzzy.isForceAccess()); + } + + public Field getField() { + + return field; + } + + public boolean isForceAccess() { + + return forceAccess; + } + + public void setForceAccess(boolean forceAccess) { + + this.forceAccess = forceAccess; + + if(forceAccess && !field.isAccessible()) + field.setAccessible(true); + else if(!forceAccess && field.isAccessible()) + field.setAccessible(false); + } + + public R getValue() { + + return getValue(null); + } + + @SuppressWarnings("unchecked") + public R getValue(T instance) { + + try { + + return (R) field.get(instance); + } + catch (Exception e) { + + throw new MoonLakeException(e.getMessage(), e); + } + } + + public void setValue(R value) { + + setValue(null, value); + } + + public void setValue(T instance, R value) { + + try { + + field.set(instance, value); + } + catch (Exception e) { + + throw new MoonLakeException(e.getMessage(), e); + } + } +} diff --git a/src/com/minecraft/moonlake/reflect/fuzzy/FuzzyMethod.java b/src/com/minecraft/moonlake/reflect/fuzzy/FuzzyMethod.java new file mode 100644 index 00000000..c9d9d190 --- /dev/null +++ b/src/com/minecraft/moonlake/reflect/fuzzy/FuzzyMethod.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2017 The MoonLake Authors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +package com.minecraft.moonlake.reflect.fuzzy; + +import com.minecraft.moonlake.exception.MoonLakeException; + +import java.lang.reflect.Method; + +public class FuzzyMethod { + + private Method method; + private boolean forceAccess; + + public FuzzyMethod(Method method, boolean forceAccess) { + + this.method = method; + this.setForceAccess(forceAccess); + } + + public FuzzyMethod(Method method) { + + this(method, false); + } + + public FuzzyMethod(FuzzyReflect fuzzy, Method method) { + + this(method, fuzzy.isForceAccess()); + } + + public Method getMethod() { + + return method; + } + + public boolean isForceAccess() { + + return forceAccess; + } + + public void setForceAccess(boolean forceAccess) { + + this.forceAccess = forceAccess; + + if(forceAccess && !method.isAccessible()) + method.setAccessible(true); + else if(!forceAccess && method.isAccessible()) + method.setAccessible(false); + } + + public R invoke(T instance) { + + return invoke(instance, new Object[0]); + } + + @SuppressWarnings("unchecked") + public R invoke(T instance, Object... args) { + + try { + + return (R) method.invoke(instance, args); + } + catch (Exception e) { + + throw new MoonLakeException(e.getMessage(), e); + } + } +} diff --git a/src/com/minecraft/moonlake/reflect/fuzzy/FuzzyReflect.java b/src/com/minecraft/moonlake/reflect/fuzzy/FuzzyReflect.java new file mode 100644 index 00000000..60f4a2ed --- /dev/null +++ b/src/com/minecraft/moonlake/reflect/fuzzy/FuzzyReflect.java @@ -0,0 +1,417 @@ +/* + * Copyright (C) 2017 The MoonLake Authors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +package com.minecraft.moonlake.reflect.fuzzy; + +import com.minecraft.moonlake.exception.MoonLakeException; +import com.minecraft.moonlake.validate.Validate; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.*; +import java.util.regex.Pattern; + +import static com.minecraft.moonlake.reflect.Reflect.*; +import static com.minecraft.moonlake.reflect.Reflect.DataType.*; + +public class FuzzyReflect { + + private Class source; + private boolean forceAccess; + + public FuzzyReflect(Class source, boolean forceAccess) { + + Validate.notNull(source, "The source class object is null."); + + this.source = source; + this.forceAccess = forceAccess; + } + + public FuzzyReflect(Class source) { + + this(source, false); + } + + public Class getSource() { + + return source; + } + + public boolean isForceAccess() { + + return forceAccess; + } + + public void setForceAccess(boolean forceAccess) { + + this.forceAccess = forceAccess; + } + + // + // Static Method + + public static FuzzyReflect fromClass(Class source) { + + Validate.notNull(source, "The source object is null."); + + return new FuzzyReflect<>(source, false); + } + + public static FuzzyReflect fromClass(Class source, boolean forceAccess) { + + Validate.notNull(source, "The source object is null."); + + return new FuzzyReflect<>(source, forceAccess); + } + + public static FuzzyReflect fromObject(Object object) { + + Validate.notNull(object, "The object is null."); + + return new FuzzyReflect<>(object.getClass()); + } + + public static FuzzyReflect fromObject(Object object, boolean forceAccess) { + + Validate.notNull(object, "The object is null."); + + return new FuzzyReflect<>(object.getClass(), forceAccess); + } + + public static FuzzyReflect fromPackage(PackageType type, String className) { + + Validate.notNull(type, "The package type object is null."); + Validate.notNull(className, "The class name object is null."); + + try { + + return new FuzzyReflect<>(type.getClass(className), false); + } + catch (Exception e) { + + throw new MoonLakeException("The package not exists '" + className + "' class.", e); + } + } + + public static FuzzyReflect fromPackage(PackageType type, String className, boolean forceAccess) { + + Validate.notNull(type, "The package type object is null."); + Validate.notNull(className, "The class name object is null."); + + try { + + return new FuzzyReflect<>(type.getClass(className), forceAccess); + } + catch (Exception e) { + + throw new MoonLakeException("The package not exists '" + className + "' class.", e); + } + } + /// + + public Set> findConstructors() { + + if(forceAccess) + return arrayToSet(source.getDeclaredConstructors()); + else + return arrayToSet(source.getConstructors()); + } + + public Constructor findConstructor() { + + try { + + if(forceAccess) + return source.getDeclaredConstructor(); + else + return source.getConstructor(); + } + catch (Exception e) { + + throw new MoonLakeException("The source class not exists default constructor.", e); + } + } + + @SuppressWarnings("unchecked") + public Constructor findConstructorByParameters(Class... args) { + + Validate.notNull(args, "The parameters object is null."); + + Class[] argsPrimitive = getPrimitive(args); + + for(Constructor constructor : findConstructors()) + if(compare(getPrimitive(constructor.getParameterTypes()), argsPrimitive)) + return (Constructor) constructor; + + throw new MoonLakeException("The source class not exists '" + Arrays.toString(args) + "' parameters constructor."); + } + + public Set findMethods() { + + if(forceAccess) + return arrayToSet(source.getDeclaredMethods(), source.getMethods()); + else + return arrayToSet(source.getMethods()); + } + + public List findMethodsByReturnType(Class returnType) { + + Validate.notNull(returnType, "The return type object is null."); + + List methodList = new ArrayList<>(); + Class returnTypePrimitive = getPrimitive(returnType); + + for(Method method : findMethods()) + if(getPrimitive(method.getReturnType()).equals(returnTypePrimitive)) + methodList.add(method); + + return methodList; + } + + public List findMethodsByParameters(Class... args) { + + Validate.notNull(args, "The parameters object is null."); + + Class[] argsPrimitive = getPrimitive(args); + List methodList = new ArrayList<>(); + + for(Method method : findMethods()) + if(compare(getPrimitive(method.getParameterTypes()), argsPrimitive)) + methodList.add(method); + + return methodList; + } + + public List findMethodsByParameters(Class returnType, Class... args) { + + Validate.notNull(args, "The parameters object is null."); + + Class[] argsPrimitive = getPrimitive(args); + List resultList = new ArrayList<>(); + List methodList = findMethodsByReturnType(returnType); + + for(Method method : methodList) + if(compare(getPrimitive(method.getParameterTypes()), argsPrimitive)) + resultList.add(method); + + return resultList; + } + + public List findMethodsByName(String name) { + + Validate.notNull(name, "The method name object is null."); + + List methodList = new ArrayList<>(); + + for(Method method : findMethods()) + if(method.getName().equals(name)) + methodList.add(method); + + return methodList; + } + + public Method findMethodByName(String name) { + + List methodList = findMethodsByName(name); + + if(methodList.size() > 0) + return methodList.get(0); + else + throw new MoonLakeException(); + } + + public Method findMethodByNameMatch(String nameRegex) { + + Validate.notNull(nameRegex, "The name regex object is null."); + + Pattern pattern = Pattern.compile(nameRegex); + + for(Method method : findMethods()) + if(pattern.matcher(method.getName()).matches()) + return method; + + throw new MoonLakeException(); + } + + public Method findMethodByNameMatchAndReturnType(String nameRegex, Class returnType) { + + Validate.notNull(nameRegex, "The name regex object is null."); + + Pattern pattern = Pattern.compile(nameRegex); + List methodList = findMethodsByReturnType(returnType); + + for(Method method : methodList) + if(pattern.matcher(method.getName()).matches()) + return method; + + throw new MoonLakeException(); + } + + public Method findMethodByNameAndParameters(String name, Class... args) { + + Validate.notNull(args, "The parameters object is null."); + + Class[] argsPrimitive = getPrimitive(args); + List methodList = findMethodsByName(name); + + for(Method method : methodList) + if(compare(getPrimitive(method.getParameterTypes()), argsPrimitive)) + return method; + + throw new MoonLakeException(); + } + + public Method findMethodByNameAndParameters(String name, Class returnType, Class... args) { + + Validate.notNull(name, "The method name object is null."); + + for(Method method : findMethodsByParameters(returnType, args)) + if(method.getName().equals(name)) + return method; + + throw new MoonLakeException(); + } + + public FuzzyMethod findFuzzyMethodByName(String name) { + + return new FuzzyMethod<>(this, findMethodByName(name)); + } + + public FuzzyMethod findFuzzyMethodByNameMatch(String nameRegex) { + + return new FuzzyMethod<>(this, findMethodByNameMatch(nameRegex)); + } + + public FuzzyMethod findFuzzyMethodByNameMatchAndReturnType(String nameRegex, Class returnType) { + + return new FuzzyMethod<>(this, findMethodByNameMatchAndReturnType(nameRegex, returnType)); + } + + public FuzzyMethod findFuzzyMethodByNameAndParameters(String name, Class... args) { + + return new FuzzyMethod<>(this, findMethodByNameAndParameters(name, args)); + } + + public FuzzyMethod findFuzzyMethodByNameAndParameters(String name, Class returnType, Class... args) { + + return new FuzzyMethod<>(this, findMethodByNameAndParameters(name, returnType, args)); + } + + public Set findFields() { + + if(forceAccess) + return arrayToSet(source.getDeclaredFields(), source.getFields()); + else + return arrayToSet(source.getFields()); + } + + public Set findFields(Class excludeClass) { + + Validate.notNull(excludeClass, "The exclude class object is null."); + + if(forceAccess) { + + Class currentClass = source; + Set fieldSet = new LinkedHashSet<>(); + + while (currentClass != excludeClass) { + fieldSet.addAll(Arrays.asList(currentClass.getDeclaredFields())); + currentClass = currentClass.getSuperclass(); + } + return fieldSet; + } + return findFields(); + } + + public Set findFieldsByType(Class fieldType) { + + Validate.notNull(fieldType, "The field type object is null."); + + Set fieldSet = new LinkedHashSet<>(); + + for(Field field : findFields()) + if(field.getType().isAssignableFrom(fieldType)) + fieldSet.add(field); + + return fieldSet; + } + + public Field findFieldByName(String name) { + + Validate.notNull(name, "The field name object is null."); + + for(Field field : findFields()) + if(field.getName().equals(name)) + return field; + + throw new MoonLakeException(); + } + + public Field findFieldByNameMatch(String nameRegex) { + + Validate.notNull(nameRegex, "The name regex object is null."); + + Pattern pattern = Pattern.compile(nameRegex); + + for(Field field : findFields()) + if(pattern.matcher(field.getName()).matches()) + return field; + + throw new MoonLakeException(); + } + + public Field findFieldByNameAndType(String name, Class fieldType) { + + Validate.notNull(name, "The field name object is null."); + Validate.notNull(fieldType, "The field type object is null."); + + for(Field field : findFields()) + if(field.getName().equals(name) && field.getType().isAssignableFrom(fieldType)) + return field; + + throw new MoonLakeException(); + } + + public FuzzyField findFuzzyFieldByName(String name) { + + return new FuzzyField<>(this, findFieldByName(name)); + } + + public FuzzyField findFuzzyFieldByNameMatch(String nameRegex) { + + return new FuzzyField<>(this, findFieldByNameMatch(nameRegex)); + } + + public FuzzyField findFuzzyFieldByNameAndType(String name, Class fieldType) { + + return new FuzzyField<>(this, findFieldByNameAndType(name, fieldType)); + } + + @SuppressWarnings("unchecked") + private static Set arrayToSet(T[]... array) { + + Set result = new LinkedHashSet<>(); + + for(T[] contents : array) + for(T content : contents) + result.add(content); + + return result; + } +} From 718316fe1c474e35423f03294fc4ad5eb1555ad7 Mon Sep 17 00:00:00 2001 From: u2g Date: Thu, 26 Jan 2017 14:58:22 +0800 Subject: [PATCH 12/16] =?UTF-8?q?=E6=A8=A1=E7=B3=8A=E5=8F=8D=E5=B0=84=20Fu?= =?UTF-8?q?zzyReflect=20=E5=8A=9F=E8=83=BD=E5=88=A0=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../moonlake/reflect/fuzzy/FuzzyField.java | 100 ----- .../moonlake/reflect/fuzzy/FuzzyMethod.java | 83 ---- .../moonlake/reflect/fuzzy/FuzzyReflect.java | 417 ------------------ 3 files changed, 600 deletions(-) delete mode 100644 src/com/minecraft/moonlake/reflect/fuzzy/FuzzyField.java delete mode 100644 src/com/minecraft/moonlake/reflect/fuzzy/FuzzyMethod.java delete mode 100644 src/com/minecraft/moonlake/reflect/fuzzy/FuzzyReflect.java diff --git a/src/com/minecraft/moonlake/reflect/fuzzy/FuzzyField.java b/src/com/minecraft/moonlake/reflect/fuzzy/FuzzyField.java deleted file mode 100644 index 3e1ad159..00000000 --- a/src/com/minecraft/moonlake/reflect/fuzzy/FuzzyField.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2017 The MoonLake Authors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -package com.minecraft.moonlake.reflect.fuzzy; - -import com.minecraft.moonlake.exception.MoonLakeException; - -import java.lang.reflect.Field; - -public class FuzzyField { - - private Field field; - private boolean forceAccess; - - public FuzzyField(Field field, boolean forceAccess) { - - this.field = field; - this.setForceAccess(forceAccess); - } - - public FuzzyField(Field field) { - - this(field, false); - } - - public FuzzyField(FuzzyReflect fuzzy, Field field) { - - this(field, fuzzy.isForceAccess()); - } - - public Field getField() { - - return field; - } - - public boolean isForceAccess() { - - return forceAccess; - } - - public void setForceAccess(boolean forceAccess) { - - this.forceAccess = forceAccess; - - if(forceAccess && !field.isAccessible()) - field.setAccessible(true); - else if(!forceAccess && field.isAccessible()) - field.setAccessible(false); - } - - public R getValue() { - - return getValue(null); - } - - @SuppressWarnings("unchecked") - public R getValue(T instance) { - - try { - - return (R) field.get(instance); - } - catch (Exception e) { - - throw new MoonLakeException(e.getMessage(), e); - } - } - - public void setValue(R value) { - - setValue(null, value); - } - - public void setValue(T instance, R value) { - - try { - - field.set(instance, value); - } - catch (Exception e) { - - throw new MoonLakeException(e.getMessage(), e); - } - } -} diff --git a/src/com/minecraft/moonlake/reflect/fuzzy/FuzzyMethod.java b/src/com/minecraft/moonlake/reflect/fuzzy/FuzzyMethod.java deleted file mode 100644 index c9d9d190..00000000 --- a/src/com/minecraft/moonlake/reflect/fuzzy/FuzzyMethod.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2017 The MoonLake Authors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -package com.minecraft.moonlake.reflect.fuzzy; - -import com.minecraft.moonlake.exception.MoonLakeException; - -import java.lang.reflect.Method; - -public class FuzzyMethod { - - private Method method; - private boolean forceAccess; - - public FuzzyMethod(Method method, boolean forceAccess) { - - this.method = method; - this.setForceAccess(forceAccess); - } - - public FuzzyMethod(Method method) { - - this(method, false); - } - - public FuzzyMethod(FuzzyReflect fuzzy, Method method) { - - this(method, fuzzy.isForceAccess()); - } - - public Method getMethod() { - - return method; - } - - public boolean isForceAccess() { - - return forceAccess; - } - - public void setForceAccess(boolean forceAccess) { - - this.forceAccess = forceAccess; - - if(forceAccess && !method.isAccessible()) - method.setAccessible(true); - else if(!forceAccess && method.isAccessible()) - method.setAccessible(false); - } - - public R invoke(T instance) { - - return invoke(instance, new Object[0]); - } - - @SuppressWarnings("unchecked") - public R invoke(T instance, Object... args) { - - try { - - return (R) method.invoke(instance, args); - } - catch (Exception e) { - - throw new MoonLakeException(e.getMessage(), e); - } - } -} diff --git a/src/com/minecraft/moonlake/reflect/fuzzy/FuzzyReflect.java b/src/com/minecraft/moonlake/reflect/fuzzy/FuzzyReflect.java deleted file mode 100644 index 60f4a2ed..00000000 --- a/src/com/minecraft/moonlake/reflect/fuzzy/FuzzyReflect.java +++ /dev/null @@ -1,417 +0,0 @@ -/* - * Copyright (C) 2017 The MoonLake Authors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -package com.minecraft.moonlake.reflect.fuzzy; - -import com.minecraft.moonlake.exception.MoonLakeException; -import com.minecraft.moonlake.validate.Validate; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.*; -import java.util.regex.Pattern; - -import static com.minecraft.moonlake.reflect.Reflect.*; -import static com.minecraft.moonlake.reflect.Reflect.DataType.*; - -public class FuzzyReflect { - - private Class source; - private boolean forceAccess; - - public FuzzyReflect(Class source, boolean forceAccess) { - - Validate.notNull(source, "The source class object is null."); - - this.source = source; - this.forceAccess = forceAccess; - } - - public FuzzyReflect(Class source) { - - this(source, false); - } - - public Class getSource() { - - return source; - } - - public boolean isForceAccess() { - - return forceAccess; - } - - public void setForceAccess(boolean forceAccess) { - - this.forceAccess = forceAccess; - } - - // - // Static Method - - public static FuzzyReflect fromClass(Class source) { - - Validate.notNull(source, "The source object is null."); - - return new FuzzyReflect<>(source, false); - } - - public static FuzzyReflect fromClass(Class source, boolean forceAccess) { - - Validate.notNull(source, "The source object is null."); - - return new FuzzyReflect<>(source, forceAccess); - } - - public static FuzzyReflect fromObject(Object object) { - - Validate.notNull(object, "The object is null."); - - return new FuzzyReflect<>(object.getClass()); - } - - public static FuzzyReflect fromObject(Object object, boolean forceAccess) { - - Validate.notNull(object, "The object is null."); - - return new FuzzyReflect<>(object.getClass(), forceAccess); - } - - public static FuzzyReflect fromPackage(PackageType type, String className) { - - Validate.notNull(type, "The package type object is null."); - Validate.notNull(className, "The class name object is null."); - - try { - - return new FuzzyReflect<>(type.getClass(className), false); - } - catch (Exception e) { - - throw new MoonLakeException("The package not exists '" + className + "' class.", e); - } - } - - public static FuzzyReflect fromPackage(PackageType type, String className, boolean forceAccess) { - - Validate.notNull(type, "The package type object is null."); - Validate.notNull(className, "The class name object is null."); - - try { - - return new FuzzyReflect<>(type.getClass(className), forceAccess); - } - catch (Exception e) { - - throw new MoonLakeException("The package not exists '" + className + "' class.", e); - } - } - /// - - public Set> findConstructors() { - - if(forceAccess) - return arrayToSet(source.getDeclaredConstructors()); - else - return arrayToSet(source.getConstructors()); - } - - public Constructor findConstructor() { - - try { - - if(forceAccess) - return source.getDeclaredConstructor(); - else - return source.getConstructor(); - } - catch (Exception e) { - - throw new MoonLakeException("The source class not exists default constructor.", e); - } - } - - @SuppressWarnings("unchecked") - public Constructor findConstructorByParameters(Class... args) { - - Validate.notNull(args, "The parameters object is null."); - - Class[] argsPrimitive = getPrimitive(args); - - for(Constructor constructor : findConstructors()) - if(compare(getPrimitive(constructor.getParameterTypes()), argsPrimitive)) - return (Constructor) constructor; - - throw new MoonLakeException("The source class not exists '" + Arrays.toString(args) + "' parameters constructor."); - } - - public Set findMethods() { - - if(forceAccess) - return arrayToSet(source.getDeclaredMethods(), source.getMethods()); - else - return arrayToSet(source.getMethods()); - } - - public List findMethodsByReturnType(Class returnType) { - - Validate.notNull(returnType, "The return type object is null."); - - List methodList = new ArrayList<>(); - Class returnTypePrimitive = getPrimitive(returnType); - - for(Method method : findMethods()) - if(getPrimitive(method.getReturnType()).equals(returnTypePrimitive)) - methodList.add(method); - - return methodList; - } - - public List findMethodsByParameters(Class... args) { - - Validate.notNull(args, "The parameters object is null."); - - Class[] argsPrimitive = getPrimitive(args); - List methodList = new ArrayList<>(); - - for(Method method : findMethods()) - if(compare(getPrimitive(method.getParameterTypes()), argsPrimitive)) - methodList.add(method); - - return methodList; - } - - public List findMethodsByParameters(Class returnType, Class... args) { - - Validate.notNull(args, "The parameters object is null."); - - Class[] argsPrimitive = getPrimitive(args); - List resultList = new ArrayList<>(); - List methodList = findMethodsByReturnType(returnType); - - for(Method method : methodList) - if(compare(getPrimitive(method.getParameterTypes()), argsPrimitive)) - resultList.add(method); - - return resultList; - } - - public List findMethodsByName(String name) { - - Validate.notNull(name, "The method name object is null."); - - List methodList = new ArrayList<>(); - - for(Method method : findMethods()) - if(method.getName().equals(name)) - methodList.add(method); - - return methodList; - } - - public Method findMethodByName(String name) { - - List methodList = findMethodsByName(name); - - if(methodList.size() > 0) - return methodList.get(0); - else - throw new MoonLakeException(); - } - - public Method findMethodByNameMatch(String nameRegex) { - - Validate.notNull(nameRegex, "The name regex object is null."); - - Pattern pattern = Pattern.compile(nameRegex); - - for(Method method : findMethods()) - if(pattern.matcher(method.getName()).matches()) - return method; - - throw new MoonLakeException(); - } - - public Method findMethodByNameMatchAndReturnType(String nameRegex, Class returnType) { - - Validate.notNull(nameRegex, "The name regex object is null."); - - Pattern pattern = Pattern.compile(nameRegex); - List methodList = findMethodsByReturnType(returnType); - - for(Method method : methodList) - if(pattern.matcher(method.getName()).matches()) - return method; - - throw new MoonLakeException(); - } - - public Method findMethodByNameAndParameters(String name, Class... args) { - - Validate.notNull(args, "The parameters object is null."); - - Class[] argsPrimitive = getPrimitive(args); - List methodList = findMethodsByName(name); - - for(Method method : methodList) - if(compare(getPrimitive(method.getParameterTypes()), argsPrimitive)) - return method; - - throw new MoonLakeException(); - } - - public Method findMethodByNameAndParameters(String name, Class returnType, Class... args) { - - Validate.notNull(name, "The method name object is null."); - - for(Method method : findMethodsByParameters(returnType, args)) - if(method.getName().equals(name)) - return method; - - throw new MoonLakeException(); - } - - public FuzzyMethod findFuzzyMethodByName(String name) { - - return new FuzzyMethod<>(this, findMethodByName(name)); - } - - public FuzzyMethod findFuzzyMethodByNameMatch(String nameRegex) { - - return new FuzzyMethod<>(this, findMethodByNameMatch(nameRegex)); - } - - public FuzzyMethod findFuzzyMethodByNameMatchAndReturnType(String nameRegex, Class returnType) { - - return new FuzzyMethod<>(this, findMethodByNameMatchAndReturnType(nameRegex, returnType)); - } - - public FuzzyMethod findFuzzyMethodByNameAndParameters(String name, Class... args) { - - return new FuzzyMethod<>(this, findMethodByNameAndParameters(name, args)); - } - - public FuzzyMethod findFuzzyMethodByNameAndParameters(String name, Class returnType, Class... args) { - - return new FuzzyMethod<>(this, findMethodByNameAndParameters(name, returnType, args)); - } - - public Set findFields() { - - if(forceAccess) - return arrayToSet(source.getDeclaredFields(), source.getFields()); - else - return arrayToSet(source.getFields()); - } - - public Set findFields(Class excludeClass) { - - Validate.notNull(excludeClass, "The exclude class object is null."); - - if(forceAccess) { - - Class currentClass = source; - Set fieldSet = new LinkedHashSet<>(); - - while (currentClass != excludeClass) { - fieldSet.addAll(Arrays.asList(currentClass.getDeclaredFields())); - currentClass = currentClass.getSuperclass(); - } - return fieldSet; - } - return findFields(); - } - - public Set findFieldsByType(Class fieldType) { - - Validate.notNull(fieldType, "The field type object is null."); - - Set fieldSet = new LinkedHashSet<>(); - - for(Field field : findFields()) - if(field.getType().isAssignableFrom(fieldType)) - fieldSet.add(field); - - return fieldSet; - } - - public Field findFieldByName(String name) { - - Validate.notNull(name, "The field name object is null."); - - for(Field field : findFields()) - if(field.getName().equals(name)) - return field; - - throw new MoonLakeException(); - } - - public Field findFieldByNameMatch(String nameRegex) { - - Validate.notNull(nameRegex, "The name regex object is null."); - - Pattern pattern = Pattern.compile(nameRegex); - - for(Field field : findFields()) - if(pattern.matcher(field.getName()).matches()) - return field; - - throw new MoonLakeException(); - } - - public Field findFieldByNameAndType(String name, Class fieldType) { - - Validate.notNull(name, "The field name object is null."); - Validate.notNull(fieldType, "The field type object is null."); - - for(Field field : findFields()) - if(field.getName().equals(name) && field.getType().isAssignableFrom(fieldType)) - return field; - - throw new MoonLakeException(); - } - - public FuzzyField findFuzzyFieldByName(String name) { - - return new FuzzyField<>(this, findFieldByName(name)); - } - - public FuzzyField findFuzzyFieldByNameMatch(String nameRegex) { - - return new FuzzyField<>(this, findFieldByNameMatch(nameRegex)); - } - - public FuzzyField findFuzzyFieldByNameAndType(String name, Class fieldType) { - - return new FuzzyField<>(this, findFieldByNameAndType(name, fieldType)); - } - - @SuppressWarnings("unchecked") - private static Set arrayToSet(T[]... array) { - - Set result = new LinkedHashSet<>(); - - for(T[] contents : array) - for(T content : contents) - result.add(content); - - return result; - } -} From b87badb766e22a9cbcee47c505bd553a0d958786 Mon Sep 17 00:00:00 2001 From: u2g Date: Thu, 26 Jan 2017 19:59:02 +0800 Subject: [PATCH 13/16] =?UTF-8?q?=E4=B8=A4=E4=B8=AA=E6=96=B0=E7=9A=84?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=8C=85=E5=AE=8C=E6=88=90=E4=BB=A5=E5=8F=8A?= =?UTF-8?q?=E7=8E=A9=E5=AE=B6=E6=8E=A5=E5=8F=A3=E7=9A=84=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E5=92=8C=E5=87=BD=E6=95=B0=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../moonlake/api/player/AbstractPlayer.java | 13 ++ .../api/player/SimpleMoonLakePlayer.java | 5 + .../api/player/SimpleMoonLakePlayer_v1_8.java | 7 + .../api/player/SimpleMoonLakePlayer_v1_9.java | 6 + .../api/player/inventory/InventoryPlayer.java | 7 + .../nms/packet/PacketPlayOutBookOpen.java | 123 ++++++++++++++++++ .../packet/PacketPlayOutCustomPayload.java | 117 +++++++++++++++++ .../packet/wrapped/PacketDataSerializer.java | 84 ++++++++++++ 8 files changed, 362 insertions(+) create mode 100644 src/com/minecraft/moonlake/nms/packet/PacketPlayOutBookOpen.java create mode 100644 src/com/minecraft/moonlake/nms/packet/PacketPlayOutCustomPayload.java create mode 100644 src/com/minecraft/moonlake/nms/packet/wrapped/PacketDataSerializer.java diff --git a/src/com/minecraft/moonlake/api/player/AbstractPlayer.java b/src/com/minecraft/moonlake/api/player/AbstractPlayer.java index 2a7c91f0..60b613af 100644 --- a/src/com/minecraft/moonlake/api/player/AbstractPlayer.java +++ b/src/com/minecraft/moonlake/api/player/AbstractPlayer.java @@ -18,6 +18,7 @@ package com.minecraft.moonlake.api.player; +import com.minecraft.moonlake.MoonLakeAPI; import com.minecraft.moonlake.api.entity.AttributeType; import com.minecraft.moonlake.api.fancy.FancyMessage; import com.minecraft.moonlake.api.player.depend.EconomyPlayerData; @@ -31,6 +32,7 @@ import com.minecraft.moonlake.property.ReadOnlyStringProperty; import com.minecraft.moonlake.property.SimpleObjectProperty; import com.minecraft.moonlake.property.SimpleStringProperty; +import com.minecraft.moonlake.reflect.Reflect; import com.minecraft.moonlake.util.StringUtil; import com.minecraft.moonlake.validate.Validate; import com.mojang.authlib.GameProfile; @@ -377,6 +379,17 @@ public World getWorld() { @Override public void updateInventory() { + if(Reflect.getServerVersionNumber() <= 8) { + // 服务端版本低于 1.8 或为 1.8 + MoonLakeAPI.runTaskLaterAsync(MoonLakeAPI.getMoonLake(), new Runnable() { + @Override + public void run() { + // 则延迟 1tick 更新 + getBukkitPlayer().updateInventory(); + } + }, 1L); + return; + } getBukkitPlayer().updateInventory(); } diff --git a/src/com/minecraft/moonlake/api/player/SimpleMoonLakePlayer.java b/src/com/minecraft/moonlake/api/player/SimpleMoonLakePlayer.java index 0a2f6711..6480fbea 100644 --- a/src/com/minecraft/moonlake/api/player/SimpleMoonLakePlayer.java +++ b/src/com/minecraft/moonlake/api/player/SimpleMoonLakePlayer.java @@ -166,6 +166,11 @@ public ItemStack getItemInOffHand() { return null; } + @Override + public void setItemInHand(ItemStack itemStack) { + + } + @Override public void setItemInMainHand(ItemStack itemStack) { diff --git a/src/com/minecraft/moonlake/api/player/SimpleMoonLakePlayer_v1_8.java b/src/com/minecraft/moonlake/api/player/SimpleMoonLakePlayer_v1_8.java index b1c54280..6c871882 100644 --- a/src/com/minecraft/moonlake/api/player/SimpleMoonLakePlayer_v1_8.java +++ b/src/com/minecraft/moonlake/api/player/SimpleMoonLakePlayer_v1_8.java @@ -176,6 +176,13 @@ public ItemStack getItemInOffHand() { throw new IllegalBukkitVersionException("The method not support 1.8 and old version."); } + @Override + @SuppressWarnings("deprecation") // 移除过期警告, 1.8 版本此函数没有警告 + public void setItemInHand(ItemStack itemStack) { + + getBukkitPlayer().setItemInHand(itemStack); + } + @Override public void setItemInMainHand(ItemStack itemStack) { diff --git a/src/com/minecraft/moonlake/api/player/SimpleMoonLakePlayer_v1_9.java b/src/com/minecraft/moonlake/api/player/SimpleMoonLakePlayer_v1_9.java index 1882aff8..878d3a75 100644 --- a/src/com/minecraft/moonlake/api/player/SimpleMoonLakePlayer_v1_9.java +++ b/src/com/minecraft/moonlake/api/player/SimpleMoonLakePlayer_v1_9.java @@ -176,6 +176,12 @@ public ItemStack getItemInOffHand() { return getBukkitPlayer().getInventory().getItemInOffHand(); } + @Override + public void setItemInHand(ItemStack itemStack) { + + setItemInMainHand(itemStack); + } + @Override public void setItemInMainHand(ItemStack itemStack) { diff --git a/src/com/minecraft/moonlake/api/player/inventory/InventoryPlayer.java b/src/com/minecraft/moonlake/api/player/inventory/InventoryPlayer.java index c740bb4a..26b63dcb 100644 --- a/src/com/minecraft/moonlake/api/player/inventory/InventoryPlayer.java +++ b/src/com/minecraft/moonlake/api/player/inventory/InventoryPlayer.java @@ -82,6 +82,13 @@ public interface InventoryPlayer extends InventoryHolder { */ ItemStack getItemOnCursor(); + /** + * 设置此玩家的手中物品 (注: 如果 Bukkit 版本为 1.9 或更高不建议使用此函数) + * + * @param itemStack 物品栈 + */ + void setItemInHand(ItemStack itemStack); + /** * 设置此玩家的主手中物品 * diff --git a/src/com/minecraft/moonlake/nms/packet/PacketPlayOutBookOpen.java b/src/com/minecraft/moonlake/nms/packet/PacketPlayOutBookOpen.java new file mode 100644 index 00000000..e34c9444 --- /dev/null +++ b/src/com/minecraft/moonlake/nms/packet/PacketPlayOutBookOpen.java @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2017 The MoonLake Authors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +package com.minecraft.moonlake.nms.packet; + +import com.minecraft.moonlake.api.player.MoonLakePlayer; +import com.minecraft.moonlake.manager.PlayerManager; +import com.minecraft.moonlake.nms.packet.exception.PacketException; +import com.minecraft.moonlake.nms.packet.wrapped.PacketDataSerializer; +import com.minecraft.moonlake.property.BooleanProperty; +import com.minecraft.moonlake.property.ObjectProperty; +import com.minecraft.moonlake.property.SimpleBooleanProperty; +import com.minecraft.moonlake.property.SimpleObjectProperty; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +/** + *

PacketPlayOutBookOpen

+ * 数据包输出书本打开(详细doc待补充...) + * + * @version 1.0 + * @author Month_Light + */ +public class PacketPlayOutBookOpen extends PacketAbstract { + + private final static String CHANNEL = "MC|BOpen"; + private ObjectProperty book; + private BooleanProperty onlyPacket; + + /** + * 数据包输出书本打开构造函数 + * + * @deprecated 已过时, 请使用 {@link #PacketPlayOutBookOpen(ItemStack, boolean)} + */ + @Deprecated + public PacketPlayOutBookOpen() { + + this(null, false); + } + + /** + * 数据包输出书本打开构造函数 + * + * @param itemStack 书本物品栈 + */ + public PacketPlayOutBookOpen(ItemStack itemStack) { + + this(itemStack, false); + } + + /** + * 数据包输出书本打开构造函数 + * + * @param itemStack 书本物品栈 + * @param onlyPacket 是否仅数据包 + */ + public PacketPlayOutBookOpen(ItemStack itemStack, boolean onlyPacket) { + + this.book = new SimpleObjectProperty<>(itemStack); + this.onlyPacket = new SimpleBooleanProperty(onlyPacket); + } + + /** + * 获取此数据包输出书本打开的书本物品栈 + * + * @return 书本物品栈 + */ + public ObjectProperty getBook() { + + return book; + } + + /** + * 获取此数据包输出书本打开是否仅数据包 + * + * @return 是否仅为数据包 + */ + public BooleanProperty getOnlyPacket() { + + return onlyPacket; + } + + @Override + public void send(Player... players) throws PacketException { + + if(fireEvent(this, players)) return; + + try { + + for(MoonLakePlayer mplayer : PlayerManager.adapter(players)) { + + ItemStack handItemStack = mplayer.getItemInHand(); + mplayer.setItemInHand(book.get()); + // 发送数据包 + new PacketPlayOutCustomPayload(CHANNEL, new PacketDataSerializer()).send(mplayer); + // 判断是否需要恢复原来的手中物品 + if(onlyPacket.get()) + mplayer.setItemInHand(handItemStack); + // 更新玩家的背包 + mplayer.updateInventory(); + } + } + catch (Exception e) { + + throw new PacketException("The nms packet play out book open send exception.", e); + } + } +} diff --git a/src/com/minecraft/moonlake/nms/packet/PacketPlayOutCustomPayload.java b/src/com/minecraft/moonlake/nms/packet/PacketPlayOutCustomPayload.java new file mode 100644 index 00000000..48b2cd07 --- /dev/null +++ b/src/com/minecraft/moonlake/nms/packet/PacketPlayOutCustomPayload.java @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2017 The MoonLake Authors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +package com.minecraft.moonlake.nms.packet; + +import com.minecraft.moonlake.nms.packet.exception.PacketException; +import com.minecraft.moonlake.nms.packet.exception.PacketInitializeException; +import com.minecraft.moonlake.nms.packet.wrapped.PacketDataSerializer; +import com.minecraft.moonlake.property.ObjectProperty; +import com.minecraft.moonlake.property.SimpleObjectProperty; +import com.minecraft.moonlake.property.SimpleStringProperty; +import com.minecraft.moonlake.property.StringProperty; +import org.bukkit.entity.Player; + +import static com.minecraft.moonlake.reflect.Reflect.*; + +/** + *

PacketPlayOutCustomPayload

+ * 数据包输出自定义通道数据(详细doc待补充...) + * + * @version 1.0 + * @author Month_Light + */ +public class PacketPlayOutCustomPayload extends PacketAbstract { + + private final static Class CLASS_PACKETPLAYOUTCUSTOMPAYLOAD; + + static { + + try { + + CLASS_PACKETPLAYOUTCUSTOMPAYLOAD = PackageType.MINECRAFT_SERVER.getClass("PacketPlayOutCustomPayload"); + } + catch (Exception e) { + + throw new PacketInitializeException("The nms packet play custom pay load reflect raw initialize exception.", e); + } + } + + private StringProperty channel; + private ObjectProperty data; + + /** + * 数据包输出自定义通道数据构造函数 + * + * @deprecated 已过时, 请使用 {@link #PacketPlayOutCustomPayload(String, PacketDataSerializer)} + */ + @Deprecated + public PacketPlayOutCustomPayload() { + + this("MC", new PacketDataSerializer()); + } + + /** + * 数据包输出自定义通道数据构造函数 + * + * @param channel 通道 + * @param data 数据 + */ + public PacketPlayOutCustomPayload(String channel, PacketDataSerializer data) { + + this.channel = new SimpleStringProperty(channel); + this.data = new SimpleObjectProperty<>(data); + } + + /** + * 获取此数据包输出自定义通道数据的通道 + * + * @return 通道 + */ + public StringProperty getChannel() { + + return channel; + } + + /** + * 获取此数据包输出自定义通道数据的数据 + * + * @return 数据 + */ + public ObjectProperty getData() { + + return data; + } + + @Override + public void send(Player... players) throws PacketException { + + if(super.fireEvent(this, players)) return; + + try { + + Object packet = instantiateObject(CLASS_PACKETPLAYOUTCUSTOMPAYLOAD, channel.get(), data.get().asNMS()); + + PacketFactory.get().sendPacket(players, packet); + } + catch (Exception e) { + + throw new PacketException("The nms packet play out custom pay load send exception.", e); + } + } +} diff --git a/src/com/minecraft/moonlake/nms/packet/wrapped/PacketDataSerializer.java b/src/com/minecraft/moonlake/nms/packet/wrapped/PacketDataSerializer.java new file mode 100644 index 00000000..5494a4b8 --- /dev/null +++ b/src/com/minecraft/moonlake/nms/packet/wrapped/PacketDataSerializer.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2017 The MoonLake Authors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +package com.minecraft.moonlake.nms.packet.wrapped; + +import com.minecraft.moonlake.nms.exception.NMSException; +import com.minecraft.moonlake.property.ObjectProperty; +import com.minecraft.moonlake.property.SimpleObjectProperty; +import com.minecraft.moonlake.reflect.Reflect; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; + +public class PacketDataSerializer { + + private final static Class CLASS_PACKETDATASERIALIZER; + + static { + + try { + + CLASS_PACKETDATASERIALIZER = Reflect.PackageType.MINECRAFT_SERVER.getClass("PacketDataSerializer"); + } + catch (Exception e) { + + throw new NMSException("The packet data serializer initialize exception.", e); + } + } + + private ObjectProperty byteBuf; + + public PacketDataSerializer() { + + this(Unpooled.buffer()); + } + + public PacketDataSerializer(ByteBuf byteBuf) { + + this.byteBuf = new SimpleObjectProperty<>(byteBuf); + } + + public ByteBuf getByteBuf() { + + return byteBuf.get(); + } + + public void setByteBuf(ByteBuf byteBuf) { + + this.byteBuf.set(byteBuf); + } + + @Override + public String toString() { + return "PacketDataSerializer{" + + "byteBuf=" + byteBuf.get() + + '}'; + } + + public Object asNMS() throws NMSException { + + try { + + return Reflect.instantiateObject(CLASS_PACKETDATASERIALIZER, getByteBuf()); + } + catch (Exception e) { + + throw new NMSException(); + } + } +} From 18c15148623e44eaa20a065504313221fc6aef47 Mon Sep 17 00:00:00 2001 From: u2g Date: Thu, 26 Jan 2017 22:14:57 +0800 Subject: [PATCH 14/16] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=8C=85=E9=80=9A=E9=81=93=E7=9B=91=E5=90=AC=E5=99=A8=E6=B2=A1?= =?UTF-8?q?=E6=9C=89=E5=88=A4=E6=96=AD=E5=B0=B1=E5=81=9A=E5=A4=84=E7=90=86?= =?UTF-8?q?=E5=AF=BC=E8=87=B4=E5=92=8C=20ProtocolLib=20=E6=8F=92=E4=BB=B6?= =?UTF-8?q?=E5=86=B2=E7=AA=81=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/packet/listener/PacketINCChannel.java | 10 ++++++++-- .../api/packet/listener/PacketListenerFactory.java | 12 ------------ 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/src/com/minecraft/moonlake/api/packet/listener/PacketINCChannel.java b/src/com/minecraft/moonlake/api/packet/listener/PacketINCChannel.java index 39be39c7..35195747 100644 --- a/src/com/minecraft/moonlake/api/packet/listener/PacketINCChannel.java +++ b/src/com/minecraft/moonlake/api/packet/listener/PacketINCChannel.java @@ -82,7 +82,10 @@ public void run() { try { - channel.pipeline().addBefore(KEY_HANDLER, KEY_PLAYER, new ChannelHandler(player)); + if(channel.pipeline().get(KEY_PLAYER) == null) { + + channel.pipeline().addBefore(KEY_HANDLER, KEY_PLAYER, new ChannelHandler(player)); + } } catch (Exception e) { @@ -232,7 +235,10 @@ public void run() { channel = (Channel) FIELD_CHANNEL.get(obj); } - channel.pipeline().remove(KEY_SERVER); + if(channel.pipeline().get(KEY_SERVER) != null) { + + channel.pipeline().remove(KEY_SERVER); + } } catch (Exception e) { } diff --git a/src/com/minecraft/moonlake/api/packet/listener/PacketListenerFactory.java b/src/com/minecraft/moonlake/api/packet/listener/PacketListenerFactory.java index f4181c12..83b1ebd8 100644 --- a/src/com/minecraft/moonlake/api/packet/listener/PacketListenerFactory.java +++ b/src/com/minecraft/moonlake/api/packet/listener/PacketListenerFactory.java @@ -35,7 +35,6 @@ import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.plugin.Plugin; -import java.net.InetSocketAddress; import java.util.ArrayList; import java.util.List; @@ -245,15 +244,4 @@ public static int getHandlersSize() { */ private PacketListenerFactory() { } - - /** - * 将指定网络套子节地址转换为地址加端口形式 - * - * @param address 网络套子节地址 - * @return 地址:端口 (例: 127.0.0.1:25565) - */ - private static String toAddress(InetSocketAddress address) { - - return address.getHostName() + ":" + address.getPort(); - } } From 2e6085a4ac6d107cb362003e8115a8460db48662 Mon Sep 17 00:00:00 2001 From: u2g Date: Thu, 26 Jan 2017 23:34:37 +0800 Subject: [PATCH 15/16] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=8C=85=20PacketPlayOutBookOpen=20=E5=9C=A8=201.9=20=E6=88=96?= =?UTF-8?q?=E6=9B=B4=E9=AB=98=E7=9A=84=E6=9C=8D=E5=8A=A1=E7=AB=AF=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E4=B8=8D=E5=B7=A5=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nms/packet/PacketPlayOutBookOpen.java | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/com/minecraft/moonlake/nms/packet/PacketPlayOutBookOpen.java b/src/com/minecraft/moonlake/nms/packet/PacketPlayOutBookOpen.java index e34c9444..def20659 100644 --- a/src/com/minecraft/moonlake/nms/packet/PacketPlayOutBookOpen.java +++ b/src/com/minecraft/moonlake/nms/packet/PacketPlayOutBookOpen.java @@ -26,6 +26,8 @@ import com.minecraft.moonlake.property.ObjectProperty; import com.minecraft.moonlake.property.SimpleBooleanProperty; import com.minecraft.moonlake.property.SimpleObjectProperty; +import com.minecraft.moonlake.reflect.Reflect; +import io.netty.buffer.ByteBuf; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; @@ -107,7 +109,7 @@ public void send(Player... players) throws PacketException { ItemStack handItemStack = mplayer.getItemInHand(); mplayer.setItemInHand(book.get()); // 发送数据包 - new PacketPlayOutCustomPayload(CHANNEL, new PacketDataSerializer()).send(mplayer); + new PacketPlayOutCustomPayload(CHANNEL, handlerEnumHand()).send(mplayer); // 判断是否需要恢复原来的手中物品 if(onlyPacket.get()) mplayer.setItemInHand(handItemStack); @@ -120,4 +122,26 @@ public void send(Player... players) throws PacketException { throw new PacketException("The nms packet play out book open send exception.", e); } } + + private static PacketDataSerializer handlerEnumHand() { + + if(Reflect.getServerVersionNumber() <= 8) + // 1.8 版本不需要这个 EnumHand 的 + return new PacketDataSerializer(); + + // 处理 1.9+ 版本打开书本需要枚举手的数据 + // 0 为 MAIN_HAND, 1 为 OFF_HAND + PacketDataSerializer data = new PacketDataSerializer(); + writeEnumHand(data.getByteBuf(), 0); + return data; + } + + private static void writeEnumHand(ByteBuf byteBuf, int i) { + // 此代码摘自 PacketDataSerializer 的 d(int i) 函数 + while((i & 0xffffff80) != 0) { + byteBuf.writeByte(i & 0x7f | 0x80); + i >>>= 7; + } + byteBuf.writeByte(i); + } } From a3d3937fd0ed0d4183e5898c71d19c7308310e6d Mon Sep 17 00:00:00 2001 From: u2g Date: Fri, 27 Jan 2017 13:05:45 +0800 Subject: [PATCH 16/16] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=88=B0=20v1.9-a1=20?= =?UTF-8?q?=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++-- config.yml | 6 +++--- plugin.yml | 2 +- src/com/minecraft/moonlake/MoonLakePlugin.java | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index e789002b..316f5209 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -# MoonLake [![GitHub version](https://d25lcipzij17d.cloudfront.net/badge.svg?id=gh&type=6&v=1.9-alpha&x2=0)](https://github.com/u2g/MoonLake) [![Open Source Love](https://badges.frapsoft.com/os/v1/open-source.svg?v=102)](https://github.com/u2g/MoonLake) [![Open Source Love](https://badges.frapsoft.com/os/gpl/gpl.svg?v=102)](https://github.com/u2g/MoonLake) +# MoonLake [![GitHub version](https://d25lcipzij17d.cloudfront.net/badge.svg?id=gh&type=6&v=1.9-a1&x2=0)](https://github.com/u2g/MoonLake) [![Open Source Love](https://badges.frapsoft.com/os/v1/open-source.svg?v=102)](https://github.com/u2g/MoonLake) [![Open Source Love](https://badges.frapsoft.com/os/gpl/gpl.svg?v=102)](https://github.com/u2g/MoonLake) Minecraft MoonLake Core API Plugin -By Month_Light Ver: 1.9-alpha +By Month_Light Ver: 1.9-a1 ## 简介 这个插件提供了大量的 API 功能,实现了一些 Bukkit 无法做到的 NMS 功能
diff --git a/config.yml b/config.yml index 126a153e..ae813565 100644 --- a/config.yml +++ b/config.yml @@ -1,14 +1,14 @@ ################################ # MoonLake Core API Plugin # -# By Month_Light Ver: 1.9-alpha # +# By Month_Light Ver: 1.9-a1 # ################################ # 插件版本号: 此项请勿修改! -version: '1.9-alpha' +version: '1.9-a1' # 数据包通道监听器 # 此项可设置是否开启这个功能 # 如果关闭则插件中的一些API功能将无法使用 # 例如: MoonLakePlayerJoinEvent # PS: 此项是实时监听客户端与服务端的数据包交流 -PacketChannelListener: false +PacketChannelListener: true diff --git a/plugin.yml b/plugin.yml index 9b1de075..c3424fd5 100644 --- a/plugin.yml +++ b/plugin.yml @@ -1,6 +1,6 @@ name: MoonLake main: com.minecraft.moonlake.MoonLakePlugin -version: 1.9-alpha +version: 1.9-a1 prefix: MoonLake description: Minecraft MoonLake Core API Plugin website: http://www.mcyszh.com/ diff --git a/src/com/minecraft/moonlake/MoonLakePlugin.java b/src/com/minecraft/moonlake/MoonLakePlugin.java index cf856ea3..748e1456 100644 --- a/src/com/minecraft/moonlake/MoonLakePlugin.java +++ b/src/com/minecraft/moonlake/MoonLakePlugin.java @@ -32,7 +32,7 @@ *
*
*

Minecraft MoonLake Core API Plugin

- *

By Month_Light Ver: 1.9-alpha

+ *

By Month_Light Ver: 1.9-a1

*

Website: MoonLake Website

*

QQ Group: 377607025 -> Jump

*
@@ -67,7 +67,7 @@ *

修改操作请您遵守 GPLv3 协议,您必须公开修改过的所有代码!

*
* - * @version 1.9-alpha + * @version 1.9-a1 * @author Month_Light */ public class MoonLakePlugin extends JavaPlugin implements MoonLake {