From 23e723c236ce676b14e85ba4359435589c3dbc55 Mon Sep 17 00:00:00 2001 From: zhangyuheng Date: Tue, 30 Jul 2024 15:14:43 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E7=BC=A9=E7=95=A5=E5=9B=BE?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=20=E6=96=B0=E5=A2=9E=E5=8E=9F=E5=9B=BE?= =?UTF-8?q?=E4=BF=9D=E5=AD=98=E4=B8=8E=E7=8E=A9=E5=AE=B6=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E8=AE=B0=E5=BD=95=EF=BC=88=E6=96=B9=E4=BE=BF=E6=9F=A5=E5=9B=BE?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 49 ++++--- pom.xml | 27 +++- .../cn/lunadeer/colorfulmap/ColorfulMap.java | 14 +- .../lunadeer/colorfulmap/Configuration.java | 46 +++++++ .../java/cn/lunadeer/colorfulmap/Events.java | 49 ++++++- .../cn/lunadeer/colorfulmap/MapManager.java | 17 ++- .../cn/lunadeer/colorfulmap/StorageMaps.java | 54 ++++++-- .../lunadeer/colorfulmap/commands/Reload.java | 19 +++ .../lunadeer/colorfulmap/commands/ToMap.java | 11 +- .../lunadeer/colorfulmap/generator/Multi.java | 49 ++++--- .../colorfulmap/generator/TextRenderer.java | 55 -------- .../cn/lunadeer/colorfulmap/utils/Common.java | 14 ++ .../colorfulmap/utils/GiteaReleaseCheck.java | 43 ++++-- .../lunadeer/colorfulmap/utils/ImageTool.java | 33 +++++ .../colorfulmap/utils/Notification.java | 92 +++++++++++-- .../lunadeer/colorfulmap/utils/Scheduler.java | 126 ++++++++++++++++++ .../utils/SendMessageAbstract.java | 52 ++++++++ .../cn/lunadeer/colorfulmap/utils/Time.java | 67 ---------- .../colorfulmap/utils/VaultConnect/Vault.java | 48 +++++++ .../utils/VaultConnect/Vault2.java | 50 +++++++ .../utils/VaultConnect/VaultConnect.java | 94 +++++++++++++ .../utils/VaultConnect/VaultInterface.java | 21 +++ .../lunadeer/colorfulmap/utils/XLogger.java | 64 +++++---- .../bStatsMetrics.java} | 6 +- src/main/resources/config.yml | 4 + src/main/resources/plugin.yml | 7 + 26 files changed, 854 insertions(+), 257 deletions(-) create mode 100644 src/main/java/cn/lunadeer/colorfulmap/commands/Reload.java delete mode 100644 src/main/java/cn/lunadeer/colorfulmap/generator/TextRenderer.java create mode 100644 src/main/java/cn/lunadeer/colorfulmap/utils/Common.java create mode 100644 src/main/java/cn/lunadeer/colorfulmap/utils/ImageTool.java create mode 100644 src/main/java/cn/lunadeer/colorfulmap/utils/Scheduler.java create mode 100644 src/main/java/cn/lunadeer/colorfulmap/utils/SendMessageAbstract.java delete mode 100644 src/main/java/cn/lunadeer/colorfulmap/utils/Time.java create mode 100644 src/main/java/cn/lunadeer/colorfulmap/utils/VaultConnect/Vault.java create mode 100644 src/main/java/cn/lunadeer/colorfulmap/utils/VaultConnect/Vault2.java create mode 100644 src/main/java/cn/lunadeer/colorfulmap/utils/VaultConnect/VaultConnect.java create mode 100644 src/main/java/cn/lunadeer/colorfulmap/utils/VaultConnect/VaultInterface.java rename src/main/java/cn/lunadeer/colorfulmap/{Metrics.java => utils/bStatsMetrics.java} (99%) diff --git a/README.md b/README.md index 41ec850..4cf2d6c 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,33 @@ +
+ # ColorfulMap + + ### [开源地址](https://ssl.lunadeer.cn:14446/zhangyuheng/ColorfulMap) | [文档地址](https://ssl.lunadeer.cn:14448/doc/26/) + ### [下载页面](https://ssl.lunadeer.cn:14446/zhangyuheng/ColorfulMap/releases) + ### [统计页面](https://bstats.org/plugin/bukkit/ColorfulMap/21443) | [Hangar](https://hangar.papermc.io/zhangyuheng/ColorfulMap) -## 简介 +
-![](https://ssl.lunadeer.cn:14437/i/2024/02/21/65d5e0d10b7d5.png) +## 简介 用于将图片转换为地图画,悬挂在展示框上增添装饰。 ## 说明 -本插件大约相当于 [ImageFrame](https://github.com/LOOHP/ImageFrame) 的简版以及 [ImageMaps](https://github.com/SydMontague/ImageMaps) 的高版本重制版。前者功能丰富,不过可能由于项目体量较大,对于新版本的兼容较慢,后者在 1.18 开始就停止了更新,切不支持 Folia 核心。 +本插件大约相当于 [ImageFrame](https://github.com/LOOHP/ImageFrame) +的简版以及 [ImageMaps](https://github.com/SydMontague/ImageMaps) 的高版本重制版。前者功能丰富,不过可能由于项目体量较大,对于新版本的兼容较慢,后者在 +1.18 开始就停止了更新,切不支持 Folia 核心。 ## 功能介绍 - 将图片转换为地图画; - 图片缩放; - 自动放置; +- 支持消耗金钱生成地图画(需要 Vault 前置); ## 支持版本 @@ -33,32 +42,35 @@ ## 玩家使用方法 -1. 首先需要将你想要转换的图片上传到 [图床](https://ssl.lunadeer.cn:14437/) ,便于本插件从网络读取图片内容。上传完成后会得到一个图片的网络地址,复制此地址。 +1. 首先需要将你想要转换的图片上传到 [图床](https://ssl.lunadeer.cn:14437/) ,便于本插件从网络读取图片内容。上传完成后会得到一个图片的网络地址,复制此地址。 -2. 在游戏中输入指令:`/tomap <图片地址>` 即可获得一张地图。地图的左上角会显示这张地图画所需的展示框阵列的尺寸,如下图所示 5x4 代表你需要在墙上准备一组长5格,宽4格的展示框阵列才能摆的下这张地图画。 +2. 在游戏中输入指令:`/tomap <图片地址>` 即可获得一张地图。地图的左上角会显示这张地图画所需的展示框阵列的尺寸,如下图所示 + 5x4 代表你需要在墙上准备一组长5格,宽4格的展示框阵列才能摆的下这张地图画。 -![](https://ssl.lunadeer.cn:14437/i/2024/02/21/65d5ef7e8d676.png) + ![](https://ssl.lunadeer.cn:14437/i/2024/02/21/65d5ef7e8d676.png) 3. 对着展示框阵列的**左下角展示框**摆放此地图,则会自动在墙上的剩余展示框内放置对应的地图。 -4. 如果图片太大或太小可以尝试在指令后加入缩放倍率,例如 `/tomap <图片地址> 0.5`表示将以原图的50%大小渲染。如果你希望将图片填满所有地图边缘处没有留白,那么你需要保证你的图片的长宽分辨率均为**128的倍数**,因为在MC中一张地图的分辨率为128x128。 +4. 如果图片太大或太小可以尝试在指令后加入缩放倍率,例如 `/tomap <图片地址> 0.5` + 表示将以原图的50%大小渲染。如果你希望将图片填满所有地图边缘处没有留白,那么你需要保证你的图片的长宽分辨率均为**128的倍数 + **,因为在MC中一张地图的分辨率为128x128。 ## 管理员指南 -## 指令 +## 指令 & 权限节点 -> 以下指令中尖括号 `<>` 表示必填,方括号 `[]` 表示选填。 +> 以下指令中尖括号 `<>` 表示必填,方括号 `[]` 表示选填。 -### 玩家指令 +| 功能 | 指令 | 权限节点 | 默认 | +|-------|------------------------|--------------------|------| +| 生成地图画 | `/tomap <图片地址> [缩放倍率]` | colorfulmap.tomap | true | +| 重载配置 | `/reloadColorfulMap` | colorfulmap.reload | op | +## 如何查图 -| 功能 | 指令 | 权限节点 | -|-------|------------------------|-------------------| -| 生成地图画 | `/tomap <图片地址> [缩放倍率]` | colorfulmap.tomap | +2.0版本开始地图画会保存一份玩家获取图片的原图,路径为 `plugins/ColorfulMap/maps/{图片uuid}/raw.png` ,方便服主快速查阅图片内容。 - - -### 管理员指令 +当玩家放置地图后还会同时保存一份元数据文件,`plugins/ColorfulMap/maps/{图片uuid}/meta.txt`,此文件记录了放置地图的玩家、放置时间、地图画的位置等信息。 ## 配置文件参考 @@ -69,6 +81,10 @@ MaxFrameY: 18 CheckUpdate: true +Economy: + Enable: false + CostPerMap: 100.0 + Debug: false ``` @@ -80,7 +96,6 @@ Mail: [zhangyuheng@lunadeer.cn](mailto:zhangyuheng@lunadeer.cn) QQ群:309428300 - ## 统计 ![bstats](https://bstats.org/signatures/bukkit/ColorfulMap.svg) diff --git a/pom.xml b/pom.xml index d93fe1b..b370ab2 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ cn.lunadeer ColorfulMap - 1.5 + 2.0 jar ColorfulMap @@ -62,6 +62,14 @@ papermc https://repo.papermc.io/repository/maven-public/ + + jitpack.io + https://jitpack.io + + + codemc-repo + https://repo.codemc.org/repository/maven-public + @@ -71,5 +79,22 @@ 1.20.1-R0.1-SNAPSHOT provided + + net.kyori + adventure-platform-bukkit + 4.3.3 + + + com.github.MilkBowl + VaultAPI + 1.7 + provided + + + net.milkbowl.vault + VaultUnlockedAPI + 2.2 + provided + diff --git a/src/main/java/cn/lunadeer/colorfulmap/ColorfulMap.java b/src/main/java/cn/lunadeer/colorfulmap/ColorfulMap.java index 4728e50..172df2e 100644 --- a/src/main/java/cn/lunadeer/colorfulmap/ColorfulMap.java +++ b/src/main/java/cn/lunadeer/colorfulmap/ColorfulMap.java @@ -1,8 +1,8 @@ package cn.lunadeer.colorfulmap; +import cn.lunadeer.colorfulmap.commands.Reload; import cn.lunadeer.colorfulmap.commands.ToMap; -import cn.lunadeer.colorfulmap.utils.GiteaReleaseCheck; -import cn.lunadeer.colorfulmap.utils.XLogger; +import cn.lunadeer.colorfulmap.utils.*; import org.bukkit.Bukkit; import org.bukkit.plugin.java.JavaPlugin; @@ -15,13 +15,19 @@ public final class ColorfulMap extends JavaPlugin { // Plugin startup logic instance = this; config = new Configuration(this); + new XLogger(this); + XLogger.setDebug(config.isDebug()); + new Notification(this); + new Scheduler(this); Objects.requireNonNull(Bukkit.getPluginCommand("tomap")).setExecutor(new ToMap()); + Objects.requireNonNull(Bukkit.getPluginCommand("reloadColorfulMap")).setExecutor(new Reload()); + Bukkit.getPluginManager().registerEvents(new Events(), this); new MapManager().init(); - Metrics metrics = new Metrics(this, 21443); + bStatsMetrics metrics = new bStatsMetrics(this, 21443); if (config.isCheckUpdate()) { giteaReleaseCheck = new GiteaReleaseCheck(this, "https://ssl.lunadeer.cn:14446", @@ -30,7 +36,7 @@ public final class ColorfulMap extends JavaPlugin { } XLogger.info("ColorfulMap 已加载"); - XLogger.info("版本: " + getPluginMeta().getVersion()); + XLogger.info("版本: " + this.getDescription().getVersion()); // https://patorjk.com/software/taag/#p=display&f=Big&t=ColorfulMap XLogger.info(" _____ _ __ _ __ __"); XLogger.info(" / ____| | | / _| | | \\/ |"); diff --git a/src/main/java/cn/lunadeer/colorfulmap/Configuration.java b/src/main/java/cn/lunadeer/colorfulmap/Configuration.java index 727f9a1..ee15210 100644 --- a/src/main/java/cn/lunadeer/colorfulmap/Configuration.java +++ b/src/main/java/cn/lunadeer/colorfulmap/Configuration.java @@ -1,5 +1,7 @@ package cn.lunadeer.colorfulmap; +import cn.lunadeer.colorfulmap.utils.VaultConnect.VaultConnect; +import cn.lunadeer.colorfulmap.utils.XLogger; import org.bukkit.configuration.file.FileConfiguration; public class Configuration { @@ -18,6 +20,22 @@ public class Configuration { _max_frame_x = _file.getInt("MaxFrameX", 32); _max_frame_y = _file.getInt("MaxFrameY", 18); _check_update = _file.getBoolean("CheckUpdate", true); + _economy_enable = _file.getBoolean("Economy.Enable", false); + _price = (float) _file.getDouble("Economy.CostPerMap", 100.0); + if (_economy_enable) { + XLogger.info("已启用经济系统"); + new VaultConnect(_plugin); + } + } + + public void saveAll() { + _file.set("Debug", _debug); + _file.set("MaxFrameX", _max_frame_x); + _file.set("MaxFrameY", _max_frame_y); + _file.set("CheckUpdate", _check_update); + _file.set("Economy.Enable", _economy_enable); + _file.set("Economy.CostPerMap", _price); + _plugin.saveConfig(); } public Boolean isDebug() { @@ -54,10 +72,38 @@ public class Configuration { return _check_update; } + public void setCheckUpdate(Boolean check_update) { + _check_update = check_update; + _file.set("CheckUpdate", check_update); + _plugin.saveConfig(); + } + + public Boolean isEconomyEnable() { + return _economy_enable; + } + + public void setEconomyEnable(Boolean economy_enable) { + _economy_enable = economy_enable; + _file.set("Economy.Enable", economy_enable); + _plugin.saveConfig(); + } + + public Float getPrice() { + return _price; + } + + public void setPrice(Float price) { + _price = price; + _file.set("Economy.CostPerMap", price); + _plugin.saveConfig(); + } + private final ColorfulMap _plugin; private FileConfiguration _file; private Boolean _debug; private Integer _max_frame_x; private Integer _max_frame_y; private Boolean _check_update; + private Boolean _economy_enable; + private Float _price; } diff --git a/src/main/java/cn/lunadeer/colorfulmap/Events.java b/src/main/java/cn/lunadeer/colorfulmap/Events.java index dfc924e..f095e20 100644 --- a/src/main/java/cn/lunadeer/colorfulmap/Events.java +++ b/src/main/java/cn/lunadeer/colorfulmap/Events.java @@ -2,6 +2,7 @@ package cn.lunadeer.colorfulmap; import cn.lunadeer.colorfulmap.generator.ImageRenderer; import cn.lunadeer.colorfulmap.utils.Notification; +import cn.lunadeer.colorfulmap.utils.VaultConnect.VaultConnect; import cn.lunadeer.colorfulmap.utils.XLogger; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.TextComponent; @@ -16,11 +17,15 @@ import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.inventory.ItemStack; +import java.time.LocalTime; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.UUID; import static cn.lunadeer.colorfulmap.Apis.getItemFrameMatrix; +import static cn.lunadeer.colorfulmap.StorageMaps.getImageTilePath; +import static cn.lunadeer.colorfulmap.StorageMaps.writeMeta; public class Events implements Listener { @EventHandler(priority = EventPriority.HIGHEST) @@ -47,13 +52,23 @@ public class Events implements Listener { Player player = event.getPlayer(); List lore = item.getItemMeta().lore(); XLogger.debug("PlayerInteractEntityEvent"); - if (lore == null || lore.size() != 3) { + if (lore == null || lore.size() != 1) { return; } XLogger.debug("putImageMapsOnItemFrame"); - UUID uuid = UUID.fromString(((TextComponent) lore.get(0)).content()); - int count_x = Integer.parseInt(((TextComponent) lore.get(1)).content()); - int count_y = Integer.parseInt(((TextComponent) lore.get(2)).content()); + /* + MapMeta meta = (MapMeta) mapItem.getItemMeta(); + List lore = new ArrayList<>(); + String size_info = "size: " + x_count + "x" + y_count; + lore.add(Component.text(size_info).hoverEvent(Component.text(map_images_uuid.toString()))); + meta.lore(lore); + mapItem.setItemMeta(meta); + */ + TextComponent textComponent = (TextComponent) lore.get(0); + UUID uuid = UUID.fromString(((TextComponent) Objects.requireNonNull(textComponent.hoverEvent()).value()).content()); + String[] size = textComponent.content().split(": ")[1].split("x"); + int count_x = Integer.parseInt(size[0]); + int count_y = Integer.parseInt(size[1]); XLogger.debug("uuid: " + uuid); XLogger.debug("count_x: " + count_x); XLogger.debug("count_y: " + count_y); @@ -67,10 +82,25 @@ public class Events implements Listener { return; } + if (ColorfulMap.config.isEconomyEnable()) { + float cost = ColorfulMap.config.getPrice() * count_x * count_y; + if (!VaultConnect.instance.economyAvailable()) { + Notification.error(player, "无法放置地图画: 无法连接到经济插件"); + return; + } + if (VaultConnect.instance.getBalance(player) < cost) { + Notification.error(player, "无法放置地图画: 余额不足"); + Notification.error(player, "此图片尺寸为 %d x %d 个展示框,单价 %f,总价 %f,你的余额为 %f", + count_x, count_y, ColorfulMap.config.getPrice(), cost, VaultConnect.instance.getBalance(player)); + return; + } + VaultConnect.instance.withdrawPlayer(player, cost); + } + List maps = new ArrayList<>(); for (int y = 0; y < count_y; y++) { for (int x = 0; x < count_x; x++) { - String path = "maps/" + uuid + "/" + x + "_" + y + ".png"; + String path = getImageTilePath(uuid, x, y); ItemStack map = ImageRenderer.getMapItemFromImageTile(player, path); if (map == null) { Notification.error(player, "无法加载地图,原始路径丢失:" + path); @@ -80,6 +110,15 @@ public class Events implements Listener { } } + // 记录操作信息 + List imageMeta = new ArrayList<>(); + imageMeta.add("Player: " + player.getName() + "(" + player.getUniqueId() + ")"); + imageMeta.add("Time: " + LocalTime.now()); + imageMeta.add("Location: " + item_frame.getLocation()); + imageMeta.add("Size: " + count_x + "x" + count_y); + imageMeta.add("ImageUUID: " + uuid); + writeMeta(uuid, imageMeta); + XLogger.debug("maps size: " + maps.size()); XLogger.debug("item_frames size: " + item_frames.size()); for (int i = 0; i < item_frames.size(); i++) { diff --git a/src/main/java/cn/lunadeer/colorfulmap/MapManager.java b/src/main/java/cn/lunadeer/colorfulmap/MapManager.java index b89ab4e..564f81f 100644 --- a/src/main/java/cn/lunadeer/colorfulmap/MapManager.java +++ b/src/main/java/cn/lunadeer/colorfulmap/MapManager.java @@ -16,9 +16,7 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; +import java.util.*; public class MapManager implements Listener { @@ -40,7 +38,7 @@ public class MapManager implements Listener { public void init() { MapManager.instance = this; Bukkit.getPluginManager().registerEvents(this, ColorfulMap.instance); - loadImages(); + reloadImages(); } @@ -86,8 +84,9 @@ public class MapManager implements Listener { /*** * Loads images from data file to HashMap. */ - private void loadImages() { + public void reloadImages() { FileConfiguration config = dataFile.getConfig(); + List recordToDelete = new ArrayList<>(); for (String world : config.getKeys(false)) { for (String id : Objects.requireNonNull(config.getConfigurationSection(world)).getKeys(false)) { String path = config.getString(world + "." + id); @@ -96,7 +95,8 @@ public class MapManager implements Listener { } BufferedImage image = StorageMaps.load(path); if (image == null) { - XLogger.err("无法加载图片: " + path); + XLogger.err("无法加载图片: %s 已移除记录", path); + recordToDelete.add(world + "." + id); continue; } if (!savedImages.containsKey(world)) { @@ -105,6 +105,11 @@ public class MapManager implements Listener { savedImages.get(world).put(Integer.parseInt(id), image); } } + // 删除无效记录 + for (String record : recordToDelete) { + config.set(record, null); + } + dataFile.saveConfig(); } diff --git a/src/main/java/cn/lunadeer/colorfulmap/StorageMaps.java b/src/main/java/cn/lunadeer/colorfulmap/StorageMaps.java index 3c27fd0..02eb49f 100644 --- a/src/main/java/cn/lunadeer/colorfulmap/StorageMaps.java +++ b/src/main/java/cn/lunadeer/colorfulmap/StorageMaps.java @@ -1,6 +1,7 @@ package cn.lunadeer.colorfulmap; import cn.lunadeer.colorfulmap.utils.Notification; +import cn.lunadeer.colorfulmap.utils.XLogger; import org.bukkit.entity.Player; import javax.imageio.ImageIO; @@ -16,26 +17,36 @@ public class StorageMaps { /** * save images to plugins/ColorfulMap/maps/{map_uuid}/x_y.png * - * @param player player - * @param images images + * @param player player + * @param images images * @param x_count x_count * @param y_count y_count */ - public static UUID save(Player player, List images, int x_count, int y_count) { + public static UUID save(Player player, BufferedImage raw, BufferedImage thumb, + List images, int x_count, int y_count) { if (images.size() != x_count * y_count) { return null; } UUID map_uuid = UUID.randomUUID(); + File map_folder = new File(data_folder, "maps/" + map_uuid); + if (!map_folder.exists()) { + if (!map_folder.mkdirs()) { + Notification.error(player, "Failed to save map: failed to create map folder"); + return null; + } + } + File raw_file = new File(map_folder, "raw.png"); + File thumb_file = new File(map_folder, "thumb.png"); + try { + ImageIO.write(raw, "png", raw_file); + ImageIO.write(thumb, "png", thumb_file); + } catch (Exception e) { + Notification.error(player, "Failed to save map: " + e.getMessage()); + return null; + } for (int y = 0; y < y_count; y++) { for (int x = 0; x < x_count; x++) { BufferedImage image = images.get(y * x_count + x); - File map_folder = new File(data_folder, "maps/" + map_uuid); - if (!map_folder.exists()) { - if (!map_folder.mkdirs()) { - Notification.error(player, "Failed to save map: failed to create map folder"); - return null; - } - } File image_file = new File(map_folder, x + "_" + y + ".png"); try { ImageIO.write(image, "png", image_file); @@ -48,13 +59,30 @@ public class StorageMaps { return map_uuid; } + public static String getThumbnailPath(UUID map_uuid) { + return "maps/" + map_uuid + "/thumb.png"; + } + + public static String getImageTilePath(UUID map_uuid, int x, int y) { + return "maps/" + map_uuid + "/" + x + "_" + y + ".png"; + } + + public static void writeMeta(UUID map_uuid, List info) { + File meta_file = new File(data_folder, "maps/" + map_uuid + "/meta.txt"); + try { + java.nio.file.Files.write(meta_file.toPath(), info); + } catch (Exception e) { + XLogger.err("写入地图画操作记录失败:%s", e.getMessage()); + } + } + /** * load images from plugins/ColorfulMap/maps/{map_uuid}/x_y.png * - * @param player player + * @param player player * @param map_uuid map_uuid - * @param x_count x_count - * @param y_count y_count + * @param x_count x_count + * @param y_count y_count * @return images */ public static List load(Player player, UUID map_uuid, int x_count, int y_count) { diff --git a/src/main/java/cn/lunadeer/colorfulmap/commands/Reload.java b/src/main/java/cn/lunadeer/colorfulmap/commands/Reload.java new file mode 100644 index 0000000..e7b7769 --- /dev/null +++ b/src/main/java/cn/lunadeer/colorfulmap/commands/Reload.java @@ -0,0 +1,19 @@ +package cn.lunadeer.colorfulmap.commands; + +import cn.lunadeer.colorfulmap.ColorfulMap; +import cn.lunadeer.colorfulmap.MapManager; +import cn.lunadeer.colorfulmap.utils.Notification; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; + +public class Reload implements CommandExecutor { + @Override + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { + ColorfulMap.config.reload(); + MapManager.instance.reloadImages(); + Notification.info(sender, "重载成功"); + return true; + } +} diff --git a/src/main/java/cn/lunadeer/colorfulmap/commands/ToMap.java b/src/main/java/cn/lunadeer/colorfulmap/commands/ToMap.java index 38d7761..4330f2e 100644 --- a/src/main/java/cn/lunadeer/colorfulmap/commands/ToMap.java +++ b/src/main/java/cn/lunadeer/colorfulmap/commands/ToMap.java @@ -1,9 +1,8 @@ package cn.lunadeer.colorfulmap.commands; -import cn.lunadeer.colorfulmap.ColorfulMap; import cn.lunadeer.colorfulmap.generator.Multi; import cn.lunadeer.colorfulmap.utils.Notification; -import cn.lunadeer.colorfulmap.utils.Time; +import cn.lunadeer.colorfulmap.utils.Scheduler; import cn.lunadeer.colorfulmap.utils.XLogger; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; @@ -46,14 +45,8 @@ public class ToMap implements CommandExecutor { return true; } } -// ItemStack mapImage = Multi.generate(player, url, scale); -// if (mapImage == null){ -// Notification.error(player, "生成地图失败"); -// return true; -// } -// player.getInventory().addItem(mapImage); float finalScale = scale; - Time.runAsync(ColorfulMap.instance, () -> { + Scheduler.runTaskAsync(() -> { ItemStack mapImage = Multi.generate(player, url, finalScale); if (mapImage == null) { Notification.error(player, "生成地图失败"); diff --git a/src/main/java/cn/lunadeer/colorfulmap/generator/Multi.java b/src/main/java/cn/lunadeer/colorfulmap/generator/Multi.java index bebd1c6..fb8b335 100644 --- a/src/main/java/cn/lunadeer/colorfulmap/generator/Multi.java +++ b/src/main/java/cn/lunadeer/colorfulmap/generator/Multi.java @@ -2,7 +2,9 @@ package cn.lunadeer.colorfulmap.generator; import cn.lunadeer.colorfulmap.ColorfulMap; import cn.lunadeer.colorfulmap.StorageMaps; +import cn.lunadeer.colorfulmap.utils.ImageTool; import cn.lunadeer.colorfulmap.utils.Notification; +import cn.lunadeer.colorfulmap.utils.VaultConnect.VaultConnect; import net.kyori.adventure.text.Component; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; @@ -15,25 +17,23 @@ import java.util.ArrayList; import java.util.List; import java.util.UUID; -import static cn.lunadeer.colorfulmap.generator.TextRenderer.applyTextToMap; +import static cn.lunadeer.colorfulmap.StorageMaps.getThumbnailPath; +import static cn.lunadeer.colorfulmap.generator.ImageRenderer.getMapItemFromImageTile; public class Multi { public static ItemStack generate(Player player, String url, Float scale) { try { URL _url = new URL(url); - BufferedImage image = ImageIO.read(_url); + BufferedImage raw_image = ImageIO.read(_url); + BufferedImage resized_image; if (scale != 1.0) { - int width = image.getWidth(); - int height = image.getHeight(); - int new_width = (int) (width * scale); - int new_height = (int) (height * scale); - BufferedImage newImage = new BufferedImage(new_width, new_height, BufferedImage.TYPE_INT_ARGB); - newImage.getGraphics().drawImage(image, 0, 0, new_width, new_height, null); - image = newImage; + resized_image = ImageTool.resize(raw_image, scale); + } else { + resized_image = raw_image; } - int image_width = image.getWidth(); - int image_height = image.getHeight(); + int image_width = resized_image.getWidth(); + int image_height = resized_image.getHeight(); int x_count = (int) Math.ceil(image_width / 128.0); int y_count = (int) Math.ceil(image_height / 128.0); if (x_count > ColorfulMap.config.getMaxFrameX() || y_count > ColorfulMap.config.getMaxFrameY()) { @@ -42,17 +42,15 @@ public class Multi { } int new_width = x_count * 128; int new_height = y_count * 128; - BufferedImage newImage = new BufferedImage(new_width, new_height, BufferedImage.TYPE_INT_ARGB); - newImage.getGraphics().drawImage(image, (new_width - image_width) / 2, (new_height - image_height) / 2, null); - image = newImage; - image_width = image.getWidth(); - image_height = image.getHeight(); + resized_image = ImageTool.center(resized_image, new_width, new_height); + image_width = resized_image.getWidth(); + image_height = resized_image.getHeight(); List split_images = new ArrayList<>(); for (int y = 0; y < y_count; y++) { for (int x = 0; x < x_count; x++) { int width = Math.min(128, image_width - x * 128); int height = Math.min(128, image_height - y * 128); - BufferedImage sub_image = image.getSubimage(x * 128, y * 128, width, height); + BufferedImage sub_image = resized_image.getSubimage(x * 128, y * 128, width, height); split_images.add(sub_image); } } @@ -60,20 +58,21 @@ public class Multi { Notification.error(player, "无法生成地图画: 图片为空"); return null; } - UUID map_images_uuid = StorageMaps.save(player, split_images, x_count, y_count); + + UUID map_images_uuid = StorageMaps.save(player, raw_image, ImageTool.thumb(raw_image), split_images, x_count, y_count); if (map_images_uuid == null) { Notification.error(player, "无法生成地图画: 无法保存图片"); return null; } - List map_info = new ArrayList<>(); - map_info.add("size: " + x_count + "x" + y_count); - ItemStack mapItem = applyTextToMap(player, map_info); - // add lore to map item (uuid, x_count, y_count) + ItemStack mapItem = getMapItemFromImageTile(player, getThumbnailPath(map_images_uuid)); + if (mapItem == null) { + Notification.error(player, "无法生成地图画: 无法生成地图"); + return null; + } MapMeta meta = (MapMeta) mapItem.getItemMeta(); List lore = new ArrayList<>(); - lore.add(Component.text(map_images_uuid.toString())); - lore.add(Component.text(String.valueOf(x_count))); - lore.add(Component.text(String.valueOf(y_count))); + String size_info = "size: " + x_count + "x" + y_count; + lore.add(Component.text(size_info).hoverEvent(Component.text(map_images_uuid.toString()))); meta.lore(lore); mapItem.setItemMeta(meta); return mapItem; diff --git a/src/main/java/cn/lunadeer/colorfulmap/generator/TextRenderer.java b/src/main/java/cn/lunadeer/colorfulmap/generator/TextRenderer.java deleted file mode 100644 index 06edae7..0000000 --- a/src/main/java/cn/lunadeer/colorfulmap/generator/TextRenderer.java +++ /dev/null @@ -1,55 +0,0 @@ -package cn.lunadeer.colorfulmap.generator; - -import cn.lunadeer.colorfulmap.utils.Notification; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.MapMeta; -import org.bukkit.map.MapCanvas; -import org.bukkit.map.MapRenderer; -import org.bukkit.map.MapView; -import org.bukkit.map.MinecraftFont; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -public class TextRenderer extends MapRenderer { - - public TextRenderer(List text) { - this.text = text; - } - - private final List text; - - /** - * Render to the given map. - * - * @param map The MapView being rendered to. - * @param canvas The canvas to use for rendering. - * @param player The player who triggered the rendering. - */ - @Override - public void render(@NotNull MapView map, @NotNull MapCanvas canvas, @NotNull Player player) { - try { - int y = 0; - for (String line : text) { - canvas.drawText(0, y, MinecraftFont.Font, line); - y += 10; - } - } catch (Exception e) { - Notification.error(player, "Failed to render text: " + e.getMessage()); - } - } - - public static ItemStack applyTextToMap(Player player, List text){ - ItemStack mapItem = new ItemStack(Material.FILLED_MAP, 1); - MapMeta meta = (MapMeta) mapItem.getItemMeta(); - MapView mapView = Bukkit.createMap(player.getWorld()); - TextRenderer renderer = new TextRenderer(text); - mapView.addRenderer(renderer); - meta.setMapView(mapView); - mapItem.setItemMeta(meta); - return mapItem; - } -} diff --git a/src/main/java/cn/lunadeer/colorfulmap/utils/Common.java b/src/main/java/cn/lunadeer/colorfulmap/utils/Common.java new file mode 100644 index 0000000..19620bd --- /dev/null +++ b/src/main/java/cn/lunadeer/colorfulmap/utils/Common.java @@ -0,0 +1,14 @@ +package cn.lunadeer.colorfulmap.utils; + +public class Common { + + public static boolean isPaper() { + try { + Class.forName("io.papermc.paper.threadedregions.scheduler.ScheduledTask"); + return true; + } catch (ClassNotFoundException e) { + return false; + } + } + +} diff --git a/src/main/java/cn/lunadeer/colorfulmap/utils/GiteaReleaseCheck.java b/src/main/java/cn/lunadeer/colorfulmap/utils/GiteaReleaseCheck.java index 626224b..174e7f1 100644 --- a/src/main/java/cn/lunadeer/colorfulmap/utils/GiteaReleaseCheck.java +++ b/src/main/java/cn/lunadeer/colorfulmap/utils/GiteaReleaseCheck.java @@ -1,5 +1,11 @@ package cn.lunadeer.colorfulmap.utils; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.event.ClickEvent; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.plugin.java.JavaPlugin; import org.json.simple.JSONArray; import org.json.simple.JSONObject; @@ -12,9 +18,9 @@ import java.io.File; import java.io.InputStreamReader; import java.net.URL; import java.nio.file.Files; -import java.util.concurrent.TimeUnit; +import java.util.Random; -public class GiteaReleaseCheck { +public class GiteaReleaseCheck implements Listener { private static class GiteaRelease { public String tag_name; public String message; @@ -22,19 +28,23 @@ public class GiteaReleaseCheck { public String download_url; } + private static GiteaReleaseCheck instance = null; + public GiteaReleaseCheck(JavaPlugin plugin, String giteaServer, String owner, String repo) { + instance = this; this.gitea_server = giteaServer; this.owner = owner; this.repo = repo; this.plugin = plugin; - this.current_version = plugin.getPluginMeta().getVersion(); + this.current_version = plugin.getDescription().getVersion(); + this.plugin.getServer().getPluginManager().registerEvents(this, plugin); // 异步每12小时检查一次更新 - plugin.getServer().getAsyncScheduler().runAtFixedRate(plugin, (instance) -> { + Scheduler.runTaskRepeatAsync(() -> { getLatestRelease(); if (auto_update) { downloadUpdate(); } - }, 10, 60 * 60 * 12, TimeUnit.SECONDS); + }, (10 + new Random().nextInt(10)) * 20, (60 * 60 * 12 + new Random().nextInt(60)) * 20); } public void enableAutoUpdate() { @@ -169,11 +179,24 @@ public class GiteaReleaseCheck { } } - private String gitea_server; - private String owner; - private String repo; - private JavaPlugin plugin; - private String current_version; + @EventHandler + private void onPlayerJoin(PlayerJoinEvent event) { + if (!event.getPlayer().isOp()) { + return; + } + Player player = event.getPlayer(); + if (latest_release != null && isNewVersion(current_version, latest_release.tag_name)) { + Notification.info(player, "发现新版本:" + latest_release.tag_name + " 详细内容请查看控制台或点击下方链接"); + Component download = Component.text(latest_release.html_url).clickEvent(ClickEvent.openUrl(latest_release.html_url)).hoverEvent(Component.text("点击打开")); + Notification.info(player,download); + } + } + + private final String gitea_server; + private final String owner; + private final String repo; + private final JavaPlugin plugin; + private final String current_version; private GiteaRelease latest_release = null; private boolean auto_update = false; diff --git a/src/main/java/cn/lunadeer/colorfulmap/utils/ImageTool.java b/src/main/java/cn/lunadeer/colorfulmap/utils/ImageTool.java new file mode 100644 index 0000000..815f20c --- /dev/null +++ b/src/main/java/cn/lunadeer/colorfulmap/utils/ImageTool.java @@ -0,0 +1,33 @@ +package cn.lunadeer.colorfulmap.utils; + +import java.awt.image.BufferedImage; + +public class ImageTool { + + public static BufferedImage resize(BufferedImage image, float scale) { + int new_width = (int) (image.getWidth() * scale); + int new_height = (int) (image.getHeight() * scale); + BufferedImage newImage = new BufferedImage(new_width, new_height, BufferedImage.TYPE_INT_ARGB); + newImage.getGraphics().drawImage(image, 0, 0, new_width, new_height, null); + return newImage; + } + + public static BufferedImage center(BufferedImage image, int width, int height) { + int image_width = image.getWidth(); + int image_height = image.getHeight(); + BufferedImage newImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + newImage.getGraphics().drawImage(image, (width - image_width) / 2, (height - image_height) / 2, null); + return newImage; + } + + public static BufferedImage thumb(BufferedImage img) { + double scale; + if (img.getWidth() > img.getHeight()) { + scale = 128.0 / img.getWidth(); + } else { + scale = 128.0 / img.getHeight(); + } + return center(resize(img, (float) scale), 128, 128); + } + +} diff --git a/src/main/java/cn/lunadeer/colorfulmap/utils/Notification.java b/src/main/java/cn/lunadeer/colorfulmap/utils/Notification.java index d2eec1f..279a1ba 100644 --- a/src/main/java/cn/lunadeer/colorfulmap/utils/Notification.java +++ b/src/main/java/cn/lunadeer/colorfulmap/utils/Notification.java @@ -5,59 +5,125 @@ import net.kyori.adventure.text.format.Style; import net.kyori.adventure.text.format.TextColor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; public class Notification { + public static Notification instance; + + public final SendMessageAbstract sender; + + public Notification(JavaPlugin plugin) { + instance = this; + this.plugin = plugin; + this.prefix = "[" + plugin.getName() + "]"; + this.sender = new SendMessageAbstract(plugin); + } + private static final Style i_style = Style.style(TextColor.color(139, 255, 123)); private static final Style w_style = Style.style(TextColor.color(255, 185, 69)); private static final Style e_style = Style.style(TextColor.color(255, 96, 72)); + private static final Style d_style = Style.style(TextColor.color(0, 255, 255)); - private static final String prefix = "[ColorfulMap] "; + private String prefix; + private JavaPlugin plugin; + + public void setPrefix(String prefix) { + this.prefix = prefix; + } public static void info(Player player, String msg) { - player.sendMessage(Component.text(prefix + msg, i_style)); + instance.sender.sendMessage(player, Component.text(instance.prefix + " " + msg, i_style)); + } + + public static void info(Player player, String msg, Object... args) { + instance.sender.sendMessage(player, Component.text(instance.prefix + " " + String.format(msg, args), i_style)); } public static void warn(Player player, String msg) { - player.sendMessage(Component.text(prefix + msg, w_style)); + instance.sender.sendMessage(player, Component.text(instance.prefix + " " + msg, w_style)); + } + + public static void warn(Player player, String msg, Object... args) { + instance.sender.sendMessage(player, Component.text(instance.prefix + " " + String.format(msg, args), w_style)); } public static void error(Player player, String msg) { - player.sendMessage(Component.text(prefix + msg, e_style)); + instance.sender.sendMessage(player, Component.text(instance.prefix + " " + msg, e_style)); + } + + public static void error(Player player, String msg, Object... args) { + instance.sender.sendMessage(player, Component.text(instance.prefix + " " + String.format(msg, args), e_style)); } public static void info(CommandSender sender, String msg) { - sender.sendMessage(Component.text(prefix + msg, i_style)); + instance.sender.sendMessage(sender, Component.text(instance.prefix + " " + msg, i_style)); + } + + public static void info(CommandSender sender, String msg, Object... args) { + instance.sender.sendMessage(sender, Component.text(instance.prefix + " " + String.format(msg, args), i_style)); } public static void warn(CommandSender sender, String msg) { - sender.sendMessage(Component.text(prefix + msg, w_style)); + instance.sender.sendMessage(sender, Component.text(instance.prefix + " " + msg, w_style)); + } + + public static void warn(CommandSender sender, String msg, Object... args) { + instance.sender.sendMessage(sender, Component.text(instance.prefix + " " + String.format(msg, args), w_style)); } public static void error(CommandSender sender, String msg) { - sender.sendMessage(Component.text(prefix + msg, e_style)); + instance.sender.sendMessage(sender, Component.text(instance.prefix + " " + msg, e_style)); + } + + public static void error(CommandSender sender, String msg, Object... args) { + instance.sender.sendMessage(sender, Component.text(instance.prefix + " " + String.format(msg, args), e_style)); } public static void info(Player player, Component msg) { - player.sendMessage(Component.text(prefix, i_style).append(msg)); + instance.sender.sendMessage(player, Component.text(instance.prefix, i_style).append(Component.text(" ")).append(msg)); } public static void warn(Player player, Component msg) { - player.sendMessage(Component.text(prefix, w_style).append(msg)); + instance.sender.sendMessage(player, Component.text(instance.prefix, w_style).append(Component.text(" ")).append(msg)); } public static void error(Player player, Component msg) { - player.sendMessage(Component.text(prefix, e_style).append(msg)); + instance.sender.sendMessage(player, Component.text(instance.prefix, e_style).append(Component.text(" ")).append(msg)); } public static void info(CommandSender player, Component msg) { - player.sendMessage(Component.text(prefix, i_style).append(msg)); + instance.sender.sendMessage(player, Component.text(instance.prefix, i_style).append(Component.text(" ")).append(msg)); } public static void warn(CommandSender player, Component msg) { - player.sendMessage(Component.text(prefix, w_style).append(msg)); + instance.sender.sendMessage(player, Component.text(instance.prefix, w_style).append(Component.text(" ")).append(msg)); } public static void error(CommandSender player, Component msg) { - player.sendMessage(Component.text(prefix, e_style).append(msg)); + instance.sender.sendMessage(player, Component.text(instance.prefix, e_style).append(Component.text(" ")).append(msg)); + } + + public static void all(String msg) { + instance.sender.broadcast(Component.text(instance.prefix + " " + msg, i_style)); + } + + public static void all(Component msg) { + instance.sender.broadcast(Component.text(instance.prefix, i_style).append(Component.text(" ")).append(msg)); + } + + public static void all(String msg, Object... args) { + instance.sender.broadcast(Component.text(instance.prefix + " " + String.format(msg, args), i_style)); + } + + public static void actionBar(Player player, String msg) { + instance.sender.sendActionBar(player, Component.text(msg)); + } + + public static void actionBar(Player player, String msg, Object... args) { + instance.sender.sendActionBar(player, Component.text(String.format(msg, args))); + } + + public static void actionBar(Player player, Component msg) { + instance.sender.sendActionBar(player, msg); } } diff --git a/src/main/java/cn/lunadeer/colorfulmap/utils/Scheduler.java b/src/main/java/cn/lunadeer/colorfulmap/utils/Scheduler.java new file mode 100644 index 0000000..19cd329 --- /dev/null +++ b/src/main/java/cn/lunadeer/colorfulmap/utils/Scheduler.java @@ -0,0 +1,126 @@ +package cn.lunadeer.colorfulmap.utils; + +import org.bukkit.plugin.java.JavaPlugin; + +import java.util.concurrent.TimeUnit; + +import static cn.lunadeer.colorfulmap.utils.Common.isPaper; + +public class Scheduler { + public static Scheduler instance; + private final JavaPlugin plugin; + private boolean isPaper = false; + + public Scheduler(JavaPlugin plugin) { + instance = this; + this.plugin = plugin; + this.isPaper = isPaper(); + } + + public static void cancelAll() { + if (instance.isPaper) { + instance.plugin.getServer().getGlobalRegionScheduler().cancelTasks(instance.plugin); + instance.plugin.getServer().getGlobalRegionScheduler().cancelTasks(instance.plugin); + } else { + instance.plugin.getServer().getScheduler().cancelTasks(instance.plugin); + } + } + + /** + * Run a task later + * + * @param task The task to run + * @param delay The delay in ticks (20 ticks = 1 second) + * @return The scheduled task + */ + public static void runTaskLater(Runnable task, long delay) { + if (delay <= 0) { + runTask(task); + return; + } + if (instance.isPaper) { + instance.plugin.getServer().getGlobalRegionScheduler().runDelayed(instance.plugin, (plugin) -> task.run(), delay); + } else { + instance.plugin.getServer().getScheduler().runTaskLater(instance.plugin, task, delay); + } + } + + /** + * Run a task + * + * @param task The task to run + * @return The scheduled task + */ + public static void runTask(Runnable task) { + if (instance.isPaper) { + instance.plugin.getServer().getGlobalRegionScheduler().run(instance.plugin, (plugin) -> task.run()); + } else { + instance.plugin.getServer().getScheduler().runTask(instance.plugin, task); + } + } + + /** + * Run a task repeatedly + * + * @param task The task to run + * @param delay The delay in ticks (20 ticks = 1 second) + * @param period The period in ticks (20 ticks = 1 second) + * @return The scheduled task + */ + public static void runTaskRepeat(Runnable task, long delay, long period) { + if (instance.isPaper) { + instance.plugin.getServer().getGlobalRegionScheduler().runAtFixedRate(instance.plugin, (plugin) -> task.run(), delay, period); + } else { + instance.plugin.getServer().getScheduler().runTaskTimer(instance.plugin, task, delay, period); + } + } + + /** + * Run a task later asynchronously + * + * @param task The task to run + * @param delay The delay in milliseconds + * @return The scheduled task + */ + public static void runTaskLaterAsync(Runnable task, long delay) { + if (delay <= 0) { + runTaskAsync(task); + return; + } + if (instance.isPaper) { + instance.plugin.getServer().getAsyncScheduler().runDelayed(instance.plugin, (plugin) -> task.run(), delay * 50, TimeUnit.MILLISECONDS); + } else { + instance.plugin.getServer().getScheduler().runTaskLaterAsynchronously(instance.plugin, task, delay); + } + } + + /** + * Run a task asynchronously + * + * @param task The task to run + * @return The scheduled task + */ + public static void runTaskAsync(Runnable task) { + if (instance.isPaper) { + instance.plugin.getServer().getAsyncScheduler().runNow(instance.plugin, (plugin) -> task.run()); + } else { + instance.plugin.getServer().getScheduler().runTaskAsynchronously(instance.plugin, task); + } + } + + /** + * Run a task repeatedly asynchronously + * + * @param task The task to run + * @param delay The delay in milliseconds + * @param period The period in milliseconds + * @return The scheduled task + */ + public static void runTaskRepeatAsync(Runnable task, long delay, long period) { + if (instance.isPaper) { + instance.plugin.getServer().getAsyncScheduler().runAtFixedRate(instance.plugin, (plugin) -> task.run(), delay * 50, period * 50, TimeUnit.MILLISECONDS); + } else { + instance.plugin.getServer().getScheduler().runTaskTimerAsynchronously(instance.plugin, task, delay, period); + } + } +} diff --git a/src/main/java/cn/lunadeer/colorfulmap/utils/SendMessageAbstract.java b/src/main/java/cn/lunadeer/colorfulmap/utils/SendMessageAbstract.java new file mode 100644 index 0000000..f346f11 --- /dev/null +++ b/src/main/java/cn/lunadeer/colorfulmap/utils/SendMessageAbstract.java @@ -0,0 +1,52 @@ +package cn.lunadeer.colorfulmap.utils; + +import net.kyori.adventure.platform.bukkit.BukkitAudiences; +import net.kyori.adventure.text.Component; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; + +public class SendMessageAbstract { + + private BukkitAudiences adventure = null; + private JavaPlugin plugin; + + public SendMessageAbstract(JavaPlugin plugin) { + this.plugin = plugin; + if (!Common.isPaper()) { + this.adventure = BukkitAudiences.create(plugin); + } + } + + public void sendMessage(Player player, Component msg) { + if (this.adventure == null) { + player.sendMessage(msg); + } else { + this.adventure.player(player).sendMessage(msg); + } + } + + public void sendMessage(CommandSender sender, Component msg) { + if (this.adventure == null) { + sender.sendMessage(msg); + } else { + this.adventure.sender(sender).sendMessage(msg); + } + } + + public void broadcast(Component msg) { + if (this.adventure == null) { + plugin.getServer().broadcast(msg); + } else { + adventure.all().sendMessage(msg); + } + } + + public void sendActionBar(Player player, Component msg) { + if (this.adventure == null) { + player.sendActionBar(msg); + } else { + this.adventure.player(player).sendActionBar(msg); + } + } +} diff --git a/src/main/java/cn/lunadeer/colorfulmap/utils/Time.java b/src/main/java/cn/lunadeer/colorfulmap/utils/Time.java deleted file mode 100644 index 6cb7a0d..0000000 --- a/src/main/java/cn/lunadeer/colorfulmap/utils/Time.java +++ /dev/null @@ -1,67 +0,0 @@ -package cn.lunadeer.colorfulmap.utils; - -import org.bukkit.Bukkit; -import org.bukkit.plugin.Plugin; - -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.concurrent.TimeUnit; - -public class Time { - - public static String nowStr() { - // yyyy-MM-dd HH:mm:ss - return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); - } - - /** - * 尝试获取folia的调度器 - * - * @return 是否成功 - */ - private static boolean tryFolia() { - try { - Bukkit.getAsyncScheduler(); - return true; - } catch (Throwable ignored) { - } - return false; - } - - private static Boolean IS_FOLIA = null; - - /** - * 判断是否是folia核心 - * - * @return 是否是folia核心 - */ - public static Boolean isFolia() { - if (IS_FOLIA == null) IS_FOLIA = tryFolia(); - return IS_FOLIA; - } - - /** - * 定时异步任务 - * - * @param plugin 插件 - * @param runnable 任务 - * @param ticks 间隔 - */ - public static void runAtFixedRateAsync(Plugin plugin, Runnable runnable, int ticks) { - if (isFolia()) - Bukkit.getAsyncScheduler().runAtFixedRate(plugin, (task) -> runnable.run(), ticks / 20, ticks / 20, TimeUnit.SECONDS); - else Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, runnable, ticks, ticks); - } - - public static void runLater(Plugin plugin, Runnable runnable, int ticks) { - if (isFolia()) - Bukkit.getAsyncScheduler().runDelayed(plugin, (task) -> runnable.run(), ticks / 20, TimeUnit.SECONDS); - else Bukkit.getScheduler().runTaskLater(plugin, runnable, ticks); - } - - public static void runAsync(Plugin plugin, Runnable runnable) { - if (isFolia()) - Bukkit.getAsyncScheduler().runNow(plugin, (task) -> runnable.run()); - else Bukkit.getScheduler().runTaskAsynchronously(plugin, runnable); - } -} diff --git a/src/main/java/cn/lunadeer/colorfulmap/utils/VaultConnect/Vault.java b/src/main/java/cn/lunadeer/colorfulmap/utils/VaultConnect/Vault.java new file mode 100644 index 0000000..00828e6 --- /dev/null +++ b/src/main/java/cn/lunadeer/colorfulmap/utils/VaultConnect/Vault.java @@ -0,0 +1,48 @@ +package cn.lunadeer.colorfulmap.utils.VaultConnect; + +import cn.lunadeer.colorfulmap.utils.XLogger; +import net.milkbowl.vault.economy.Economy; +import org.bukkit.entity.Player; +import org.bukkit.plugin.RegisteredServiceProvider; +import org.bukkit.plugin.java.JavaPlugin; + +public class Vault implements VaultInterface { + + private Economy econ = null; + + @Override + public boolean init(JavaPlugin plugin) { + RegisteredServiceProvider rsp = plugin.getServer().getServicesManager().getRegistration(Economy.class); + if (rsp != null) { + econ = rsp.getProvider(); + return true; + } + XLogger.err("Vault 不可用"); + return false; + } + + @Override + public String currencyNamePlural() { + return econ.currencyNamePlural(); + } + + @Override + public String currencyNameSingular() { + return econ.currencyNameSingular(); + } + + @Override + public void withdrawPlayer(Player player, double amount) { + econ.withdrawPlayer(player, amount); + } + + @Override + public void depositPlayer(Player player, double amount) { + econ.depositPlayer(player, amount); + } + + @Override + public double getBalance(Player player) { + return econ.getBalance(player); + } +} diff --git a/src/main/java/cn/lunadeer/colorfulmap/utils/VaultConnect/Vault2.java b/src/main/java/cn/lunadeer/colorfulmap/utils/VaultConnect/Vault2.java new file mode 100644 index 0000000..d9c4afd --- /dev/null +++ b/src/main/java/cn/lunadeer/colorfulmap/utils/VaultConnect/Vault2.java @@ -0,0 +1,50 @@ +package cn.lunadeer.colorfulmap.utils.VaultConnect; + +import cn.lunadeer.colorfulmap.utils.XLogger; +import net.milkbowl.vault2.economy.Economy; +import org.bukkit.entity.Player; +import org.bukkit.plugin.RegisteredServiceProvider; +import org.bukkit.plugin.java.JavaPlugin; + +import java.math.BigDecimal; + +public class Vault2 implements VaultInterface { + + private Economy econ = null; + + @Override + public boolean init(JavaPlugin plugin) { + RegisteredServiceProvider rsp = plugin.getServer().getServicesManager().getRegistration(Economy.class); + if (rsp != null) { + econ = rsp.getProvider(); + return true; + } + XLogger.err("VaultUnlocked 不可用"); + return false; + } + + @Override + public String currencyNamePlural() { + return econ.defaultCurrencyNamePlural(); + } + + @Override + public String currencyNameSingular() { + return econ.defaultCurrencyNameSingular(); + } + + @Override + public void withdrawPlayer(Player player, double amount) { + econ.withdraw("MPU", player.getUniqueId(), BigDecimal.valueOf(amount)); + } + + @Override + public void depositPlayer(Player player, double amount) { + econ.deposit("MPU", player.getUniqueId(), BigDecimal.valueOf(amount)); + } + + @Override + public double getBalance(Player player) { + return econ.getBalance("MPU", player.getUniqueId()).doubleValue(); + } +} diff --git a/src/main/java/cn/lunadeer/colorfulmap/utils/VaultConnect/VaultConnect.java b/src/main/java/cn/lunadeer/colorfulmap/utils/VaultConnect/VaultConnect.java new file mode 100644 index 0000000..38cbbe8 --- /dev/null +++ b/src/main/java/cn/lunadeer/colorfulmap/utils/VaultConnect/VaultConnect.java @@ -0,0 +1,94 @@ +package cn.lunadeer.colorfulmap.utils.VaultConnect; + +import cn.lunadeer.colorfulmap.utils.XLogger; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.server.ServiceRegisterEvent; +import org.bukkit.plugin.java.JavaPlugin; + +public class VaultConnect implements Listener { + + public static VaultConnect instance; + private VaultInterface vaultInstance = null; + private JavaPlugin plugin; + + public VaultConnect(JavaPlugin plugin) { + this.plugin = plugin; + instance = this; + plugin.getServer().getPluginManager().registerEvents(this, plugin); + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onEnable(ServiceRegisterEvent event) { + } + + public boolean economyAvailable() { + if (vaultInstance == null) { + if (foundClass("net.milkbowl.vault.economy.Economy")) { + vaultInstance = new Vault(); + } else if (foundClass("net.milkbowl.vault2.economy.Economy")) { + vaultInstance = new Vault2(); + } else { + XLogger.err("没有可用的经济插件"); + return false; + } + if (!vaultInstance.init(plugin)) { + vaultInstance = null; + XLogger.err("没有可用的经济插件"); + return false; + } + } + return true; + } + + public String currencyNamePlural() { + if (economyAvailable()) { + return vaultInstance.currencyNamePlural(); + } + XLogger.warn("没有可用的经济插件"); + return ""; + } + + public String currencyNameSingular() { + if (economyAvailable()) { + return vaultInstance.currencyNameSingular(); + } + XLogger.warn("没有可用的经济插件"); + return ""; + } + + public void withdrawPlayer(Player player, double amount) { + if (economyAvailable()) { + vaultInstance.withdrawPlayer(player, amount); + return; + } + XLogger.warn("没有可用的经济插件"); + } + + public void depositPlayer(Player player, double amount) { + if (economyAvailable()) { + vaultInstance.depositPlayer(player, amount); + return; + } + XLogger.warn("没有可用的经济插件"); + } + + public double getBalance(Player player) { + if (economyAvailable()) { + return vaultInstance.getBalance(player); + } + XLogger.warn("没有可用的经济插件"); + return 0; + } + + private static boolean foundClass(String className) { + try { + Class.forName(className); + return true; + } catch (ClassNotFoundException e) { + return false; + } + } +} diff --git a/src/main/java/cn/lunadeer/colorfulmap/utils/VaultConnect/VaultInterface.java b/src/main/java/cn/lunadeer/colorfulmap/utils/VaultConnect/VaultInterface.java new file mode 100644 index 0000000..349042c --- /dev/null +++ b/src/main/java/cn/lunadeer/colorfulmap/utils/VaultConnect/VaultInterface.java @@ -0,0 +1,21 @@ +package cn.lunadeer.colorfulmap.utils.VaultConnect; + +import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; + +public interface VaultInterface { + + public boolean init(JavaPlugin plugin); + + public String currencyNamePlural(); + + + public String currencyNameSingular(); + + public void withdrawPlayer(Player player, double amount); + + public void depositPlayer(Player player, double amount); + + public double getBalance(Player player); + +} diff --git a/src/main/java/cn/lunadeer/colorfulmap/utils/XLogger.java b/src/main/java/cn/lunadeer/colorfulmap/utils/XLogger.java index 055a0dc..666c60a 100644 --- a/src/main/java/cn/lunadeer/colorfulmap/utils/XLogger.java +++ b/src/main/java/cn/lunadeer/colorfulmap/utils/XLogger.java @@ -1,56 +1,62 @@ package cn.lunadeer.colorfulmap.utils; -import cn.lunadeer.colorfulmap.ColorfulMap; -import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; +import org.jetbrains.annotations.Nullable; import java.util.logging.Logger; public class XLogger { - private static final ColorfulMap _plugin = ColorfulMap.instance; - private static final Logger _logger = _plugin.getLogger(); + public static XLogger instance; - private static final String prefix = "[ColorfulMap] "; - - public static void info(Player player, String message) { - Notification.info(player, prefix + "I | " + message); - if (ColorfulMap.config.isDebug()) - debug("来自玩家[ " + player.getName() + " ] 的信息 | " + message); + public XLogger() { + instance = this; + this._logger = Logger.getLogger("Lunadeer"); } + public XLogger(@Nullable JavaPlugin plugin) { + instance = this; + this._logger = plugin != null ? plugin.getLogger() : Logger.getLogger("Lunadeer"); + } + + public static XLogger setDebug(boolean debug) { + instance._debug = debug; + return instance; + } + + private final Logger _logger; + private boolean _debug = false; + public static void info(String message) { - _logger.info(" I | " + message); + instance._logger.info(" I | " + message); } - public static void warn(Player player, String message) { - Notification.warn(player, prefix + "W | " + message); - if (ColorfulMap.config.isDebug()) - debug("来自玩家[ " + player.getName() + " ] 的警告 | " + message); + public static void info(String message, Object... args) { + instance._logger.info(" I | " + String.format(message, args)); } public static void warn(String message) { - _logger.info(" W | " + message); + instance._logger.warning(" W | " + message); } - public static void err(Player player, String message) { - Notification.error(player, prefix + "E | " + message); - if (ColorfulMap.config.isDebug()) - debug("来自玩家[ " + player.getName() + " ] 的报错 | " + message); + public static void warn(String message, Object... args) { + instance._logger.warning(" W | " + String.format(message, args)); } public static void err(String message) { - _logger.info(" E | " + message); + instance._logger.severe(" E | " + message); } - public static void debug(Player player, String message) { - if (!ColorfulMap.config.isDebug()) return; - if (player.isOp()) - Notification.info(player, prefix + "D | " + message); - else - debug("来自玩家[ " + player.getName() + " ] 的调试 | " + message); + public static void err(String message, Object... args) { + instance._logger.severe(" E | " + String.format(message, args)); } public static void debug(String message) { - if (!ColorfulMap.config.isDebug()) return; - _logger.info(" D | " + message); + if (!instance._debug) return; + instance._logger.info(" D | " + message); + } + + public static void debug(String message, Object... args) { + if (!instance._debug) return; + instance._logger.info(" D | " + String.format(message, args)); } } diff --git a/src/main/java/cn/lunadeer/colorfulmap/Metrics.java b/src/main/java/cn/lunadeer/colorfulmap/utils/bStatsMetrics.java similarity index 99% rename from src/main/java/cn/lunadeer/colorfulmap/Metrics.java rename to src/main/java/cn/lunadeer/colorfulmap/utils/bStatsMetrics.java index 1464ad7..8c96ec5 100644 --- a/src/main/java/cn/lunadeer/colorfulmap/Metrics.java +++ b/src/main/java/cn/lunadeer/colorfulmap/utils/bStatsMetrics.java @@ -1,4 +1,4 @@ -package cn.lunadeer.colorfulmap; +package cn.lunadeer.colorfulmap.utils; import org.bukkit.Bukkit; import org.bukkit.configuration.file.YamlConfiguration; @@ -23,7 +23,7 @@ import java.util.logging.Level; import java.util.stream.Collectors; import java.util.zip.GZIPOutputStream; -public class Metrics { +public class bStatsMetrics { private final Plugin plugin; private final MetricsBase metricsBase; @@ -35,7 +35,7 @@ public class Metrics { * @param serviceId The id of the service. It can be found at What is my plugin id? */ - public Metrics(JavaPlugin plugin, int serviceId) { + public bStatsMetrics(JavaPlugin plugin, int serviceId) { this.plugin = plugin; // Get the config file File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats"); diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 121a02c..3c62180 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -2,6 +2,10 @@ MaxFrameX: 32 MaxFrameY: 18 +Economy: + Enable: false + CostPerMap: 100.0 + CheckUpdate: true Debug: false \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 18a35fd..304b3c7 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -9,7 +9,14 @@ commands: description: 将图片转换为地图画 usage: /tomap <图片url> [缩放比例(默认1)] permission: colorfulmap.tomap + reloadColorfulMap: + description: 重载ColorfulMap配置 + usage: /reloadColorfulMap + permission: colorfulmap.reload permissions: colorfulmap.tomap: description: 允许使用/tomap命令 default: true + colorfulmap.reload: + description: 允许使用/reloadColorfulMap命令 + default: op