├── .github └── workflows │ ├── maven-publish.yml │ └── maven.yml ├── .gitignore ├── LICENSE.md ├── README.md ├── pom.xml └── src └── main ├── java └── com │ └── tripleying │ └── dogend │ └── mailbox │ ├── MailBox.java │ ├── api │ ├── command │ │ ├── BaseCommand.java │ │ └── BaseTabCompleter.java │ ├── data │ │ ├── BaseData.java │ │ ├── Data.java │ │ ├── DataType.java │ │ └── sql │ │ │ ├── CreateTable.java │ │ │ ├── DeleteData.java │ │ │ ├── InsertData.java │ │ │ ├── LastData.java │ │ │ ├── LastInsertID.java │ │ │ ├── SQLCommand.java │ │ │ ├── SelectCount.java │ │ │ ├── SelectData.java │ │ │ └── UpdateData.java │ ├── event │ │ ├── MailBoxEvent.java │ │ ├── MailBoxLoadFinishEvent.java │ │ ├── mail │ │ │ ├── MailBoxMailEvent.java │ │ │ ├── MailBoxPersonMailDeleteEvent.java │ │ │ ├── MailBoxPersonMailEvent.java │ │ │ ├── MailBoxPersonMailPreSendEvent.java │ │ │ ├── MailBoxPersonMailReceiveEvent.java │ │ │ ├── MailBoxPersonMailSendEvent.java │ │ │ ├── MailBoxSystemMailDeleteEvent.java │ │ │ ├── MailBoxSystemMailEvent.java │ │ │ └── MailBoxSystemMailSendEvent.java │ │ └── module │ │ │ ├── MailBoxModuleEvent.java │ │ │ ├── MailBoxModuleLoadEvent.java │ │ │ └── MailBoxModuleUnloadEvent.java │ ├── mail │ │ ├── BaseMail.java │ │ ├── CustomData.java │ │ ├── PersonMail.java │ │ ├── PlayerData.java │ │ ├── SystemMail.java │ │ └── attach │ │ │ ├── AttachCommand.java │ │ │ ├── AttachDoubleMoney.java │ │ │ ├── AttachFile.java │ │ │ ├── AttachIntegerMoney.java │ │ │ ├── AttachMoney.java │ │ │ └── ProxyPlayer.java │ ├── module │ │ ├── InvalidModuleException.java │ │ ├── MailBoxModule.java │ │ ├── ModuleClassLoader.java │ │ └── ModuleInfo.java │ ├── money │ │ ├── BaseMoney.java │ │ ├── DoubleMoney.java │ │ └── IntegerMoney.java │ └── util │ │ ├── CommonConfig.java │ │ └── Version.java │ ├── command │ ├── CheckCommand.java │ ├── HelpCommand.java │ ├── ReloadCommand.java │ └── UpdateCommand.java │ ├── data │ ├── CommandBuilder.java │ ├── MySQLData.java │ ├── SQLData.java │ ├── SQLiteData.java │ └── SimpleCP.java │ ├── listener │ └── onPlayerJoin.java │ ├── manager │ ├── CommandManager.java │ ├── DataManager.java │ ├── ListenerManager.java │ ├── MailManager.java │ ├── ModuleManager.java │ ├── MoneyManager.java │ └── TabManager.java │ └── util │ ├── ConfigUpdatePackage.java │ ├── ConfigUtil.java │ ├── FileUtil.java │ ├── HTTPUtil.java │ ├── ItemStackUtil.java │ ├── MessageUtil.java │ ├── ModuleUtil.java │ ├── ReflectUtil.java │ ├── TimeUtil.java │ └── UpdateUtil.java └── resources ├── config.yml ├── database.yml ├── message.yml └── plugin.yml /.github/workflows/maven-publish.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a package using Maven and then publish it to GitHub packages when a release is created 2 | # For more information see: https://github.com/actions/setup-java/blob/main/docs/advanced-usage.md#apache-maven-with-a-settings-path 3 | 4 | name: Maven Package 5 | 6 | on: 7 | release: 8 | types: [created] 9 | 10 | jobs: 11 | build: 12 | 13 | runs-on: ubuntu-latest 14 | permissions: 15 | contents: read 16 | packages: write 17 | 18 | steps: 19 | - uses: actions/checkout@v3 20 | - name: Set up JDK 8 21 | uses: actions/setup-java@v3 22 | with: 23 | java-version: '8' 24 | distribution: 'temurin' 25 | server-id: github # Value of the distributionManagement/repository/id field of the pom.xml 26 | settings-path: ${{ github.workspace }} # location for the settings.xml file 27 | 28 | - name: Build with Maven 29 | run: mvn -B package --file pom.xml 30 | 31 | - name: Publish to GitHub Packages Apache Maven 32 | run: mvn deploy -s $GITHUB_WORKSPACE/settings.xml 33 | env: 34 | GITHUB_TOKEN: ${{ github.token }} 35 | -------------------------------------------------------------------------------- /.github/workflows/maven.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time 2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven 3 | 4 | # This workflow uses actions that are not certified by GitHub. 5 | # They are provided by a third-party and are governed by 6 | # separate terms of service, privacy policy, and support 7 | # documentation. 8 | 9 | name: Java CI with Maven 10 | 11 | on: 12 | push: 13 | branches: [ "master" ] 14 | pull_request: 15 | branches: [ "master" ] 16 | 17 | jobs: 18 | build: 19 | 20 | runs-on: ubuntu-latest 21 | 22 | steps: 23 | - uses: actions/checkout@v3 24 | - name: Set up JDK 8 25 | uses: actions/setup-java@v3 26 | with: 27 | java-version: '8' 28 | distribution: 'temurin' 29 | cache: maven 30 | - name: Build with Maven 31 | run: mvn -B package --file pom.xml 32 | 33 | # Optional: Uploads the full dependency graph to GitHub to improve the quality of Dependabot alerts this repository can receive 34 | - name: Update dependency graph 35 | uses: advanced-security/maven-dependency-submission-action@571e99aab1055c2e71a1e2309b9691de18d6b7d6 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | target/ 3 | *.iml 4 | nb-configuration.xml -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Dogend 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MailBox 2 | A plugin of Minecraft (1.7.10-1.19). 3 | Used to send items and money to players. 4 | Mail type and Money type can be extended through the MailBoxModule. 5 | (The plugin itself has no actual function ~) 6 | 7 | 用于Bukkit服务器的我的世界邮箱插件 8 | 支持版本 1.7.10 - 1.19 9 | 可以向玩家发送物品、金钱以及在领取时执行指令 10 | 通过模块可以扩展邮件类型、金钱类型 11 | (插件本身没有实际功能哦~) 12 | 13 | ##### 官方网站 14 | ##### WebSite: http://qwq.tripleying.com/plugins/mailbox 15 | 16 | ##### 官方Wiki 17 | ##### WIKI: http://qwq.tripleying.com/plugins/mailbox/wiki 18 | 19 | ##### 模块列表 20 | ##### MailBoxModule: http://qwq.tripleying.com/plugins/mailbox/wiki?page=module-list 21 | 22 | [![](https://jitpack.io/v/Dogend233/MailBox.svg)](https://jitpack.io/#Dogend233/MailBox) 23 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 4.0.0 7 | 8 | com.tripleying.dogend 9 | MailBox 10 | jar 11 | 3.3.1 12 | 13 | 14 | UTF-8 15 | UTF-8 16 | 1.8 17 | 1.8 18 | 19 | 20 | MailBox 21 | A Bukkit Plugin of Minecraft 1.7.10-1.19. 22 | 23 | 24 | 25 | spigot-repo 26 | https://hub.spigotmc.org/nexus/content/repositories/snapshots/ 27 | 28 | 29 | 30 | 31 | 32 | org.bukkit 33 | bukkit 34 | 1.12.2-R0.1-SNAPSHOT 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/MailBox.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox; 2 | 3 | import com.tripleying.dogend.mailbox.api.event.MailBoxLoadFinishEvent; 4 | import com.tripleying.dogend.mailbox.api.mail.attach.AttachCommand; 5 | import com.tripleying.dogend.mailbox.data.SQLiteData; 6 | import com.tripleying.dogend.mailbox.api.mail.attach.AttachFile; 7 | import com.tripleying.dogend.mailbox.api.util.CommonConfig; 8 | import com.tripleying.dogend.mailbox.listener.onPlayerJoin; 9 | import com.tripleying.dogend.mailbox.manager.*; 10 | import com.tripleying.dogend.mailbox.data.MySQLData; 11 | import com.tripleying.dogend.mailbox.util.ConfigUtil; 12 | import com.tripleying.dogend.mailbox.util.FileUtil; 13 | import com.tripleying.dogend.mailbox.util.MessageUtil; 14 | import com.tripleying.dogend.mailbox.util.UpdateUtil; 15 | import java.io.File; 16 | import org.bukkit.Bukkit; 17 | import org.bukkit.command.CommandSender; 18 | import org.bukkit.configuration.file.YamlConfiguration; 19 | import org.bukkit.configuration.serialization.ConfigurationSerialization; 20 | import org.bukkit.event.HandlerList; 21 | import org.bukkit.plugin.java.JavaPlugin; 22 | 23 | /** 24 | * 邮箱主类 25 | * @author Dogend 26 | */ 27 | public class MailBox extends JavaPlugin { 28 | 29 | /** 30 | * 邮箱实例 31 | */ 32 | private static MailBox mailbox; 33 | /** 34 | * MC版本 35 | */ 36 | private static double mc_version; 37 | // 管理器 38 | private DataManager datamgr; 39 | private MailManager mailmgr; 40 | private MoneyManager moneymgr; 41 | private CommandManager cmdmgr; 42 | private ListenerManager listenermgr; 43 | private ModuleManager modulemgr; 44 | 45 | @Override 46 | public void onEnable(){ 47 | mailbox = this; 48 | System.out.println( 49 | " _____ ____ _____ ______ _ _ _____ \n" + 50 | " | __ \\ / __ \\ / ____| ____| \\ | | __ \\ \n" + 51 | " | | | | | | | | __| |__ | \\| | | | |\n" + 52 | " | | | | | | | | |_ | __| | . ` | | | |\n" + 53 | " | |__| | |__| | |__| | |____| |\\ | |__| |\n" + 54 | " |_____/ \\____/ \\_____|______|_| \\_|_____/ " 55 | ); 56 | // 为邮件附件注册序列化 57 | ConfigurationSerialization.registerClass(AttachCommand.class); 58 | ConfigurationSerialization.registerClass(AttachFile.class); 59 | // 获取游戏版本 60 | String v1 = Bukkit.getServer().getVersion(); 61 | v1 = v1.substring(v1.indexOf("MC")+3, v1.length()-1).trim(); 62 | String v2; 63 | if(v1.indexOf('.')==v1.lastIndexOf('.')){ 64 | v2 = v1; 65 | }else{ 66 | v2 = v1.substring(0, v1.lastIndexOf('.')); 67 | } 68 | v2 = v2.substring(v1.indexOf('.')+1); 69 | if(v2.length()==1) v2 = "0"+v2; 70 | mc_version = Double.parseDouble(v1.substring(0, v1.indexOf('.'))+"."+v2); 71 | // 设置默认编码 72 | if(mc_version<1.09) FileUtil.setCharset(Bukkit.getServer().getName()); 73 | // 加载插件 74 | load(); 75 | } 76 | 77 | public void load(){ 78 | // 加载各管理器 79 | this.datamgr = new DataManager(); 80 | this.mailmgr = new MailManager(); 81 | this.moneymgr = new MoneyManager(); 82 | this.cmdmgr = new CommandManager(); 83 | this.listenermgr = new ListenerManager(); 84 | this.modulemgr = new ModuleManager(); 85 | // 初始化配置文件 86 | YamlConfiguration msg = FileUtil.getConfig("message.yml"); 87 | YamlConfiguration db = FileUtil.getConfig("database.yml"); 88 | YamlConfiguration config = FileUtil.getConfig("config.yml"); 89 | // 检查配置文件更新 90 | if(config.getBoolean("auto-config", false)){ 91 | ConfigUtil.checkConfigVersion("message", msg); 92 | ConfigUtil.checkConfigVersion("database", db); 93 | ConfigUtil.checkConfigVersion("config", config); 94 | } 95 | // 初始化消息工具 96 | MessageUtil.init(msg); 97 | // 配置默认数据源 98 | this.loadDataBase(db); 99 | // 初始化公共配置 100 | CommonConfig.init(config); 101 | // 当服务器完全启动后加载 102 | Bukkit.getScheduler().runTask(this, () -> { 103 | // 注册基础指令 104 | this.cmdmgr.registerBaseCommand(); 105 | try{ 106 | // 加载本地模块 107 | this.modulemgr.loadLocalModule(); 108 | }catch(Exception ex){ 109 | }finally{ 110 | // 选择使用的数据源 111 | String database = config.getString("database", "sqlite"); 112 | if(this.datamgr.selectData(database)){ 113 | // 注册指令 114 | Bukkit.getPluginCommand("mailbox").setExecutor(this.cmdmgr); 115 | Bukkit.getPluginCommand("mailbox").setTabCompleter(this.cmdmgr.getTabManager()); 116 | // 注册监听器 117 | Bukkit.getPluginManager().registerEvents(new onPlayerJoin(), this); 118 | // 发起加载完成事件 119 | Bukkit.getPluginManager().callEvent(new MailBoxLoadFinishEvent()); 120 | }else{ 121 | // 启动数据源失败, 卸载插件 122 | MessageUtil.error(MessageUtil.data_enable_error.replaceAll("%data%", database)); 123 | Bukkit.getPluginManager().disablePlugin(this); 124 | } 125 | } 126 | }); 127 | // 更新检查 128 | if(config.getBoolean("update-check", false)) UpdateUtil.updatePlugin(Bukkit.getConsoleSender(), CommonConfig.auto_update); 129 | } 130 | 131 | public void loadDataBase(YamlConfiguration database){ 132 | // 加载SQLite配置 133 | if(database.getBoolean("sqlite.enable", false)){ 134 | this.datamgr.addData(null, new SQLiteData(database)); 135 | } 136 | // 加载MySQL配置 137 | if(database.getBoolean("mysql.enable", false)){ 138 | this.datamgr.addData(null, new MySQLData(database)); 139 | } 140 | } 141 | 142 | public void unload(){ 143 | // 关闭在线玩家的GUI 144 | Bukkit.getOnlinePlayers().forEach(p -> p.closeInventory()); 145 | // 注销监听器 146 | HandlerList.unregisterAll(this); 147 | // 关闭数据源 148 | if(this.datamgr!=null) this.datamgr.closeData(); 149 | // 卸载全部模块 150 | if(this.modulemgr!=null) this.modulemgr.unloadAllModule(); 151 | } 152 | 153 | public void reload(CommandSender cs){ 154 | MessageUtil.error(cs, MessageUtil.reload_unload); 155 | unload(); 156 | MessageUtil.log(cs, MessageUtil.reload_load); 157 | load(); 158 | MessageUtil.log(cs, MessageUtil.reload_finish); 159 | } 160 | 161 | @Override 162 | public void onDisable(){ 163 | // 卸载插件 164 | unload(); 165 | // 为邮件附件注销序列化 166 | ConfigurationSerialization.unregisterClass(AttachFile.class); 167 | ConfigurationSerialization.unregisterClass(AttachCommand.class); 168 | } 169 | 170 | public DataManager getDataManager(){ 171 | return this.datamgr; 172 | } 173 | 174 | public MailManager getMailManager(){ 175 | return this.mailmgr; 176 | } 177 | 178 | public MoneyManager getMoneyManager(){ 179 | return this.moneymgr; 180 | } 181 | 182 | public CommandManager getCommandManager(){ 183 | return this.cmdmgr; 184 | } 185 | 186 | public ListenerManager getListenerManager(){ 187 | return this.listenermgr; 188 | } 189 | 190 | public ModuleManager getModuleManager(){ 191 | return this.modulemgr; 192 | } 193 | 194 | public static MailBox getMailBox(){ 195 | return mailbox; 196 | } 197 | 198 | public static double getMCVersion(){ 199 | return mc_version; 200 | } 201 | 202 | @Override 203 | public File getFile(){ 204 | return super.getFile(); 205 | } 206 | 207 | } -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/command/BaseCommand.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.command; 2 | 3 | import org.bukkit.command.CommandSender; 4 | 5 | /** 6 | * 基础指令 7 | * @author Dogend 8 | */ 9 | public interface BaseCommand { 10 | 11 | /** 12 | * 获取指令标签 (mailbox后的第一个参数) 13 | * @return label 14 | */ 15 | public String getLabel(); 16 | 17 | /** 18 | * 获取指令介绍 19 | * @param sender 指令发送者 20 | * @return String 21 | */ 22 | public String getDescription(CommandSender sender); 23 | 24 | /** 25 | * 指令主体 26 | * 返回false则触发help指令 27 | * @param sender 指令发送者 28 | * @param args 指令参数(去掉了mailbox) 29 | * @return boolean 30 | */ 31 | public boolean onCommand(CommandSender sender, String[] args); 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/command/BaseTabCompleter.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.command; 2 | 3 | import java.util.List; 4 | import org.bukkit.command.CommandSender; 5 | 6 | /** 7 | * 基础指令补全器 8 | * @author Administrator 9 | */ 10 | public interface BaseTabCompleter { 11 | 12 | /** 13 | * 指令发送者是否被允许补全该指令 14 | * @param sender 指令发送者 15 | * @return boolean 16 | */ 17 | public boolean allowTab(CommandSender sender); 18 | 19 | /** 20 | * 指令补全器主体 21 | * @param sender 指令发送者 22 | * @param args 指令参数(去掉了mailbox) 23 | * @return List 24 | */ 25 | public List onTabComplete(CommandSender sender, String[] args); 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/data/BaseData.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.data; 2 | 3 | import com.tripleying.dogend.mailbox.api.mail.CustomData; 4 | import com.tripleying.dogend.mailbox.api.mail.PersonMail; 5 | import com.tripleying.dogend.mailbox.api.mail.PlayerData; 6 | import com.tripleying.dogend.mailbox.api.mail.SystemMail; 7 | import java.util.LinkedHashMap; 8 | import java.util.List; 9 | import java.util.Map; 10 | import org.bukkit.entity.Player; 11 | 12 | /** 13 | * 基础数据父类 14 | * @author Dogend 15 | */ 16 | public interface BaseData { 17 | 18 | /** 19 | * 获取数据源类型 20 | * @return String 21 | */ 22 | public String getType(); 23 | 24 | /** 25 | * 启用数据源 26 | * @return boolean 27 | */ 28 | public boolean enable(); 29 | 30 | /** 31 | * 关闭数据源 32 | */ 33 | public void close(); 34 | 35 | /** 36 | * 创建玩家数据存储库 37 | * @return boolean 38 | */ 39 | public boolean createPlayerDataStorage(); 40 | 41 | /** 42 | * 通过UUID获取玩家数据 43 | * 若玩家数据不存在则创建新数据 44 | * 若玩家名与数据库已存玩家名不同则更新数据 45 | * @param p 玩家 46 | * @return PlayerData 47 | */ 48 | public PlayerData getPlayerData(Player p); 49 | 50 | /** 51 | * 获取全部玩家数据 52 | * @return List 53 | */ 54 | public List getAllPlayerData(); 55 | 56 | /** 57 | * 更新玩家数据 58 | * 若玩家数据不存在则插入数据 59 | * @param pd PlayerData 60 | * @return PlayerData 61 | */ 62 | public boolean updatePlayerData(PlayerData pd); 63 | 64 | /** 65 | * 创建个人邮件存储库 66 | * @return boolean 67 | */ 68 | public boolean createPersonMailStorage(); 69 | 70 | /** 71 | * 获取个人邮件数量 72 | * @param p 玩家 73 | * @return Long 74 | */ 75 | public long getPersonMailCount(Player p); 76 | 77 | /** 78 | * 获取未领取附件的个人邮件数量 79 | * @param p 玩家 80 | * @return Long 81 | */ 82 | public long getNotReceivedPersonMailCount(Player p); 83 | 84 | /** 85 | * 获取个人邮件列表 86 | * 拉取时邮件过期会进行删除 87 | * @param p 玩家 88 | * @return List 89 | */ 90 | public List getPersonMail(Player p); 91 | 92 | /** 93 | * 以特定id和type获取个人邮件 94 | * 不存在返回null 95 | * @param p 玩家 96 | * @param id id 97 | * @param type 邮件类型 98 | * @return PersonMail 99 | */ 100 | public PersonMail getPersonMail(Player p, long id, String type); 101 | 102 | /** 103 | * 获取固定数量的个人邮件列表 104 | * 拉取时邮件过期会进行删除 105 | * @param p 玩家 106 | * @param count 每页个数 107 | * @param page 页数 108 | * @return List 109 | */ 110 | public List getPersonMail(Player p, int count, int page); 111 | 112 | /** 113 | * 发送一封个人邮件 114 | * @param pm 个人邮件 115 | * @param p 玩家 116 | * @return boolean 117 | */ 118 | public boolean sendPersonMail(PersonMail pm, Player p); 119 | 120 | /** 121 | * 领取一封个人邮件 122 | * @param pm 个人邮件 123 | * @param p 玩家 124 | * @return boolean 125 | */ 126 | public boolean receivePersonMail(PersonMail pm, Player p); 127 | 128 | /** 129 | * 删除个人邮件 130 | * @param pm 个人邮件 131 | * @return boolean 132 | */ 133 | public boolean deletePersonMail(PersonMail pm); 134 | 135 | /** 136 | * 清空玩家已领取的邮件 137 | * @param p 玩家 138 | * @return long 139 | */ 140 | public long clearPersonReceivedMail(Player p); 141 | 142 | /** 143 | * 创建系统邮件存储库 144 | * @param sm 系统邮件实例 145 | * @return boolean 146 | */ 147 | public boolean createSystemMailStorage(SystemMail sm); 148 | 149 | /** 150 | * 获取系统邮件最大ID 151 | * @param sm 系统邮件实例 152 | * @return long 153 | */ 154 | public long getSystemMailMax(SystemMail sm); 155 | 156 | /** 157 | * 获取系统邮件数量 158 | * @param sm 系统邮件 159 | * @return Long 160 | */ 161 | public long getSystemMailCount(SystemMail sm); 162 | 163 | /** 164 | * 获取系统邮件列表 165 | * @param sm 系统邮件实例 166 | * @return List 167 | */ 168 | public List getSystemMail(SystemMail sm); 169 | 170 | /** 171 | * 获取特定id的系统邮件列表 172 | * 没有返回null 173 | * @param sm 系统邮件 174 | * @param id id 175 | * @return SystemMail 176 | */ 177 | public SystemMail getSystemMail(SystemMail sm, long id); 178 | 179 | /** 180 | * 获取固定数量的系统邮件列表 181 | * @param sm 系统邮件实例 182 | * @param count 每页个数 183 | * @param page 页数 184 | * @return List 185 | */ 186 | public List getSystemMail(SystemMail sm, int count, int page); 187 | 188 | /** 189 | * 获取id从min到max的邮件集合 190 | * @param sm 系统邮件实例 191 | * @param min 最小值 192 | * @param max 最大值 193 | * @return Map 194 | */ 195 | public Map getSystemMail(SystemMail sm, long min, long max); 196 | 197 | /** 198 | * 发送一封系统邮件 199 | * 若返回的邮件ID为0则发送失败 200 | * @param sm 系统邮件 201 | * @return SystemMail 202 | */ 203 | public SystemMail sendSystemMail(SystemMail sm); 204 | 205 | /** 206 | * 删除系统邮件 207 | * @param sm 系统邮件实例 208 | * @return boolean 209 | */ 210 | public boolean deleteSystemMail(SystemMail sm); 211 | 212 | /** 213 | * 创建自定义存储库 214 | * @param cd CustomData 215 | * @since 3.1.0 216 | * @return boolean 217 | */ 218 | public boolean createCustomStorage(CustomData cd); 219 | 220 | /** 221 | * 将自定义数据插入存储库 222 | * @param cd 自定义数据 223 | * @since 3.1.0 224 | * @return boolean 225 | */ 226 | public boolean insertCustomData(CustomData cd); 227 | 228 | /** 229 | * 按主键将存储库的其他数据更新 230 | * @param cd 自定义数据 231 | * @since 3.3.0 232 | * @return boolean 233 | */ 234 | public boolean updateCustomDataByPrimaryKey(CustomData cd); 235 | 236 | /** 237 | * 以特定条件获取自定义数据 238 | * @param cd 自定义数据实例 239 | * @param args 条件 240 | * @since 3.1.0 241 | * @return List 242 | */ 243 | public List selectCustomData(CustomData cd, LinkedHashMap args); 244 | 245 | /** 246 | * 以特定条件删除自定义数据 247 | * @param cd 自定义数据实例 248 | * @param args 条件 249 | * @since 3.1.0 250 | * @return List 251 | */ 252 | public long deleteCustomData(CustomData cd, LinkedHashMap args); 253 | 254 | } 255 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/data/Data.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.data; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * 数据字段注解 10 | * @author Dogend 11 | */ 12 | @Target(ElementType.FIELD) 13 | @Retention(RetentionPolicy.RUNTIME) 14 | public @interface Data { 15 | 16 | // 字段类型 17 | public DataType type(); 18 | 19 | // 字段长度(String类型用) 20 | public int size() default 50; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/data/DataType.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.data; 2 | 3 | /** 4 | * 邮件字段类型 5 | * 用于在数据库中创建字段, 进行查询等操作 6 | * SystemMail默认创建字段id, title, body, sender, sendtime, attach 7 | * @author Dogend 8 | */ 9 | public enum DataType { 10 | 11 | Integer,// 整数 12 | Long,// 长整数 13 | Boolean,// 布尔值 14 | DateTime,// 日期 15 | String,// 字符串 16 | YamlString,// YML字符串 17 | /** 18 | * 自增主键 (CustomData用) 19 | * @since 3.1.0 20 | */ 21 | Primary; 22 | 23 | } -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/data/sql/CreateTable.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.data.sql; 2 | 3 | import java.util.LinkedHashMap; 4 | import java.util.Map; 5 | import java.util.Map.Entry; 6 | 7 | /** 8 | * 创建表 9 | * @author Dogend 10 | */ 11 | public class CreateTable implements SQLCommand { 12 | 13 | private String primary; 14 | private final String table; 15 | private final Map columns; 16 | 17 | public CreateTable(String table){ 18 | this.table = table; 19 | this.columns = new LinkedHashMap(); 20 | } 21 | 22 | public CreateTable setPrimaryKey(String column){ 23 | this.primary = column; 24 | return this; 25 | } 26 | 27 | public CreateTable addInt(String column){ 28 | this.columns.put(column, "int(1)"); 29 | return this; 30 | } 31 | 32 | public CreateTable addLong(String column){ 33 | this.columns.put(column, "bigint(1)"); 34 | return this; 35 | } 36 | 37 | public CreateTable addBoolean(String column){ 38 | this.columns.put(column, "tinyint(1)"); 39 | return this; 40 | } 41 | 42 | public CreateTable addDateTime(String column){ 43 | this.columns.put(column, "datetime"); 44 | return this; 45 | } 46 | 47 | public CreateTable addString(String column, int length){ 48 | this.columns.put(column, "varchar(N)".replace("N", Integer.toString(length))); 49 | return this; 50 | } 51 | 52 | public CreateTable addYamlString(String column){ 53 | this.columns.put(column, "mediumtext"); 54 | return this; 55 | } 56 | 57 | @Override 58 | public String toMySQLCommand(){ 59 | StringBuilder sb = new StringBuilder("CREATE TABLE IF NOT EXISTS "); 60 | sb.append('`').append(this.table).append("` ("); 61 | if(this.primary!=null){ 62 | sb.append('`').append(this.primary).append("` bigint(1) AUTO_INCREMENT,"); 63 | } 64 | for(Entry entry:this.columns.entrySet()){ 65 | sb.append('`').append(entry.getKey()).append("` ").append(entry.getValue()).append(','); 66 | } 67 | if(this.primary!=null){ 68 | sb.append("PRIMARY KEY (`").append(this.primary).append("`)"); 69 | }else if(!this.columns.isEmpty()){ 70 | sb.deleteCharAt(sb.length()-1); 71 | } 72 | sb.append(')'); 73 | return sb.toString(); 74 | } 75 | 76 | @Override 77 | public String toSQLiteCommand(){ 78 | StringBuilder sb = new StringBuilder("CREATE TABLE IF NOT EXISTS "); 79 | sb.append('`').append(this.table).append("` ("); 80 | if(this.primary!=null){ 81 | sb.append('`').append(this.primary).append("` INTEGER PRIMARY KEY AUTOINCREMENT,"); 82 | } 83 | for(Entry entry:this.columns.entrySet()){ 84 | sb.append('`').append(entry.getKey()).append("` ").append(entry.getValue()).append(','); 85 | } 86 | if(!this.columns.isEmpty()){ 87 | sb.deleteCharAt(sb.length()-1); 88 | } 89 | sb.append(')'); 90 | return sb.toString(); 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/data/sql/DeleteData.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.data.sql; 2 | 3 | import java.util.LinkedList; 4 | import java.util.List; 5 | 6 | /** 7 | * 删除数据 8 | * @author Dogend 9 | */ 10 | public class DeleteData implements SQLCommand { 11 | 12 | private final String table; 13 | private final List where; 14 | 15 | public DeleteData(String table){ 16 | this.table = table; 17 | this.where = new LinkedList(); 18 | } 19 | 20 | public DeleteData addWhere(String column){ 21 | this.where.add(column); 22 | return this; 23 | } 24 | 25 | private String toCommand(){ 26 | StringBuilder sb = new StringBuilder().append("DELETE FROM `").append(this.table).append('`'); 27 | if(!this.where.isEmpty()){ 28 | sb.append(" WHERE"); 29 | for(String column:this.where){ 30 | sb.append(" `").append(column).append("` = ? AND"); 31 | } 32 | sb.delete(sb.length()-3, sb.length()); 33 | } 34 | return sb.toString(); 35 | } 36 | 37 | @Override 38 | public String toMySQLCommand() { 39 | return this.toCommand(); 40 | } 41 | 42 | @Override 43 | public String toSQLiteCommand() { 44 | return this.toCommand(); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/data/sql/InsertData.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.data.sql; 2 | 3 | import java.util.LinkedList; 4 | import java.util.List; 5 | 6 | /** 7 | * 插入数据 8 | * @author Dogend 9 | */ 10 | public class InsertData implements SQLCommand { 11 | 12 | private final String table; 13 | private final List columns; 14 | 15 | public InsertData(String table){ 16 | this.table = table; 17 | this.columns = new LinkedList(); 18 | } 19 | 20 | public InsertData addColumns(String column){ 21 | this.columns.add(column); 22 | return this; 23 | } 24 | 25 | private String toCommand(){ 26 | StringBuilder sb = new StringBuilder().append("INSERT INTO ").append('`').append(this.table).append('`'); 27 | StringBuilder sbk = new StringBuilder().append('('); 28 | StringBuilder sbv = new StringBuilder().append('('); 29 | for(String column:this.columns){ 30 | sbk.append('`').append(column).append("`,"); 31 | sbv.append("?,"); 32 | } 33 | if(!this.columns.isEmpty()){ 34 | sbk.deleteCharAt(sbk.length()-1); 35 | sbv.deleteCharAt(sbv.length()-1); 36 | } 37 | sbk.append(')'); 38 | sbv.append(')'); 39 | sb.append(' ').append(sbk.toString()).append(" VALUES ").append(sbv.toString()); 40 | return sb.toString(); 41 | } 42 | 43 | @Override 44 | public String toMySQLCommand() { 45 | return this.toCommand(); 46 | } 47 | 48 | @Override 49 | public String toSQLiteCommand() { 50 | return this.toCommand(); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/data/sql/LastData.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.data.sql; 2 | 3 | import java.util.LinkedList; 4 | import java.util.List; 5 | 6 | /** 7 | * 表中最后一条数据(按ID排列) 8 | * @author Dogend 9 | */ 10 | public class LastData implements SQLCommand { 11 | 12 | private final String table; 13 | private final List select; 14 | 15 | public LastData(String table){ 16 | this.table = table; 17 | this.select = new LinkedList(); 18 | } 19 | 20 | public LastData addSelect(String column){ 21 | this.select.add(column); 22 | return this; 23 | } 24 | 25 | private String toCommand(){ 26 | StringBuilder sb = new StringBuilder().append("SELECT "); 27 | if(this.select.isEmpty()){ 28 | sb.append("*"); 29 | }else{ 30 | for(String column:this.select){ 31 | sb.append('`').append(column).append("`,"); 32 | } 33 | sb.deleteCharAt(sb.length()-1); 34 | } 35 | sb.append(" FROM `").append(this.table).append("` order by `id` desc limit 1"); 36 | return sb.toString(); 37 | } 38 | 39 | @Override 40 | public String toMySQLCommand() { 41 | return this.toCommand(); 42 | } 43 | 44 | @Override 45 | public String toSQLiteCommand() { 46 | return this.toCommand(); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/data/sql/LastInsertID.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.data.sql; 2 | 3 | /** 4 | * 上次插入的主键ID 5 | * @author Dogend 6 | */ 7 | public class LastInsertID implements SQLCommand { 8 | 9 | private final static String mysql = "SELECT LAST_INSERT_ID() AS `id`"; 10 | private final static String sqlite = "SELECT LAST_INSERT_ROWID() AS `id`"; 11 | 12 | @Override 13 | public String toMySQLCommand() { 14 | return mysql; 15 | } 16 | 17 | @Override 18 | public String toSQLiteCommand() { 19 | return sqlite; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/data/sql/SQLCommand.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.data.sql; 2 | 3 | /** 4 | * SQL指令父类 5 | * @author Dogend 6 | */ 7 | public interface SQLCommand { 8 | 9 | public String toMySQLCommand(); 10 | public String toSQLiteCommand(); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/data/sql/SelectCount.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.data.sql; 2 | 3 | /** 4 | * 查询表中数据数量 5 | * @author Dogend 6 | */ 7 | public class SelectCount implements SQLCommand { 8 | 9 | private final String table; 10 | 11 | public SelectCount(String table){ 12 | this.table = table; 13 | } 14 | 15 | private String toCommand(){ 16 | return new StringBuilder().append("SELECT COUNT(*) FROM `").append(table).append('`').toString(); 17 | } 18 | 19 | @Override 20 | public String toMySQLCommand() { 21 | return this.toCommand(); 22 | } 23 | 24 | @Override 25 | public String toSQLiteCommand() { 26 | return this.toCommand(); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/data/sql/SelectData.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.data.sql; 2 | 3 | import java.util.LinkedList; 4 | import java.util.List; 5 | 6 | /** 7 | * 选择数据 8 | * @author Dogend 9 | */ 10 | public class SelectData implements SQLCommand { 11 | 12 | private String order; 13 | private boolean desc; 14 | private boolean limit; 15 | private final String table; 16 | private final List select; 17 | private final List where; 18 | private final List between; 19 | 20 | public SelectData(String table){ 21 | this.order = null; 22 | this.desc = false; 23 | this.limit = false; 24 | this.table = table; 25 | this.select = new LinkedList(); 26 | this.where = new LinkedList(); 27 | this.between = new LinkedList(); 28 | } 29 | 30 | public SelectData addSelectWithoutBackquote(String column){ 31 | this.select.add(column); 32 | return this; 33 | } 34 | 35 | public SelectData addSelect(String column){ 36 | this.select.add("`"+column+"`"); 37 | return this; 38 | } 39 | 40 | public SelectData addWhere(String column){ 41 | this.where.add(column); 42 | return this; 43 | } 44 | 45 | public SelectData addBetween(String column){ 46 | this.between.add(column); 47 | return this; 48 | } 49 | 50 | public SelectData orderBy(String column){ 51 | this.order = column; 52 | return this; 53 | } 54 | 55 | public SelectData desc(boolean desc){ 56 | this.desc = desc; 57 | return this; 58 | } 59 | 60 | public SelectData setLimit(boolean limit){ 61 | this.limit = limit; 62 | return this; 63 | } 64 | 65 | private String toCommand(){ 66 | StringBuilder sb = new StringBuilder().append("SELECT "); 67 | if(this.select.isEmpty()){ 68 | sb.append("*"); 69 | }else{ 70 | for(String column:this.select){ 71 | sb.append(column).append(","); 72 | } 73 | sb.deleteCharAt(sb.length()-1); 74 | } 75 | sb.append(" FROM `").append(this.table).append('`'); 76 | if(!this.where.isEmpty() || !this.between.isEmpty()){ 77 | sb.append(" WHERE"); 78 | for(String column:this.where){ 79 | sb.append(" `").append(column).append("` = ? AND"); 80 | } 81 | for(String column:this.between){ 82 | sb.append(" (`").append(column).append("` BETWEEN ? AND ? ) AND"); 83 | } 84 | sb.delete(sb.length()-3, sb.length()); 85 | } 86 | if(this.order!=null){ 87 | sb.append(" ORDER BY `").append(this.order).append("`"); 88 | if(this.desc){ 89 | sb.append(" DESC"); 90 | } 91 | } 92 | if(this.limit){ 93 | sb.append(" LIMIT ?, ?"); 94 | } 95 | return sb.toString(); 96 | } 97 | 98 | @Override 99 | public String toMySQLCommand() { 100 | return this.toCommand(); 101 | } 102 | 103 | @Override 104 | public String toSQLiteCommand() { 105 | return this.toCommand(); 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/data/sql/UpdateData.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.data.sql; 2 | 3 | import java.util.LinkedList; 4 | import java.util.List; 5 | 6 | /** 7 | * 更新数据 8 | * @author Dogend 9 | */ 10 | public class UpdateData implements SQLCommand { 11 | 12 | private final String table; 13 | private final List set; 14 | private final List where; 15 | 16 | public UpdateData(String table){ 17 | this.table = table; 18 | this.set = new LinkedList(); 19 | this.where = new LinkedList(); 20 | } 21 | 22 | public UpdateData addSet(String column){ 23 | this.set.add(column); 24 | return this; 25 | } 26 | 27 | public UpdateData addWhere(String column){ 28 | this.where.add(column); 29 | return this; 30 | } 31 | 32 | private String toCommand(){ 33 | if(this.set.isEmpty() || this.where.isEmpty()) return ""; 34 | StringBuilder sb = new StringBuilder().append("UPDATE `").append(this.table).append("` SET "); 35 | if(this.set.size()==1){ 36 | sb.append('`').append(this.set.get(0)).append("` = ?"); 37 | }else{ 38 | for(String column:this.set){ 39 | sb.append('`').append(column).append("` = ? ,"); 40 | } 41 | sb.deleteCharAt(sb.length()-1); 42 | } 43 | sb.append(" WHERE"); 44 | for(String column:this.where){ 45 | sb.append(" `").append(column).append("` = ? AND"); 46 | } 47 | sb.delete(sb.length()-3, sb.length()); 48 | return sb.toString(); 49 | } 50 | 51 | @Override 52 | public String toMySQLCommand() { 53 | return this.toCommand(); 54 | } 55 | 56 | @Override 57 | public String toSQLiteCommand() { 58 | return this.toCommand(); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/event/MailBoxEvent.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.event; 2 | 3 | import org.bukkit.event.Event; 4 | 5 | /** 6 | * 邮箱事件 7 | * @author Dogend 8 | */ 9 | public abstract class MailBoxEvent extends Event {} -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/event/MailBoxLoadFinishEvent.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.event; 2 | 3 | import org.bukkit.event.HandlerList; 4 | 5 | /** 6 | * 插件加载完成事件 7 | * 此事件只会在服务器完全启动并运行后发生 8 | * 当插件首次加载或重载时, 除更新检查外所有操作执行完成时触发 9 | * @author Dogend 10 | */ 11 | public class MailBoxLoadFinishEvent extends MailBoxEvent { 12 | 13 | private static final HandlerList HANDLERS = new HandlerList(); 14 | 15 | @Override 16 | public HandlerList getHandlers() { 17 | return HANDLERS; 18 | } 19 | 20 | public static HandlerList getHandlerList() { 21 | return HANDLERS; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/event/mail/MailBoxMailEvent.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.event.mail; 2 | 3 | import com.tripleying.dogend.mailbox.api.event.MailBoxEvent; 4 | 5 | /** 6 | * 邮箱邮件事件 7 | * @author Dogend 8 | */ 9 | public abstract class MailBoxMailEvent extends MailBoxEvent {} 10 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/event/mail/MailBoxPersonMailDeleteEvent.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.event.mail; 2 | 3 | import com.tripleying.dogend.mailbox.api.mail.PersonMail; 4 | import org.bukkit.event.HandlerList; 5 | 6 | /** 7 | * 邮箱个人邮件删除事件 8 | * @author Dogend 9 | */ 10 | public class MailBoxPersonMailDeleteEvent extends MailBoxPersonMailEvent { 11 | 12 | private static final HandlerList HANDLERS = new HandlerList(); 13 | private final PersonMail pm; 14 | 15 | public MailBoxPersonMailDeleteEvent(PersonMail pm){ 16 | this.pm = pm; 17 | } 18 | 19 | public PersonMail getPersonMail(){ 20 | return this.pm; 21 | } 22 | 23 | @Override 24 | public HandlerList getHandlers() { 25 | return HANDLERS; 26 | } 27 | 28 | public static HandlerList getHandlerList() { 29 | return HANDLERS; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/event/mail/MailBoxPersonMailEvent.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.event.mail; 2 | 3 | /** 4 | * 邮箱个人邮件事件 5 | * @author Dogend 6 | */ 7 | public abstract class MailBoxPersonMailEvent extends MailBoxMailEvent {} -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/event/mail/MailBoxPersonMailPreSendEvent.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.event.mail; 2 | 3 | import com.tripleying.dogend.mailbox.api.mail.PersonMail; 4 | import org.bukkit.event.Cancellable; 5 | import org.bukkit.event.HandlerList; 6 | 7 | /** 8 | * 邮箱个人邮件预发送事件 9 | * 当邮件满足发送条件即将准备发送时触发 10 | * @author Dogend 11 | */ 12 | public class MailBoxPersonMailPreSendEvent extends MailBoxPersonMailEvent implements Cancellable { 13 | 14 | private static final HandlerList HANDLERS = new HandlerList(); 15 | private final PersonMail pm; 16 | private boolean cancel; 17 | 18 | public MailBoxPersonMailPreSendEvent(PersonMail pm){ 19 | this.pm = pm; 20 | this.cancel = false; 21 | } 22 | 23 | public PersonMail getPersonMail(){ 24 | return this.pm; 25 | } 26 | 27 | @Override 28 | public HandlerList getHandlers() { 29 | return HANDLERS; 30 | } 31 | 32 | public static HandlerList getHandlerList() { 33 | return HANDLERS; 34 | } 35 | 36 | @Override 37 | public boolean isCancelled() { 38 | return this.cancel; 39 | } 40 | 41 | @Override 42 | public void setCancelled(boolean bln) { 43 | this.cancel = bln; 44 | } 45 | 46 | } -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/event/mail/MailBoxPersonMailReceiveEvent.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.event.mail; 2 | 3 | import com.tripleying.dogend.mailbox.api.mail.PersonMail; 4 | import org.bukkit.event.HandlerList; 5 | 6 | /** 7 | * 邮箱个人邮件领取事件 8 | * @author Dogend 9 | */ 10 | public class MailBoxPersonMailReceiveEvent extends MailBoxPersonMailEvent { 11 | 12 | private static final HandlerList HANDLERS = new HandlerList(); 13 | private final PersonMail pm; 14 | 15 | public MailBoxPersonMailReceiveEvent(PersonMail pm){ 16 | this.pm = pm; 17 | } 18 | 19 | public PersonMail getPersonMail(){ 20 | return this.pm; 21 | } 22 | 23 | @Override 24 | public HandlerList getHandlers() { 25 | return HANDLERS; 26 | } 27 | 28 | public static HandlerList getHandlerList() { 29 | return HANDLERS; 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/event/mail/MailBoxPersonMailSendEvent.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.event.mail; 2 | 3 | import com.tripleying.dogend.mailbox.api.mail.PersonMail; 4 | import org.bukkit.event.HandlerList; 5 | 6 | /** 7 | * 邮箱个人邮件发送事件 8 | * @author Dogend 9 | */ 10 | public class MailBoxPersonMailSendEvent extends MailBoxPersonMailEvent { 11 | 12 | private static final HandlerList HANDLERS = new HandlerList(); 13 | private final PersonMail pm; 14 | 15 | public MailBoxPersonMailSendEvent(PersonMail pm){ 16 | this.pm = pm; 17 | } 18 | 19 | public PersonMail getPersonMail(){ 20 | return this.pm; 21 | } 22 | 23 | @Override 24 | public HandlerList getHandlers() { 25 | return HANDLERS; 26 | } 27 | 28 | public static HandlerList getHandlerList() { 29 | return HANDLERS; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/event/mail/MailBoxSystemMailDeleteEvent.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.event.mail; 2 | 3 | import com.tripleying.dogend.mailbox.api.mail.SystemMail; 4 | import org.bukkit.event.HandlerList; 5 | 6 | /** 7 | * 邮箱系统邮件删除事件 8 | * @author Dogend 9 | */ 10 | public class MailBoxSystemMailDeleteEvent extends MailBoxSystemMailEvent { 11 | 12 | private static final HandlerList HANDLERS = new HandlerList(); 13 | private final SystemMail sm; 14 | 15 | public MailBoxSystemMailDeleteEvent(SystemMail sm){ 16 | this.sm = sm; 17 | } 18 | 19 | public SystemMail getSystemMail(){ 20 | return this.sm; 21 | } 22 | 23 | @Override 24 | public HandlerList getHandlers() { 25 | return HANDLERS; 26 | } 27 | 28 | public static HandlerList getHandlerList() { 29 | return HANDLERS; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/event/mail/MailBoxSystemMailEvent.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.event.mail; 2 | 3 | /** 4 | * 邮箱系统邮件事件 5 | * @author Dogend 6 | */ 7 | public abstract class MailBoxSystemMailEvent extends MailBoxMailEvent {} 8 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/event/mail/MailBoxSystemMailSendEvent.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.event.mail; 2 | 3 | import com.tripleying.dogend.mailbox.api.mail.SystemMail; 4 | import org.bukkit.event.HandlerList; 5 | 6 | /** 7 | * 邮箱系统邮件发送事件 8 | * @author Dogend 9 | */ 10 | public class MailBoxSystemMailSendEvent extends MailBoxSystemMailEvent { 11 | 12 | private static final HandlerList HANDLERS = new HandlerList(); 13 | private final SystemMail sm; 14 | 15 | public MailBoxSystemMailSendEvent(SystemMail sm){ 16 | this.sm = sm; 17 | } 18 | 19 | public SystemMail getSystemMail(){ 20 | return this.sm; 21 | } 22 | 23 | @Override 24 | public HandlerList getHandlers() { 25 | return HANDLERS; 26 | } 27 | 28 | public static HandlerList getHandlerList() { 29 | return HANDLERS; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/event/module/MailBoxModuleEvent.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.event.module; 2 | 3 | import com.tripleying.dogend.mailbox.api.event.MailBoxEvent; 4 | 5 | /** 6 | * 邮箱模块事件 7 | * @author Dogend 8 | */ 9 | public abstract class MailBoxModuleEvent extends MailBoxEvent {} -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/event/module/MailBoxModuleLoadEvent.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.event.module; 2 | 3 | import com.tripleying.dogend.mailbox.api.module.MailBoxModule; 4 | import org.bukkit.event.HandlerList; 5 | 6 | /** 7 | * 邮箱模块加载事件 8 | * @author Dogend 9 | */ 10 | public class MailBoxModuleLoadEvent extends MailBoxModuleEvent { 11 | 12 | private static final HandlerList HANDLERS = new HandlerList(); 13 | // 触发事件的模块 14 | private final MailBoxModule module; 15 | 16 | public MailBoxModuleLoadEvent(MailBoxModule module){ 17 | this.module = module; 18 | } 19 | 20 | public MailBoxModule getModule(){ 21 | return this.module; 22 | } 23 | 24 | @Override 25 | public HandlerList getHandlers() { 26 | return HANDLERS; 27 | } 28 | 29 | public static HandlerList getHandlerList() { 30 | return HANDLERS; 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/event/module/MailBoxModuleUnloadEvent.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.event.module; 2 | 3 | import com.tripleying.dogend.mailbox.api.module.MailBoxModule; 4 | import org.bukkit.event.HandlerList; 5 | 6 | /** 7 | * 模块卸载事件 8 | * @author Dogend 9 | */ 10 | public class MailBoxModuleUnloadEvent extends MailBoxModuleEvent { 11 | 12 | private static final HandlerList HANDLERS = new HandlerList(); 13 | // 触发事件的模块 14 | private final MailBoxModule module; 15 | 16 | public MailBoxModuleUnloadEvent(MailBoxModule module){ 17 | this.module = module; 18 | } 19 | 20 | public MailBoxModule getModule(){ 21 | return this.module; 22 | } 23 | 24 | @Override 25 | public HandlerList getHandlers() { 26 | return HANDLERS; 27 | } 28 | 29 | public static HandlerList getHandlerList() { 30 | return HANDLERS; 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/mail/BaseMail.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.mail; 2 | 3 | import com.tripleying.dogend.mailbox.api.mail.attach.AttachFile; 4 | import com.tripleying.dogend.mailbox.manager.MailManager; 5 | import java.util.ArrayList; 6 | import java.util.Arrays; 7 | import java.util.List; 8 | import java.util.Objects; 9 | import org.bukkit.configuration.file.YamlConfiguration; 10 | 11 | /** 12 | * 基础邮件父类 13 | * 不要继承此类进行附属开发 14 | * @author Dogend 15 | */ 16 | public abstract class BaseMail { 17 | 18 | /** 19 | * 邮件id 20 | */ 21 | protected long id; 22 | 23 | /** 24 | * 邮件类型 25 | */ 26 | protected String type; 27 | 28 | /** 29 | * 邮件类型显示名称 30 | */ 31 | protected String display; 32 | 33 | /** 34 | * 邮件标题 35 | */ 36 | protected String title; 37 | 38 | /** 39 | * 邮件内容 40 | */ 41 | protected List body; 42 | 43 | /** 44 | * 发送人 45 | */ 46 | protected String sender; 47 | 48 | /** 49 | * 发送时间 50 | */ 51 | protected String sendtime; 52 | 53 | /** 54 | * 邮件附件 55 | */ 56 | protected AttachFile attach; 57 | 58 | /** 59 | * 创建一封初始的新邮件 60 | * @param type 邮件类型 61 | * @param display 显示名称 62 | */ 63 | public BaseMail(String type, String display){ 64 | this.id = 0; 65 | this.type = type; 66 | this.display = display; 67 | this.title = "无"; 68 | this.body = new ArrayList(); 69 | this.sender = "无"; 70 | this.sendtime = "2021-01-01 08:00:00"; 71 | this.attach = new AttachFile(); 72 | } 73 | 74 | /** 75 | * 创建一封完整参数的邮件 76 | * @param id 邮件id 77 | * @param title 邮件标题 78 | * @param type 邮件类型 79 | * @param display 展示名称 80 | * @param body 邮件内容 81 | * @param sender 发送人 82 | * @param sendtime 发送时间 83 | * @param attach 邮件附件 84 | */ 85 | public BaseMail(long id, String title, String type, String display, List body, String sender, String sendtime, AttachFile attach){ 86 | this.id = id; 87 | this.title = title; 88 | this.type = type; 89 | this.display = display; 90 | this.body = body==null?new ArrayList():body; 91 | this.sender = sender; 92 | this.sendtime = sendtime; 93 | this.attach = attach==null?new AttachFile():attach; 94 | } 95 | 96 | /** 97 | * 从yml恢复一封邮件 98 | * @param yml YamlConfiguration 99 | */ 100 | public BaseMail(YamlConfiguration yml){ 101 | this.id = yml.getLong("id"); 102 | this.title = yml.getString("title"); 103 | this.type = yml.getString("type"); 104 | this.display = MailManager.getMailManager().getSystemMailDisplay(type); 105 | this.body = yml.getStringList("body"); 106 | this.sender = yml.getString("sender"); 107 | this.sendtime = yml.getString("sendtime"); 108 | this.attach = (AttachFile)yml.get("attach"); 109 | } 110 | 111 | public long getId() { 112 | return id; 113 | } 114 | 115 | public BaseMail setId(long id) { 116 | this.id = id; 117 | return this; 118 | } 119 | 120 | public String getType(){ 121 | return this.type; 122 | } 123 | 124 | public BaseMail setType(String type) { 125 | this.type = type; 126 | this.display = MailManager.getMailManager().getSystemMailDisplay(type); 127 | if(this instanceof SystemMail){ 128 | return MailManager.getMailManager().loadSystemMail(this.toYamlConfiguration()); 129 | }else{ 130 | return this; 131 | } 132 | 133 | } 134 | 135 | public String getDisplay(){ 136 | return this.display; 137 | } 138 | 139 | public String getTitle() { 140 | return title; 141 | } 142 | 143 | public BaseMail setTitle(String title) { 144 | this.title = title; 145 | return this; 146 | } 147 | 148 | public List getBody() { 149 | return body; 150 | } 151 | 152 | public BaseMail setBody(List body) { 153 | this.body = body; 154 | return this; 155 | } 156 | 157 | public BaseMail addBody(String... strs){ 158 | this.body.addAll(Arrays.asList(strs)); 159 | return this; 160 | } 161 | 162 | public String getSender() { 163 | return sender; 164 | } 165 | 166 | public BaseMail setSender(String sender){ 167 | this.sender = sender; 168 | return this; 169 | } 170 | 171 | public String getSendtime() { 172 | return sendtime; 173 | } 174 | 175 | public BaseMail setSendtime(String sendtime) { 176 | this.sendtime = sendtime; 177 | return this; 178 | } 179 | 180 | public AttachFile getAttachFile(){ 181 | return this.attach; 182 | } 183 | 184 | public BaseMail setAttachFile(AttachFile attach) { 185 | this.attach = attach; 186 | return this; 187 | } 188 | 189 | /** 190 | * 邮件是否过期 191 | * 过期自动删除 192 | * @return boolean 193 | */ 194 | public abstract boolean isExpire(); 195 | 196 | @Override 197 | public boolean equals(Object o){ 198 | if(this == o) return true; 199 | if(o!=null && o instanceof BaseMail){ 200 | final BaseMail bm =(BaseMail)o; 201 | return (this.id==bm.id && this.type.equals(bm.type) && this.title.equals(bm.title) && this.sender.equals(bm.sender) && this.sendtime.equals(bm.sendtime) && this.body.equals(bm.body) && this.attach.equals(bm.attach)); 202 | } 203 | return false; 204 | } 205 | 206 | @Override 207 | public int hashCode() { 208 | int hash = 5; 209 | hash = 43 * hash + (int) (this.id ^ (this.id >>> 32)); 210 | hash = 43 * hash + Objects.hashCode(this.type); 211 | hash = 43 * hash + Objects.hashCode(this.title); 212 | hash = 43 * hash + Objects.hashCode(this.body); 213 | hash = 43 * hash + Objects.hashCode(this.sender); 214 | hash = 43 * hash + Objects.hashCode(this.sendtime); 215 | hash = 43 * hash + Objects.hashCode(this.attach); 216 | return hash; 217 | } 218 | 219 | @Override 220 | public String toString(){ 221 | StringBuilder sb = new StringBuilder(); 222 | sb.append("id: ").append(this.id).append('\n'); 223 | sb.append("type: ").append(this.type).append('\n'); 224 | sb.append("title: ").append(this.title).append('\n'); 225 | sb.append("body: ").append('\n'); 226 | this.body.forEach(s -> { 227 | sb.append("- ").append(s).append("\n"); 228 | }); 229 | sb.append("sender: ").append(this.type).append('\n'); 230 | sb.append("sendtime: ").append(this.type).append('\n'); 231 | sb.append(this.attach.toString()); 232 | return sb.toString(); 233 | } 234 | 235 | public YamlConfiguration toYamlConfiguration(){ 236 | YamlConfiguration yml = new YamlConfiguration(); 237 | yml.set("id", this.id); 238 | yml.set("type", this.type); 239 | yml.set("title", this.title); 240 | yml.set("body", this.body); 241 | yml.set("sender", this.sender); 242 | yml.set("sendtime", this.sendtime); 243 | yml.set("attach", this.attach); 244 | return yml; 245 | } 246 | 247 | } 248 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/mail/CustomData.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.mail; 2 | 3 | import com.tripleying.dogend.mailbox.manager.DataManager; 4 | import java.util.LinkedHashMap; 5 | import java.util.List; 6 | import org.bukkit.configuration.file.YamlConfiguration; 7 | 8 | /** 9 | * 自定义数据存储库 10 | * @since 3.1.0 11 | * @author Dogend 12 | */ 13 | public abstract class CustomData { 14 | 15 | /** 16 | * 数据存储库名 17 | */ 18 | private final String name; 19 | 20 | public CustomData(String name){ 21 | this.name = name; 22 | } 23 | 24 | public String getName() { 25 | return name; 26 | } 27 | 28 | /** 29 | * 创建存储库 30 | * (这一步建议监听模块加载完成事件) 31 | * @return boolean 32 | */ 33 | public boolean createStorage(){ 34 | return DataManager.getDataManager().createCustomStorage(this); 35 | } 36 | 37 | /** 38 | * 从yml加载一个CustomData 39 | * @param yml YamlConfiguratin 40 | * @return CustomData 41 | */ 42 | public abstract CustomData loadFromYamlConfiguration(YamlConfiguration yml); 43 | 44 | /** 45 | * 将自定义数据插入存储库 46 | * @return boolean 47 | */ 48 | public boolean insertCustomData(){ 49 | return DataManager.getDataManager().insertCustomData(this); 50 | } 51 | 52 | /** 53 | * 按主键将存储库的其他数据更新 54 | * @since 3.3.0 55 | * @return boolean 56 | */ 57 | public boolean updateCustomDataByPrimaryKey(){ 58 | return DataManager.getDataManager().updateCustomDataByPrimaryKey(this); 59 | } 60 | 61 | /** 62 | * 以特定条件获取自定义数据 63 | * @param args 条件 64 | * @return List 65 | */ 66 | public List selectCustomData(LinkedHashMap args){ 67 | return DataManager.getDataManager().selectCustomData(this, args); 68 | } 69 | 70 | /** 71 | * 以特定条件删除自定义数据 72 | * @param args 条件 73 | * @return long 74 | */ 75 | public long deleteCustomData(LinkedHashMap args){ 76 | return DataManager.getDataManager().deleteCustomData(this, args); 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/mail/PersonMail.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.mail; 2 | 3 | import com.tripleying.dogend.mailbox.api.event.mail.MailBoxPersonMailDeleteEvent; 4 | import com.tripleying.dogend.mailbox.api.event.mail.MailBoxPersonMailPreSendEvent; 5 | import com.tripleying.dogend.mailbox.api.event.mail.MailBoxPersonMailReceiveEvent; 6 | import com.tripleying.dogend.mailbox.api.event.mail.MailBoxPersonMailSendEvent; 7 | import com.tripleying.dogend.mailbox.manager.MailManager; 8 | import com.tripleying.dogend.mailbox.util.TimeUtil; 9 | import java.util.Objects; 10 | import java.util.UUID; 11 | import org.bukkit.Bukkit; 12 | import org.bukkit.configuration.file.YamlConfiguration; 13 | import org.bukkit.entity.Player; 14 | 15 | /** 16 | * 个人邮件 17 | * 直接玩家收件箱的邮件 18 | * @author Dogend 19 | */ 20 | public final class PersonMail extends BaseMail { 21 | 22 | /** 23 | * 是否已接收附件 24 | */ 25 | protected boolean received; 26 | /** 27 | * 收件人 28 | */ 29 | protected String uuid; 30 | 31 | /** 32 | * 将一封SystemMail转换为PersonMail 33 | * @param sm 系统邮件 34 | */ 35 | public PersonMail(SystemMail sm){ 36 | super(sm.toYamlConfiguration()); 37 | this.received = false; 38 | } 39 | 40 | /** 41 | * 从yml恢复一封邮件 42 | * @param yml YamlConfiguration 43 | */ 44 | public PersonMail(YamlConfiguration yml){ 45 | super(yml); 46 | this.received = yml.getBoolean("received"); 47 | this.uuid = yml.getString("uuid"); 48 | } 49 | 50 | /** 51 | * 设置接收者 52 | * @param p 玩家 53 | * @return this 54 | */ 55 | public PersonMail setReceiver(Player p){ 56 | this.uuid = p.getUniqueId().toString(); 57 | return this; 58 | } 59 | 60 | /** 61 | * 是否已读/接收附件 62 | * @return boolean 63 | */ 64 | public boolean isReceived(){ 65 | return this.received; 66 | } 67 | 68 | /** 69 | * 获取UUID 70 | * @return String 71 | */ 72 | public String getUUID() { 73 | return uuid; 74 | } 75 | 76 | /** 77 | * 获取接收人 78 | * @return Player 79 | */ 80 | public Player getReceiver(){ 81 | return Bukkit.getPlayer(UUID.fromString(this.uuid)); 82 | } 83 | 84 | /** 85 | * 判断邮件是否过期 86 | * @return boolean 87 | */ 88 | @Override 89 | public boolean isExpire(){ 90 | return TimeUtil.isExpire(this.sendtime); 91 | } 92 | 93 | /** 94 | * 发送邮件 95 | * @return boolean 96 | */ 97 | public boolean sendMail(){ 98 | Player p = Bukkit.getPlayer(UUID.fromString(this.uuid)); 99 | if(p!=null){ 100 | MailBoxPersonMailPreSendEvent evt = new MailBoxPersonMailPreSendEvent(this); 101 | Bukkit.getPluginManager().callEvent(evt); 102 | if(evt.isCancelled()) return false; 103 | if(MailManager.getMailManager().sendPersonMail(this, p)){ 104 | Bukkit.getPluginManager().callEvent(new MailBoxPersonMailSendEvent(this)); 105 | return true; 106 | } 107 | } 108 | return false; 109 | } 110 | 111 | /** 112 | * 玩家查看邮件 113 | * 如果没有附件则设置为已领取 114 | * 如果领取状态改变则返回true 115 | * @return boolean 116 | */ 117 | public boolean seeMail(){ 118 | return (!this.isReceived() && !this.getAttachFile().hasAttach() && this.receivedMail()); 119 | } 120 | 121 | /** 122 | * 已读/领取邮件 123 | * @return boolean 124 | */ 125 | public boolean receivedMail(){ 126 | Player p = Bukkit.getPlayer(UUID.fromString(this.uuid)); 127 | if(p!=null && this.getAttachFile().checkInventory(p) && MailManager.getMailManager().receivePersonMail(this, p)){ 128 | this.getAttachFile().receivedAttach(p); 129 | this.received = true; 130 | Bukkit.getPluginManager().callEvent(new MailBoxPersonMailReceiveEvent(this)); 131 | return true; 132 | } 133 | return false; 134 | } 135 | 136 | /** 137 | * 删除邮件 138 | */ 139 | public void deleteMail(){ 140 | if(MailManager.getMailManager().deletePersonMail(this)){ 141 | Bukkit.getPluginManager().callEvent(new MailBoxPersonMailDeleteEvent(this)); 142 | } 143 | } 144 | 145 | @Override 146 | public boolean equals(Object o){ 147 | if(this == o) return true; 148 | if(o!=null && o instanceof PersonMail && super.equals(o)){ 149 | PersonMail pm =(PersonMail)o; 150 | return (this.received==pm.received && this.uuid.equals(pm.uuid)); 151 | } 152 | return false; 153 | } 154 | 155 | @Override 156 | public int hashCode() { 157 | int hash = super.hashCode(); 158 | hash = 83 * hash + (this.received ? 1 : 0); 159 | hash = 83 * hash + Objects.hashCode(this.uuid); 160 | return hash; 161 | } 162 | 163 | @Override 164 | public String toString(){ 165 | StringBuilder sb = new StringBuilder(); 166 | sb.append("uuid: ").append(this.uuid).append('\n'); 167 | sb.append("received: ").append(this.received).append('\n'); 168 | sb.append(super.toString()); 169 | return sb.toString(); 170 | } 171 | 172 | @Override 173 | public YamlConfiguration toYamlConfiguration(){ 174 | YamlConfiguration yml = super.toYamlConfiguration(); 175 | yml.set("uuid", this.uuid); 176 | yml.set("received", this.received); 177 | return yml; 178 | } 179 | 180 | } 181 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/mail/PlayerData.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.mail; 2 | 3 | import com.tripleying.dogend.mailbox.MailBox; 4 | import java.util.LinkedHashMap; 5 | import java.util.Map; 6 | import java.util.Map.Entry; 7 | import java.util.UUID; 8 | import org.bukkit.Bukkit; 9 | import org.bukkit.configuration.ConfigurationSection; 10 | import org.bukkit.configuration.file.YamlConfiguration; 11 | import org.bukkit.entity.Player; 12 | 13 | /** 14 | * 玩家数据 15 | * @author Dogend 16 | */ 17 | public class PlayerData { 18 | 19 | /** 20 | * 玩家名 21 | */ 22 | private final String name; 23 | /** 24 | * 玩家UUID 25 | */ 26 | private final UUID uuid; 27 | /** 28 | * 数据 29 | */ 30 | private final Map data; 31 | 32 | public PlayerData(Player player){ 33 | this.name = player.getName(); 34 | this.uuid = player.getUniqueId(); 35 | this.data = new LinkedHashMap(); 36 | } 37 | 38 | public PlayerData(Player player, Map data){ 39 | this.name = player.getName(); 40 | this.uuid = player.getUniqueId(); 41 | this.data = data; 42 | } 43 | 44 | public PlayerData(YamlConfiguration yml){ 45 | this.name = yml.getString("name"); 46 | this.uuid = UUID.fromString(yml.getString("uuid")); 47 | this.data = new LinkedHashMap(); 48 | ConfigurationSection data = yml.getConfigurationSection("data"); 49 | for(String key:data.getKeys(false)){ 50 | this.data.put(key, data.get(key)); 51 | } 52 | } 53 | 54 | /** 55 | * 获取玩家名 56 | * @return String 57 | */ 58 | public String getName(){ 59 | return this.name; 60 | } 61 | 62 | /** 63 | * 获取玩家UUID 64 | * @return UUID 65 | */ 66 | public UUID getUUID(){ 67 | return this.uuid; 68 | } 69 | 70 | /** 71 | * 获取玩家 72 | * @return Player 73 | */ 74 | public Player getPlayer(){ 75 | return Bukkit.getPlayer(this.uuid); 76 | } 77 | 78 | /** 79 | * 获取全部数据 80 | * @return Map 81 | */ 82 | public Map getData(){ 83 | return this.data; 84 | } 85 | 86 | /** 87 | * 设置数据 88 | * @param type 系统邮件类型 89 | * @param value 数据值 90 | */ 91 | public void setData(String type, Object value){ 92 | this.data.put(type, value); 93 | } 94 | 95 | /** 96 | * 获取数据 97 | * 若不存在返回null 98 | * @param type 系统邮件类型 99 | * @return null 100 | */ 101 | public Object getData(String type){ 102 | if(this.data.containsKey(type)){ 103 | return this.data.get(type); 104 | }else{ 105 | return null; 106 | } 107 | } 108 | 109 | /** 110 | * 保存数据 111 | * @return boolean 112 | */ 113 | public boolean saveData(){ 114 | return MailBox.getMailBox().getDataManager().getData().updatePlayerData(this); 115 | } 116 | 117 | public YamlConfiguration toYamlConfiguration(){ 118 | YamlConfiguration yml = new YamlConfiguration(); 119 | yml.set("name", this.name); 120 | yml.set("uuid", this.uuid.toString()); 121 | YamlConfiguration dyml = new YamlConfiguration(); 122 | for(Entry entry:this.data.entrySet()){ 123 | dyml.set(entry.getKey(), entry.getValue()); 124 | } 125 | yml.set("data", dyml); 126 | return yml; 127 | } 128 | 129 | } 130 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/mail/SystemMail.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.mail; 2 | 3 | import com.tripleying.dogend.mailbox.api.event.mail.MailBoxPersonMailPreSendEvent; 4 | import com.tripleying.dogend.mailbox.api.event.mail.MailBoxPersonMailSendEvent; 5 | import com.tripleying.dogend.mailbox.api.event.mail.MailBoxSystemMailDeleteEvent; 6 | import com.tripleying.dogend.mailbox.api.event.mail.MailBoxSystemMailSendEvent; 7 | import com.tripleying.dogend.mailbox.manager.MailManager; 8 | import java.util.Iterator; 9 | import java.util.Map; 10 | import org.bukkit.Bukkit; 11 | import org.bukkit.command.CommandSender; 12 | import org.bukkit.configuration.file.YamlConfiguration; 13 | import org.bukkit.entity.Player; 14 | 15 | /** 16 | * 系统邮件 17 | * 当玩家登陆时, 判断条件将此邮件则以个人邮件形式发送给玩家 18 | * @author Dogend 19 | */ 20 | public abstract class SystemMail extends BaseMail { 21 | 22 | public SystemMail(String type, String display) { 23 | super(type, display); 24 | } 25 | 26 | public SystemMail(YamlConfiguration yml) { 27 | super(yml); 28 | } 29 | 30 | /** 31 | * 创建一个新的系统邮件实例 32 | * @return SystemMail 33 | */ 34 | public abstract SystemMail createSystemMail(); 35 | 36 | /** 37 | * 从yml加载一个系统邮件实例 38 | * @param yml YamlConfiguration 39 | * @return SystemMail 40 | */ 41 | public abstract SystemMail loadSystemMail(YamlConfiguration yml); 42 | 43 | /** 44 | * 对比玩家数据并给玩家发送邮件 45 | * @param pd 玩家数据 46 | */ 47 | public abstract void checkPlayerData(PlayerData pd); 48 | 49 | /** 50 | * 通过邮件ID自增值对比玩家数据并给玩家发送邮件 51 | * @param pd 玩家数据 52 | */ 53 | protected void checkPlayerDataByMaxId(PlayerData pd){ 54 | Player p = pd.getPlayer(); 55 | if(p==null) return; 56 | Object d = pd.getData(this.type); 57 | long now = d==null?0:Long.parseLong(d.toString()); 58 | long max = MailManager.getMailManager().getSystemMailMax(this); 59 | if(now smap = MailManager.getMailManager().getSystemMail(this, now, max); 62 | Iterator> it = smap.entrySet().iterator(); 63 | while(it.hasNext()){ 64 | Map.Entry me = it.next(); 65 | SystemMail sm = me.getValue(); 66 | if(sm.couldSend2Player(p) && sm.send2Player(p)){ 67 | now = me.getKey(); 68 | }else{ 69 | break; 70 | } 71 | } 72 | pd.setData(this.type, now); 73 | pd.saveData(); 74 | } 75 | } 76 | 77 | /** 78 | * 是否需要在玩家进入时对比玩家数据 79 | * @return boolean 80 | */ 81 | public abstract boolean needCheckPlayerData(); 82 | 83 | /** 84 | * 这封邮件是否能发送给此玩家 85 | * @param p 玩家 86 | * @return boolean 87 | */ 88 | public abstract boolean couldSend2Player(Player p); 89 | 90 | /** 91 | * 是否自动创建邮件数据表 92 | * @return boolean 93 | */ 94 | public abstract boolean autoCreateDatabaseTable(); 95 | 96 | /** 97 | * 这个人是否有权限发送此邮件 98 | * @param sender 控制台/玩家 99 | * @return boolean 100 | */ 101 | public abstract boolean couldSendMail(CommandSender sender); 102 | 103 | /** 104 | * 作为个人邮件发送给玩家 105 | * @param p 玩家 106 | * @return PersonMail 107 | */ 108 | public boolean send2Player(Player p){ 109 | PersonMail pm = new PersonMail(this); 110 | pm.setReceiver(p); 111 | MailBoxPersonMailPreSendEvent evt = new MailBoxPersonMailPreSendEvent(pm); 112 | Bukkit.getPluginManager().callEvent(evt); 113 | if(!evt.isCancelled() && MailManager.getMailManager().sendPersonMail(pm, p)){ 114 | Bukkit.getPluginManager().callEvent(new MailBoxPersonMailSendEvent(pm)); 115 | return true; 116 | } 117 | return false; 118 | } 119 | 120 | /** 121 | * 发送邮件 122 | * @since 3.0.1 123 | * @return SystemMail 124 | */ 125 | public SystemMail sendMail(){ 126 | SystemMail sm = MailManager.getMailManager().sendSystemMail(this); 127 | if(sm.getId()!=0){ 128 | Bukkit.getPluginManager().callEvent(new MailBoxSystemMailSendEvent(sm)); 129 | } 130 | return sm; 131 | } 132 | 133 | /** 134 | * 删除邮件 135 | */ 136 | public void deleteMail(){ 137 | if(MailManager.getMailManager().deleteSystemMail(this)){ 138 | Bukkit.getPluginManager().callEvent(new MailBoxSystemMailDeleteEvent(this)); 139 | } 140 | } 141 | 142 | @Override 143 | public boolean equals(Object o){ 144 | if(this == o) return true; 145 | return (o!=null && o instanceof SystemMail && super.equals(o)); 146 | } 147 | 148 | @Override 149 | public int hashCode() { 150 | return super.hashCode(); 151 | } 152 | 153 | @Override 154 | public String toString(){ 155 | return super.toString(); 156 | } 157 | 158 | @Override 159 | public YamlConfiguration toYamlConfiguration(){ 160 | return super.toYamlConfiguration(); 161 | } 162 | 163 | } 164 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/mail/attach/AttachCommand.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.mail.attach; 2 | 3 | import java.util.LinkedHashMap; 4 | import java.util.LinkedList; 5 | import java.util.List; 6 | import java.util.Map; 7 | import org.bukkit.Bukkit; 8 | import org.bukkit.Server; 9 | import org.bukkit.command.CommandSender; 10 | import org.bukkit.configuration.serialization.ConfigurationSerializable; 11 | import org.bukkit.entity.Player; 12 | 13 | /** 14 | * 附件指令 15 | * @author Dogend 16 | */ 17 | public class AttachCommand implements ConfigurationSerializable { 18 | 19 | private final List console; 20 | private final List player; 21 | private final List op; 22 | 23 | public AttachCommand(){ 24 | this.console = new LinkedList(); 25 | this.player = new LinkedList(); 26 | this.op = new LinkedList(); 27 | } 28 | 29 | /** 30 | * 是否有任何指令 31 | * @return boolean 32 | */ 33 | public boolean hasCommand(){ 34 | return !this.console.isEmpty() || !this.player.isEmpty() || !this.op.isEmpty(); 35 | } 36 | 37 | /** 38 | * 添加控制台指令 39 | * @param cmd 指令 40 | */ 41 | public void addConsoleCommand(String cmd){ 42 | this.console.add(cmd); 43 | } 44 | 45 | /** 46 | * 清空控制台指令 47 | */ 48 | public void clearConsoleCommand(){ 49 | this.console.clear(); 50 | } 51 | 52 | /** 53 | * 添加玩家指令 54 | * @param cmd 指令 55 | */ 56 | public void addPlayerCommand(String cmd){ 57 | this.player.add(cmd); 58 | } 59 | 60 | /** 61 | * 清空玩家指令 62 | */ 63 | public void clearPlayerCommand(){ 64 | this.player.clear(); 65 | } 66 | 67 | /** 68 | * 添加OP指令 69 | * @param cmd 指令 70 | */ 71 | public void addOPCommand(String cmd){ 72 | this.op.add(cmd); 73 | } 74 | 75 | /** 76 | * 清空OP指令 77 | */ 78 | public void clearOPCommand(){ 79 | this.op.clear(); 80 | } 81 | 82 | /** 83 | * 获取控制台指令 84 | * @return List 85 | */ 86 | public List getConsole() { 87 | return this.console; 88 | } 89 | 90 | /** 91 | * 获取玩家指令 92 | * @return List 93 | */ 94 | public List getPlayer() { 95 | return this.player; 96 | } 97 | 98 | /** 99 | * 获取OP指令 100 | * @return List 101 | */ 102 | public List getOp() { 103 | return this.op; 104 | } 105 | 106 | /** 107 | * 执行指令 108 | * @param p 玩家 109 | */ 110 | public void doCommand(Player p){ 111 | if(!this.hasCommand()) return; 112 | this.doConsoleCommand(p); 113 | this.doPlayerCommand(p); 114 | this.doOPCommand(p); 115 | } 116 | 117 | /** 118 | * 执行控制台指令 119 | * @param p Player 120 | */ 121 | public void doConsoleCommand(Player p){ 122 | if(this.console.isEmpty()) return; 123 | String name = p.getName(); 124 | Server server = Bukkit.getServer(); 125 | CommandSender cs = Bukkit.getConsoleSender(); 126 | this.console.forEach(cc -> server.dispatchCommand(cs, cc.replace("%player%", name))); 127 | 128 | } 129 | 130 | /** 131 | * 执行普通玩家指令 132 | * @param p 玩家 133 | */ 134 | public void doPlayerCommand(Player p){ 135 | if(this.player.isEmpty()) return; 136 | String name = p.getName(); 137 | Server server = Bukkit.getServer(); 138 | this.player.forEach(pc -> server.dispatchCommand(p, pc.replace("%player%", name))); 139 | } 140 | 141 | /** 142 | * 以OP身份执行玩家指令 143 | * @param p 玩家 144 | */ 145 | public void doOPCommand(Player p){ 146 | if(this.op.isEmpty()) return; 147 | // boolean isOp = p.isOp(); 148 | // try{ 149 | // p.setOp(true); 150 | // this.op.forEach(oc -> p.performCommand(oc.replace("%player%", p.getName()))); 151 | // }finally { 152 | // p.setOp(isOp); 153 | // } 154 | String name = p.getName(); 155 | Server server = Bukkit.getServer(); 156 | CommandSender cs = ProxyPlayer.getProxyPlayer(p); 157 | System.out.println(cs.isOp()); 158 | this.op.forEach(oc -> server.dispatchCommand(cs, oc.replace("%player%", name))); 159 | } 160 | 161 | /** 162 | * 获取全部指令 163 | * @return Map 164 | */ 165 | public Map> getCommand(){ 166 | Map> map = new LinkedHashMap(); 167 | map.put("console", this.console); 168 | map.put("player", this.player); 169 | map.put("op", this.op); 170 | return map; 171 | } 172 | 173 | /** 174 | * 配置文件序列化 175 | * @return Map 176 | */ 177 | @Override 178 | public Map serialize() { 179 | Map cmd = new LinkedHashMap(); 180 | if(!this.console.isEmpty()){ 181 | cmd.put("console", this.console); 182 | } 183 | if(!this.player.isEmpty()){ 184 | cmd.put("player", this.player); 185 | } 186 | if(!this.op.isEmpty()){ 187 | cmd.put("op", this.op); 188 | } 189 | return cmd; 190 | } 191 | 192 | /** 193 | * 配置文件反序列化 194 | * @param map Map 195 | * @return AttachCommand 196 | */ 197 | public static AttachCommand deserialize(Map map){ 198 | AttachCommand cmd = new AttachCommand(); 199 | if(map.containsKey("console")){ 200 | List list = (List)map.get("console"); 201 | list.forEach(cc -> cmd.addConsoleCommand(cc)); 202 | } 203 | if(map.containsKey("player")){ 204 | List list = (List)map.get("player"); 205 | list.forEach(pc -> cmd.addPlayerCommand(pc)); 206 | } 207 | if(map.containsKey("op")){ 208 | List list = (List)map.get("op"); 209 | list.forEach(oc -> cmd.addOPCommand(oc)); 210 | } 211 | return cmd; 212 | } 213 | 214 | } 215 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/mail/attach/AttachDoubleMoney.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.mail.attach; 2 | 3 | /** 4 | * 小数附件金钱 5 | * @author Dogend 6 | */ 7 | public class AttachDoubleMoney implements AttachMoney { 8 | 9 | private double count; 10 | 11 | public AttachDoubleMoney(){ 12 | this.count = 0.0; 13 | } 14 | 15 | public AttachDoubleMoney(double count){ 16 | this.count = count; 17 | } 18 | 19 | @Override 20 | public Object getCount() { 21 | return this.count; 22 | } 23 | 24 | @Override 25 | public boolean addCount(Object o) { 26 | if(o instanceof Double && (double)o>=0.0){ 27 | count += (double)o; 28 | return true; 29 | }else{ 30 | return false; 31 | } 32 | } 33 | 34 | @Override 35 | public boolean removeCount(Object o) { 36 | if(o instanceof Double && (double)o>=0.0){ 37 | if(count-(double)o<0.0){ 38 | return false; 39 | }else{ 40 | count -= (double)o; 41 | return true; 42 | } 43 | }else{ 44 | return false; 45 | } 46 | } 47 | 48 | @Override 49 | public boolean isZero() { 50 | return count==0.0; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/mail/attach/AttachFile.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.mail.attach; 2 | 3 | import com.tripleying.dogend.mailbox.MailBox; 4 | import com.tripleying.dogend.mailbox.manager.MoneyManager; 5 | import com.tripleying.dogend.mailbox.util.ItemStackUtil; 6 | import java.util.ArrayList; 7 | import java.util.HashMap; 8 | import java.util.LinkedHashMap; 9 | import java.util.List; 10 | import java.util.Map; 11 | import org.bukkit.configuration.serialization.ConfigurationSerializable; 12 | import org.bukkit.entity.Player; 13 | import org.bukkit.inventory.ItemStack; 14 | 15 | /** 16 | * 邮件附件 17 | * @author Dogend 18 | */ 19 | public class AttachFile implements ConfigurationSerializable { 20 | 21 | /** 22 | * 金钱附件 23 | */ 24 | private final Map moneys; 25 | /** 26 | * 物品附件 27 | */ 28 | private final List items; 29 | /** 30 | * 指令附件 31 | */ 32 | private AttachCommand cmds; 33 | 34 | /** 35 | * 创建一个新的附件 36 | */ 37 | public AttachFile(){ 38 | this.moneys = new HashMap(); 39 | this.items = new ArrayList(); 40 | this.cmds = new AttachCommand(); 41 | } 42 | 43 | /** 44 | * 添加金钱附件 45 | * @param name 金钱 46 | * @param count 数量 47 | * @return boolean 48 | */ 49 | public boolean addMoney(String name, Object count){ 50 | AttachMoney am; 51 | if(this.moneys.containsKey(name)){ 52 | am = this.moneys.get(name); 53 | }else{ 54 | am = MailBox.getMailBox().getMoneyManager().getAttachMoney(name); 55 | this.moneys.put(name, am); 56 | } 57 | return am.addCount(count); 58 | } 59 | 60 | /** 61 | * 减少金钱附件 62 | * @param name 金钱 63 | * @param count 数量 64 | * @return boolean 65 | */ 66 | public boolean removeMoney(String name, Object count){ 67 | if(this.moneys.containsKey(name)){ 68 | AttachMoney am = this.moneys.get(name); 69 | boolean bl = am.removeCount(count); 70 | if(am.isZero()){ 71 | this.moneys.remove(name); 72 | } 73 | return bl; 74 | } 75 | return false; 76 | } 77 | 78 | /** 79 | * 移除金钱附件 80 | * @param name 金钱 81 | */ 82 | public void removeMoney(String name){ 83 | if(this.moneys.containsKey(name)) this.moneys.remove(name); 84 | } 85 | 86 | /** 87 | * 移除全部金钱附件 88 | */ 89 | public void removeAllMoney(){ 90 | this.moneys.clear(); 91 | } 92 | 93 | /** 94 | * 添加物品 95 | * @param iss ItemStack 96 | */ 97 | public void addItemStack(ItemStack... iss){ 98 | for(ItemStack is:iss){ 99 | if(is!=null) this.items.add(is); 100 | } 101 | } 102 | 103 | /** 104 | * 移除所有物品 105 | */ 106 | public void removeAllItemStack(){ 107 | this.items.clear(); 108 | } 109 | 110 | /** 111 | * 是否存在任何附件 112 | * @return boolean 113 | */ 114 | public boolean hasAttach(){ 115 | return !this.moneys.isEmpty() || !this.items.isEmpty() || this.cmds.hasCommand(); 116 | } 117 | 118 | /** 119 | * 获取指令 120 | * @return AttachCommand 121 | */ 122 | public AttachCommand getCommands() { 123 | return this.cmds; 124 | } 125 | 126 | /** 127 | * 获取金钱 128 | * @return Map 129 | */ 130 | public Map getMoneys() { 131 | return this.moneys; 132 | } 133 | 134 | /** 135 | * 获取物品 136 | * @return List 137 | */ 138 | public List getItemStacks() { 139 | return this.items; 140 | } 141 | 142 | /** 143 | * 判断玩家背包是否有足够位置放下物品堆 144 | * @param p 玩家 145 | * @return boolean 146 | */ 147 | public boolean checkInventory(Player p){ 148 | return this.items.isEmpty()?true:ItemStackUtil.hasBlank(p, this.items)==0; 149 | } 150 | 151 | /** 152 | * 使玩家领取附件 153 | * @param p 玩家 154 | */ 155 | public void receivedAttach(Player p){ 156 | if(!this.hasAttach()) return; 157 | this.receivedMoney(p); 158 | this.receivedItem(p); 159 | this.receivedCommand(p); 160 | } 161 | 162 | /** 163 | * 使玩家领取金钱 164 | * @param p 玩家 165 | */ 166 | public void receivedMoney(Player p){ 167 | this.moneys.forEach((n,m) -> { 168 | if(!m.isZero()){ 169 | MoneyManager.getMoneyManager().addBalance(p, n, m.getCount()); 170 | } 171 | }); 172 | } 173 | 174 | /** 175 | * 使玩家领取物品 176 | * @param p 玩家 177 | */ 178 | public void receivedItem(Player p){ 179 | if(!this.items.isEmpty()){ 180 | ItemStack[] iss = new ItemStack[this.items.size()]; 181 | int i=0; 182 | for(ItemStack is:this.items){ 183 | iss[i++] = is; 184 | } 185 | p.getInventory().addItem(iss); 186 | } 187 | } 188 | 189 | /** 190 | * 使玩家领取指令 191 | * @param p 玩家 192 | */ 193 | public void receivedCommand(Player p){ 194 | this.cmds.doCommand(p); 195 | } 196 | 197 | /** 198 | * 配置文件序列化 199 | * @return Map 200 | */ 201 | @Override 202 | public Map serialize() { 203 | Map attach = new LinkedHashMap(); 204 | if(!this.moneys.isEmpty()){ 205 | Map mmap = new HashMap(); 206 | this.moneys.forEach((k,v) -> { 207 | if(!v.isZero()) mmap.put(k, v.getCount()); 208 | }); 209 | attach.put("money", mmap); 210 | } 211 | if(!this.items.isEmpty()){ 212 | Map item = new HashMap(); 213 | int i = 1; 214 | for(ItemStack is:this.items){ 215 | item.put(Integer.toString(i++), is); 216 | } 217 | attach.put("item", item); 218 | } 219 | if(this.cmds.hasCommand()){ 220 | attach.put("command", this.cmds); 221 | } 222 | return attach; 223 | } 224 | 225 | /** 226 | * 配置文件反序列化 227 | * @param map Map 228 | * @return AttachFile 229 | */ 230 | public static AttachFile deserialize(Map map){ 231 | AttachFile attach = new AttachFile(); 232 | if(map.containsKey("money")){ 233 | Map money = (Map)map.get("money"); 234 | money.forEach((k,v) -> attach.addMoney(k, v)); 235 | } 236 | if(map.containsKey("item")){ 237 | Map item = (Map)map.get("item"); 238 | item.forEach((k,v) -> attach.addItemStack((ItemStack)v)); 239 | } 240 | if(map.containsKey("command")){ 241 | attach.cmds = (AttachCommand)map.get("command"); 242 | } 243 | return attach; 244 | } 245 | 246 | @Override 247 | public String toString(){ 248 | StringBuilder sb = new StringBuilder(); 249 | sb.append("attach: "); 250 | sb.append('\n').append("- money: "); 251 | this.moneys.forEach((k,v) -> sb.append('\n').append("-- ").append(k).append(": ").append(v.getCount())); 252 | sb.append('\n').append("- item: "); 253 | this.items.forEach(i -> sb.append('\n').append("-- ").append(i.getType().name()).append(": ").append(i.getAmount())); 254 | sb.append('\n').append("- command: "); 255 | this.cmds.getCommand().forEach((t,l) -> { 256 | sb.append('\n').append("-- ").append(t).append(": "); 257 | l.forEach(c -> sb.append('\n').append("--- ").append(c)); 258 | }); 259 | return sb.toString(); 260 | } 261 | 262 | } 263 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/mail/attach/AttachIntegerMoney.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.mail.attach; 2 | 3 | /** 4 | * 整数附件金钱 5 | * @author Dogend 6 | */ 7 | public class AttachIntegerMoney implements AttachMoney { 8 | 9 | private int count; 10 | 11 | public AttachIntegerMoney(){ 12 | this.count = 0; 13 | } 14 | 15 | public AttachIntegerMoney(int count){ 16 | this.count = count; 17 | } 18 | 19 | @Override 20 | public Object getCount() { 21 | return this.count; 22 | } 23 | 24 | @Override 25 | public boolean addCount(Object o) { 26 | if(o instanceof Integer && (int)o>=0){ 27 | count += (int)o; 28 | return true; 29 | }else{ 30 | return false; 31 | } 32 | } 33 | 34 | @Override 35 | public boolean removeCount(Object o) { 36 | if(o instanceof Integer && (int)o>=0){ 37 | if(count-(int)o<0){ 38 | return false; 39 | }else{ 40 | count -= (int)o; 41 | return true; 42 | } 43 | }else{ 44 | return false; 45 | } 46 | } 47 | 48 | @Override 49 | public boolean isZero() { 50 | return count==0; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/mail/attach/AttachMoney.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.mail.attach; 2 | 3 | /** 4 | * 附件金钱接口 5 | * @author Dogend 6 | */ 7 | public interface AttachMoney { 8 | 9 | /** 10 | * 获取当前数量 11 | * @return Object 12 | */ 13 | public Object getCount(); 14 | 15 | /** 16 | * 增加指定数量 17 | * @param o Object 18 | * @return boolean 19 | */ 20 | public boolean addCount(Object o); 21 | 22 | /** 23 | * 移除指定数量 24 | * @param o Object 25 | * @return boolean 26 | */ 27 | public boolean removeCount(Object o); 28 | 29 | /** 30 | * 是否为空 31 | * @return boolean 32 | */ 33 | public boolean isZero(); 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/mail/attach/ProxyPlayer.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.mail.attach; 2 | 3 | import java.lang.reflect.InvocationHandler; 4 | import java.lang.reflect.Method; 5 | import java.lang.reflect.Proxy; 6 | import org.bukkit.entity.Player; 7 | 8 | /** 9 | * 代理玩家 10 | * @since 3.1.0 11 | * @author Dogend 12 | */ 13 | public class ProxyPlayer implements InvocationHandler { 14 | 15 | /** 16 | * 被代理的玩家 17 | */ 18 | public Player cs; 19 | 20 | public ProxyPlayer(Player p){ 21 | this.cs = p; 22 | } 23 | 24 | /** 25 | * 将代理玩家执行isOp和hasPermission方法的返回值更改为true 26 | * @param proxy 代理对象 27 | * @param method 原方法 28 | * @param args 方法参数 29 | * @return 方法返回值 30 | * @throws Throwable 异常 31 | */ 32 | @Override 33 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 34 | if("isOp".equals(method.getName())){ 35 | return true; 36 | } 37 | if("hasPermission".equals(method.getName())){ 38 | return true; 39 | } 40 | return method.invoke(cs, args); 41 | } 42 | 43 | /** 44 | * 获取代理玩家 45 | * @param p Player 46 | * @return Player 47 | */ 48 | public static Player getProxyPlayer(Player p){ 49 | ProxyPlayer pp = new ProxyPlayer(p); 50 | return (Player) Proxy.newProxyInstance(p.getClass().getClassLoader(), p.getClass().getInterfaces(), pp); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/module/InvalidModuleException.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.module; 2 | 3 | /** 4 | * 无效的模块异常 5 | * @since 3.1.0 6 | * @author Administrator 7 | */ 8 | public class InvalidModuleException extends Exception { 9 | 10 | public InvalidModuleException(Throwable cause) { 11 | super(cause); 12 | } 13 | 14 | public InvalidModuleException() { 15 | } 16 | 17 | public InvalidModuleException(String message, Throwable cause) { 18 | super(message, cause); 19 | } 20 | 21 | public InvalidModuleException(String message) { 22 | super(message); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/module/MailBoxModule.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.module; 2 | 3 | import com.tripleying.dogend.mailbox.MailBox; 4 | import com.tripleying.dogend.mailbox.api.command.BaseCommand; 5 | import com.tripleying.dogend.mailbox.api.data.BaseData; 6 | import com.tripleying.dogend.mailbox.api.mail.SystemMail; 7 | import com.tripleying.dogend.mailbox.api.money.BaseMoney; 8 | import com.tripleying.dogend.mailbox.util.ModuleUtil; 9 | import java.io.File; 10 | import java.util.HashSet; 11 | import java.util.LinkedHashMap; 12 | import java.util.Map; 13 | import java.util.Set; 14 | import java.util.jar.JarFile; 15 | import org.bukkit.configuration.file.YamlConfiguration; 16 | import org.bukkit.event.Listener; 17 | 18 | /** 19 | * 模块父类 20 | * @author Dogend 21 | */ 22 | public abstract class MailBoxModule { 23 | 24 | /** 25 | * 模块文件名 26 | */ 27 | private String filename; 28 | /** 29 | * 模块jar文件 30 | */ 31 | private JarFile jar; 32 | /** 33 | * 模块信息 34 | */ 35 | private ModuleInfo info; 36 | /** 37 | * 配置文件 38 | */ 39 | private final Map configs; 40 | 41 | public MailBoxModule(){ 42 | this.configs = new LinkedHashMap(); 43 | } 44 | 45 | /** 46 | * 初始化 47 | */ 48 | private void init(ModuleInfo info, JarFile jar, String filename){ 49 | this.info = info; 50 | this.jar = jar; 51 | this.filename = filename; 52 | } 53 | 54 | /** 55 | * 模块启动方法 56 | */ 57 | public void onEnable(){} 58 | 59 | /** 60 | * 模块卸载方法 61 | */ 62 | public void onDisable(){}; 63 | 64 | /** 65 | * 获取模块信息 66 | * @return ModuleInfo 67 | */ 68 | public ModuleInfo getInfo(){ 69 | return this.info; 70 | } 71 | 72 | /** 73 | * 注册一个数据源 74 | * @param data 数据实例 75 | */ 76 | public void registerData(BaseData data){ 77 | MailBox.getMailBox().getDataManager().addData(this, data); 78 | } 79 | 80 | /** 81 | * 注册一个金钱 82 | * @param money 金钱实例 83 | */ 84 | public void registerMoney(BaseMoney money){ 85 | MailBox.getMailBox().getMoneyManager().registerMoney(this, money); 86 | } 87 | 88 | /** 89 | * 注销一个金钱 90 | * @param money 金钱实例 91 | */ 92 | public void unregisterMoney(BaseMoney money){ 93 | MailBox.getMailBox().getMoneyManager().unregisterMoney(money); 94 | } 95 | 96 | /** 97 | * 注销所有金钱 98 | */ 99 | public void unregisterAllMoney(){ 100 | MailBox.getMailBox().getMoneyManager().unregisterAllMoney(this); 101 | } 102 | 103 | /** 104 | * 注册一个系统邮件 105 | * @param sm 系统邮件实例 106 | */ 107 | public void registerSystemMail(SystemMail sm){ 108 | MailBox.getMailBox().getMailManager().registerSystemMail(this, sm); 109 | } 110 | 111 | /** 112 | * 注销一个系统邮件 113 | * @param sm 系统邮件实例 114 | */ 115 | public void unregisterSystemMail(SystemMail sm){ 116 | MailBox.getMailBox().getMailManager().unregisterSystemMail(sm); 117 | } 118 | 119 | /** 120 | * 注销所有系统邮件 121 | */ 122 | public void unregisterAllSystemMail(){ 123 | MailBox.getMailBox().getMailManager().unregisterAllSystemMail(this); 124 | } 125 | 126 | /** 127 | * 注册一个指令 128 | * @param cmd 指令实例 129 | */ 130 | public void registerCommand(BaseCommand cmd){ 131 | MailBox.getMailBox().getCommandManager().registerCommand(this, cmd); 132 | } 133 | 134 | /** 135 | * 注销一个指令 136 | * @param cmd 指令实例 137 | */ 138 | public void unregisterCommand(BaseCommand cmd){ 139 | MailBox.getMailBox().getCommandManager().unregisterCommand(cmd); 140 | } 141 | 142 | /** 143 | * 注销所有指令 144 | */ 145 | public void unregisterAllCommand(){ 146 | MailBox.getMailBox().getCommandManager().unregisterAllCommand(this); 147 | } 148 | 149 | /** 150 | * 注册一个监听器 151 | * @param listener 指令实例 152 | */ 153 | public void registerListener(Listener listener){ 154 | MailBox.getMailBox().getListenerManager().registerListener(this, listener); 155 | } 156 | 157 | /** 158 | * 注销一个监听器 159 | * @param listener 指令实例 160 | */ 161 | public void unregisterListener(Listener listener){ 162 | MailBox.getMailBox().getListenerManager().unregisterListener(listener); 163 | } 164 | 165 | /** 166 | * 注销所有监听器 167 | */ 168 | public void unregisterAllListener(){ 169 | MailBox.getMailBox().getListenerManager().unregisterAllListener(this); 170 | } 171 | 172 | /** 173 | * 获取模块文件夹 174 | * @return File 175 | */ 176 | public File getDataFolder(){ 177 | return ModuleUtil.getModuleDataFolder(this); 178 | } 179 | 180 | /** 181 | * 保存默认配置 182 | * @param files 路径+文件名 183 | */ 184 | public void saveDefaultConfig(String... files){ 185 | for(String file:files){ 186 | ModuleUtil.saveConfig(this, file); 187 | } 188 | } 189 | 190 | /** 191 | * 保存默认config.yml配置 192 | */ 193 | public void saveDefaultConfig(){ 194 | this.saveDefaultConfig("config.yml"); 195 | } 196 | 197 | /** 198 | * 重载配置文件 199 | * @param files 路径+文件名 200 | */ 201 | public void reloadConfig(String... files){ 202 | this.configs.clear(); 203 | for(String file:files){ 204 | this.configs.put(file, ModuleUtil.getConfig(this, file)); 205 | } 206 | } 207 | 208 | /** 209 | * 重载配置文件 210 | */ 211 | public void reloadConfig(){ 212 | if(this.configs.isEmpty()){ 213 | this.configs.put("config.yml", ModuleUtil.getConfig(this, "config.yml")); 214 | }else{ 215 | Set files = new HashSet(); 216 | files.addAll(this.configs.keySet()); 217 | this.configs.clear(); 218 | for(String file:files){ 219 | this.configs.put(file, ModuleUtil.getConfig(this, file)); 220 | } 221 | } 222 | } 223 | 224 | /** 225 | * 获取内存中的配置文件 226 | * @param file 路径+文件名 227 | * @return YamlConfiguration 228 | */ 229 | public YamlConfiguration getConfig(String file){ 230 | if(!this.configs.containsKey(file)) this.configs.put(file, ModuleUtil.getConfig(this, file)); 231 | return this.configs.get(file); 232 | } 233 | 234 | /** 235 | * 获取内存中的config.yml 236 | * @return YamlConfiguration 237 | */ 238 | public YamlConfiguration getConfig(){ 239 | return this.getConfig("config.yml"); 240 | } 241 | 242 | /** 243 | * 获取Jar文件 244 | * @return JarFile 245 | */ 246 | public JarFile getJar(){ 247 | return this.jar; 248 | } 249 | 250 | /** 251 | * 获取插件文件名 252 | * @return FileName 253 | */ 254 | public String getFileName(){ 255 | return this.filename; 256 | } 257 | 258 | } 259 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/module/ModuleClassLoader.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.module; 2 | 3 | import com.tripleying.dogend.mailbox.manager.ModuleManager; 4 | import com.tripleying.dogend.mailbox.util.MessageUtil; 5 | import com.tripleying.dogend.mailbox.util.ModuleUtil; 6 | import java.io.File; 7 | import java.io.IOException; 8 | import java.lang.reflect.Constructor; 9 | import java.lang.reflect.Method; 10 | import java.net.MalformedURLException; 11 | import java.net.URL; 12 | import java.net.URLClassLoader; 13 | import java.util.ArrayList; 14 | import java.util.Collection; 15 | import java.util.Collections; 16 | import java.util.Enumeration; 17 | import java.util.List; 18 | import java.util.Map; 19 | import java.util.Set; 20 | import java.util.concurrent.ConcurrentHashMap; 21 | import java.util.jar.JarFile; 22 | import org.bukkit.Bukkit; 23 | 24 | /** 25 | * 模块类加载器 26 | * @since 3.1.0 27 | * @author Administrator 28 | */ 29 | public class ModuleClassLoader extends URLClassLoader { 30 | 31 | private final MailBoxModule module; 32 | private final Map> classes = new ConcurrentHashMap(); 33 | private final ModuleInfo info; 34 | private final File file; 35 | private final JarFile jar; 36 | private final ModuleManager mm; 37 | private final Set seenIllegalAccess = Collections.newSetFromMap(new ConcurrentHashMap()); 38 | 39 | static { 40 | ClassLoader.registerAsParallelCapable(); 41 | } 42 | 43 | public ModuleClassLoader(File file, ClassLoader parent, ModuleManager mm) throws IOException, InvalidModuleException, MalformedURLException { 44 | super(new URL[]{file.toURI().toURL()}, parent); 45 | this.file = file; 46 | this.mm = mm; 47 | // 读取jar文件 48 | jar = new JarFile(this.file); 49 | // 读取模块信息 50 | try { 51 | info = ModuleUtil.loadModuleInfo(jar); 52 | } catch (Exception ex) { 53 | closeJar(); 54 | throw new InvalidModuleException(MessageUtil.modlue_load_error_not_info.replaceAll("%module%", file.getName()), ex); 55 | } 56 | if(!info.isAvaliable()){ 57 | closeJar(); 58 | throw new InvalidModuleException(MessageUtil.modlue_load_error_info_err.replaceAll("%module%", file.getName())); 59 | } 60 | String name = info.getName(); 61 | if(mm.hasModule(name)){ 62 | closeJar(); 63 | throw new InvalidModuleException(MessageUtil.modlue_load_error_has_duplicate.replaceAll("%module%", file.getName()).replaceAll("%another%", mm.getMailBoxModule(name).getFileName())); 64 | } 65 | // 检查前置插件/模块 66 | if(!info.getDependPlugin().isEmpty()){ 67 | List lost = new ArrayList(); 68 | info.getDependPlugin().stream().filter(plugin -> (!Bukkit.getPluginManager().isPluginEnabled(plugin))).forEachOrdered(plugin -> { 69 | lost.add(plugin); 70 | }); 71 | if(!lost.isEmpty()){ 72 | closeJar(); 73 | throw new InvalidModuleException(MessageUtil.modlue_load_error_depend_plugin.replaceAll("%module%", file.getName()).replaceAll("%depends%", lost.stream().reduce("",(a,b) -> a.concat(" ").concat(b)))); 74 | } 75 | } 76 | if(!info.getDependModule().isEmpty()){ 77 | List lost = new ArrayList(); 78 | info.getDependModule().stream().filter(mod -> (!mm.hasModule(mod))).forEachOrdered(mod -> { 79 | lost.add(mod); 80 | }); 81 | if(!lost.isEmpty()){ 82 | closeJar(); 83 | throw new InvalidModuleException(MessageUtil.modlue_load_error_depend_module.replaceAll("%module%", file.getName()).replaceAll("%depends%", lost.stream().reduce("",(a,b) -> a.concat(" ").concat(b)))); 84 | } 85 | } 86 | Class clazz; 87 | try { 88 | clazz = Class.forName(info.getMain(), true, this); 89 | }catch (ClassNotFoundException ex) { 90 | closeJar(); 91 | throw new InvalidModuleException(MessageUtil.modlue_load_error_main_find.replaceAll("%module%", name).replaceAll("%main%", info.getMain()), ex); 92 | } 93 | try { 94 | Constructor constructor = clazz.getConstructor(); 95 | Object instance = constructor.newInstance(); 96 | Method init = MailBoxModule.class.getDeclaredMethod("init", ModuleInfo.class, JarFile.class, String.class); 97 | init.setAccessible(true); 98 | module = MailBoxModule.class.cast(instance); 99 | init.invoke(module, info, jar, file.getName()); 100 | } catch (Exception ex) { 101 | closeJar(); 102 | throw new InvalidModuleException(MessageUtil.modlue_load_error_main_init.replaceAll("%module%", name), ex); 103 | } 104 | } 105 | 106 | private void closeJar(){ 107 | try {jar.close();} catch (Exception exj) {} 108 | } 109 | 110 | @Override 111 | public void close() throws IOException { 112 | try{ 113 | super.close(); 114 | }finally { 115 | this.jar.close(); 116 | } 117 | } 118 | 119 | public MailBoxModule getModule() { 120 | return module; 121 | } 122 | 123 | @Override 124 | public URL getResource(String name) { 125 | return this.findResource(name); 126 | } 127 | 128 | @Override 129 | public Enumeration getResources(String name) throws IOException { 130 | return this.findResources(name); 131 | } 132 | 133 | @Override 134 | protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { 135 | return this.loadModuleClass(name, resolve, true); 136 | } 137 | 138 | public Class loadModuleClass(String name, boolean resolve, boolean checkGlobal) throws ClassNotFoundException { 139 | Class result; 140 | try { 141 | result = super.loadClass(name, resolve); 142 | if (checkGlobal || result.getClassLoader() == this) { 143 | return result; 144 | } 145 | }catch (ClassNotFoundException ex) {} 146 | if (checkGlobal && (result = this.mm.getClassFromModuleClassLoaders(name, resolve)) != null) { 147 | ModuleInfo provider; 148 | if (result.getClassLoader() instanceof ModuleClassLoader 149 | && (provider = ((ModuleClassLoader)result.getClassLoader()).info) != this.info 150 | && !this.seenIllegalAccess.contains(provider.getName()) 151 | && !this.info.isDependModule(provider.getName())) { 152 | this.seenIllegalAccess.add(provider.getName()); 153 | MessageUtil.error(MessageUtil.modlue_load_error_no_depend.replaceAll("%module%", this.info.getName()).replaceAll("%provider%", provider.getName()).replaceAll("%class%", name)); 154 | } 155 | return result; 156 | } 157 | throw new ClassNotFoundException(name); 158 | } 159 | 160 | @Override 161 | protected Class findClass(String name) throws ClassNotFoundException { 162 | Class result = this.classes.get(name); 163 | if (result == null) { 164 | result = super.findClass(name); 165 | } 166 | this.classes.put(name, result); 167 | return result; 168 | } 169 | 170 | Collection> getClasses() { 171 | return this.classes.values(); 172 | } 173 | 174 | } 175 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/module/ModuleInfo.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.module; 2 | 3 | import com.tripleying.dogend.mailbox.api.util.Version; 4 | import com.tripleying.dogend.mailbox.util.FileUtil; 5 | import java.util.ArrayList; 6 | import java.util.Arrays; 7 | import java.util.List; 8 | import org.bukkit.configuration.file.YamlConfiguration; 9 | 10 | /** 11 | * 模块信息 12 | * @author Dogend 13 | */ 14 | public class ModuleInfo { 15 | 16 | /** 17 | * 插件名 18 | */ 19 | private final String name; 20 | /** 21 | * 插件主类 22 | */ 23 | private final String main; 24 | /** 25 | * 插件描述 26 | */ 27 | private final String description; 28 | /** 29 | * 插件作者 30 | */ 31 | private final List author; 32 | /** 33 | * 插件版本 34 | */ 35 | private final Version version; 36 | /** 37 | * 前置插件 38 | */ 39 | private final List depend_plugin; 40 | /** 41 | * 前置模块 42 | */ 43 | private final List depend_module; 44 | /** 45 | * 软前置模块 46 | */ 47 | private final List softdepend_module; 48 | /** 49 | * 后置模块 50 | */ 51 | private final List before_module; 52 | /** 53 | * 是否可用 54 | */ 55 | private final boolean avaliable; 56 | 57 | public ModuleInfo(YamlConfiguration yml){ 58 | this.name = yml.getString("name", null); 59 | this.main = yml.getString("main", null); 60 | this.description = yml.getString("description", "none").replaceAll("&", "§"); 61 | this.author = yml.contains("author") 62 | ?FileUtil.getYamlStringList(yml, "author") 63 | :Arrays.asList("none"); 64 | this.version = new Version(yml.getString("version", "1.0.0")); 65 | this.depend_plugin = yml.contains("depend-plugin") 66 | ?FileUtil.getYamlStringList(yml, "depend-plugin") 67 | :new ArrayList(); 68 | this.depend_module = yml.contains("depend-module") 69 | ?FileUtil.getYamlStringList(yml, "depend-module") 70 | :new ArrayList(); 71 | this.softdepend_module = yml.contains("softdepend-module") 72 | ?FileUtil.getYamlStringList(yml, "softdepend-module") 73 | :new ArrayList(); 74 | this.before_module = new ArrayList(); 75 | if(this.name!=null && this.main!=null && this.version.isAvaliable()){ 76 | this.avaliable = true; 77 | }else{ 78 | this.avaliable = false; 79 | } 80 | } 81 | 82 | public String getName(){ 83 | return this.name; 84 | } 85 | 86 | public String getMain(){ 87 | return this.main; 88 | } 89 | 90 | public String getDescription(){ 91 | return this.description; 92 | } 93 | 94 | public List getAuthors(){ 95 | return this.author; 96 | } 97 | 98 | public Version getVersion(){ 99 | return this.version; 100 | } 101 | 102 | public List getDependPlugin(){ 103 | return this.depend_plugin; 104 | } 105 | 106 | public List getDependModule(){ 107 | return this.depend_module; 108 | } 109 | 110 | public List getSoftdependModule(){ 111 | return this.softdepend_module; 112 | } 113 | 114 | public List getBeforeModule(){ 115 | return this.before_module; 116 | } 117 | 118 | /** 119 | * 判断A模块是否是此模块的前置 120 | * @since 3.1.0 121 | * @param name A模块名 122 | * @return boolean 123 | */ 124 | public boolean isDependModule(String name){ 125 | return this.depend_module.contains(name) || this.softdepend_module.contains(name); 126 | } 127 | 128 | public void addBeforeModule(String module){ 129 | if(!this.before_module.contains(module)){ 130 | this.before_module.add(module); 131 | } 132 | } 133 | 134 | public void removeBeforeModule(String module){ 135 | if(this.before_module.contains(module)){ 136 | this.before_module.remove(module); 137 | } 138 | } 139 | 140 | public boolean isAvaliable(){ 141 | return this.avaliable; 142 | } 143 | 144 | } 145 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/money/BaseMoney.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.money; 2 | 3 | import org.bukkit.entity.Player; 4 | 5 | /** 6 | * 基础金钱父类 7 | * 不要继承此类进行附属开发 8 | * @author Dogend 9 | */ 10 | public abstract class BaseMoney { 11 | 12 | /** 13 | * 金钱名 14 | */ 15 | protected final String name; 16 | /** 17 | * 显示名称 18 | */ 19 | protected final String display; 20 | 21 | public BaseMoney(String name, String display){ 22 | this.name = name; 23 | this.display = display; 24 | } 25 | 26 | public String getName(){ 27 | return this.name; 28 | } 29 | 30 | public String getDisplay(){ 31 | return this.display; 32 | } 33 | 34 | /** 35 | * 获取玩家余额 36 | * @param p 玩家 37 | * @return 余额 38 | */ 39 | public abstract Object getPlayerBalance(Player p); 40 | 41 | /** 42 | * 给予玩家金钱 43 | * @param p 玩家 44 | * @param i 金钱 45 | * @return boolean 46 | */ 47 | public abstract boolean givePlayerBalance(Player p, Object i); 48 | 49 | /** 50 | * 移除玩家金钱 51 | * @param p 玩家 52 | * @param i 金钱 53 | * @return boolean 54 | */ 55 | public abstract boolean removePlayerBalance(Player p, Object i); 56 | 57 | /** 58 | * 玩家是否有足够余额 59 | * @param p 玩家 60 | * @param i 金钱 61 | * @return boolean 62 | */ 63 | public abstract boolean hasPlayerBalance(Player p, Object i); 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/money/DoubleMoney.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.money; 2 | 3 | import org.bukkit.entity.Player; 4 | 5 | /** 6 | * 小数型钱父类 7 | * @author Dogend 8 | */ 9 | public abstract class DoubleMoney extends BaseMoney { 10 | 11 | public DoubleMoney(String name, String display) { 12 | super(name, display); 13 | } 14 | 15 | @Override 16 | public final boolean givePlayerBalance(Player p, Object i) { 17 | if(i instanceof Double && (double)i>=0.0){ 18 | return givePlayerBalance(p, (double)i); 19 | }else{ 20 | return false; 21 | } 22 | } 23 | 24 | protected abstract boolean givePlayerBalance(Player p, double i); 25 | 26 | @Override 27 | public final boolean removePlayerBalance(Player p, Object i) { 28 | if(i instanceof Double && (double)i>=0.0 && hasPlayerBalance(p,(double)i)){ 29 | return removePlayerBalance(p, (double)i); 30 | }else{ 31 | return false; 32 | } 33 | } 34 | 35 | protected abstract boolean removePlayerBalance(Player p, double i); 36 | 37 | @Override 38 | public final boolean hasPlayerBalance(Player p, Object i) { 39 | if(i instanceof Double && (double)i>=0.0){ 40 | return hasPlayerBalance(p, (double)i); 41 | }else{ 42 | return false; 43 | } 44 | } 45 | 46 | protected abstract boolean hasPlayerBalance(Player p, double i); 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/money/IntegerMoney.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.money; 2 | 3 | import org.bukkit.entity.Player; 4 | 5 | /** 6 | * 整数钱父类 7 | * @author Dogend 8 | */ 9 | public abstract class IntegerMoney extends BaseMoney { 10 | 11 | public IntegerMoney(String name, String display) { 12 | super(name, display); 13 | } 14 | 15 | @Override 16 | public final boolean givePlayerBalance(Player p, Object i) { 17 | if(i instanceof Integer && (int)i>=0){ 18 | return givePlayerBalance(p, (int)i); 19 | }else{ 20 | return false; 21 | } 22 | } 23 | 24 | protected abstract boolean givePlayerBalance(Player p, int i); 25 | 26 | @Override 27 | public final boolean removePlayerBalance(Player p, Object i) { 28 | if(i instanceof Integer && (int)i>=0 && hasPlayerBalance(p,(int)i)){ 29 | return removePlayerBalance(p, (int)i); 30 | }else{ 31 | return false; 32 | } 33 | } 34 | 35 | protected abstract boolean removePlayerBalance(Player p, int i); 36 | 37 | @Override 38 | public final boolean hasPlayerBalance(Player p, Object i) { 39 | if(i instanceof Integer && (int)i>=0){ 40 | return hasPlayerBalance(p, (int)i); 41 | }else{ 42 | return false; 43 | } 44 | } 45 | 46 | protected abstract boolean hasPlayerBalance(Player p, int i); 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/util/CommonConfig.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.util; 2 | 3 | import org.bukkit.configuration.file.YamlConfiguration; 4 | 5 | /** 6 | * 公共配置 7 | * @author Dogend 8 | */ 9 | public class CommonConfig { 10 | 11 | public static int expire_day; 12 | public static boolean auto_update; 13 | 14 | public static void init(YamlConfiguration yml){ 15 | expire_day = yml.getInt("expire-day", 30); 16 | auto_update = yml.getBoolean("auto-update", false); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/api/util/Version.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.api.util; 2 | 3 | /** 4 | * 版本工具 5 | * @author Dogend 6 | */ 7 | public class Version { 8 | 9 | /** 10 | * 模块版本字符串 11 | */ 12 | private final String version; 13 | /** 14 | * 模块版本数组 15 | */ 16 | private final int[] versionarr; 17 | /** 18 | * 是否可用 19 | */ 20 | private final boolean avaliable; 21 | 22 | public Version(String version){ 23 | this.version = version; 24 | if(this.version!=null){ 25 | String[] vsr = this.version.split("\\."); 26 | if(vsr.length==3){ 27 | int[] vr = new int[3]; 28 | for(int i=0;i<3;i++){ 29 | try{ 30 | vr[i] = Integer.parseInt(vsr[i]); 31 | }catch(NumberFormatException ex){ 32 | vr = null; 33 | break; 34 | } 35 | } 36 | if(vr!=null){ 37 | this.versionarr = vr; 38 | this.avaliable = true; 39 | return; 40 | } 41 | } 42 | } 43 | this.versionarr = null; 44 | this.avaliable = false; 45 | } 46 | 47 | /** 48 | * 检查版本是否最新 49 | * @param newest 最新版本 50 | * @return boolean 51 | */ 52 | public boolean checkNewest(Version newest){ 53 | if(newest.avaliable){ 54 | for(int i=0;i<3;i++){ 55 | if(this.versionarr[i]>newest.versionarr[i]) return true; 56 | if(this.versionarr[i] onTabComplete(CommandSender sender, String[] args) { 43 | return null; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/command/HelpCommand.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.command; 2 | 3 | import com.tripleying.dogend.mailbox.api.command.BaseCommand; 4 | import com.tripleying.dogend.mailbox.api.command.BaseTabCompleter; 5 | import java.util.List; 6 | import org.bukkit.command.CommandSender; 7 | 8 | /** 9 | * 帮助指令 10 | * @author Dogend 11 | */ 12 | public class HelpCommand implements BaseCommand, BaseTabCompleter { 13 | 14 | @Override 15 | public String getLabel() { 16 | return "help"; 17 | } 18 | 19 | @Override 20 | public String getDescription(CommandSender sender) { 21 | return "插件帮助"; 22 | } 23 | 24 | @Override 25 | public boolean onCommand(CommandSender sender, String[] args) { 26 | return false; 27 | } 28 | 29 | @Override 30 | public boolean allowTab(CommandSender sender) { 31 | return true; 32 | } 33 | 34 | @Override 35 | public List onTabComplete(CommandSender sender, String[] args) { 36 | return null; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/command/ReloadCommand.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.command; 2 | 3 | import com.tripleying.dogend.mailbox.MailBox; 4 | import com.tripleying.dogend.mailbox.api.command.BaseCommand; 5 | import com.tripleying.dogend.mailbox.api.command.BaseTabCompleter; 6 | import java.util.List; 7 | import org.bukkit.command.CommandSender; 8 | 9 | /** 10 | * 重载指令 11 | * @author Dogend 12 | */ 13 | public class ReloadCommand implements BaseCommand, BaseTabCompleter { 14 | 15 | @Override 16 | public String getLabel() { 17 | return "reload"; 18 | } 19 | 20 | @Override 21 | public String getDescription(CommandSender sender) { 22 | return sender.isOp()?"重载插件":null; 23 | } 24 | 25 | @Override 26 | public boolean onCommand(CommandSender sender, String[] args) { 27 | if(sender.isOp()){ 28 | MailBox.getMailBox().reload(sender); 29 | return true; 30 | }else{ 31 | return false; 32 | } 33 | } 34 | 35 | @Override 36 | public boolean allowTab(CommandSender sender) { 37 | return sender.isOp(); 38 | } 39 | 40 | @Override 41 | public List onTabComplete(CommandSender sender, String[] args) { 42 | return null; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/command/UpdateCommand.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.command; 2 | 3 | import com.tripleying.dogend.mailbox.api.command.BaseCommand; 4 | import com.tripleying.dogend.mailbox.api.command.BaseTabCompleter; 5 | import com.tripleying.dogend.mailbox.util.UpdateUtil; 6 | import java.util.List; 7 | import org.bukkit.command.CommandSender; 8 | 9 | /** 10 | * 更新指令 11 | * @author Dogend 12 | */ 13 | public class UpdateCommand implements BaseCommand, BaseTabCompleter { 14 | 15 | @Override 16 | public String getLabel() { 17 | return "update"; 18 | } 19 | 20 | @Override 21 | public String getDescription(CommandSender sender) { 22 | return sender.isOp()?"自动更新插件":null; 23 | } 24 | 25 | @Override 26 | public boolean onCommand(CommandSender sender, String[] args) { 27 | if(sender.isOp()){ 28 | UpdateUtil.updatePlugin(sender, true); 29 | return true; 30 | }else{ 31 | return false; 32 | } 33 | } 34 | 35 | @Override 36 | public boolean allowTab(CommandSender sender) { 37 | return sender.isOp(); 38 | } 39 | 40 | @Override 41 | public List onTabComplete(CommandSender sender, String[] args) { 42 | return null; 43 | } 44 | 45 | } -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/data/CommandBuilder.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.data; 2 | 3 | import com.tripleying.dogend.mailbox.api.mail.SystemMail; 4 | import com.tripleying.dogend.mailbox.api.data.sql.CreateTable; 5 | import com.tripleying.dogend.mailbox.api.data.sql.DeleteData; 6 | import com.tripleying.dogend.mailbox.api.data.sql.InsertData; 7 | import com.tripleying.dogend.mailbox.api.data.sql.LastData; 8 | import com.tripleying.dogend.mailbox.api.data.sql.LastInsertID; 9 | import com.tripleying.dogend.mailbox.api.data.sql.SelectData; 10 | import com.tripleying.dogend.mailbox.api.data.sql.UpdateData; 11 | import com.tripleying.dogend.mailbox.util.ReflectUtil; 12 | import java.util.Map; 13 | import com.tripleying.dogend.mailbox.api.data.Data; 14 | import com.tripleying.dogend.mailbox.api.data.DataType; 15 | import com.tripleying.dogend.mailbox.api.mail.CustomData; 16 | 17 | /** 18 | * SQL指令构造器 19 | * @author Dogend 20 | */ 21 | public class CommandBuilder { 22 | 23 | public static CreateTable sqlPlayerDataCreateCommand(){ 24 | return new CreateTable("mailbox_player_data") 25 | .addString("name", 36) 26 | .addString("uuid", 36) 27 | .addYamlString("data"); 28 | } 29 | 30 | public static InsertData sqlPlayerDataInsertCommand(){ 31 | return new InsertData("mailbox_player_data") 32 | .addColumns("name") 33 | .addColumns("uuid") 34 | .addColumns("data"); 35 | } 36 | 37 | public static SelectData sqlPlayerDataSelectCommand(){ 38 | return new SelectData("mailbox_player_data") 39 | .addWhere("uuid"); 40 | } 41 | 42 | public static SelectData sqlPlayerDataSelectAllCommand(){ 43 | return new SelectData("mailbox_player_data"); 44 | } 45 | 46 | public static UpdateData sqlPlayerDataUpdateCommand(){ 47 | return new UpdateData("mailbox_player_data") 48 | .addSet("name") 49 | .addSet("data") 50 | .addWhere("uuid"); 51 | } 52 | 53 | public static CreateTable sqlPersonMailCreateCommand(){ 54 | return new CreateTable("mailbox_person_mail") 55 | .addString("uuid", 36) 56 | .addString("type", 10) 57 | .addLong("id") 58 | .addString("title", 50) 59 | .addYamlString("body") 60 | .addString("sender", 36) 61 | .addDateTime("sendtime") 62 | .addBoolean("received") 63 | .addYamlString("attach"); 64 | } 65 | 66 | public static SelectData sqlPersonMailSelectCommand(){ 67 | return new SelectData("mailbox_person_mail") 68 | .addWhere("uuid") 69 | .orderBy("sendtime") 70 | .desc(true); 71 | } 72 | 73 | public static InsertData sqlPersonMailInsertCommand(){ 74 | return new InsertData("mailbox_person_mail") 75 | .addColumns("uuid") 76 | .addColumns("type") 77 | .addColumns("id") 78 | .addColumns("title") 79 | .addColumns("body") 80 | .addColumns("sender") 81 | .addColumns("sendtime") 82 | .addColumns("received") 83 | .addColumns("attach"); 84 | } 85 | 86 | public static UpdateData sqlPersonMailReceiveCommand(){ 87 | return new UpdateData("mailbox_person_mail") 88 | .addSet("received") 89 | .addWhere("uuid") 90 | .addWhere("type") 91 | .addWhere("id"); 92 | } 93 | 94 | public static DeleteData sqlPersonMailDeleteCommand(){ 95 | return new DeleteData("mailbox_person_mail") 96 | .addWhere("uuid") 97 | .addWhere("type") 98 | .addWhere("id") 99 | .addWhere("received"); 100 | } 101 | 102 | public static DeleteData sqlPersonMailClearCommand(){ 103 | return new DeleteData("mailbox_person_mail") 104 | .addWhere("uuid") 105 | .addWhere("received"); 106 | } 107 | 108 | public static CreateTable sqlSystemMailCreateCommand(String type, Class clazz){ 109 | Map cols = ReflectUtil.getSystemMailColumns(clazz); 110 | CreateTable cmd = new CreateTable(getSystemMailTable(type)) 111 | .setPrimaryKey("id") 112 | .addString("title", 50) 113 | .addYamlString("body") 114 | .addString("sender", 36) 115 | .addDateTime("sendtime") 116 | .addYamlString("attach"); 117 | cols.forEach((f,dc) -> { 118 | switch(dc.type()){ 119 | case Integer: 120 | cmd.addInt(f); 121 | break; 122 | case Long: 123 | cmd.addLong(f); 124 | break; 125 | case Boolean: 126 | cmd.addBoolean(f); 127 | break; 128 | case DateTime: 129 | cmd.addDateTime(f); 130 | break; 131 | default: 132 | case String: 133 | cmd.addString(f, dc.size()); 134 | break; 135 | case YamlString: 136 | cmd.addYamlString(f); 137 | break; 138 | } 139 | }); 140 | return cmd; 141 | } 142 | 143 | public static LastData sqlSystemMailLastDataIDCommand(String type){ 144 | return new LastData(getSystemMailTable(type)); 145 | } 146 | 147 | public static SelectData sqlSystemMailSelectCommand(String type){ 148 | return new SelectData(getSystemMailTable(type)) 149 | .orderBy("sendtime") 150 | .desc(true); 151 | } 152 | 153 | public static InsertData sqlSystemMailInsertCommand(String type, Class clazz){ 154 | Map cols = ReflectUtil.getSystemMailColumns(clazz); 155 | InsertData cmd = new InsertData(getSystemMailTable(type)) 156 | .addColumns("title") 157 | .addColumns("body") 158 | .addColumns("sender") 159 | .addColumns("sendtime") 160 | .addColumns("attach"); 161 | cols.forEach((f,dc) -> cmd.addColumns(f)); 162 | return cmd; 163 | } 164 | 165 | public static DeleteData sqlSystemMailDeleteCommand(String type){ 166 | return new DeleteData(getSystemMailTable(type)) 167 | .addWhere("id"); 168 | } 169 | 170 | private static String getSystemMailTable(String type){ 171 | return "mailbox_system_".concat(type).concat("_mail"); 172 | } 173 | 174 | public static LastInsertID sqlLastInsertIDCommand(){ 175 | return new LastInsertID(); 176 | } 177 | 178 | public static CreateTable sqlCustomDataCreateCommand(CustomData cd){ 179 | Map cols = ReflectUtil.getCustomDataColumns(cd.getClass()); 180 | CreateTable cmd = new CreateTable(cd.getName()); 181 | cols.forEach((f,dc) -> { 182 | switch(dc.type()){ 183 | case Integer: 184 | cmd.addInt(f); 185 | break; 186 | case Long: 187 | cmd.addLong(f); 188 | break; 189 | case Boolean: 190 | cmd.addBoolean(f); 191 | break; 192 | case DateTime: 193 | cmd.addDateTime(f); 194 | break; 195 | default: 196 | case String: 197 | cmd.addString(f, dc.size()); 198 | break; 199 | case YamlString: 200 | cmd.addYamlString(f); 201 | break; 202 | case Primary: 203 | cmd.setPrimaryKey(f); 204 | break; 205 | } 206 | }); 207 | return cmd; 208 | } 209 | 210 | public static InsertData sqlCustomDataInsertCommand(CustomData cd){ 211 | Map cols = ReflectUtil.getCustomDataColumns(cd.getClass()); 212 | InsertData cmd = new InsertData(cd.getName()); 213 | cols.forEach((f,dc) -> {if(!dc.type().equals(DataType.Primary))cmd.addColumns(f);} ); 214 | return cmd; 215 | } 216 | 217 | public static UpdateData sqlCustomDataUpdateByPrimaryKeyCommand(CustomData cd){ 218 | Map cols = ReflectUtil.getCustomDataColumns(cd.getClass()); 219 | UpdateData cmd = new UpdateData(cd.getName()); 220 | cols.forEach((f,dc) -> { 221 | if(dc.type().equals(DataType.Primary)){ 222 | cmd.addWhere(f); 223 | }else{ 224 | cmd.addSet(f); 225 | } 226 | }); 227 | return cmd; 228 | } 229 | 230 | public static SelectData sqlCustomDataSelectCommand(CustomData cd){ 231 | return new SelectData(cd.getName()); 232 | } 233 | 234 | public static DeleteData sqlCustomDataDeleteCommand(CustomData cd){ 235 | return new DeleteData(cd.getName()); 236 | } 237 | 238 | } 239 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/data/MySQLData.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.data; 2 | 3 | import com.tripleying.dogend.mailbox.api.data.sql.SQLCommand; 4 | import com.tripleying.dogend.mailbox.util.TimeUtil; 5 | import java.sql.Connection; 6 | import java.sql.DriverManager; 7 | import java.sql.ResultSet; 8 | import java.sql.SQLException; 9 | import org.bukkit.configuration.file.YamlConfiguration; 10 | 11 | /** 12 | * MySQL数据 13 | * @author Dogend 14 | */ 15 | public class MySQLData extends SQLData { 16 | 17 | private Connection connection; 18 | private final boolean encp; 19 | private final String url; 20 | /** 21 | * 连接池 22 | */ 23 | protected final SimpleCP cp; 24 | 25 | public MySQLData(YamlConfiguration yml){ 26 | super(yml.getString("mysql.type", "mysql")); 27 | this.url = "jdbc:mysql://".concat(yml.getString("mysql.host")).concat(":").concat(Integer.toString(yml.getInt("mysql.port"))).concat("/").concat(yml.getString("mysql.database")) 28 | .concat("?user=").concat(yml.getString("mysql.username")).concat("&password=").concat(yml.getString("mysql.password")) 29 | .concat("&autoReconnect=true&autoReconnectForPools=true&useSSL=false"); 30 | this.encp = yml.getBoolean("mysql.encp", false); 31 | if(this.encp) this.cp = new SimpleCP(yml.getConfigurationSection("simplecp"), url); 32 | else this.cp = null; 33 | } 34 | 35 | @Override 36 | public boolean enable(){ 37 | try{ 38 | if(this.encp){ 39 | return this.cp.enable(); 40 | }else{ 41 | this.createConnection(); 42 | return !this.connection.isClosed(); 43 | } 44 | }catch(Exception ex){ 45 | ex.printStackTrace(); 46 | return false; 47 | } 48 | } 49 | 50 | private void createConnection(){ 51 | try{ 52 | this.connection = DriverManager.getConnection(url); 53 | }catch(Exception ex){ 54 | ex.printStackTrace(); 55 | } 56 | } 57 | 58 | @Override 59 | public Connection getConnection() { 60 | return this.encp?this.getCpConnection():this.getNoCpConnection(); 61 | } 62 | 63 | public Connection getCpConnection() { 64 | Connection conn = this.cp.getConnection(); 65 | if(this.cp.isAvailable(conn)){ 66 | return conn; 67 | }else{ 68 | this.cp.releaseConnection(conn); 69 | return null; 70 | } 71 | } 72 | 73 | public Connection getNoCpConnection() { 74 | try { 75 | if(this.connection==null || this.connection.isClosed()){ 76 | this.createConnection();; 77 | } 78 | } catch (SQLException ex) { 79 | ex.printStackTrace(); 80 | } 81 | try { 82 | if(null!=this.connection && !this.connection.isClosed()){ 83 | return this.connection; 84 | } 85 | } catch (SQLException ex) { 86 | ex.printStackTrace(); 87 | } 88 | return null; 89 | } 90 | 91 | @Override 92 | public void releaseConnection(Connection con) { 93 | if(this.encp) this.cp.releaseConnection(con); 94 | } 95 | 96 | @Override 97 | public void close() { 98 | if(this.encp) this.cp.close(); 99 | else { 100 | if(this.connection!=null){ 101 | try { 102 | this.connection.close(); 103 | } catch (SQLException ex) {} 104 | }; 105 | } 106 | } 107 | 108 | @Override 109 | protected String command2String(SQLCommand cmd) { 110 | return cmd.toMySQLCommand(); 111 | } 112 | 113 | @Override 114 | protected String getDateTime(String col, ResultSet rs) throws SQLException{ 115 | return TimeUtil.long2String(rs.getTimestamp(col).getTime()); 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/data/SQLiteData.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.data; 2 | 3 | import com.tripleying.dogend.mailbox.MailBox; 4 | import com.tripleying.dogend.mailbox.api.data.sql.SQLCommand; 5 | import com.tripleying.dogend.mailbox.util.FileUtil; 6 | import java.sql.Connection; 7 | import java.sql.DriverManager; 8 | import java.sql.ResultSet; 9 | import java.sql.SQLException; 10 | import org.bukkit.configuration.file.YamlConfiguration; 11 | 12 | /** 13 | * SQLite数据 14 | * @author Dogend 15 | */ 16 | public class SQLiteData extends SQLData { 17 | 18 | private final String url; 19 | private Connection connection; 20 | 21 | public SQLiteData(YamlConfiguration yml){ 22 | super(yml.getString("sqlite.type", "sqlite")); 23 | url = "jdbc:sqlite:plugins/MailBox/".concat(yml.getString("sqlite.database", "MailBox")).concat(".db"); 24 | } 25 | 26 | @Override 27 | public boolean enable(){ 28 | try{ 29 | if(MailBox.getMCVersion()<1.11) Class.forName("org.sqlite.JDBC"); 30 | this.createConnection(); 31 | return !this.connection.isClosed(); 32 | }catch(Exception ex){ 33 | ex.printStackTrace(); 34 | return false; 35 | } 36 | } 37 | 38 | private void createConnection(){ 39 | try{ 40 | FileUtil.getMailBoxFolder(); 41 | this.connection = DriverManager.getConnection(url); 42 | }catch(Exception ex){ 43 | ex.printStackTrace(); 44 | } 45 | } 46 | 47 | @Override 48 | public Connection getConnection() { 49 | try { 50 | if(this.connection==null || this.connection.isClosed()){ 51 | this.createConnection();; 52 | } 53 | } catch (SQLException ex) { 54 | ex.printStackTrace(); 55 | } 56 | try { 57 | if(null!=this.connection && !this.connection.isClosed()){ 58 | return this.connection; 59 | } 60 | } catch (SQLException ex) { 61 | ex.printStackTrace(); 62 | } 63 | return null; 64 | } 65 | 66 | @Override 67 | public void releaseConnection(Connection con) {} 68 | 69 | @Override 70 | public void close() { 71 | if(this.connection!=null){ 72 | try { 73 | this.connection.close(); 74 | } catch (SQLException ex) {} 75 | }; 76 | } 77 | 78 | @Override 79 | protected String command2String(SQLCommand cmd) { 80 | return cmd.toSQLiteCommand(); 81 | } 82 | 83 | @Override 84 | protected String getDateTime(String col, ResultSet rs) throws SQLException{ 85 | return rs.getString(col); 86 | } 87 | 88 | } -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/data/SimpleCP.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.data; 2 | 3 | import java.sql.Connection; 4 | import java.sql.DriverManager; 5 | import java.sql.ResultSet; 6 | import java.sql.SQLException; 7 | import java.sql.Statement; 8 | import java.util.List; 9 | import java.util.concurrent.CopyOnWriteArrayList; 10 | import java.util.concurrent.atomic.AtomicInteger; 11 | import org.bukkit.configuration.ConfigurationSection; 12 | 13 | /** 14 | * 简单连接池 15 | * @author Dogend 16 | */ 17 | public class SimpleCP { 18 | 19 | /** 20 | * 空闲连接 21 | */ 22 | private final List free = new CopyOnWriteArrayList<>(); 23 | /** 24 | * 活动连接 25 | */ 26 | private final List active = new CopyOnWriteArrayList<>(); 27 | /** 28 | * 大小 29 | */ 30 | private final AtomicInteger size; 31 | /** 32 | * 连接URL 33 | */ 34 | private final String url; 35 | /** 36 | * 做小空闲连接数量 37 | */ 38 | private final int min; 39 | /** 40 | * 最大连接数量 41 | */ 42 | private final int max; 43 | /** 44 | * 连接超时时间 45 | */ 46 | private final int timeout; 47 | 48 | public SimpleCP(ConfigurationSection config, String url){ 49 | this.min = config.getInt("min", 10); 50 | this.max = config.getInt("max", 20); 51 | this.timeout = config.getInt("timeout", 3000); 52 | this.size = new AtomicInteger(0); 53 | this.url= url; 54 | } 55 | 56 | /** 57 | * 启用连接池 58 | * @return boolean 59 | */ 60 | public boolean enable(){ 61 | for(int i=0; i0){ 93 | connection = free.remove(0); 94 | }else{ 95 | connection = createConnection(); 96 | } 97 | if(isAvailable(connection)){ 98 | active.add(connection); 99 | }else{ 100 | size.decrementAndGet(); 101 | connection = getConnection(); 102 | } 103 | }else{ 104 | try{ 105 | wait(timeout); 106 | }catch(InterruptedException ex){ 107 | ex.printStackTrace(); 108 | } 109 | } 110 | return connection; 111 | } 112 | 113 | /** 114 | * 释放连接 115 | * @param connection 连接 116 | */ 117 | public synchronized void releaseConnection(Connection connection) { 118 | if(isAvailable(connection)){ 119 | if(free.size() map; 29 | private final Map mod_map; 30 | 31 | public CommandManager(){ 32 | manager = this; 33 | this.tab = new TabManager(); 34 | this.map = new LinkedHashMap(); 35 | this.mod_map = new HashMap(); 36 | } 37 | 38 | @Override 39 | public boolean onCommand(CommandSender cs, Command cmnd, String string, String[] args) { 40 | if(args.length>0){ 41 | String label = args[0]; 42 | if(this.map.containsKey(label)){ 43 | if(this.map.get(label).onCommand(cs, args)){ 44 | return true; 45 | } 46 | } 47 | } 48 | this.help(cs); 49 | return true; 50 | } 51 | 52 | /** 53 | * 注册基础指令 54 | */ 55 | public void registerBaseCommand(){ 56 | putCommand(new HelpCommand()); 57 | putCommand(new CheckCommand()); 58 | putCommand(new UpdateCommand()); 59 | putCommand(new ReloadCommand()); 60 | } 61 | 62 | public void help(CommandSender cs){ 63 | MessageUtil.log(cs, MessageUtil.command_help); 64 | this.map.forEach((l,cmd) -> { 65 | String desc = cmd.getDescription(cs); 66 | if(desc!=null){ 67 | MessageUtil.log(cs, MessageUtil.color("&6/mailbox ".concat(l).concat(" &b").concat(desc))); 68 | } 69 | }); 70 | } 71 | 72 | private void putCommand(BaseCommand cmd){ 73 | String label = cmd.getLabel(); 74 | this.map.put(label, cmd); 75 | if(cmd instanceof BaseTabCompleter){ 76 | this.tab.registerTab(label, (BaseTabCompleter)cmd); 77 | } 78 | } 79 | 80 | private void removeCommand(String label){ 81 | this.map.remove(label); 82 | this.tab.unregisterTab(label); 83 | } 84 | 85 | /** 86 | * 注册指令 87 | * @param module 模块 88 | * @param cmd 指令类 89 | * @return boolean 90 | */ 91 | public boolean registerCommand(MailBoxModule module, BaseCommand cmd){ 92 | String label = cmd.getLabel(); 93 | if(this.map.containsKey(label)){ 94 | MessageUtil.log(MessageUtil.command_reg_error.replaceAll("%command%", label)); 95 | return false; 96 | }else{ 97 | putCommand(cmd); 98 | this.mod_map.put(cmd, module); 99 | MessageUtil.log(MessageUtil.command_reg.replaceAll("%command%", label)); 100 | return true; 101 | } 102 | } 103 | 104 | /** 105 | * 注销指令 106 | * @param label 指令名 107 | */ 108 | public void unregisterCommand(String label){ 109 | if(this.map.containsKey(label)){ 110 | this.mod_map.remove(this.map.get(label)); 111 | removeCommand(label); 112 | MessageUtil.log(MessageUtil.command_unreg.replaceAll("%command%", label)); 113 | } 114 | } 115 | 116 | /** 117 | * 注销指令 118 | * @param cmd 指令实例 119 | */ 120 | public void unregisterCommand(BaseCommand cmd){ 121 | if(this.map.containsValue(cmd)){ 122 | this.mod_map.remove(cmd); 123 | removeCommand(cmd.getLabel()); 124 | MessageUtil.log(MessageUtil.command_unreg.replaceAll("%command%", cmd.getLabel())); 125 | } 126 | } 127 | 128 | /** 129 | * 注销全部指令 130 | * @param module 模块 131 | */ 132 | public void unregisterAllCommand(MailBoxModule module){ 133 | if(this.mod_map.containsValue(module)){ 134 | Set cmds = new HashSet(); 135 | this.mod_map.entrySet().stream().filter(me -> (me.getValue()==module)).forEachOrdered(me -> { 136 | cmds.add(me.getKey()); 137 | }); 138 | cmds.forEach(cmd -> { 139 | this.unregisterCommand(cmd); 140 | }); 141 | } 142 | } 143 | 144 | public TabManager getTabManager() { 145 | return this.tab; 146 | } 147 | 148 | public static CommandManager getCommandManager(){ 149 | return manager; 150 | } 151 | 152 | } 153 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/manager/ListenerManager.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.manager; 2 | 3 | import com.tripleying.dogend.mailbox.MailBox; 4 | import com.tripleying.dogend.mailbox.api.module.MailBoxModule; 5 | import com.tripleying.dogend.mailbox.util.MessageUtil; 6 | import java.util.HashSet; 7 | import java.util.LinkedHashMap; 8 | import java.util.Map; 9 | import java.util.Set; 10 | import org.bukkit.Bukkit; 11 | import org.bukkit.event.HandlerList; 12 | import org.bukkit.event.Listener; 13 | 14 | /** 15 | * 监听器管理器 16 | * @author Dogend 17 | */ 18 | public class ListenerManager { 19 | 20 | private static ListenerManager manager; 21 | private final Map mod_map; 22 | 23 | public ListenerManager(){ 24 | manager = this; 25 | this.mod_map = new LinkedHashMap(); 26 | } 27 | 28 | /** 29 | * 注册监听器 30 | * @param module 模块 31 | * @param listener 监听器 32 | */ 33 | public void registerListener(MailBoxModule module, Listener listener){ 34 | this.mod_map.put(listener, module); 35 | Bukkit.getPluginManager().registerEvents(listener, MailBox.getMailBox()); 36 | MessageUtil.log(MessageUtil.listener_reg.replaceAll("%listener%", listener.getClass().getName())); 37 | } 38 | 39 | /** 40 | * 注销监听器 41 | * @param listener 监听器 42 | */ 43 | public void unregisterListener(Listener listener){ 44 | if(this.mod_map.containsKey(listener)){ 45 | this.mod_map.remove(listener); 46 | HandlerList.unregisterAll(listener); 47 | MessageUtil.log(MessageUtil.listener_unreg.replaceAll("%listener%", listener.getClass().getName())); 48 | } 49 | } 50 | 51 | /** 52 | * 注销全部监听器 53 | * @param module 模块 54 | */ 55 | public void unregisterAllListener(MailBoxModule module){ 56 | if(this.mod_map.containsValue(module)){ 57 | Set cmds = new HashSet(); 58 | this.mod_map.entrySet().stream().filter(me -> (me.getValue()==module)).forEachOrdered(me -> { 59 | cmds.add(me.getKey()); 60 | }); 61 | cmds.forEach(cmd -> { 62 | this.unregisterListener(cmd); 63 | }); 64 | } 65 | } 66 | 67 | public static ListenerManager getListenerManager(){ 68 | return manager; 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/manager/MoneyManager.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.manager; 2 | 3 | import com.tripleying.dogend.mailbox.api.mail.attach.AttachDoubleMoney; 4 | import com.tripleying.dogend.mailbox.api.mail.attach.AttachIntegerMoney; 5 | import com.tripleying.dogend.mailbox.api.mail.attach.AttachMoney; 6 | import com.tripleying.dogend.mailbox.api.module.MailBoxModule; 7 | import com.tripleying.dogend.mailbox.api.money.DoubleMoney; 8 | import com.tripleying.dogend.mailbox.api.money.IntegerMoney; 9 | import com.tripleying.dogend.mailbox.api.money.BaseMoney; 10 | import com.tripleying.dogend.mailbox.util.MessageUtil; 11 | import java.util.ArrayList; 12 | import java.util.HashMap; 13 | import java.util.HashSet; 14 | import java.util.List; 15 | import java.util.Map; 16 | import java.util.Set; 17 | import org.bukkit.entity.Player; 18 | 19 | /** 20 | * 金钱管理器 21 | * @author Dogend 22 | */ 23 | public class MoneyManager { 24 | 25 | private static MoneyManager manager; 26 | private final Map map; 27 | private final Map mod_map; 28 | 29 | public MoneyManager(){ 30 | manager = this; 31 | this.map = new HashMap(); 32 | this.mod_map = new HashMap(); 33 | } 34 | 35 | /** 36 | * 给予玩家金钱 37 | * @param p 玩家 38 | * @param name 金钱名 39 | * @param count 金钱数量 40 | * @return boolean 41 | */ 42 | public boolean addBalance(Player p, String name, Object count){ 43 | if(this.map.containsKey(name)){ 44 | return this.map.get(name).givePlayerBalance(p, count); 45 | } 46 | return false; 47 | } 48 | 49 | /** 50 | * 移除玩家金钱 51 | * @param p 玩家 52 | * @param name 金钱名 53 | * @param count 金钱数量 54 | * @return boolean 55 | */ 56 | public boolean removeBalance(Player p, String name, Object count){ 57 | if(this.map.containsKey(name)){ 58 | return this.map.get(name).removePlayerBalance(p, count); 59 | } 60 | return false; 61 | } 62 | 63 | /** 64 | * 获取玩家余额 65 | * @param p 玩家 66 | * @param name 金钱名 67 | * @return boolean 68 | */ 69 | public Object getBalance(Player p, String name){ 70 | if(this.map.containsKey(name)){ 71 | return this.map.get(name).getPlayerBalance(p); 72 | } 73 | return 0; 74 | } 75 | 76 | /** 77 | * 判断玩家是否有足够的余额 78 | * @param p 玩家 79 | * @param name 金钱名 80 | * @param count 金钱数量 81 | * @return boolean 82 | */ 83 | public boolean hasBalance(Player p, String name, Object count){ 84 | if(this.map.containsKey(name)){ 85 | return this.map.get(name).hasPlayerBalance(p, count); 86 | } 87 | return false; 88 | } 89 | 90 | /** 91 | * 获取金钱展示名称 92 | * @param name 金钱名 93 | * @return String 94 | */ 95 | public String getMoneyDisplay(String name){ 96 | return this.map.containsKey(name)?this.map.get(name).getDisplay():"无"; 97 | } 98 | 99 | /** 100 | * 获取金钱列表 101 | * @return List 102 | */ 103 | public List getMoneyList(){ 104 | List list = new ArrayList(); 105 | list.addAll(this.map.values()); 106 | return list; 107 | } 108 | 109 | /** 110 | * 获取一个金钱附件 111 | * @param name 金钱名 112 | * @return AttachMoney 113 | */ 114 | public AttachMoney getAttachMoney(String name){ 115 | if(this.map.containsKey(name)){ 116 | BaseMoney money = this.map.get(name); 117 | if(money instanceof IntegerMoney) return new AttachIntegerMoney(); 118 | if(money instanceof DoubleMoney) return new AttachDoubleMoney(); 119 | } 120 | return null; 121 | } 122 | 123 | /** 124 | * 获取一个金钱附件 125 | * @param name 金钱名 126 | * @param o 数量 127 | * @return AttachMoney 128 | */ 129 | public AttachMoney getAttachMoney(String name, Object o){ 130 | if(this.map.containsKey(name)){ 131 | BaseMoney money = this.map.get(name); 132 | if(money instanceof IntegerMoney && o instanceof Integer) return new AttachIntegerMoney((int)o); 133 | if(money instanceof DoubleMoney && o instanceof Double) return new AttachDoubleMoney((double)o); 134 | } 135 | return null; 136 | } 137 | 138 | /** 139 | * 注册金钱 140 | * @param module 模块 141 | * @param money 金钱类 142 | */ 143 | public void registerMoney(MailBoxModule module, BaseMoney money){ 144 | String name = money.getName(); 145 | if(money instanceof IntegerMoney || money instanceof DoubleMoney){ 146 | if(this.map.containsKey(name)){ 147 | MessageUtil.log(MessageUtil.money_reg_duplicate.replaceAll("%money%", name)); 148 | }else{ 149 | this.map.put(name, money); 150 | this.mod_map.put(money, module); 151 | MessageUtil.log(MessageUtil.money_reg.replaceAll("%money%", name)); 152 | } 153 | }else{ 154 | MessageUtil.log(MessageUtil.money_reg_invalid.replaceAll("%money%", name)); 155 | } 156 | } 157 | 158 | /** 159 | * 注销金钱 160 | * @param name 金钱名 161 | */ 162 | public void unregisterMoney(String name){ 163 | if(this.map.containsKey(name)){ 164 | this.mod_map.remove(this.map.get(name)); 165 | this.map.remove(name); 166 | MessageUtil.log(MessageUtil.money_unreg.replaceAll("%money%", name)); 167 | } 168 | } 169 | 170 | /** 171 | * 注销金钱 172 | * @param money 金钱实例 173 | */ 174 | public void unregisterMoney(BaseMoney money){ 175 | if(this.map.containsValue(money)){ 176 | this.mod_map.remove(money); 177 | this.map.remove(money.getName()); 178 | MessageUtil.log(MessageUtil.money_unreg.replaceAll("%money%", money.getName())); 179 | } 180 | } 181 | 182 | /** 183 | * 注销全部金钱 184 | * @param module 模块 185 | */ 186 | public void unregisterAllMoney(MailBoxModule module){ 187 | if(this.mod_map.containsValue(module)){ 188 | Set moneys = new HashSet(); 189 | this.mod_map.entrySet().stream().filter(me -> (me.getValue()==module)).forEachOrdered(me -> { 190 | moneys.add(me.getKey()); 191 | }); 192 | moneys.forEach(money -> { 193 | this.unregisterMoney(money); 194 | }); 195 | } 196 | } 197 | 198 | public static MoneyManager getMoneyManager(){ 199 | return manager; 200 | } 201 | 202 | } -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/manager/TabManager.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.manager; 2 | 3 | import com.tripleying.dogend.mailbox.api.command.BaseTabCompleter; 4 | import java.util.ArrayList; 5 | import java.util.LinkedHashMap; 6 | import java.util.List; 7 | import java.util.Map; 8 | import org.bukkit.command.Command; 9 | import org.bukkit.command.CommandSender; 10 | import org.bukkit.command.TabCompleter; 11 | 12 | /** 13 | * 指令补全管理器 14 | * @author Administrator 15 | */ 16 | public class TabManager implements TabCompleter { 17 | 18 | private final Map map; 19 | 20 | public TabManager(){ 21 | this.map = new LinkedHashMap(); 22 | } 23 | 24 | /** 25 | * 注册指令补全器 26 | * @param label 指令标签 27 | * @param tab 指令补全器 28 | * @return boolean 29 | */ 30 | public boolean registerTab(String label, BaseTabCompleter tab){ 31 | if(this.map.containsKey(label)){ 32 | return false; 33 | }else{ 34 | this.map.put(label, tab); 35 | return true; 36 | } 37 | } 38 | 39 | /** 40 | * 注销指令补全器 41 | * @param label 指令标签 42 | */ 43 | public void unregisterTab(String label){ 44 | if(this.map.containsKey(label)){ 45 | this.map.remove(label); 46 | } 47 | } 48 | 49 | @Override 50 | public List onTabComplete(CommandSender sender, Command command, String alias, String[] args) { 51 | if(args.length>0){ 52 | String label = args[0]; 53 | if(this.map.containsKey(label)){ 54 | return this.map.get(label).onTabComplete(sender, args); 55 | } 56 | List list = new ArrayList(); 57 | this.map.forEach((k,v) -> { 58 | if(k.startsWith(label) && v.allowTab(sender)){ 59 | list.add(k); 60 | } 61 | }); 62 | return list; 63 | } 64 | return null; 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/util/ConfigUpdatePackage.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.util; 2 | 3 | import com.google.gson.JsonObject; 4 | import java.util.LinkedHashMap; 5 | import java.util.LinkedList; 6 | import java.util.List; 7 | import java.util.Map; 8 | import org.bukkit.configuration.InvalidConfigurationException; 9 | import org.bukkit.configuration.file.YamlConfiguration; 10 | 11 | /** 12 | * 配置文件升级工具包 13 | * @author Dogend 14 | */ 15 | public class ConfigUpdatePackage{ 16 | 17 | private final String version; 18 | private final List removes; 19 | private final Map adds; 20 | private final boolean avaliable; 21 | 22 | public ConfigUpdatePackage(JsonObject jo){ 23 | this.removes = new LinkedList(); 24 | this.adds = new LinkedHashMap(); 25 | this.version = jo.get("version").getAsString(); 26 | if(jo.has("remove")){ 27 | jo.get("remove").getAsJsonArray().forEach(v -> this.removes.add(v.getAsString())); 28 | } 29 | if(jo.has("add")){ 30 | jo.get("add").getAsJsonArray().forEach(ja -> { 31 | Object value; 32 | JsonObject jao = ja.getAsJsonObject(); 33 | switch(jao.get("type").getAsString().toLowerCase()){ 34 | case "int": 35 | case "integer": 36 | value = jao.get("value").getAsInt(); 37 | break; 38 | case "double": 39 | value = jao.get("value").getAsDouble(); 40 | break; 41 | case "bool": 42 | case "boolean": 43 | value = jao.get("value").getAsBoolean(); 44 | break; 45 | case "str": 46 | case "string": 47 | default: 48 | value = jao.get("value").getAsString(); 49 | break; 50 | case "list": 51 | List list = new LinkedList(); 52 | jao.get("value").getAsJsonArray().forEach(v -> list.add(v.getAsString())); 53 | value = list; 54 | break; 55 | case "yml": 56 | case "yaml": 57 | YamlConfiguration yml = new YamlConfiguration(); 58 | try { 59 | yml.loadFromString(jao.get("value").getAsString()); 60 | value = yml.getConfigurationSection(jao.get("root").getAsString()); 61 | } catch (InvalidConfigurationException ex) { 62 | this.avaliable = false; 63 | return; 64 | } 65 | break; 66 | 67 | } 68 | this.adds.put(jao.get("key").getAsString(), value); 69 | }); 70 | } 71 | this.avaliable = true; 72 | } 73 | 74 | /** 75 | * 升级 76 | * @param yml 配置文件 77 | */ 78 | public void update(YamlConfiguration yml){ 79 | yml.set("version", this.version); 80 | this.removes.forEach(key -> yml.set(key, null)); 81 | this.adds.forEach((key,value) -> yml.set(key, value)); 82 | } 83 | 84 | public String getVersion() { 85 | return version; 86 | } 87 | 88 | public boolean isAvaliable(){ 89 | return this.avaliable; 90 | } 91 | } -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/util/ConfigUtil.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.util; 2 | 3 | import com.google.gson.JsonObject; 4 | import com.tripleying.dogend.mailbox.MailBox; 5 | import java.io.File; 6 | import java.io.StringReader; 7 | import java.util.LinkedHashMap; 8 | import java.util.Map; 9 | import org.bukkit.configuration.file.YamlConfiguration; 10 | 11 | /** 12 | * 配置工具 13 | * @author Dogend 14 | */ 15 | public class ConfigUtil { 16 | 17 | /** 18 | * 检查配置版本 19 | * @param config 配置名 20 | * @param yml 配置文件 21 | */ 22 | public static void checkConfigVersion(String config, YamlConfiguration yml){ 23 | if(yml.contains("version")){ 24 | String version = yml.getString("version"); 25 | Map map = new LinkedHashMap(); 26 | getUpdateMap(config, version, map); 27 | map.forEach((v,cup) -> { 28 | if(v.equals(yml.getString("version"))) cup.update(yml); 29 | }); 30 | if(!version.equals(yml.getString("version"))){ 31 | if(FileUtil.saveYaml(new StringReader(yml.saveToString()), new File(FileUtil.getMailBoxFolder(), config.concat(".yml")))){ 32 | MessageUtil.log(MessageUtil.config_update.replaceAll("%config%", config).replaceAll("%version%", yml.getString("version"))); 33 | }else{ 34 | MessageUtil.error(MessageUtil.config_save_error.replaceAll("%config%", config)); 35 | } 36 | } 37 | } 38 | } 39 | 40 | /** 41 | * 获取更新列表 42 | * @param config 配置名 43 | * @param version 版本 44 | * @param map LinkedHashMap 45 | */ 46 | public static void getUpdateMap(String config, String version, Map map){ 47 | JsonObject json = HTTPUtil.getJson(MailBox.getMailBox().getDescription().getWebsite().concat("/config?config=").concat(config).concat("&version=").concat(version)); 48 | if(json.get("update").getAsBoolean()){ 49 | ConfigUpdatePackage cup = new ConfigUpdatePackage(json); 50 | if(cup.isAvaliable()){ 51 | map.put(version, cup); 52 | getUpdateMap(config, cup.getVersion(), map); 53 | } 54 | } 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/util/FileUtil.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.util; 2 | 3 | import com.tripleying.dogend.mailbox.MailBox; 4 | import java.io.BufferedReader; 5 | import java.io.BufferedWriter; 6 | import java.io.File; 7 | import java.io.FileInputStream; 8 | import java.io.FileNotFoundException; 9 | import java.io.FileOutputStream; 10 | import java.io.IOException; 11 | import java.io.InputStream; 12 | import java.io.InputStreamReader; 13 | import java.io.OutputStreamWriter; 14 | import java.io.PrintWriter; 15 | import java.io.Reader; 16 | import java.io.UnsupportedEncodingException; 17 | import java.sql.ResultSet; 18 | import java.sql.SQLException; 19 | import java.util.Arrays; 20 | import java.util.List; 21 | import org.bukkit.configuration.InvalidConfigurationException; 22 | import org.bukkit.configuration.file.YamlConfiguration; 23 | 24 | /** 25 | * 文件工具 26 | * @author Dogend 27 | */ 28 | public class FileUtil { 29 | 30 | /** 31 | * 插件数据文件夹 32 | */ 33 | private final static File data_folder; 34 | /** 35 | * 默认编码格式 36 | */ 37 | private static String charset = "UTF-8"; 38 | /** 39 | * 1.9以下默认编码为UTF-8的服务端核心 40 | */ 41 | private static final List UTF8_Server; 42 | 43 | static{ 44 | data_folder = new File("plugins/MailBox"); 45 | UTF8_Server = Arrays.asList("Uranium", "Cauldron"); 46 | } 47 | 48 | /** 49 | * 设置默认编码 50 | * @param server 服务端核心 51 | */ 52 | public static void setCharset(String server){ 53 | if(!UTF8_Server.contains(server)) charset = System.getProperty("file.encoding"); 54 | } 55 | 56 | /** 57 | * 获取默认编码 58 | * @return charset 59 | */ 60 | public static String getCharset(){ 61 | return charset; 62 | } 63 | 64 | /** 65 | * 为所选路径创建文件夹并返回 66 | * @param path 路径 67 | * @return File 68 | */ 69 | public static File createFolder(String path){ 70 | File file = new File(data_folder, path); 71 | if(!file.exists()) file.mkdirs(); 72 | return file; 73 | } 74 | 75 | /** 76 | * 获取MailBox插件文件夹 77 | * @return File 78 | */ 79 | public static File getMailBoxFolder(){ 80 | File file = new File("plugins/MailBox"); 81 | if(!file.exists()) file.mkdirs(); 82 | return file; 83 | } 84 | 85 | /** 86 | * 获取jar内的文件 87 | * @param fileName 文件名 88 | * @return InputStream 89 | */ 90 | public static InputStream getInputStream(String fileName){ 91 | return MailBox.getMailBox().getResource(fileName); 92 | } 93 | 94 | /** 95 | * 获取jar内文件的Reader, 使用默认编码 96 | * @param fileName 文件名 97 | * @return InputStreamReader 98 | * @throws UnsupportedEncodingException 编码格式不支持 99 | */ 100 | public static InputStreamReader getInputStreamReader(String fileName) throws UnsupportedEncodingException{ 101 | return new InputStreamReader(getInputStream(fileName), charset); 102 | } 103 | 104 | /** 105 | * 获取jar内文件Reader并指定编码 106 | * @param fileName 文件名 107 | * @param charset 编码格式 108 | * @return InputStreamReader 109 | * @throws UnsupportedEncodingException 编码格式不支持 110 | */ 111 | public static InputStreamReader getInputStreamReader(String fileName, String charset) throws UnsupportedEncodingException{ 112 | return new InputStreamReader(getInputStream(fileName), charset); 113 | } 114 | 115 | /** 116 | * 读取一个yml 117 | * @param f 文件 118 | * @return YamlConfiguration 119 | * @throws java.io.FileNotFoundException 文件不存在 120 | * @throws java.io.UnsupportedEncodingException 不支持的编码 121 | */ 122 | public static YamlConfiguration getYaml(File f) throws FileNotFoundException, UnsupportedEncodingException{ 123 | return YamlConfiguration.loadConfiguration(new InputStreamReader(new FileInputStream(f), charset)); 124 | } 125 | 126 | /** 127 | * 读取一个yml 128 | * @param r Reader 129 | * @return YamlConfiguration 130 | */ 131 | public static YamlConfiguration getYaml(Reader r){ 132 | return YamlConfiguration.loadConfiguration(r); 133 | } 134 | 135 | /** 136 | * 获取配置文件(不存在则自动创建) 137 | * @param file 配置文件名 138 | * @return YamlConfiguration 139 | */ 140 | public static YamlConfiguration getConfig(String file){ 141 | File f = new File(getMailBoxFolder(), file); 142 | if(!f.exists()){ 143 | try { 144 | try (InputStreamReader isr = getInputStreamReader(file)) { 145 | if(saveYaml(isr, f)){ 146 | MessageUtil.log(MessageUtil.file_create.replaceAll("%file%", file)); 147 | }else{ 148 | throw new IOException(); 149 | } 150 | isr.close(); 151 | } 152 | } catch (IOException ex) { 153 | MessageUtil.error(MessageUtil.file_create_error.replaceAll("%file%", file)); 154 | return null; 155 | } 156 | } 157 | MessageUtil.log(MessageUtil.file_read.replaceAll("%file%", file)); 158 | try { 159 | return getYaml(f); 160 | } catch (Exception ex) { 161 | return new YamlConfiguration(); 162 | } 163 | } 164 | 165 | /** 166 | * 保存Yaml文件 167 | * @param reader InputStreamReader / StringReader 168 | * @param file 目标文件 169 | * @return boolean 170 | */ 171 | public static boolean saveYaml(Reader reader, File file){ 172 | try { 173 | OutputStreamWriter osw; 174 | BufferedWriter bw; 175 | PrintWriter pw; 176 | try(BufferedReader br = new BufferedReader(reader)){ 177 | osw = new OutputStreamWriter(new FileOutputStream(file), charset); 178 | bw = new BufferedWriter(osw); 179 | pw = new PrintWriter(bw); 180 | String temp; 181 | while((temp=br.readLine())!=null){ 182 | pw.println(temp); 183 | } 184 | br.close(); 185 | reader.close(); 186 | } 187 | pw.close(); 188 | bw.close(); 189 | osw.close(); 190 | return true; 191 | } catch (IOException ex) { 192 | ex.printStackTrace(); 193 | return false; 194 | } 195 | } 196 | 197 | /** 198 | * 从yml获取StringList 199 | * @param yml yml 200 | * @param key 键 201 | * @return 值 202 | */ 203 | public static List getYamlStringList(YamlConfiguration yml, String key){ 204 | List list = yml.getStringList(key); 205 | if(list.isEmpty()){ 206 | return Arrays.asList(yml.getString(key)); 207 | }else{ 208 | return list; 209 | } 210 | } 211 | 212 | /** 213 | * 将String读取为Yaml并取出指定key的值 214 | * @param rs 结果集 215 | * @param key 路径 216 | * @return ConfigurationSection 217 | * @throws InvalidConfigurationException 配置无效异常 218 | * @throws java.sql.SQLException SQL异常 219 | */ 220 | public static Object string2Section(ResultSet rs, String key) throws InvalidConfigurationException, SQLException{ 221 | YamlConfiguration yml = new YamlConfiguration(); 222 | yml.loadFromString(rs.getString(key)); 223 | return yml.contains(key)?yml.get(key):null; 224 | } 225 | 226 | /** 227 | * 将yml的一个片段取出并保存为String 228 | * @param yml yml 229 | * @param key 路径 230 | * @return String 231 | */ 232 | public static String section2String(YamlConfiguration yml, String key){ 233 | Object o = yml.get(key); 234 | YamlConfiguration ny = new YamlConfiguration(); 235 | ny.set(key, o); 236 | return ny.saveToString(); 237 | } 238 | 239 | } 240 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/util/HTTPUtil.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.util; 2 | 3 | import com.google.gson.JsonObject; 4 | import com.google.gson.JsonParser; 5 | import java.io.BufferedReader; 6 | import java.io.File; 7 | import java.io.FileOutputStream; 8 | import java.io.IOException; 9 | import java.io.InputStream; 10 | import java.io.InputStreamReader; 11 | import java.net.HttpURLConnection; 12 | import java.net.URL; 13 | import java.net.URLConnection; 14 | import java.util.ArrayList; 15 | import java.util.List; 16 | 17 | /** 18 | * HTTP工具 19 | * @author Dogend 20 | */ 21 | public class HTTPUtil { 22 | 23 | /** 24 | * 按行获取文字 25 | * @param requestUrl 请求地址 26 | * @return List 27 | */ 28 | public static List getLineList(String requestUrl){ 29 | try{ 30 | URL url = new URL(requestUrl); 31 | URLConnection urlConnection = url.openConnection(); 32 | urlConnection.setConnectTimeout(3000); 33 | urlConnection.setReadTimeout(2000); 34 | HttpURLConnection connection; 35 | if(urlConnection instanceof HttpURLConnection) 36 | { 37 | connection = (HttpURLConnection) urlConnection; 38 | } 39 | else 40 | { 41 | return null; 42 | } 43 | BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8")); 44 | List urlString = new ArrayList(); 45 | String current; 46 | while((current = in.readLine()) != null) 47 | { 48 | urlString.add(current); 49 | } 50 | return urlString; 51 | }catch(IOException ex){ 52 | ex.printStackTrace(); 53 | } 54 | return null; 55 | } 56 | 57 | /** 58 | * 获取json对象 59 | * @param requestUrl 请求地址 60 | * @return json对象 61 | */ 62 | public static JsonObject getJson(String requestUrl){ 63 | String res = ""; 64 | JsonObject object = null; 65 | StringBuilder buffer = new StringBuilder(); 66 | try { 67 | URL url = new URL(requestUrl); 68 | HttpURLConnection urlCon = (HttpURLConnection) url.openConnection(); 69 | if (200 == urlCon.getResponseCode()) { 70 | InputStream is = urlCon.getInputStream(); 71 | InputStreamReader isr = new InputStreamReader(is, "utf-8"); 72 | BufferedReader br = new BufferedReader(isr); 73 | String str = null; 74 | while ((str = br.readLine()) != null) { 75 | buffer.append(str); 76 | } 77 | br.close(); 78 | isr.close(); 79 | is.close(); 80 | res = buffer.toString(); 81 | JsonParser parse = new JsonParser(); 82 | object = (JsonObject) parse.parse(res); 83 | } else { 84 | throw new Exception(); 85 | } 86 | } catch (Exception e) { 87 | } 88 | return object; 89 | } 90 | 91 | /** 92 | * 下载文件 93 | * @param requestUrl 请求地址 94 | * @param file 目标文件 95 | * @throws Exception 异常 96 | */ 97 | public static void downloadFile(String requestUrl, File file) throws Exception { 98 | int byteread = 0; 99 | URL url = new URL(requestUrl); 100 | URLConnection conn = url.openConnection(); 101 | HttpURLConnection httpURLConnection = (HttpURLConnection) conn; 102 | httpURLConnection.setRequestProperty("Charset", "UTF-8"); 103 | httpURLConnection.connect(); 104 | InputStream inStream = httpURLConnection.getInputStream(); 105 | FileOutputStream fs = new FileOutputStream(file); 106 | byte[] buffer = new byte[1204]; 107 | while ((byteread = inStream.read(buffer)) != -1) { 108 | fs.write(buffer, 0, byteread); 109 | } 110 | } 111 | 112 | } 113 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/util/ItemStackUtil.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.util; 2 | 3 | import com.tripleying.dogend.mailbox.MailBox; 4 | import java.util.ArrayList; 5 | import java.util.HashMap; 6 | import java.util.List; 7 | import java.util.Set; 8 | import org.bukkit.entity.Player; 9 | import org.bukkit.inventory.ItemStack; 10 | 11 | /** 12 | * 物品堆工具 13 | * @author Dogend 14 | */ 15 | public class ItemStackUtil { 16 | 17 | /** 18 | * 判断玩家背包是否有足够位置放下物品堆 19 | * @param p 玩家 20 | * @param il 物品堆列表 21 | * @return 还需要的空位 22 | */ 23 | public static int hasBlank(Player p, List il){ 24 | int ils = il.size(); 25 | int allAir = 0; 26 | for(ItemStack it:MailBox.getMCVersion()<1.10 ? p.getInventory().getContents() : p.getInventory().getStorageContents()){ 27 | if(it==null){ 28 | if((allAir++)>=ils){ 29 | return 0; 30 | } 31 | } 32 | } 33 | if(allAir im = p.getInventory().all(is1.getType()); 38 | if(!im.isEmpty()){ 39 | Set ks = im.keySet(); 40 | for(Integer k:ks){ 41 | ItemStack is2 = im.get(k); 42 | if(is2.isSimilar(is1) && is2.getAmount()+is1.getAmount()<=is2.getMaxStackSize()){ 43 | continue o; 44 | } 45 | } 46 | } 47 | needAir++; 48 | } 49 | return allAir>=needAir?0:needAir-allAir; 50 | }else{ 51 | return 0; 52 | } 53 | } 54 | 55 | /** 56 | * 判断玩家背包里是否有指定数量的物品 57 | * @param isl 物品列表 58 | * @param p 玩家 59 | * @return 缺失的物品列表 60 | */ 61 | public static List hasSendItem(List isl, Player p){ 62 | List lackList = new ArrayList(); 63 | for(int i=0;i removeSendItem(List isl, Player p){ 99 | boolean success = true; 100 | ArrayList clearList = new ArrayList(); 101 | HashMap reduceList = new HashMap(); 102 | List lackList = new ArrayList(); 103 | for(int i=0;i { 138 | p.getInventory().clear(k); 139 | }); 140 | } 141 | if(!reduceList.isEmpty()){ 142 | reduceList.forEach((k, v) -> { 143 | p.getInventory().setItem(k, v); 144 | }); 145 | } 146 | } 147 | return lackList; 148 | } 149 | 150 | } 151 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/util/MessageUtil.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.util; 2 | 3 | import org.bukkit.Bukkit; 4 | import org.bukkit.command.CommandSender; 5 | import org.bukkit.command.ConsoleCommandSender; 6 | import org.bukkit.configuration.file.YamlConfiguration; 7 | 8 | /** 9 | * 消息工具 10 | * @author Dogend 11 | */ 12 | public class MessageUtil { 13 | 14 | /** 15 | * 控制台对象 16 | */ 17 | private static final ConsoleCommandSender console; 18 | /** 19 | * 插件前缀 20 | */ 21 | private static String prefix; 22 | // 重载 23 | public static String reload_load; 24 | public static String reload_unload; 25 | public static String reload_finish; 26 | // 文件 27 | public static String file_read; 28 | public static String file_create; 29 | public static String file_create_error; 30 | // 配置 31 | public static String config_update; 32 | public static String config_save_error; 33 | // 数据 34 | public static String data_enable; 35 | public static String data_enable_error; 36 | public static String data_reg; 37 | public static String data_reg_error; 38 | public static String data_unreg; 39 | // 邮件 40 | public static String mail_reg; 41 | public static String mail_reg_error; 42 | public static String mail_unreg; 43 | // 金钱 44 | public static String money_reg; 45 | public static String money_reg_invalid; 46 | public static String money_reg_duplicate; 47 | public static String money_unreg; 48 | // 指令 49 | public static String command_reg; 50 | public static String command_reg_error; 51 | public static String command_unreg; 52 | public static String command_help; 53 | // 监听器 54 | public static String listener_reg; 55 | public static String listener_unreg; 56 | // 模块 57 | public static String modlue_load_empty; 58 | public static String modlue_load_success; 59 | public static String modlue_load_error_not_jar; 60 | public static String modlue_load_error_not_info; 61 | public static String modlue_load_error_info_err; 62 | public static String modlue_load_error_has_duplicate; 63 | public static String modlue_load_error_depend_plugin; 64 | public static String modlue_load_error_depend_module; 65 | public static String modlue_load_error_recycle_depend; 66 | public static String modlue_load_error_main_err; 67 | public static String modlue_unload; 68 | public static String modlue_load_error_main_find; 69 | public static String modlue_load_error_main_init; 70 | public static String modlue_load_error_no_depend; 71 | 72 | static { 73 | console = Bukkit.getConsoleSender(); 74 | prefix = "§b[MailBox]: "; 75 | reload_load = "正在加载插件......"; 76 | reload_unload = "正在卸载插件......"; 77 | reload_finish = "插件重载完成."; 78 | file_read = "读取文件: §b%file%"; 79 | file_create = "创建文件: §b%file%"; 80 | file_create_error = "创建文件失败: §b%file%"; 81 | config_update = "已将 %config%.yml 更新至 v%version%"; 82 | config_save_error = "保存 %config% 的新配置文件失败"; 83 | } 84 | 85 | public static void init(YamlConfiguration yml){ 86 | prefix = color(yml.getString("prefix", "&b[MailBox]: ")); 87 | reload_load = color(yml.getString("reload.load", "正在加载插件......")); 88 | reload_unload = color(yml.getString("reload.unload", "正在卸载插件......")); 89 | reload_finish = color(yml.getString("reload.finish", "插件重载完成.")); 90 | file_read = color(yml.getString("file.read", "读取文件: &b%file%")); 91 | file_create = color(yml.getString("file.create", "创建文件: &b%file%")); 92 | file_create_error = color(yml.getString("file.create-error", "创建文件失败: &b%file%")); 93 | config_update = color(yml.getString("config.update", "已将 %config%.yml 更新至 v%version%")); 94 | config_save_error = color(yml.getString("config.save-error", "保存 %config% 的新配置文件失败")); 95 | data_enable = color(yml.getString("data.enable", "已启用数据源: &6%data%")); 96 | data_enable_error = color(yml.getString("data.enable-error", "数据源: %data% 启用失败, 卸载插件")); 97 | data_reg = color(yml.getString("data.reg", "注册数据源: &6%data%")); 98 | data_reg_error = color(yml.getString("data.reg-error", "注册数据源失败, 已有同名数据源被注册: &6%data%")); 99 | data_unreg = color(yml.getString("data.unreg", "已卸载其他数据源")); 100 | mail_reg = color(yml.getString("mail.reg", "注册系统邮件: &6%mail%")); 101 | mail_reg_error = color(yml.getString("mail.reg-error", "注册系统邮件失败, 已有同名系统邮件被注册: &6%mail%")); 102 | mail_unreg = color(yml.getString("mail.unreg", "注销系统邮件: &6%mail%")); 103 | money_reg = color(yml.getString("money.reg", "注册金钱: &6%money%")); 104 | money_reg_invalid = color(yml.getString("money.reg-invalid", "注册金钱失败, 无效的金钱类: &6%money%")); 105 | money_reg_duplicate = color(yml.getString("money.reg-duplicate", "注册金钱失败, 已有同名金钱被注册: &6%money%")); 106 | money_unreg = color(yml.getString("money.unreg", "注销金钱: &6%money%")); 107 | command_reg = color(yml.getString("command.reg", "注册指令: &6%command%")); 108 | command_reg_error = color(yml.getString("command.reg-error", "注册指令失败, 已有同名指令被注册: &6%command%")); 109 | command_unreg = color(yml.getString("command.unreg", "注销指令: &6%command%")); 110 | command_help = color(yml.getString("command.help", "&b==========&6[MailBox邮箱]&b==========")); 111 | listener_reg = color(yml.getString("listener.reg", "注册监听器: &6%listener%")); 112 | listener_unreg = color(yml.getString("listener.unreg", "注销监听器: &6%listener%")); 113 | modlue_load_empty = color(yml.getString("modlue.load.empty", "无本地模块可加载")); 114 | modlue_load_success = color(yml.getString("modlue.load.success", "加载模块: &6%module% - v%version%")); 115 | modlue_load_error_not_jar = color(yml.getString("modlue.load.error.not-jar", "模块加载失败: %module% 无效的Jar文件 ")); 116 | modlue_load_error_not_info = color(yml.getString("modlue.load.error.not-info", "模块加载失败: %module% 读取模块信息失败 ")); 117 | modlue_load_error_info_err = color(yml.getString("modlue.load.error.info-err", "模块加载失败: %module% 模块信息不可用 ")); 118 | modlue_load_error_has_duplicate = color(yml.getString("modlue.load.error.has-duplicate", "模块加载失败: %module% 已有重名模块被加载: %another%")); 119 | modlue_load_error_depend_plugin = color(yml.getString("modlue.load.error.depend-plugin", "模块加载失败: %module% 缺少前置插件: %depends%")); 120 | modlue_load_error_depend_module = color(yml.getString("modlue.load.error.depend-module", "模块加载失败: %module% 缺少前置模块: %depends%")); 121 | modlue_load_error_recycle_depend = color(yml.getString("modlue.load.error.recycle-depend", "模块加载失败: %module% 检测到循环依赖")); 122 | modlue_load_error_main_err = color(yml.getString("modlue.load.error.main.read-err", "模块加载失败: %module% 主类错误")); 123 | modlue_load_error_main_find = color(yml.getString("modlue.load.error.main.not-found", "模块加载失败: %module% 找不到模块主类 %main%")); 124 | modlue_load_error_main_init = color(yml.getString("modlue.load.error.main.init-err", "模块加载失败: %module% 调用初始化失败")); 125 | modlue_load_error_no_depend = color(yml.getString("modlue.load.error.no-depend", "警告: 模块 %module% 从非前置模块 %provider% 加载了类 %class%")); 126 | 127 | modlue_unload = color(yml.getString("modlue.unload", "卸载模块: &6%module%")); 128 | } 129 | 130 | /** 131 | * 将&转换为颜色字符§ 132 | * @param original 原字符串 133 | * @return 转换后的字符串 134 | */ 135 | public static String color(String original){ 136 | return original.replaceAll("&", "§"); 137 | } 138 | 139 | /** 140 | * 发送日志(绿色) 141 | * @param cs 指令发送者 142 | * @param msg 信息 143 | */ 144 | public static void log(CommandSender cs, String msg){ 145 | cs.sendMessage(prefix+"§a"+msg); 146 | } 147 | 148 | /** 149 | * 后台打印日志(绿色) 150 | * @param msg 信息 151 | */ 152 | public static void log(String msg){ 153 | log(console, msg); 154 | } 155 | 156 | /** 157 | * 发送错误(红色) 158 | * @param cs 指令发送者 159 | * @param msg 信息 160 | */ 161 | public static void error(CommandSender cs, String msg){ 162 | cs.sendMessage(prefix+"§c"+msg); 163 | } 164 | 165 | /** 166 | * 后台打印错误(红色) 167 | * @param msg 信息 168 | */ 169 | public static void error(String msg){ 170 | error(console, msg); 171 | } 172 | 173 | } 174 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/util/ModuleUtil.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.util; 2 | 3 | import java.io.File; 4 | import com.tripleying.dogend.mailbox.api.module.MailBoxModule; 5 | import com.tripleying.dogend.mailbox.api.module.ModuleInfo; 6 | import java.io.BufferedReader; 7 | import java.io.BufferedWriter; 8 | import java.io.FileOutputStream; 9 | import java.io.IOException; 10 | import java.io.InputStream; 11 | import java.io.InputStreamReader; 12 | import java.io.OutputStreamWriter; 13 | import java.io.PrintWriter; 14 | import java.io.UnsupportedEncodingException; 15 | import java.util.jar.JarEntry; 16 | import java.util.jar.JarFile; 17 | import org.bukkit.configuration.file.YamlConfiguration; 18 | 19 | /** 20 | * 模块工具 21 | * @author Dogend 22 | */ 23 | public class ModuleUtil { 24 | 25 | /** 26 | * 获取模块文件夹 27 | * @return File 28 | */ 29 | public static File getModuleFolder(){ 30 | File file = new File("plugins/MailBox/Module"); 31 | if(!file.exists()) file.mkdirs(); 32 | return file; 33 | } 34 | 35 | /** 36 | * 获取模块文件夹 37 | * @param module 模块 38 | * @return File 39 | */ 40 | public static File getModuleDataFolder(MailBoxModule module){ 41 | File file = new File(getModuleFolder(), module.getInfo().getName()); 42 | if(!file.exists()) file.mkdirs(); 43 | return file; 44 | } 45 | 46 | /** 47 | * 保存配置文件 48 | * @param module 模块 49 | * @param file 文件 50 | */ 51 | public static void saveConfig(MailBoxModule module, String file){ 52 | JarFile jar = module.getJar(); 53 | File f = new File(getModuleDataFolder(module), file); 54 | File parent = f.getParentFile(); 55 | if(!parent.exists()) parent.mkdirs(); 56 | if(!f.exists()){ 57 | try{ 58 | OutputStreamWriter osw; 59 | BufferedWriter bw; 60 | PrintWriter pw; 61 | try (InputStreamReader isr = getInputStreamReader(jar.getInputStream(jar.getEntry(file))); 62 | BufferedReader br = new BufferedReader(isr)) { 63 | osw = new OutputStreamWriter(new FileOutputStream(f), FileUtil.getCharset()); 64 | bw = new BufferedWriter(osw); 65 | pw = new PrintWriter(bw); 66 | String temp; 67 | while((temp=br.readLine())!=null){ 68 | pw.println(temp); 69 | } 70 | br.close(); 71 | isr.close(); 72 | } 73 | pw.close(); 74 | bw.close(); 75 | osw.close(); 76 | MessageUtil.log(MessageUtil.file_create.replaceAll("%file%", file)); 77 | }catch(IOException ex){ 78 | ex.printStackTrace(); 79 | MessageUtil.error(MessageUtil.file_create_error.replaceAll("%file%", file)); 80 | } 81 | } 82 | } 83 | 84 | /** 85 | * 获取配置文件 86 | * @param module 模块 87 | * @param file 文件 88 | * @return YamlConfiguration 89 | */ 90 | public static YamlConfiguration getConfig(MailBoxModule module, String file){ 91 | File f = new File(getModuleDataFolder(module), file); 92 | if(!f.exists()) saveConfig(module, file); 93 | try { 94 | return FileUtil.getYaml(f); 95 | } catch (Exception ex) { 96 | return new YamlConfiguration(); 97 | } 98 | } 99 | 100 | /** 101 | * 获取使用默认编码创建一个InputStream的Reader 102 | * @param is 输入流 103 | * @return InputStreamReader 104 | * @throws UnsupportedEncodingException 编码格式不支持 105 | */ 106 | public static InputStreamReader getInputStreamReader(InputStream is) throws UnsupportedEncodingException{ 107 | return new InputStreamReader(is, FileUtil.getCharset()); 108 | } 109 | 110 | /** 111 | * 从jar加载模块信息 112 | * @param jar Jar 113 | * @return ModuleInfo 114 | * @throws Exception 异常 115 | */ 116 | public static ModuleInfo loadModuleInfo(JarFile jar) throws Exception{ 117 | JarEntry entry = jar.getJarEntry("module.yml"); 118 | try( 119 | InputStream input = jar.getInputStream(entry); 120 | InputStreamReader reader = getInputStreamReader(input) 121 | ){ 122 | YamlConfiguration yml = YamlConfiguration.loadConfiguration(reader); 123 | return new ModuleInfo(yml); 124 | } 125 | } 126 | 127 | } 128 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/util/ReflectUtil.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.util; 2 | 3 | import com.tripleying.dogend.mailbox.api.data.DataType; 4 | import com.tripleying.dogend.mailbox.api.mail.SystemMail; 5 | import java.lang.reflect.Field; 6 | import java.lang.reflect.Method; 7 | import java.util.ArrayList; 8 | import java.util.Arrays; 9 | import java.util.Iterator; 10 | import java.util.LinkedHashMap; 11 | import java.util.List; 12 | import java.util.Map; 13 | import org.bukkit.configuration.file.YamlConfiguration; 14 | import com.tripleying.dogend.mailbox.api.data.Data; 15 | import com.tripleying.dogend.mailbox.api.mail.CustomData; 16 | 17 | /** 18 | * 反射工具 19 | * @author Dogend 20 | */ 21 | public class ReflectUtil { 22 | 23 | /** 24 | * 获取类的方法 25 | * @param clazz 类 26 | * @param methodName 方法名 27 | * @param params 参数列表 28 | * @return 方法 29 | */ 30 | public static Method getMethod(Class clazz, String methodName, Class... params) { 31 | Method method = null; 32 | try { 33 | method = clazz.getMethod(methodName, params); 34 | } catch (NoSuchMethodException | SecurityException e) {} 35 | return method; 36 | } 37 | 38 | /** 39 | * 获取类的字段 40 | * @param clazz 类 41 | * @param fieldNames 字段名 42 | * @return 字段 43 | * @throws Exception 异常 44 | */ 45 | public static Field findField(Class clazz, String ... fieldNames) throws Exception { 46 | Exception failed = null; 47 | for (String fieldName : fieldNames) { 48 | try { 49 | Field f = clazz.getDeclaredField(fieldName); 50 | f.setAccessible(true); 51 | return f; 52 | } 53 | catch (Exception e) { 54 | failed = e; 55 | } 56 | } 57 | return null; 58 | } 59 | 60 | /** 61 | * 获取私有字段值 62 | * @param T 63 | * @param E 64 | * @param classToAccess 类 65 | * @param instance 实例 66 | * @param fieldNames 字段名 67 | * @return T 68 | * @throws Exception 异常 69 | */ 70 | public static T getPrivateValue(Class classToAccess, E instance, String ... fieldNames) throws Exception { 71 | return (T)findField(classToAccess, fieldNames).get(instance); 72 | } 73 | 74 | /** 75 | * 获取系统邮件需要在数据源中创建的字段及类型 76 | * @param clazz 继承系统邮件的类 77 | * @return Map 78 | */ 79 | public static Map getSystemMailColumns(Class clazz){ 80 | Map map = new LinkedHashMap(); 81 | List fields = new ArrayList(); 82 | Class sc = clazz; 83 | do{ 84 | fields.addAll(Arrays.asList(sc.getDeclaredFields())); 85 | sc = sc.getSuperclass(); 86 | }while(sc!=SystemMail.class); 87 | for(Field field:fields){ 88 | if(field.isAnnotationPresent(Data.class)){ 89 | map.put(field.getName(), field.getDeclaredAnnotation(Data.class)); 90 | } 91 | } 92 | return map; 93 | } 94 | 95 | /** 96 | * 获取系统邮件需要在数据源中创建的字段及值 97 | * @param sm 系统邮件实例 98 | * @param cols 系统邮件在数据源中创建的字段及类型 99 | * @return Map 100 | * @throws java.lang.Exception 异常 101 | */ 102 | public static Map getSystemMailValues(SystemMail sm, Map cols) throws Exception { 103 | Map map = new LinkedHashMap(); 104 | Map temp = new LinkedHashMap(); 105 | Map fields = new LinkedHashMap(); 106 | Class sc = sm.getClass(); 107 | do{ 108 | fields.put(sc, sc.getDeclaredFields()); 109 | sc = sc.getSuperclass(); 110 | }while(sc!=SystemMail.class); 111 | Iterator> it = fields.entrySet().iterator(); 112 | while(it.hasNext()){ 113 | Map.Entry me = it.next(); 114 | for(Field f:me.getValue()){ 115 | if(f.isAnnotationPresent(Data.class)){ 116 | f.setAccessible(true); 117 | temp.put(f.getName(), f.get(sm)); 118 | } 119 | } 120 | } 121 | cols.forEach((c,dc) -> { 122 | if(dc.type()==DataType.YamlString){ 123 | YamlConfiguration yml = new YamlConfiguration(); 124 | yml.set(c, temp.get(c)); 125 | map.put(c, yml.saveToString()); 126 | }else{ 127 | map.put(c, temp.get(c)); 128 | } 129 | }); 130 | return map; 131 | } 132 | 133 | /** 134 | * 获取自定义数据需要在数据源中创建的字段及类型 135 | * @param cd 继承自定义数据的类 136 | * @since 3.1.0 137 | * @return Map 138 | */ 139 | public static Map getCustomDataColumns(Class cd){ 140 | Map map = new LinkedHashMap(); 141 | List fields = new ArrayList(); 142 | Class sc = cd; 143 | do{ 144 | fields.addAll(Arrays.asList(sc.getDeclaredFields())); 145 | sc = sc.getSuperclass(); 146 | }while(sc!=CustomData.class); 147 | for(Field field:fields){ 148 | if(field.isAnnotationPresent(Data.class)){ 149 | map.put(field.getName(), field.getDeclaredAnnotation(Data.class)); 150 | } 151 | } 152 | return map; 153 | } 154 | 155 | /** 156 | * 获取自定义数据需要在数据源中创建的字段及值 157 | * @param cd 自定义数据实例 158 | * @param cols 自定义数据在数据源中创建的字段及类型 159 | * @since 3.1.0 160 | * @return Map 161 | * @throws java.lang.Exception 异常 162 | */ 163 | public static Map getCustomDataValues(CustomData cd, Map cols) throws Exception { 164 | Map map = new LinkedHashMap(); 165 | Map temp = new LinkedHashMap(); 166 | Map fields = new LinkedHashMap(); 167 | Class sc = cd.getClass(); 168 | do{ 169 | fields.put(sc, sc.getDeclaredFields()); 170 | sc = sc.getSuperclass(); 171 | }while(sc!=CustomData.class); 172 | Iterator> it = fields.entrySet().iterator(); 173 | while(it.hasNext()){ 174 | Map.Entry me = it.next(); 175 | for(Field f:me.getValue()){ 176 | if(f.isAnnotationPresent(Data.class)){ 177 | f.setAccessible(true); 178 | temp.put(f.getName(), f.get(cd)); 179 | } 180 | } 181 | } 182 | cols.forEach((c,dc) -> { 183 | if(dc.type()==DataType.YamlString){ 184 | YamlConfiguration yml = new YamlConfiguration(); 185 | yml.set(c, temp.get(c)); 186 | map.put(c, yml.saveToString()); 187 | }else{ 188 | map.put(c, temp.get(c)); 189 | } 190 | }); 191 | return map; 192 | } 193 | 194 | } 195 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/util/TimeUtil.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.util; 2 | 3 | import com.tripleying.dogend.mailbox.api.util.CommonConfig; 4 | import java.text.ParseException; 5 | import java.text.SimpleDateFormat; 6 | import java.util.Date; 7 | 8 | /** 9 | * 时间工具 10 | * @author Dogend 11 | */ 12 | public class TimeUtil { 13 | 14 | private static final SimpleDateFormat sdf; 15 | 16 | static{ 17 | sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 18 | } 19 | 20 | /** 21 | * 将日期格式化为字符串 22 | * @param date Date 23 | * @return String 24 | */ 25 | public static String date2String(Date date){ 26 | return sdf.format(date); 27 | } 28 | 29 | /** 30 | * 将时间戳格式化为字符串 31 | * @param time long 32 | * @return String 33 | */ 34 | public static String long2String(long time){ 35 | return sdf.format(new Date(time)); 36 | } 37 | 38 | /** 39 | * 获取当前时间并格式化为字符串 40 | * @return String 41 | */ 42 | public static String currentTimeString(){ 43 | return long2String(System.currentTimeMillis()); 44 | } 45 | 46 | /** 47 | * 判断个人邮件是否过期 48 | * @param sendtime 发送时间 49 | * @return boolean 50 | */ 51 | public static boolean isExpire(String sendtime){ 52 | try { 53 | long deadline = sdf.parse(sendtime).getTime() + 1000L*60*60*24*CommonConfig.expire_day; 54 | return System.currentTimeMillis()>deadline; 55 | } catch (ParseException ex) { 56 | ex.printStackTrace(); 57 | return false; 58 | } 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/com/tripleying/dogend/mailbox/util/UpdateUtil.java: -------------------------------------------------------------------------------- 1 | package com.tripleying.dogend.mailbox.util; 2 | 3 | import com.google.gson.JsonObject; 4 | import com.tripleying.dogend.mailbox.MailBox; 5 | import com.tripleying.dogend.mailbox.api.util.Version; 6 | import java.io.File; 7 | import java.util.Iterator; 8 | import java.util.List; 9 | import java.util.Map; 10 | import org.bukkit.Bukkit; 11 | import org.bukkit.command.CommandSender; 12 | import org.bukkit.command.PluginCommand; 13 | import org.bukkit.command.SimpleCommandMap; 14 | import org.bukkit.plugin.Plugin; 15 | import org.bukkit.plugin.PluginManager; 16 | import org.bukkit.plugin.SimplePluginManager; 17 | import org.bukkit.scheduler.BukkitRunnable; 18 | 19 | /** 20 | * 更新工具 21 | * @author Dogend 22 | */ 23 | public class UpdateUtil { 24 | 25 | /** 26 | * 更新插件 27 | * @param sender 指令发送者 28 | * @param download 是否下载新版本 29 | */ 30 | public static void updatePlugin(CommandSender sender, boolean download){ 31 | new BukkitRunnable(){ 32 | @Override 33 | public void run(){ 34 | try{ 35 | List version = HTTPUtil.getLineList(MailBox.getMailBox().getDescription().getWebsite()+"/version"); 36 | if(version.isEmpty()){ 37 | MessageUtil.error(sender, "获取版本信息失败"); 38 | }else{ 39 | Version now = new Version(MailBox.getMailBox().getDescription().getVersion()); 40 | if(now.checkNewest(version.get(0))){ 41 | MessageUtil.log(sender, "插件已是最新版本"); 42 | }else{ 43 | MessageUtil.log(sender, "检测到最新版本, 正在获取更新信息"); 44 | JsonObject jo = HTTPUtil.getJson(MailBox.getMailBox().getDescription().getWebsite()+"/version?info"); 45 | MessageUtil.log(sender, "检测到新版本: ".concat(jo.get("version").getAsString())); 46 | MessageUtil.log(sender, "更新时间: ".concat(jo.get("time").getAsString())); 47 | MessageUtil.log(sender, "更新内容:"); 48 | jo.getAsJsonArray("info").forEach(i -> MessageUtil.log("-".concat(i.getAsString()))); 49 | if(download){ 50 | MessageUtil.log(sender, "准备更新......"); 51 | File newfile = new File("Plugins/[邮箱]-MailBox-v"+version.get(0)+".jar"); 52 | MessageUtil.log(sender, "准备下载新文件......"); 53 | HTTPUtil.downloadFile(MailBox.getMailBox().getDescription().getWebsite()+"/files/download.php", newfile); 54 | MessageUtil.log(sender, "下载完成, 准备卸载旧插件并删除, 然后加载新插件"); 55 | File oldfile = MailBox.getMailBox().getFile(); 56 | unloadPlugin("MailBox"); 57 | oldfile.delete(); 58 | loadPlugin(newfile); 59 | } 60 | } 61 | } 62 | } catch (Exception ex) { 63 | MessageUtil.error(sender, "更新失败"); 64 | ex.printStackTrace(); 65 | } 66 | } 67 | }.runTask(MailBox.getMailBox()); 68 | } 69 | 70 | /** 71 | * 加载插件 72 | * (此代码来自CatServer) 73 | * @param file 插件文件 74 | */ 75 | public static void loadPlugin(File file){ 76 | PluginManager manager = Bukkit.getServer().getPluginManager(); 77 | try{ 78 | Plugin plugin = manager.loadPlugin(file); 79 | plugin.onLoad(); 80 | manager.enablePlugin(plugin); 81 | }catch (Exception ex){ 82 | ex.printStackTrace(); 83 | } 84 | } 85 | 86 | /** 87 | * 卸载插件 88 | * (此代码来自CatServer) 89 | * @param pluginName 插件名 90 | */ 91 | public static void unloadPlugin(String pluginName){ 92 | SimplePluginManager manager = (SimplePluginManager)Bukkit.getServer().getPluginManager(); 93 | try{ 94 | List plugins = (List)ReflectUtil.getPrivateValue(SimplePluginManager.class, manager, "plugins"); 95 | Map lookupNames = (Map)ReflectUtil.getPrivateValue(SimplePluginManager.class, manager, "lookupNames"); 96 | SimpleCommandMap commandMap = (SimpleCommandMap)ReflectUtil.getPrivateValue(SimplePluginManager.class, manager, "commandMap"); 97 | Map knownCommands = (Map)ReflectUtil.getPrivateValue(SimpleCommandMap.class, commandMap, "knownCommands"); 98 | for (Plugin plugin : manager.getPlugins()) { 99 | if (!plugin.getDescription().getName().equalsIgnoreCase(pluginName)) continue; 100 | manager.disablePlugin(plugin); 101 | plugins.remove(plugin); 102 | lookupNames.remove(pluginName); 103 | Iterator it = knownCommands.entrySet().iterator(); 104 | while (it.hasNext()) { 105 | PluginCommand command; 106 | Map.Entry entry = it.next(); 107 | if (!(entry.getValue() instanceof PluginCommand) || (command = (PluginCommand)entry.getValue()).getPlugin() != plugin) continue; 108 | command.unregister(commandMap); 109 | it.remove(); 110 | } 111 | return; 112 | } 113 | }catch (Exception ex){ 114 | ex.printStackTrace(); 115 | } 116 | 117 | } 118 | 119 | } 120 | -------------------------------------------------------------------------------- /src/main/resources/config.yml: -------------------------------------------------------------------------------- 1 | version: '3.0.0' 2 | # 从已装的数据源选择一个进行使用 3 | # Select one of the installed data sources to use 4 | database: 'sqlite' 5 | # 个人邮件过期时间 (天) 6 | # Personal mail expiration time (day) 7 | expire-day: 30 8 | # 插件启动时进行更新检查 9 | # Check for updates when the plugin starts 10 | update-check: false 11 | # 检测到新版本时是否自动更新 12 | # Whether to update automatically when a new version is detected 13 | auto-update: false 14 | # 检测到配置文件与版本不符时是否更新 15 | # Update config when the configuration file is detected to be inconsistent with the version 16 | # 注: 该操作会删除文档中的注释 17 | # Note: This action will delete the comments in the document 18 | auto-config: false -------------------------------------------------------------------------------- /src/main/resources/database.yml: -------------------------------------------------------------------------------- 1 | version: "3.0.0" 2 | # SQLite 数据库 3 | # SQLite database settings 4 | sqlite: 5 | # 是否启用 6 | # Enable 7 | enable: true 8 | # 数据库类型 9 | # Database type 10 | type: 'sqlite' 11 | # 数据库名 12 | # Database name 13 | database: MailBox 14 | # MySQL 数据库 15 | # MySQL database settings 16 | mysql: 17 | # 是否启用 18 | # Enable 19 | enable: false 20 | # 数据库类型 21 | # Database type 22 | type: 'mysql' 23 | # 数据库名 24 | # Database name 25 | database: mailbox 26 | # 数据库地址 27 | # Database address 28 | host: localhost 29 | # 数据库端口 30 | # Ddatabase port 31 | port: 3306 32 | # 数据库用户名 33 | # Ddatabase user name 34 | username: 'root' 35 | # 数据库密码 36 | # Ddatabase password 37 | password: 'root' 38 | # 是否启用下方的连接池 39 | # Enable Simple Connection Pool 40 | encp: false 41 | # 简单连接池 (插件内置的MySQL使用) 42 | # Simple Connection Pool (Used for mysql in this plugin) 43 | simplecp: 44 | # 最小空闲连接数量 45 | # Minimum number of free connections 46 | min: 10 47 | # 最大连接数量 48 | # Maximum number of connections 49 | max: 20 50 | # 等待时间(ms) 51 | # Waiting time (ms) 52 | timeout: 3000 -------------------------------------------------------------------------------- /src/main/resources/message.yml: -------------------------------------------------------------------------------- 1 | version: '3.2.0' 2 | prefix: '&b[MailBox]: ' 3 | reload: 4 | load: '正在加载插件......' 5 | unload: '正在卸载插件' 6 | finish: '插件重载完成.' 7 | file: 8 | read: '读取文件: &b%file%' 9 | create: '创建文件: &b%file%' 10 | create-error: '创建文件失败: &b%file%' 11 | config: 12 | update: 已将 %config%.yml 更新至 v%version% 13 | save-error: 保存 %config% 的新配置文件失败 14 | data: 15 | enable: '已启用数据源: &6%data%' 16 | enable-error: '数据源: %data% 启用失败, 卸载插件' 17 | reg: '注册数据源: &6%data%' 18 | reg-error: '注册数据源失败, 已有同名数据源被注册: &6%data%' 19 | unreg: 已卸载其他数据源 20 | mail: 21 | reg: '注册系统邮件: &6%mail%' 22 | reg-error: '注册系统邮件失败, 已有同名系统邮件被注册: &6%mail%' 23 | unreg: '注销系统邮件: &6%mail%' 24 | money: 25 | reg: '注册金钱: &6%money%' 26 | reg-invalid: '注册金钱失败, 无效的金钱类: &6%money%' 27 | reg-duplicate: '注册金钱失败, 已有同名金钱被注册: &6%money%' 28 | unreg: '注销金钱: &6%money%' 29 | command: 30 | reg: '注册指令: &6%command%' 31 | reg-error: '注册指令失败, 已有同名指令被注册: &6%command%' 32 | unreg: '注销指令: &6%command%' 33 | help: '&b==========&6[MailBox邮箱]&b==========' 34 | listener: 35 | reg: '注册监听器: &6%listener%' 36 | unreg: '注销监听器: &6%listener%' 37 | modlue: 38 | load: 39 | empty: 无本地模块可加载 40 | success: '加载模块: &6%module% - v%version%' 41 | error: 42 | not-jar: '模块加载失败: %module% 无效的Jar文件 ' 43 | not-info: '模块加载失败: %module% 读取模块信息失败 ' 44 | info-err: '模块加载失败: %module% 模块信息不可用 ' 45 | has-duplicate: '模块加载失败: %module% 已有重名模块被加载: %another%' 46 | depend-plugin: '模块加载失败: %module% 缺少前置插件: %depends%' 47 | depend-module: '模块加载失败: %module% 缺少前置模块: %depends%' 48 | recycle-depend: '模块加载失败: %module% 检测到循环依赖' 49 | main: 50 | read-err: '模块加载失败: %module% 主类错误' 51 | not-found: '模块加载失败: %module% 找不到模块主类 %main% ' 52 | init-err: '模块加载失败: %module% 调用初始化失败' 53 | no-depend: '警告: 模块 %module% 从非前置模块 %provider% 加载了类 %class%' 54 | unload: '卸载模块: &6%module%' -------------------------------------------------------------------------------- /src/main/resources/plugin.yml: -------------------------------------------------------------------------------- 1 | name: MailBox 2 | main: com.tripleying.dogend.mailbox.MailBox 3 | version: 3.3.1 4 | description: MailBox邮箱 5 | author: Dogend 6 | website: http://qwq.tripleying.com/plugins/mailbox 7 | prefix: MailBox 8 | commands: 9 | mailbox: 10 | description: MailBox主指令 11 | aliases: mail 12 | usage: | 13 | /mailbox 主指令 --------------------------------------------------------------------------------