diff --git a/src/main/java/com/carmwork/plugin/timeforflight/Main.java b/src/main/java/com/carmwork/plugin/timeforflight/Main.java index 1cbc491..7b50d98 100644 --- a/src/main/java/com/carmwork/plugin/timeforflight/Main.java +++ b/src/main/java/com/carmwork/plugin/timeforflight/Main.java @@ -1,7 +1,11 @@ package com.carmwork.plugin.timeforflight; +import com.carmwork.plugin.timeforflight.commands.ToggleFlyCommand; +import com.carmwork.plugin.timeforflight.managers.ConfigManager; import org.bukkit.plugin.java.JavaPlugin; +import java.util.logging.Level; + public class Main extends JavaPlugin { private static Main instance; @@ -14,7 +18,16 @@ public class Main extends JavaPlugin { public void onEnable() { instance = this; + logInfo("加载配置文件中"); + ConfigManager.loadConfig(); + + logInfo("注册指令"); + Main.getInstance().getCommand("togglefly").setExecutor(new ToggleFlyCommand()); } + public static void logInfo(String message) { + Main.getInstance().getLogger().log(Level.INFO, message); + } + } \ No newline at end of file diff --git a/src/main/java/com/carmwork/plugin/timeforflight/commands/TimeForFlightCommand.java b/src/main/java/com/carmwork/plugin/timeforflight/commands/TimeForFlightCommand.java index 0f993eb..d2bcaf2 100644 --- a/src/main/java/com/carmwork/plugin/timeforflight/commands/TimeForFlightCommand.java +++ b/src/main/java/com/carmwork/plugin/timeforflight/commands/TimeForFlightCommand.java @@ -1,4 +1,7 @@ package com.carmwork.plugin.timeforflight.commands; +/** + * 管理员管理、查看玩家飞行时间的指令 + */ public class TimeForFlightCommand { } diff --git a/src/main/java/com/carmwork/plugin/timeforflight/commands/ToggleFlyCommand.java b/src/main/java/com/carmwork/plugin/timeforflight/commands/ToggleFlyCommand.java new file mode 100644 index 0000000..99a4896 --- /dev/null +++ b/src/main/java/com/carmwork/plugin/timeforflight/commands/ToggleFlyCommand.java @@ -0,0 +1,92 @@ +package com.carmwork.plugin.timeforflight.commands; + +import com.carmwork.plugin.timeforflight.managers.DataManager; +import com.carmwork.plugin.timeforflight.models.UserData; +import com.carmwork.plugin.timeforflight.utils.MessageParser; +import com.carmwork.plugin.timeforflight.utils.TimeFormat; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +/** + * 开关飞行的指令 + */ +public class ToggleFlyCommand implements CommandExecutor { + + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (args.length == 0 || !sender.isOp()) { + if (!(sender instanceof Player)) { + sender.sendMessage(MessageParser.parseColor("该指令只允许玩家使用。")); + sender.sendMessage(MessageParser.parseColor("您可以输入 /togglefly <玩家名> 设置某个玩家的飞行状态。")); + return true; + } + + Player player = (Player) sender; + + UserData userData = DataManager.getData(player.getUniqueId()); + if (player.hasPermission("timeforflight.unlimited")) { + + player.setAllowFlight(true); + player.sendMessage(MessageParser.parseColor("&f您现在可以飞行了!")); + return true; + } else if (player.hasPermission("timeforflight.allowflight")) { + if (userData.canFly()) { + userData.startFlyTask(player); + player.sendMessage(MessageParser.parseColor("&f您现在可以飞行了!")); + player.sendMessage(MessageParser.parseColor("&f剩余飞行时长 &a" + TimeFormat.getTimeString(userData.getRemainTime()))); + return true; + } else { + player.sendMessage(MessageParser.parseColor("&c您的飞行时长不足,无法开启飞行。")); + return true; + } + } else { + player.sendMessage(MessageParser.parseColor("&c抱歉!&f但您没有使用该指令的权限。")); + return true; + } + } else if (args.length == 1) { + if (!sender.isOp()) { + sender.sendMessage(MessageParser.parseColor("&c抱歉!&f但您没有使用该指令的权限。")); + return true; + } + Player player = Bukkit.getPlayer(args[0]); + if (player == null) { + sender.sendMessage("玩家 " + args[0] + " 不在线。"); + return true; + } + + UserData userData = DataManager.getData(player.getUniqueId()); + if (player.hasPermission("timeforflight.unlimited")) { + + player.setAllowFlight(true); + player.sendMessage(MessageParser.parseColor("&f您现在可以飞行了!")); + sender.sendMessage(MessageParser.parseColor("已为玩家 " + player.getName() + " 开启飞行。")); + return true; + } else if (player.hasPermission("timeforflight.allowflight")) { + if (userData.canFly()) { + userData.startFlyTask(player); + player.sendMessage(MessageParser.parseColor("&f您现在可以飞行了!")); + player.sendMessage(MessageParser.parseColor("&f剩余飞行时长 &a" + TimeFormat.getTimeString(userData.getRemainTime()))); + sender.sendMessage(MessageParser.parseColor("已为玩家 " + player.getName() + " 开启飞行。")); + + return true; + } else { + player.sendMessage(MessageParser.parseColor("&c您的飞行时长不足,无法开启飞行。")); + sender.sendMessage(MessageParser.parseColor("玩家 " + player.getName() + " 飞行时间不足。")); + return true; + } + } else { + sender.sendMessage(MessageParser.parseColor("玩家 " + player.getName() + " 没有飞行权限。")); + return true; + } + + + } + return true; + } + + +} diff --git a/src/main/java/com/carmwork/plugin/timeforflight/listeners/PlayerListener.java b/src/main/java/com/carmwork/plugin/timeforflight/listeners/PlayerListener.java new file mode 100644 index 0000000..e4281b6 --- /dev/null +++ b/src/main/java/com/carmwork/plugin/timeforflight/listeners/PlayerListener.java @@ -0,0 +1,37 @@ +package com.carmwork.plugin.timeforflight.listeners; + +import com.carmwork.plugin.timeforflight.managers.DataManager; +import com.carmwork.plugin.timeforflight.models.UserData; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +public class PlayerListener implements Listener { + + @EventHandler + public void onJoin(PlayerJoinEvent event) { + Player player = event.getPlayer(); + UserData playerCache = DataManager.loadData(player.getUniqueId()); + if (player.hasPermission("timeforflight.getflighttime") + && !player.hasPermission("timeforflight.unlimited")) { + playerCache.startGivenTask(player); + } + + } + + @EventHandler + public void onQuit(PlayerQuitEvent event) { + Player player = event.getPlayer(); + UserData playerCache = DataManager.getData(player.getUniqueId()); + + if (player.getAllowFlight()) { + player.setAllowFlight(false); + player.setFlying(false); + } + + + DataManager.unloadData(player.getUniqueId()); + } +} diff --git a/src/main/java/com/carmwork/plugin/timeforflight/managers/ConfigManager.java b/src/main/java/com/carmwork/plugin/timeforflight/managers/ConfigManager.java new file mode 100644 index 0000000..7bf2c4c --- /dev/null +++ b/src/main/java/com/carmwork/plugin/timeforflight/managers/ConfigManager.java @@ -0,0 +1,53 @@ +package com.carmwork.plugin.timeforflight.managers; + +import com.carmwork.plugin.timeforflight.Main; +import com.carmwork.plugin.timeforflight.utils.MessageParser; +import org.bukkit.configuration.file.FileConfiguration; + +import java.util.Objects; + +public class ConfigManager { + + + private static FileConfiguration configuration; + + public static void loadConfig() { + + Main.getInstance().saveDefaultConfig(); + Main.getInstance().reloadConfig(); + + configuration = Main.getInstance().getConfig(); + + } + + public static int getTimeInterval() { + return getConfiguration().getInt("settings.interval", 600); + } + + public static int getTimeGiven() { + return getConfiguration().getInt("settings.giveTime", 60); + } + + public static boolean isAlertEnabled() { + return getConfiguration().getBoolean("settings.alert.enable", true); + } + + /** + * # - 变量: %(interval) 间隔时间 + * # - 变量: %(time) 赠送时间 + * + * @return 通知消息 + */ + public static String getAlertMessage() { + return MessageParser.parseColor(Objects.requireNonNull(getConfiguration().getString( + "settings.alert.message", + "&7您刚刚完成了一次在线 &f%(interval) 秒&7,获增了 &f%(time) 秒&7飞行时间。" + ))) + .replace("%(interval)", Integer.toString(getTimeInterval())) + .replace("%(time)", Integer.toString(getTimeGiven())); + } + + public static FileConfiguration getConfiguration() { + return configuration; + } +} diff --git a/src/main/java/com/carmwork/plugin/timeforflight/managers/DataManager.java b/src/main/java/com/carmwork/plugin/timeforflight/managers/DataManager.java new file mode 100644 index 0000000..47e2995 --- /dev/null +++ b/src/main/java/com/carmwork/plugin/timeforflight/managers/DataManager.java @@ -0,0 +1,63 @@ +package com.carmwork.plugin.timeforflight.managers; + +import com.carmwork.plugin.timeforflight.Main; +import com.carmwork.plugin.timeforflight.models.UserData; + +import java.io.File; +import java.util.*; + +public class DataManager { + private static File userdatasFolder; + + /** + * 通过这个Map缓存玩家的数据 + */ + public static Map userDatas = new HashMap<>(); + + public static void init() { + userdatasFolder = new File(Main.getInstance().getDataFolder() + File.separator + "userdatas"); + if (!userdatasFolder.isDirectory() || !userdatasFolder.exists()) { + userdatasFolder.mkdir(); + } + } + + public static UserData loadData(UUID uuid) { + UserData prefixCache = new UserData(uuid); + + userDatas.put(uuid, prefixCache); + + return prefixCache; + } + + + public static UserData getData(UUID uuid) { + return userDatas.getOrDefault(uuid, loadData(uuid)); + } + + public static void unloadData(UUID uuid) { + if (isDataLoaded(uuid)) { + UserData data = getData(uuid); + data.stopTasks(); + data.saveData(); + + userDatas.remove(uuid); + } + } + + + public static boolean isDataLoaded(UUID uuid) { + return userDatas.containsKey(uuid); + } + + /** + * 判断一个UUID是否有已保存的数据 + * + * @param uuid 判断的UUID + * @return 是否已有数据 + */ + public static boolean hasData(UUID uuid) { + return Arrays.stream(Objects.requireNonNull(userdatasFolder.listFiles())) + .anyMatch(file -> file.getName().startsWith(uuid.toString())); + } + +} diff --git a/src/main/java/com/carmwork/plugin/timeforflight/models/UserData.java b/src/main/java/com/carmwork/plugin/timeforflight/models/UserData.java new file mode 100644 index 0000000..809cf08 --- /dev/null +++ b/src/main/java/com/carmwork/plugin/timeforflight/models/UserData.java @@ -0,0 +1,167 @@ +package com.carmwork.plugin.timeforflight.models; + +import com.carmwork.plugin.timeforflight.Main; +import com.carmwork.plugin.timeforflight.managers.ConfigManager; +import org.bukkit.Bukkit; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +import java.io.File; +import java.io.IOException; +import java.util.UUID; + +public class UserData { + + + UUID uuid; + + private File datafile; + private FileConfiguration data; + + boolean fileLoaded; + + private int remainTime; + + private BukkitRunnable giveTask; + private BukkitRunnable flyTask; + + + public UserData(UUID uuid) { + this.uuid = uuid; + File userdatasFolder = new File(Main.getInstance().getDataFolder() + "/userdatas"); + if (!userdatasFolder.isDirectory() || !userdatasFolder.exists()) { + userdatasFolder.mkdir(); + } + this.datafile = new File(userdatasFolder, this.uuid + ".yml"); + this.remainTime = 0; + + + this.fileLoaded = datafile.exists(); + if (fileLoaded) { + this.data = YamlConfiguration.loadConfiguration(datafile); + + readData(); + } + } + + public void startFlyTask(Player player) { + player.setAllowFlight(true); + flyTask = new BukkitRunnable() { + @Override + public void run() { + if (canFly()) { + removeTime(1); + } else { + player.setAllowFlight(false); + player.setFlying(false); + } + } + }; + flyTask.runTaskTimer(Main.getInstance(), 0L, 20L); + + } + + public void stopFly() { + if (this.flyTask != null) { + this.flyTask.cancel(); + } + } + + public void readData() { + this.remainTime = getData().getInt("remainTime"); + } + + public void addTime(int remainTime) { + this.remainTime += remainTime; + } + + public void removeTime(int time) { + this.remainTime -= time; + } + + public void addTimeInConfig() { + addTime(ConfigManager.getTimeGiven()); + } + + public boolean canFly() { + return getRemainTime() > 0; + } + + + public BukkitRunnable getGiveTask() { + return giveTask; + } + + public void startGivenTask(Player player) { + giveTask = new BukkitRunnable() { + @Override + public void run() { + if (!player.isOnline() + || !player.hasPermission("timeforflight.getflighttime") + || player.hasPermission("timeforflight.unlimited")) { + cancel(); + } + addTimeInConfig(); + if (ConfigManager.isAlertEnabled()) { + player.sendMessage(ConfigManager.getAlertMessage()); + } + } + }; + + getGiveTask().runTaskTimerAsynchronously(Main.getInstance(), + ConfigManager.getTimeInterval() * 20, + ConfigManager.getTimeInterval() * 20); + } + + public void stopTasks() { + if (getGiveTask() != null) { + getGiveTask().cancel(); + } + if (this.flyTask != null) { + this.flyTask.cancel(); + } + } + + public boolean isFileLoaded() { + return fileLoaded; + } + + public File getDatafile() { + return datafile; + } + + public FileConfiguration getData() { + return data; + } + + public int getRemainTime() { + return remainTime; + } + + private void checkFile() { + if (!datafile.exists()) { + try { + datafile.createNewFile(); + } catch (IOException ex) { + Bukkit.getLogger().info("Could not load file " + "/userdatas/" + "yml" + ex); + } + } + if (!isFileLoaded()) { + this.data = YamlConfiguration.loadConfiguration(datafile); + this.fileLoaded = true; + } + } + + public void saveData() { + checkFile(); + getData().set("remainTime", getRemainTime()); + try { + getData().save(datafile); + } catch (IOException e) { + e.printStackTrace(); + } + } + +} diff --git a/src/main/java/com/carmwork/plugin/timeforflight/utils/MessageParser.java b/src/main/java/com/carmwork/plugin/timeforflight/utils/MessageParser.java new file mode 100644 index 0000000..e5c6887 --- /dev/null +++ b/src/main/java/com/carmwork/plugin/timeforflight/utils/MessageParser.java @@ -0,0 +1,12 @@ +package com.carmwork.plugin.timeforflight.utils; + +import net.md_5.bungee.api.chat.BaseComponent; + +public class MessageParser { + + public static String parseColor(String text) { + return text.replaceAll("&", "§").replace("§§", "&"); + } + + +} diff --git a/src/main/java/com/carmwork/plugin/timeforflight/utils/TimeFormat.java b/src/main/java/com/carmwork/plugin/timeforflight/utils/TimeFormat.java new file mode 100644 index 0000000..850a19e --- /dev/null +++ b/src/main/java/com/carmwork/plugin/timeforflight/utils/TimeFormat.java @@ -0,0 +1,23 @@ +package com.carmwork.plugin.timeforflight.utils; + +public class TimeFormat { + + + public static String getTimeString(int time) { + int temp; + StringBuilder sb = new StringBuilder(); + + temp = time / 60 / 60 % 60; + sb.append((temp < 10) ? "0" + temp + ":" : "" + temp + ":"); + + temp = time % 3600 / 60; + sb.append((temp < 10) ? "0" + temp + ":" : "" + temp + ":"); + + temp = time % 3600 % 60; + sb.append((temp < 10) ? "0" + temp : "" + temp); + + return sb.toString(); + } + + +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml new file mode 100644 index 0000000..00e90b8 --- /dev/null +++ b/src/main/resources/config.yml @@ -0,0 +1,14 @@ +#权限节点 +# + + +settings: + interval: 60 #赠送飞行时间的在线时长间隔(秒) + giveTime: 6 #每满足一次赠送条件时 赠送的飞行时长(秒) + alert: #玩家通知 + enable: true #是否启用玩家通知 + # 通知消息 + # - 支持使用 “&” 代替小结号作为颜色符号 + # - 变量: %(interval) 间隔时间 + # - 变量: %(time) 赠送时间 + message: "&7您刚刚完成了一次在线 &f%(interval) 秒&7,获增了 &f%(time) 秒&7飞行时间。" \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 9474c3f..6489d90 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -6,4 +6,15 @@ depend: [ProtocolLib] commands: TimeForFlight: aliases: - - flighttime \ No newline at end of file + - flighttime + ToggleFly: + aliases: + - ToggleFlight +permissions: + timeforflight.unlimited: + default: op + description: "无限制飞行,不计算飞行时间" + timeforflight.allowflight: + description: "拥有此权限的玩家允许飞行" + timeforflight.getflighttime: + description: "拥有次权限的玩家会获赠飞行时间" \ No newline at end of file