├── .doc ├── example-config.yml ├── javadoc │ └── JAVADOC-README.md └── repository │ └── REPO-README.md ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bugs_report.md │ └── feature_issues.md └── workflows │ ├── codeql-analysis.yml │ ├── deploy.yml │ └── maven.yml ├── .gitignore ├── LICENSE ├── README.md ├── api ├── pom.xml └── src │ └── main │ └── java │ └── cc │ └── carm │ └── plugin │ └── minesql │ ├── IMineSQL.java │ ├── MineSQL.java │ └── api │ ├── SQLDriverType.java │ ├── SQLRegistry.java │ ├── conf │ ├── SQLDriverConfig.java │ ├── drivers │ │ └── H2MemConfig.java │ └── impl │ │ ├── FileBasedConfig.java │ │ └── RemoteAuthConfig.java │ ├── source │ ├── SQLPoolSettings.java │ └── SQLSourceConfig.java │ └── table │ ├── SQLTablesRoot.java │ └── SimpleSQLTable.java ├── core ├── pom.xml └── src │ └── main │ ├── java │ └── cc │ │ └── carm │ │ └── plugin │ │ └── minesql │ │ ├── MineSQLCore.java │ │ ├── MineSQLPlatform.java │ │ ├── MineSQLRegistry.java │ │ ├── command │ │ ├── MineSQLCommand.java │ │ └── MineSQLHelpFormatter.java │ │ ├── conf │ │ ├── PluginConfiguration.java │ │ └── SQLSourceGroup.java │ │ ├── lib │ │ └── PluginLibraries.java │ │ └── util │ │ ├── DBPropertiesUtil.java │ │ └── VersionReader.java │ ├── resources │ ├── PLUGIN_INFO │ ├── acf-core_zh_CN.properties │ ├── acf-minecraft_zh_CN.properties │ ├── db-properties │ │ └── .example-mysql.properties │ └── versions.properties │ └── templates │ └── cc │ └── carm │ └── plugin │ └── minesql │ └── References.java ├── platforms ├── bukkit │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── cc │ │ │ └── carm │ │ │ └── plugin │ │ │ └── minesql │ │ │ └── MineSQLBukkit.java │ │ └── resources │ │ └── plugin.yml ├── bungee │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── cc │ │ │ └── carm │ │ │ └── plugin │ │ │ └── minesql │ │ │ └── MineSQLBungee.java │ │ └── resources │ │ └── bungee.yml └── velocity │ ├── pom.xml │ └── src │ └── main │ └── java │ └── cc │ └── carm │ └── plugin │ └── minesql │ └── MineSQLVelocity.java ├── plugin └── pom.xml ├── pom.xml └── renovate.json /.doc/example-config.yml: -------------------------------------------------------------------------------- 1 | version: ${project.version} #配置文件版本,若与插件版本不同请记得检查配置文件内容 2 | 3 | debug: false 4 | 5 | # 统计数据设定 6 | # 改选项用于帮助开发者统计插件版本与使用情况,且绝不会影响性能与使用体验。 7 | # 当然,您也可以选择在这里关闭,或在plugins/bStats下的配置文件中关闭。 8 | metrics: true 9 | 10 | # 检查更新设定 11 | # 该选项用于插件判断是否要检查更新,若您不希望插件检查更新并提示您,可以选择关闭。 12 | # 检查更新为异步操作,绝不会影响性能与使用体验。 13 | check-update: true 14 | 15 | # 启用 Properties 文件配置 16 | # 相关配置介绍(BeeCP) https://github.com/Chris2018998/BeeCP/wiki/Configuration--List#配置列表 17 | properties: 18 | # 该选项用于启用 Properties 配置读取,若您不希望插件启用 Properties 文件配置,可以选择关闭。 19 | enable: true 20 | # 文件夹路径,将读取该文件夹下的所有 .properties 文件,并以文件名为数据管理器名称。 21 | # 读取时,将排除以 “.” 开头的文件与非 .properties 文件。 22 | # 默认为 "db-properties/" 相对路径,指向“plugins/MineSQL/db-properties/”; 23 | # 该选项也支持绝对路径,但使用绝对路径时,请务必注意权限问题。 24 | folder: "db-properties/" 25 | 26 | # 数据库源配置 27 | # 目前支持的驱动类型(driver-type)有 mariadb、mysql 与 h2(文件数据库) 。 28 | 29 | databases: 30 | 31 | "example-mariadb": # 数据库源名称 不可包含“.” 以“example-”开头的数据源不会被加载 32 | type: mariadb # MySQL / MariaDB 类型 33 | host: 127.0.0.1 # 数据库地址 34 | port: 3306 # 数据库端口 35 | username: minecraft # 数据库用户名 36 | password: password #数据库连接密码 37 | database: minecraft #数据库名 38 | 39 | "example-h2": 40 | type: h2-file 41 | file: "example.db" #数据库文件路径,相对于“plugins/MineSQL/db-files/” -------------------------------------------------------------------------------- /.doc/javadoc/JAVADOC-README.md: -------------------------------------------------------------------------------- 1 | # MineSQL _(EasySQL Plugin)_ Javadoc 2 | 3 | 基于 [Github Pages](https://pages.github.com/) 搭建,请访问 [JavaDoc](https://carmjos.github.io/MineSQL) 。 4 | 5 | ## 如何实现? 6 | 7 | 若您也想通过 [Github Actions](https://docs.github.com/en/actions/learn-github-actions) 8 | 自动部署项目的Javadoc到 [Github Pages](https://pages.github.com/) , 9 | 可以参考我的文章 [《自动部署Javadoc到Github Pages》](https://pages.carm.cc/doc/javadoc-in-github.html) 。 -------------------------------------------------------------------------------- /.doc/repository/REPO-README.md: -------------------------------------------------------------------------------- 1 | # MineSQL Repository 2 | 3 | 采用github的repo分支进行依赖,随项目发布而自动更新。 4 | 5 | 其他依赖方式见主页介绍。 6 | 7 | ## 依赖方式 8 | 9 | ### Maven 10 | 11 | ```xml 12 | 13 | 14 | MineSQL 15 | GitHub Branch Repository 16 | https://raw.githubusercontent.com/CarmJos/MineSQL/repo/ 17 | 18 | 19 | ``` 20 | 21 | ### Gradle 22 | 23 | ```groovy 24 | repositories { 25 | maven { url 'https://raw.githubusercontent.com/CarmJos/MineSQL/repo/' } 26 | } 27 | ``` -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [ CarmJos ] 2 | custom: [ 'https://donate.carm.cc' ] -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bugs_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 问题提交 3 | about: 描述问题并提交,帮助我们对其进行检查与修复。 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | ### **问题简述** 11 | 用简短的话语描述一下大概问题。 12 | 13 | ### **问题来源** 14 | 描述一下通过哪些操作才发现的问题,如: 15 | 1. 打开 '...' 16 | 2. 点击了 '....' 17 | 3. 出现了报错 '....' 18 | 19 | ### **预期结果**(可选) 20 | 如果问题不发生,应该是什么情况 21 | 22 | ### **问题截图/问题报错** 23 | 如果有报错或输出,请提供截图。 24 | 25 | ### *操作环境** 26 | 请在后台输入 `version` 并复制相关输出。 27 | 28 | 29 | ### **其他补充** 30 | 如有其他补充,可以在这里描述。 31 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_issues.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 功能需求 3 | about: 希望我们提供更多的功能。 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | ### **功能简述** 11 | 简单的描述一下你想要的功能 12 | 13 | ### **需求来源** 14 | 简单的描述一下为什么需要这个功能。 15 | 16 | ### **功能参考**(可选) 17 | 如果有相关功能的参考,如文本、截图,请提供给我们。 18 | 19 | ### **附加内容** 20 | 如果有什么小细节需要重点注意,请在这里告诉我们。 21 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL Analysis" 13 | 14 | on: 15 | push: 16 | branches: [ master ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ master ] 20 | schedule: 21 | - cron: '45 12 * * 1' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | permissions: 28 | actions: read 29 | contents: read 30 | security-events: write 31 | 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | language: [ 'java' ] 36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] 37 | # Learn more about CodeQL language support at https://git.io/codeql-language-support 38 | 39 | steps: 40 | - name: Checkout repository 41 | uses: actions/checkout@v2 42 | 43 | # Initializes the CodeQL tools for scanning. 44 | - name: Initialize CodeQL 45 | uses: github/codeql-action/init@v1 46 | with: 47 | languages: ${{ matrix.language }} 48 | # If you wish to specify custom queries, you can do so here or in a config file. 49 | # By default, queries listed here will override any specified in a config file. 50 | # Prefix the list here with "+" to use these queries and those in the config file. 51 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 52 | 53 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 54 | # If this step fails, then you should remove it and run the build manually (see below) 55 | - name: Autobuild 56 | uses: github/codeql-action/autobuild@v1 57 | 58 | # ℹ️ Command-line programs to run using the OS shell. 59 | # 📚 https://git.io/JvXDl 60 | 61 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 62 | # and modify them (or add more) to build your code if your project 63 | # uses a compiled language 64 | 65 | #- run: | 66 | # make bootstrap 67 | # make release 68 | 69 | - name: Perform CodeQL Analysis 70 | uses: github/codeql-action/analyze@v1 71 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: "Deploy & Publish" 2 | 3 | on: 4 | # 支持手动触发构建 5 | workflow_dispatch: 6 | release: 7 | # 创建release的时候触发 8 | types: [ published ] 9 | 10 | jobs: 11 | packages-deploy: 12 | name: "Deploy Project (GitHub Packages)" 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v2 17 | - name: "Set up JDK" 18 | uses: actions/setup-java@v2 19 | with: 20 | java-version: '11' 21 | distribution: 'adopt' 22 | cache: maven 23 | server-id: github 24 | server-username: MAVEN_USERNAME 25 | server-password: MAVEN_TOKEN 26 | gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} # Value of the GPG private key to import 27 | gpg-passphrase: MAVEN_GPG_PASSPHRASE # env variable for GPG private key passphrase 28 | 29 | - name: "Maven Deploy" 30 | run: mvn -B -Pgithub deploy --file pom.xml -DskipTests 31 | env: 32 | MAVEN_USERNAME: ${{ github.repository_owner }} 33 | MAVEN_TOKEN: ${{secrets.GITHUB_TOKEN}} 34 | MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }} 35 | 36 | - name: "Release Asset Upload" 37 | id: upload-release-asset 38 | uses: shogo82148/actions-upload-release-asset@v1 39 | env: 40 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 41 | with: 42 | upload_url: ${{ github.event.release.upload_url }} 43 | asset_path: ".asset/*.jar" 44 | asset_content_type: application/java-archive 45 | 46 | github-deploy: 47 | name: "Deploy Project (GitHub Repo)" 48 | runs-on: ubuntu-latest 49 | steps: 50 | - uses: actions/checkout@v2 51 | - name: "Set up JDK" 52 | uses: actions/setup-java@v2 53 | with: 54 | java-version: '11' 55 | distribution: 'adopt' 56 | cache: maven 57 | 58 | - name: "Maven Deploy" 59 | run: mvn -B -Plocal deploy --file pom.xml -DskipTests -Dgpg.skip 60 | 61 | - name: "Copy artifacts" 62 | run: | 63 | rm -rf deploy 64 | mkdir -vp deploy 65 | cp -vrf $HOME/local-deploy/* deploy/ 66 | cp -vrf .doc/repository/REPO-README.md deploy/README.md 67 | 68 | - name: "Copy Javadoc" 69 | run: | 70 | rm -rf docs 71 | mkdir -vp docs 72 | cp -vrf api/target/apidocs/* docs/ 73 | cp -vrf .doc/javadoc/JAVADOC-README.md docs/README.md 74 | 75 | - name: "Generate Javadoc sitemap" 76 | id: sitemap 77 | uses: cicirello/generate-sitemap@v1 78 | with: 79 | base-url-path: https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }} 80 | path-to-root: docs 81 | 82 | - name: "Output Javadoc stats" 83 | run: | 84 | echo "sitemap-path = ${{ steps.sitemap.outputs.sitemap-path }}" 85 | echo "url-count = ${{ steps.sitemap.outputs.url-count }}" 86 | echo "excluded-count = ${{ steps.sitemap.outputs.excluded-count }}" 87 | ls -l docs 88 | 89 | - name: "Configure Git" 90 | env: 91 | DEPLOY_PRI: ${{secrets.DEPLOY_PRI}} 92 | run: | 93 | sudo timedatectl set-timezone "Asia/Shanghai" 94 | mkdir -p ~/.ssh/ 95 | echo "$DEPLOY_PRI" > ~/.ssh/id_rsa 96 | chmod 600 ~/.ssh/id_rsa 97 | ssh-keyscan github.com >> ~/.ssh/known_hosts 98 | git config --global user.name '${{ github.repository_owner }}' 99 | git config --global user.email '${{ github.repository_owner }}@users.noreply.github.com' 100 | 101 | - name: "Commit&Push repository files" 102 | run: | 103 | cd deploy 104 | git init 105 | git remote add origin git@github.com:${{ github.repository_owner }}/${{ github.event.repository.name }}.git 106 | git checkout -b repo 107 | git add -A 108 | git commit -m "Maven project deployment." 109 | git push origin HEAD:repo --force 110 | 111 | - name: "Commit&Push API documentation" 112 | run: | 113 | cd docs 114 | git init 115 | git remote add origin git@github.com:${{ github.repository_owner }}/${{ github.event.repository.name }}.git 116 | git checkout -b gh-pages 117 | git add -A 118 | git commit -m "API Document generated." 119 | git push origin HEAD:gh-pages --force 120 | 121 | central-deploy: 122 | name: "Deploy Project (Central)" 123 | runs-on: ubuntu-latest 124 | steps: 125 | - uses: actions/checkout@v2 126 | - name: "Set up JDK" 127 | uses: actions/setup-java@v2 128 | with: 129 | java-version: '11' 130 | distribution: 'adopt' 131 | cache: maven 132 | server-id: ossrh 133 | server-username: MAVEN_USERNAME 134 | server-password: MAVEN_PASSWORD 135 | gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} # Value of the GPG private key to import 136 | gpg-passphrase: MAVEN_GPG_PASSPHRASE # env variable for GPG private key passphrase 137 | 138 | - name: "Central Deploy" 139 | run: mvn -B -Possrh deploy --file pom.xml -DskipTests 140 | env: 141 | MAVEN_USERNAME: ${{ secrets.OSSRH_USER }} 142 | MAVEN_PASSWORD: ${{ secrets.OSSRH_PASS }} 143 | MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }} 144 | -------------------------------------------------------------------------------- /.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://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven 3 | 4 | name: Build & Tests 5 | 6 | on: 7 | # 支持手动触发构建 8 | workflow_dispatch: 9 | pull_request: 10 | push: 11 | paths-ignore: 12 | - ".github/**" 13 | - "README.md" 14 | - "LICENCE" 15 | 16 | jobs: 17 | build: 18 | 19 | runs-on: ubuntu-latest 20 | 21 | steps: 22 | - uses: actions/checkout@v2 23 | - name: "Set up JDK" 24 | uses: actions/setup-java@v2 25 | with: 26 | java-version: '11' 27 | distribution: 'adopt' 28 | - name: "Package" 29 | run: mvn -B package --file pom.xml -Dgpg.skip 30 | 31 | - name: "Upload artifacts" 32 | uses: actions/upload-artifact@v4 33 | with: 34 | name: artifacts 35 | path: "**/target/" 36 | retention-days: 5 37 | include-hidden-files: true 38 | 39 | - name: "Upload assets" 40 | uses: actions/upload-artifact@v4 41 | with: 42 | name: assets 43 | path: ".asset/" 44 | retention-days: 5 45 | include-hidden-files: true -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea/ 2 | /target/ 3 | **/target/ 4 | ./*.iml 5 | *.iml 6 | asset/ 7 | api-docs/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ```text 2 | __ ____ ________ __ 3 | / |/ (_)__ ___ / __/ __ \ / / 4 | / /|_/ / / _ \/ -_)\ \/ /_/ / / /__ 5 | /_/ /_/_/_//_/\__/___/\___\_\/____/ 6 | #MineSQL (EasySQL-Plugin) 7 | ``` 8 | 9 | # MineSQL (EasySQL-Plugin) 10 | 11 | [![version](https://img.shields.io/github/v/release/CarmJos/MineSQL)](https://github.com/CarmJos/MineSQL/releases) 12 | [![License](https://img.shields.io/github/license/CarmJos/MineSQL)](https://opensource.org/licenses/GPL-3.0) 13 | [![workflow](https://github.com/CarmJos/MineSQL/actions/workflows/maven.yml/badge.svg?branch=master)](https://github.com/CarmJos/MineSQL/actions/workflows/maven.yml) 14 | ![CodeSize](https://img.shields.io/github/languages/code-size/CarmJos/MineSQL) 15 | [![CodeFactor](https://www.codefactor.io/repository/github/carmjos/minesql/badge)](https://www.codefactor.io/repository/github/carmjos/minesql) 16 | ![](https://visitor-badge.glitch.me/badge?page_id=MineSQL.readme) 17 | 18 | 轻松(用)SQL的独立运行库插件,支持多种服务端,适用于MineCraft全版本。 19 | 20 | ## 优势 21 | 22 | ### 对于服主 (插件使用者) 23 | 24 | - 统一配置数据库连接,避免重复配置费时费力分神。 25 | - 支持更高级更全面的配置方式,以根据不同的使 26 | 用场景独立优化[连接池配置](https://github.com/Chris2018998/BeeCP/wiki/Configuration--List)。 27 | - 使相关插件共用连接池,避免每个插件单独新开连接池导致资源的浪费。 28 | 29 | ### 对于插件开发者 30 | 31 | - 基于 [EasySQL](https://github.com/CarmJos/EasySQL) 进行快捷的数据库操作。 32 | - 通过 `MineSQL.getRegistry().get(database-name)` 快捷获取数据源,避免繁琐的链接过程。 33 | - 详细的 DEBUG 方法,找到可恶的错误究竟在哪。 34 | - 不再需要打包各类JDBC-Driver、连接池依赖以及EasySQL本体到插件中。 35 | 36 | ### 额外提醒 37 | 38 | - 使用本依赖时,请保证其他插件的来源安全,避免可能带来的数据安全风险。 39 | 40 | ## 安装 41 | 42 | 1. 从 [Releases(发行)](https://github.com/CarmJos/MineSQL/releases/) 43 | 中点击 [最新版](https://github.com/CarmJos/MineSQL/releases/latest) 下载 `MineSQL-x.y.z.jar` 。 44 | 2. 将下载的 `MineSQL-x.y.z.jar` 放入服务器 `plugins/` 文件夹下。 45 | 3. 启动服务器,预加载配置文件后关闭服务器。 46 | 4. 修改 `plugins/MineSQL/config.yml` 以配置您的数据库选项。 47 | 5. 启动服务器,若配置无误,则您会看到 MineSQL一切正常的提示消息。 48 | 49 | ## 配置 50 | 51 | ### 插件配置文件 [`config.yml`](.doc/example-config.yml) 52 | 53 | 完整示例配置请见 [示例配置文件](.doc/example-config.yml)。 54 | 55 | #### MySQL/MariaDB 数据源详细配置示例 56 | 57 | ```yaml 58 | sources: 59 | "mysql-database": # 数据源ID,建议全英文小写并以“-”分隔,例如:hello-minecraft 60 | # 数据库驱动类型 61 | # 若您的数据库为 mariadb,则强烈推荐设置为 mariadb 62 | type: mysql 63 | host: 127.0.0.1 # 数据库地址 64 | port: 3306 # 数据库端口 65 | database: minecraft # 数据库库名 66 | username: db-user # 数据库用户名 67 | password: 1234567 #数据库连接密码 68 | ``` 69 | 70 | #### h2 数据源详细配置示例 71 | 72 | ```yaml 73 | sources: 74 | # h2数据库运行模式 75 | # 可选 h2-file(文件模式) 与 h2-mem(内存模式) 76 | # 文件模式下,须指定 file路径 ,以服务器运行目录为基准,支持绝对路径和相对路径。 77 | # 内存模式下,所有数据库都将存储在内存中,一旦关服则数据将全部丢失,该模式一般用于测试 78 | "h2-file-db": # 数据源ID,建议全小写以“-”分隔,例如:hello-minecraft 79 | type: h2-file 80 | file-path: "db-files/minecraft" 81 | "h2-mem-db": # 数据源ID,建议全小写以“-”分隔,例如:hello-minecraft 82 | type: h2-mem 83 | ``` 84 | 85 | ### Properties 配置文件 [`<插件目录>/db-properties/*.properties`](core/src/main/resources/db-properties/.example-mysql.properties) 86 | 87 | 示例配置请见 [示例MySQL数据源Properties](core/src/main/resources/db-properties/.example-mysql.properties)。 88 | 89 | Properties 文件的文件名几位数据源的ID,允许为英文、数字、下划线、短横线;请不要包含中文、其他特殊符号与空格,以`.`开头的文件将被忽略。 90 | 91 | 该功能一般用于专业开发者使用,若您不了解该功能,请尽量使用config.yml中提供的配置方式,简单便捷,能够满足大多数需求。 92 | 93 | 更多帮助详见 [BeeCP项目帮助](https://github.com/Chris2018998/BeeCP) 。 94 | 95 | ## 指令 96 | 97 | 插件主指令为 `/minesql` ,所有指令只允许后台执行。 98 | 99 | ```text 100 | # help 101 | - 查看插件指令帮助。 102 | 103 | # version 104 | - 查看当前插件、核心库(EasySQL)与连接池依赖版本。 105 | 106 | # list 107 | - 列出当前所有的数据源管理器与相关信息。 108 | 109 | # info <数据源名称> 110 | - 查看指定数据源的统计信息与当前仍未关闭的查询。 111 | ``` 112 | 113 | ## 开发 114 | 115 | ### 依赖方式 116 | 117 |
118 | 展开查看 Maven 依赖方式 119 | 120 | ```xml 121 | 122 | 123 | 124 | 125 | 126 | 127 | maven 128 | Maven Central 129 | https://repo1.maven.org/maven2 130 | 131 | 132 | 133 | 134 | MineSQL 135 | GitHub Branch Repository 136 | https://raw.githubusercontent.com/CarmJos/MineSQL/repo/ 137 | 138 | 139 | 140 | 141 | carm-repo 142 | Carm's Repo 143 | https://repo.carm.cc/repository/maven-public/ 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | cc.carm.plugin 152 | minesql-api 153 | [LATEST RELEASE] 154 | provided 155 | 156 | 157 | 158 | 159 | ``` 160 | 161 |
162 | 163 |
164 | 展开查看 Gradle 依赖方式 165 | 166 | ```groovy 167 | repositories { 168 | 169 | //采用Maven中心库,安全稳定,但版本更新需要等待同步 170 | mavenCentral() 171 | 172 | // 采用github分支依赖库,稳定更新快 173 | maven { url 'https://raw.githubusercontent.com/CarmJos/MineSQL/repo/' } 174 | 175 | // 采用我的私人依赖库,简单方便,但可能因为变故而无法使用 176 | maven { url 'https://repo.carm.cc/repository/maven-public/' } 177 | } 178 | 179 | dependencies { 180 | compileOnly "cc.carm.plugin:minesql-api:[LATEST RELEASE]" 181 | } 182 | ``` 183 | 184 |
185 | 186 | ### 操作示例 187 | 188 | 本插件接口入口类为 `MineSQL` ,更多方法详见 [MineSQL-Javadoc](https://carmjos.github.io/MineSQL/) 。 189 | 190 | 关于 EasySQL的使用方法,请详见 [EasySQL开发文档](https://github.com/CarmJos/EasySQL/tree/master/.documentation) 。 191 | 192 | 193 |
194 | 点击查看简单实例 195 | 196 | ```java 197 | 198 | public class Main extends JavaPlugin { 199 | 200 | @Override 201 | public void onEnable() { 202 | 203 | SQLManager manager = MineSQL.getRegistery().get(getConfig().getString("database")); 204 | 205 | if (manager == null) { 206 | System.out.println("请配置一个正确的数据库名。"); 207 | setEnabled(false); 208 | return; 209 | } 210 | 211 | // do something... 212 | 213 | } 214 | 215 | } 216 | 217 | ``` 218 | 219 |
220 | 221 | ## 开源协议 222 | 223 | 本项目源码采用 [GNU General Public License v3.0](https://opensource.org/licenses/GPL-3.0) 开源协议。 224 | 225 |
226 | 关于 GPL 协议 227 | 228 | > GNU General Public Licence (GPL) 有可能是开源界最常用的许可模式。GPL 保证了所有开发者的权利,同时为使用者提供了足够的复制,分发,修改的权利: 229 | > 230 | > #### 可自由复制 231 | > 你可以将软件复制到你的电脑,你客户的电脑,或者任何地方。复制份数没有任何限制。 232 | > #### 可自由分发 233 | > 在你的网站提供下载,拷贝到U盘送人,或者将源代码打印出来从窗户扔出去(环保起见,请别这样做)。 234 | > #### 可以用来盈利 235 | > 你可以在分发软件的时候收费,但你必须在收费前向你的客户提供该软件的 GNU GPL 许可协议,以便让他们知道,他们可以从别的渠道免费得到这份软件,以及你收费的理由。 236 | > #### 可自由修改 237 | > 如果你想添加或删除某个功能,没问题,如果你想在别的项目中使用部分代码,也没问题,唯一的要求是,使用了这段代码的项目也必须使用 238 | > GPL 协议。 239 | > 240 | > 需要注意的是,分发的时候,需要明确提供源代码和二进制文件,另外,用于某些程序的某些协议有一些问题和限制,你可以看一下 241 | > @PierreJoye 写的 Practical Guide to GPL Compliance 一文。使用 GPL 协议,你必须在源代码代码中包含相应信息,以及协议本身。 242 | > 243 | > *以上文字来自 [五种开源协议GPL,LGPL,BSD,MIT,Apache](https://www.oschina.net/question/54100_9455) 。* 244 |
245 | -------------------------------------------------------------------------------- /api/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | minesql-parent 7 | cc.carm.plugin 8 | 1.4.3 9 | 10 | 4.0.0 11 | 12 | 13 | ${project.jdk.version} 14 | ${project.jdk.version} 15 | UTF-8 16 | UTF-8 17 | 18 | 19 | minesql-api 20 | jar 21 | 22 | MineSQL-API 23 | 轻松(用)SQL的独立运行库插件的公用API接口部分。 24 | https://github.com/CarmJos/MineSQL 25 | 26 | 27 | 28 | CarmJos 29 | Carm Jos 30 | carm@carm.cc 31 | https://www.carm.cc 32 | 33 | Main Developer 34 | Designer 35 | 36 | 37 | 38 | 39 | 40 | 41 | GNU General Public License v3.0 42 | https://opensource.org/licenses/GPL-3.0 43 | 44 | 45 | 46 | 47 | GitHub Issues 48 | https://github.com/CarmJos/MineSQL/issues 49 | 50 | 51 | 52 | GitHub Actions 53 | https://github.com/CarmJos/MineSQL/actions/workflows/maven.yml 54 | 55 | 56 | 57 | 58 | 59 | cc.carm.lib 60 | easysql-api 61 | ${deps.easysql.version} 62 | compile 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | org.apache.maven.plugins 71 | maven-source-plugin 72 | 73 | 74 | org.apache.maven.plugins 75 | maven-compiler-plugin 76 | 77 | 78 | org.apache.maven.plugins 79 | maven-jar-plugin 80 | 81 | 82 | org.apache.maven.plugins 83 | maven-javadoc-plugin 84 | 3.11.2 85 | 86 | javadoc 87 | false 88 | UTF-8 89 | UTF-8 90 | UTF-8 91 | zh_CN 92 | 93 | true 94 | cc.carm.lib:easysql-api 95 | cc.carm.plugin:* 96 | 97 | 98 | 99 | attach-javadocs 100 | 101 | jar 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /api/src/main/java/cc/carm/plugin/minesql/IMineSQL.java: -------------------------------------------------------------------------------- 1 | package cc.carm.plugin.minesql; 2 | 3 | import cc.carm.lib.easysql.api.SQLManager; 4 | import cc.carm.lib.easysql.api.SQLQuery; 5 | import cc.carm.plugin.minesql.api.SQLRegistry; 6 | import cc.carm.plugin.minesql.api.source.SQLSourceConfig; 7 | import cc.carm.plugin.minesql.api.table.SQLTablesRoot; 8 | import cc.carm.plugin.minesql.api.table.SimpleSQLTable; 9 | import org.jetbrains.annotations.NotNull; 10 | import org.jetbrains.annotations.Nullable; 11 | 12 | import javax.sql.DataSource; 13 | import java.io.File; 14 | import java.util.Map; 15 | import java.util.Properties; 16 | import java.util.UUID; 17 | import java.util.function.Consumer; 18 | import java.util.logging.Logger; 19 | 20 | interface IMineSQL { 21 | 22 | @NotNull File getPluginFolder(); 23 | 24 | default @NotNull File getSourceFolder() { 25 | return new File(getPluginFolder(), "db-files"); 26 | } 27 | 28 | @NotNull Logger getLogger(); 29 | 30 | @NotNull SQLRegistry getRegistry(); 31 | 32 | @NotNull SQLRegistry createRegistry(); 33 | 34 | /** 35 | * 创建一个新的 SQLManager 实例 36 | * 37 | * @param name 实例名称 38 | * @param configuration SQLManager 实例的配置 39 | * @return {@link SQLManager} 实例 40 | * @throws Exception 若创建失败则抛出异常 41 | */ 42 | @NotNull SQLManager create(@NotNull String name, 43 | @NotNull SQLSourceConfig configuration) throws Exception; 44 | 45 | /** 46 | * 创建一个新的 SQLManager 实例 47 | * 48 | * @param name 实例名称 49 | * @param properties SQLManager 实例的配置文件 50 | * @return {@link SQLManager} 实例 51 | * @throws Exception 若创建失败则抛出异常 52 | */ 53 | @NotNull SQLManager create(@NotNull String name, 54 | @NotNull Properties properties) throws Exception; 55 | 56 | @NotNull SQLManager create(@NotNull String name, @NotNull DataSource source) throws Exception; 57 | 58 | /** 59 | * 终止并关闭一个 SQLManager 实例。 60 | * 61 | * @param manager SQLManager实例 62 | * @param activeQueries 终止前仍未被关闭的SQLQuery列表 63 | */ 64 | void shutdown(SQLManager manager, @Nullable Consumer> activeQueries); 65 | 66 | /** 67 | * 读取一个 {@link SQLTablesRoot} 中全部的 {@link SimpleSQLTable} 实例并初始化。 68 | * 69 | * @param tablesRoot {@link SQLTablesRoot}实例 70 | */ 71 | void createTables(@NotNull SQLTablesRoot tablesRoot) throws Exception; 72 | 73 | /** 74 | * 读取一个 {@link SQLTablesRoot}类中 中全部的静态 {@link SimpleSQLTable} 实例并初始化。 75 | * 76 | * @param tablesRootClazz {@link SQLTablesRoot}静态类 77 | */ 78 | void createTables(@NotNull Class tablesRootClazz) throws Exception; 79 | 80 | } 81 | -------------------------------------------------------------------------------- /api/src/main/java/cc/carm/plugin/minesql/MineSQL.java: -------------------------------------------------------------------------------- 1 | package cc.carm.plugin.minesql; 2 | 3 | import cc.carm.lib.easysql.api.SQLManager; 4 | import cc.carm.lib.easysql.api.SQLQuery; 5 | import cc.carm.plugin.minesql.api.SQLRegistry; 6 | import cc.carm.plugin.minesql.api.source.SQLSourceConfig; 7 | import cc.carm.plugin.minesql.api.table.SQLTablesRoot; 8 | import cc.carm.plugin.minesql.api.table.SimpleSQLTable; 9 | import org.jetbrains.annotations.ApiStatus; 10 | import org.jetbrains.annotations.NotNull; 11 | import org.jetbrains.annotations.Nullable; 12 | 13 | import javax.sql.DataSource; 14 | import java.io.File; 15 | import java.util.Map; 16 | import java.util.Properties; 17 | import java.util.UUID; 18 | import java.util.function.Consumer; 19 | import java.util.logging.Logger; 20 | 21 | public class MineSQL { 22 | 23 | private MineSQL() { 24 | throw new UnsupportedOperationException("API Instance"); 25 | } 26 | 27 | private static IMineSQL instance; 28 | 29 | @ApiStatus.Internal 30 | @SuppressWarnings("ClassEscapesDefinedScope") 31 | protected static void initializeAPI(@NotNull IMineSQL api) { 32 | MineSQL.instance = api; 33 | } 34 | 35 | public static Logger getLogger() { 36 | return instance.getLogger(); 37 | } 38 | 39 | /** 40 | * @return 数据库源文件所在目录,非插件数据目录。 41 | */ 42 | public static File getDataSourceFolder() { 43 | return instance.getSourceFolder(); 44 | } 45 | 46 | /** 47 | * 得到管理器注册池 48 | * 49 | * @return {@link SQLRegistry} 注册池 50 | */ 51 | public static SQLRegistry getRegistry() { 52 | return instance.getRegistry(); 53 | } 54 | 55 | /** 56 | * 创建一个独立的管理器注册池。 57 | * 58 | * @return {@link SQLRegistry} 59 | */ 60 | public static @NotNull SQLRegistry createRegistry() { 61 | return instance.createRegistry(); 62 | } 63 | 64 | /** 65 | * 创建一个新的 SQLManager 实例 66 | * 67 | * @param name 实例名称 68 | * @param configuration SQLManager 实例的配置 69 | * @return {@link SQLManager} 实例 70 | * @throws Exception 若创建失败则抛出异常 71 | */ 72 | public static @NotNull SQLManager create(@NotNull String name, 73 | @NotNull SQLSourceConfig configuration) throws Exception { 74 | return instance.create(name, configuration); 75 | } 76 | 77 | /** 78 | * 创建一个新的 SQLManager 实例 79 | * 80 | * @param name 实例名称 81 | * @param properties SQLManager 实例的配置文件 82 | * @return {@link SQLManager} 实例 83 | * @throws Exception 若创建失败则抛出异常 84 | */ 85 | public static @NotNull SQLManager create(@NotNull String name, 86 | @NotNull Properties properties) throws Exception { 87 | return instance.create(name, properties); 88 | } 89 | 90 | public static @NotNull SQLManager create(@NotNull String name, @NotNull DataSource source) throws Exception { 91 | return instance.create(name, source); 92 | } 93 | 94 | /** 95 | * 终止并关闭一个 SQLManager 实例。 96 | * 97 | * @param manager SQLManager实例 98 | * @param activeQueries 终止前仍未被关闭的SQLQuery列表 99 | */ 100 | public static void shutdown(SQLManager manager, @Nullable Consumer> activeQueries) { 101 | instance.shutdown(manager, activeQueries); 102 | } 103 | 104 | /** 105 | * 终止并关闭一个 SQLManager 实例。 106 | * 107 | * @param manager SQLManager实例 108 | * @param forceClose 是否强制关闭进行中的查询 109 | */ 110 | public static void shutdown(SQLManager manager, boolean forceClose) { 111 | shutdown(manager, (unclosedQueries) -> { 112 | if (forceClose) unclosedQueries.values().forEach(SQLQuery::close); 113 | }); 114 | } 115 | 116 | /** 117 | * 终止并关闭一个 SQLManager 实例。 118 | *
若在终止时仍有活跃的查询,则将会强制关闭。 119 | * 120 | * @param manager SQLManager实例 121 | */ 122 | public static void shutdown(SQLManager manager) { 123 | shutdown(manager, true); 124 | } 125 | 126 | 127 | /** 128 | * 读取一个 {@link SQLTablesRoot} 中全部的 {@link SimpleSQLTable} 实例并初始化。 129 | * 130 | * @param tablesRoot {@link SQLTablesRoot}实例 131 | */ 132 | public static void createTables(@NotNull SQLTablesRoot tablesRoot) throws Exception { 133 | instance.createTables(tablesRoot); 134 | } 135 | 136 | /** 137 | * 读取一个 {@link SQLTablesRoot}类中 中全部的静态 {@link SimpleSQLTable} 实例并初始化。 138 | * 139 | * @param tablesRootClazz {@link SQLTablesRoot}静态类 140 | */ 141 | public static void createTables(@NotNull Class tablesRootClazz) throws Exception { 142 | instance.createTables(tablesRootClazz); 143 | } 144 | 145 | } 146 | -------------------------------------------------------------------------------- /api/src/main/java/cc/carm/plugin/minesql/api/SQLDriverType.java: -------------------------------------------------------------------------------- 1 | package cc.carm.plugin.minesql.api; 2 | 3 | import cc.carm.lib.easysql.api.SQLManager; 4 | import cc.carm.lib.easysql.api.function.SQLHandler; 5 | import org.jetbrains.annotations.Contract; 6 | import org.jetbrains.annotations.NotNull; 7 | import org.jetbrains.annotations.Nullable; 8 | 9 | import java.util.Arrays; 10 | import java.util.Optional; 11 | 12 | public enum SQLDriverType { 13 | 14 | MARIADB( 15 | "org.mariadb.jdbc.Driver", "jdbc:mariadb://", 16 | new String[]{"maria-db"}, null 17 | ), 18 | 19 | MYSQL("com.mysql.jdbc.Driver", "jdbc:mysql://", null, null), 20 | 21 | H2_FILE("org.h2.Driver", "jdbc:h2:file:", 22 | new String[]{"h2"}, 23 | (manager) -> { 24 | manager.executeSQL("SET MODE=MySQL"); 25 | manager.executeSQL("SET DB_CLOSE_DELAY=-1"); 26 | manager.executeSQL("SET DB_CLOSE_ON_EXIT=FALSE"); 27 | } 28 | ), 29 | 30 | H2_MEM("org.h2.Driver", "jdbc:h2:mem:", 31 | new String[]{"h2-memory", "h2-temp"}, 32 | (manager) -> { 33 | manager.executeSQL("SET MODE=MySQL"); 34 | manager.executeSQL("SET DB_CLOSE_DELAY=-1"); 35 | manager.executeSQL("SET DB_CLOSE_ON_EXIT=FALSE"); 36 | } 37 | ); 38 | 39 | private final @NotNull String driverClass; 40 | private final @NotNull String jdbcPrefix; 41 | private final @NotNull String[] databaseAlias; 42 | private final @Nullable SQLHandler initializer; 43 | 44 | SQLDriverType(@NotNull String driverClass, @NotNull String jdbcPrefix, 45 | @Nullable String[] databaseAlias, 46 | @Nullable SQLHandler initializer) { 47 | 48 | this.driverClass = driverClass; 49 | this.jdbcPrefix = jdbcPrefix; 50 | this.databaseAlias = Optional.ofNullable(databaseAlias).orElse(new String[0]); 51 | this.initializer = initializer; 52 | } 53 | 54 | public @NotNull String[] getDatabaseAlias() { 55 | return databaseAlias; 56 | } 57 | 58 | public @NotNull String getDriverClass() { 59 | return driverClass; 60 | } 61 | 62 | public @NotNull String getJdbcPrefix() { 63 | return jdbcPrefix; 64 | } 65 | 66 | public @Nullable SQLHandler getInitializer() { 67 | return initializer; 68 | } 69 | 70 | @Contract("null->null") 71 | public static @Nullable SQLDriverType parse(@Nullable String driverString) { 72 | if (driverString == null) return null; 73 | return Arrays.stream(values()) 74 | .filter(value -> value.name().equalsIgnoreCase(driverString) || anyMatch(value.getDatabaseAlias(), driverString)) 75 | .findFirst().orElse(null); 76 | } 77 | 78 | private static boolean anyMatch(String[] array, String value) { 79 | return Arrays.stream(array).anyMatch(s -> s.equalsIgnoreCase(value)); 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /api/src/main/java/cc/carm/plugin/minesql/api/SQLRegistry.java: -------------------------------------------------------------------------------- 1 | package cc.carm.plugin.minesql.api; 2 | 3 | import cc.carm.lib.easysql.api.SQLManager; 4 | import org.jetbrains.annotations.NotNull; 5 | import org.jetbrains.annotations.Nullable; 6 | import org.jetbrains.annotations.Unmodifiable; 7 | 8 | import java.util.Map; 9 | import java.util.Optional; 10 | 11 | /** 12 | * 入口类 13 | */ 14 | public interface SQLRegistry { 15 | /** 16 | * 获取原生注册的首个 SQLManager 实例 17 | * 18 | * @return {@link SQLManager} 实例 19 | */ 20 | default @Nullable SQLManager get() { 21 | return get(null); 22 | } 23 | 24 | /** 25 | * 获取原生注册的指定名称的 SQLManager 实例 26 | * 27 | * @param name 要获取的 SQLManager 实例名称, 如果为 null 则获取首个实例 28 | * @return {@link SQLManager} 实例 29 | */ 30 | default @Nullable SQLManager get(@Nullable String name) { 31 | return getOptional(name).orElse(null); 32 | } 33 | 34 | /** 35 | * 获取原生注册的指定名称的 SQLManager 实例,并要求其不得为空 36 | * 37 | * @param name 要获取的 SQLManager 实例名称, 如果为 null 则获取首个实例 38 | * @return {@link SQLManager} 实例 39 | * @throws NullPointerException 若不存在对应实例则抛出空指针异常 40 | */ 41 | default @NotNull SQLManager getNotNull(@Nullable String name) throws NullPointerException { 42 | return getOptional(name).orElseThrow(() -> new NullPointerException("并不存在ID为 #" + name + " 的SQLManager.")); 43 | } 44 | 45 | /** 46 | * 获取原生注册的指定名称的 SQLManager 实例 47 | * 48 | * @param name 要获取的 SQLManager 实例名称, 如果为 null 则获取首个实例 49 | * @return {@link SQLManager} 实例 50 | */ 51 | @NotNull Optional getOptional(@Nullable String name); 52 | 53 | /** 54 | * 获取某命名空间下所有 SQLManager 实例 55 | * 56 | * @return {@link SQLManager} 实例集合 57 | */ 58 | @Unmodifiable 59 | @NotNull Map list(); 60 | 61 | /** 62 | * 注册一个新的 SQLManager 实例 63 | * 64 | * @param name 实例名称 65 | * @param sqlManager 实例 66 | * @throws IllegalStateException 当所要注册的实例已经存在时抛出 67 | */ 68 | void register(@NotNull String name, @NotNull SQLManager sqlManager) throws IllegalStateException; 69 | 70 | /** 71 | * 从注册池中注销一个新的 SQLManager 实例 72 | * 73 | * @param name 实例名称 74 | * @return 所被注销的 {@link SQLManager} 75 | * @throws NullPointerException 当所要注销的实例不存在时抛出 76 | */ 77 | @NotNull SQLManager unregister(@NotNull String name) throws NullPointerException; 78 | 79 | } 80 | -------------------------------------------------------------------------------- /api/src/main/java/cc/carm/plugin/minesql/api/conf/SQLDriverConfig.java: -------------------------------------------------------------------------------- 1 | package cc.carm.plugin.minesql.api.conf; 2 | 3 | import cc.carm.plugin.minesql.api.SQLDriverType; 4 | import cc.carm.plugin.minesql.api.source.SQLSourceConfig; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | import java.util.Map; 8 | 9 | public abstract class SQLDriverConfig { 10 | 11 | protected final @NotNull SQLDriverType type; 12 | 13 | public SQLDriverConfig(@NotNull SQLDriverType type) { 14 | this.type = type; 15 | } 16 | 17 | public abstract SQLSourceConfig createSource(); 18 | 19 | public @NotNull SQLDriverType getType() { 20 | return type; 21 | } 22 | 23 | public abstract @NotNull Map serialize(); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /api/src/main/java/cc/carm/plugin/minesql/api/conf/drivers/H2MemConfig.java: -------------------------------------------------------------------------------- 1 | package cc.carm.plugin.minesql.api.conf.drivers; 2 | 3 | import cc.carm.plugin.minesql.api.SQLDriverType; 4 | import cc.carm.plugin.minesql.api.conf.SQLDriverConfig; 5 | import cc.carm.plugin.minesql.api.source.SQLSourceConfig; 6 | import org.jetbrains.annotations.NotNull; 7 | import org.jetbrains.annotations.Nullable; 8 | 9 | import java.util.LinkedHashMap; 10 | import java.util.Map; 11 | import java.util.Optional; 12 | 13 | public class H2MemConfig extends SQLDriverConfig { 14 | 15 | protected final @Nullable String database; 16 | 17 | public H2MemConfig(@Nullable String database) { 18 | super(SQLDriverType.H2_MEM); 19 | this.database = database; 20 | } 21 | 22 | public @Nullable String getDatabase() { 23 | return database; 24 | } 25 | 26 | @Override 27 | public SQLSourceConfig createSource() { 28 | return SQLSourceConfig.create(getType().getDriverClass(), buildJDBC(), getType().getInitializer()); 29 | } 30 | 31 | protected String buildJDBC() { 32 | return getType().getJdbcPrefix() + Optional.ofNullable(getDatabase()).orElse(""); 33 | } 34 | 35 | @Override 36 | public @NotNull Map serialize() { 37 | Map values = new LinkedHashMap<>(); 38 | 39 | values.put("type", getType().name()); 40 | if (getDatabase() != null) values.put("database", getDatabase()); 41 | 42 | return values; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /api/src/main/java/cc/carm/plugin/minesql/api/conf/impl/FileBasedConfig.java: -------------------------------------------------------------------------------- 1 | package cc.carm.plugin.minesql.api.conf.impl; 2 | 3 | import cc.carm.plugin.minesql.MineSQL; 4 | import cc.carm.plugin.minesql.api.SQLDriverType; 5 | import cc.carm.plugin.minesql.api.conf.SQLDriverConfig; 6 | import cc.carm.plugin.minesql.api.source.SQLSourceConfig; 7 | import org.jetbrains.annotations.NotNull; 8 | 9 | import java.io.File; 10 | import java.util.LinkedHashMap; 11 | import java.util.Map; 12 | 13 | public class FileBasedConfig extends SQLDriverConfig { 14 | 15 | protected final @NotNull String filePath; 16 | 17 | public FileBasedConfig(@NotNull SQLDriverType type, 18 | @NotNull String filePath) { 19 | super(type); 20 | this.filePath = filePath; 21 | } 22 | 23 | public @NotNull String getFilePath() { 24 | return filePath; 25 | } 26 | 27 | @Override 28 | public SQLSourceConfig createSource() { 29 | File file = new File(MineSQL.getDataSourceFolder(), filePath); 30 | return SQLSourceConfig.create( 31 | getType().getDriverClass(), 32 | getType().getJdbcPrefix() + file.getAbsolutePath(), 33 | getType().getInitializer() 34 | ); 35 | } 36 | 37 | @Override 38 | public @NotNull Map serialize() { 39 | Map values = new LinkedHashMap<>(); 40 | 41 | values.put("type", getType().name()); 42 | values.put("file", getFilePath()); 43 | 44 | return values; 45 | } 46 | 47 | 48 | } 49 | 50 | -------------------------------------------------------------------------------- /api/src/main/java/cc/carm/plugin/minesql/api/conf/impl/RemoteAuthConfig.java: -------------------------------------------------------------------------------- 1 | package cc.carm.plugin.minesql.api.conf.impl; 2 | 3 | import cc.carm.plugin.minesql.api.SQLDriverType; 4 | import cc.carm.plugin.minesql.api.conf.SQLDriverConfig; 5 | import cc.carm.plugin.minesql.api.source.SQLSourceConfig; 6 | import org.jetbrains.annotations.NotNull; 7 | import org.jetbrains.annotations.Nullable; 8 | 9 | import java.util.LinkedHashMap; 10 | import java.util.Map; 11 | 12 | public class RemoteAuthConfig extends SQLDriverConfig { 13 | 14 | protected final @NotNull String host; 15 | protected final int port; 16 | protected final @NotNull String database; 17 | protected final @Nullable String username; 18 | protected final @Nullable String password; 19 | 20 | protected final @Nullable String extraSettings; 21 | 22 | public RemoteAuthConfig(@NotNull SQLDriverType type, 23 | @NotNull String host, int port, @NotNull String database, 24 | @Nullable String username, @Nullable String password, 25 | @Nullable String extraSettings) { 26 | super(type); 27 | this.host = host; 28 | this.port = port; 29 | this.database = database; 30 | this.username = username; 31 | this.password = password; 32 | this.extraSettings = extraSettings; 33 | } 34 | 35 | @Override 36 | public SQLSourceConfig createSource() { 37 | return SQLSourceConfig.create( 38 | getType().getDriverClass(), buildJDBC(), getType().getInitializer() 39 | ).setUsername(getUsername()).setPassword(getPassword()); 40 | } 41 | 42 | public @NotNull String getHost() { 43 | return host; 44 | } 45 | 46 | public int getPort() { 47 | return port; 48 | } 49 | 50 | public @NotNull String getDatabase() { 51 | return database; 52 | } 53 | 54 | public @Nullable String getUsername() { 55 | return username; 56 | } 57 | 58 | 59 | public @Nullable String getPassword() { 60 | return password; 61 | } 62 | 63 | public @Nullable String getExtraSettings() { 64 | return extraSettings; 65 | } 66 | 67 | protected String buildJDBC() { 68 | return String.format("%s%s:%s/%s%s", getType().getJdbcPrefix(), getHost(), getPort(), getDatabase(), getExtraSettings()); 69 | } 70 | 71 | @Override 72 | public @NotNull Map serialize() { 73 | Map values = new LinkedHashMap<>(); 74 | 75 | values.put("type", getType().name()); 76 | 77 | values.put("host", getHost()); 78 | values.put("port", getPort()); 79 | values.put("database", getDatabase()); 80 | if (getUsername() != null) values.put("username", username); 81 | if (getPassword() != null) values.put("password", password); 82 | if (getExtraSettings() != null) values.put("extra", extraSettings); 83 | 84 | return values; 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /api/src/main/java/cc/carm/plugin/minesql/api/source/SQLPoolSettings.java: -------------------------------------------------------------------------------- 1 | package cc.carm.plugin.minesql.api.source; 2 | 3 | import org.jetbrains.annotations.Nullable; 4 | 5 | public class SQLPoolSettings { 6 | 7 | private @Nullable String poolName; 8 | private @Nullable Integer maxPoolSize; 9 | private @Nullable Integer maxActive; 10 | 11 | private @Nullable Integer maxHoldTime; 12 | 13 | private @Nullable Long idleTimeout; 14 | 15 | private @Nullable Long maxWaitTime; 16 | 17 | private @Nullable String schema; 18 | private @Nullable Boolean autoCommit; 19 | private @Nullable Boolean readOnly; 20 | 21 | private @Nullable String validationSQL; 22 | private @Nullable Integer validationTimeout; 23 | private @Nullable Long validationInterval; 24 | 25 | public @Nullable String getValidationSQL() { 26 | return validationSQL; 27 | } 28 | 29 | public SQLPoolSettings setValidationSQL(String validationSQL) { 30 | this.validationSQL = validationSQL; 31 | return this; 32 | } 33 | 34 | public @Nullable Long getValidationInterval() { 35 | return validationInterval; 36 | } 37 | 38 | public SQLPoolSettings setValidationInterval(@Nullable Long validationInterval) { 39 | this.validationInterval = validationInterval; 40 | return this; 41 | } 42 | 43 | public @Nullable String getPoolName() { 44 | return poolName; 45 | } 46 | 47 | public SQLPoolSettings setPoolName(String poolName) { 48 | this.poolName = poolName; 49 | return this; 50 | } 51 | 52 | public @Nullable String getSchema() { 53 | return schema; 54 | } 55 | 56 | public SQLPoolSettings setSchema(String schema) { 57 | this.schema = schema; 58 | return this; 59 | } 60 | 61 | public @Nullable Boolean getAutoCommit() { 62 | return autoCommit; 63 | } 64 | 65 | public SQLPoolSettings setAutoCommit(Boolean autoCommit) { 66 | this.autoCommit = autoCommit; 67 | return this; 68 | } 69 | 70 | public @Nullable Boolean getReadOnly() { 71 | return readOnly; 72 | } 73 | 74 | public SQLPoolSettings setReadOnly(Boolean readOnly) { 75 | this.readOnly = readOnly; 76 | return this; 77 | } 78 | 79 | public @Nullable Integer getMaxHoldTime() { 80 | return maxHoldTime; 81 | } 82 | 83 | public SQLPoolSettings setMaxHoldTime(@Nullable Integer maxHoldTime) { 84 | this.maxHoldTime = maxHoldTime; 85 | return this; 86 | } 87 | 88 | public @Nullable Integer getValidationTimeout() { 89 | return validationTimeout; 90 | } 91 | 92 | public SQLPoolSettings setValidationTimeout(Integer validationTimeout) { 93 | this.validationTimeout = validationTimeout; 94 | return this; 95 | } 96 | 97 | public @Nullable Long getIdleTimeout() { 98 | return idleTimeout; 99 | } 100 | 101 | public SQLPoolSettings setIdleTimeout(Long idleTimeout) { 102 | this.idleTimeout = idleTimeout; 103 | return this; 104 | } 105 | 106 | public @Nullable Integer getMaxActive() { 107 | return maxActive; 108 | } 109 | 110 | public SQLPoolSettings setMaxActive(Integer maxActive) { 111 | this.maxActive = maxActive; 112 | return this; 113 | } 114 | 115 | public @Nullable Integer getMaxPoolSize() { 116 | return maxPoolSize; 117 | } 118 | 119 | public SQLPoolSettings setMaxPoolSize(@Nullable Integer maxPoolSize) { 120 | this.maxPoolSize = maxPoolSize; 121 | return this; 122 | } 123 | 124 | public @Nullable Long getMaxWaitTime() { 125 | return maxWaitTime; 126 | } 127 | 128 | public SQLPoolSettings setMaxWaitTime(Long maxWaitTime) { 129 | this.maxWaitTime = maxWaitTime; 130 | return this; 131 | } 132 | 133 | 134 | } 135 | -------------------------------------------------------------------------------- /api/src/main/java/cc/carm/plugin/minesql/api/source/SQLSourceConfig.java: -------------------------------------------------------------------------------- 1 | package cc.carm.plugin.minesql.api.source; 2 | 3 | import cc.carm.lib.easysql.api.SQLManager; 4 | import cc.carm.lib.easysql.api.function.SQLHandler; 5 | import cc.carm.plugin.minesql.api.SQLDriverType; 6 | import cc.carm.plugin.minesql.api.conf.drivers.H2MemConfig; 7 | import cc.carm.plugin.minesql.api.conf.impl.FileBasedConfig; 8 | import cc.carm.plugin.minesql.api.conf.impl.RemoteAuthConfig; 9 | import org.jetbrains.annotations.NotNull; 10 | import org.jetbrains.annotations.Nullable; 11 | 12 | import java.io.File; 13 | import java.util.Optional; 14 | import java.util.function.Consumer; 15 | 16 | public class SQLSourceConfig { 17 | 18 | public static SQLSourceConfig createMySQL(@NotNull String host, int port, @NotNull String database, 19 | @NotNull String username, @Nullable String password, 20 | @Nullable String extraSettings) { 21 | return new RemoteAuthConfig(SQLDriverType.MYSQL, host, port, database, username, password, extraSettings).createSource(); 22 | } 23 | 24 | public static SQLSourceConfig createMariaDB(@NotNull String host, int port, @NotNull String database, 25 | @NotNull String username, @Nullable String password, 26 | @Nullable String extraSettings) { 27 | return new RemoteAuthConfig(SQLDriverType.MARIADB, host, port, database, username, password, extraSettings).createSource(); 28 | } 29 | 30 | public static SQLSourceConfig createH2File(@NotNull File file) { 31 | return create(SQLDriverType.H2_FILE, file.getAbsolutePath()); 32 | } 33 | 34 | public static SQLSourceConfig createH2File(@NotNull String filePath) { 35 | return new FileBasedConfig(SQLDriverType.H2_FILE, filePath).createSource(); 36 | } 37 | 38 | public static SQLSourceConfig createH2Mem(@Nullable String databaseName) { 39 | return new H2MemConfig(databaseName).createSource(); 40 | } 41 | 42 | public static SQLSourceConfig create(@NotNull SQLDriverType sourceType, @NotNull String url) { 43 | return create(sourceType.getDriverClass(), sourceType.getJdbcPrefix() + url, sourceType.getInitializer()); 44 | } 45 | 46 | public static SQLSourceConfig create(@NotNull String driverClass, @NotNull String jdbcURL) { 47 | return create(driverClass, jdbcURL, null); 48 | } 49 | 50 | public static SQLSourceConfig create(@NotNull String driverClassName, @NotNull String jdbcURL, 51 | @Nullable SQLHandler initializer) { 52 | return new SQLSourceConfig(driverClassName, jdbcURL, initializer, null); 53 | } 54 | 55 | public static SQLSourceConfig create(@NotNull String driverClassName, @NotNull String jdbcURL, 56 | @Nullable SQLHandler initializer, @Nullable SQLPoolSettings settings) { 57 | return new SQLSourceConfig(driverClassName, jdbcURL, initializer, settings); 58 | } 59 | 60 | private @NotNull String driverClassName; 61 | private @NotNull String jdbcURL; 62 | private @Nullable String username; 63 | private @Nullable String password; 64 | 65 | private @Nullable SQLHandler initializer; 66 | private @NotNull SQLPoolSettings settings; 67 | 68 | public SQLSourceConfig(@NotNull String driverClassName, @NotNull String jdbcURL, 69 | @Nullable SQLHandler initializer, @Nullable SQLPoolSettings settings) { 70 | this.driverClassName = driverClassName; 71 | this.jdbcURL = jdbcURL; 72 | this.initializer = initializer; 73 | this.settings = Optional.ofNullable(settings).orElse(new SQLPoolSettings()); 74 | } 75 | 76 | public @NotNull String getDriverClassName() { 77 | return driverClassName; 78 | } 79 | 80 | public SQLSourceConfig setDriverClassName(String driverClassName) { 81 | this.driverClassName = driverClassName; 82 | return this; 83 | } 84 | 85 | public @NotNull String getJdbcURL() { 86 | return jdbcURL; 87 | } 88 | 89 | public SQLSourceConfig setJdbcURL(String jdbcURL) { 90 | this.jdbcURL = jdbcURL; 91 | return this; 92 | } 93 | 94 | public @Nullable String getUsername() { 95 | return username; 96 | } 97 | 98 | public SQLSourceConfig setUsername(String username) { 99 | this.username = username; 100 | return this; 101 | } 102 | 103 | public @Nullable String getPassword() { 104 | return password; 105 | } 106 | 107 | public SQLSourceConfig setPassword(String password) { 108 | this.password = password; 109 | return this; 110 | } 111 | 112 | public @Nullable SQLHandler getInitializer() { 113 | return initializer; 114 | } 115 | 116 | public SQLSourceConfig setInitializer(SQLHandler initializer) { 117 | this.initializer = initializer; 118 | return this; 119 | } 120 | 121 | public @NotNull SQLPoolSettings getSettings() { 122 | return settings; 123 | } 124 | 125 | public SQLSourceConfig setSettings(SQLPoolSettings settings) { 126 | this.settings = settings; 127 | return this; 128 | } 129 | 130 | public SQLSourceConfig editSettings(Consumer consumer) { 131 | consumer.accept(settings); 132 | return this; 133 | } 134 | 135 | } 136 | -------------------------------------------------------------------------------- /api/src/main/java/cc/carm/plugin/minesql/api/table/SQLTablesRoot.java: -------------------------------------------------------------------------------- 1 | package cc.carm.plugin.minesql.api.table; 2 | 3 | import cc.carm.lib.easysql.api.function.SQLHandler; 4 | 5 | import java.util.function.Supplier; 6 | 7 | /** 8 | * 表声明类的根节点,用于标注该类用于记录表的结构信息。 9 | *
创建表请使用 {@link SimpleSQLTable#of(String, String, Supplier, SQLHandler)}。 10 | */ 11 | public abstract class SQLTablesRoot { 12 | } 13 | -------------------------------------------------------------------------------- /api/src/main/java/cc/carm/plugin/minesql/api/table/SimpleSQLTable.java: -------------------------------------------------------------------------------- 1 | package cc.carm.plugin.minesql.api.table; 2 | 3 | import cc.carm.lib.easysql.api.SQLManager; 4 | import cc.carm.lib.easysql.api.action.PreparedSQLUpdateAction; 5 | import cc.carm.lib.easysql.api.action.PreparedSQLUpdateBatchAction; 6 | import cc.carm.lib.easysql.api.builder.*; 7 | import cc.carm.lib.easysql.api.function.SQLHandler; 8 | import cc.carm.plugin.minesql.MineSQL; 9 | import org.jetbrains.annotations.NotNull; 10 | import org.jetbrains.annotations.Nullable; 11 | 12 | import java.sql.SQLException; 13 | import java.util.Optional; 14 | import java.util.function.Supplier; 15 | 16 | public class SimpleSQLTable { 17 | 18 | public static @NotNull SimpleSQLTable of(@NotNull String tableName, 19 | @NotNull SQLHandler tableBuilder) { 20 | return new SimpleSQLTable(null, tableName, null, tableBuilder); 21 | } 22 | 23 | public static @NotNull SimpleSQLTable of(@Nullable String database, @NotNull String tableName, 24 | @NotNull SQLHandler tableBuilder) { 25 | return new SimpleSQLTable(database, tableName, null, tableBuilder); 26 | } 27 | 28 | public static @NotNull SimpleSQLTable of(@Nullable String database, @NotNull String tableName, 29 | @Nullable String tablePrefix, @NotNull SQLHandler tableBuilder) { 30 | return new SimpleSQLTable(database, tableName, () -> tablePrefix, tableBuilder); 31 | } 32 | 33 | public static @NotNull SimpleSQLTable of(@Nullable String database, @NotNull String tableName, 34 | @Nullable Supplier tablePrefix, @NotNull SQLHandler tableBuilder) { 35 | return new SimpleSQLTable(database, tableName, tablePrefix, tableBuilder); 36 | } 37 | 38 | protected final @Nullable String database; 39 | protected final @NotNull String tableName; 40 | 41 | protected final @Nullable Supplier tablePrefix; 42 | protected final @NotNull SQLHandler tableCreator; 43 | 44 | public SimpleSQLTable(@Nullable String database, @NotNull String tableName, 45 | @Nullable Supplier tablePrefix, @NotNull SQLHandler table) { 46 | this.database = database; 47 | this.tableName = tableName; 48 | this.tablePrefix = tablePrefix; 49 | this.tableCreator = table; 50 | } 51 | 52 | public boolean create() throws SQLException { 53 | SQLManager sqlManager = getSQLManager(); 54 | if (sqlManager == null) throw new SQLException(getExceptionReason()); 55 | 56 | TableCreateBuilder tableBuilder = sqlManager.createTable(getTableName()); 57 | tableCreator.accept(tableBuilder); 58 | return tableBuilder.build().executeFunction(l -> l > 0, false); 59 | } 60 | 61 | public @Nullable String getDatabase() { 62 | return database; 63 | } 64 | 65 | public @Nullable SQLManager getSQLManager() { 66 | return MineSQL.getRegistry().get(getDatabase()); 67 | } 68 | 69 | public @NotNull String getTableName() { 70 | String prefix = getTablePrefix(); 71 | return (prefix != null ? prefix : "") + tableName; 72 | } 73 | 74 | public @Nullable String getTablePrefix() { 75 | return Optional.ofNullable(tablePrefix).map(Supplier::get).orElse(null); 76 | } 77 | 78 | public @NotNull TableQueryBuilder createQuery() { 79 | return Optional.ofNullable(getSQLManager()).map(this::createQuery) 80 | .orElseThrow(() -> new NullPointerException(getExceptionReason())); 81 | } 82 | 83 | public @NotNull TableQueryBuilder createQuery(@NotNull SQLManager sqlManager) { 84 | return sqlManager.createQuery().inTable(getTableName()); 85 | } 86 | 87 | public @NotNull DeleteBuilder createDelete() { 88 | return Optional.ofNullable(getSQLManager()).map(this::createDelete) 89 | .orElseThrow(() -> new NullPointerException(getExceptionReason())); 90 | } 91 | 92 | public @NotNull DeleteBuilder createDelete(@NotNull SQLManager sqlManager) { 93 | return sqlManager.createDelete(getTableName()); 94 | } 95 | 96 | public @NotNull UpdateBuilder createUpdate() { 97 | return Optional.ofNullable(getSQLManager()).map(this::createUpdate) 98 | .orElseThrow(() -> new NullPointerException(getExceptionReason())); 99 | } 100 | 101 | public @NotNull UpdateBuilder createUpdate(@NotNull SQLManager sqlManager) { 102 | return sqlManager.createUpdate(getTableName()); 103 | } 104 | 105 | public @NotNull InsertBuilder> createInsert() { 106 | return Optional.ofNullable(getSQLManager()).map(this::createInsert) 107 | .orElseThrow(() -> new NullPointerException(getExceptionReason())); 108 | } 109 | 110 | public @NotNull InsertBuilder> createInsert(@NotNull SQLManager sqlManager) { 111 | return sqlManager.createInsert(getTableName()); 112 | } 113 | 114 | public @NotNull InsertBuilder> createInsertBatch() { 115 | return Optional.ofNullable(getSQLManager()).map(this::createInsertBatch) 116 | .orElseThrow(() -> new NullPointerException(getExceptionReason())); 117 | } 118 | 119 | public @NotNull InsertBuilder> createInsertBatch(@NotNull SQLManager sqlManager) { 120 | return sqlManager.createInsertBatch(getTableName()); 121 | } 122 | 123 | public @NotNull ReplaceBuilder> createReplace() { 124 | return Optional.ofNullable(getSQLManager()).map(this::createReplace) 125 | .orElseThrow(() -> new NullPointerException(getExceptionReason())); 126 | 127 | } 128 | 129 | public @NotNull ReplaceBuilder> createReplace(@NotNull SQLManager sqlManager) { 130 | return sqlManager.createReplace(getTableName()); 131 | } 132 | 133 | public @NotNull ReplaceBuilder> createReplaceBatch() { 134 | return Optional.ofNullable(getSQLManager()).map(this::createReplaceBatch) 135 | .orElseThrow(() -> new NullPointerException(getExceptionReason())); 136 | } 137 | 138 | public @NotNull ReplaceBuilder> createReplaceBatch(@NotNull SQLManager sqlManager) { 139 | return sqlManager.createReplaceBatch(getTableName()); 140 | } 141 | 142 | public @NotNull TableAlterBuilder alter() { 143 | return Optional.ofNullable(getSQLManager()).map(this::alter) 144 | .orElseThrow(() -> new NullPointerException(getExceptionReason())); 145 | } 146 | 147 | public @NotNull TableAlterBuilder alter(@NotNull SQLManager sqlManager) { 148 | return sqlManager.alterTable(getTableName()); 149 | } 150 | 151 | private String getExceptionReason() { 152 | if (getDatabase() == null) return "Cannot find any SQLManager."; 153 | else return "Cannot find any SQLManager for \"" + getDatabase() + "\"."; 154 | } 155 | 156 | } 157 | -------------------------------------------------------------------------------- /core/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | minesql-parent 7 | cc.carm.plugin 8 | 1.4.3 9 | 10 | 4.0.0 11 | 12 | ${project.jdk.version} 13 | ${project.jdk.version} 14 | UTF-8 15 | UTF-8 16 | true 17 | true 18 | 19 | minesql-core 20 | 21 | MineSQL-Core 22 | 轻松(用)SQL的独立运行库插件的主要实现部分。 23 | https://github.com/CarmJos/MineSQL 24 | 25 | 26 | 27 | CarmJos 28 | Carm Jos 29 | carm@carm.cc 30 | https://www.carm.cc 31 | 32 | Main Developer 33 | Designer 34 | 35 | 36 | 37 | 38 | 39 | 40 | GNU General Public License v3.0 41 | https://opensource.org/licenses/GPL-3.0 42 | 43 | 44 | 45 | 46 | GitHub Issues 47 | https://github.com/CarmJos/MineSQL/issues 48 | 49 | 50 | 51 | GitHub Actions 52 | https://github.com/CarmJos/MineSQL/actions/workflows/maven.yml 53 | 54 | 55 | 56 | 57 | 58 | ${project.parent.groupId} 59 | minesql-api 60 | ${project.parent.version} 61 | compile 62 | 63 | 64 | 65 | co.aikar 66 | acf-core 67 | 0.5.1-SNAPSHOT 68 | provided 69 | 70 | 71 | 72 | com.github.chris2018998 73 | beecp 74 | compile 75 | 76 | 77 | 78 | cc.carm.lib 79 | easysql-impl 80 | compile 81 | 82 | 83 | 84 | org.mariadb.jdbc 85 | mariadb-java-client 86 | compile 87 | 88 | 89 | 90 | com.mysql 91 | mysql-connector-j 92 | compile 93 | 94 | 95 | 96 | com.h2database 97 | h2 98 | compile 99 | 100 | 101 | 102 | cc.carm.lib 103 | easyplugin-githubchecker 104 | ${deps.easyplugin.version} 105 | compile 106 | 107 | 108 | 109 | cc.carm.lib 110 | easyplugin-utils 111 | ${deps.easyplugin.version} 112 | compile 113 | 114 | 115 | 116 | cc.carm.lib 117 | configured-yaml 118 | ${deps.easyconf.version} 119 | compile 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | org.apache.maven.plugins 128 | maven-compiler-plugin 129 | 130 | 131 | maven-resources-plugin 132 | 3.3.1 133 | 134 | 135 | filter-version 136 | process-resources 137 | 138 | copy-resources 139 | 140 | 141 | ${project.build.directory}/generated-sources/java 142 | 143 | 144 | src/main/templates 145 | true 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | org.codehaus.mojo 154 | build-helper-maven-plugin 155 | 3.6.0 156 | 157 | 158 | add-source 159 | generate-sources 160 | 161 | add-source 162 | 163 | 164 | 165 | ${project.build.directory}/generated-sources/java 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | -------------------------------------------------------------------------------- /core/src/main/java/cc/carm/plugin/minesql/MineSQLCore.java: -------------------------------------------------------------------------------- 1 | package cc.carm.plugin.minesql; 2 | 3 | import cc.carm.lib.configuration.source.ConfigurationHolder; 4 | import cc.carm.lib.configuration.source.yaml.YAMLConfigFactory; 5 | import cc.carm.lib.easyplugin.utils.JarResourceUtils; 6 | import cc.carm.lib.easysql.api.SQLManager; 7 | import cc.carm.lib.easysql.api.SQLQuery; 8 | import cc.carm.lib.easysql.manager.SQLManagerImpl; 9 | import cc.carm.lib.githubreleases4j.GithubReleases4J; 10 | import cc.carm.plugin.minesql.api.source.SQLSourceConfig; 11 | import cc.carm.plugin.minesql.api.table.SQLTablesRoot; 12 | import cc.carm.plugin.minesql.api.table.SimpleSQLTable; 13 | import cc.carm.plugin.minesql.command.MineSQLCommand; 14 | import cc.carm.plugin.minesql.command.MineSQLHelpFormatter; 15 | import cc.carm.plugin.minesql.conf.PluginConfiguration; 16 | import cc.carm.plugin.minesql.conf.SQLSourceGroup; 17 | import cc.carm.plugin.minesql.util.DBPropertiesUtil; 18 | import co.aikar.commands.CommandManager; 19 | import co.aikar.commands.InvalidCommandArgument; 20 | import co.aikar.commands.Locales; 21 | import org.jetbrains.annotations.NotNull; 22 | import org.jetbrains.annotations.Nullable; 23 | import org.stone.beecp.BeeDataSource; 24 | import org.stone.beecp.BeeDataSourceConfig; 25 | 26 | import javax.sql.DataSource; 27 | import java.io.File; 28 | import java.lang.reflect.Field; 29 | import java.sql.SQLException; 30 | import java.util.*; 31 | import java.util.function.Consumer; 32 | import java.util.logging.Logger; 33 | 34 | public class MineSQLCore implements IMineSQL { 35 | 36 | protected static MineSQLCore instance; 37 | 38 | 39 | protected final MineSQLPlatform platform; 40 | 41 | protected final MineSQLRegistry registry; 42 | protected final ConfigurationHolder configProvider; 43 | protected final PluginConfiguration config; 44 | 45 | public MineSQLCore(MineSQLPlatform platform) { 46 | instance = this; 47 | this.platform = platform; 48 | 49 | getLogger().info("加载配置文件..."); 50 | this.configProvider = YAMLConfigFactory.from(new File(platform.getPluginFolder(), "config.yml")).build(); 51 | this.config = new PluginConfiguration(); 52 | this.configProvider.initialize(this.config); 53 | 54 | getLogger().info("初始化MineSQL API..."); 55 | MineSQL.initializeAPI(this); 56 | 57 | getLogger().info("初始化注册池..."); 58 | this.registry = createRegistry(); 59 | 60 | Map dbProperties = readProperties(); 61 | Map dbConfigurations = readConfigurations(); 62 | 63 | if (dbProperties.isEmpty() && dbConfigurations.isEmpty()) { 64 | getLogger().warning("未检测到任何数据库配置,将不会预创建任何SQLManager。"); 65 | return; 66 | } 67 | 68 | dbProperties.forEach((id, properties) -> { 69 | try { 70 | getLogger().info("正在初始化数据库 #" + id + " ..."); 71 | SQLManagerImpl sqlManager = create(id, properties); 72 | this.registry.getManagers().put(id, sqlManager); 73 | getLogger().info("完成成初始化数据库 #" + id + " 。"); 74 | } catch (Exception ex) { 75 | getLogger().severe("初始化SQLManager(#" + id + ") 出错,请检查配置文件: " + ex.getMessage()); 76 | ex.printStackTrace(); 77 | } 78 | }); 79 | 80 | dbConfigurations.forEach((id, configuration) -> { 81 | try { 82 | getLogger().info("正在初始化数据库 #" + id + " ..."); 83 | SQLManagerImpl sqlManager = create(id, configuration); 84 | this.registry.getManagers().put(id, sqlManager); 85 | getLogger().info("完成初始化数据库 #" + id + " 。"); 86 | } catch (Exception ex) { 87 | getLogger().severe("初始化SQLManager(#" + id + ") 出错,请检查配置文件: " + ex.getMessage()); 88 | ex.printStackTrace(); 89 | } 90 | }); 91 | } 92 | 93 | public MineSQLPlatform getPlatform() { 94 | return platform; 95 | } 96 | 97 | public static MineSQLCore getInstance() { 98 | return instance; 99 | } 100 | 101 | @Override 102 | public @NotNull MineSQLRegistry getRegistry() { 103 | return this.registry; 104 | } 105 | 106 | @Override 107 | public @NotNull MineSQLRegistry createRegistry() { 108 | return new MineSQLRegistry(); 109 | } 110 | 111 | @Override 112 | public @NotNull SQLManagerImpl create(@NotNull String name, @NotNull SQLSourceConfig conf) throws Exception { 113 | BeeDataSourceConfig config = new BeeDataSourceConfig(); 114 | config.setDriverClassName(conf.getDriverClassName()); 115 | config.setJdbcUrl(conf.getJdbcURL()); 116 | Optional.ofNullable(conf.getUsername()).ifPresent(config::setUsername); 117 | Optional.ofNullable(conf.getPassword()).ifPresent(config::setPassword); 118 | 119 | Optional.ofNullable(conf.getSettings().getPoolName()).ifPresent(config::setPoolName); 120 | Optional.ofNullable(conf.getSettings().getMaxPoolSize()).ifPresent(config::setMaxActive); 121 | Optional.ofNullable(conf.getSettings().getMaxActive()).ifPresent(config::setMaxActive); 122 | 123 | Optional.ofNullable(conf.getSettings().getIdleTimeout()).ifPresent(config::setIdleTimeout); 124 | Optional.ofNullable(conf.getSettings().getMaxWaitTime()).ifPresent(config::setMaxWait); 125 | Optional.ofNullable(conf.getSettings().getMaxHoldTime()).ifPresent(config::setHoldTimeout); 126 | 127 | Optional.ofNullable(conf.getSettings().getAutoCommit()).ifPresent(config::setDefaultAutoCommit); 128 | Optional.ofNullable(conf.getSettings().getReadOnly()).ifPresent(config::setDefaultReadOnly); 129 | Optional.ofNullable(conf.getSettings().getSchema()).ifPresent(config::setDefaultSchema); 130 | 131 | Optional.ofNullable(conf.getSettings().getValidationSQL()).ifPresent(config::setAliveTestSql); 132 | Optional.ofNullable(conf.getSettings().getValidationTimeout()).ifPresent(config::setAliveTestTimeout); 133 | Optional.ofNullable(conf.getSettings().getValidationInterval()).ifPresent(config::setTimerCheckInterval); 134 | 135 | SQLManagerImpl manager = create(name, config); 136 | if (conf.getInitializer() != null) { 137 | conf.getInitializer().accept(manager); 138 | } 139 | 140 | return manager; 141 | } 142 | 143 | @Override 144 | public @NotNull SQLManagerImpl create(@NotNull String name, @NotNull Properties properties) { 145 | return create(name, new BeeDataSourceConfig(properties)); 146 | } 147 | 148 | @Override 149 | public @NotNull SQLManagerImpl create(@NotNull String name, @NotNull DataSource source) { 150 | return new SQLManagerImpl(source, name); 151 | } 152 | 153 | public @NotNull SQLManagerImpl create(@NotNull String name, @NotNull BeeDataSourceConfig configuration) { 154 | return create(name, (DataSource) new BeeDataSource(configuration)); 155 | } 156 | 157 | @Override 158 | public void shutdown(SQLManager manager, @Nullable Consumer> activeQueries) { 159 | if (activeQueries != null) activeQueries.accept(manager.getActiveQuery()); 160 | 161 | if (manager.getDataSource() instanceof BeeDataSource) { 162 | BeeDataSource dataSource = (BeeDataSource) manager.getDataSource(); 163 | dataSource.close(); //Close bee connection pool 164 | } 165 | } 166 | 167 | @Override 168 | public void createTables(@NotNull SQLTablesRoot tablesRoot) throws SQLException { 169 | for (Field field : tablesRoot.getClass().getDeclaredFields()) { 170 | initializeTableField(tablesRoot, field); 171 | } 172 | } 173 | 174 | @Override 175 | public void createTables(@NotNull Class clazz) throws SQLException { 176 | initializeTableClass(clazz); 177 | } 178 | 179 | protected void initializeTableClass(@NotNull Class clazz) throws SQLException { 180 | if (!SQLTablesRoot.class.isAssignableFrom(clazz)) return; 181 | 182 | for (Field field : clazz.getDeclaredFields()) { 183 | initializeTableField(clazz, field); 184 | } 185 | 186 | for (Class subClass : clazz.getDeclaredClasses()) { 187 | initializeTableClass(subClass); 188 | } 189 | 190 | } 191 | 192 | protected void initializeTableField(@NotNull Object source, @NotNull Field field) throws SQLException { 193 | try { 194 | field.setAccessible(true); 195 | Object object = field.get(source); 196 | 197 | if (object instanceof SimpleSQLTable) { 198 | ((SimpleSQLTable) object).create(); 199 | } else if (source instanceof SQLTablesRoot && object instanceof SQLTablesRoot) { 200 | createTables((SQLTablesRoot) object); 201 | } else if (source instanceof Class && object instanceof Class) { 202 | // 当且仅当 源字段与字段 均为静态类时,才对目标字段进行下一步初始化加载。 203 | initializeTableClass((Class) object); 204 | } 205 | } catch (IllegalAccessException ignored) { 206 | } 207 | } 208 | 209 | public void shutdownAll() { 210 | this.registry.getManagers().forEach((k, manager) -> { 211 | getLogger().info(" 正在关闭数据库 " + k + "..."); 212 | shutdown(manager, activeQueries -> { 213 | if (activeQueries.isEmpty()) return; 214 | getLogger().info(" 数据库 " + k + " 仍有 " + activeQueries.size() + " 条活动查询"); 215 | if (manager.getDataSource() instanceof BeeDataSource 216 | && getConfig().SETTINGS.FORCE_CLOSE.getNotNull()) { 217 | getLogger().info(" 将强制关闭全部活跃链接..."); 218 | BeeDataSource dataSource = (BeeDataSource) manager.getDataSource(); 219 | dataSource.close(); //Close bee connection pool 220 | } 221 | }); 222 | }); 223 | this.registry.getManagers().clear(); 224 | } 225 | 226 | @Override 227 | public @NotNull File getPluginFolder() { 228 | return getPlatform().getPluginFolder(); 229 | } 230 | 231 | @Override 232 | public @NotNull Logger getLogger() { 233 | return getPlatform().getLogger(); 234 | } 235 | 236 | public PluginConfiguration getConfig() { 237 | return config; 238 | } 239 | 240 | public ConfigurationHolder getConfigProvider() { 241 | return configProvider; 242 | } 243 | 244 | public @NotNull Map readConfigurations() { 245 | SQLSourceGroup group = getConfig().SOURCES.getNotNull(); 246 | Map sources = new LinkedHashMap<>(); 247 | group.getSources().entrySet().stream() 248 | .filter(entry -> !entry.getKey().startsWith("example-")) 249 | .forEach(entry -> sources.put(entry.getKey(), entry.getValue().createSource())); 250 | return sources; 251 | } 252 | 253 | public @NotNull Map readProperties() { 254 | if (!getConfig().PROPERTIES.ENABLE.getNotNull()) return new HashMap<>(); 255 | 256 | String propertiesFolder = getConfig().PROPERTIES.FOLDER.get(); 257 | if (propertiesFolder == null || propertiesFolder.length() == 0) return new HashMap<>(); 258 | 259 | File file = new File(getPluginFolder(), propertiesFolder); 260 | if (!file.exists() || !file.isDirectory()) { 261 | if ((propertiesFolder.equals("db-properties/") || propertiesFolder.equals("db-properties"))) { 262 | try { 263 | JarResourceUtils.copyFolderFromJar( 264 | "db-properties", getPluginFolder(), 265 | JarResourceUtils.CopyOption.COPY_IF_NOT_EXIST 266 | ); 267 | } catch (Exception ex) { 268 | getLogger().severe("初始化properties示例文件失败:" + ex.getMessage()); 269 | } 270 | } else { 271 | file.mkdirs(); 272 | } 273 | } 274 | 275 | return DBPropertiesUtil.readFromFolder(file); 276 | } 277 | 278 | @SuppressWarnings("deprecation") 279 | protected void initializeCommands(CommandManager commandManager) { 280 | commandManager.enableUnstableAPI("help"); 281 | commandManager.setHelpFormatter(new MineSQLHelpFormatter(commandManager)); 282 | commandManager.getLocales().setDefaultLocale(Locales.SIMPLIFIED_CHINESE); 283 | commandManager.getCommandContexts().registerContext(SQLManager.class, c -> { 284 | String name = c.popFirstArg(); 285 | try { 286 | return getRegistry().getNotNull(name); 287 | } catch (NullPointerException exception) { 288 | throw new InvalidCommandArgument("不存在名为 " + name + " 的数据库管理器。"); 289 | } 290 | }); 291 | commandManager.getCommandCompletions().registerCompletion("sql-managers", c -> { 292 | if (c.getIssuer().isPlayer()) return Collections.emptyList(); 293 | else return getRegistry().list().keySet(); 294 | }); 295 | commandManager.registerCommand(new MineSQLCommand(this)); 296 | } 297 | 298 | public void checkUpdate(String currentVersion) { 299 | Logger logger = getLogger(); 300 | 301 | Integer behindVersions = GithubReleases4J.getVersionBehind(References.REPO_OWNER, References.REPO_NAME, currentVersion); 302 | String downloadURL = GithubReleases4J.getReleasesURL(References.REPO_OWNER, References.REPO_NAME); 303 | if (behindVersions == null) { 304 | logger.severe("检查更新失败,请您定期查看插件是否更新,避免安全问题。"); 305 | logger.severe("下载地址 " + downloadURL); 306 | } else if (behindVersions < 0) { 307 | logger.severe("检查更新失败! 当前版本未知,请您使用原生版本以避免安全问题。"); 308 | logger.severe("最新版下载地址 " + downloadURL); 309 | } else if (behindVersions > 0) { 310 | logger.warning("发现新版本! 目前已落后 " + behindVersions + " 个版本。"); 311 | logger.warning("最新版下载地址 " + downloadURL); 312 | } else { 313 | logger.info("检查完成,当前已是最新版本。"); 314 | } 315 | } 316 | 317 | 318 | } 319 | -------------------------------------------------------------------------------- /core/src/main/java/cc/carm/plugin/minesql/MineSQLPlatform.java: -------------------------------------------------------------------------------- 1 | package cc.carm.plugin.minesql; 2 | 3 | import co.aikar.commands.CommandManager; 4 | import org.jetbrains.annotations.NotNull; 5 | import org.jetbrains.annotations.Nullable; 6 | 7 | import java.io.File; 8 | import java.util.logging.Logger; 9 | 10 | public interface MineSQLPlatform { 11 | 12 | @NotNull File getPluginFolder(); 13 | 14 | @NotNull Logger getLogger(); 15 | 16 | @Nullable CommandManager getCommandManager(); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /core/src/main/java/cc/carm/plugin/minesql/MineSQLRegistry.java: -------------------------------------------------------------------------------- 1 | package cc.carm.plugin.minesql; 2 | 3 | import cc.carm.lib.easysql.api.SQLManager; 4 | import cc.carm.plugin.minesql.api.SQLRegistry; 5 | import org.jetbrains.annotations.NotNull; 6 | import org.jetbrains.annotations.Nullable; 7 | import org.jetbrains.annotations.Unmodifiable; 8 | 9 | import java.util.Collections; 10 | import java.util.HashMap; 11 | import java.util.Map; 12 | import java.util.Optional; 13 | 14 | public class MineSQLRegistry implements SQLRegistry { 15 | 16 | private final HashMap managers = new HashMap<>(); 17 | 18 | protected HashMap getManagers() { 19 | return managers; 20 | } 21 | 22 | @Override 23 | public @NotNull Optional<@Nullable SQLManager> getOptional(@Nullable String id) { 24 | if (id != null) return Optional.of(this.managers.get(id)); 25 | else if (managers.isEmpty()) return Optional.empty(); 26 | else return Optional.ofNullable(managers.values().iterator().next()); 27 | } 28 | 29 | @Override 30 | @Unmodifiable 31 | public @NotNull Map list() { 32 | return Collections.unmodifiableMap(this.managers); 33 | } 34 | 35 | @Override 36 | public void register(@NotNull String name, @NotNull SQLManager sqlManager) throws IllegalStateException { 37 | if (this.managers.containsKey(name)) { 38 | throw new IllegalStateException("已存在ID为 " + name + " 的SQLManager实例。"); 39 | } 40 | this.managers.put(name, sqlManager); 41 | } 42 | 43 | @Override 44 | public @NotNull SQLManager unregister(@NotNull String name) throws NullPointerException { 45 | SQLManager manager = this.managers.remove(name); 46 | if (manager == null) throw new NullPointerException("不存在ID为 " + name + " 的SQLManager实例。"); 47 | return manager; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /core/src/main/java/cc/carm/plugin/minesql/command/MineSQLCommand.java: -------------------------------------------------------------------------------- 1 | package cc.carm.plugin.minesql.command; 2 | 3 | import cc.carm.lib.easysql.api.SQLManager; 4 | import cc.carm.lib.easysql.api.SQLQuery; 5 | import cc.carm.plugin.minesql.MineSQLCore; 6 | import cc.carm.plugin.minesql.lib.PluginLibraries; 7 | import cc.carm.plugin.minesql.util.VersionReader; 8 | import co.aikar.commands.BaseCommand; 9 | import co.aikar.commands.CommandHelp; 10 | import co.aikar.commands.CommandIssuer; 11 | import co.aikar.commands.annotation.*; 12 | 13 | import java.util.Map; 14 | import java.util.UUID; 15 | 16 | 17 | @SuppressWarnings("unused") 18 | @CommandAlias("MineSQL") 19 | @Description("MineSQL的主指令,用于开发者进行调试,只允许后台执行。") 20 | public class MineSQLCommand extends BaseCommand { 21 | 22 | protected final MineSQLCore core; 23 | 24 | public MineSQLCommand(MineSQLCore core) { 25 | this.core = core; 26 | } 27 | 28 | @HelpCommand 29 | @Syntax("&9[页码或子指令名称]") 30 | @Description("查看指定数据源的统计信息与当前仍未关闭的查询。") 31 | public void help(CommandIssuer issuer, CommandHelp help) { 32 | if (issuer.isPlayer()) { 33 | issuer.sendMessage("§c只有后台执行才能使用此命令。"); 34 | return; 35 | } 36 | help.showHelp(); 37 | } 38 | 39 | @Subcommand("version") 40 | @Description("查看当前插件版本与核心库(EasySQL)版本。") 41 | public void version(CommandIssuer issuer) { 42 | if (issuer.isPlayer()) { 43 | issuer.sendMessage("§c只有后台执行才能使用此命令。"); 44 | return; 45 | } 46 | VersionReader reader = PluginLibraries.READER; 47 | String pluginVersion = reader.get("plugin", null); 48 | if (pluginVersion == null) { 49 | issuer.sendMessage("§c无法获取当前版本信息,请保证使用原生版本以避免安全问题。"); 50 | return; 51 | } 52 | issuer.sendMessage("§r当前插件版本为 §b" + pluginVersion + "§r。 §7(基于 EasySQL &3" + reader.get("api") + "&7)"); 53 | issuer.sendMessage("§8 - &f连接池依赖 BeeCP §9" + reader.get("beecp")); 54 | issuer.sendMessage("§8 - &f数据库驱动 MySQL §9" + PluginLibraries.MYSQL_DRIVER.getVersion()); 55 | issuer.sendMessage("§8 - &f数据库驱动 MariaDB §9" + PluginLibraries.MARIADB_DRIVER.getVersion()); 56 | issuer.sendMessage("§8 - &f数据库驱动 h2-database §9" + PluginLibraries.H2_DRIVER.getVersion()); 57 | 58 | issuer.sendMessage("§r正在检查插件更新,请稍候..."); 59 | core.checkUpdate(pluginVersion); 60 | } 61 | 62 | @Subcommand("list") 63 | @Description("列出当前所有的数据源管理器与相关信息。") 64 | public void list(CommandIssuer issuer) { 65 | if (issuer.isPlayer()) { 66 | issuer.sendMessage("§c只有后台执行才能使用此命令。"); 67 | return; 68 | } 69 | Map runningManagers = MineSQLCore.getInstance().getRegistry().list(); 70 | if (runningManagers.isEmpty()) { 71 | issuer.sendMessage("§r当前无正在运行的数据库管理器。"); 72 | } else { 73 | issuer.sendMessage("§r当前有 §b" + runningManagers.size() + " §r个正在运行的数据库管理器:"); 74 | runningManagers.forEach( 75 | (name, manager) -> issuer.sendMessage("- " + name + " (" + manager.getActiveQuery().size() + " running)") 76 | ); 77 | } 78 | 79 | } 80 | 81 | @Subcommand("info") 82 | @CommandCompletion("@sql-managers") 83 | @Syntax("&9<数据源名称>") 84 | @Description("查看指定数据源的统计信息与当前仍未关闭的查询。") 85 | public void info(CommandIssuer issuer, 86 | @Syntax("&9数据源名称") @Description("数据源管理器名称,一般在配置文件中指定。") SQLManager manager) { 87 | if (issuer.isPlayer()) { 88 | issuer.sendMessage("§c只有后台执行才能使用此命令。"); 89 | return; 90 | } 91 | Map activeQueries = manager.getActiveQuery(); 92 | if (activeQueries.isEmpty()) { 93 | issuer.sendMessage("§r当前暂无活跃查询。"); 94 | } else { 95 | issuer.sendMessage("§r当前有 §b" + activeQueries.size() + " §r个活跃查询:"); 96 | activeQueries.forEach((uuid, query) -> { 97 | issuer.sendMessage("§8#§b " + uuid.toString()); 98 | issuer.sendMessage("§8-§f " + query.getSQLContent()); 99 | }); 100 | } 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /core/src/main/java/cc/carm/plugin/minesql/command/MineSQLHelpFormatter.java: -------------------------------------------------------------------------------- 1 | package cc.carm.plugin.minesql.command; 2 | 3 | import co.aikar.commands.*; 4 | 5 | public class MineSQLHelpFormatter extends CommandHelpFormatter { 6 | 7 | public MineSQLHelpFormatter(CommandManager manager) { 8 | super(manager); 9 | } 10 | 11 | @Override 12 | public void printHelpHeader(CommandHelp help, CommandIssuer issuer) { 13 | issuer.sendMessage("§3§lMineSQL §7指令帮助"); 14 | } 15 | 16 | @Override 17 | public void printHelpCommand(CommandHelp help, CommandIssuer issuer, HelpEntry entry) { 18 | issuer.sendMessage("§8# §f" + entry.getCommand() + " §r" + entry.getParameterSyntax()); 19 | if (!entry.getDescription().isEmpty()) { 20 | issuer.sendMessage("§8- §7" + entry.getDescription()); 21 | } 22 | } 23 | 24 | @Override 25 | public void printHelpFooter(CommandHelp help, CommandIssuer issuer) { 26 | } 27 | 28 | @Override 29 | public void printSearchHeader(CommandHelp help, CommandIssuer issuer) { 30 | issuer.sendMessage("§3§lMineSQL §7指令帮助查询"); 31 | } 32 | 33 | @Override 34 | public void printSearchEntry(CommandHelp help, CommandIssuer issuer, HelpEntry entry) { 35 | printHelpCommand(help, issuer, entry); 36 | } 37 | 38 | @Override 39 | public void printSearchFooter(CommandHelp help, CommandIssuer issuer) { 40 | } 41 | 42 | @Override 43 | public void printDetailedHelpHeader(CommandHelp help, CommandIssuer issuer, HelpEntry entry) { 44 | issuer.sendMessage("§3§lMineSQL §7指令帮助 §8(§f" + entry.getCommand() + "§8)"); 45 | } 46 | 47 | @Override 48 | public void printDetailedHelpCommand(CommandHelp help, CommandIssuer issuer, HelpEntry entry) { 49 | printHelpCommand(help, issuer, entry); 50 | } 51 | 52 | @Override 53 | public void printDetailedParameter(CommandHelp help, CommandIssuer issuer, HelpEntry entry, CommandParameter param) { 54 | if (param.getDescription() != null) { 55 | if (param.getSyntax() != null) { 56 | issuer.sendMessage("§8@§r" + param.getSyntax() + "§7 §f" + param.getDescription()); 57 | } else { 58 | issuer.sendMessage("§8@§f" + param.getName() + "§7 §f" + param.getDescription()); 59 | } 60 | } 61 | } 62 | 63 | @Override 64 | public void printDetailedHelpFooter(CommandHelp help, CommandIssuer issuer, HelpEntry entry) { 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /core/src/main/java/cc/carm/plugin/minesql/conf/PluginConfiguration.java: -------------------------------------------------------------------------------- 1 | package cc.carm.plugin.minesql.conf; 2 | 3 | import cc.carm.lib.configuration.Configuration; 4 | import cc.carm.lib.configuration.annotation.ConfigPath; 5 | import cc.carm.lib.configuration.annotation.HeaderComments; 6 | import cc.carm.lib.configuration.value.standard.ConfiguredValue; 7 | 8 | @ConfigPath(root = true) 9 | public class PluginConfiguration implements Configuration { 10 | 11 | @HeaderComments("排错模式,一般留给开发者检查问题,平常使用无需开启。") 12 | public final ConfiguredValue DEBUG = ConfiguredValue.of(Boolean.class, false); 13 | 14 | @HeaderComments({"", 15 | "统计数据设定", 16 | "该选项用于帮助开发者统计插件版本与使用情况,且绝不会影响性能与使用体验。", 17 | "当然,您也可以选择在这里关闭,或在plugins/bStats下的配置文件中关闭所有插件的统计信息。" 18 | }) 19 | public final ConfiguredValue METRICS = ConfiguredValue.of(Boolean.class, true); 20 | 21 | @HeaderComments({"", 22 | "检查更新设定", 23 | "该选项用于插件判断是否要检查更新,若您不希望插件检查更新并提示您,可以选择关闭。", 24 | "检查更新为异步操作,绝不会影响性能与使用体验。" 25 | }) 26 | public final ConfiguredValue UPDATE_CHECKER = ConfiguredValue.of(Boolean.class, true); 27 | 28 | @HeaderComments({"插件注册池配置"}) 29 | public final SettingsConfig SETTINGS = new SettingsConfig(); 30 | 31 | @HeaderComments({"", 32 | "Properties 数据库配置文件配置", 33 | "相关配置介绍(BeeCP) https://github.com/Chris2018998/BeeCP/wiki/Configuration--List#配置列表" 34 | }) 35 | public final PropertiesConfig PROPERTIES = new PropertiesConfig(); 36 | 37 | @HeaderComments({"", 38 | "数据库源配置", 39 | "目前支持的驱动类型(type)有 mariadb、mysql、h2-file(文件数据库) 与 h2-mem(内存临时数据库)。", 40 | "详细配置介绍请查看 https://github.com/CarmJos/MineSQL/.doc/README.md" 41 | }) 42 | public final ConfiguredValue SOURCES = ConfiguredValue.builderOf(SQLSourceGroup.class) 43 | .fromSection() 44 | .parse((w, sec) -> SQLSourceGroup.parse(sec)) 45 | .serialize(SQLSourceGroup::serialize) 46 | .defaults(SQLSourceGroup.defaults()) 47 | .build(); 48 | 49 | public static class PropertiesConfig implements Configuration { 50 | 51 | @HeaderComments({"该选项用于启用 Properties 配置读取。", "若您不希望插件启用 Properties 文件配置功能,可以选择关闭。"}) 52 | public ConfiguredValue ENABLE = ConfiguredValue.of(Boolean.class, true); 53 | 54 | @HeaderComments({ 55 | "文件夹路径,将读取该文件夹下的所有 .properties 文件,并以文件名为数据管理器名称。", 56 | "读取时,将排除以 “.” 开头的文件与非 .properties 文件。", 57 | "默认为 \"db-properties/\" 相对路径,指向“plugins/MineSQL/db-properties/”;", 58 | "该选项也支持绝对路径,但使用绝对路径时,请务必注意权限问题。" 59 | }) 60 | public ConfiguredValue FOLDER = ConfiguredValue.of(String.class, "db-properties/"); 61 | 62 | } 63 | 64 | public static class SettingsConfig implements Configuration { 65 | 66 | @HeaderComments({"在插件卸载时是否强制关闭活跃链接"}) 67 | public ConfiguredValue FORCE_CLOSE = ConfiguredValue.of(Boolean.class, true); 68 | 69 | } 70 | 71 | 72 | } 73 | -------------------------------------------------------------------------------- /core/src/main/java/cc/carm/plugin/minesql/conf/SQLSourceGroup.java: -------------------------------------------------------------------------------- 1 | package cc.carm.plugin.minesql.conf; 2 | 3 | import cc.carm.lib.configuration.source.section.ConfigureSection; 4 | import cc.carm.plugin.minesql.MineSQL; 5 | import cc.carm.plugin.minesql.api.SQLDriverType; 6 | import cc.carm.plugin.minesql.api.conf.SQLDriverConfig; 7 | import cc.carm.plugin.minesql.api.conf.drivers.H2MemConfig; 8 | import cc.carm.plugin.minesql.api.conf.impl.FileBasedConfig; 9 | import cc.carm.plugin.minesql.api.conf.impl.RemoteAuthConfig; 10 | import org.jetbrains.annotations.NotNull; 11 | import org.jetbrains.annotations.Nullable; 12 | 13 | import java.util.Collections; 14 | import java.util.LinkedHashMap; 15 | import java.util.Map; 16 | 17 | public class SQLSourceGroup { 18 | 19 | protected final LinkedHashMap sources; 20 | 21 | public SQLSourceGroup(LinkedHashMap sources) { 22 | this.sources = sources; 23 | } 24 | 25 | public Map getSources() { 26 | return Collections.unmodifiableMap(sources); 27 | } 28 | 29 | public @NotNull Map serialize() { 30 | Map data = new LinkedHashMap<>(); 31 | this.sources.forEach((k, v) -> data.put(k, v.serialize())); 32 | return data; 33 | } 34 | 35 | public static @NotNull SQLSourceGroup defaults() { 36 | LinkedHashMap configs = new LinkedHashMap<>(); 37 | configs.put("example-mysql", new RemoteAuthConfig( 38 | SQLDriverType.MARIADB, "127.0.0.1", 3306, 39 | "minecraft", "minecraft", "minecraft", 40 | "?sslMode=false" 41 | )); 42 | configs.put("example-h2-file", new FileBasedConfig(SQLDriverType.H2_FILE, "test")); 43 | configs.put("example-h2-mem", new H2MemConfig("temp")); 44 | return new SQLSourceGroup(configs); 45 | } 46 | 47 | public static @NotNull SQLSourceGroup parse(ConfigureSection rootSection) { 48 | LinkedHashMap configs = new LinkedHashMap<>(); 49 | for (String name : rootSection.getKeys(false)) { 50 | if (!rootSection.isSection(name)) continue; 51 | ConfigureSection section = rootSection.getSection(name); 52 | if (section == null) continue; 53 | SQLDriverConfig conf = parse(name, section); 54 | if (conf != null) configs.put(name, conf); 55 | } 56 | return new SQLSourceGroup(configs); 57 | } 58 | 59 | public static @Nullable SQLDriverConfig parse(String name, ConfigureSection section) { 60 | @Nullable String driverString = section.getString("type"); 61 | @Nullable SQLDriverType driverType = SQLDriverType.parse(driverString); 62 | if (driverType == null) { 63 | MineSQL.getLogger().severe("驱动类型 " + driverString + " 不存在于预设中," + " 请检查配置文件 sources." + name + "。"); 64 | return null; 65 | } 66 | 67 | switch (driverType) { 68 | case MYSQL: 69 | case MARIADB: { 70 | String host = section.getString("host"); 71 | int port = section.getInt("port", 0); 72 | String database = section.getString("database"); 73 | if (host == null || database == null || !(port > 0 && port <= 65535)) { 74 | MineSQL.getLogger().severe("数据库连接配置有误," + " 请检查配置文件 sources." + name + "。"); 75 | return null; 76 | } 77 | 78 | String username = section.getString("username"); 79 | String password = section.getString("password"); 80 | String extra = section.getString("extra"); 81 | return new RemoteAuthConfig(driverType, host, port, database, username, password, extra); 82 | } 83 | case H2_MEM: { 84 | return new H2MemConfig(section.getString("database")); 85 | } 86 | case H2_FILE: { 87 | String filePath = section.getString("file"); 88 | if (filePath == null) { 89 | MineSQL.getLogger().severe("数据库文件地址配置有误," + " 请检查配置文件 sources." + name + "。"); 90 | return null; 91 | } 92 | return new FileBasedConfig(SQLDriverType.H2_FILE, filePath); 93 | } 94 | } 95 | 96 | return null; 97 | } 98 | 99 | 100 | } 101 | -------------------------------------------------------------------------------- /core/src/main/java/cc/carm/plugin/minesql/lib/PluginLibraries.java: -------------------------------------------------------------------------------- 1 | package cc.carm.plugin.minesql.lib; 2 | 3 | import cc.carm.plugin.minesql.util.VersionReader; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | public enum PluginLibraries { 7 | 8 | BEECP("com.github.chris2018998", "beecp"), 9 | H2_DRIVER("com.h2database", "h2"), 10 | MYSQL_DRIVER("com.mysql", "mysql-connector-j"), 11 | MARIADB_DRIVER("org.mariadb.jdbc", "mariadb-java-client"); 12 | 13 | public static final VersionReader READER = new VersionReader(); 14 | 15 | private final @NotNull String groupID; 16 | private final @NotNull String artifactID; 17 | 18 | PluginLibraries(@NotNull String groupID, @NotNull String artifactID) { 19 | this.groupID = groupID; 20 | this.artifactID = artifactID; 21 | } 22 | 23 | public @NotNull String getVersion() { 24 | return READER.get(name().toLowerCase().replace('_', '-')); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /core/src/main/java/cc/carm/plugin/minesql/util/DBPropertiesUtil.java: -------------------------------------------------------------------------------- 1 | package cc.carm.plugin.minesql.util; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | 5 | import java.io.File; 6 | import java.io.FileInputStream; 7 | import java.io.IOException; 8 | import java.io.InputStream; 9 | import java.util.HashMap; 10 | import java.util.Map; 11 | import java.util.Properties; 12 | 13 | public class DBPropertiesUtil { 14 | 15 | public static Map readFromFolder(File propertiesFolder) { 16 | Map propertiesMap = new HashMap<>(); 17 | if (!propertiesFolder.exists() || !propertiesFolder.isDirectory()) return propertiesMap; 18 | 19 | File[] files = propertiesFolder.listFiles(); 20 | if (files == null) return propertiesMap; 21 | for (File file : files) { 22 | if (!validateName(file.getName())) continue; 23 | String name = file.getName().substring(0, file.getName().lastIndexOf(".")); 24 | try (InputStream is = new FileInputStream(file)) { 25 | propertiesMap.put(name, read(is)); 26 | } catch (IOException ignored) { 27 | } 28 | } 29 | 30 | return propertiesMap; 31 | } 32 | 33 | public static @NotNull Properties read(InputStream stream) throws IOException { 34 | Properties properties = new Properties(); 35 | properties.load(stream); 36 | return properties; 37 | } 38 | 39 | public static boolean validateName(String name) { 40 | return !name.contains(" ") && !name.startsWith(".") && name.endsWith(".properties"); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /core/src/main/java/cc/carm/plugin/minesql/util/VersionReader.java: -------------------------------------------------------------------------------- 1 | package cc.carm.plugin.minesql.util; 2 | 3 | import org.jetbrains.annotations.Contract; 4 | import org.jetbrains.annotations.NotNull; 5 | import org.jetbrains.annotations.Nullable; 6 | 7 | import java.io.InputStream; 8 | import java.util.Properties; 9 | 10 | public class VersionReader { 11 | 12 | String versionsFileName; 13 | 14 | 15 | public VersionReader() { 16 | this("versions.properties"); 17 | } 18 | 19 | public VersionReader(String versionsFileName) { 20 | this.versionsFileName = versionsFileName; 21 | } 22 | 23 | public synchronized @NotNull String get(@NotNull String artifactID) { 24 | return get(artifactID, "unknown"); 25 | } 26 | 27 | @Contract("_,!null->!null") 28 | public synchronized @Nullable String get(@NotNull String artifactID, 29 | @Nullable String defaultValue) { 30 | try (InputStream is = this.getClass().getResourceAsStream("/" + versionsFileName)) { 31 | Properties p = new Properties(); 32 | p.load(is); 33 | return p.getProperty(artifactID, defaultValue); 34 | } catch (Exception ignore) { 35 | } 36 | return defaultValue; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /core/src/main/resources/PLUGIN_INFO: -------------------------------------------------------------------------------- 1 | &d __ ____ &f________ __ 2 | &d / |/ (_)__ ___ &f/ __/ __ \ / / 3 | &d / /|_/ / / _ \/ -_)&f\ \/ /_/ / / /__ 4 | &d/_/ /_/_/_//_/\__/&f___/\___\_\/____/ 5 | &8# &dMine&fSQL &8&o(EasySQL-Plugin) &7v&f${project.version} 6 | &8- &7查看更多信息请访问项目主页&f https://github.com/CarmJos/MineSQL -------------------------------------------------------------------------------- /core/src/main/resources/acf-core_zh_CN.properties: -------------------------------------------------------------------------------- 1 | # suppress inspection "UnusedProperty" for whole file 2 | # 3 | # Copyright (c) 2016-2021 Daniel Ennis (Aikar) - MIT License 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining 6 | # a copy of this software and associated documentation files (the 7 | # "Software"), to deal in the Software without restriction, including 8 | # without limitation the rights to use, copy, modify, merge, publish, 9 | # distribute, sublicense, and/or sell copies of the Software, and to 10 | # permit persons to whom the Software is furnished to do so, subject to 11 | # the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be 14 | # included in all copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | # 24 | acf-core.permission_denied=很抱歉,你没有执行此命令的权限。 25 | acf-core.permission_denied_parameter=很抱歉,你没有执行此命令的权限。 26 | acf-core.error_generic_logged=很抱歉,插件产生了内部错误。问题已输出在游戏日志中。 27 | acf-core.unknown_command=§r您输入了未知的指令,输入 §b/EasySQL help §r获得指令帮助。 28 | acf-core.invalid_syntax=§r指令用法 §b{command} {syntax} §r。 29 | acf-core.error_prefix=在执行指令时出现了一个错误:\n{message} 30 | acf-core.error_performing_command=很抱歉,指令执行中出现了错误。 31 | acf-core.info_message=§r{message} 32 | acf-core.please_specify_one_of=错误:请输入 {valid} 中的某一个。 33 | acf-core.must_be_a_number=错误:{num} 必须是数字。 34 | acf-core.must_be_min_length=错误:至少需要输入 {min} 个字符。 35 | acf-core.must_be_max_length=错误:最多需要输入 {max} 个字符。 36 | acf-core.please_specify_at_most=错误:请输入一个不大于 {max} 的值。 37 | acf-core.please_specify_at_least=错误:请输入一个不小于 {min} 的值。 38 | acf-core.not_allowed_on_console=错误:控制台不能执行此命令。 39 | acf-core.could_not_find_player=错误:找不到名叫 {search} 的玩家。 40 | acf-core.no_command_matched_search=§r抱歉,没有匹配 §b{search} §r的指令。 41 | acf-core.help_no_results=§r抱歉,没有相关的指令帮助。 -------------------------------------------------------------------------------- /core/src/main/resources/acf-minecraft_zh_CN.properties: -------------------------------------------------------------------------------- 1 | # suppress inspection "UnusedProperty" for whole file 2 | # 3 | # Copyright (c) 2016-2021 Daniel Ennis (Aikar) - MIT License 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining 6 | # a copy of this software and associated documentation files (the 7 | # "Software"), to deal in the Software without restriction, including 8 | # without limitation the rights to use, copy, modify, merge, publish, 9 | # distribute, sublicense, and/or sell copies of the Software, and to 10 | # permit persons to whom the Software is furnished to do so, subject to 11 | # the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be 14 | # included in all copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | # 24 | 25 | acf-minecraft.invalid_world = 错误:该世界不存在。 26 | acf-minecraft.you_must_be_holding_item = 错误:你的主手上必须持有物品。 27 | acf-minecraft.player_is_vanished_confirm = \ 28 | 警告:{vanished} 已被隐藏。不要暴露他们的身份!\n\ 29 | 如果你确认这么做,请在他们的名字后面加上 :confirm 。\n\ 30 | 例如:{vanished}:confirm 31 | acf-minecraft.username_too_short = 错误:名字太短,请至少输入三个字符。 32 | acf-minecraft.is_not_a_valid_name = 错误:{name} 不是一个可以用的名字。 33 | acf-minecraft.multiple_players_match = 错误:{search} 的搜索结果过多(共计{all}人),请再详细一点。 34 | acf-minecraft.no_player_found_server = 没有搜索到匹配 {search} 的在线玩家。 35 | acf-minecraft.no_player_found_offline = 没有搜索到匹配 {search} 的在线/离线玩家。 36 | acf-minecraft.no_player_found = 没有搜索到匹配 {search} 的玩家。 37 | acf-minecraft.location_please_specify_world = 错误:请指明世界。例如:world:x,y,z。 38 | acf-minecraft.location_please_specify_xyz = 错误:请指明坐标x,y和z。例如:world:x,y,z。 39 | acf-minecraft.location_console_not_relative = 错误:控制台不能使用相对坐标来指明位置。 -------------------------------------------------------------------------------- /core/src/main/resources/db-properties/.example-mysql.properties: -------------------------------------------------------------------------------- 1 | # suppress inspection "UnusedProperty" for whole file 2 | 3 | # 该功能一般用于专业开发者使用,若您不了解该功能,请尽量使用config.yml中提供的配置方式,简单便捷,能够满足大多数需求。 4 | # 更多帮助详见 BeeCP项目地址 https://github.com/Chris2018998/BeeCP 5 | 6 | #JDBC 用户名 7 | username=root 8 | #JDBC 密码 9 | password=root 10 | # JDBC连接URL 11 | jdbcUrl=jdbc:mysql://localhost/test 12 | # JDBC驱动类名 13 | driverClassName=com.mysql.cj.jdbc.Driver 14 | # 连接有效性测试SQL语句 15 | connectionTestSQL=select 1 from dual 16 | # 池名,如果未赋值则会自动产生一个 17 | poolName=Pool1 18 | # 是否使用公平模式 (竞争模式=false) 19 | fairMode=false 20 | # 连接池初始大小 21 | initialSize=1 22 | # 连接池最大个数 23 | maxActive=10 24 | # 信号量许可大小 min(最大连接数/2,CPU核心数) 25 | borrowSemaphoreSize=4 26 | # 连接借用等待最大时间(毫秒) 27 | maxWait=8000 28 | # 连接闲置最大时间(毫秒) 29 | idleTimeout=18000 30 | # 连接被持有不用最大允许时间(毫秒) 31 | holdTimeout=30000 32 | # 连接有效性测试SQL语句 33 | validTestTimeout=3 34 | # 连接测试的间隔时间(毫秒) 35 | validAssumeTime=500 36 | # 闲置扫描线程间隔时间(毫秒) 37 | timerCheckInterval=30000 38 | # 在结束时是否直接关闭使用中连接 39 | forceCloseUsingOnClear=true 40 | # 延迟清理的时候时间(毫秒) 41 | delayTimeForNextClear=3000 42 | 43 | # JMX监控支持开关 44 | enableJmx=false 45 | 46 | # Catalog默认值 47 | defaultCatalog=test1 48 | # Schema默认值 49 | defaultSchema=test2 50 | # ReadOnly默认值 51 | defaultReadOnly=true 52 | # 自动提交默认值 53 | defaultAutoCommit=true 54 | 55 | # 事物隔离代码,未设置时则从第一个连接上读取 56 | defaultTransactionIsolationCode=1 57 | defaultTransactionIsolationName=TRANSACTION_READ_UNCOMMITTED 58 | 59 | # 额外链接配置 60 | connectProperties=cachePrepStmts=true 61 | connectProperties.count=2 62 | connectProperties.1=prepStmtCacheSize=50 63 | connectProperties.2=prepStmtCacheSqlLimit=2048&useServerPrepStmts=true -------------------------------------------------------------------------------- /core/src/main/resources/versions.properties: -------------------------------------------------------------------------------- 1 | # suppress inspection "SpellCheckingInspection" for whole file 2 | 3 | plugin=${project.version} 4 | api=${deps.easysql.version} 5 | 6 | beecp=${deps.beecp.version} 7 | 8 | mysql-driver=${deps.mysql-driver.version} 9 | mariadb-driver=${deps.mariadb-driver.version} 10 | h2-driver=${deps.h2-driver.version} 11 | 12 | -------------------------------------------------------------------------------- /core/src/main/templates/cc/carm/plugin/minesql/References.java: -------------------------------------------------------------------------------- 1 | package cc.carm.plugin.minesql; 2 | 3 | public interface References { 4 | 5 | String REPO_OWNER = "CarmJos"; 6 | String REPO_NAME = "MineSQL"; 7 | String VERSION = "${project.version}"; 8 | 9 | } 10 | -------------------------------------------------------------------------------- /platforms/bukkit/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | minesql-parent 7 | cc.carm.plugin 8 | 1.4.3 9 | ../../pom.xml 10 | 11 | 4.0.0 12 | 13 | 14 | ${project.jdk.version} 15 | ${project.jdk.version} 16 | UTF-8 17 | UTF-8 18 | true 19 | true 20 | 21 | 22 | minesql-platform-bukkit 23 | jar 24 | 25 | MineSQL-Bukkit 26 | 轻松(用)SQL的独立运行库Bukkit版本插件。 27 | https://github.com/CarmJos/MineSQL 28 | 29 | 30 | 31 | CarmJos 32 | Carm Jos 33 | carm@carm.cc 34 | https://www.carm.cc 35 | 36 | Main Developer 37 | Designer 38 | 39 | 40 | 41 | 42 | 43 | 44 | GNU General Public License v3.0 45 | https://opensource.org/licenses/GPL-3.0 46 | 47 | 48 | 49 | 50 | GitHub Issues 51 | https://github.com/CarmJos/MineSQL/issues 52 | 53 | 54 | 55 | GitHub Actions 56 | https://github.com/CarmJos/MineSQL/actions/workflows/maven.yml 57 | 58 | 59 | 60 | 61 | 62 | ${project.parent.groupId} 63 | minesql-core 64 | ${project.parent.version} 65 | compile 66 | 67 | 68 | 69 | cc.carm.lib 70 | easyplugin-main 71 | ${deps.easyplugin.version} 72 | compile 73 | 74 | 75 | 76 | org.spigotmc 77 | spigot-api 78 | 1.16.3-R0.1-SNAPSHOT 79 | provided 80 | 81 | 82 | 83 | org.bstats 84 | bstats-bukkit 85 | ${deps.bstats.version} 86 | compile 87 | 88 | 89 | 90 | co.aikar 91 | acf-paper 92 | ${deps.acf.version} 93 | compile 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | org.apache.maven.plugins 102 | maven-compiler-plugin 103 | 104 | 105 | org.apache.maven.plugins 106 | maven-jar-plugin 107 | 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /platforms/bukkit/src/main/java/cc/carm/plugin/minesql/MineSQLBukkit.java: -------------------------------------------------------------------------------- 1 | package cc.carm.plugin.minesql; 2 | 3 | import cc.carm.lib.easyplugin.EasyPlugin; 4 | import cc.carm.plugin.minesql.conf.PluginConfiguration; 5 | import co.aikar.commands.CommandManager; 6 | import co.aikar.commands.PaperCommandManager; 7 | import org.bstats.bukkit.Metrics; 8 | import org.bstats.charts.SimplePie; 9 | import org.jetbrains.annotations.NotNull; 10 | 11 | import java.io.File; 12 | 13 | public class MineSQLBukkit extends EasyPlugin implements MineSQLPlatform { 14 | 15 | protected static MineSQLBukkit instance; 16 | 17 | protected MineSQLCore core; 18 | protected PaperCommandManager commandManager; 19 | 20 | @Override 21 | protected void load() { 22 | MineSQLBukkit.instance = this; 23 | 24 | log("加载基础核心..."); 25 | this.core = new MineSQLCore(this); 26 | } 27 | 28 | @Override 29 | protected boolean initialize() { 30 | log("初始化指令管理器..."); 31 | this.commandManager = new PaperCommandManager(this); 32 | 33 | log("注册相关指令..."); 34 | this.core.initializeCommands(getCommandManager()); 35 | 36 | if (getConfiguration().METRICS.getNotNull()) { 37 | log("启用统计数据..."); 38 | Metrics metrics = new Metrics(this, 14075); 39 | metrics.addCustomChart(new SimplePie("update_check", 40 | () -> getConfiguration().UPDATE_CHECKER.getNotNull() ? "ENABLED" : "DISABLED") 41 | ); 42 | metrics.addCustomChart(new SimplePie("properties_configuration", 43 | () -> getConfiguration().PROPERTIES.ENABLE.getNotNull() ? "ENABLED" : "DISABLED") 44 | ); 45 | } 46 | 47 | if (getConfiguration().UPDATE_CHECKER.getNotNull()) { 48 | log("开始检查更新,可能需要一小段时间..."); 49 | log(" 如不希望检查更新,可在配置文件中关闭。"); 50 | getScheduler().runAsync(() -> this.core.checkUpdate(getDescription().getVersion())); 51 | } else { 52 | log("已禁用检查更新,跳过。"); 53 | } 54 | 55 | return true; 56 | } 57 | 58 | @Override 59 | protected void shutdown() { 60 | log("终止全部数据库连接..."); 61 | this.core.shutdownAll(); 62 | } 63 | 64 | @Override 65 | public boolean isDebugging() { 66 | return getConfiguration().DEBUG.getNotNull(); 67 | } 68 | 69 | public static @NotNull MineSQLBukkit getInstance() { 70 | return MineSQLBukkit.instance; 71 | } 72 | 73 | public @NotNull PluginConfiguration getConfiguration() { 74 | return this.core.getConfig(); 75 | } 76 | 77 | public @NotNull CommandManager getCommandManager() { 78 | return commandManager; 79 | } 80 | 81 | @Override 82 | public @NotNull File getPluginFolder() { 83 | return getDataFolder(); 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /platforms/bukkit/src/main/resources/plugin.yml: -------------------------------------------------------------------------------- 1 | main: cc.carm.plugin.minesql.MineSQLBukkit 2 | version: ${project.version} 3 | 4 | prefix: MineSQL 5 | name: MineSQL 6 | load: STARTUP 7 | 8 | website: ${project.url} 9 | description: ${project.description} 10 | authors: 11 | - CarmJos 12 | - GhostChu 13 | 14 | api-version: 1.13 -------------------------------------------------------------------------------- /platforms/bungee/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | minesql-parent 7 | cc.carm.plugin 8 | 1.4.3 9 | ../../pom.xml 10 | 11 | 4.0.0 12 | 13 | 14 | ${project.jdk.version} 15 | ${project.jdk.version} 16 | UTF-8 17 | UTF-8 18 | true 19 | true 20 | 21 | 22 | minesql-platform-bungee 23 | jar 24 | 25 | MineSQL-Bungee 26 | 轻松(用)SQL的独立运行库Bungee版本插件。 27 | https://github.com/CarmJos/MineSQL 28 | 29 | 30 | 31 | CarmJos 32 | Carm Jos 33 | carm@carm.cc 34 | https://www.carm.cc 35 | 36 | Main Developer 37 | Designer 38 | 39 | 40 | 41 | 42 | 43 | 44 | GNU General Public License v3.0 45 | https://opensource.org/licenses/GPL-3.0 46 | 47 | 48 | 49 | 50 | GitHub Issues 51 | https://github.com/CarmJos/MineSQL/issues 52 | 53 | 54 | 55 | GitHub Actions 56 | https://github.com/CarmJos/MineSQL/actions/workflows/maven.yml 57 | 58 | 59 | 60 | 61 | 62 | ${project.parent.groupId} 63 | minesql-core 64 | ${project.parent.version} 65 | compile 66 | 67 | 68 | 69 | io.github.waterfallmc 70 | waterfall-api 71 | 1.21-R0.2-SNAPSHOT 72 | provided 73 | 74 | 75 | 76 | org.bstats 77 | bstats-bungeecord 78 | ${deps.bstats.version} 79 | compile 80 | 81 | 82 | 83 | co.aikar 84 | acf-bungee 85 | ${deps.acf.version} 86 | compile 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | org.apache.maven.plugins 95 | maven-compiler-plugin 96 | 97 | 98 | org.apache.maven.plugins 99 | maven-jar-plugin 100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /platforms/bungee/src/main/java/cc/carm/plugin/minesql/MineSQLBungee.java: -------------------------------------------------------------------------------- 1 | package cc.carm.plugin.minesql; 2 | 3 | import cc.carm.lib.easyplugin.utils.ColorParser; 4 | import cc.carm.lib.easyplugin.utils.JarResourceUtils; 5 | import cc.carm.plugin.minesql.conf.PluginConfiguration; 6 | import co.aikar.commands.BungeeCommandManager; 7 | import co.aikar.commands.CommandManager; 8 | import net.md_5.bungee.api.ProxyServer; 9 | import net.md_5.bungee.api.plugin.Plugin; 10 | import org.bstats.bungeecord.Metrics; 11 | import org.bstats.charts.SimplePie; 12 | import org.jetbrains.annotations.NotNull; 13 | 14 | import java.io.File; 15 | import java.util.Arrays; 16 | import java.util.Optional; 17 | import java.util.logging.Logger; 18 | 19 | public class MineSQLBungee extends Plugin implements MineSQLPlatform { 20 | 21 | protected static MineSQLBungee instance; 22 | 23 | protected MineSQLCore core; 24 | protected BungeeCommandManager commandManager; 25 | 26 | @Override 27 | public void onLoad() { 28 | MineSQLBungee.instance = this; 29 | 30 | getLogger().info("加载基础核心..."); 31 | this.core = new MineSQLCore(this); 32 | } 33 | 34 | @Override 35 | public void onEnable() { 36 | outputInfo(); 37 | getLogger().info("初始化指令管理器..."); 38 | this.commandManager = new BungeeCommandManager(this); 39 | 40 | getLogger().info("注册相关指令..."); 41 | this.core.initializeCommands(getCommandManager()); 42 | 43 | if (getConfiguration().METRICS.getNotNull()) { 44 | getLogger().info("启用统计数据..."); 45 | Metrics metrics = new Metrics(this, 14076); 46 | metrics.addCustomChart(new SimplePie("update_check", 47 | () -> getConfiguration().UPDATE_CHECKER.getNotNull() ? "ENABLED" : "DISABLED") 48 | ); 49 | metrics.addCustomChart(new SimplePie("properties_configuration", 50 | () -> getConfiguration().PROPERTIES.ENABLE.getNotNull() ? "ENABLED" : "DISABLED") 51 | ); 52 | } 53 | 54 | if (getConfiguration().UPDATE_CHECKER.getNotNull()) { 55 | getLogger().info("开始检查更新,可能需要一小段时间..."); 56 | getLogger().info(" 如不希望检查更新,可在配置文件中关闭。"); 57 | ProxyServer.getInstance().getScheduler().runAsync( 58 | this, () -> this.core.checkUpdate(getDescription().getVersion()) 59 | ); 60 | } else { 61 | getLogger().info("已禁用检查更新,跳过。"); 62 | } 63 | } 64 | 65 | @Override 66 | public void onDisable() { 67 | outputInfo(); 68 | getLogger().info("终止全部数据库连接..."); 69 | this.core.shutdownAll(); 70 | } 71 | 72 | public static MineSQLBungee getInstance() { 73 | return instance; 74 | } 75 | 76 | @Override 77 | public @NotNull Logger getLogger() { 78 | return super.getLogger(); 79 | } 80 | 81 | public @NotNull PluginConfiguration getConfiguration() { 82 | return this.core.getConfig(); 83 | } 84 | 85 | @Override 86 | public @NotNull File getPluginFolder() { 87 | return getDataFolder(); 88 | } 89 | 90 | @Override 91 | public @NotNull CommandManager getCommandManager() { 92 | return this.commandManager; 93 | } 94 | 95 | @SuppressWarnings("deprecation") 96 | public void outputInfo() { 97 | Optional.ofNullable(JarResourceUtils.readResource(this.getResourceAsStream("PLUGIN_INFO"))) 98 | .map(v -> ColorParser.parse(Arrays.asList(v))) 99 | .ifPresent(list -> list.forEach(s -> ProxyServer.getInstance().getConsole().sendMessage(s))); 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /platforms/bungee/src/main/resources/bungee.yml: -------------------------------------------------------------------------------- 1 | main: cc.carm.plugin.minesql.MineSQLBungee 2 | name: MineSQL 3 | version: ${project.version} 4 | 5 | website: ${project.url} 6 | description: ${project.description} 7 | 8 | author: "CarmJos" -------------------------------------------------------------------------------- /platforms/velocity/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | minesql-parent 7 | cc.carm.plugin 8 | 1.4.3 9 | ../../pom.xml 10 | 11 | 4.0.0 12 | 13 | 14 | ${project.jdk.version} 15 | ${project.jdk.version} 16 | UTF-8 17 | UTF-8 18 | true 19 | true 20 | 21 | 22 | minesql-platform-velocity 23 | jar 24 | 25 | MineSQL-Velocity 26 | 轻松(用)SQL的独立运行库Velocity版本插件。 27 | https://github.com/CarmJos/MineSQL 28 | 29 | 30 | 31 | CarmJos 32 | Carm Jos 33 | carm@carm.cc 34 | https://www.carm.cc 35 | 36 | Main Developer 37 | Designer 38 | 39 | 40 | 41 | 42 | 43 | 44 | GNU General Public License v3.0 45 | https://opensource.org/licenses/GPL-3.0 46 | 47 | 48 | 49 | 50 | GitHub Issues 51 | https://github.com/CarmJos/MineSQL/issues 52 | 53 | 54 | 55 | GitHub Actions 56 | https://github.com/CarmJos/MineSQL/actions/workflows/maven.yml 57 | 58 | 59 | 60 | 61 | velocity 62 | Velocity 63 | https://nexus.velocitypowered.com/repository/maven-public/ 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | com.velocitypowered 72 | velocity-api 73 | 3.1.1 74 | provided 75 | 76 | 77 | 78 | 79 | ${project.parent.groupId} 80 | minesql-core 81 | ${project.parent.version} 82 | compile 83 | 84 | 85 | 86 | org.bstats 87 | bstats-velocity 88 | ${deps.bstats.version} 89 | compile 90 | 91 | 92 | 93 | co.aikar 94 | acf-velocity 95 | ${deps.acf.version} 96 | compile 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | org.apache.maven.plugins 106 | maven-compiler-plugin 107 | 108 | 109 | org.apache.maven.plugins 110 | maven-jar-plugin 111 | 112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /platforms/velocity/src/main/java/cc/carm/plugin/minesql/MineSQLVelocity.java: -------------------------------------------------------------------------------- 1 | package cc.carm.plugin.minesql; 2 | 3 | import cc.carm.plugin.minesql.conf.PluginConfiguration; 4 | import co.aikar.commands.CommandManager; 5 | import co.aikar.commands.VelocityCommandManager; 6 | import com.google.inject.Inject; 7 | import com.velocitypowered.api.event.PostOrder; 8 | import com.velocitypowered.api.event.Subscribe; 9 | import com.velocitypowered.api.event.proxy.ProxyInitializeEvent; 10 | import com.velocitypowered.api.event.proxy.ProxyShutdownEvent; 11 | import com.velocitypowered.api.plugin.Plugin; 12 | import com.velocitypowered.api.plugin.PluginContainer; 13 | import com.velocitypowered.api.plugin.PluginDescription; 14 | import com.velocitypowered.api.plugin.annotation.DataDirectory; 15 | import com.velocitypowered.api.proxy.ProxyServer; 16 | import org.bstats.charts.SimplePie; 17 | import org.bstats.velocity.Metrics; 18 | import org.jetbrains.annotations.NotNull; 19 | 20 | import java.io.File; 21 | import java.nio.file.Path; 22 | import java.util.logging.Logger; 23 | 24 | 25 | @Plugin(id = "minesql", name = "MineSQL (EasySQL-Plugin)", 26 | version = References.VERSION, 27 | description = "EasySQL Plugin For Velocity", 28 | url = "https://github.com/CarmJos/MineSQL", 29 | authors = {"CarmJos", "GhostChu"} 30 | ) 31 | public class MineSQLVelocity implements MineSQLPlatform { 32 | 33 | private final ProxyServer server; 34 | private final Logger logger; 35 | private final File dataFolder; 36 | 37 | private final Metrics.Factory metricsFactory; 38 | 39 | protected MineSQLCore core; 40 | protected VelocityCommandManager commandManager; 41 | 42 | @Inject 43 | public MineSQLVelocity(ProxyServer server, Logger logger, 44 | @DataDirectory Path dataDirectory, 45 | Metrics.Factory metricsFactory) { 46 | this.server = server; 47 | this.logger = logger; 48 | this.dataFolder = dataDirectory.toFile(); 49 | this.metricsFactory = metricsFactory; 50 | 51 | getLogger().info("加载基础核心..."); 52 | this.core = new MineSQLCore(this); 53 | } 54 | 55 | @Subscribe(order = PostOrder.FIRST) 56 | public void onInitialize(ProxyInitializeEvent event) { 57 | 58 | 59 | getLogger().info("初始化指令管理器..."); 60 | this.commandManager = new VelocityCommandManager(server, this); 61 | 62 | getLogger().info("注册相关指令..."); 63 | this.core.initializeCommands(getCommandManager()); 64 | 65 | if (getConfiguration().METRICS.getNotNull()) { 66 | getLogger().info("启用统计数据..."); 67 | Metrics metrics = this.metricsFactory.make(this, 14078); 68 | metrics.addCustomChart(new SimplePie("update_check", 69 | () -> getConfiguration().UPDATE_CHECKER.getNotNull() ? "ENABLED" : "DISABLED") 70 | ); 71 | metrics.addCustomChart(new SimplePie("properties_configuration", 72 | () -> getConfiguration().PROPERTIES.ENABLE.getNotNull() ? "ENABLED" : "DISABLED") 73 | ); 74 | } 75 | 76 | if (getConfiguration().UPDATE_CHECKER.getNotNull()) { 77 | getLogger().info("开始检查更新,可能需要一小段时间..."); 78 | getLogger().info(" 如不希望检查更新,可在配置文件中关闭。"); 79 | server.getScheduler().buildTask(this, () -> this.core.checkUpdate(getVersion())).schedule(); 80 | } else { 81 | getLogger().info("已禁用检查更新,跳过。"); 82 | } 83 | 84 | } 85 | 86 | @Subscribe(order = PostOrder.LAST) 87 | public void onShutdown(ProxyShutdownEvent event) { 88 | getLogger().info("终止全部数据库连接..."); 89 | this.core.shutdownAll(); 90 | } 91 | 92 | public ProxyServer getServer() { 93 | return server; 94 | } 95 | 96 | public @NotNull Logger getLogger() { 97 | return logger; 98 | } 99 | 100 | public String getVersion() { 101 | return this.server.getPluginManager().getPlugin("minesql") 102 | .map(PluginContainer::getDescription) 103 | .flatMap(PluginDescription::getVersion).orElse("1.0.0"); 104 | } 105 | 106 | @Override 107 | public @NotNull File getPluginFolder() { 108 | return this.dataFolder; 109 | } 110 | 111 | @Override 112 | public @NotNull CommandManager getCommandManager() { 113 | return commandManager; 114 | } 115 | 116 | public @NotNull PluginConfiguration getConfiguration() { 117 | return this.core.getConfig(); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /plugin/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | minesql-parent 7 | cc.carm.plugin 8 | 1.4.3 9 | 10 | 4.0.0 11 | 12 | ${project.jdk.version} 13 | ${project.jdk.version} 14 | UTF-8 15 | UTF-8 16 | true 17 | true 18 | 19 | minesql-plugin 20 | 21 | 22 | 23 | 24 | ${project.parent.groupId} 25 | minesql-platform-bukkit 26 | ${project.parent.version} 27 | compile 28 | 29 | 30 | 31 | ${project.parent.groupId} 32 | minesql-platform-bungee 33 | ${project.parent.version} 34 | compile 35 | 36 | 37 | 38 | ${project.parent.groupId} 39 | minesql-platform-velocity 40 | ${project.parent.version} 41 | compile 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | org.apache.maven.plugins 50 | maven-compiler-plugin 51 | 52 | 53 | org.apache.maven.plugins 54 | maven-jar-plugin 55 | 56 | 57 | org.apache.maven.plugins 58 | maven-shade-plugin 59 | 3.6.0 60 | 61 | 62 | package 63 | 64 | shade 65 | 66 | 67 | 68 | 69 | 70 | ${project.parent.name}-${project.parent.version} 71 | ${project.parent.basedir}/.asset/ 72 | false 73 | 74 | 75 | org.bstats 76 | ${code.package}.lib.bstats 77 | 78 | 79 | org.json 80 | ${code.package}.lib.json 81 | 82 | 83 | cc.carm.lib.easyplugin 84 | ${code.package}.lib.easyplugin 85 | 86 | 87 | cc.carm.lib.githubreleases4j 88 | ${code.package}.lib.githubreleases4j 89 | 90 | 91 | cc.carm.lib.configuration 92 | ${code.package}.lib.configuration 93 | 94 | 95 | org.bspfsystems.yamlconfiguration 96 | ${code.package}.lib.configuration.yaml 97 | 98 | 99 | org.yaml.snakeyaml 100 | ${code.package}.lib.yaml 101 | 102 | 103 | 104 | co.aikar.commands 105 | ${code.package}.lib.acf 106 | 107 | 108 | co.aikar.locales 109 | ${code.package}.lib.locales 110 | 111 | 112 | 113 | net.byteflux.libby 114 | ${code.package}.lib.libby 115 | 116 | 117 | 118 | 119 | 120 | co.aikar:* 121 | 122 | META-INF/MANIFEST.MF 123 | META-INF/*.txt 124 | acf-core*.properties 125 | acf-minecraft*.properties 126 | 127 | 128 | 129 | *:* 130 | 131 | META-INF/MANIFEST.MF 132 | META-INF/*.txt 133 | LICENSE 134 | README 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | 8 9 | ${project.jdk.version} 10 | ${project.jdk.version} 11 | UTF-8 12 | UTF-8 13 | 14 | 0.4.7 15 | 4.1.4 16 | 1.5.12 17 | 4.1.7 18 | 19 | 1.1.5 20 | 0.5.1-SNAPSHOT 21 | 3.0.0 22 | 23 | 8.2.0 24 | 3.1.0 25 | 2.2.220 26 | 27 | cc.carm.plugin.minesql 28 | 29 | 30 | cc.carm.plugin 31 | minesql-parent 32 | pom 33 | 1.4.3 34 | 35 | api 36 | core 37 | 38 | platforms/bukkit 39 | platforms/bungee 40 | platforms/velocity 41 | 42 | plugin 43 | 44 | 45 | MineSQL 46 | 轻松(用)SQL的独立运行库插件,支持多种服务端,适用于MineCraft全版本。 47 | https://github.com/CarmJos/MineSQL 48 | 49 | 50 | 51 | CarmJos 52 | Carm Jos 53 | carm@carm.cc 54 | https://www.carm.cc 55 | 56 | Main Developer 57 | Designer 58 | 59 | 60 | 61 | Ghost-Chu 62 | 鬼畜 63 | https://github.com/Ghost-Chu/ 64 | 65 | 66 | huanmeng_qwq 67 | 幻梦 68 | https://github.com/huanmeng-qwq/ 69 | 70 | 71 | 72 | 73 | scm:git:git@github.com:CarmJos/MineSQL 74 | scm:git:git@github.com:CarmJos/MineSQL.git 75 | https://github.com/CarmJos/MineSQL 76 | HEAD 77 | 78 | 79 | 80 | 81 | GNU General Public License v3.0 82 | https://opensource.org/licenses/GPL-3.0 83 | 84 | 85 | 86 | 87 | GitHub Issues 88 | https://github.com/CarmJos/MineSQL/issues 89 | 90 | 91 | 92 | GitHub Actions 93 | https://github.com/CarmJos/MineSQL/actions/workflows/maven.yml 94 | 95 | 96 | 97 | https://github.com/CarmJos/MineSQL/releases 98 | 99 | 100 | 101 | 102 | 103 | aikar 104 | https://repo.aikar.co/content/groups/aikar/ 105 | 106 | 107 | 108 | central 109 | https://repo1.maven.org/maven2/ 110 | 111 | 112 | 113 | carm-repo 114 | Carm's Repo 115 | https://repo.carm.cc/repository/maven-public/ 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | org.jetbrains 124 | annotations 125 | 24.0.1 126 | provided 127 | 128 | 129 | 130 | junit 131 | junit 132 | 4.13.2 133 | test 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | com.github.chris2018998 144 | beecp 145 | ${deps.beecp.version} 146 | 147 | 148 | 149 | cc.carm.lib 150 | easysql-impl 151 | ${deps.easysql.version} 152 | 153 | 154 | 155 | 156 | com.google.guava 157 | guava 158 | 32.0.0-jre 159 | 160 | 161 | 162 | 163 | org.mariadb.jdbc 164 | mariadb-java-client 165 | ${deps.mariadb-driver.version} 166 | 167 | 168 | 169 | 170 | com.mysql 171 | mysql-connector-j 172 | ${deps.mysql-driver.version} 173 | 174 | 175 | 176 | 177 | com.h2database 178 | h2 179 | ${deps.h2-driver.version} 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | org.apache.maven.plugins 189 | maven-clean-plugin 190 | 2.6.1 191 | 192 | 193 | 194 | ${project.basedir}/.asset/ 195 | true 196 | 197 | **/* 198 | 199 | 200 | 201 | 202 | 203 | 204 | org.apache.maven.plugins 205 | maven-surefire-plugin 206 | 2.22.2 207 | 208 | false 209 | 210 | 211 | 212 | org.apache.maven.plugins 213 | maven-gpg-plugin 214 | 3.2.7 215 | 216 | 217 | sign-artifacts 218 | verify 219 | 220 | sign 221 | 222 | 223 | 224 | 225 | 226 | --pinentry-mode 227 | loopback 228 | 229 | 230 | 231 | 232 | org.apache.maven.plugins 233 | maven-release-plugin 234 | 2.5.3 235 | 236 | true 237 | false 238 | release 239 | deploy 240 | 241 | 242 | 243 | 244 | 245 | 246 | org.apache.maven.plugins 247 | maven-compiler-plugin 248 | 3.14.0 249 | 250 | ${project.jdk.version} 251 | ${project.jdk.version} 252 | UTF-8 253 | -parameters 254 | 255 | 256 | 257 | org.apache.maven.plugins 258 | maven-jar-plugin 259 | 3.4.2 260 | 261 | 262 | org.apache.maven.plugins 263 | maven-source-plugin 264 | 3.3.1 265 | 266 | 267 | package 268 | 269 | jar-no-fork 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | src/main/resources 279 | true 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | ossrh 288 | 289 | 290 | ossrh 291 | https://s01.oss.sonatype.org/content/repositories/snapshots 292 | 293 | 294 | 295 | ossrh 296 | https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/ 297 | 298 | 299 | 300 | 301 | 302 | github 303 | 304 | 305 | github 306 | GitHub Packages 307 | https://maven.pkg.github.com/CarmJos/MineSQL 308 | 309 | 310 | 311 | 312 | 313 | local 314 | 315 | 316 | localRepository 317 | file:${user.home}/local-deploy/ 318 | 319 | 320 | localRepository 321 | file:${user.home}/local-deploy/ 322 | 323 | 324 | 325 | 326 | 327 | 328 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:recommended" 5 | ] 6 | } 7 | --------------------------------------------------------------------------------