diff --git a/README.md b/README.md
index ced0a38..3b6ed98 100644
--- a/README.md
+++ b/README.md
@@ -43,6 +43,9 @@
- **支持跨服**
- **gui显示自己的权限包**
- **语言支持整理**
+- **支持自定义哪个玩家的头颅**
+- **支持物品发光(附魔效果)**
+- **玩家进入游戏时赋予权限更早**
- 手动删除过期的或无效数据
- 取消前置插件
diff --git a/config/packages.yml b/config/packages.yml
index 6f7b47d..82d53fa 100644
--- a/config/packages.yml
+++ b/config/packages.yml
@@ -12,8 +12,17 @@ packages:
# Permission package display name.
displayName: '&4Test Package'
# 显示的物品类型.
+ # 可以使用id, 但不可与type同时使用.
+ # 可以定义物品的种类, 特殊的如头颅可以指定哪个玩家的头颅.
# Show the type of item.
+ # You can use 'id', but you can't use 'type' at the same time.
+ # You can define the type of item, such as skull can set which player's head.
+ #id: 397
+ #type: SKULL_ITEM:5
+ #type: SKULL_ITEM:MHF_Present1
type: NETHER_STAR
+ # 是否有附魔发光的特效
+ glowing: false
# 标签.
# Lores.
lores:
diff --git a/pom.xml b/pom.xml
index e79b2ac..7f68fe8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
4.0.0
gg.frog.mc
permissionstime
- 0.1.1-SNAPSHOT
+ 0.1.2-SNAPSHOT
jar
PermissionsTime
支持跨服的权限限时插件
@@ -38,7 +38,7 @@
org.bukkit
bukkit
- 1.12-pre6-SNAPSHOT
+ 1.8-R0.1-SNAPSHOT
jar
compile
diff --git a/src/main/gg/frog/mc/permissionstime/config/PackagesCfg.java b/src/main/gg/frog/mc/permissionstime/config/PackagesCfg.java
index 456e4eb..f36e79c 100644
--- a/src/main/gg/frog/mc/permissionstime/config/PackagesCfg.java
+++ b/src/main/gg/frog/mc/permissionstime/config/PackagesCfg.java
@@ -19,6 +19,7 @@ import gg.frog.mc.permissionstime.PluginMain;
import gg.frog.mc.permissionstime.model.cfg.PermissionPackageBean;
import gg.frog.mc.permissionstime.utils.StrUtil;
import gg.frog.mc.permissionstime.utils.config.PluginConfig;
+import gg.frog.mc.permissionstime.utils.nms.ItemUtil;
public class PackagesCfg extends PluginConfig {
@@ -66,35 +67,42 @@ public class PackagesCfg extends PluginConfig {
if (ppb != null) {
Material type = null;
int exid = 0;
+ String skullOwner = null;
if (ppb.getType() != null) {
String[] args = ppb.getType().split(":");
- try {
- switch (args.length) {
- case 2:
- exid = Integer.parseInt(args[1]);
- case 1:
- type = Material.getMaterial(args[0].toUpperCase(Locale.ENGLISH));
+ type = Material.getMaterial(args[0].toUpperCase(Locale.ENGLISH));
+ if (args.length == 2) {
+ try {
+ exid = Integer.parseInt(args[1]);
+ } catch (NumberFormatException e) {
+ if (Material.SKULL_ITEM.equals(type)) {
+ exid = 3;
+ skullOwner = args[1];
+ } else {
+ e.printStackTrace();
+ }
}
- } catch (NumberFormatException e) {
- e.printStackTrace();
}
} else if (ppb.getId() != null) {
String[] args = ppb.getId().split(":");
- try {
- switch (args.length) {
- case 2:
- exid = Integer.parseInt(args[1]);
- case 1:
- int id = Integer.parseInt(args[0]);
- type = Material.getMaterial(id);
+ int id = Integer.parseInt(args[0]);
+ type = Material.getMaterial(id);
+ if (args.length == 2) {
+ try {
+ exid = Integer.parseInt(args[1]);
+ } catch (NumberFormatException e) {
+ if (Material.SKULL_ITEM.equals(type)) {
+ exid = 3;
+ skullOwner = args[1];
+ } else {
+ e.printStackTrace();
+ }
}
- } catch (NumberFormatException e) {
- e.printStackTrace();
}
}
if (type != null) {
- ItemStack items = new ItemStack(type, 1, (short) 0, (byte) exid);
- ItemMeta meta = items.getItemMeta();
+ ItemStack item = new ItemStack(type, 1, (short) 0, (byte) exid);
+ ItemMeta meta = item.getItemMeta();
meta.setDisplayName(StrUtil.messageFormat(ppb.getDisplayName() + "&r(" + name + ")"));
List lores = new ArrayList();
for (String lore : ppb.getLores()) {
@@ -102,8 +110,14 @@ public class PackagesCfg extends PluginConfig {
}
lores.add("");
meta.setLore(lores);
- items.setItemMeta(meta);
- return items;
+ item.setItemMeta(meta);
+ if (ppb.getGlowing() && !meta.hasEnchants()) {
+ item = ItemUtil.addEnchantLight(item);
+ }
+ if (skullOwner != null) {
+ item = ItemUtil.addSkullOwner(item, skullOwner);
+ }
+ return item;
}
}
return null;
diff --git a/src/main/gg/frog/mc/permissionstime/database/SqlManager.java b/src/main/gg/frog/mc/permissionstime/database/SqlManager.java
index 9eb5380..640c7be 100644
--- a/src/main/gg/frog/mc/permissionstime/database/SqlManager.java
+++ b/src/main/gg/frog/mc/permissionstime/database/SqlManager.java
@@ -8,7 +8,6 @@ import gg.frog.mc.permissionstime.config.PluginCfg;
import gg.frog.mc.permissionstime.database.impl.MySQLPlayerDataDao;
import gg.frog.mc.permissionstime.database.impl.SqlitePlayerDataDao;
import gg.frog.mc.permissionstime.model.db.PlayerDataBean;
-import gg.frog.mc.permissionstime.utils.StrUtil;
import lib.PatPeter.SQLibrary.Database;
import lib.PatPeter.SQLibrary.MySQL;
import lib.PatPeter.SQLibrary.SQLite;
diff --git a/src/main/gg/frog/mc/permissionstime/listener/MainListener.java b/src/main/gg/frog/mc/permissionstime/listener/MainListener.java
index 18d13f4..fe63a04 100644
--- a/src/main/gg/frog/mc/permissionstime/listener/MainListener.java
+++ b/src/main/gg/frog/mc/permissionstime/listener/MainListener.java
@@ -3,10 +3,11 @@ package gg.frog.mc.permissionstime.listener;
import java.util.List;
import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
-import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerKickEvent;
+import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import gg.frog.mc.permissionstime.PluginMain;
@@ -24,28 +25,17 @@ public class MainListener implements Listener {
this.pm = pm;
}
- /**
- * 一个监听器例子
- *
- * @param e
- */
- @EventHandler
- public void onJoin(PlayerJoinEvent event) {
- new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- List pdbList = pm.getSqlManager().getTime(event.getPlayer().getUniqueId().toString());
- PermissionPackageBean.reloadPlayerPermissions(event.getPlayer(), pdbList, pm);
- } catch (Exception e) {
- e.printStackTrace();
- event.getPlayer().sendMessage(StrUtil.messageFormat(PluginCfg.PLUGIN_PREFIX + LangCfg.MSG_FAIL_SET_PERMISSION));
- }
- }
- }).start();
+ @EventHandler(priority = EventPriority.LOWEST)
+ public void onJoin(PlayerLoginEvent event) {
+ try {
+ List pdbList = pm.getSqlManager().getTime(event.getPlayer().getUniqueId().toString());
+ PermissionPackageBean.reloadPlayerPermissions(event.getPlayer(), pdbList, pm, false);
+ } catch (Exception e) {
+ e.printStackTrace();
+ event.getPlayer().sendMessage(StrUtil.messageFormat(PluginCfg.PLUGIN_PREFIX + LangCfg.MSG_FAIL_SET_PERMISSION));
+ }
}
- @EventHandler
public void onQuit(PlayerQuitEvent event) {
new Thread(new Runnable() {
@Override
@@ -59,7 +49,6 @@ public class MainListener implements Listener {
}).start();
}
- @EventHandler
public void onKick(PlayerKickEvent event) {
new Thread(new Runnable() {
@Override
diff --git a/src/main/gg/frog/mc/permissionstime/model/cfg/PermissionPackageBean.java b/src/main/gg/frog/mc/permissionstime/model/cfg/PermissionPackageBean.java
index e431711..9054d49 100644
--- a/src/main/gg/frog/mc/permissionstime/model/cfg/PermissionPackageBean.java
+++ b/src/main/gg/frog/mc/permissionstime/model/cfg/PermissionPackageBean.java
@@ -14,8 +14,11 @@ import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.scheduler.BukkitTask;
import gg.frog.mc.permissionstime.PluginMain;
+import gg.frog.mc.permissionstime.config.LangCfg;
import gg.frog.mc.permissionstime.config.PackagesCfg;
+import gg.frog.mc.permissionstime.config.PluginCfg;
import gg.frog.mc.permissionstime.model.db.PlayerDataBean;
+import gg.frog.mc.permissionstime.utils.StrUtil;
import gg.frog.mc.permissionstime.utils.config.IConfigBean;
import net.milkbowl.vault.permission.Permission;
@@ -30,8 +33,9 @@ public class PermissionPackageBean implements IConfigBean {
private String displayName = null;
private String id;
private String type;
+ private Boolean glowing;
private List lores = new ArrayList<>();
- private Boolean global = null;
+ private Boolean global;
private List permissions = new ArrayList<>();
private List groups = new ArrayList<>();
private static Map taskMap = new ConcurrentHashMap<>();
@@ -60,6 +64,14 @@ public class PermissionPackageBean implements IConfigBean {
this.type = type;
}
+ public Boolean getGlowing() {
+ return glowing;
+ }
+
+ public void setGlowing(Boolean glowing) {
+ this.glowing = glowing;
+ }
+
public List getLores() {
return lores;
}
@@ -98,6 +110,7 @@ public class PermissionPackageBean implements IConfigBean {
config.set("displayName", displayName);
config.set("id", id);
config.set("type", type);
+ config.set("glowing", glowing);
config.set("lores", lores);
config.set("global", global);
config.set("permissions", permissions);
@@ -116,6 +129,7 @@ public class PermissionPackageBean implements IConfigBean {
if (id == null && type == null) {
type = "NETHER_STAR";
}
+ glowing = config.getBoolean("glowing");
lores = config.getStringList("lores");
global = config.getBoolean("global");
permissions = config.getStringList("permissions");
@@ -124,7 +138,7 @@ public class PermissionPackageBean implements IConfigBean {
@Override
public String toString() {
- return "PermissionPackageBean [displayName=" + displayName + ", id=" + id + ", type=" + type + ", lores=" + lores + ", global=" + global + ", permissions=" + permissions + ", groups=" + groups + "]";
+ return "PermissionPackageBean [displayName=" + displayName + ", id=" + id + ", type=" + type + ", glowing=" + glowing + ", lores=" + lores + ", global=" + global + ", permissions=" + permissions + ", groups=" + groups + "]";
}
private void givePlayer(OfflinePlayer player, Server server, Permission permission) {
@@ -196,6 +210,10 @@ public class PermissionPackageBean implements IConfigBean {
}
public static void reloadPlayerPermissions(OfflinePlayer player, List pdbList, PluginMain plugin) {
+ reloadPlayerPermissions(player, pdbList, plugin, true);
+ }
+
+ public static void reloadPlayerPermissions(OfflinePlayer player, List pdbList, PluginMain plugin, boolean async) {
long delay = -1;
long now = new Date().getTime();
PermissionPackageBean addPpb = new PermissionPackageBean();
@@ -219,13 +237,23 @@ public class PermissionPackageBean implements IConfigBean {
subPpb.getGroups().removeAll(p.getGroups());
}
}
- plugin.getServer().getScheduler().runTask(plugin, new Runnable() {
- @Override
- public void run() {
- subPpb.clearPlayer(player, plugin.getServer(), plugin.getPermission());
- addPpb.givePlayer(player, plugin.getServer(), plugin.getPermission());
- }
- });
+ if (async) {
+ plugin.getServer().getScheduler().runTask(plugin, new Runnable() {
+ @Override
+ public void run() {
+ try {
+ subPpb.clearPlayer(player, plugin.getServer(), plugin.getPermission());
+ addPpb.givePlayer(player, plugin.getServer(), plugin.getPermission());
+ } catch (Exception e) {
+ e.printStackTrace();
+ player.getPlayer().sendMessage(StrUtil.messageFormat(PluginCfg.PLUGIN_PREFIX + LangCfg.MSG_FAIL_SET_PERMISSION));
+ }
+ }
+ });
+ } else {
+ subPpb.clearPlayer(player, plugin.getServer(), plugin.getPermission());
+ addPpb.givePlayer(player, plugin.getServer(), plugin.getPermission());
+ }
BukkitTask task = taskMap.get(player.getUniqueId().toString());
if (task != null) {
plugin.getServer().getScheduler().cancelTask(task.getTaskId());
diff --git a/src/main/gg/frog/mc/permissionstime/utils/config/PluginConfig.java b/src/main/gg/frog/mc/permissionstime/utils/config/PluginConfig.java
index 89b1463..54ae939 100644
--- a/src/main/gg/frog/mc/permissionstime/utils/config/PluginConfig.java
+++ b/src/main/gg/frog/mc/permissionstime/utils/config/PluginConfig.java
@@ -18,6 +18,8 @@ import org.bukkit.configuration.file.YamlConfiguration;
import com.google.common.base.Charsets;
import gg.frog.mc.permissionstime.PluginMain;
+import gg.frog.mc.permissionstime.config.PluginCfg;
+import gg.frog.mc.permissionstime.utils.StrUtil;
/**
* 配置操作
@@ -105,7 +107,7 @@ public abstract class PluginConfig {
try {
getConfig().save(configFile);
} catch (IOException ex) {
- PluginMain.LOG.log(Level.SEVERE, "Could not save config to " + configFile, ex);
+ PluginMain.LOG.log(Level.SEVERE, StrUtil.messageFormat(PluginCfg.PLUGIN_PREFIX + "Could not save config to " + configFile), ex);
}
}
@@ -114,7 +116,7 @@ public abstract class PluginConfig {
getConfig().save(configFile);
reloadConfig();
} catch (IOException ex) {
- PluginMain.LOG.log(Level.SEVERE, "Could not save config to " + configFile, ex);
+ PluginMain.LOG.log(Level.SEVERE, StrUtil.messageFormat(PluginCfg.PLUGIN_PREFIX + "Could not save config to " + configFile), ex);
}
}
diff --git a/src/main/gg/frog/mc/permissionstime/utils/nms/ItemUtil.java b/src/main/gg/frog/mc/permissionstime/utils/nms/ItemUtil.java
new file mode 100644
index 0000000..4875cf7
--- /dev/null
+++ b/src/main/gg/frog/mc/permissionstime/utils/nms/ItemUtil.java
@@ -0,0 +1,124 @@
+package gg.frog.mc.permissionstime.utils.nms;
+
+import java.lang.reflect.Method;
+
+import org.bukkit.enchantments.Enchantment;
+import org.bukkit.inventory.ItemStack;
+
+import gg.frog.mc.permissionstime.PluginMain;
+import gg.frog.mc.permissionstime.config.PluginCfg;
+import gg.frog.mc.permissionstime.utils.StrUtil;
+
+public class ItemUtil {
+
+ private static Class> nbtBaseClass;
+ private static Class> nbtTagCompoundClass;
+ private static Class> nbtTagStringClass;
+ private static Class> nbtTagIntClass;
+// private static Class> nbtTagShortClass;
+// private static Class> nbtTagListClass;
+ private static Class> nmsItemstackClass;
+ private static Method asNmsCopyMethod;
+ private static Method asCraftMirrorMethod;
+ private static Method hasTagMethod;
+ private static Method getTagMethod;
+ private static Method setTagMethod;
+ private static Method nbtSetMethod;
+// private static Method nbtListAddSetMethod;
+ private static boolean setupOk;
+
+ static {
+ try {
+ nmsItemstackClass = NMSUtil.getNmsClass("ItemStack");// add
+ nbtBaseClass = NMSUtil.getNmsClass("NBTBase");// dy
+ nbtTagStringClass = NMSUtil.getNmsClass("NBTTagString");// dx
+ nbtTagIntClass = NMSUtil.getNmsClass("NBTTagInt");// dp
+ nbtTagCompoundClass = NMSUtil.getNmsClass("NBTTagCompound");// dh
+// nbtTagShortClass = NMSUtil.getNmsClass("NBTTagShort");
+// nbtTagListClass = NMSUtil.getNmsClass("NBTTagList");
+ asNmsCopyMethod = NMSUtil.getObcClass("inventory.CraftItemStack").getMethod("asNMSCopy", new Class[] { ItemStack.class });
+ asCraftMirrorMethod = NMSUtil.getObcClass("inventory.CraftItemStack").getMethod("asCraftMirror", new Class[] { nmsItemstackClass });
+ hasTagMethod = nmsItemstackClass.getMethod("hasTag", new Class[0]);// p
+ getTagMethod = nmsItemstackClass.getMethod("getTag", new Class[0]);// q
+ setTagMethod = nmsItemstackClass.getMethod("setTag", new Class[] { nbtTagCompoundClass });// d
+ nbtSetMethod = nbtTagCompoundClass.getMethod("set", new Class[] { String.class, nbtBaseClass });// a
+// nbtListAddSetMethod = nbtTagListClass.getMethod("add", new Class[] { nbtBaseClass });
+ setupOk = true;
+ } catch (Exception e) {
+ e.printStackTrace();
+// try {
+// nmsItemstackClass = Class.forName("add");
+// nbtBaseClass = Class.forName("dy");
+// nbtTagStringClass = Class.forName("dx");
+// nbtTagIntClass = Class.forName("dp");
+// nbtTagCompoundClass = Class.forName("dh");
+// asNmsCopyMethod = NMSUtil.getObcClass("inventory.CraftItemStack").getMethod("asNMSCopy", new Class[] { ItemStack.class });
+// asCraftMirrorMethod = NMSUtil.getObcClass("inventory.CraftItemStack").getMethod("asCraftMirror", new Class[] { nmsItemstackClass });
+// hasTagMethod = nmsItemstackClass.getMethod("func_77942_o", new Class[0]);
+// getTagMethod = nmsItemstackClass.getMethod("func_77978_p", new Class[0]);
+// setTagMethod = nmsItemstackClass.getMethod("func_77982_d", new Class[] { nbtTagCompoundClass });
+// nbtSetMethod = nbtTagCompoundClass.getMethod("func_74782_a", new Class[] { String.class, nbtBaseClass });
+// setupOk = true;
+// } catch (Exception ex) {
+// ex.printStackTrace();
+// PluginMain.LOG.warning(StrUtil.messageFormat(PluginCfg.PLUGIN_PREFIX + "ItemUtil setup fail. Some functions are unavailable."));
+// }
+ PluginMain.LOG.warning(StrUtil.messageFormat(PluginCfg.PLUGIN_PREFIX + "ItemUtil setup fail. Some functions are unavailable."));
+ }
+ }
+
+ public static ItemStack addEnchantLight(ItemStack item) {
+ item.addUnsafeEnchantment(Enchantment.PROTECTION_ENVIRONMENTAL, 0);
+ if (!NMSUtil.getServerVersion().startsWith("v1_7_") && setupOk) {
+ try {
+ Object nmsItemstack = asNmsCopyMethod.invoke(null, new Object[] { item });
+ if (nmsItemstack == null) {
+ return item;
+ }
+ Object nbtCompound = null;
+ if (((Boolean) hasTagMethod.invoke(nmsItemstack, new Object[0])).booleanValue()) {
+ nbtCompound = getTagMethod.invoke(nmsItemstack, new Object[0]);
+ } else {
+ nbtCompound = nbtTagCompoundClass.newInstance();
+ setTagMethod.invoke(nmsItemstack, new Object[] { nbtCompound });
+ }
+ if (nbtCompound == null) {
+ return item;
+ }
+ Object nbtHideFlags = nbtTagIntClass.getConstructor(int.class).newInstance(1);
+ nbtSetMethod.invoke(nbtCompound, new Object[] { "HideFlags", nbtHideFlags });
+ return (ItemStack) asCraftMirrorMethod.invoke(null, new Object[] { nmsItemstack });
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ return item;
+ }
+
+ public static ItemStack addSkullOwner(ItemStack item, String name) {
+ if (setupOk) {
+ try {
+ Object nmsItemstack = asNmsCopyMethod.invoke(null, new Object[] { item });
+ if (nmsItemstack == null) {
+ return item;
+ }
+ Object nbtCompound = null;
+ if (((Boolean) hasTagMethod.invoke(nmsItemstack, new Object[0])).booleanValue()) {
+ nbtCompound = getTagMethod.invoke(nmsItemstack, new Object[0]);
+ } else {
+ nbtCompound = nbtTagCompoundClass.newInstance();
+ setTagMethod.invoke(nmsItemstack, new Object[] { nbtCompound });
+ }
+ if (nbtCompound == null) {
+ return item;
+ }
+ Object nbtString = nbtTagStringClass.getConstructor(String.class).newInstance(name);
+ nbtSetMethod.invoke(nbtCompound, new Object[] { "SkullOwner", nbtString });
+ return (ItemStack) asCraftMirrorMethod.invoke(null, new Object[] { nmsItemstack });
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ return item;
+ }
+}
diff --git a/src/main/gg/frog/mc/permissionstime/utils/nms/NMSUtil.java b/src/main/gg/frog/mc/permissionstime/utils/nms/NMSUtil.java
new file mode 100644
index 0000000..acf354c
--- /dev/null
+++ b/src/main/gg/frog/mc/permissionstime/utils/nms/NMSUtil.java
@@ -0,0 +1,26 @@
+package gg.frog.mc.permissionstime.utils.nms;
+
+import org.bukkit.Bukkit;
+
+public class NMSUtil {
+
+ private static String serverVersion;
+
+ static {
+ String packageName = Bukkit.getServer().getClass().getPackage().getName();
+ serverVersion = packageName.substring(packageName.lastIndexOf('.') + 1);
+ }
+
+ public static String getServerVersion() {
+ return serverVersion;
+ }
+
+ public static Class> getNmsClass(String name) throws ClassNotFoundException {
+ return Class.forName("net.minecraft.server." + getServerVersion() + "." + name);
+ }
+
+ public static Class> getObcClass(String name) throws ClassNotFoundException {
+ return Class.forName("org.bukkit.craftbukkit." + getServerVersion() + "." + name);
+ }
+
+}
diff --git a/src/resources/packages.yml b/src/resources/packages.yml
index 6f7b47d..82d53fa 100644
--- a/src/resources/packages.yml
+++ b/src/resources/packages.yml
@@ -12,8 +12,17 @@ packages:
# Permission package display name.
displayName: '&4Test Package'
# 显示的物品类型.
+ # 可以使用id, 但不可与type同时使用.
+ # 可以定义物品的种类, 特殊的如头颅可以指定哪个玩家的头颅.
# Show the type of item.
+ # You can use 'id', but you can't use 'type' at the same time.
+ # You can define the type of item, such as skull can set which player's head.
+ #id: 397
+ #type: SKULL_ITEM:5
+ #type: SKULL_ITEM:MHF_Present1
type: NETHER_STAR
+ # 是否有附魔发光的特效
+ glowing: false
# 标签.
# Lores.
lores: