mirror of
https://github.com/CarmJos/ScriptItems
synced 2024-09-19 21:35:50 +00:00
完成物品基本逻辑与配置文件读取
This commit is contained in:
parent
e77c7e2804
commit
fb1ee145f0
@ -14,10 +14,11 @@
|
|||||||
物品指令绑定插件,给予玩家可执行对应指令的消耗物品,基于EasyPlugin实现。
|
物品指令绑定插件,给予玩家可执行对应指令的消耗物品,基于EasyPlugin实现。
|
||||||
|
|
||||||
## 插件功能与优势
|
## 插件功能与优势
|
||||||
|
> 加 * 的功能仍在开发中。
|
||||||
|
|
||||||
- 物品指令绑定,给予玩家可执行对应指令的消耗物品,支持PlaceholderAPI变量。
|
- 物品指令绑定,给予玩家可执行对应指令的消耗物品,支持PlaceholderAPI变量。
|
||||||
- **允许限定。** 允许给物品对应的指令组设定“领取次数”、“每日领取次数”与“领取时间”限定。
|
- **允许限定。** 允许给物品对应的指令组设定“领取次数”、“每日领取次数”与“领取时间”限定。
|
||||||
- **详细记录。** 每个物品均有独立ID,并对使用的玩家与执行结果进行详细记录,便于追踪查询。
|
- **\*详细记录。** 每个物品均有独立ID,并对使用的玩家与执行结果进行详细记录,便于追踪查询。
|
||||||
- **异步存取。** 数据读取与存储均为异步操作,不影响服务器性能。
|
- **异步存取。** 数据读取与存储均为异步操作,不影响服务器性能。
|
||||||
- **轻量插件。** 适合小型服务器使用,配置简单方便。
|
- **轻量插件。** 适合小型服务器使用,配置简单方便。
|
||||||
- **规范开发。** 插件架构符合开发规范,适合新手开发者学习。
|
- **规范开发。** 插件架构符合开发规范,适合新手开发者学习。
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
package cc.carm.plugin.commanditem;
|
package cc.carm.plugin.commanditem;
|
||||||
|
|
||||||
|
import cc.carm.plugin.commanditem.manager.ItemsManager;
|
||||||
|
|
||||||
public class CommandItemAPI {
|
public class CommandItemAPI {
|
||||||
|
|
||||||
|
public static ItemsManager getItemsManager() {
|
||||||
|
return Main.getInstance().itemsManager;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,9 @@ import cc.carm.lib.easyplugin.EasyPlugin;
|
|||||||
import cc.carm.lib.easyplugin.i18n.EasyPluginMessageProvider;
|
import cc.carm.lib.easyplugin.i18n.EasyPluginMessageProvider;
|
||||||
import cc.carm.plugin.commanditem.configuration.PluginConfig;
|
import cc.carm.plugin.commanditem.configuration.PluginConfig;
|
||||||
import cc.carm.plugin.commanditem.hooker.GHUpdateChecker;
|
import cc.carm.plugin.commanditem.hooker.GHUpdateChecker;
|
||||||
|
import cc.carm.plugin.commanditem.listener.ItemListener;
|
||||||
import cc.carm.plugin.commanditem.manager.ConfigManager;
|
import cc.carm.plugin.commanditem.manager.ConfigManager;
|
||||||
|
import cc.carm.plugin.commanditem.manager.ItemsManager;
|
||||||
import cc.carm.plugin.commanditem.util.JarResourceUtils;
|
import cc.carm.plugin.commanditem.util.JarResourceUtils;
|
||||||
import org.bstats.bukkit.Metrics;
|
import org.bstats.bukkit.Metrics;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
@ -24,6 +26,8 @@ public class Main extends EasyPlugin {
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected ItemsManager itemsManager;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean initialize() {
|
protected boolean initialize() {
|
||||||
|
|
||||||
@ -34,6 +38,11 @@ public class Main extends EasyPlugin {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
info("注册指令...");
|
||||||
|
|
||||||
|
info("注册监听器...");
|
||||||
|
regListener(new ItemListener());
|
||||||
|
|
||||||
if (PluginConfig.METRICS.get()) {
|
if (PluginConfig.METRICS.get()) {
|
||||||
info("启用统计数据...");
|
info("启用统计数据...");
|
||||||
new Metrics(this, 14459);
|
new Metrics(this, 14459);
|
||||||
@ -41,7 +50,7 @@ public class Main extends EasyPlugin {
|
|||||||
|
|
||||||
if (PluginConfig.CHECK_UPDATE.get()) {
|
if (PluginConfig.CHECK_UPDATE.get()) {
|
||||||
log("开始检查更新...");
|
log("开始检查更新...");
|
||||||
GHUpdateChecker checker = new GHUpdateChecker(getLogger(), "CarmJos", "ItemCommands");
|
GHUpdateChecker checker = new GHUpdateChecker(getLogger(), "CarmJos", "CommandItem");
|
||||||
getScheduler().runAsync(() -> checker.checkUpdate(getDescription().getVersion()));
|
getScheduler().runAsync(() -> checker.checkUpdate(getDescription().getVersion()));
|
||||||
} else {
|
} else {
|
||||||
log("已禁用检查更新,跳过。");
|
log("已禁用检查更新,跳过。");
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package cc.carm.plugin.commanditem.configuration;
|
package cc.carm.plugin.commanditem.configuration;
|
||||||
|
|
||||||
import cc.carm.lib.easyplugin.configuration.values.ConfigValue;
|
import cc.carm.lib.easyplugin.configuration.values.ConfigValue;
|
||||||
|
import cc.carm.lib.easyplugin.configuration.values.ConfigValueMap;
|
||||||
|
|
||||||
public class PluginConfig {
|
public class PluginConfig {
|
||||||
|
|
||||||
@ -20,4 +21,13 @@ public class PluginConfig {
|
|||||||
"log-storage.enable", Boolean.class, true
|
"log-storage.enable", Boolean.class, true
|
||||||
);
|
);
|
||||||
|
|
||||||
|
public static class CustomStorage {
|
||||||
|
|
||||||
|
public static ConfigValue<Boolean> ENABLE = new ConfigValue<>("custom-storage.enable", Boolean.class, false);
|
||||||
|
|
||||||
|
public static ConfigValue<String> PATH = new ConfigValue<>("custom-storage.path", String.class, "items/");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,20 +4,48 @@ import cc.carm.lib.easyplugin.configuration.values.ConfigValue;
|
|||||||
|
|
||||||
public class DBTables {
|
public class DBTables {
|
||||||
|
|
||||||
public static class LogTable {
|
/**
|
||||||
|
* 物品发放记录表
|
||||||
|
* 用于记录每个物品的发放情况,包含发放时间,发放人,发放数量以及发放给了谁。
|
||||||
|
*/
|
||||||
|
public static class GiveTable {
|
||||||
|
|
||||||
protected static final ConfigValue<String> TABLE_NAME = new ConfigValue<>(
|
protected static final ConfigValue<String> TABLE_NAME = new ConfigValue<>(
|
||||||
"log-storage.database.table-name", String.class,
|
"log-storage.database.tables.give", String.class,
|
||||||
"log_item_commands"
|
"log_item_give"
|
||||||
);
|
);
|
||||||
|
|
||||||
protected static final String[] TABLE_COLUMNS = new String[]{
|
protected static final String[] TABLE_COLUMNS = new String[]{
|
||||||
"`uuid` VARCHAR(36) NOT NULL PRIMARY KEY COMMENT '用户UUID'", // 用户的UUID
|
"`id` INT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE KEY",
|
||||||
"`time` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '用户在线秒数'",// 用户在线时间(秒)
|
"`uuid` VARCHAR(36) NOT NULL PRIMARY KEY", // ItemUUID
|
||||||
"`update` DATETIME NOT NULL " +
|
"`settings` VARCHAR(36) NOT NULL", // 该物品配置对应的Identifier
|
||||||
"DEFAULT CURRENT_TIMESTAMP " +
|
"`operator` VARCHAR(36)", "`operator_name` VARCHAR(32)", // 发放人的相关信息
|
||||||
"ON UPDATE CURRENT_TIMESTAMP " +
|
"`receiver` VARCHAR(36)", "`receiver_name` VARCHAR(32)", // 接受者的相关信息
|
||||||
" COMMENT '最后更新时间'"
|
"`amount` INT UNSIGNED NOT NULL DEFAULT 1", // 同uuid物品的发放数量
|
||||||
|
"`time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP" // 发放时间
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 物品拿取记录表
|
||||||
|
* 改表用于记录物品的使用情况,即谁在什么时候使用了哪个物品,以及领取时任务的执行情况。
|
||||||
|
* 请注意:只有在发生物品拿取(即 take action )事件时才会记录!
|
||||||
|
*/
|
||||||
|
public static class TakeTable {
|
||||||
|
|
||||||
|
protected static final ConfigValue<String> TABLE_NAME = new ConfigValue<>(
|
||||||
|
"log-storage.database.tables.received", String.class,
|
||||||
|
"log_item_received"
|
||||||
|
);
|
||||||
|
|
||||||
|
protected static final String[] TABLE_COLUMNS = new String[]{
|
||||||
|
"`id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY",
|
||||||
|
"`uuid` VARCHAR(36) NOT NULL", // ItemUUID
|
||||||
|
"`receiver` VARCHAR(36)", "`receiver_name` VARCHAR(32)", // 接受者的相关信息
|
||||||
|
"`result` TINYINT(2) NOT NULL DEFAULT 0",// 领取结果
|
||||||
|
"`time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP",
|
||||||
|
"INDEX `item`(`uuid`)"
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,12 +3,16 @@ package cc.carm.plugin.commanditem.database;
|
|||||||
import cc.carm.lib.easysql.EasySQL;
|
import cc.carm.lib.easysql.EasySQL;
|
||||||
import cc.carm.lib.easysql.api.SQLManager;
|
import cc.carm.lib.easysql.api.SQLManager;
|
||||||
import cc.carm.plugin.commanditem.Main;
|
import cc.carm.plugin.commanditem.Main;
|
||||||
|
import cc.carm.plugin.commanditem.util.DatabaseTable;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
public class DataManager {
|
public class DataManager {
|
||||||
private SQLManager sqlManager;
|
private SQLManager sqlManager;
|
||||||
|
|
||||||
|
private DatabaseTable givenTable;
|
||||||
|
private DatabaseTable receivedTable;
|
||||||
|
|
||||||
public boolean initialize() {
|
public boolean initialize() {
|
||||||
try {
|
try {
|
||||||
Main.info(" 尝试连接到数据库...");
|
Main.info(" 尝试连接到数据库...");
|
||||||
@ -25,9 +29,12 @@ public class DataManager {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
Main.info(" 创建插件记录所需表...");
|
Main.info(" 创建插件记录所需表...");
|
||||||
getSQLManager().createTable(DBTables.LogTable.TABLE_NAME.get())
|
|
||||||
.setColumns(DBTables.LogTable.TABLE_COLUMNS)
|
this.givenTable = new DatabaseTable(DBTables.GiveTable.TABLE_NAME.get(), DBTables.GiveTable.TABLE_COLUMNS);
|
||||||
.build().execute();
|
this.receivedTable = new DatabaseTable(DBTables.TakeTable.TABLE_NAME.get(), DBTables.TakeTable.TABLE_COLUMNS);
|
||||||
|
|
||||||
|
this.givenTable.createTable(this.sqlManager);
|
||||||
|
this.receivedTable.createTable(this.sqlManager);
|
||||||
|
|
||||||
} catch (SQLException exception) {
|
} catch (SQLException exception) {
|
||||||
Main.severe("无法创建插件所需的表,请检查数据库权限。");
|
Main.severe("无法创建插件所需的表,请检查数据库权限。");
|
||||||
@ -48,6 +55,15 @@ public class DataManager {
|
|||||||
return sqlManager;
|
return sqlManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DatabaseTable getGivenTable() {
|
||||||
|
return givenTable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DatabaseTable getReceivedTable() {
|
||||||
|
return receivedTable;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,34 @@
|
|||||||
|
package cc.carm.plugin.commanditem.item;
|
||||||
|
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class CommandItem {
|
||||||
|
|
||||||
|
@NotNull UUID uuid;
|
||||||
|
|
||||||
|
@NotNull ItemSettings configuration;
|
||||||
|
@NotNull ItemStack itemStack;
|
||||||
|
|
||||||
|
public CommandItem(@NotNull UUID uuid, @NotNull ItemSettings configuration, @NotNull ItemStack itemStack) {
|
||||||
|
this.uuid = uuid;
|
||||||
|
this.configuration = configuration;
|
||||||
|
this.itemStack = itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull UUID getUUID() {
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull ItemSettings getConfiguration() {
|
||||||
|
return configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull ItemStack getItemStack() {
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
package cc.carm.plugin.commanditem.item;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
public class ItemAction {
|
||||||
|
|
||||||
|
@NotNull ItemActionType type;
|
||||||
|
@Nullable String actionContent;
|
||||||
|
|
||||||
|
public ItemAction(@NotNull ItemActionType type, @Nullable String actionContent) {
|
||||||
|
this.type = type;
|
||||||
|
this.actionContent = actionContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull ItemActionType getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable String getActionContent() {
|
||||||
|
return actionContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean execute(Player player) {
|
||||||
|
return getType().execute(player, getActionContent());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static @Nullable ItemAction read(@Nullable String actionString) {
|
||||||
|
if (actionString == null) return null;
|
||||||
|
int prefixStart = actionString.indexOf("[");
|
||||||
|
int prefixEnd = actionString.indexOf("]");
|
||||||
|
if (prefixStart < 0 || prefixEnd < 0) return null;
|
||||||
|
|
||||||
|
String prefix = actionString.substring(prefixStart + 1, prefixEnd);
|
||||||
|
ItemActionType actionType = ItemActionType.read(prefix);
|
||||||
|
if (actionType == null) return null;
|
||||||
|
|
||||||
|
return new ItemAction(actionType, actionString.substring(prefixEnd + 1).trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package cc.carm.plugin.commanditem.item;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class ItemActionGroup {
|
||||||
|
|
||||||
|
|
||||||
|
List<ItemAction> actions;
|
||||||
|
|
||||||
|
public ItemActionGroup(List<ItemAction> actions) {
|
||||||
|
this.actions = actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static @NotNull ItemActionGroup read(@NotNull List<String> actionsString) {
|
||||||
|
List<ItemAction> actions = actionsString.stream()
|
||||||
|
.map(ItemAction::read).filter(Objects::nonNull).collect(Collectors.toList());
|
||||||
|
return new ItemActionGroup(actions);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,121 @@
|
|||||||
|
package cc.carm.plugin.commanditem.item;
|
||||||
|
|
||||||
|
import cc.carm.lib.easyplugin.utils.MessageUtils;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.Sound;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
|
public enum ItemActionType {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 以玩家聊天的形式执行
|
||||||
|
* 若内容以 “/" 开头,则会以玩家身份执行命令。
|
||||||
|
*/
|
||||||
|
CHAT((player, string) -> {
|
||||||
|
if (string == null) return true; //没有需要执行的
|
||||||
|
List<String> finalContents = MessageUtils.setPlaceholders(player, Collections.singletonList(string));
|
||||||
|
boolean success = true;
|
||||||
|
for (String finalContent : finalContents) {
|
||||||
|
try {
|
||||||
|
player.chat(finalContent);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 以后台的形式执行指令
|
||||||
|
* 指令内容不需要以“/”开头。
|
||||||
|
*/
|
||||||
|
CONSOLE((player, string) -> {
|
||||||
|
if (string == null) return true;
|
||||||
|
List<String> finalCommands = MessageUtils.setPlaceholders(player, Collections.singletonList(string));
|
||||||
|
boolean success = true;
|
||||||
|
for (String finalCommand : finalCommands) {
|
||||||
|
try {
|
||||||
|
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), finalCommand);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 向玩家发送消息。
|
||||||
|
*/
|
||||||
|
MESSAGE((sender, messages) -> {
|
||||||
|
MessageUtils.send(sender, messages);
|
||||||
|
return true;
|
||||||
|
}),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 向玩家发送声音。
|
||||||
|
* 允许配置音量与音调
|
||||||
|
* <ul>
|
||||||
|
* <li>SOUND_NAME</li>
|
||||||
|
* <li>SOUND_NAME:VOLUME</li>
|
||||||
|
* <li>SOUND_NAME:VOLUME:PITCH</li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
SOUND((player, string) -> {
|
||||||
|
if (string == null) return true;
|
||||||
|
try {
|
||||||
|
String[] args = string.contains(":") ? string.split(":") : new String[]{string};
|
||||||
|
Sound sound = Arrays.stream(Sound.values())
|
||||||
|
.filter(s -> s.name().equals(args[0]))
|
||||||
|
.findFirst().orElse(null);
|
||||||
|
|
||||||
|
if (sound == null) return true;
|
||||||
|
float volume = args.length > 1 ? Float.parseFloat(args[1]) : 1F;
|
||||||
|
float pitch = args.length > 2 ? Float.parseFloat(args[2]) : 1F;
|
||||||
|
|
||||||
|
player.playSound(player.getLocation(), sound, volume, pitch);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
return true; // 声音放不放无关紧要
|
||||||
|
}),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拿取玩家手上的一个物品
|
||||||
|
*/
|
||||||
|
TAKE((player, string) -> {
|
||||||
|
if (player.getInventory().getItemInMainHand().getType() != Material.AIR) {
|
||||||
|
int current = player.getInventory().getItemInMainHand().getAmount();
|
||||||
|
player.getInventory().getItemInMainHand().setAmount(current - 1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
BiFunction<@NotNull Player, @Nullable String, @NotNull Boolean> executor;
|
||||||
|
|
||||||
|
ItemActionType(BiFunction<@NotNull Player, @Nullable String, @NotNull Boolean> executor) {
|
||||||
|
this.executor = executor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BiFunction<Player, String, Boolean> getExecutor() {
|
||||||
|
return executor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean execute(@NotNull Player player, @Nullable String content) {
|
||||||
|
return getExecutor().apply(player, content);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ItemActionType read(String string) {
|
||||||
|
return Arrays.stream(ItemActionType.values())
|
||||||
|
.filter(action -> action.name().equalsIgnoreCase(string))
|
||||||
|
.findFirst().orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package cc.carm.plugin.commanditem.item;
|
||||||
|
|
||||||
|
public enum ItemExecuteResult {
|
||||||
|
|
||||||
|
SUCCESS(0),
|
||||||
|
FAILED(1),
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
int id;
|
||||||
|
|
||||||
|
ItemExecuteResult(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
package cc.carm.plugin.commanditem.item;
|
||||||
|
|
||||||
|
import cc.carm.lib.easysql.api.util.TimeDateUtils;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
public class ItemRestrictions {
|
||||||
|
|
||||||
|
long startTime;
|
||||||
|
long endTime;
|
||||||
|
|
||||||
|
public ItemRestrictions() {
|
||||||
|
this(-1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemRestrictions(long startTime, long endTime) {
|
||||||
|
this.startTime = startTime;
|
||||||
|
this.endTime = endTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return 限定的开始时间,-1表示不限定。
|
||||||
|
*/
|
||||||
|
public long getStartTime() {
|
||||||
|
return startTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return 限定的结束时间,-1表示不限定。
|
||||||
|
*/
|
||||||
|
public long getEndTime() {
|
||||||
|
return endTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CheckResult check() {
|
||||||
|
if (startTime > 0 && startTime > System.currentTimeMillis()) return CheckResult.NOT_STARTED;
|
||||||
|
if (endTime > 0 && endTime < System.currentTimeMillis()) return CheckResult.EXPIRED;
|
||||||
|
return CheckResult.AVAILABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum CheckResult {
|
||||||
|
|
||||||
|
AVAILABLE,
|
||||||
|
NOT_STARTED,
|
||||||
|
EXPIRED;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static @NotNull ItemRestrictions read(@Nullable ConfigurationSection section) {
|
||||||
|
if (section == null) return new ItemRestrictions();
|
||||||
|
return new ItemRestrictions(
|
||||||
|
TimeDateUtils.parseTimeMillis(section.getString("time.start")),
|
||||||
|
TimeDateUtils.parseTimeMillis(section.getString("time.end"))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
105
src/main/java/cc/carm/plugin/commanditem/item/ItemSettings.java
Normal file
105
src/main/java/cc/carm/plugin/commanditem/item/ItemSettings.java
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
package cc.carm.plugin.commanditem.item;
|
||||||
|
|
||||||
|
import cc.carm.plugin.commanditem.CommandItemAPI;
|
||||||
|
import cc.carm.plugin.commanditem.manager.ConfigManager;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.ImmutableSortedMap;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.annotations.Unmodifiable;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class ItemSettings {
|
||||||
|
|
||||||
|
protected final @NotNull String identifier;
|
||||||
|
@Nullable String name;
|
||||||
|
|
||||||
|
@Nullable ItemStackConfig item;
|
||||||
|
@NotNull ItemRestrictions restrictions;
|
||||||
|
|
||||||
|
@Nullable ItemActionGroup defaultActions;
|
||||||
|
@NotNull Map<String, String> permissions;
|
||||||
|
@NotNull Map<String, ItemActionGroup> actions;
|
||||||
|
|
||||||
|
public ItemSettings(@NotNull String identifier, @Nullable String name,
|
||||||
|
@Nullable ItemStackConfig item, @NotNull ItemRestrictions restrictions,
|
||||||
|
@Nullable ItemActionGroup defaultActions,
|
||||||
|
@NotNull Map<String, String> permissions,
|
||||||
|
@NotNull Map<String, ItemActionGroup> actions) {
|
||||||
|
this.identifier = identifier;
|
||||||
|
this.name = name;
|
||||||
|
this.item = item;
|
||||||
|
this.restrictions = restrictions;
|
||||||
|
this.defaultActions = defaultActions;
|
||||||
|
this.permissions = permissions;
|
||||||
|
this.actions = actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull String getIdentifier() {
|
||||||
|
return identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable ItemStack getItemStack(int amount) {
|
||||||
|
ItemStack originalItem = this.item == null ? null : this.item.getItemStack(amount);
|
||||||
|
if (originalItem == null) return null;
|
||||||
|
return applyItem(originalItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable ItemStack getItemStack() {
|
||||||
|
return getItemStack(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Unmodifiable
|
||||||
|
public @NotNull Map<String, String> getPermissions() {
|
||||||
|
return ImmutableSortedMap.copyOf(permissions);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Unmodifiable
|
||||||
|
public @NotNull Map<String, ItemActionGroup> getActions() {
|
||||||
|
return ImmutableMap.copyOf(actions);
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable ItemActionGroup getDefaultActions() {
|
||||||
|
return defaultActions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable ItemActionGroup getPlayerActions(@NotNull Player player) {
|
||||||
|
String actionGroup = getPermissions().entrySet().stream()
|
||||||
|
.filter(entry -> player.hasPermission(entry.getValue()))
|
||||||
|
.map(Map.Entry::getKey).findFirst().orElse(null);
|
||||||
|
return getActions().getOrDefault(actionGroup, getDefaultActions());
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull ItemStack applyItem(ItemStack originalItem) {
|
||||||
|
return CommandItemAPI.getItemsManager().applyTag(originalItem, identifier, UUID.randomUUID());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static @NotNull ItemSettings load(@NotNull File file) throws Exception {
|
||||||
|
return load(YamlConfiguration.loadConfiguration(file));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static @NotNull ItemSettings load(@NotNull FileConfiguration config) throws Exception {
|
||||||
|
String identifier = config.getString("identifier");
|
||||||
|
if (identifier == null) throw new Exception("identifier not provided.");
|
||||||
|
return new ItemSettings(
|
||||||
|
identifier, config.getString("name"),
|
||||||
|
ItemStackConfig.read(config.getConfigurationSection("item")),
|
||||||
|
ItemRestrictions.read(config.getConfigurationSection("restrictions")),
|
||||||
|
ItemActionGroup.read(config.getStringList("actions.default")),
|
||||||
|
ConfigManager.readStringMap(config.getConfigurationSection("permissions"), (s -> s)),
|
||||||
|
ConfigManager.readListMap(config.getConfigurationSection("actions"), ItemActionGroup::read)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,103 @@
|
|||||||
|
package cc.carm.plugin.commanditem.item;
|
||||||
|
|
||||||
|
import cc.carm.lib.easyplugin.utils.ItemStackFactory;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@SuppressWarnings("UnusedReturnValue")
|
||||||
|
public class ItemStackConfig {
|
||||||
|
|
||||||
|
protected @Nullable ItemStack original;
|
||||||
|
|
||||||
|
protected @Nullable Material material;
|
||||||
|
protected @Nullable String displayName;
|
||||||
|
protected @Nullable List<String> lore;
|
||||||
|
|
||||||
|
public ItemStackConfig() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemStackConfig(@Nullable Material material, @Nullable String displayName, @Nullable List<String> lore) {
|
||||||
|
this(null, material, displayName, lore);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemStackConfig(@Nullable ItemStack original) {
|
||||||
|
this(original, null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemStackConfig(@Nullable ItemStack original,
|
||||||
|
@Nullable Material material, @Nullable String displayName, @Nullable List<String> lore) {
|
||||||
|
this.original = original;
|
||||||
|
this.material = material;
|
||||||
|
this.displayName = displayName;
|
||||||
|
this.lore = lore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable ItemStack getItemStack(int amount) {
|
||||||
|
if (amount <= 0) return null;
|
||||||
|
if (original != null) return original.clone();
|
||||||
|
if (material == null) return null;
|
||||||
|
ItemStackFactory factory = new ItemStackFactory(material, amount);
|
||||||
|
if (displayName != null) factory.setDisplayName(displayName);
|
||||||
|
if (lore != null && !lore.isEmpty()) factory.setLore(lore);
|
||||||
|
return factory.toItemStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable ItemStack getItemStack() {
|
||||||
|
return getItemStack(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable ItemStack getOriginal() {
|
||||||
|
return original;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemStackConfig setOriginal(@Nullable ItemStack original) {
|
||||||
|
this.original = original;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable Material getMaterial() {
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemStackConfig setMaterial(@Nullable Material material) {
|
||||||
|
this.material = material;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable String getDisplayName() {
|
||||||
|
return displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemStackConfig setDisplayName(@Nullable String displayName) {
|
||||||
|
this.displayName = displayName;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable List<String> getLore() {
|
||||||
|
return lore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemStackConfig setLore(@Nullable List<String> lore) {
|
||||||
|
this.lore = lore;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static @Nullable ItemStackConfig read(@Nullable ConfigurationSection section) {
|
||||||
|
if (section == null) return null;
|
||||||
|
ItemStackConfig config = new ItemStackConfig();
|
||||||
|
if (section.contains("original") && section.isItemStack("original")) {
|
||||||
|
config.setOriginal(section.getItemStack("original"));
|
||||||
|
}
|
||||||
|
Optional.ofNullable(section.getString("material")).map(Material::matchMaterial).ifPresent(config::setMaterial);
|
||||||
|
Optional.ofNullable(section.getString("displayName")).ifPresent(config::setDisplayName);
|
||||||
|
Optional.of(section.getStringList("lore")).filter(l -> !l.isEmpty()).ifPresent(config::setLore);
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
package cc.carm.plugin.commanditem.listener;
|
||||||
|
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.entity.EntityPickupItemEvent;
|
||||||
|
import org.bukkit.event.inventory.CraftItemEvent;
|
||||||
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
|
|
||||||
|
public class ItemListener implements Listener {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 监听玩家点击,并执行物品对应的操作。
|
||||||
|
*
|
||||||
|
* @param event 玩家点击事件
|
||||||
|
*/
|
||||||
|
@EventHandler
|
||||||
|
public void onClick(PlayerInteractEvent event) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 监听玩家合成,阻止玩家将指令物品合成浪费掉。
|
||||||
|
*
|
||||||
|
* @param event 合成事件
|
||||||
|
*/
|
||||||
|
@EventHandler
|
||||||
|
public void onCraft(CraftItemEvent event) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阻止非玩家捡起指令物品
|
||||||
|
*
|
||||||
|
* @param event 捡起事件
|
||||||
|
*/
|
||||||
|
@EventHandler
|
||||||
|
public void onPickup(EntityPickupItemEvent event) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -5,8 +5,15 @@ import cc.carm.lib.easyplugin.configuration.language.MessagesConfig;
|
|||||||
import cc.carm.lib.easyplugin.configuration.language.MessagesInitializer;
|
import cc.carm.lib.easyplugin.configuration.language.MessagesInitializer;
|
||||||
import cc.carm.plugin.commanditem.Main;
|
import cc.carm.plugin.commanditem.Main;
|
||||||
import cc.carm.plugin.commanditem.configuration.PluginMessages;
|
import cc.carm.plugin.commanditem.configuration.PluginMessages;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
public class ConfigManager {
|
public class ConfigManager {
|
||||||
|
|
||||||
@ -53,5 +60,41 @@ public class ConfigManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <V> Map<String, V> readStringMap(@Nullable ConfigurationSection section,
|
||||||
|
@NotNull Function<String, V> valueCast) {
|
||||||
|
if (section == null) return new LinkedHashMap<>();
|
||||||
|
Map<String, V> result = new LinkedHashMap<>();
|
||||||
|
for (String key : section.getKeys(false)) {
|
||||||
|
V finalValue = valueCast.apply(section.getString(key));
|
||||||
|
if (finalValue != null) result.put(key, finalValue);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <V> Map<String, V> readSectionMap(@Nullable ConfigurationSection section,
|
||||||
|
@NotNull Function<ConfigurationSection, V> valueCast) {
|
||||||
|
if (section == null) return new LinkedHashMap<>();
|
||||||
|
Map<String, V> result = new LinkedHashMap<>();
|
||||||
|
for (String key : section.getKeys(false)) {
|
||||||
|
if (!section.isConfigurationSection(key)) continue;
|
||||||
|
V finalValue = valueCast.apply(section.getConfigurationSection(key));
|
||||||
|
if (finalValue != null) result.put(key, finalValue);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static <V> Map<String, V> readListMap(@Nullable ConfigurationSection section,
|
||||||
|
@NotNull Function<@NotNull List<String>, V> valueCast) {
|
||||||
|
if (section == null) return new LinkedHashMap<>();
|
||||||
|
Map<String, V> result = new LinkedHashMap<>();
|
||||||
|
for (String key : section.getKeys(false)) {
|
||||||
|
if (!section.isConfigurationSection(key)) continue;
|
||||||
|
V finalValue = valueCast.apply(section.getStringList(key));
|
||||||
|
if (finalValue != null) result.put(key, finalValue);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,124 @@
|
|||||||
|
package cc.carm.plugin.commanditem.manager;
|
||||||
|
|
||||||
|
import cc.carm.plugin.commanditem.Main;
|
||||||
|
import cc.carm.plugin.commanditem.configuration.PluginConfig;
|
||||||
|
import cc.carm.plugin.commanditem.item.CommandItem;
|
||||||
|
import cc.carm.plugin.commanditem.item.ItemSettings;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.bukkit.inventory.meta.tags.CustomItemTagContainer;
|
||||||
|
import org.bukkit.inventory.meta.tags.ItemTagType;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.annotations.Unmodifiable;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class ItemsManager {
|
||||||
|
|
||||||
|
private static final String FOLDER_NAME = "items";
|
||||||
|
|
||||||
|
public HashMap<String, ItemSettings> items = new HashMap<>();
|
||||||
|
|
||||||
|
protected NamespacedKey idKey;
|
||||||
|
protected NamespacedKey uuidKey;
|
||||||
|
|
||||||
|
public void initialize() {
|
||||||
|
this.idKey = new NamespacedKey(Main.getInstance(), "id");
|
||||||
|
this.uuidKey = new NamespacedKey(Main.getInstance(), "uuid");
|
||||||
|
loadItems();
|
||||||
|
Main.info("共加载了 " + items.size() + " 个前缀。");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadItems() {
|
||||||
|
File prefixDataFolder = getStorageFolder();
|
||||||
|
if (!prefixDataFolder.isDirectory() || !prefixDataFolder.exists()) {
|
||||||
|
boolean success = prefixDataFolder.mkdir();
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] filesList = prefixDataFolder.list();
|
||||||
|
if (filesList == null || filesList.length < 1) {
|
||||||
|
Main.severe("配置文件夹中暂无任何物品,请检查。");
|
||||||
|
Main.severe("There's no configured items.");
|
||||||
|
Main.severe("Path: " + prefixDataFolder.getAbsolutePath());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<File> files = Arrays.stream(filesList)
|
||||||
|
.map(s -> new File(prefixDataFolder, s))
|
||||||
|
.filter(File::isFile)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
HashMap<String, ItemSettings> dataItems = new HashMap<>();
|
||||||
|
|
||||||
|
if (files.size() > 0) {
|
||||||
|
for (File file : files) {
|
||||||
|
try {
|
||||||
|
ItemSettings item = ItemSettings.load(file);
|
||||||
|
Main.info("完成物品加载 " + item.getIdentifier() + " : " + item.getName());
|
||||||
|
Main.info("Successfully loaded " + item.getIdentifier() + " : " + item.getName());
|
||||||
|
dataItems.put(item.getIdentifier(), item);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Main.severe("在加载物品 " + file.getAbsolutePath() + " 时出错,请检查配置!");
|
||||||
|
Main.severe("Error occurred when loading item #" + file.getAbsolutePath() + " !");
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
items = dataItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static File getStorageFolder() {
|
||||||
|
if (PluginConfig.CustomStorage.ENABLE.get()) {
|
||||||
|
return new File(PluginConfig.CustomStorage.PATH.get());
|
||||||
|
} else {
|
||||||
|
return new File(Main.getInstance().getDataFolder() + File.separator + FOLDER_NAME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Unmodifiable
|
||||||
|
public Map<String, ItemSettings> listItemSettings() {
|
||||||
|
return ImmutableMap.copyOf(items);
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable ItemSettings getItemSettings(@NotNull String identifier) {
|
||||||
|
return items.get(identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemStack applyTag(@NotNull ItemStack originalItem, String identifier, UUID uuid) {
|
||||||
|
if (!originalItem.hasItemMeta()) return originalItem;
|
||||||
|
ItemMeta meta = originalItem.getItemMeta();
|
||||||
|
if (meta == null) return originalItem;
|
||||||
|
CustomItemTagContainer container = meta.getCustomTagContainer();
|
||||||
|
container.setCustomTag(idKey, ItemTagType.STRING, identifier);
|
||||||
|
container.setCustomTag(uuidKey, ItemTagType.STRING, uuid.toString());
|
||||||
|
originalItem.setItemMeta(meta);
|
||||||
|
return originalItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable CommandItem parseCommandItem(@Nullable ItemStack item) {
|
||||||
|
if (item == null) return null;
|
||||||
|
if (!item.hasItemMeta()) return null;
|
||||||
|
ItemMeta meta = item.getItemMeta();
|
||||||
|
if (meta == null) return null;
|
||||||
|
CustomItemTagContainer container = meta.getCustomTagContainer();
|
||||||
|
String settingsID = container.getCustomTag(this.idKey, ItemTagType.STRING);
|
||||||
|
String itemUUID = container.getCustomTag(this.uuidKey, ItemTagType.STRING);
|
||||||
|
if (settingsID == null || itemUUID == null) return null;
|
||||||
|
ItemSettings settings = getItemSettings(settingsID);
|
||||||
|
if (settings == null) return null;
|
||||||
|
return new CommandItem(UUID.fromString(itemUUID), settings, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCommandItem(ItemStack item) {
|
||||||
|
return item.hasItemMeta() && item.getItemMeta() != null
|
||||||
|
&& item.getItemMeta().getCustomTagContainer().hasCustomTag(idKey, ItemTagType.STRING);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -15,6 +15,14 @@ metrics: true
|
|||||||
# 检查更新为异步操作,绝不会影响性能与使用体验。
|
# 检查更新为异步操作,绝不会影响性能与使用体验。
|
||||||
check-update: true
|
check-update: true
|
||||||
|
|
||||||
|
custom-storage:
|
||||||
|
# 自定义存储位置
|
||||||
|
# 默认存储位置为 “插件文件夹”/items
|
||||||
|
# 可以规定到远程文件夹中去寻找前缀相关的设定
|
||||||
|
# 支持绝对文件路径,如 "/etc/minecraft/configurations/items/"
|
||||||
|
enable: false # 是否启用
|
||||||
|
path: "items/" # 一定要指向一个文件夹!
|
||||||
|
|
||||||
log-storage:
|
log-storage:
|
||||||
# 是否启用日志记录存储
|
# 是否启用日志记录存储
|
||||||
# 可用于追踪物品的发放、领取情况与执行记录。
|
# 可用于追踪物品的发放、领取情况与执行记录。
|
||||||
@ -32,4 +40,6 @@ log-storage:
|
|||||||
password: "password"
|
password: "password"
|
||||||
extra: "?useSSL=false"
|
extra: "?useSSL=false"
|
||||||
# 插件相关表的名称
|
# 插件相关表的名称
|
||||||
table-name: "log_item_commands"
|
tables:
|
||||||
|
give: "log_item_give"
|
||||||
|
take: "log_item_take"
|
55
src/main/resources/items/.example-item.yml
Normal file
55
src/main/resources/items/.example-item.yml
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
# 唯一标识 [必须]
|
||||||
|
# 将用于判定一个物品对于的配置文件
|
||||||
|
# 必须 必须 必须 保持唯一!
|
||||||
|
identifier: "pro"
|
||||||
|
|
||||||
|
name: "Pro会员前缀"
|
||||||
|
|
||||||
|
item:
|
||||||
|
# 使用原生 ItemStack 配置物品 可能引起配置无法加载而报错!
|
||||||
|
original:
|
||||||
|
==: org.bukkit.inventory.ItemStack
|
||||||
|
type: DIAMOND
|
||||||
|
damage: 8
|
||||||
|
meta:
|
||||||
|
==: ItemMeta
|
||||||
|
meta-type: UNSPECIFIC
|
||||||
|
display-name: "&b&lPro+ &b会员前缀"
|
||||||
|
lore:
|
||||||
|
- "&7手持物品右键点击即可获得!"
|
||||||
|
|
||||||
|
# 使用插件提供的方法配置物品,更简单
|
||||||
|
type: DIAMOND
|
||||||
|
name: "&b&lPro+ &b会员前缀"
|
||||||
|
lore:
|
||||||
|
- "&7手持物品右键点击即可获得!"
|
||||||
|
|
||||||
|
functions:
|
||||||
|
log-give: true # 是否为该物品记录发放日志
|
||||||
|
log-take: false # 是否为该物品记录拿取日志 (即出现 [take] action 时记录)
|
||||||
|
|
||||||
|
# 限定相关配置
|
||||||
|
restrictions:
|
||||||
|
time: # 允许领取的时间范围
|
||||||
|
start: 2021-12-21 15:33:21 # 开始时间,若无该选项则不限制开始时间
|
||||||
|
end: 2022-01-21 15:33:21 # 结束时间,若无该选项则不限制结束时间
|
||||||
|
|
||||||
|
# 相关权限设定
|
||||||
|
# 若玩家拥有配置的权限,则会执行权限对应的操作;
|
||||||
|
# 权限配置从上向下判断,若权限设定为空,则会使用default的操作。
|
||||||
|
permissions:
|
||||||
|
normal: "prefix.item.use"
|
||||||
|
have: "prefix.pro"
|
||||||
|
|
||||||
|
# 玩家右键物品时执行的操作
|
||||||
|
actions:
|
||||||
|
default: # 默认执行的操作
|
||||||
|
- "[message] &c您没有使用该物品的权限!"
|
||||||
|
normal: # 若有 normal 权限设定,则执行此操作
|
||||||
|
- "[console] say %player_name% 获得了 %name% !"
|
||||||
|
- "[console] lp user %player_name% permission set prefix.pro true"
|
||||||
|
- "[chat] /prefix" # 以玩家聊天的形式发出消息,若以 "/" 开头则会被视为命令
|
||||||
|
- "[sound] ENTITY_PLAYER_LEVELUP" # 播放声音
|
||||||
|
- "[take]" # 拿走对应物品 (即数量-1)
|
||||||
|
have:
|
||||||
|
- "[message] &c您已经拥有了该前缀,无法重复领取!"
|
Loading…
Reference in New Issue
Block a user