diff --git a/README.md b/README.md
index 179fc99..e2c0c36 100644
--- a/README.md
+++ b/README.md
@@ -51,6 +51,7 @@
- **提示权限包到期**
- **玩家登录时删除过期的或无效数据**
- **提示剩余时间**
+- **权限包到期可执行自定义命令**
- 取消前置插件
diff --git a/config/packages.yml b/config/packages.yml
index 82d53fa..7d831ed 100644
--- a/config/packages.yml
+++ b/config/packages.yml
@@ -42,3 +42,8 @@ packages:
groups:
- group1
- group2:world1
+ # 权限包过期后执行的控制台命令
+ # Package expire console commands.
+ expireCommands:
+ - 'bc %player% 的权限包到期了.'
+ - 'bc 请及时续期.'
diff --git a/pom.xml b/pom.xml
index 7ab6edb..81b8dfd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
4.0.0
gg.frog.mc
permissionstime
- 0.2.4-SNAPSHOT
+ 0.3.0-SNAPSHOT
jar
PermissionsTime
支持跨服的权限限时插件
@@ -34,6 +34,10 @@
bstats-repo
http://repo.bstats.org/content/repositories/releases/
+
+ placeholderapi
+ http://repo.extendedclip.com/content/repositories/placeholderapi/
+
@@ -54,6 +58,12 @@
1.6
provided
+
+ me.clip
+ placeholderapi
+ 2.0.8
+ provided
+
lib.PatPeter.SQLibrary
SQLibrary
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 2526cb5..6d877af 100644
--- a/src/main/gg/frog/mc/permissionstime/model/cfg/PermissionPackageBean.java
+++ b/src/main/gg/frog/mc/permissionstime/model/cfg/PermissionPackageBean.java
@@ -31,279 +31,305 @@ import net.milkbowl.vault.permission.Permission;
*/
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;
- private List permissions = new ArrayList<>();
- private List groups = new ArrayList<>();
- private static Map taskMap = new ConcurrentHashMap<>();
+ private String displayName = null;
+ private String id;
+ private String type;
+ private Boolean glowing;
+ private List lores = new ArrayList<>();
+ private Boolean global;
+ private List permissions = new ArrayList<>();
+ private List groups = new ArrayList<>();
+ private List expireCommands = new ArrayList<>();
+ private static Map taskMap = new ConcurrentHashMap<>();
- public String getDisplayName() {
- return displayName;
- }
+ public String getDisplayName() {
+ return displayName;
+ }
- public void setDisplayName(String displayName) {
- this.displayName = displayName;
- }
+ public void setDisplayName(String displayName) {
+ this.displayName = displayName;
+ }
- public String getId() {
- return id;
- }
+ public String getId() {
+ return id;
+ }
- public void setId(String id) {
- this.id = id;
- }
+ public void setId(String id) {
+ this.id = id;
+ }
- public String getType() {
- return type;
- }
+ public String getType() {
+ return type;
+ }
- public void setType(String type) {
- this.type = type;
- }
+ public void setType(String type) {
+ this.type = type;
+ }
- public Boolean getGlowing() {
- return glowing;
- }
+ public Boolean getGlowing() {
+ return glowing;
+ }
- public void setGlowing(Boolean glowing) {
- this.glowing = glowing;
- }
+ public void setGlowing(Boolean glowing) {
+ this.glowing = glowing;
+ }
- public List getLores() {
- return lores;
- }
+ public List getLores() {
+ return lores;
+ }
- public void setLores(List lores) {
- this.lores = lores;
- }
+ public void setLores(List lores) {
+ this.lores = lores;
+ }
- public Boolean getGlobal() {
- return global;
- }
+ public Boolean getGlobal() {
+ return global;
+ }
- public void setGlobal(Boolean global) {
- this.global = global;
- }
+ public void setGlobal(Boolean global) {
+ this.global = global;
+ }
- public List getPermissions() {
- return permissions;
- }
+ public List getPermissions() {
+ return permissions;
+ }
- public void setPermissions(List permissions) {
- this.permissions = permissions;
- }
+ public void setPermissions(List permissions) {
+ this.permissions = permissions;
+ }
- public List getGroups() {
- return groups;
- }
+ public List getGroups() {
+ return groups;
+ }
- public void setGroups(List groups) {
- this.groups = groups;
- }
+ public void setGroups(List groups) {
+ this.groups = groups;
+ }
- @Override
- public YamlConfiguration toConfig() {
- YamlConfiguration config = new YamlConfiguration();
- 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);
- config.set("groups", groups);
- return config;
- }
+ public List getExpireCommands() {
+ return expireCommands;
+ }
- @Override
- public void toConfigBean(MemorySection config) {
- displayName = config.getString("displayName");
- if (displayName == null) {
- displayName = "No Name";
- }
- id = config.getString("id");
- type = config.getString("type");
- if (id == null && type == null) {
- type = "NETHER_STAR";
- }
- glowing = config.getBoolean("glowing");
- lores = config.getStringList("lores");
- global = config.getBoolean("global");
- permissions = config.getStringList("permissions");
- groups = config.getStringList("groups");
- }
+ public void setExpireCommands(List expireCommands) {
+ this.expireCommands = expireCommands;
+ }
- @Override
- public String toString() {
- return "PermissionPackageBean [displayName=" + displayName + ", id=" + id + ", type=" + type + ", glowing=" + glowing + ", lores=" + lores + ", global=" + global + ", permissions=" + permissions + ", groups=" + groups + "]";
- }
+ @Override
+ public YamlConfiguration toConfig() {
+ YamlConfiguration config = new YamlConfiguration();
+ 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);
+ config.set("groups", groups);
+ config.set("expireCommands", expireCommands);
+ return config;
+ }
- private void givePlayer(OfflinePlayer player, Server server, Permission permission) {
- List worlds = server.getWorlds();
- for (String pem : permissions) {
- String[] args = pem.split(":");
- pem = args[0];
- if (args.length > 1) {
- for (int i = 1; i < args.length; i++) {
- String worldName = args[i];
- permission.playerAdd(worldName, player, pem);
- }
- } else {
- for (World world : worlds) {
- String worldName = world.getName();
- permission.playerAdd(worldName, player, pem);
- }
- }
- }
- for (String groupName : groups) {
- String[] args = groupName.split(":");
- groupName = args[0];
- if (args.length > 1) {
- for (int i = 1; i < args.length; i++) {
- String worldName = args[i];
- permission.playerAddGroup(worldName, player, groupName);
- }
- } else {
- for (World world : worlds) {
- String worldName = world.getName();
- permission.playerAddGroup(worldName, player, groupName);
- }
- }
- }
- }
+ @Override
+ public void toConfigBean(MemorySection config) {
+ displayName = config.getString("displayName");
+ if (displayName == null) {
+ displayName = "No Name";
+ }
+ id = config.getString("id");
+ type = config.getString("type");
+ if (id == null && type == null) {
+ type = "NETHER_STAR";
+ }
+ glowing = config.getBoolean("glowing");
+ lores = config.getStringList("lores");
+ global = config.getBoolean("global");
+ permissions = config.getStringList("permissions");
+ groups = config.getStringList("groups");
+ expireCommands = config.getStringList("expireCommands");
+ }
- private void clearPlayer(OfflinePlayer player, Server server, Permission permission) {
- List worlds = server.getWorlds();
- for (String pem : permissions) {
- String[] args = pem.split(":");
- pem = args[0];
- if (args.length > 1) {
- for (int i = 1; i < args.length; i++) {
- String worldName = args[i];
- permission.playerRemove(worldName, player, pem);
- }
- } else {
- for (World world : worlds) {
- String worldName = world.getName();
- permission.playerRemove(worldName, player, pem);
- }
- }
- }
- for (String groupName : groups) {
- String[] args = groupName.split(":");
- groupName = args[0];
- if (args.length > 1) {
- for (int i = 1; i < args.length; i++) {
- String worldName = args[i];
- permission.playerRemoveGroup(worldName, player, groupName);
- }
- } else {
- for (World world : worlds) {
- String worldName = world.getName();
- permission.playerRemoveGroup(worldName, player, groupName);
- }
- }
- }
- }
+ @Override
+ public String toString() {
+ return "PermissionPackageBean [displayName=" + displayName + ", id=" + id + ", type=" + type + ", glowing="
+ + glowing + ", lores=" + lores + ", global=" + global + ", permissions=" + permissions + ", groups="
+ + groups + ", expireCommands=" + expireCommands + "]";
+ }
- public static void reloadPlayerPermissions(OfflinePlayer player, List pdbList, PluginMain plugin) {
- reloadPlayerPermissions(player, pdbList, plugin, true);
- }
+ private void givePlayer(OfflinePlayer player, Server server, Permission permission) {
+ List worlds = server.getWorlds();
+ for (String pem : permissions) {
+ String[] args = pem.split(":");
+ pem = args[0];
+ if (args.length > 1) {
+ for (int i = 1; i < args.length; i++) {
+ String worldName = args[i];
+ permission.playerAdd(worldName, player, pem);
+ }
+ } else {
+ for (World world : worlds) {
+ String worldName = world.getName();
+ permission.playerAdd(worldName, player, pem);
+ }
+ }
+ }
+ for (String groupName : groups) {
+ String[] args = groupName.split(":");
+ groupName = args[0];
+ if (args.length > 1) {
+ for (int i = 1; i < args.length; i++) {
+ String worldName = args[i];
+ permission.playerAddGroup(worldName, player, groupName);
+ }
+ } else {
+ for (World world : worlds) {
+ String worldName = world.getName();
+ permission.playerAddGroup(worldName, player, groupName);
+ }
+ }
+ }
+ }
- public static void reloadPlayerPermissions(OfflinePlayer player, List pdbList, PluginMain plugin, boolean async) {
- long delay = -1;
- long now = new Date().getTime();
- PermissionPackageBean addPpb = new PermissionPackageBean();
- addPpb.getGroups().add(PackagesCfg.DEFAULT_GROUP);
- PermissionPackageBean subPpb = new PermissionPackageBean();
- subPpb.getPermissions().addAll(PackagesCfg.allPermissions);
- subPpb.getGroups().addAll(PackagesCfg.allGroups);
- for (PlayerDataBean pdb : pdbList) {
- long leftTime = pdb.getExpire() - now;
- if (leftTime > 0) {
- if (delay == -1) {
- delay = leftTime;
- } else if (delay > leftTime) {
- delay = leftTime;
- }
- }
- PermissionPackageBean p = PackagesCfg.PACKAGES.get(pdb.getPackageName());
- if (p != null) {
- addPpb.getPermissions().addAll(p.getPermissions());
- subPpb.getPermissions().removeAll(p.getPermissions());
- addPpb.getGroups().addAll(p.getGroups());
- subPpb.getGroups().removeAll(p.getGroups());
- }
- }
- 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());
- }
- checkExpire(player, plugin);
- BukkitTask task = taskMap.get(player.getUniqueId().toString());
- if (pdbList.size() > 0) {
- delay = (delay / 1000 + 1) * 20;// 1秒=20ticks
- task = plugin.getServer().getScheduler().runTaskLaterAsynchronously(plugin, new Runnable() {
- @Override
- public void run() {
- List tpdbList = plugin.getSqlManager().getTime(player.getUniqueId().toString());
- reloadPlayerPermissions(player, tpdbList, plugin);
- }
- }, delay);
- taskMap.put(player.getUniqueId().toString(), task);
- }
- }
+ private void clearPlayer(OfflinePlayer player, Server server, Permission permission) {
+ List worlds = server.getWorlds();
+ for (String pem : permissions) {
+ String[] args = pem.split(":");
+ pem = args[0];
+ if (args.length > 1) {
+ for (int i = 1; i < args.length; i++) {
+ String worldName = args[i];
+ permission.playerRemove(worldName, player, pem);
+ }
+ } else {
+ for (World world : worlds) {
+ String worldName = world.getName();
+ permission.playerRemove(worldName, player, pem);
+ }
+ }
+ }
+ for (String groupName : groups) {
+ String[] args = groupName.split(":");
+ groupName = args[0];
+ if (args.length > 1) {
+ for (int i = 1; i < args.length; i++) {
+ String worldName = args[i];
+ permission.playerRemoveGroup(worldName, player, groupName);
+ }
+ } else {
+ for (World world : worlds) {
+ String worldName = world.getName();
+ permission.playerRemoveGroup(worldName, player, groupName);
+ }
+ }
+ }
+ }
- public static void delPlayerAllPermissions(OfflinePlayer player, PluginMain plugin) throws Exception {
- PermissionPackageBean subPpb = new PermissionPackageBean();
- subPpb.getPermissions().addAll(PackagesCfg.allPermissions);
- subPpb.getGroups().addAll(PackagesCfg.allGroups);
- plugin.getServer().getScheduler().runTask(plugin, new Runnable() {
- @Override
- public void run() {
- subPpb.clearPlayer(player, plugin.getServer(), plugin.getPermission());
- }
- });
- BukkitTask task = taskMap.get(player.getUniqueId().toString());
- if (task != null) {
- plugin.getServer().getScheduler().cancelTask(task.getTaskId());
- }
- }
+ public static void reloadPlayerPermissions(OfflinePlayer player, List pdbList, PluginMain plugin) {
+ reloadPlayerPermissions(player, pdbList, plugin, true);
+ }
- public static void checkExpire(OfflinePlayer player, PluginMain plugin) {
- List playerDataList = plugin.getSqlManager().getAllTime(player.getUniqueId().toString());
- long now = new Date().getTime();
- for (PlayerDataBean playerData : playerDataList) {
- if (playerData.getExpire() < now) {
- PermissionPackageBean packageBean = PackagesCfg.PACKAGES.get(playerData.getPackageName());
- plugin.getServer().getScheduler().runTask(plugin, new Runnable() {
- @Override
- public void run() {
- Player p = player.getPlayer();
- if (p != null) {
- p.sendMessage(StrUtil.messageFormat(PluginCfg.PLUGIN_PREFIX + LangCfg.MSG_IS_EXPIRATION_DATE, packageBean != null ? packageBean.getDisplayName() : LangCfg.MSG_UNKNOWN_PACKAGE, playerData.getPackageName()));
- }
- }
- });
- plugin.getSqlManager().delById(playerData.getId());
- }
- }
- }
+ public static void reloadPlayerPermissions(OfflinePlayer player, List pdbList, PluginMain plugin,
+ boolean async) {
+ long delay = -1;
+ long now = new Date().getTime();
+ PermissionPackageBean addPpb = new PermissionPackageBean();
+ addPpb.getGroups().add(PackagesCfg.DEFAULT_GROUP);
+ PermissionPackageBean subPpb = new PermissionPackageBean();
+ subPpb.getPermissions().addAll(PackagesCfg.allPermissions);
+ subPpb.getGroups().addAll(PackagesCfg.allGroups);
+ for (PlayerDataBean pdb : pdbList) {
+ long leftTime = pdb.getExpire() - now;
+ if (leftTime > 0) {
+ if (delay == -1) {
+ delay = leftTime;
+ } else if (delay > leftTime) {
+ delay = leftTime;
+ }
+ }
+ PermissionPackageBean p = PackagesCfg.PACKAGES.get(pdb.getPackageName());
+ if (p != null) {
+ addPpb.getPermissions().addAll(p.getPermissions());
+ subPpb.getPermissions().removeAll(p.getPermissions());
+ addPpb.getGroups().addAll(p.getGroups());
+ subPpb.getGroups().removeAll(p.getGroups());
+ }
+ }
+ 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());
+ }
+ checkExpire(player, plugin);
+ BukkitTask task = taskMap.get(player.getUniqueId().toString());
+ if (pdbList.size() > 0) {
+ delay = (delay / 1000 + 1) * 20;// 1秒=20ticks
+ task = plugin.getServer().getScheduler().runTaskLaterAsynchronously(plugin, new Runnable() {
+ @Override
+ public void run() {
+ List tpdbList = plugin.getSqlManager().getTime(player.getUniqueId().toString());
+ reloadPlayerPermissions(player, tpdbList, plugin);
+ }
+ }, delay);
+ taskMap.put(player.getUniqueId().toString(), task);
+ }
+ }
+
+ public static void delPlayerAllPermissions(OfflinePlayer player, PluginMain plugin) throws Exception {
+ PermissionPackageBean subPpb = new PermissionPackageBean();
+ subPpb.getPermissions().addAll(PackagesCfg.allPermissions);
+ subPpb.getGroups().addAll(PackagesCfg.allGroups);
+ plugin.getServer().getScheduler().runTask(plugin, new Runnable() {
+ @Override
+ public void run() {
+ subPpb.clearPlayer(player, plugin.getServer(), plugin.getPermission());
+ }
+ });
+ BukkitTask task = taskMap.get(player.getUniqueId().toString());
+ if (task != null) {
+ plugin.getServer().getScheduler().cancelTask(task.getTaskId());
+ }
+ }
+
+ public static void checkExpire(OfflinePlayer player, PluginMain plugin) {
+ List playerDataList = plugin.getSqlManager().getAllTime(player.getUniqueId().toString());
+ long now = new Date().getTime();
+ for (PlayerDataBean playerData : playerDataList) {
+ if (playerData.getExpire() < now) {
+ PermissionPackageBean packageBean = PackagesCfg.PACKAGES.get(playerData.getPackageName());
+ plugin.getServer().getScheduler().runTask(plugin, new Runnable() {
+ @Override
+ public void run() {
+ Player p = player.getPlayer();
+ if (p != null) {
+ p.sendMessage(StrUtil.messageFormat(
+ PluginCfg.PLUGIN_PREFIX + LangCfg.MSG_IS_EXPIRATION_DATE,
+ packageBean != null ? packageBean.getDisplayName() : LangCfg.MSG_UNKNOWN_PACKAGE,
+ playerData.getPackageName()));
+ for (String commands : packageBean.getExpireCommands()) {
+ try {
+ commands = StrUtil.messageFormat(player.getPlayer(), commands);
+ plugin.getServer().dispatchCommand(plugin.getServer().getConsoleSender(), commands);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ });
+ plugin.getSqlManager().delById(playerData.getId());
+ }
+ }
+ }
}
diff --git a/src/main/gg/frog/mc/permissionstime/utils/StrUtil.java b/src/main/gg/frog/mc/permissionstime/utils/StrUtil.java
index f1f0e6e..e4189a1 100644
--- a/src/main/gg/frog/mc/permissionstime/utils/StrUtil.java
+++ b/src/main/gg/frog/mc/permissionstime/utils/StrUtil.java
@@ -4,9 +4,12 @@ import java.text.MessageFormat;
import java.util.Date;
import org.apache.commons.lang.time.DateFormatUtils;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
import gg.frog.mc.permissionstime.config.LangCfg;
import gg.frog.mc.permissionstime.database.IPlayerDataDao;
+import me.clip.placeholderapi.PlaceholderAPI;
public class StrUtil {
@@ -14,9 +17,26 @@ public class StrUtil {
private static final long dt = 24 * 60 * IPlayerDataDao.TIME_UNIT;
private static final long ht = 60 * IPlayerDataDao.TIME_UNIT;
private static final long mt = IPlayerDataDao.TIME_UNIT;
+ private static final boolean placeholderAPI;
+
+ static {
+ if(Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI")) {
+ placeholderAPI = true;
+ }else {
+ placeholderAPI = false;
+ }
+ }
public static String messageFormat(String src, Object... args) {
- return MessageFormat.format(src, args).replace("&", "§").replace("\\n", "\n");
+ return MessageFormat.format(src, args).replace("&", "§").replace("\\n", "\n");
+ }
+
+ public static String messageFormat(Player player, String src, Object... args) {
+ String message = MessageFormat.format(src, args).replace("&", "§").replace("\\n", "\n").replace("%player%", player.getDisplayName());
+ if(placeholderAPI) {
+ message = PlaceholderAPI.setPlaceholders(player, message);
+ }
+ return message;
}
public static String timestampToString(long time) {
diff --git a/src/resources/packages.yml b/src/resources/packages.yml
index 82d53fa..7d831ed 100644
--- a/src/resources/packages.yml
+++ b/src/resources/packages.yml
@@ -42,3 +42,8 @@ packages:
groups:
- group1
- group2:world1
+ # 权限包过期后执行的控制台命令
+ # Package expire console commands.
+ expireCommands:
+ - 'bc %player% 的权限包到期了.'
+ - 'bc 请及时续期.'
diff --git a/src/resources/plugin.yml b/src/resources/plugin.yml
index a3643fa..2b556fc 100644
--- a/src/resources/plugin.yml
+++ b/src/resources/plugin.yml
@@ -1,10 +1,11 @@
name: PermissionsTime
-version: 0.2.4-SNAPSHOT
+version: 0.3.0-SNAPSHOT
main: gg.frog.mc.permissionstime.PluginMain
author: GeekFrog
softdepend:
- SQLibrary
- Vault
+- PlaceholderAPI
commands:
permissionstime:
description: Show all commands.
diff --git a/帖子代码.txt b/帖子代码.txt
index 85f94a0..7b4ef3b 100644
--- a/帖子代码.txt
+++ b/帖子代码.txt
@@ -3,7 +3,7 @@
[align=center][table=98%,#4169e1]
[tr][td][align=center][size=6][color=#ffffff][b]唠叨[/b][/color][/size][/align][/td][/tr]
[/table][/align][align=center][table=98%,gray]
-[tr][td][align=center][size=4][color=#ffa500][b]这是本人第一个发布的插件, 希望能让大家满意![/b][/color][/size][/align][align=center][size=4][color=#dda0dd][b]本插件需要JAVA8!!![/b][/color][/size][/align][align=center][size=4][color=#98fb98][b]下载地址在最下面![/b][/color][/size][/align][align=center][size=4][color=#c0c0c0][b]最新版本: [/b][/color][b][color=#8b0000]0.2.3[/color][color=#c0c0c0],推荐大家使用新版本,只需替换插件的jar包和语言文件即可![/color][/b][/size][/align][/td][/tr]
+[tr][td][align=center][size=4][color=#ffa500][b]这是本人第一个发布的插件, 希望能让大家满意![/b][/color][/size][/align][align=center][size=4][color=#dda0dd][b]本插件需要JAVA8!!![/b][/color][/size][/align][align=center][size=4][color=#98fb98][b]下载地址在最下面![/b][/color][/size][/align][align=center][size=4][color=#c0c0c0][b]最新版本: [/b][/color][b][color=#8b0000]0.3.0[/color][color=#c0c0c0],推荐大家使用新版本,只需替换插件的jar包和语言文件即可![/color][/b][/size][/align][/td][/tr]
[/table][/align][align=center][table=98%,#4169e1]
[tr][td][align=center][size=6][color=#ffffff][b]前言[/b][/color][/size][/align][/td][/tr]
[/table][/align][align=center][table=98%,gray]
@@ -197,6 +197,11 @@ cmd:
[tr][td][align=center][size=6][color=#ffffff][b]更新日志[/b][/color][/size][/align][/td][/tr]
[/table][/align][align=center][table=98%,gray]
[tr][td][spoiler][size=4][b][url=http://ci.frog.gg/jenkins/job/PermissionsTime/changes]详细的更新记录[/url]
+[color=#ffffff]2017年8月1日 V0.3.0[/color][quote][color=#000000]
+1.权限包到期可执行自定义命令[/color][/quote]
+[color=#ffffff]2017年7月31日 V0.2.4[/color][quote][color=#000000]
+1.插件统计更换成bstats
+2.兼容服务端文件夹路径含有空格字符[/color][/quote]
[color=#ffffff]2017年7月27日 V0.2.3[/color][quote][color=#000000]
1.取消保存配置文件
2.语言文件整理[/color][/quote]
@@ -221,15 +226,13 @@ cmd:
[/table][/align][align=center][table=98%,#4169e1]
[tr][td][align=center][size=6][color=#ffffff][b]下载地址[/b][/color][/size][/align][/td][/tr]
[/table][/align][align=center][table=98%,gray]
-[tr][td][size=4][b][align=center][color=#000] [url=http://ci.frog.gg/jenkins/job/PermissionsTime/57/]V0.2.3版下载地址[/url][/color][/align][align=center][color=#ffffff]前置插件:[/color][color=#000][url=https://dev.bukkit.org/projects/vault/files]vault[/url][/color][color=#000000] , [/color][color=#000][url=https://dev.bukkit.org/projects/sqlibrary/files]sqlibrary[/url][/color][/align][align=center][color=#ffffff]前置插件最好去原站下载适合的版本, 如果无法下载可以在帖内下载。[/color][/align]
+[tr][td][size=4][b][align=center][color=#000] [url=http://ci.frog.gg/jenkins/job/PermissionsTime/63/]V0.3.0版下载地址[/url][/color][/align][align=center][color=#ffffff]前置插件:[/color][color=#000][url=https://dev.bukkit.org/projects/vault/files]vault[/url][/color][color=#000000] , [/color][color=#000][url=https://dev.bukkit.org/projects/sqlibrary/files]sqlibrary[/url][/color][/align][align=center][color=#ffffff]前置插件最好去原站下载适合的版本, 如果无法下载可以在帖内下载。[/color][/align]
[align=center][b][color=#ffffff]帖内下载:[/color][/b][/align][align=center][color=#000][attach]1101088[/attach][/color][/align][align=center][color=#000][b][color=#ff0000]前置插件必须安装[/color][/b][/color][/align][align=center][color=#000][attach]1101089[/attach][/color][/align][align=center][color=#000][attach]1101090[/attach][/color][/align][align=center][color=#000][attach]1101110[/attach][/color][/align]
[align=center][color=#000][color=#ff0000][b]如果大家觉得好用就给点金粒吧,如果不好请告诉我,帮助我改进。[/b][/color][/color][/align][align=center][color=#000][b]BUG可以在帖内回复我。[/b][/color][/align][/b][/size][/td][/tr]
[/table][/align][align=center][table=98%,#4169e1]
[tr][td][align=center][size=6][color=#ffffff][b]使用统计[/b][/color][/size][/align][/td][/tr]
[/table][/align][align=center][table=98%,gray]
-[tr][td][align=center][b][size=4][color=#ff0000]图片可能经常抽风[/color][/size][/b][/align]
-[align=center][img]http://i.mcstats.org/PermissionsTime/Global+Statistics.borderless.png[/img][/align]
-[align=center][img]http://i.mcstats.org/PermissionsTime/Version+Demographics.borderless.png[/img][/align][/td][/tr]
+[tr][td][align=center][url=https://bstats.org/plugin/bukkit/PermissionsTime][size=4][b]https://bstats.org/plugin/bukkit/PermissionsTime[/b][/size][/url][/align][/td][/tr]
[/table][/align][align=center][table=98%,#4169e1]
[tr][td][align=center][size=6][color=#ffffff][b]此插件已加入我的世界公益插件计划[/b][/color][/size][/align][/td][/tr]
[/table][/align][align=center][table=98%,gray]