diff --git a/src/main/java/com/blank038/servermarket/dto/impl/MysqlStorageHandlerImpl.java b/src/main/java/com/blank038/servermarket/dto/impl/MysqlStorageHandlerImpl.java index a37855f..4cc8571 100644 --- a/src/main/java/com/blank038/servermarket/dto/impl/MysqlStorageHandlerImpl.java +++ b/src/main/java/com/blank038/servermarket/dto/impl/MysqlStorageHandlerImpl.java @@ -12,6 +12,7 @@ import com.blank038.servermarket.internal.cache.sale.SaleCache; import com.blank038.servermarket.internal.enums.PayType; import com.blank038.servermarket.internal.i18n.I18n; +import lombok.Getter; import org.bukkit.Bukkit; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.FileConfiguration; @@ -33,6 +34,7 @@ * @author Blank038 */ public class MysqlStorageHandlerImpl extends AbstractStorageHandler { + @Getter private static MySqlStorageHandler storageHandler; private final String playersTable = "servermarket_players", @@ -46,7 +48,7 @@ public void initialize() { "CREATE TABLE IF NOT EXISTS `servermarket_players`( `player_uuid` VARCHAR(36) NOT NULL, `data` TEXT, `locked` TINYINT, PRIMARY KEY (`player_uuid`)) ENGINE = InnoDB DEFAULT CHARSET = utf8;", "CREATE TABLE IF NOT EXISTS `servermarket_sales` ( `sale_uuid` VARCHAR(36) NOT NULL, `market` VARCHAR(20) NOT NULL, `owner_name` VARCHAR(20) NOT NULL, `owner_uuid` VARCHAR(36) NOT NULL, `pay_type` VARCHAR(20) NOT NULL, `eco_type` VARCHAR(50), `price` int, `data` TEXT, `post_time` TIMESTAMP NOT NULL, PRIMARY KEY (`sale_uuid`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;", "CREATE TABLE IF NOT EXISTS `servermarket_logs` ( `id` INT AUTO_INCREMENT, `trigger_time` TIMESTAMP, `trigger_uuid` VARCHAR(36) NOT NULL, `market` VARCHAR(50), `log_type` VARCHAR(10) NOT NULL, `data` TEXT, PRIMARY KEY (`id`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;", - "CREATE TABLE IF NOT EXISTS `servermarket_offline_transactions` ( `id` INT AUTO_INCREMENT, `owner_uuid` VARCHAR(36) NOT NULL, `market` VARCHAR(50) NOT NULL, `amount` TINYINT, `pay_type` VARCHAR(20) NOT NULL, `eco_type` VARCHAR(50), PRIMARY KEY (`id`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;" + "CREATE TABLE IF NOT EXISTS `servermarket_offline_transactions` ( `id` INT AUTO_INCREMENT, `owner_uuid` VARCHAR(36) NOT NULL, `market` VARCHAR(50) NOT NULL, `amount` INT, `pay_type` VARCHAR(20) NOT NULL, `eco_type` VARCHAR(50), PRIMARY KEY (`id`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;" }; storageHandler = new MySqlStorageHandler( diff --git a/src/main/java/com/blank038/servermarket/internal/command/MainCommand.java b/src/main/java/com/blank038/servermarket/internal/command/MainCommand.java index 878fb78..08b629e 100644 --- a/src/main/java/com/blank038/servermarket/internal/command/MainCommand.java +++ b/src/main/java/com/blank038/servermarket/internal/command/MainCommand.java @@ -1,6 +1,7 @@ package com.blank038.servermarket.internal.command; import com.blank038.servermarket.api.ServerMarketApi; +import com.blank038.servermarket.internal.handler.PatchHandler; import com.blank038.servermarket.internal.plugin.ServerMarket; import com.blank038.servermarket.internal.data.DataContainer; import com.blank038.servermarket.api.handler.filter.FilterHandler; @@ -14,18 +15,26 @@ import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; import org.bukkit.entity.Player; +import java.util.ArrayList; +import java.util.List; import java.util.Map; /** * @author Blank038 */ -public class MainCommand implements CommandExecutor { +public class MainCommand implements CommandExecutor, TabCompleter { private final ServerMarket instance; public MainCommand(ServerMarket serverMarket) { - instance = serverMarket; + this.instance = serverMarket; + } + + public void register() { + this.instance.getCommand("servermarket").setExecutor(this); + this.instance.getCommand("servermarket").setTabCompleter(this); } /** @@ -64,6 +73,9 @@ public boolean onCommand(CommandSender sender, Command command, String label, St sender.sendMessage(I18n.getStrAndHeader("reload")); } break; + case "patch": + this.usePatch(sender, args); + break; default: this.sendHelp(sender, label); break; @@ -134,4 +146,28 @@ private void sendHelp(CommandSender sender, String label) { sender.sendMessage(TextUtil.formatHexColor(text).replace("%c", label)); } } + + /** + * To fix legacy issues from previous versions. + */ + private void usePatch(CommandSender sender, String[] args) { + if (!sender.hasPermission("servermarket.patch")) { + sender.sendMessage(I18n.getStrAndHeader("no-permission")); + return; + } + if (args.length == 1) { + sender.sendMessage(I18n.getStrAndHeader("wrong-patch-id")); + return; + } + boolean result = PatchHandler.executePatch(args[1]); + sender.sendMessage(I18n.getStrAndHeader("patch-result." + result)); + } + + @Override + public List onTabComplete(CommandSender commandSender, Command command, String s, String[] strings) { + if (strings.length == 2) { + return new ArrayList<>(PatchHandler.getPatchIds()); + } + return null; + } } \ No newline at end of file diff --git a/src/main/java/com/blank038/servermarket/internal/handler/PatchHandler.java b/src/main/java/com/blank038/servermarket/internal/handler/PatchHandler.java new file mode 100644 index 0000000..fe44752 --- /dev/null +++ b/src/main/java/com/blank038/servermarket/internal/handler/PatchHandler.java @@ -0,0 +1,59 @@ +package com.blank038.servermarket.internal.handler; + +import com.blank038.servermarket.dto.impl.MysqlStorageHandlerImpl; +import com.blank038.servermarket.internal.plugin.ServerMarket; +import lombok.Getter; + +import java.sql.SQLException; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.BooleanSupplier; +import java.util.logging.Level; + +/** + * @author Blank038 + */ +public class PatchHandler { + private static final Map PATCH_MAP = new HashMap<>(); + + static { + // Patch id example: "version-level-number" + // Patch level: F=FATAL, U=URGENT, S=SLIGHT, O=OPTIONAL + PATCH_MAP.put("251-U-1", () -> { + AtomicBoolean atomicBoolean = new AtomicBoolean(true); + if (ServerMarket.getStorageHandler() instanceof MysqlStorageHandlerImpl) { + MysqlStorageHandlerImpl.getStorageHandler().connect((statement) -> { + try { + statement.executeUpdate(); + } catch (SQLException e) { + atomicBoolean.set(false); + ServerMarket.getInstance().getLogger().log(Level.WARNING, e, () -> "Failed to update column data type."); + } + }, "ALTER TABLE `servermarket_offline_transactions` CHANGE `amount` `amount` INT;"); + } + return atomicBoolean.get(); + }); + } + + public static boolean executePatch(String id) { + if (PATCH_MAP.containsKey(id)) { + try { + return PATCH_MAP.get(id).getAsBoolean(); + } catch (Exception e) { + ServerMarket.getInstance().getLogger().log(Level.SEVERE, e, () -> "Patch failed to apply: " + id); + return false; + } + } + return false; + } + + public static void registerPatch(String id, BooleanSupplier supplier) { + PATCH_MAP.putIfAbsent(id, supplier); + } + + public static Set getPatchIds() { + return PATCH_MAP.keySet(); + } +} diff --git a/src/main/java/com/blank038/servermarket/internal/plugin/ServerMarket.java b/src/main/java/com/blank038/servermarket/internal/plugin/ServerMarket.java index d9fb4ba..cf75455 100644 --- a/src/main/java/com/blank038/servermarket/internal/plugin/ServerMarket.java +++ b/src/main/java/com/blank038/servermarket/internal/plugin/ServerMarket.java @@ -40,7 +40,7 @@ public void onEnable() { this.getConsoleLogger().setPrefix("&f[&eServerMarket&f] &8"); this.loadConfig(true); // register command executor - super.getCommand("servermarket").setExecutor(new MainCommand(this)); + new MainCommand(this).register(); // register listeners new CoreListener().register(); new PlayerCommonListener().register(); diff --git a/src/main/resources/language/en_US.yml b/src/main/resources/language/en_US.yml index d535984..8a7c2d9 100644 --- a/src/main/resources/language/en_US.yml +++ b/src/main/resources/language/en_US.yml @@ -3,17 +3,18 @@ unknown-command: "Unknown command, please enter /%c help to view command help." help: default: - "&bServerMarket:" - - "&f/%c open Open the global market." - - "&f/%c search Search for items in the market." - - "&f/%c box View the market storage box." - - "&f/%c show View market information." + - "&f/%c open &7Open the global market." + - "&f/%c search &7Search for items in the market." + - "&f/%c box &7View the market storage box." + - "&f/%c show &7View market information." admin: - "&bServerMarket:" - - "&f/%c open Open the global market." - - "&f/%c search Search for items in the market." - - "&f/%c box View the market storage box." - - "&f/%c show View market information." - - "&f/%c reload Reload plugin configuration files." + - "&f/%c open &7Open the global market." + - "&f/%c search &7Search for items in the market." + - "&f/%c box &7View the market storage box." + - "&f/%c show &7View market information." + - "&f/%c patch &7Apply patch" + - "&f/%c reload &7Reload plugin configuration files." pulling-start: "Loading your data." pulling-completed: "Data loading completed." @@ -25,6 +26,7 @@ error-store: "The item is not in the storage box, it may have already been claim get-store-item: "Successfully obtained &e%item% &fx &e%amount% from the storage box." wrong-market: "Please enter a market name." wrong-key: "Please enter a keyword." +wrong-patch-id: "Please enter a patch id." price-null: "Please enter the price." wrong-number: "Please enter a number." min-price: "The price must be greater than %min%." @@ -57,6 +59,10 @@ show: - "&cPlease hold the item in your hand before putting it up for auction." reload: "Plugin configuration reloaded successfully." +patch-result: + yes: "Successfully applied the patch." + no: "Patch failed to apply." + status-text: loaded: "&aLoaded successfully." error: "&cAn exception has occurred." diff --git a/src/main/resources/language/zh_CN.yml b/src/main/resources/language/zh_CN.yml index 3ed5a46..15f4c4a 100644 --- a/src/main/resources/language/zh_CN.yml +++ b/src/main/resources/language/zh_CN.yml @@ -3,17 +3,18 @@ unknown-command: "未知命令, 请输入 /%c help 查看命令帮助." help: default: - "&bServerMarket:" - - "&f/%c open <市场编号> 打开全球市场" - - "&f/%c search <市场编号> <关键字> 搜索市场物品" - - "&f/%c show 查看市场情况" - - "&f/%c box 查看市场暂存盒" + - "&f/%c open <市场编号> &7打开全球市场" + - "&f/%c search <市场编号> <关键字> &7搜索市场物品" + - "&f/%c show &7查看市场情况" + - "&f/%c box &7查看市场暂存盒" admin: - "&bServerMarket:" - - "&f/%c open <市场编号> 打开全球市场" - - "&f/%c search <市场编号> <关键字> 搜索市场物品" - - "&f/%c box 查看市场暂存盒" - - "&f/%c show 查看市场情况" - - "&f/%c reload 重载插件配置文件" + - "&f/%c open <市场编号> &7打开全球市场" + - "&f/%c search <市场编号> <关键字> &7搜索市场物品" + - "&f/%c box &7查看市场暂存盒" + - "&f/%c show &7查看市场情况" + - "&f/%c patch <补丁编号> &7使用补丁" + - "&f/%c reload &7重载插件配置文件" pulling-start: "正在加载你的数据." pulling-completed: "数据已经加载完成." @@ -25,6 +26,7 @@ error-store: "该物品不在暂存库中, 可能已经领取过了." get-store-item: "成功从暂存库中获得 &e%item% &fx &e%amount%" wrong-market: "请输入一个市场名." wrong-key: "请输入一个关键字." +wrong-patch-id: "请输入一个补丁编号." price-null: "请输入价格." wrong-number: "请输入一个数字." min-price: "价格必须大于%min%." @@ -57,6 +59,10 @@ show: - "&c上架物品前请将物品手持在手上." reload: "插件配置重载完成." +patch-result: + yes: "成功使用补丁." + no: "使用失败." + status-text: loaded: "&a已加载" error: "&c出现异常"