[
  {
    "path": ".gitattributes",
    "content": "﻿# Auto detect text files and perform LF normalization\n* text=auto\n\n*.java text diff=java encoding=utf-8\n*.xml text\n*.yml text encoding=utf-8\n*.md text\n*.png binary diff=exif\n\n# Ignore for export\n.gitattributes export-ignore\n.gitignore export-ignore\n.travis export-ignore\n/.github/ export-ignore\n/.idea/ export-ignore"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug.md",
    "content": "---\nlabels: bug\nname: Report a bug\nabout: Report a bug with Minepacks\n---\n\n<!-- bug reporting guide\nDon't put anything inside this block, as it won't be included in the issue.\nPlease make sure to follow the following guidelines:\n1.  When linking files, do not copy paste them into the post! Copy and paste any logs into https://gist.github.com/ , then paste a link to them in the relevant area.\n2.  If you are reporting a performance issue, please include a link to a timings and/or profiler report.\n3.  Check whether it has already been reported. You can search the issue tracker to see if the bug has already been reported at https://github.com/GeorgH93/Minepacks/issues?q=is%3Aissue+is%3Aopen+label%3Abug\n4.  Make sure not to write between the arrows, as anything there will be hidden.  -->\n\n### Information\n**Environment information**\n*Plugin + server version info*:\n<!-- Please provide the full output of the \"/backpack version\" command. Please do not just put \"latest\" as a version. -->\n```\n\n<!-- Replace this with the output of \"/backpack version\". You can run the command in your console or as op ingame. -->\n\n```\n\n*Online mode*: <!-- Replace this with \"yes\" if your server is running in online mode, with \"no\" if your server is running in offline mode (if you are using BungeeCord please use your BungeeCord online mode!) -->\n\n*BungeeCord*: <!-- Replace this with \"yes\" you use BungeeCord, with \"no\" if not -->\n\n**Server/crash log**\n<!-- If you see an error message in the console/log please provide it. Please provide at least 10 lines befor and after the error! If you like to share the full log file please use https://gist.github.com/\nThe log can contain user related information like ip, name or uuid, so please replace them if they are not necessary. -->\n```\n\n<!-- Replace this with your crash log / link to your log file -->\n\n```\n\n**Plugin config (optional)**\n<!-- Some problems are depending on the used configuration. To enable us to help you faster you can provide us with some details about your config or the full config.yml file (please use https://gist.github.com/ to upload your config.yml, make sure to remove confidential informations like database passwords!) -->\n```\n\n<!-- Replace this with details about your config -->\n\n```\n\n### Details\n**Description**  \n<!-- Replace this with a brief summary of the bug. -->\n\n**Steps to reproduce**  \n<!-- Replace this with what exactly you did to cause the bug. -->\n\n**Expected behavior**  \n<!-- Replace this with what you expect to happen. -->\n\n**Other information** (e.g. detailed explanation, related issues, suggestions how to fix, links for us to have context, screenshots, etc.)\n<!-- Replace this with any additional information, if necessary. -->\n\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature.md",
    "content": "---\nlabels: enhancement\nname: Request a feature\nabout: Request a feature you want to see in Minepacks.\n---\n\n<!-- feature request guide\nDon't put anything inside this block, as it won't be included in the issue.\nPlease make sure to follow the following guidelines:\n1.  When linking files, do not copy paste them into the post! Copy and paste any logs into https://gist.github.com/ , then paste a link to them in the relevant area.\n2.  Keep it simple. Make sure it's easy to understand what you're requesting. Keep it to one request per GitHub issue.\n3.  Check whether it has already been asked or added. You can search the issue tracker to see if the your feature has already been requested at https://github.com/GeorgH93/Minepacks/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3Aenhancement\n4.  Make sure not to write between the arrows, as anything there will be hidden.  -->\n\n### Feature request\n\n**Feature description**\n<!-- What feature are you suggesting? -->\n\n**How the feature is useful**\n<!-- How is the feature useful to players, server owners and/or developers? -->"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/help.md",
    "content": "---\nlabels: question\nname: Request help\nabout: Request help with Minepacks.\n---\n\n<!-- help request guide\nDon't put anything inside this block, as it won't be included in the issue.\nPlease make sure to follow the following guidelines:\n1.  When linking files, do not copy paste them into the post! Copy and paste any logs into https://gist.github.com/ , then paste a link to them in the relevant area.\n2.  Please make sure it's easy to understand what you need help with.\n3.  Make sure not to write between the arrows, as anything there will be hidden.  -->\n\n### Help request\n\n**Problem**\n<!-- What problem did you encounter? -->\n\n**What I have tried**\n<!-- What have you tried so far? -->"
  },
  {
    "path": ".github/workflows/codeql.yml",
    "content": "name: \"CodeQL\"\n\non:\n  push:\n    branches: [ \"master\" ]\n  pull_request:\n    branches: [ \"master\" ]\n  schedule:\n    - cron: \"56 15 * * 3\"\n\njobs:\n  analyze:\n    name: Analyze\n    runs-on: ubuntu-latest\n    permissions:\n      actions: read\n      contents: read\n      security-events: write\n\n    strategy:\n      fail-fast: false\n      matrix:\n        language: [ java ]\n\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v5\n\n      - name: Initialize CodeQL\n        uses: github/codeql-action/init@v4\n        with:\n          languages: ${{ matrix.language }}\n          queries: +security-and-quality\n\n      - name: Autobuild\n        uses: github/codeql-action/autobuild@v4\n\n      - name: Perform CodeQL Analysis\n        uses: github/codeql-action/analyze@v4\n        with:\n          category: \"/language:${{ matrix.language }}\"\n"
  },
  {
    "path": ".github/workflows/maven.yml",
    "content": "# This workflow will build a Java project with Maven\n# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven\n\nname: Build\n\non: [push, pull_request]\n\njobs:\n  buildAndTest:\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        java-version: [ 8, 11, 17, 21, 25 ]\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v5\n      - name: Set up JDK ${{ matrix.java-version }}\n        uses: actions/setup-java@v5\n        with:\n          distribution: temurin\n          java-version: ${{ matrix.java-version }}\n      - name: Build and test with maven\n        run: mvn -B -s .github/workflows/settings.xml clean package --file pom.xml\n"
  },
  {
    "path": ".github/workflows/release.yml",
    "content": "# This workflow will run every time a new release is created.\n# It will first build the plugin using Maven, then publish it to GitHub packages and finally attach the artifacts to the release\n\nname: Build and release\n\non:\n  release:\n    types: [created]\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n\n    steps:\n    - uses: actions/checkout@v5\n    - name: Set up JDK 21\n      uses: actions/setup-java@v5\n      with:\n        java-version: 21\n        distribution: temurin\n        server-id: github\n        settings-path: ${{ github.workspace }} # location for the settings.xml file\n\n    - name: Setup workspace\n      run: mkdir artifacts\n\n    - name: Build with Maven\n      run: |\n        mvn -B -s .github/workflows/settings.xml install --file pom.xml\n        cp Minepacks/target/M*.jar artifacts/\n\n    - name: Build with Maven (Standalone)\n      run: |\n        mvn -B -s .github/workflows/settings.xml clean install --file pom.xml -P Standalone,ExcludeBadRabbit\n        mv Minepacks/target/M*-Standalone.jar artifacts/\n\n    - name: Build with Maven (Release)\n      run: |\n        mvn -B -s .github/workflows/settings.xml clean package --file pom.xml -P Release\n        mv Minepacks/target/M*-Release.jar artifacts/\n\n    - name: Upload the artifacts\n      uses: skx/github-action-publish-binaries@master\n      env:\n        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n      with:\n        args: 'artifacts/M*'\n"
  },
  {
    "path": ".github/workflows/settings.xml",
    "content": "<settings xmlns=\"http://maven.apache.org/SETTINGS/1.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd\">\n  <mirrors>\n    <mirror>\n      <id>pcgf-public</id>\n      <name>PCGF Public</name>\n      <url>https://repo.pcgamingfreaks.at/repository/maven-public/</url>\n      <mirrorOf>central,spigot-nexus,spigot-repo,placeholderapi,sonatype-nexus-snapshots,pcgf-repo,herocraftonline-repo,sk89q-repo,CodeMC,mvdw-software</mirrorOf>\n    </mirror>\n  </mirrors>\n  <servers>\n    <server>\n      <id>github</id>\n      <username>${env.GITHUB_ACTOR}</username>\n      <password>${env.GITHUB_TOKEN}</password>\n    </server>\n  </servers>\n</settings>"
  },
  {
    "path": ".github/workflows/sonarcloud.yml",
    "content": "name: SonarCloud\non:\n  push:\n    branches:\n      - master\n      - dev\n#  pull_request:\n#    types: [opened, synchronize, reopened]\njobs:\n  build:\n    name: Build\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v5\n        with:\n          fetch-depth: 0  # Shallow clones should be disabled for a better relevancy of analysis\n      - name: Set up JDK 21\n        uses: actions/setup-java@v5\n        with:\n          java-version: 21\n          distribution: temurin\n      - name: Cache SonarCloud packages\n        uses: actions/cache@v5\n        with:\n          path: ~/.sonar/cache\n          key: ${{ runner.os }}-sonar\n          restore-keys: ${{ runner.os }}-sonar\n      - name: Cache Maven packages\n        uses: actions/cache@v5\n        with:\n          path: ~/.m2\n          key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}\n          restore-keys: ${{ runner.os }}-m2\n      - name: Build and analyze\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}  # Needed to get PR information, if any\n          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}\n        run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=GeorgH93_Minepacks\n"
  },
  {
    "path": ".gitignore",
    "content": "# Windows image file caches\r\nThumbs.db\r\nehthumbs.db\r\n\r\n# Folder config file\r\nDesktop.ini\r\n\r\n# Recycle Bin used on file shares\r\n$RECYCLE.BIN/\r\n\r\n# Windows Installer files\r\n*.cab\r\n*.msi\r\n*.msm\r\n*.msp\r\n\r\n*.bat\r\n\r\n# =========================\r\n# Operating System Files\r\n# =========================\r\n\r\n# OSX\r\n# =========================\r\n\r\n.DS_Store\r\n.AppleDouble\r\n.LSOverride\r\n\r\n# Icon must end with two \\r\r\nIcon\r\n\r\n\r\n# Thumbnails\r\n._*\r\n\r\n# Files that might appear on external disk\r\n.Spotlight-V100\r\n.Trashes\r\n\r\n# Directories potentially created on remote AFP share\r\n.AppleDB\r\n.AppleDesktop\r\nNetwork Trash Folder\r\nTemporary Items\r\n.apdisk\r\n\r\n# Temp files\r\n*.tmp\r\n\r\n\r\n*.sh\r\n\r\n# =========================\r\n# IDE Project Files\r\n# =========================\r\n*.classpath\r\n*.project\r\n*.prefs\r\ntarget/\r\n/bin/\r\n*.iml\r\n/.idea/\r\n\r\n.flattened-pom.xml"
  },
  {
    "path": "Components/Minepacks-BadRabbit-Bukkit/pom.xml",
    "content": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\t<artifactId>Minepacks-BadRabbit-Bukkit</artifactId>\n\t<parent>\n\t\t<artifactId>Minepacks-Parent</artifactId>\n\t\t<groupId>at.pcgamingfreaks</groupId>\n\t\t<version>${revision}</version>\n\t\t<relativePath>../../pom.xml</relativePath>\n\t</parent>\n\t<version>${revision}</version>\n\t<packaging>jar</packaging>\n\n\t<name>Minepacks-BadRabbit-Bukkit</name>\n\t<description>BadRabbit loader for Minepacks.</description>\n\t<url>https://www.spigotmc.org/resources/19286/</url>\n\n\t<dependencies>\n\t\t<dependency>\n\t\t\t<groupId>at.pcgamingfreaks</groupId>\n\t\t\t<artifactId>Minepacks-MagicValues</artifactId>\n\t\t\t<version>${revision}</version>\n\t\t\t<scope>provided</scope>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>at.pcgamingfreaks.pcgf_pluginlib</groupId>\n\t\t\t<artifactId>pcgf_pluginlib-common</artifactId>\n\t\t\t<version>${pcgfPluginLibVersion}</version>\n\t\t\t<scope>provided</scope>\n\t\t</dependency>\n\t\t<!-- BadRabbit -->\n\t\t<dependency>\n\t\t\t<groupId>at.pcgamingfreaks</groupId>\n\t\t\t<artifactId>BadRabbit-Bukkit</artifactId>\n\t\t\t<version>1.11</version>\n\t\t</dependency>\n\t\t<!-- Bukkit -->\n\t\t<dependency>\n\t\t\t<groupId>org.bukkit</groupId>\n\t\t\t<artifactId>bukkit</artifactId>\n\t\t\t<version>${bukkitVersion}</version>\n\t\t\t<scope>provided</scope>\n\t\t</dependency>\n\t</dependencies>\n</project>\n"
  },
  {
    "path": "Components/Minepacks-BadRabbit-Bukkit/src/at/pcgamingfreaks/Minepacks/Bukkit/MinepacksBadRabbit.java",
    "content": "/*\n *   Copyright (C) 2022 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit;\n\nimport at.pcgamingfreaks.BadRabbit.Bukkit.BadRabbit;\nimport at.pcgamingfreaks.Minepacks.MagicValues;\nimport at.pcgamingfreaks.Version;\n\nimport org.bukkit.Bukkit;\nimport org.bukkit.plugin.Plugin;\nimport org.bukkit.plugin.java.JavaPlugin;\nimport org.jetbrains.annotations.NotNull;\n\n/**\n * Uses BadRabbit to initiate the plugin in normal or standalone mode depending on the users' environment.\n */\n@SuppressWarnings(\"unused\")\npublic class MinepacksBadRabbit extends BadRabbit\n{\n\t@Override\n\tprotected @NotNull JavaPlugin createInstance() throws Exception\n\t{\n\t\tPlugin pcgfPluginLib = Bukkit.getPluginManager().getPlugin(\"PCGF_PluginLib\");\n\t\tboolean standalone = true;\n\t\tif(pcgfPluginLib != null)\n\t\t{\n\t\t\tif(new Version(pcgfPluginLib.getDescription().getVersion()).olderThan(new Version(MagicValues.MIN_PCGF_PLUGIN_LIB_VERSION)))\n\t\t\t{\n\t\t\t\tgetLogger().info(\"PCGF-PluginLib to old! Switching to standalone mode!\");\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tgetLogger().info(\"PCGF-PluginLib installed. Switching to normal mode!\");\n\t\t\t\tstandalone = false;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tgetLogger().info(\"PCGF-PluginLib not installed. Switching to standalone mode!\");\n\t\t}\n\t\tif(standalone)\n\t\t{\n\t\t\tClass<?> standaloneClass = Class.forName(\"at.pcgamingfreaks.MinepacksStandalone.Bukkit.Minepacks\");\n\t\t\treturn (JavaPlugin) standaloneClass.newInstance();\n\t\t}\n\t\telse\n\t\t{\n\t\t\tClass<?> normalClass = Class.forName(\"at.pcgamingfreaks.Minepacks.Bukkit.Minepacks\");\n\t\t\treturn (JavaPlugin) normalClass.newInstance();\n\t\t}\n\t}\n}"
  },
  {
    "path": "Components/Minepacks-Bootstrap-Paper/pom.xml",
    "content": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\t\t xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\t<artifactId>Minepacks-Bootstrap-Paper</artifactId>\n\t<parent>\n\t\t<artifactId>Minepacks-Parent</artifactId>\n\t\t<groupId>at.pcgamingfreaks</groupId>\n\t\t<version>${revision}</version>\n\t\t<relativePath>../../pom.xml</relativePath>\n\t</parent>\n\t<version>${revision}</version>\n\t<packaging>jar</packaging>\n\n\t<name>Minepacks-Bootstrap-Paper</name>\n\t<description>Paper API extension for Minepacks.</description>\n\n\t<repositories>\n\t\t<repository>\n\t\t\t<id>papermc</id>\n\t\t\t<url>https://repo.papermc.io/repository/maven-public/</url>\n\t\t</repository>\n\t</repositories>\n\n\t<dependencies>\n\t\t<dependency>\n\t\t\t<groupId>at.pcgamingfreaks.pcgf_pluginlib</groupId>\n\t\t\t<artifactId>pcgf_pluginlib-version</artifactId>\n\t\t\t<version>${pcgfPluginLibVersion}</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>at.pcgamingfreaks.pcgf_pluginlib</groupId>\n\t\t\t<artifactId>pcgf_pluginlib-version_detection</artifactId>\n\t\t\t<version>${pcgfPluginLibVersion}</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>io.papermc.paper</groupId>\n\t\t\t<artifactId>paper-api</artifactId>\n\t\t\t<version>1.19.4-R0.1-SNAPSHOT</version>\n\t\t\t<scope>provided</scope>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>at.pcgamingfreaks</groupId>\n\t\t\t<artifactId>Minepacks-MagicValues</artifactId>\n\t\t\t<version>${version}</version>\n\t\t\t<scope>provided</scope>\n\t\t</dependency>\n\t</dependencies>\n\n\t<build>\n\t\t<defaultGoal>clean install</defaultGoal>\n\t\t<sourceDirectory>src</sourceDirectory>\n\t\t<resources>\n\t\t\t<resource>\n\t\t\t\t<directory>resources</directory>\n\t\t\t\t<filtering>true</filtering>\n\t\t\t</resource>\n\t\t</resources>\n\t\t<plugins>\n\t\t\t<plugin>\n\t\t\t\t<groupId>org.apache.maven.plugins</groupId>\n\t\t\t\t<artifactId>maven-compiler-plugin</artifactId>\n\t\t\t\t<version>3.8.1</version>\n\t\t\t\t<configuration>\n\t\t\t\t\t<release>17</release>\n\t\t\t\t</configuration>\n\t\t\t</plugin>\n\t\t\t<plugin>\n\t\t\t\t<groupId>org.apache.maven.plugins</groupId>\n\t\t\t\t<artifactId>maven-shade-plugin</artifactId>\n\t\t\t\t<version>${mavenShade.version}</version>\n\t\t\t\t<executions>\n\t\t\t\t\t<execution>\n\t\t\t\t\t\t<phase>package</phase>\n\t\t\t\t\t\t<goals>\n\t\t\t\t\t\t\t<goal>shade</goal>\n\t\t\t\t\t\t</goals>\n\t\t\t\t\t\t<configuration>\n\t\t\t\t\t\t\t<createDependencyReducedPom>false</createDependencyReducedPom>\n\t\t\t\t\t\t\t<minimizeJar>false</minimizeJar>\n\t\t\t\t\t\t\t<artifactSet>\n\t\t\t\t\t\t\t\t<includes>\n\t\t\t\t\t\t\t\t\t<include>at.pcgamingfreaks.pcgf_pluginlib:pcgf_pluginlib-version_detection</include>\n\t\t\t\t\t\t\t\t</includes>\n\t\t\t\t\t\t\t</artifactSet>\n\t\t\t\t\t\t</configuration>\n\t\t\t\t\t</execution>\n\t\t\t\t</executions>\n\t\t\t</plugin>\n\t\t</plugins>\n\t</build>\n</project>\n"
  },
  {
    "path": "Components/Minepacks-Bootstrap-Paper/resources/paper-plugin.yml",
    "content": "name: \"Minepacks\"\nauthor: \"${author}\"\nversion: \"${pluginVersion}\"\napi-version: \"1.19\"\nfolia-supported: true\nmain: \"at.pcgamingfreaks.MinepacksStandalone.Bukkit.Minepacks\"\nbootstrapper: \"at.pcgamingfreaks.Minepacks.Paper.MinepacksBootstrap\"\n\ndependencies:\n  - name: PCGF_PluginLib\n    required: false\n    bootstrap: true\n  - name: MVdWPlaceholderAPI\n    required: false\n  - name: PlaceholderAPI\n    required: false\n\nload-after:\n  - name: PCGF_PluginLib\n    bootstrap: true\n  - name: MVdWPlaceholderAPI\n  - name: PlaceholderAPI\n"
  },
  {
    "path": "Components/Minepacks-Bootstrap-Paper/src/at/pcgamingfreaks/Minepacks/Paper/MinepacksBootstrap.java",
    "content": "/*\n *   Copyright (C) 2023 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Paper;\n\nimport at.pcgamingfreaks.Minepacks.MagicValues;\nimport at.pcgamingfreaks.PCGF_PluginLibVersionDetection;\nimport at.pcgamingfreaks.Version;\n\nimport org.bukkit.plugin.java.JavaPlugin;\nimport org.jetbrains.annotations.NotNull;\n\nimport io.papermc.paper.plugin.bootstrap.BootstrapContext;\nimport io.papermc.paper.plugin.bootstrap.PluginBootstrap;\nimport io.papermc.paper.plugin.bootstrap.PluginProviderContext;\n\nimport java.lang.reflect.Field;\n\n@SuppressWarnings({ \"UnstableApiUsage\", \"unused\" })\npublic class MinepacksBootstrap implements PluginBootstrap\n{\n\tprivate static final String MAIN_CLASS_NORMAL = \"at.pcgamingfreaks.Minepacks.Bukkit.Minepacks\";\n\tprivate static final String MAIN_CLASS_STANDALONE = \"at.pcgamingfreaks.MinepacksStandalone.Bukkit.Minepacks\";\n\n\tpublic void bootstrap(@NotNull PluginProviderContext context)\n\t{\n\t}\n\n\t@Override\n\tpublic void bootstrap(@NotNull BootstrapContext bootstrapContext)\n\t{\n\t}\n\n\t@Override\n\tpublic @NotNull JavaPlugin createPlugin(@NotNull PluginProviderContext context)\n\t{\n\t\ttry\n\t\t{\n\t\t\tif(checkPcgfPluginLib(context) && patchPluginMeta(context))\n\t\t\t{\n\t\t\t\tClass<?> normalClass = Class.forName(MAIN_CLASS_NORMAL);\n\t\t\t\treturn (JavaPlugin) normalClass.newInstance();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tClass<?> standaloneClass = Class.forName(MAIN_CLASS_STANDALONE);\n\t\t\t\treturn (JavaPlugin) standaloneClass.newInstance();\n\t\t\t}\n\t\t}\n\t\tcatch(Exception e)\n\t\t{\n\t\t\tthrow new RuntimeException(\"Failed to create Minepacks plugin instance!\", e);\n\t\t}\n\t}\n\n\tprivate boolean patchPluginMeta(final @NotNull PluginProviderContext context)\n\t{\n\t\ttry\n\t\t{\n\t\t\tClass<?> pluginMetaClass = context.getConfiguration().getClass();\n\t\t\tField mainField = pluginMetaClass.getDeclaredField(\"main\");\n\t\t\tmainField.setAccessible(true);\n\t\t\tmainField.set(context.getConfiguration(), MAIN_CLASS_NORMAL);\n\t\t\treturn true;\n\t\t}\n\t\tcatch(Exception e)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tcontext.getLogger().error(\"Failed to patch main class in PluginMeta! Falling back to Standalone mode!\", e);\n\t\t\t}\n\t\t\tcatch(Throwable ignored)\n\t\t\t{\n\t\t\t\tSystem.out.println(\"[Minepacks] Failed to patch main class in PluginMeta! Falling back to Standalone mode!\");\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\tprivate boolean checkPcgfPluginLib(final @NotNull PluginProviderContext context)\n\t{\n\t\tString version = PCGF_PluginLibVersionDetection.getVersionBukkit();\n\t\tif (version != null)\n\t\t{\n\t\t\tif (new Version(version).olderThan(new Version(MagicValues.MIN_PCGF_PLUGIN_LIB_VERSION)))\n\t\t\t{\n\t\t\t\tlogInfo(\"PCGF-PluginLib to old! Switching to standalone mode!\", context);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tlogInfo(\"PCGF-PluginLib installed. Switching to normal mode!\", context);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tlogInfo(\"PCGF-PluginLib not installed. Switching to standalone mode!\", context);\n\t\t}\n\t\treturn false;\n\t}\n\n\t//TODO remove this stupid code once the paper API stabilizes to a point where once can expect at least the logger class ot not randomly change\n\tprivate void logInfo(final @NotNull String message, final @NotNull PluginProviderContext context)\n\t{\n\t\ttry\n\t\t{\n\t\t\tcontext.getLogger().info(message);\n\t\t}\n\t\tcatch(Throwable t)\n\t\t{\n\t\t\tSystem.out.println(\"[Minepacks] Failed to log message: \" + message);\n\t\t}\n\t}\n}"
  },
  {
    "path": "Components/Minepacks-MagicValues/pom.xml",
    "content": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\t<artifactId>Minepacks-MagicValues</artifactId>\n\t<parent>\n\t\t<artifactId>Minepacks-Parent</artifactId>\n\t\t<groupId>at.pcgamingfreaks</groupId>\n\t\t<version>${revision}</version>\n\t\t<relativePath>../../pom.xml</relativePath>\n\t</parent>\n\t<version>${revision}</version>\n\t<packaging>jar</packaging>\n\n\t<name>Minepacks-MagicValues</name>\n\t<description>Contains the magic values used by Minepacks.</description>\n\n\t<build>\n\t\t<defaultGoal>clean install</defaultGoal>\n\t\t<resources>\n\t\t\t<resource>\n\t\t\t\t<directory>resources</directory>\n\t\t\t\t<filtering>true</filtering>\n\t\t\t</resource>\n\t\t</resources>\n\t</build>\n</project>\n"
  },
  {
    "path": "Components/Minepacks-MagicValues/resources/Minepacks.properties",
    "content": "LanguageFileVersion=${languageFileVersion}\nConfigFileVersion=${configFileVersion}\nPCGFPluginLibVersion=${pcgfPluginLibVersion}\n"
  },
  {
    "path": "Components/Minepacks-MagicValues/src/at/pcgamingfreaks/Minepacks/MagicValues.java",
    "content": "/*\n *   Copyright (C) 2023 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks;\n\nimport org.jetbrains.annotations.NotNull;\n\nimport java.io.InputStream;\nimport java.util.Properties;\n\npublic class MagicValues\n{\n\tpublic static final int LANG_VERSION;\n\tpublic static final int CONFIG_VERSION;\n\tpublic static final String MIN_PCGF_PLUGIN_LIB_VERSION;\n\tpublic static final String MIN_MC_VERSION_FOR_UPDATES = \"1.8\";\n\n\tstatic\n\t{\n\t\tString pcgfPluginLibVersion = \"99999\", langVersion = \"0\", configVersion = \"0\";\n\n\t\ttry(InputStream propertiesStream = MagicValues.class.getClassLoader().getResourceAsStream(\"Minepacks.properties\"))\n\t\t{\n\t\t\tProperties properties = new Properties();\n\t\t\tproperties.load(propertiesStream);\n\n\t\t\tpcgfPluginLibVersion = properties.getProperty(\"PCGFPluginLibVersion\");\n\t\t\tlangVersion = properties.getProperty(\"LanguageFileVersion\");\n\t\t\tconfigVersion = properties.getProperty(\"ConfigFileVersion\");\n\t\t}\n\t\tcatch(Exception e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t}\n\t\tMIN_PCGF_PLUGIN_LIB_VERSION = pcgfPluginLibVersion;\n\t\t// Try to parse the version strings, fall back to a known min version\n\t\tLANG_VERSION = tryParse(langVersion, 20);\n\t\tCONFIG_VERSION = tryParse(configVersion, 33);\n\t}\n\n\tprivate static int tryParse(@NotNull String string, int fallbackValue)\n\t{\n\t\ttry\n\t\t{\n\t\t\treturn Integer.parseInt(string);\n\t\t}\n\t\tcatch (NumberFormatException ignored)\n\t\t{\n\t\t\tSystem.out.println(\"Failed to parse integer '\" + string + \"'! Falling back to: \" + fallbackValue);\n\t\t}\n\t\treturn fallbackValue;\n\t}\n\n\tprivate MagicValues() { /* You should not create an instance of this utility class! */ }\n}\n"
  },
  {
    "path": "LICENSE",
    "content": "GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU General Public License is a free, copyleft license for\nsoftware and other kinds of works.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nthe GNU General Public License is intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.  We, the Free Software Foundation, use the\nGNU General Public License for most of our software; it applies also to\nany other work released this way by its authors.  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  To protect your rights, we need to prevent others from denying you\nthese rights or asking you to surrender the rights.  Therefore, you have\ncertain responsibilities if you distribute copies of the software, or if\nyou modify it: responsibilities to respect the freedom of others.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must pass on to the recipients the same\nfreedoms that you received.  You must make sure that they, too, receive\nor can get the source code.  And you must show them these terms so they\nknow their rights.\n\n  Developers that use the GNU GPL protect your rights with two steps:\n(1) assert copyright on the software, and (2) offer you this License\ngiving you legal permission to copy, distribute and/or modify it.\n\n  For the developers' and authors' protection, the GPL clearly explains\nthat there is no warranty for this free software.  For both users' and\nauthors' sake, the GPL requires that modified versions be marked as\nchanged, so that their problems will not be attributed erroneously to\nauthors of previous versions.\n\n  Some devices are designed to deny users access to install or run\nmodified versions of the software inside them, although the manufacturer\ncan do so.  This is fundamentally incompatible with the aim of\nprotecting users' freedom to change the software.  The systematic\npattern of such abuse occurs in the area of products for individuals to\nuse, which is precisely where it is most unacceptable.  Therefore, we\nhave designed this version of the GPL to prohibit the practice for those\nproducts.  If such problems arise substantially in other domains, we\nstand ready to extend this provision to those domains in future versions\nof the GPL, as needed to protect the freedom of users.\n\n  Finally, every program is threatened constantly by software patents.\nStates should not allow patents to restrict development and use of\nsoftware on general-purpose computers, but in those that do, we wish to\navoid the special danger that patents applied to a free program could\nmake it effectively proprietary.  To prevent this, the GPL assures that\npatents cannot be used to render the program non-free.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Use with the GNU Affero General Public License.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU Affero General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the special requirements of the GNU Affero General Public License,\nsection 13, concerning interaction through a network will apply to the\ncombination as such.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    {one line to give the program's name and a brief idea of what it does.}\n    Copyright (C) {year}  {name of author}\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n  If the program does terminal interaction, make it output a short\nnotice like this when it starts in an interactive mode:\n\n    {project}  Copyright (C) {year}  {fullname}\n    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, your program's commands\nmight be different; for a GUI interface, you would use an \"about box\".\n\n  You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU GPL, see\n<http://www.gnu.org/licenses/>.\n\n  The GNU General Public License does not permit incorporating your program\ninto proprietary programs.  If your program is a subroutine library, you\nmay consider it more useful to permit linking proprietary applications with\nthe library.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.  But first, please read\n<http://www.gnu.org/philosophy/why-not-lgpl.html>.\n"
  },
  {
    "path": "Minepacks/pom.xml",
    "content": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\t\t xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\t<artifactId>Minepacks</artifactId>\n\t<parent>\n\t\t<artifactId>Minepacks-Parent</artifactId>\n\t\t<groupId>at.pcgamingfreaks</groupId>\n\t\t<version>${revision}</version>\n\t\t<relativePath>..</relativePath>\n\t</parent>\n\t<version>${revision}</version>\n\t<packaging>jar</packaging>\n\n\t<name>Minepacks</name>\n\t<description>Minepacks is a backpack plugin with different backpack sizes, multi language support and SQLite and MySQL storage support.</description>\n\t<url>https://www.spigotmc.org/resources/19286/</url>\n\n\t<properties>\n\t\t<dependencies>PCGF_PluginLib</dependencies>\n\t\t<soft-dependencies/>\n\t\t<mainClass>${project.groupId}.${project.artifactId}.Bukkit.${project.artifactId}</mainClass>\n\t\t<releaseType>Normal</releaseType>\n\t\t<updateChannel>Release</updateChannel>\n\t</properties>\n\n\t<pluginRepositories>\n\t\t<pluginRepository>\n\t\t\t<id>apache-snapshot</id>\n\t\t\t<url>https://repository.apache.org/content/repositories/snapshots/</url>\n\t\t</pluginRepository>\n\t</pluginRepositories>\n\n\t<dependencies>\n\t\t<!-- Minepacks API -->\n\t\t<dependency>\n\t\t\t<groupId>at.pcgamingfreaks</groupId>\n\t\t\t<artifactId>Minepacks-API</artifactId>\n\t\t\t<version>${revision}</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>at.pcgamingfreaks</groupId>\n\t\t\t<artifactId>Minepacks-MagicValues</artifactId>\n\t\t\t<version>${revision}</version>\n\t\t</dependency>\n\t\t<!-- PCGF Plugin Lib -->\n\t\t<dependency>\n\t\t\t<groupId>at.pcgamingfreaks</groupId>\n\t\t\t<artifactId>PluginLib</artifactId>\n\t\t\t<version>${pcgfPluginLibVersion}</version>\n\t\t</dependency>\n\t\t<!-- Tests -->\n\t\t<dependency>\n\t\t\t<groupId>org.junit.jupiter</groupId>\n\t\t\t<artifactId>junit-jupiter</artifactId>\n\t\t\t<version>5.8.2</version>\n\t\t\t<scope>test</scope>\n\t\t</dependency>\n\t</dependencies>\n\n\t<build>\n\t\t<defaultGoal>clean package test</defaultGoal>\n\t\t<testSourceDirectory>test/src</testSourceDirectory>\n\t\t<resources>\n\t\t\t<resource>\n\t\t\t\t<directory>resources</directory>\n\t\t\t\t<filtering>true</filtering>\n\t\t\t</resource>\n\t\t\t<resource>\n\t\t\t\t<directory>./</directory>\n\t\t\t\t<includes>\n\t\t\t\t\t<include>LICENSE</include>\n\t\t\t\t</includes>\n\t\t\t</resource>\n\t\t\t<resource>\n\t\t\t\t<directory>${project.build.directory}/generated-resources</directory>\n\t\t\t</resource>\n\t\t</resources>\n\t\t<plugins>\n\t\t\t<plugin>\n\t\t\t\t<artifactId>maven-surefire-plugin</artifactId>\n\t\t\t\t<version>3.0.0-M4</version>\n\t\t\t</plugin>\n\t\t\t<!-- Bundle the API into the JAR -->\n\t\t\t<plugin>\n\t\t\t\t<groupId>org.apache.maven.plugins</groupId>\n\t\t\t\t<artifactId>maven-shade-plugin</artifactId>\n\t\t\t\t<version>${mavenShade.version}</version>\n\t\t\t\t<executions>\n\t\t\t\t\t<execution>\n\t\t\t\t\t\t<phase>package</phase>\n\t\t\t\t\t\t<goals>\n\t\t\t\t\t\t\t<goal>shade</goal>\n\t\t\t\t\t\t</goals>\n\t\t\t\t\t\t<configuration>\n\t\t\t\t\t\t\t<createDependencyReducedPom>false</createDependencyReducedPom>\n\t\t\t\t\t\t\t<minimizeJar>false</minimizeJar>\n\t\t\t\t\t\t\t<artifactSet>\n\t\t\t\t\t\t\t\t<includes>\n\t\t\t\t\t\t\t\t\t<include>at.pcgamingfreaks:Minepacks-API</include>\n\t\t\t\t\t\t\t\t\t<include>at.pcgamingfreaks:Minepacks-MagicValues</include>\n\t\t\t\t\t\t\t\t</includes>\n\t\t\t\t\t\t\t</artifactSet>\n\t\t\t\t\t\t</configuration>\n\t\t\t\t\t</execution>\n\t\t\t\t</executions>\n\t\t\t</plugin>\n\t\t</plugins>\n\t</build>\n\n\t<profiles>\n\t\t<profile>\n\t\t\t<id>Standalone</id>\n\t\t\t<activation>\n\t\t\t\t<activeByDefault>false</activeByDefault>\n\t\t\t</activation>\n\t\t\t<properties>\n\t\t\t\t<version>${project.version}-Standalone</version>\n\t\t\t\t<dependencies/>\n\t\t\t\t<mainClass>${project.groupId}.${project.artifactId}Standalone.Bukkit.${project.artifactId}</mainClass>\n\t\t\t\t<releaseType>Standalone</releaseType>\n\t\t\t</properties>\n\t\t\t<build>\n\t\t\t\t<plugins>\n\t\t\t\t\t<!-- Shades some required libs into the final jar -->\n\t\t\t\t\t<plugin>\n\t\t\t\t\t\t<groupId>org.apache.maven.plugins</groupId>\n\t\t\t\t\t\t<artifactId>maven-shade-plugin</artifactId>\n\t\t\t\t\t\t<version>${mavenShade.version}</version>\n\t\t\t\t\t\t<executions>\n\t\t\t\t\t\t\t<execution>\n\t\t\t\t\t\t\t\t<phase>package</phase>\n\t\t\t\t\t\t\t\t<goals>\n\t\t\t\t\t\t\t\t\t<goal>shade</goal>\n\t\t\t\t\t\t\t\t</goals>\n\t\t\t\t\t\t\t\t<configuration>\n\t\t\t\t\t\t\t\t\t<shadedArtifactAttached>true</shadedArtifactAttached>\n\t\t\t\t\t\t\t\t\t<shadedClassifierName>Standalone</shadedClassifierName>\n\t\t\t\t\t\t\t\t\t<createDependencyReducedPom>false</createDependencyReducedPom>\n\t\t\t\t\t\t\t\t\t<minimizeJar>false</minimizeJar>\n\t\t\t\t\t\t\t\t\t<outputDirectory>${project.build.directory}</outputDirectory>\n\t\t\t\t\t\t\t\t\t<artifactSet>\n\t\t\t\t\t\t\t\t\t\t<includes>\n\t\t\t\t\t\t\t\t\t\t\t<include>at.pcgamingfreaks:Minepacks-API</include>\n\t\t\t\t\t\t\t\t\t\t\t<include>at.pcgamingfreaks:Minepacks-MagicValues</include>\n\t\t\t\t\t\t\t\t\t\t\t<include>at.pcgamingfreaks:PluginLib</include>\n\t\t\t\t\t\t\t\t\t\t</includes>\n\t\t\t\t\t\t\t\t\t</artifactSet>\n\t\t\t\t\t\t\t\t\t<relocations>\n\t\t\t\t\t\t\t\t\t\t<relocation>\n\t\t\t\t\t\t\t\t\t\t\t<pattern>at.pcgf.libs</pattern>\n\t\t\t\t\t\t\t\t\t\t\t<shadedPattern>at.pcgamingfreaks.MinepacksStandalone.libs</shadedPattern>\n\t\t\t\t\t\t\t\t\t\t</relocation>\n\t\t\t\t\t\t\t\t\t\t<relocation>\n\t\t\t\t\t\t\t\t\t\t\t<pattern>at.pcgamingfreaks.Minepacks</pattern>\n\t\t\t\t\t\t\t\t\t\t\t<shadedPattern>at.pcgamingfreaks.MinepacksStandalone</shadedPattern>\n\t\t\t\t\t\t\t\t\t\t\t<excludes>\n\t\t\t\t\t\t\t\t\t\t\t\t<exclude>at.pcgamingfreaks.Minepacks.Bukkit.API.Backpack</exclude>\n\t\t\t\t\t\t\t\t\t\t\t\t<exclude>at.pcgamingfreaks.Minepacks.Bukkit.API.Callback</exclude>\n\t\t\t\t\t\t\t\t\t\t\t\t<exclude>at.pcgamingfreaks.Minepacks.Bukkit.API.MinepacksPlugin</exclude>\n\t\t\t\t\t\t\t\t\t\t\t\t<exclude>at.pcgamingfreaks.Minepacks.Bukkit.API.MinepacksCommandManager</exclude>\n\t\t\t\t\t\t\t\t\t\t\t\t<exclude>at.pcgamingfreaks.Minepacks.Bukkit.API.WorldBlacklistMode</exclude>\n\t\t\t\t\t\t\t\t\t\t\t\t<exclude>at.pcgamingfreaks.Minepacks.Bukkit.API.ItemFilter</exclude>\n\t\t\t\t\t\t\t\t\t\t\t\t<exclude>at.pcgamingfreaks.Minepacks.Bukkit.API.Events.*</exclude>\n\t\t\t\t\t\t\t\t\t\t\t\t<exclude>at.pcgamingfreaks.Minepacks.MagicValues</exclude>\n\t\t\t\t\t\t\t\t\t\t\t</excludes>\n\t\t\t\t\t\t\t\t\t\t</relocation>\n\t\t\t\t\t\t\t\t\t\t<relocation>\n\t\t\t\t\t\t\t\t\t\t\t<pattern>at.pcgamingfreaks</pattern>\n\t\t\t\t\t\t\t\t\t\t\t<shadedPattern>at.pcgamingfreaks.MinepacksStandalone.libs.at.pcgamingfreaks</shadedPattern>\n\t\t\t\t\t\t\t\t\t\t\t<excludes>\n\t\t\t\t\t\t\t\t\t\t\t\t<exclude>at.pcgamingfreaks.Minepacks.**</exclude>\n\t\t\t\t\t\t\t\t\t\t\t</excludes>\n\t\t\t\t\t\t\t\t\t\t</relocation>\n\t\t\t\t\t\t\t\t\t</relocations>\n\t\t\t\t\t\t\t\t\t<filters>\n\t\t\t\t\t\t\t\t\t\t<filter>\n\t\t\t\t\t\t\t\t\t\t\t<artifact>at.pcgamingfreaks:PluginLib</artifact>\n\t\t\t\t\t\t\t\t\t\t\t<excludes>\n\t\t\t\t\t\t\t\t\t\t\t\t<exclude>at/pcgamingfreaks/Bungee/**</exclude>\n\t\t\t\t\t\t\t\t\t\t\t\t<exclude>at/pcgamingfreaks/PluginLib/**</exclude>\n\t\t\t\t\t\t\t\t\t\t\t\t<exclude>PCGF_PluginLib.properties</exclude>\n\t\t\t\t\t\t\t\t\t\t\t\t<exclude>update.yml</exclude>\n\t\t\t\t\t\t\t\t\t\t\t</excludes>\n\t\t\t\t\t\t\t\t\t\t</filter>\n\t\t\t\t\t\t\t\t\t</filters>\n\t\t\t\t\t\t\t\t</configuration>\n\t\t\t\t\t\t\t</execution>\n\t\t\t\t\t\t</executions>\n\t\t\t\t\t</plugin>\n\t\t\t\t\t<!-- Replace all the PCGF-PluginLib code with alternatives -->\n\t\t\t\t\t<plugin>\n\t\t\t\t\t\t<groupId>org.sonatype.plugins</groupId>\n\t\t\t\t\t\t<artifactId>munge-maven-plugin</artifactId>\n\t\t\t\t\t\t<version>1.0</version>\n\t\t\t\t\t\t<executions>\n\t\t\t\t\t\t\t<execution>\n\t\t\t\t\t\t\t\t<id>munge</id>\n\t\t\t\t\t\t\t\t<phase>generate-sources</phase>\n\t\t\t\t\t\t\t\t<goals>\n\t\t\t\t\t\t\t\t\t<goal>munge</goal>\n\t\t\t\t\t\t\t\t</goals>\n\t\t\t\t\t\t\t\t<configuration>\n\t\t\t\t\t\t\t\t\t<symbols>STANDALONE</symbols>\n\t\t\t\t\t\t\t\t</configuration>\n\t\t\t\t\t\t\t</execution>\n\t\t\t\t\t\t</executions>\n\t\t\t\t\t</plugin>\n\t\t\t\t</plugins>\n\t\t\t</build>\n\t\t</profile>\n\t\t<profile>\n\t\t\t<id>Release</id>\n\t\t\t<activation>\n\t\t\t\t<activeByDefault>false</activeByDefault>\n\t\t\t</activation>\n\t\t\t<properties>\n\t\t\t\t<version>${project.version}-Release</version>\n\t\t\t\t<dependencies/>\n\t\t\t\t<soft-dependencies>, PCGF_PluginLib</soft-dependencies>\n\t\t\t\t<mainClass>${project.groupId}.${project.artifactId}.Bukkit.${project.artifactId}BadRabbit</mainClass>\n\t\t\t\t<releaseType>Release</releaseType>\n\t\t\t</properties>\n\t\t\t<dependencies>\n\t\t\t\t<dependency>\n\t\t\t\t\t<groupId>at.pcgamingfreaks</groupId>\n\t\t\t\t\t<artifactId>Minepacks</artifactId>\n\t\t\t\t\t<version>${project.version}</version>\n\t\t\t\t\t<classifier>Standalone</classifier>\n\t\t\t\t</dependency>\n\t\t\t\t<dependency>\n\t\t\t\t\t<groupId>at.pcgamingfreaks</groupId>\n\t\t\t\t\t<artifactId>Minepacks-BadRabbit-Bukkit</artifactId>\n\t\t\t\t\t<version>${project.version}</version>\n\t\t\t\t</dependency>\n\t\t\t\t<dependency>\n\t\t\t\t\t<groupId>at.pcgamingfreaks</groupId>\n\t\t\t\t\t<artifactId>Minepacks-Bootstrap-Paper</artifactId>\n\t\t\t\t\t<version>${project.version}</version>\n\t\t\t\t</dependency>\n\t\t\t</dependencies>\n\t\t\t<build>\n\t\t\t\t<plugins>\n\t\t\t\t\t<plugin>\n\t\t\t\t\t\t<groupId>org.apache.maven.plugins</groupId>\n\t\t\t\t\t\t<artifactId>maven-shade-plugin</artifactId>\n\t\t\t\t\t\t<version>${mavenShade.version}</version>\n\t\t\t\t\t\t<executions>\n\t\t\t\t\t\t\t<execution>\n\t\t\t\t\t\t\t\t<phase>package</phase>\n\t\t\t\t\t\t\t\t<goals>\n\t\t\t\t\t\t\t\t\t<goal>shade</goal>\n\t\t\t\t\t\t\t\t</goals>\n\t\t\t\t\t\t\t\t<configuration>\n\t\t\t\t\t\t\t\t\t<shadedArtifactAttached>true</shadedArtifactAttached>\n\t\t\t\t\t\t\t\t\t<shadedClassifierName>Release</shadedClassifierName>\n\t\t\t\t\t\t\t\t\t<createDependencyReducedPom>false</createDependencyReducedPom>\n\t\t\t\t\t\t\t\t\t<minimizeJar>false</minimizeJar>\n\t\t\t\t\t\t\t\t\t<artifactSet>\n\t\t\t\t\t\t\t\t\t\t<includes>\n\t\t\t\t\t\t\t\t\t\t\t<include>at.pcgamingfreaks:Minepacks-API</include>\n\t\t\t\t\t\t\t\t\t\t\t<include>at.pcgamingfreaks:Minepacks-MagicValues</include>\n\t\t\t\t\t\t\t\t\t\t\t<include>at.pcgamingfreaks:Minepacks-Bootstrap-Paper</include>\n\t\t\t\t\t\t\t\t\t\t\t<include>at.pcgamingfreaks:BadRabbit-Bukkit</include>\n\t\t\t\t\t\t\t\t\t\t\t<include>at.pcgamingfreaks:Minepacks-BadRabbit-Bukkit</include>\n\t\t\t\t\t\t\t\t\t\t\t<include>at.pcgamingfreaks:Minepacks</include>\n\t\t\t\t\t\t\t\t\t\t</includes>\n\t\t\t\t\t\t\t\t\t</artifactSet>\n\t\t\t\t\t\t\t\t\t<relocations>\n\t\t\t\t\t\t\t\t\t\t<relocation>\n\t\t\t\t\t\t\t\t\t\t\t<pattern>at.pcgamingfreaks.BadRabbit</pattern>\n\t\t\t\t\t\t\t\t\t\t\t<shadedPattern>at.pcgamingfreaks.Minepacks</shadedPattern>\n\t\t\t\t\t\t\t\t\t\t</relocation>\n\t\t\t\t\t\t\t\t\t</relocations>\n\t\t\t\t\t\t\t\t</configuration>\n\t\t\t\t\t\t\t</execution>\n\t\t\t\t\t\t</executions>\n\t\t\t\t\t</plugin>\n\t\t\t\t\t<plugin>\n\t\t\t\t\t\t<groupId>org.codehaus.mojo</groupId>\n\t\t\t\t\t\t<artifactId>license-maven-plugin</artifactId>\n\t\t\t\t\t\t<version>2.6.0</version>\n\t\t\t\t\t\t<configuration>\n\t\t\t\t\t\t\t<excludedScopes>test,provided,system</excludedScopes>\n\t\t\t\t\t\t\t<generateBundle>true</generateBundle>\n\t\t\t\t\t\t\t<licensesOutputFile>${project.build.directory}/generated-resources/licenses-THIRD-PARTY.xml</licensesOutputFile>\n\t\t\t\t\t\t\t<licenseUrlReplacements>\n\t\t\t\t\t\t\t\t<licenseUrlReplacement>\n\t\t\t\t\t\t\t\t\t<regexp>https?://(www\\.)?opensource\\.org/licenses/mit-license\\.php</regexp>\n\t\t\t\t\t\t\t\t\t<replacement>https://ci.pcgamingfreaks.at/download/mit.txt</replacement>\n\t\t\t\t\t\t\t\t</licenseUrlReplacement>\n\t\t\t\t\t\t\t\t<licenseUrlReplacement>\n\t\t\t\t\t\t\t\t\t<regexp>https?://(www\\.)?gnu\\.org/licenses/gpl-3.0.txt</regexp>\n\t\t\t\t\t\t\t\t\t<replacement>https://ci.pcgamingfreaks.at/download/gpl-3.0.txt</replacement>\n\t\t\t\t\t\t\t\t</licenseUrlReplacement>\n\t\t\t\t\t\t\t</licenseUrlReplacements>\n\t\t\t\t\t\t</configuration>\n\t\t\t\t\t\t<executions>\n\t\t\t\t\t\t\t<execution>\n\t\t\t\t\t\t\t\t<id>add-third-party</id>\n\t\t\t\t\t\t\t\t<phase>generate-resources</phase>\n\t\t\t\t\t\t\t\t<goals>\n\t\t\t\t\t\t\t\t\t<goal>add-third-party</goal>\n\t\t\t\t\t\t\t\t\t<goal>download-licenses</goal>\n\t\t\t\t\t\t\t\t</goals>\n\t\t\t\t\t\t\t</execution>\n\t\t\t\t\t\t</executions>\n\t\t\t\t\t</plugin>\n\t\t\t\t</plugins>\n\t\t\t</build>\n\t\t</profile>\n\t</profiles>\n</project>\n"
  },
  {
    "path": "Minepacks/resources/config.yml",
    "content": "# Minepacks Config File\n\n# Language Settings\nLanguage:\n  # Defines the used language, and the corresponding file used. The corresponding language file will be placed in the lang folder next to the config.yml named: <Language>.yml\n  Language: en\n  # Options:\n  #     Overwrite (deletes all changes from the file and extracts a new language file)\n  #     Upgrade (extracts a new language file and copy's all settings from the old language file)\n  #     Update (adds the default (english) text values for all missing values, just some basic formatting)\n  UpdateMode: Upgrade\n\n# Title to be shown for the opened inventory for everyone except the owner of the backpack. Can contain {OwnerName} (which will be replaced with the players name).\nBackpackTitleOther: \"&b{OwnerName}'s Backpack\"\n# The title of the inventory for the owner of the backpack.\nBackpackTitle: \"&bBackpack\"\n# If disabled, both the owner and 3. party player will see the BackpackTitleOther\nUseDynamicTitle: true\n# Defines if the content of the backpack get dropped on the death of a player.\n# If enabled, it can be disabled for individual players with the \"backpack.keepOnDeath\" permission.\nDropOnDeath: true\n# If this option is enabled the backpack will not drop if the keepInventory flag for the death event is set.\n# This should add compatibility with plugins protecting the players inventory on death (like SaveRod). But might prevent the backpack form dropping on death with some plugins.\nHonorKeepInventoryOnDeath: false\n# Defines the max amount of columns for a backpack.\n# The size of the user's backpack will be defined by the permission, permissions for bigger backpacks than this value will be ignored.\n# Can be set to anything > 0. Backpacks with more than 6 columns will have a broken UI! Sizes bigger than 9 may not work with all permission plugins.\nMaxSize: 6\n# Defines how backpacks get compressed when the previous permissions allowed for a bigger backpack.\n# Options:\n#   Fast: Only free slots will be used\n#   Compress: The plugin will try to combine item stacks to their max height\n#   Sort: The plugin will sort the backpack, will leave the same amount of items that do not fit in the backpack as compress, but will leave a sorted backpack, at the cost of some extra performance\nShrinkApproach: Sort\n# Defines in which game-modes a player can access his backpack (name or id)\n# Options: ADVENTURE, CREATIVE, SPECTATOR, SURVIVAL\n# AllowedGameModes: [ \"SURVIVAL\", \"ADVENTURE\" ]\nAllowedGameModes: [ \"SURVIVAL\" ]\n\nCooldown:\n  # Defines how long a player have to wait till he can reopen his backpack.\n  # Time is in seconds. Values < 1 disable the cooldown.\n  Command: -1\n  # If enabled, cooldowns will be synced between servers (BungeeCord network). It will also allow keeping the cooldown through server restarts.\n  # You should only use it with long cooldown times.\n  Sync: false\n  AddOnJoin: true\n  # You can turn this on when using sync to reduce the memory consumption a little\n  ClearOnLeave: false\n  # Removes old cooldowns from the cache to free memory. Time in seconds.\n  CleanupInterval: 600\n\n# Controls for the auto pickup on full inventory function\nFullInventory:\n  # If items should be collected to the backpack if the players inventory is full.\n  # This is also the default if 'IsToggleAllowed' is enabled.\n  CollectItems: false\n  # Interval in seconds how often items around the player should be collected, increase it if it lags the server\n  CheckInterval: 1\n  # Radius in which items get collected, in meter/blocks, allow decimals\n  CollectRadius: 1.5\n  # If this feature may be toggled.\n  IsToggleAllowed: false\n\n\n# Database settings\nDatabase:\n  # Database type. MySQL, SQLite, Files (data is stored in files, one file per user) or Shared (use shared connection pool from PCGF PluginLib)\n  Type: SQLite\n  # Auto database cleanup settings\n  AutoCleanup:\n    # Defines the max amount of days backpacks will be stored. -1 to disable auto cleanup\n    MaxInactiveDays: -1\n  # Defines the storage format for UUIDs for compatibility with other plugins (shared tables)\n  # true: format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n  # false: format: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n  UseUUIDSeparators: false\n  # Options: auto, online, offline | auto will decide based on the server online mode option.\n  # If you are using BungeeCord, set it to whatever you use on your BungeeCord server!!!\n  UUID_Type: auto\n  # If enabled the backpack will be saved regardless of if there have been changes to it or not. This will slightly negatively impact performance.\n  # This will help with changes made to items inside the backpack by other plugins. For example plugins that allow you to interact with items, when you allow your players to store these items inside the backpack.\n  ForceSaveOnUnload: false\n  # Settings only for MySQL\n  SQL:\n    Host: \"localhost:3306\"\n    Database: \"minecraft\"\n    User: \"minecraft\"\n    Password: \"minecraft\"\n    # The max amount of connections to the database the connection pool will open\n    MaxConnections: 2\n    # Sets the max lifetime of the connection in seconds. -1 = Default (30min)\n    MaxLifetime: -1\n    # Sets the idle timeout of the connection in seconds. -1 = Default (15min)\n    IdleTimeout: -1\n    # List of properties for your SQL connection. Can be used to disable SSL.\n    # Properties: [\"useSSL=false\"]\n    Properties: []\n  # Tables settings for shared tables when using MySQL - Advanced MySQL Settings\n  # Use these settings only if you know what you are doing!!!!\n  # Do only change these settings if you know what you are doing and have some basic MySQL knowledge!!!\n  # Changing settings down here after you have used this plugin may result in data inconsistency!!!\n  Tables:\n    # Table names\n    # Don't change the players table if you have backpacks stored in your database already! Player id's might not match any more resulting data inconsistency.\n    User: backpack_players\n    Backpack: backpacks\n    Cooldown: backpack_cooldowns\n    # Field settings for the tables\n    # Do not change them after the tables have been generated!\n    # If you like to change them after the tables have been generated alter the tables manually or delete them (the system then will regenerate them).\n    Fields:\n      User:\n        Player_ID: player_id\n        Name: name\n        UUID: uuid\n      Backpack:\n        Owner_ID: owner\n        ItemStacks: itemstacks\n        Version: version\n        LastUpdate: lastupdate\n      Cooldown:\n        Player_ID: id\n        Time: time\n  # Settings controlling the cache behavior of the plugin. You may optimize it a little depending on your player count, ram or cpu bottlenecks.\n  Cache:\n    UnCache:\n      # The strategy used to uncache offline players. Options\n      #     interval (offline players get uncached every x seconds)\n      #     intervalChecked (like interval, but also ensures that the player is already offline for at least the interval time, adds a cpu overhead)\n      #     ondisconnect (player instantly gets uncached as soon as he disconnects, may adds overhead if other plugins try to access the player data when they go offline, also it may be problematic for players with unstable connections)\n      #     ondisconnectdelayed (player gets uncached x seconds after he went offline, adds overhead on disconnect, you shouldn't use this with a lot of players joining and leaving.)\n      Strategy: interval\n      # Used for the interval based uncaching algorithms, and is also used as delay for ondisconnectdelayed. Value in seconds. Default: 600 = 10 minutes\n      Interval: 600\n      Delay: 600\n\nShulkerboxes:\n  # This setting controls whether players can put shulkerboxes into their backpacks.\n  PreventInBackpack: true\n  # This setting allows disabling shulkerboxes all together. Players won't be able to craft or use them.\n  DisableShulkerboxes: false\n  # This setting controls how existing shulkerboxes are handled if they are disabled.\n  # Options: Ignore, Remove = shulker-box will be removed including its content, Destroy = shulker-box will be destroyed, and it's content will be dropped\n  Existing: \"Ignore\"\n\nItemFilter:\n  # Enables the item filter. Make sure to define items to be filtered.\n  Enabled: false\n  # Changes the filter mode, either blacklist (only unlisted materials are allowed) or whitelist (only listed materials are allowed)\n  Mode: blacklist\n  # Filter lists bellow. An item will be blocked (in blacklist mode) or allowed (in whitelist mode) if it matches on of the given filters.\n  # List of materials that should be filtered. Can be name or id (id only for MC versions older than 1.13!).\n  Materials: []\n  # List of names that should be filtered. Must match the display name of the item exactly. & color codes will be converted automatically.\n  Names: []\n  # List of lore that should be filtered. Can be a single line or all lines of the lore.\n  Lore: []\n\n# These settings allow control over how the plugin behave in different worlds\nWorldSettings:\n  # Options: blacklist (all worlds listed in FilteredWorlds will be blocked), whitelist (all worlds listed in FilteredWorlds will be allowed)\n  FilterType: \"blacklist\"\n  # All worlds listed here will not have the plugin usable\n  # FilteredWorlds: [\"creative_world\"]\n  # FilteredWorlds: [\"creative_world1\", \"creative_world2\"]\n  FilteredWorlds: []\n  # Defines how the Blacklist will be enforced\n  # Options:\n  #   Message           = The player will see a message that the usage of the backpack is not allowed in this world.\n  #   MissingPermission = The player will receive the plugins no permission message.\n  #   NoPlugin          = The plugin will not be available at all and act as if it was not installed.\n  #                       This also exclude players with permission to bypass the world restriction from using it!\n  #                       It will not disable the Shulkerboxes filter!\n  BlockMode: \"Message\"\n\n# Gives the players an item they can interact with to open their backpack. Only works on MC 1.8 or newer.\nItemShortcut:\n  # If enabled the players will be given an item they can interact with to open the backpack.\n  # The item may not be removed from their inventory as long as this option is enabled.\n  Enabled: true\n  # The name of the item in the inventory\n  ItemName: \"&eBackpack\"\n  # The texture value for the head.\n  # Heads can be found here: https://minecraft-heads.com/custom-heads/\n  # The correct value is the one listed on the head page under Other/Value\n  HeadTextureValue: \"eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvOGRjYzZlYjQwZjNiYWRhNDFlNDMzOTg4OGQ2ZDIwNzQzNzU5OGJkYmQxNzVjMmU3MzExOTFkNWE5YTQyZDNjOCJ9fX0=\"\n  # Increases compatibility with some death chest plugins. Enable this if the backpack item gets added to your death chest!\n  # Please note: This will not move items from the backpack to the death chest! The items in the backpack will still drop to the ground unless DropOnDeath is disabled.\n  ImproveDeathChestCompatibility: false\n  # Prevents the backpack from being used as a hat\n  BlockAsHat: false\n  # Opens a container if right-clicked while holding the backpack shortcut in the hand. This option will only work on MC 1.13 or newer.\n  OpenContainerOnRightClick: false\n  # The id of the slot that should be preferred when giving a player the shortcut item\n  PreferredSlotId: -1\n  # If this option is enabled the player will not be able to move the backpack item within their inventory\n  BlockItemFromMoving: false\n\nSound:\n  # Enables all sound effects\n  Enabled: true\n  # The sound effect that should be played when the backpack is opened\n  # disabled or false to disable the sound effect\n  # auto will play the chest sound for minecraft versions older than 1.11, and the shulker-box sound for newer MC versions\n  OpenSound: auto\n  # The sound effect that should be played when the backpack is closed\n  # disabled or false to disable the sound effect\n  # auto will play the chest sound for minecraft versions older than 1.11, and the shulker-box sound for newer MC versions\n  CloseSound: auto\n\n# Settings for the inventory management\nInventoryManagement:\n  ClearCommand:\n    # If enabled the plugin provides an inventory clear command that keeps the backpack item.\n    Enabled: true\n\nMisc:\n  AutoUpdate:\n    # When auto update is disabled you still can use the build in update function manually with /backpack update\n    Enabled: true\n    Channel: ${updateChannel}\n  # Enable this option if you are using a BungeeCord setup and want to share the plugin's database across multiple servers.\n  UseBungeeCord: false\n\n# Config file version. Don't touch it!\nVersion: ${configFileVersion}"
  },
  {
    "path": "Minepacks/resources/lang/chs.yml",
    "content": "# To simplify the customisation and the translation process please check out the editor: https://ptp.pcgamingfreaks.at\n\nLanguage:\n  NotFromConsole: \"§f［§b背包§f］ 控制台无法执行这个命令。\"\n  Ingame:\n    NoPermission: \"§f［§b背包§f］ 您没有权限。\"\n    WorldDisabled: \"§f［§b背包§f］ 这个世界禁用。\"\n    NaN: \"§f［§b背包§f］ 无效的数值。\"\n    OwnBackpackClose: \"§f［§b背包§f］ 背包关闭\"\n    OwnBackpackClose_SendMethod: \"action_bar\"\n    #Parameter: {OwnerName}, {OwnerDisplayName}\n    PlayerBackpackClose: \"§f［§b背包§f］ 玩家 §a{OwnerName} §f背包关闭。\"\n    PlayerBackpackClose_SendMethod: \"action_bar\"\n    InvalidBackpack: \"§f［§b背包§f］ 无效的背包。\"\n    NotAllowedInBackpack: \"§f［§b背包§f］ 物品 {ItemName} §f不能放背包内。\"\n    NotAllowedInBackpack_SendMethod: \"action_bar\"\n    DontRemoveShortcut: \"§f［§b背包§f］ 您不能从背包丢弃头颅。\"\n    DontRemoveShortcut_SendMethod: \"action_bar\"\n    BackpackShrunk: \"§f［§b背包§f］ 您的背包缩小了！一些物品掉到了地上！\"\n    Open:\n      #Parameter: {TimeLeft} time in seconds till the backpack can be reopened, {TimeSpanLeft} time formatted as string till the backpack can be reopened\n      Cooldown: \"§f［§b背包§f］ 请等待 §e{TimeLeft} §f秒。\"\n      #Parameter: {CurrentGameMode}, {AllowedGameModes}\n      WrongGameMode: \"§f［§b背包§f］ 您不能在这种游戏模式下打开背包。\"\n    Clean:\n      BackpackCleaned: \"§f［§b背包§f］ 背包清空。\"\n      BackpackCleanedBy: \"§f［§b背包§f］ 玩家 {DisplayName} 清空您的背包。\"\n      BackpackCleanedOther: \"§f［§b背包§f］ 玩家 {DisplayName} 的背包已清空。\"\n    Sort:\n      Sorted: \"§f［§b背包§f］ 背包分类\"\n    Help:\n      Header: \"\"\n      Footer: \"\"\n    Reload:\n      Reloading: \"§f［§b背包§f］ 重新加载中\"\n      Reloaded: \"§f［§b背包§f］ 更新配置与语言文件\"\n    Update:\n      CheckingForUpdates: \"§f［§b背包§f］ 检查更新\"\n      Updated: \"§f［§b背包§f］ 插件已更新，将在下次启动加载。\"\n      NoUpdate: \"§f［§b背包§f］ 没有可用的更新。\"\n      UpdateFail: \"§f［§b背包§f］ 出现错误！请检查控制台！\"\n      # You can change this message if you like to, but don't cry if the link isn't linking to the plugin anymore!\n      UpdateAvailable: \"§f［§b背包§f］ 发现新版本 https://www.spigotmc.org/resources/19286/\"\n    Backup:\n      Created: \"§f［§b背包§f］ 背包已备份\"\n      NoBackpack: \"§f［§b背包§f］ 玩家没有背包，或者背包是空的。\"\n    Restore:\n      BackupsPerPage: 10\n      Headline: \"[\\\"\\\",{\\\"text\\\":\\\"Backups\\\",\\\"color\\\":\\\"yellow\\\"},{\\\"text\\\":\\\" - \\\",\\\"color\\\":\\\"white\\\"},{\\\"text\\\":\\\"showing page {CurrentPage}/{MaxPage}\\\",\\\"color\\\":\\\"gold\\\"}]\"\n      Footer: \"[{\\\"text\\\":\\\"<<< Previous <<<\\\",\\\"color\\\":\\\"gray\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"run_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}--\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}--\\\"}},{\\\"text\\\":\\\" Showing page {CurrentPage}/{MaxPage} \\\",\\\"color\\\":\\\"gold\\\"},{\\\"text\\\":\\\">>> Next >>>\\\",\\\"color\\\":\\\"gray\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"run_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}++\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}++\\\"}}]\"\n      BackupEntry: \"[\\\"\\\",{\\\"text\\\":\\\"{BackupIdentifier}\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"suggest_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {BackupIdentifier}\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"User: {BackupPlayerName} ({BackupPlayerUUID})\\\\nCreated: {BackupDate}\\\"}}]\"\n      NoValidBackup: \"No backup matching {BackupIdentifier} found\"\n      NoUserToRestoreToFound: \"No valid user to restore backup to found\"\n      # No Json!!!\n      ParameterBackupName: \"backup_name\"\n      # No Json!!!\n      DateFormat: \"yyyy.MM.dd HH:mm:ss\"\n      Restored: \"Backup has been successful restored.\"\n    InventoryClear:\n      UnknownPlayer: \"&c找不到玩家 {Name}！\"\n      Cleared: \"物品栏已清空。\"\n      ClearedOther: \"{DisplayName}&r 的物品栏已清空。\"\n      ClearedOtherTarget: \"您的物品栏已被 {DisplayName}&r 清空。\"\n    Pickup:\n      ToggleOn: \"&7自动物品收集已切换为 &a开&7。\"\n      ToggleOff: \"&7自动物品收集已切换为 &c关&7。\"\n  Commands:\n    HelpFormat: \"§f［§b背包§f］ {Description}命令 “/{MainCommand} {SubCommand} {Parameters}”\"\n    PlayerNameVariable: \"player_name\"\n    Description:\n      Backpack: \"打开背包\"\n      Sort: \"整理背包\"\n      Clean: \"清空背包\"\n      CleanOthers: \"清空玩家背包\"\n      OpenOthers: \"显示玩家背包\"\n      Reload: \"重新加载\"\n      Update: \"检查更新\"\n      Version: \"查看版本\"\n      Backup: \"创建备份\"\n      BackupEveryone: \"为目前所有在线的玩家创建备份。\"\n      Restore: \"打开备份\"\n      RestoreList: \"列出所有备份\"\n      Help: \"查看帮助\"\n      Migrate: \"迁移数据类型\"\n      Pickup: \"当物品栏已满时切换自动拾取状态。\"\n\nCommand:\n  Backpack:\n    - backpack\n    - bp\n  Open:\n    - open\n  Sort:\n    - sort\n  Clean:\n    - clean\n    - clear\n    - empty\n  Reload:\n    - reload\n    - restart\n  Update:\n    - update\n  Backup:\n    - backup\n  Restore:\n    - restore\n  ListBackups:\n    - listbackups\n  Version:\n    - version\n  Help:\n    - help\n  InventoryClear:\n    - clear\n    - inventoryclear\n    - clean\n  Pickup:\n    - pickup\n\n# Will be shown in the console during startup\nLanguageName: \"中文\"\nAuthor: \"尹\"\n\n# Language file version. Don't touch it!\nVersion: 21"
  },
  {
    "path": "Minepacks/resources/lang/cht.yml",
    "content": "# To simplify the customisation and translation process please check out the editor: https://ptp.pcgamingfreaks.at\n\nLanguage:\n  NotFromConsole: \"&c後台將無法使用此指令!\"\n  Ingame:\n    NoPermission: \"&c您沒有足夠的權限去使用此指令!\"\n    WorldDisabled: \"&c此世界不允許玩家存取隨身背包!\"\n    NaN: \"您所輸入的數值無效!\"\n    OwnBackpackClose: \"已關閉隨身背包\"\n    OwnBackpackClose_SendMethod: \"action_bar\"\n    #Parameter: {OwnerName}, {OwnerDisplayName}\n    PlayerBackpackClose: \"{OwnerName} 的隨身背包已關閉\"\n    PlayerBackpackClose_SendMethod: \"action_bar\"\n    InvalidBackpack: \"&c無效的隨身背包!\"\n    NotAllowedInBackpack: \"&c{ItemName} 不被允許在此背包中!\"\n    NotAllowedInBackpack_SendMethod: \"action_bar\"\n    DontRemoveShortcut: \"&c您不能從背包中刪除快捷方式!\"\n    DontRemoveShortcut_SendMethod: \"action_bar\"\n    BackpackShrunk: \"&c您的背包縮小了！一些物品掉到了地上！\"\n    Open:\n      #Parameter: {TimeLeft} time in seconds till the backpack can be reopened, {TimeSpanLeft} time formatted as string till the backpack can be reopened\n      Cooldown: \"&e請等待 {TimeLeft} 秒再使用該指令\"\n      #Parameter: {CurrentGameMode}, {AllowedGameModes}\n      WrongGameMode: \"&c您將不被允許在此模式中開啟背包!\"\n    Clean:\n      BackpackCleaned: \"&e該隨身背包將已被清空~\"\n      BackpackCleanedBy: \"&e您的隨身背包已被 {DisplayName} &e清空~\"\n      BackpackCleanedOther: \"&c{DisplayName} &e的背包已被清空~\"\n    Sort:\n      Sorted: \"該隨身背包已分類\"\n    Help:\n      Header: \"&e----- &6隨身背包 指令列表 &e-----\"\n      Footer: \"\"\n    Reload:\n      Reloading: \"&6背包插件重載中!\"\n      Reloaded: \"&a已成功重載背包配置~\"\n    Update:\n      CheckingForUpdates: \"&e可用的更新檢查中...\"\n      Updated: \"插件已更新\"\n      NoUpdate: \"[\\\"\\\",{\\\"text\\\":\\\"No plugin update available.\\\",\\\"color\\\":\\\"gold\\\"}]\"\n      UpdateFail: \"[\\\"\\\",{\\\"text\\\":\\\"There was a problem looking for updates! Please check the console!\\\",\\\"color\\\":\\\"red\\\"}]\"\n      # You can change this message if you like to, but don't cry if the link isn't linking to the plugin anymore!\n      UpdateAvailable: \"[{\\\"text\\\":\\\"There is an update available! Please go to \\\\\\\"\\\",\\\"color\\\":\\\"green\\\"},{\\\"text\\\":\\\"https://www.spigotmc.org/resources/19286/\\\",\\\"color\\\":\\\"yellow\\\",\\\"underlined\\\":true,\\\"clickEvent\\\":{\\\"action\\\":\\\"open_url\\\",\\\"value\\\":\\\"https://www.spigotmc.org/resources/19286/\\\"}},{\\\"text\\\":\\\"\\\\\\\" to download it!\\\"}]\"\n    Backup:\n      Created: \"The backpack has been backed up successful.\"\n      NoBackpack: \"The player doesn't have a backpack or his backpack is empty.\"\n    Restore:\n      BackupsPerPage: 10\n      Headline: \"[\\\"\\\",{\\\"text\\\":\\\"Backups\\\",\\\"color\\\":\\\"yellow\\\"},{\\\"text\\\":\\\" - \\\",\\\"color\\\":\\\"white\\\"},{\\\"text\\\":\\\"showing page {CurrentPage}/{MaxPage}\\\",\\\"color\\\":\\\"gold\\\"}]\"\n      Footer: \"[{\\\"text\\\":\\\"<<< Previous <<<\\\",\\\"color\\\":\\\"gray\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"run_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}--\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}--\\\"}},{\\\"text\\\":\\\" Showing page {CurrentPage}/{MaxPage} \\\",\\\"color\\\":\\\"gold\\\"},{\\\"text\\\":\\\">>> Next >>>\\\",\\\"color\\\":\\\"gray\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"run_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}++\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}++\\\"}}]\"\n      BackupEntry: \"[\\\"\\\",{\\\"text\\\":\\\"{BackupIdentifier}\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"suggest_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {BackupIdentifier}\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"User: {BackupPlayerName} ({BackupPlayerUUID})\\\\nCreated: {BackupDate}\\\"}}]\"\n      NoValidBackup: \"No backup matching {BackupIdentifier} found\"\n      NoUserToRestoreToFound: \"No valid user to restore backup to found\"\n      # No Json!!!\n      ParameterBackupName: \"backup_name\"\n      # No Json!!!\n      DateFormat: \"yyyy.MM.dd HH:mm:ss\"\n      Restored: \"Backup has been successful restored.\"\n    InventoryClear:\n      UnknownPlayer: \"&c找不到玩家 {Name}！\"\n      Cleared: \"物品欄已清空。\"\n      ClearedOther: \"{DisplayName}&r 的物品欄已清空。\"\n      ClearedOtherTarget: \"您的物品欄已被 {DisplayName}&r 清空。\"\n    Pickup:\n      ToggleOn: \"&7自動物品收集已切換為 &a開&7。\"\n      ToggleOff: \"&7自動物品收集已切換為 &c關&7。\"\n  Commands:\n    HelpFormat: \"[\\\"\\\",{\\\"text\\\":\\\"/{MainCommand} {SubCommand} {Parameters}\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"suggest_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand}\\\"}},{\\\"text\\\":\\\" - \\\",\\\"color\\\":\\\"white\\\"},{\\\"text\\\":\\\"{Description}\\\",\\\"color\\\":\\\"aqua\\\"}]\"\n    PlayerNameVariable: \"player_name\"\n    Description:\n      Backpack: \"開啟您的隨身背包\"\n      Sort: \"整理您的隨身背包\"\n      Clean: \"清空您的隨身背包\"\n      CleanOthers: \"清空其他玩家的隨身背包\"\n      OpenOthers: \"顯示其他玩家的隨身背包\"\n      Reload: \"重載插件配置設定\"\n      Update: \"檢查可用的更新\"\n      Version: \"查看此插件的版本\"\n      Backup: \"建立一個新的備份\"\n      BackupEveryone: \"為目前所有在線的玩家建立備份。\"\n      Restore: \"回復備份\"\n      RestoreList: \"所有已備份的列表\"\n      Help: \"查看所有指令的幫助\"\n      Migrate: \"轉移玩家的隨身背包\"\n      Pickup: \"當物品欄已滿時切換自動拾取狀態。\"\n\nCommand:\n  Backpack:\n    - backpack\n    - bp\n  Open:\n    - open\n  Sort:\n    - sort\n  Clean:\n    - clean\n    - clear\n    - empty\n  Reload:\n    - reload\n    - restart\n  Update:\n    - update\n  Backup:\n    - backup\n  Restore:\n    - restore\n  ListBackups:\n    - listbackups\n  Version:\n    - version\n  Help:\n    - help\n  InventoryClear:\n    - clear\n    - inventoryclear\n    - clean\n  Pickup:\n    - pickup\n\n# Will be shown in the console during startup\nLanguageName: \"繁體中文\"\nAuthor: \"Umekaw\"\n\n# Language file version. Don't touch it!\nVersion: 21\n"
  },
  {
    "path": "Minepacks/resources/lang/cz.yml",
    "content": "# To simplify the customisation and translation process please check out the editor: https://ptp.pcgamingfreaks.at\n\nLanguage:\n  NotFromConsole: \"&cTento příkaz nelze použít z konzole.\"\n  Ingame:\n    NoPermission: \"&cNa toto nemáš dostatečná oprávnění!\"\n    WorldDisabled: \"&cPoužití batohu není v tomto světě povoleno.\"\n    NaN: \"[\\\"\\\",{\\\"text\\\":\\\"Zadaná hodnota není číslo!\\\",\\\"color\\\":\\\"red\\\"}]\"\n    OwnBackpackClose: \"Batoh byl zavřen!\"\n    OwnBackpackClose_SendMethod: \"action_bar\"\n    #Parameter: {OwnerName}, {OwnerDisplayName}\n    PlayerBackpackClose: \"Batoh hráče {OwnerName} byl zavřen!\"\n    PlayerBackpackClose_SendMethod: \"action_bar\"\n    InvalidBackpack: \"Neplatný batoh.\"\n    NotAllowedInBackpack: \"&c{ItemName} není v batohu povoleno.\"\n    NotAllowedInBackpack_SendMethod: \"action_bar\"\n    DontRemoveShortcut: \"&cNesmíš odstranit zkratku batohu ze svého inventáře!\"\n    DontRemoveShortcut_SendMethod: \"action_bar\"\n    BackpackShrunk: \"&cTvůj batoh se zmenšil! Některé předměty spadly na zem!\"\n    Open:\n      #Parameter: {TimeLeft} time in seconds till the backpack can be reopened, {TimeSpanLeft} time formatted as string till the backpack can be reopened\n      Cooldown: \"[{\\\"text\\\":\\\"Počkej prosím \\\",\\\"color\\\":\\\"dark_green\\\"},{\\\"text\\\":\\\"{TimeSpanLeft}\\\",\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"{TimeLeft} sekund\\\"}},{\\\"text\\\":\\\" než znovu otevřeš svůj batoh.\\\"}]\"\n      #Parameter: {CurrentGameMode}, {AllowedGameModes}\n      WrongGameMode: \"Nemáš oprávnění otevřít svůj batoh v aktuálním herním módu.\"\n    Clean:\n      BackpackCleaned: \"Batoh byl vyčištěn.\"\n      BackpackCleanedBy: \"Tvůj batoh byl vyčištěn hráčem {DisplayName}&r.\"\n      BackpackCleanedOther: \"Batoh hráče {DisplayName}&r byl vyčištěn.\"\n    Sort:\n      Sorted: \"Batoh byl seřazen.\"\n    Help:\n      Header: \"&6### Minepacks Příkazy ###\"\n      Footer: \"&6#############################\"\n    Reload:\n      Reloading: \"&1Znovu načítám Minepacks ...\"\n      Reloaded: \"&1Minepacks znovu načten!\"\n    Update:\n      CheckingForUpdates: \"&1Kontroluji aktualizace ...\"\n      Updated: \"[\\\"\\\",{\\\"text\\\":\\\"Plugin aktualizován, bude načten při příštím restartu/reloadu.\\\",\\\"color\\\":\\\"yellow\\\"}]\"\n      NoUpdate: \"[\\\"\\\",{\\\"text\\\":\\\"Žádná aktualizace pluginu není k dispozici.\\\",\\\"color\\\":\\\"gold\\\"}]\"\n      UpdateFail: \"[\\\"\\\",{\\\"text\\\":\\\"Nastal problém při hledání aktualizací! Zkontroluj konzoli!\\\",\\\"color\\\":\\\"red\\\"}]\"\n      # You can change this message if you like to, but don't cry if the link isn't linking to the plugin anymore!\n      UpdateAvailable: \"[{\\\"text\\\":\\\"Je k dispozici aktualizace! Jdi na \\\\\\\"\\\",\\\"color\\\":\\\"green\\\"},{\\\"text\\\":\\\"${project.url}\\\",\\\"color\\\":\\\"yellow\\\",\\\"underlined\\\":true,\\\"clickEvent\\\":{\\\"action\\\":\\\"open_url\\\",\\\"value\\\":\\\"${project.url}\\\"}},{\\\"text\\\":\\\"\\\\\\\" pro stažení!\\\"}]\"\n    Backup:\n      Created: \"Batoh byl úspěšně zálohován.\"\n      NoBackpack: \"Hráč nemá batoh nebo je jeho batoh prázdný.\"\n    Restore:\n      BackupsPerPage: 10\n      Headline: \"[\\\"\\\",{\\\"text\\\":\\\"Zálohy\\\",\\\"color\\\":\\\"yellow\\\"},{\\\"text\\\":\\\" - \\\",\\\"color\\\":\\\"white\\\"},{\\\"text\\\":\\\"zobrazena stránka {CurrentPage}/{MaxPage}\\\",\\\"color\\\":\\\"gold\\\"}]\"\n      Footer: \"[{\\\"text\\\":\\\"<<< Předchozí <<<\\\",\\\"color\\\":\\\"gray\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"run_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}--\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}--\\\"}},{\\\"text\\\":\\\" Zobrazena stránka {CurrentPage}/{MaxPage} \\\",\\\"color\\\":\\\"gold\\\"},{\\\"text\\\":\\\">>> Další >>>\\\",\\\"color\\\":\\\"gray\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"run_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}++\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}++\\\"}}]\"\n      BackupEntry: \"[\\\"\\\",{\\\"text\\\":\\\"{BackupIdentifier}\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"suggest_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {BackupIdentifier}\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"Uživatel: {BackupPlayerName} ({BackupPlayerUUID})\\\\nVytvořeno: {BackupDate}\\\"}}]\"\n      NoValidBackup: \"Žádná záloha odpovídající {BackupIdentifier} nenalezena\"\n      NoUserToRestoreToFound: \"Žádný platný uživatel pro obnovení zálohy nenalezen\"\n      # No Json!!!\n      ParameterBackupName: \"backup_name\"\n      # No Json!!!\n      DateFormat: \"yyyy.MM.dd HH:mm:ss\"\n      Restored: \"Záloha byla úspěšně obnovena.\"\n    InventoryClear:\n      UnknownPlayer: \"&cHráče {Name} se nepodařilo najít!\"\n      Cleared: \"Inventář vyčištěn.\"\n      ClearedOther: \"Inventář hráče {DisplayName}&r byl vyčištěn.\"\n      ClearedOtherTarget: \"Tvůj inventář byl vyčištěn hráčem {DisplayName}&r.\"\n    Pickup:\n      ToggleOn: \"&7Automatický sběr předmětů byl &aZAPNUT&7.\"\n      ToggleOff: \"&7Automatický sběr předmětů byl &cVYPNUT&7.\"\n  Commands:\n    HelpFormat: \"[\\\"\\\",{\\\"text\\\":\\\"/{MainCommand} {SubCommand} {Parameters}\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"suggest_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand}\\\"}},{\\\"text\\\":\\\" - \\\",\\\"color\\\":\\\"white\\\"},{\\\"text\\\":\\\"{Description}\\\",\\\"color\\\":\\\"aqua\\\"}]\"\n    PlayerNameVariable: \"player_name\"\n    Description:\n      Backpack: \"Otevře tvůj batoh.\"\n      Sort: \"Seřadí tvůj batoh.\"\n      Clean: \"Vyčistí tvůj batoh.\"\n      CleanOthers: \"Vyčistí batoh jiného hráče.\"\n      OpenOthers: \"Zobrazí batoh jiného hráče.\"\n      Reload: \"Znovu načte konfiguraci pluginu.\"\n      Update: \"Zkontroluje nové aktualizace pluginu.\"\n      Version: \"Vypíše detaily o verzi pluginu a jeho závislostech.\"\n      Backup: \"Vytvoří zálohu batohu hráče.\"\n      BackupEveryone: \"Vytvoří zálohu pro všechny, kteří jsou momentálně online.\"\n      Restore: \"Obnoví zálohu.\"\n      RestoreList: \"Vypíše všechny dostupné zálohy.\"\n      Help: \"Zobrazí všechny dostupné příkazy a jejich popis.\"\n      Migrate: \"Převede používanou databázi z jednoho typu na jiný.\"\n      Pickup: \"Přepne stav automatického sběru, když je inventář plný.\"\n\nCommand:\n  Backpack:\n    - backpack\n    - bp\n  Open:\n    - open\n  Sort:\n    - sort\n  Clean:\n    - clean\n    - clear\n    - empty\n  Reload:\n    - reload\n    - restart\n  Update:\n    - update\n  Backup:\n    - backup\n  Restore:\n    - restore\n  ListBackups:\n    - listbackups\n  Version:\n    - version\n  Help:\n    - help\n  InventoryClear:\n    - clear\n    - inventoryclear\n    - clean\n  Pickup:\n    - pickup\n\n# Will be shown in the console during startup\nLanguageName: \"czech\"\nAuthor: \"ProPl4yerCz\"\n\n# Language file version. Don't touch it!\nVersion: 21"
  },
  {
    "path": "Minepacks/resources/lang/de.yml",
    "content": "# To simplify the customisation and translation process please check out the editor: https://ptp.pcgamingfreaks.at\n\nLanguage:\n  NotFromConsole: \"&cDieser Befehl kann nicht in der Konsole ausgeführt werden.\"\n  Ingame:\n    NoPermission: \"&cDir fehlen die Rechte dafür.\"\n    NaN: \"[\\\"\\\",{\\\"text\\\":\\\"Die Eingabe ist keine gültige Zahl!\\\",\\\"color\\\":\\\"red\\\"}]\"\n    WorldDisabled: \"&cDie Verwendung des Rucksacks ist in dieser Welt deaktiviert!\"\n    OwnBackpackClose: \"Rucksack geschlossen.\"\n    OwnBackpackClose_SendMethod: \"action_bar\"\n    #Parameter: {OwnerName}, {OwnerDisplayName}\n    PlayerBackpackClose: \"{OwnerName}'s Rucksack geschlossen.\"\n    PlayerBackpackClose_SendMethod: \"action_bar\"\n    InvalidBackpack: \"Rucksack fehlerhaft.\"\n    NotAllowedInBackpack: \"&c{ItemName} ist im Rucksack nicht erlaubt.\"\n    DontRemoveShortcut: \"&cDu darfst den Rucksack nicht aus deinem Inventar entfernen!\"\n    DontRemoveShortcut_SendMethod: \"action_bar\"\n    BackpackShrunk: \"&cDein Rucksack ist geschrumpft! Einige Items sind auf den Boden gefallen!\"\n    Open:\n      #Parameter: {TimeLeft} time in seconds till the backpack can be reopened, {TimeSpanLeft} time formatted as string till the backpack can be reopened\n      Cooldown: \"[{\\\"text\\\":\\\"Bitte warte \\\",\\\"color\\\":\\\"dark_green\\\"},{\\\"text\\\":\\\"{TimeSpanLeft}\\\",\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"{TimeLeft} Sekunden\\\"}},{\\\"text\\\":\\\" bis du deinen Rucksack wieder öffnest.\\\"}]\"\n      #Parameter: {CurrentGameMode}, {AllowedGameModes}\n      WrongGameMode: \"Du darfst deinen Rucksack in deinem aktuellem Gamemode nicht öffnen.\"\n    Clean:\n      BackpackCleaned: \"Rucksack geleert.\"\n      BackpackCleanedBy: \"Dein Rucksack wurde von {DisplayName}&r geleert\"\n      BackpackCleanedOther: \"Der Rucksack von {DisplayName}&r wurde geleert.\"\n    Sort:\n      Sorted: \"Dein Rucksack wurde sortiert.\"\n    Help:\n      Header: \"&6### Minepacks Commands ###\"\n      Footer: \"&6#############################\"\n    Reload:\n      Reloading: \"&Minepacks wird neu geladen ...\"\n      Reloaded: \"&1Minepacks neu geladen!\"\n    Update:\n      CheckingForUpdates: \"&1Suche nach Aktualisierungen ...\"\n      Updated: \"[\\\"\\\",{\\\"text\\\":\\\"Plugin wurde aktualisiert, Änderungen werden mit dem nächsten Neustart übernommen.\\\",\\\"color\\\":\\\"yellow\\\"}]\"\n      NoUpdate: \"[\\\"\\\",{\\\"text\\\":\\\"Plugin-Aktualisierung verfügbar.\\\",\\\"color\\\":\\\"gold\\\"}]\"\n      UpdateFail: \"[\\\"\\\",{\\\"text\\\":\\\"Es gab ein Problem bei der Suche nach Updates! Bitte prüfe den Log für mehr Details.\\\",\\\"color\\\":\\\"red\\\"}]\"\n      # You can change this message if you like to, but don't cry if the link isn't linking to the plugin anymore!\n      UpdateAvailable: \"[{\\\"text\\\":\\\"Es ist eine Aktualisierung verfügbar! Bitte gehe auf \\\\\\\"\\\",\\\"color\\\":\\\"green\\\"},{\\\"text\\\":\\\"${project.url}\\\",\\\"color\\\":\\\"yellow\\\",\\\"underlined\\\":true,\\\"clickEvent\\\":{\\\"action\\\":\\\"open_url\\\",\\\"value\\\":\\\"${project.url}\\\"}},{\\\"text\\\":\\\"\\\\\\\" um es herunter zu laden!\\\"}]\"\n    Backup:\n      Created: \"Rucksack wurde gesichert.\"\n      NoBackpack: \"Der Spieler hat keinen Rucksack oder keine Items in seinem Rucksack.\"\n    Restore:\n      BackupsPerPage: 10\n      Headline: \"[\\\"\\\",{\\\"text\\\":\\\"Backups\\\",\\\"color\\\":\\\"yellow\\\"},{\\\"text\\\":\\\" - \\\",\\\"color\\\":\\\"white\\\"},{\\\"text\\\":\\\"Seite {CurrentPage}/{MaxPage}\\\",\\\"color\\\":\\\"gold\\\"}]\"\n      Footer: \"[{\\\"text\\\":\\\"<<< Vorherige <<<\\\",\\\"color\\\":\\\"gray\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"run_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}--\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}--\\\"}},{\\\"text\\\":\\\" Seite {CurrentPage}/{MaxPage} \\\",\\\"color\\\":\\\"gold\\\"},{\\\"text\\\":\\\">>> Nächste >>>\\\",\\\"color\\\":\\\"gray\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"run_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}++\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}++\\\"}}]\"\n      BackupEntry: \"[\\\"\\\",{\\\"text\\\":\\\"{BackupIdentifier}\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"suggest_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {BackupIdentifier}\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"User: {BackupPlayerName} ({BackupPlayerUUID})\\\\nErstellt: {BackupDate}\\\"}}]\"\n      NoValidBackup: \"{BackupIdentifier} ist kein gültiges Backup\"\n      NoUserToRestoreToFound: \"Kein gültiger Nutzer zum Wiederherstellen gefunden\"\n      # NoJSON\n      ParameterBackupName: \"backup_name\"\n      # No Json!!!\n      DateFormat: \"dd.MM.yyyy HH:mm:ss\"\n      Restored: \"Backup wurde erfolgreich wiederhergestellt.\"\n    InventoryClear:\n      UnknownPlayer: \"&cSpieler {Name} konnte nicht gefunden werden!\"\n      Cleared: \"Inventar gelöscht.\"\n      ClearedOther: \"Das Inventar von {DisplayName}&r wurde gelöscht.\"\n      ClearedOtherTarget: \"Dein Inventar wurde von {DisplayName}&r gelöscht.\"\n    Pickup:\n      ToggleOn: \"&7Automatisches Itemsammeln wurde &aEINGESCHALTET&7.\"\n      ToggleOff: \"&7Automatisches Itemsammeln wurde &cAUSGESCHALTET&7.\"\n  Commands:\n    HelpFormat: \"[\\\"\\\",{\\\"text\\\":\\\"/{MainCommand} {SubCommand} {Parameters}\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"suggest_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand}\\\"}},{\\\"text\\\":\\\" - \\\",\\\"color\\\":\\\"white\\\"},{\\\"text\\\":\\\"{Description}\\\",\\\"color\\\":\\\"aqua\\\"}]\"\n    PlayerNameVariable: \"player_name\"\n    Description:\n      Backpack: \"Öffnet deinen Rucksack.\"\n      Sort: \"Sortiert deinen Rucksack\"\n      Clean: \"Leert deinen Rucksack.\"\n      CleanOthers: \"Leert den Rucksack eines anderen Spielers.\"\n      OpenOthers: \"Öffnet den Rucksack eines anderen Spielers.\"\n      Reload: \"Lädt die Konfigurationsdatei neu.\"\n      Update: \"Prüft auf neue Plugin-Updates.\"\n      Backup: \"Erstellt eine Sicherungskopie eines Rucksacks.\"\n      BackupEveryone: \"Erstellt eine Sicherungskopie der Rucksäcke aller verbundenen Spieler.\"\n      Restore: \"Stellt eine Sicherungskopie eines Rucksacks wieder her.\"\n      RestoreList: \"Listet alle verfügbaren Sicherungskopien von Rucksäcken auf.\"\n      Version: \"Gibt die Versionsdetails über das Plugin und seine Abhängigkeiten aus.\"\n      Help: \"Zeigt die verfügbaren Befehle an.\"\n      Migrate: \"Erlaubt das Konvertieren der Datenbank in ein anderes Format.\"\n      Pickup: \"Schaltet den automatischen Item-Aufnahmestatus um, wenn das Inventar voll ist.\"\n\nCommand:\n  Backpack:\n    - backpack\n    - bp\n    - rucksack\n  Open:\n    - open\n    - öffnen\n  Sort:\n    - sort\n    - sortieren\n  Clean:\n    - clean\n    - clear\n    - empty\n    - leeren\n    - löschen\n  Reload:\n    - reload\n    - restart\n  Update:\n    - update\n  Backup:\n    - backup\n  Restore:\n    - restore\n  ListBackups:\n    - listbackups\n  Version:\n    - version\n  Help:\n    - help\n    - hilfe\n  InventoryClear:\n    - clear\n    - inventoryclear\n    - clean\n  Pickup:\n    - pickup\n\n# Will be shown in the console during startup\nLanguageName: \"german\"\nAuthor: \"GeorgH93\"\n\n# Language file version. Don't touch it!\nVersion: 21\n"
  },
  {
    "path": "Minepacks/resources/lang/en.yml",
    "content": "# To simplify the customisation and translation process please check out the editor: https://ptp.pcgamingfreaks.at\n\nLanguage:\n  NotFromConsole: \"&cCommand not usable from console.\"\n  Ingame:\n    NoPermission: \"&cYou don't have the permission to do that.\"\n    WorldDisabled: \"&cThe use of the backpack is not allowed in this world.\"\n    NaN: \"[\\\"\\\",{\\\"text\\\":\\\"The entered value is not a number!\\\",\\\"color\\\":\\\"red\\\"}]\"\n    OwnBackpackClose: \"Backpack closed!\"\n    OwnBackpackClose_SendMethod: \"action_bar\"\n    #Parameter: {OwnerName}, {OwnerDisplayName}\n    PlayerBackpackClose: \"{OwnerName}'s backpack closed!\"\n    PlayerBackpackClose_SendMethod: \"action_bar\"\n    InvalidBackpack: \"Invalid backpack.\"\n    NotAllowedInBackpack: \"&c{ItemName} is not allowed in the backpack.\"\n    NotAllowedInBackpack_SendMethod: \"action_bar\"\n    DontRemoveShortcut: \"&cYou must not remove the backpack shortcut from your inventory!\"\n    DontRemoveShortcut_SendMethod: \"action_bar\"\n    BackpackShrunk: \"&cYour backpack shrunk! Some items fell to the ground!\"\n    Open:\n      #Parameter: {TimeLeft} time in seconds till the backpack can be reopened, {TimeSpanLeft} time formatted as string till the backpack can be reopened\n      Cooldown: \"[{\\\"text\\\":\\\"Please wait \\\",\\\"color\\\":\\\"dark_green\\\"},{\\\"text\\\":\\\"{TimeSpanLeft}\\\",\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"{TimeLeft} seconds\\\"}},{\\\"text\\\":\\\" till you reopen your backpack.\\\"}]\"\n      #Parameter: {CurrentGameMode}, {AllowedGameModes}\n      WrongGameMode: \"You are not allowed to open your backpack in your current game-mode.\"\n    Clean:\n      BackpackCleaned: \"Backpack cleared.\"\n      BackpackCleanedBy: \"Your backpack has been cleared by {DisplayName}&r.\"\n      BackpackCleanedOther: \"{DisplayName}'s&r backpack has been cleared.\"\n    Sort:\n      Sorted: \"Backpack sorted.\"\n    Help:\n      Header: \"&6### Minepacks Commands ###\"\n      Footer: \"&6#############################\"\n    Reload:\n      Reloading: \"&1Reloading Minepacks ...\"\n      Reloaded: \"&1Minepacks reloaded!\"\n    Update:\n      CheckingForUpdates: \"&1Checking for updates ...\"\n      Updated: \"[\\\"\\\",{\\\"text\\\":\\\"Plugin updated, will be loaded on next restart/reload.\\\",\\\"color\\\":\\\"yellow\\\"}]\"\n      NoUpdate: \"[\\\"\\\",{\\\"text\\\":\\\"No plugin update available.\\\",\\\"color\\\":\\\"gold\\\"}]\"\n      UpdateFail: \"[\\\"\\\",{\\\"text\\\":\\\"There was a problem looking for updates! Please check the console!\\\",\\\"color\\\":\\\"red\\\"}]\"\n      # You can change this message if you like to, but don't cry if the link isn't linking to the plugin anymore!\n      UpdateAvailable: \"[{\\\"text\\\":\\\"There is an update available! Please go to \\\\\\\"\\\",\\\"color\\\":\\\"green\\\"},{\\\"text\\\":\\\"${project.url}\\\",\\\"color\\\":\\\"yellow\\\",\\\"underlined\\\":true,\\\"clickEvent\\\":{\\\"action\\\":\\\"open_url\\\",\\\"value\\\":\\\"${project.url}\\\"}},{\\\"text\\\":\\\"\\\\\\\" to download it!\\\"}]\"\n    Backup:\n      Created: \"The backpack has been backed up successfully.\"\n      NoBackpack: \"The player doesn't have a backpack or his backpack is empty.\"\n    Restore:\n      BackupsPerPage: 10\n      Headline: \"[\\\"\\\",{\\\"text\\\":\\\"Backups\\\",\\\"color\\\":\\\"yellow\\\"},{\\\"text\\\":\\\" - \\\",\\\"color\\\":\\\"white\\\"},{\\\"text\\\":\\\"showing page {CurrentPage}/{MaxPage}\\\",\\\"color\\\":\\\"gold\\\"}]\"\n      Footer: \"[{\\\"text\\\":\\\"<<< Previous <<<\\\",\\\"color\\\":\\\"gray\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"run_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}--\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}--\\\"}},{\\\"text\\\":\\\" Showing page {CurrentPage}/{MaxPage} \\\",\\\"color\\\":\\\"gold\\\"},{\\\"text\\\":\\\">>> Next >>>\\\",\\\"color\\\":\\\"gray\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"run_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}++\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}++\\\"}}]\"\n      BackupEntry: \"[\\\"\\\",{\\\"text\\\":\\\"{BackupIdentifier}\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"suggest_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {BackupIdentifier}\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"User: {BackupPlayerName} ({BackupPlayerUUID})\\\\nCreated: {BackupDate}\\\"}}]\"\n      NoValidBackup: \"No backup matching {BackupIdentifier} found\"\n      NoUserToRestoreToFound: \"No valid user to restore backup to found\"\n      # No Json!!!\n      ParameterBackupName: \"backup_name\"\n      # No Json!!!\n      DateFormat: \"yyyy.MM.dd HH:mm:ss\"\n      Restored: \"Backup has been successfully restored.\"\n    InventoryClear:\n      UnknownPlayer: \"&cCould not find player {Name}!\"\n      Cleared: \"Inventory cleared.\"\n      ClearedOther: \"{DisplayName}'s&r inventory has been cleared.\"\n      ClearedOtherTarget: \"Your inventory has been cleared by {DisplayName}&r.\"\n    Pickup:\n      ToggleOn: \"&7Automatic item collection has been toggled &aON&7.\"\n      ToggleOff: \"&7Automatic item collection has been toggled &cOFF&7.\"\n  Commands:\n    HelpFormat: \"[\\\"\\\",{\\\"text\\\":\\\"/{MainCommand} {SubCommand} {Parameters}\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"suggest_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand}\\\"}},{\\\"text\\\":\\\" - \\\",\\\"color\\\":\\\"white\\\"},{\\\"text\\\":\\\"{Description}\\\",\\\"color\\\":\\\"aqua\\\"}]\"\n    PlayerNameVariable: \"player_name\"\n    Description:\n      Backpack: \"Opens your backpack.\"\n      Sort: \"Sorts your backpack.\"\n      Clean: \"Cleans your backpack.\"\n      CleanOthers: \"Cleans the backpack of another player.\"\n      OpenOthers: \"Shows the backpack of another player.\"\n      Reload: \"Reloads the config of the plugin.\"\n      Update: \"Checks for new plugin updates.\"\n      Version: \"Prints the version details about the plugin and its dependencies.\"\n      Backup: \"Creates a backup of a player's backpack.\"\n      BackupEveryone: \"Creates a backup of everyone currently online.\"\n      Restore: \"Restores a backup.\"\n      RestoreList: \"Lists all available backups.\"\n      Help: \"Shows all available commands and their description.\"\n      Migrate: \"Migrates the used database from one type to another.\"\n      Pickup: \"Toggle the state of the automatic pickup when the inventory is full.\"\n\nCommand:\n  Backpack:\n    - backpack\n    - bp\n  Open:\n    - open\n  Sort:\n    - sort\n  Clean:\n    - clean\n    - clear\n    - empty\n  Reload:\n    - reload\n    - restart\n  Update:\n    - update\n  Backup:\n    - backup\n  Restore:\n    - restore\n  ListBackups:\n    - listbackups\n  Version:\n    - version\n  Help:\n    - help\n  InventoryClear:\n    - clear\n    - inventoryclear\n    - clean\n  Pickup:\n    - pickup\n\n# Will be shown in the console during startup\nLanguageName: \"english\"\nAuthor: \"GeorgH93\"\n\n# Language file version. Don't touch it!\nVersion: ${languageFileVersion}"
  },
  {
    "path": "Minepacks/resources/lang/es.yml",
    "content": "# To simplify the customisation and translation process please check out the editor: https://ptp.pcgamingfreaks.at\n\nLanguage:\n  NotFromConsole: \"&cEl comando no puede ser usado desde la consola.\"\n  Ingame:\n    NoPermission: \"&cNo tienes permiso para hacer esto.\"\n    WorldDisabled: \"&cEl uso de las mochilas no está permitido en este mundo.\"\n    NaN: \"[\\\"\\\",{\\\"text\\\":\\\"¡El valor introducido no es un número!\\\",\\\"color\\\":\\\"red\\\"}]\"\n    OwnBackpackClose: \"¡Mochila cerrada!\"\n    OwnBackpackClose_SendMethod: \"action_bar\"\n    #Parameter: {OwnerName}, {OwnerDisplayName}\n    PlayerBackpackClose: \"¡La mochila de {OwnerName} fue cerrada!\"\n    PlayerBackpackClose_SendMethod: \"action_bar\"\n    InvalidBackpack: \"Mochila no válida\"\n    NotAllowedInBackpack: \"&cNo está permitido almacenar el item {ItemName} en la mochila.\"\n    NotAllowedInBackpack_SendMethod: \"action_bar\"\n    DontRemoveShortcut: \"&cNo puedes remover la mochila de tu hotbar o inventario!\"\n    DontRemoveShortcut_SendMethod: \"action_bar\"\n    BackpackShrunk: \"&c¡Tu mochila se ha encogido! ¡Algunos objetos cayeron al suelo!\"\n    Open:\n      #Parameter: {TimeLeft} time in seconds till the backpack can be reopened, {TimeSpanLeft} time formatted as string till the backpack can be reopened\n      Cooldown: \"[{\\\"text\\\":\\\"Por favor, espera \\\",\\\"color\\\":\\\"dark_green\\\"},{\\\"text\\\":\\\"{TimeSpanLeft}\\\",\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"{TimeLeft} segundos\\\"}},{\\\"text\\\":\\\" hasta que vuelvas a abrir tu mochila.\\\"}]\"\n      #Parameter: {CurrentGameMode}, {AllowedGameModes}\n      WrongGameMode: \"No está permitido acceder a las mochilas en tu modo de juego actual.\"\n    Clean:\n      BackpackCleaned: \"Mochila vaciada\"\n      BackpackCleanedBy: \"Su mochila ha sido despejada por {DisplayName}&r.\"\n      BackpackCleanedOther: \"La mochila de {DisplayName}&r ha sido despejada.\"\n    Sort:\n      Sorted: \"Mochila organizada.\"\n    Help:\n      Header: \"&6### Comandos Minepacks ###\"\n      Footer: \"&6#############################\"\n    Reload:\n      Reloading: \"&1Actualizando...\"\n      Reloaded: \"&1¡Actualizado!\"\n    Update:\n      CheckingForUpdates: \"&cComprobando actualizaciones...\"\n      Updated: \"[\\\"\\\",{\\\"text\\\":\\\"Plugin actualizado, será cargado en el siguiente reinicio/parada.\\\",\\\"color\\\":\\\"yellow\\\"}]\"\n      NoUpdate: \"[\\\"\\\",{\\\"text\\\":\\\"No hay actualización del plugin disponible.\\\",\\\"color\\\":\\\"gold\\\"}]\"\n      UpdateFail: \"[\\\"\\\",{\\\"text\\\":\\\"¡Hubo un error comprando actualizaciones! ¡Por favor, revisa la consola!\\\",\\\"color\\\":\\\"red\\\"}]\"\n      # You can change this message if you like to, but don't cry if the link isn't linking to the plugin anymore!\n      UpdateAvailable: \"[{\\\"text\\\":\\\"¡Hay una actualización disponible! ¡Por favor, ve a \\\\\\\"\\\",\\\"color\\\":\\\"green\\\"},{\\\"text\\\":\\\"https://www.spigotmc.org/resources/19286/\\\",\\\"color\\\":\\\"yellow\\\",\\\"underlined\\\":true,\\\"clickEvent\\\":{\\\"action\\\":\\\"open_url\\\",\\\"value\\\":\\\"https://www.spigotmc.org/resources/19286/\\\"}},{\\\"text\\\":\\\"\\\\\\\" para descargarla!\\\"}]\"\n    Backup:\n      Created: \"La mochila fue respaldada con éxito.\"\n      NoBackpack: \"El jugador no tiene mochila o se encuntra vacia.\"\n    Restore:\n      BackupsPerPage: 10\n      Headline: \"[\\\"\\\",{\\\"text\\\":\\\"Backups\\\",\\\"color\\\":\\\"yellow\\\"},{\\\"text\\\":\\\" - \\\",\\\"color\\\":\\\"white\\\"},{\\\"text\\\":\\\"mostrando pág. {CurrentPage}/{MaxPage}\\\",\\\"color\\\":\\\"gold\\\"}]\"\n      Footer: \"[{\\\"text\\\":\\\"<<< Anterior <<<\\\",\\\"color\\\":\\\"gray\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"run_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}--\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}--\\\"}},{\\\"text\\\":\\\" Mostrando pág. {CurrentPage}/{MaxPage} \\\",\\\"color\\\":\\\"gold\\\"},{\\\"text\\\":\\\">>> Siguiente >>>\\\",\\\"color\\\":\\\"gray\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"run_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}++\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}++\\\"}}]\"\n      BackupEntry: \"[\\\"\\\",{\\\"text\\\":\\\"{BackupIdentifier}\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"suggest_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {BackupIdentifier}\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"User: {BackupPlayerName} ({BackupPlayerUUID})\\\\nCreado: {BackupDate}\\\"}}]\"\n      NoValidBackup: \"No se encontraron coincidencias con el backup {BackupIdentifier}.\"\n      NoUserToRestoreToFound: \"Usuario no valido para restaurar la copia de seguridad.\"\n      # No Json!!!\n      ParameterBackupName: \"backup_name\"\n      # No Json!!!\n      DateFormat: \"yyyy.MM.dd HH:mm:ss\"\n      Restored: \"La mochila fue restaurada correctamente.\"\n    InventoryClear:\n      UnknownPlayer: \"&cNo se ha podido encontrar al jugador {Name}!\"\n      Cleared: \"Inventario despejado.\"\n      ClearedOther: \"El inventario de {DisplayName}&r ha sido despejado.\"\n      ClearedOtherTarget: \"Tu inventario ha sido despejado por {DisplayName}&r.\"\n    Pickup:\n      ToggleOn: \"&7La recolección automática de objetos ha sido &aACTIVADA&7.\"\n      ToggleOff: \"&7La recolección automática de objetos ha sido &cDESACTIVADA&7.\"\n  Commands:\n    HelpFormat: \"[\\\"\\\",{\\\"text\\\":\\\"/{MainCommand} {SubCommand} {Parameters}\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"suggest_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand}\\\"}},{\\\"text\\\":\\\" - \\\",\\\"color\\\":\\\"white\\\"},{\\\"text\\\":\\\"{Description}\\\",\\\"color\\\":\\\"aqua\\\"}]\"\n    PlayerNameVariable: \"player_name\"\n    Description:\n      Backpack: \"Abre tu mochila.\"\n      Sort: \"Ordena tu mochila.\"\n      Clean: \"Vacia tu mochila.\"\n      CleanOthers: \"Vacia la mochila de otro jugador.\"\n      OpenOthers: \"Observa la mochila de otro jugador.\"\n      Reload: \"Actualiza la configuración del plugin.\"\n      Update: \"Comprueba las nuevas actualizaciones del plugin.\"\n      Version: \"Imprime los detalles de la versión del plugin y sus dependencias.\"\n      Backup: \"Crea un backup de la mochila de un jugador.\"\n      BackupEveryone: \"Crea una copia de seguridad de todos los que están conectados en ese momento.\"\n      Restore: \"Restaura una mochila.\"\n      RestoreList: \"Lista de todas las mochilas disponibles.\"\n      Help: \"Muestra todos los comandos disponibles y sus descripciones.\"\n      Migrate: \" Migra la base de datos utilizada de un tipo a otro.\"\n      Pickup: \"Alterna el estado de la recolección automática cuando el inventario está lleno.\"\n\nCommand:\n  Backpack:\n    - backpack\n    - bp\n  Open:\n    - open\n  Sort:\n    - sort\n  Clean:\n    - clean\n    - clear\n    - empty\n  Reload:\n    - reload\n    - restart\n  Update:\n    - update\n  Backup:\n    - backup\n  Restore:\n    - restore\n  ListBackups:\n    - listbackups\n  Version:\n    - version\n  Help:\n    - help\n  InventoryClear:\n    - clear\n    - inventoryclear\n    - clean\n  Pickup:\n    - pickup\n\n# Will be shown in the console during startup\nLanguageName: \"es_es\"\nAuthor: \"ThatOverPowered & PostBoxRetinal\"\n\n# Language file version. Don't touch it!\nVersion: 21\n"
  },
  {
    "path": "Minepacks/resources/lang/fr.yml",
    "content": "# To simplify the customisation and translation process please check out the editor: https://ptp.pcgamingfreaks.at\n\nLanguage:\n  NotFromConsole: \"&cCommande inutilisable depuis la console.\"\n  Ingame:\n    NoPermission: \"&cVous n'avez pas la permission !\"\n    WorldDisabled: \"&cL'utilisation du sac à dos n'est pas autorisée dans ce monde.\"\n    NaN: \"[\\\"\\\",{\\\"text\\\":\\\"La valeur saisie n'est pas un nombre !\\\",\\\"color\\\":\\\"red\\\"}]\"\n    OwnBackpackClose: \"Sac à dos fermé !\"\n    OwnBackpackClose_SendMethod: \"action_bar\"\n    #Parameter: {OwnerName}, {OwnerDisplayName}\n    PlayerBackpackClose: \"{OwnerName} sac à dos fermé !\"\n    PlayerBackpackClose_SendMethod: \"action_bar\"\n    InvalidBackpack: \"Sac à dos non valide.\"\n    NotAllowedInBackpack: \"&c{ItemName} n'est pas autorisé dans le sac à dos.\"\n    NotAllowedInBackpack_SendMethod: \"action_bar\"\n    DontRemoveShortcut: \"&cVous ne devez pas supprimer le raccourci de sac à dos de votre inventaire !\"\n    DontRemoveShortcut_SendMethod: \"action_bar\"\n    BackpackShrunk: \"&cVotre sac à dos a rétréci ! Certains objets sont tombés au sol !\"\n    Open:\n      #Parameter: {TimeLeft} time in seconds till the backpack can be reopened, {TimeSpanLeft} time formatted as string till the backpack can be reopened\n      Cooldown: \"[{\\\"text\\\":\\\"Veuillez patienter \\\",\\\"color\\\":\\\"dark_green\\\"},{\\\"text\\\":\\\"{TimeSpanLeft}\\\",\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"{TimeLeft} secondes\\\"}},{\\\"text\\\":\\\" till you reopen your backpack.\\\"}]\"\n      #Parameter: {CurrentGameMode}, {AllowedGameModes}\n      WrongGameMode: \"Vous n'êtes pas autorisé à ouvrir votre sac à dos dans votre mode de jeu actuel.\"\n    Clean:\n      BackpackCleaned: \"Sac à dos nettoyé.\"\n      BackpackCleanedBy: \"Votre sac à dos à été nettoyé par {DisplayName}&r.\"\n      BackpackCleanedOther: \"Sac à dos de {DisplayName} &rnettoyé.\"\n    Sort:\n      Sorted: \"Sac à dos trié.\"\n    Help:\n      Header: \"&6### Minepacks Commandes ###\"\n      Footer: \"&6#############################\"\n    Reload:\n      Reloading: \"&1Le plugin est en cours de redémarrage ...\"\n      Reloaded: \"&1Le plugin à été rechargé !\"\n    Update:\n      CheckingForUpdates: \"&1Vérification des mises à jour ...\"\n      Updated: \"[\\\"\\\",{\\\"text\\\":\\\"Plugin mis à jour, sera chargé au prochain redémarrage/rechargement.\\\",\\\"color\\\":\\\"yellow\\\"}]\"\n      NoUpdate: \"[\\\"\\\",{\\\"text\\\":\\\"Aucune mise à jour du plugin disponible.\\\",\\\"color\\\":\\\"gold\\\"}]\"\n      UpdateFail: \"[\\\"\\\",{\\\"text\\\":\\\"Il y a eu un problème de recherche de mises à jour ! Vérifiez la console s'il vous plaît !\\\",\\\"color\\\":\\\"red\\\"}]\"\n      # You can change this message if you like to, but don't cry if the link isn't linking to the plugin anymore!\n      UpdateAvailable: \"[{\\\"text\\\":\\\"Il y a une mise à jour disponible ! Veuillez vous rendre à l'adresse suivante \\\\\\\"\\\",\\\"color\\\":\\\"green\\\"},{\\\"text\\\":\\\"${project.url}\\\",\\\"color\\\":\\\"yellow\\\",\\\"underlined\\\":true,\\\"clickEvent\\\":{\\\"action\\\":\\\"open_url\\\",\\\"value\\\":\\\"${project.url}\\\"}},{\\\"text\\\":\\\"\\\\\\\" pour la télécharger !\\\"}]\"\n    Backup:\n      Created: \"Le sac à dos a été sauvegardé avec succès.\"\n      NoBackpack: \"Le joueur n'a pas de sac à dos ou son sac à dos est vide.\"\n    Restore:\n      BackupsPerPage: 10\n      Headline: \"[\\\"\\\",{\\\"text\\\":\\\"Backups\\\",\\\"color\\\":\\\"yellow\\\"},{\\\"text\\\":\\\" - \\\",\\\"color\\\":\\\"white\\\"},{\\\"text\\\":\\\"Page {CurrentPage}/{MaxPage}\\\",\\\"color\\\":\\\"gold\\\"}]\"\n      Footer: \"[{\\\"text\\\":\\\"<<< Previous <<<\\\",\\\"color\\\":\\\"gray\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"run_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}--\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}--\\\"}},{\\\"text\\\":\\\" Page {CurrentPage}/{MaxPage} \\\",\\\"color\\\":\\\"gold\\\"},{\\\"text\\\":\\\">>> Next >>>\\\",\\\"color\\\":\\\"gray\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"run_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}++\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}++\\\"}}]\"\n      BackupEntry: \"[\\\"\\\",{\\\"text\\\":\\\"{BackupIdentifier}\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"suggest_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {BackupIdentifier}\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"Utilisateur: {BackupPlayerName} ({BackupPlayerUUID})\\\\nCréé: {BackupDate}\\\"}}]\"\n      NoValidBackup: \"Aucune correspondance des sauvegardes {BackupIdentifier} trouvé.\"\n      NoUserToRestoreToFound: \"Aucun utilisateur valide pour restaurer la sauvegarde sur trouvée\"\n      # No Json!!!\n      ParameterBackupName: \"backup_name\"\n      # No Json!!!\n      DateFormat: \"dd.MM.yyyy HH:mm:ss\"\n      Restored: \"La sauvegarde a été restaurée avec succès.\"\n    InventoryClear:\n      UnknownPlayer: \"&cImpossible de trouver le joueur {Name}!\"\n      Cleared: \"Inventaire nettoyé.\"\n      ClearedOther: \"Inventaire de {DisplayName} &rnettoyé.\"\n      ClearedOtherTarget: \"Votre inventaire a été effacé par {DisplayName}&r.\"\n    Pickup:\n      ToggleOn: \"&7Le ramassage automatique à été défini sur: &aON&7.\"\n      ToggleOff: \"&7Le ramassage automatique à été défini sur: &cOFF&7.\"\n  Commands:\n    HelpFormat: \"[\\\"\\\",{\\\"text\\\":\\\"/{MainCommand} {SubCommand} {Parameters}\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"suggest_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand}\\\"}},{\\\"text\\\":\\\" - \\\",\\\"color\\\":\\\"white\\\"},{\\\"text\\\":\\\"{Description}\\\",\\\"color\\\":\\\"aqua\\\"}]\"\n    PlayerNameVariable: \"player_name\"\n    Description:\n      Backpack: \"Ouvre votre sac à dos.\"\n      Sort: \"Trie votre sac à dos.\"\n      Clean: \"Nettoie votre sac à dos.\"\n      CleanOthers: \"Nettoie le sac à dos d'un autre joueur.\"\n      OpenOthers: \"Montre le sac à dos d'un autre joueur.\"\n      Reload: \"Recharge la configuration du plugin.\"\n      Update: \"Vérifie les nouvelles mises à jour des plugins.\"\n      Version: \"Imprime les détails de la version du plugin et de ses dépendances.\"\n      Backup: \"Crée une sauvegarde d'un sac à dos de joueur.\"\n      BackupEveryone: \"Crée une backup de tout les backpacks.\"\n      Restore: \"Restaure une sauvegarde.\"\n      RestoreList: \"Liste toutes les sauvegardes disponibles.\"\n      Help: \"Affiche toutes les commandes disponibles et leur description.\"\n      Migrate: \"Migre la base de données utilisée d'un type à un autre.\"\n      Pickup: \"Switch l'état de ramassage automatique (ON/OFF).\"\n\nCommand:\n  Backpack:\n    - backpack\n    - bp\n  Open:\n    - open\n  Sort:\n    - sort\n  Clean:\n    - clean\n    - clear\n    - empty\n  Reload:\n    - reload\n    - restart\n  Update:\n    - update\n  Backup:\n    - backup\n  Restore:\n    - restore\n  ListBackups:\n    - listbackups\n  Version:\n    - version\n  Help:\n    - help\n  InventoryClear:\n    - clear\n    - inventoryclear\n    - clean\n  Pickup:\n    - pickup\n\n# Will be shown in the console during startup\nLanguageName: \"Français\"\nAuthor: \"HiiRaZ & Sniper_TVmc\"\n\n# Language file version. Don't touch it!\nVersion: 21\n"
  },
  {
    "path": "Minepacks/resources/lang/hu.yml",
    "content": "# To simplify the customisation and the translation process please check out the editor: https://ptp.pcgamingfreaks.at\n\nLanguage:\n  NotFromConsole: \"&cA parancs nem használható konzolból.\"\n  Ingame:\n    NoPermission: \"&cNincs jogod ezt megtenni.\"\n    WorldDisabled: \"&cA hátizsák használata nem engedélyezett ebben a világban.\"\n    NaN: \"[\\\"\\\",{\\\"text\\\":\\\"A beírt érték nem egy szám!\\\",\\\"color\\\":\\\"red\\\"}]\"\n    OwnBackpackClose: \"Hátizsák bezárva!\"\n    OwnBackpackClose_SendMethod: \"action_bar\"\n    #Parameter: {OwnerName}, {OwnerDisplayName}\n    PlayerBackpackClose: \"{OwnerName} hátizsákja bezárva!\"\n    PlayerBackpackClose_SendMethod: \"action_bar\"\n    InvalidBackpack: \"Érvénytelen hátizsák.\"\n    NotAllowedInBackpack: \"&c{ItemName} nem engedélyezett a hátizsákban.\"\n    NotAllowedInBackpack_SendMethod: \"action_bar\"\n    DontRemoveShortcut: \"&cNem szabad eltávolítani a hátizsák ikonját az eszköztárból!\"\n    DontRemoveShortcut_SendMethod: \"action_bar\"\n    BackpackShrunk: \"&cA hátizsákod összement! Néhány tárgy a földre esett!\"\n    Open:\n      #Parameter: {TimeLeft} time in seconds till the backpack can be reopened, {TimeSpanLeft} time formatted as string till the backpack can be reopened\n      Cooldown: \"[{\\\"text\\\":\\\"Várj \\\",\\\"color\\\":\\\"dark_green\\\"},{\\\"text\\\":\\\"{TimeSpanLeft}\\\",\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"{TimeLeft} másodperc\\\"}},{\\\"text\\\":\\\", amíg újra nem nyitja a hátizsákot.\\\"}]\"\n      #Parameter: {CurrentGameMode}, {AllowedGameModes}\n      WrongGameMode: \"A jelenlegi játékmódban nem engedélyezett kinyitni a hátizsákot.\"\n    Clean:\n      BackpackCleaned: \"Hátizsák kitisztítva.\"\n      BackpackCleanedBy: \"A hátizsákodat {DisplayName}&r tisztította ki.\"\n      BackpackCleanedOther: \"{DisplayName}&r hátizsákja ki lett tisztítva.\"\n    Sort:\n      Sorted: \"Hátizsák rendezve.\"\n    Help:\n      Header: \"&6### Minepacks parancsok ###\"\n      Footer: \"&6#############################\"\n    Reload:\n      Reloading: \"&1Minepacks újratöltése ...\"\n      Reloaded: \"&1Minepacks újratöltve!\"\n    Update:\n      CheckingForUpdates: \"&1Frissítések ellenőrzése ...\"\n      Updated: \"[\\\"\\\",{\\\"text\\\":\\\"Plugin frissítve, be lesz töltve a következő újraindítás/újratöltésnél.\\\",\\\"color\\\":\\\"yellow\\\"}]\"\n      NoUpdate: \"[\\\"\\\",{\\\"text\\\":\\\"Nincs plugin frissítés elérhető.\\\",\\\"color\\\":\\\"gold\\\"}]\"\n      UpdateFail: \"[\\\"\\\",{\\\"text\\\":\\\"Probléma volt a frissítések keresésekor! Kérlek, ellenőrizd a konzolt!\\\",\\\"color\\\":\\\"red\\\"}]\"\n      # You can change this message if you like to, but don't cry if the link isn't linking to the plugin anymore!\n      UpdateAvailable: \"[{\\\"text\\\":\\\"Van egy frissítés elérhető! Menj a(z) \\\\\\\"\\\",\\\"color\\\":\\\"green\\\"},{\\\"text\\\":\\\"${project.url}\\\",\\\"color\\\":\\\"yellow\\\",\\\"underlined\\\":true,\\\"clickEvent\\\":{\\\"action\\\":\\\"open_url\\\",\\\"value\\\":\\\"${project.url}\\\"}},{\\\"text\\\":\\\"\\\\\\\", hogy letöltsd!\\\"}]\"\n    Backup:\n      Created: \"A hátizsák sikeresen mentésre került.\"\n      NoBackpack: \"A játékosnak nincs egy hátizsákja vagy a hátizsákja üres.\"\n    Restore:\n      BackupsPerPage: 10\n      Headline: \"[\\\"\\\",{\\\"text\\\":\\\"Mentések\\\",\\\"color\\\":\\\"yellow\\\"},{\\\"text\\\":\\\" - \\\",\\\"color\\\":\\\"white\\\"},{\\\"text\\\":\\\"oldal {CurrentPage}/{MaxPage}\\\",\\\"color\\\":\\\"gold\\\"}]\"\n      Footer: \"[{\\\"text\\\":\\\"<<< Előző <<<\\\",\\\"color\\\":\\\"gray\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"run_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}--\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}--\\\"}},{\\\"text\\\":\\\" Oldal {CurrentPage}/{MaxPage} \\\",\\\"color\\\":\\\"gold\\\"},{\\\"text\\\":\\\">>> Következő >>>\\\",\\\"color\\\":\\\"gray\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"run_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}++\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}++\\\"}}]\"\n      BackupEntry: \"[\\\"\\\",{\\\"text\\\":\\\"{BackupIdentifier}\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"suggest_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {BackupIdentifier}\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"Felhasználó: {BackupPlayerName} ({BackupPlayerUUID})\\\\nLétrehozva: {BackupDate}\\\"}}]\"\n      NoValidBackup: \"Nincs mentés találva {BackupIdentifier}\"\n      NoUserToRestoreToFound: \"Nincs érvényes felhasználó, aki visszaállíthatja a biztonsági másolatot\"\n      # No Json!!!\n      ParameterBackupName: \"backup_name\"\n      # No Json!!!\n      DateFormat: \"yyyy.MM.dd HH:mm:ss\"\n      Restored: \"Biztonsági mentés sikeresen visszaállítva.\"\n    InventoryClear:\n      UnknownPlayer: \"&cNem található a játékos {Name}!\"\n      Cleared: \"Leltár törölve.\"\n      ClearedOther: \"{DisplayName}&r leltára törölve lett.\"\n      ClearedOtherTarget: \"A leltárodat {DisplayName}&r törölte.\"\n    Pickup:\n      ToggleOn: \"&7Az automatikus tárgyfelvétel &aBEKAPCSOLVA&7.\"\n      ToggleOff: \"&7Az automatikus tárgyfelvétel &cKIKAPOCSOLVA&7.\"\n  Commands:\n    HelpFormat: \"[\\\"\\\",{\\\"text\\\":\\\"/{MainCommand} {SubCommand} {Parameters}\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"suggest_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand}\\\"}},{\\\"text\\\":\\\" - \\\",\\\"color\\\":\\\"white\\\"},{\\\"text\\\":\\\"{Description}\\\",\\\"color\\\":\\\"aqua\\\"}]\"\n    PlayerNameVariable: \"player_name\"\n    Description:\n      Backpack: \"Megnyitja a hátizsákod.\"\n      Clean: \"Törli a hátizsákod.\"\n      CleanOthers: \"Törli más játékosok hátizsákját.\"\n      OpenOthers: \"Megmutatja más játékosok hátizsákját.\"\n      Reload: \"Újratölti a konfigot és a plugint.\"\n      Update: \"Ellenőrzi a plugin új frissítéseit.\"\n      Version: \"Kiírja a plugin verziójának részleteit és annak függőségeit.\"\n      Backup: \"Létrehoz egy mentést a játékosok hátizsákjáról.\"\n      BackupEveryone: \"Biztonsági mentést készít minden jelenleg online lévő személyről.\"\n      Restore: \"Visszaállít egy mentést.\"\n      RestoreList: \"Listázza az összes elérhető mentéseket.\"\n      Help: \"Megmutatja az összes elérhető parancsokat és azok leírását.\"\n      Migrate: \"A használt adatbázist áttelepíti egyik típusról a másikra.\"\n      Pickup: \"Átváltja az automatikus felvétel állapotát, ha a leltár tele van.\"\n\nCommand:\n  Backpack:\n    - backpack\n    - bp\n  Open:\n    - open\n  Sort:\n    - sort\n  Clean:\n    - clean\n    - clear\n    - empty\n  Reload:\n    - reload\n    - restart\n  Update:\n    - update\n  Backup:\n    - backup\n  Restore:\n    - restore\n  ListBackups:\n    - listbackups\n  Version:\n    - version\n  Help:\n    - help\n  InventoryClear:\n    - clear\n    - inventoryclear\n    - clean\n  Pickup:\n    - pickup\n\n# Will be shown in the console during startup\nLanguageName: \"hungarian\"\nAuthor: \"montlikadani\"\n\n# Language file version. Don't touch it!\nVersion: 21\n"
  },
  {
    "path": "Minepacks/resources/lang/it.yml",
    "content": "# To simplify the customisation and the translation process please check out the editor: https://ptp.pcgamingfreaks.at\n\nLanguage:\n  NotFromConsole: \"&cComando non utilizzabile dalla console.\"\n  Ingame:\n    NoPermission: \"&cPermesso negato.\"\n    WorldDisabled: \"&cL'uso dei backpack non è autorizzato in questo mondo.\"\n    NaN: \"[\\\"\\\",{\\\"text\\\":\\\"Il valore inserito non è un numero!\\\",\\\"color\\\":\\\"red\\\"}]\"\n    OwnBackpackClose: \"Backpack chiuso!\"\n    OwnBackpackClose_SendMethod: \"action_bar\"\n    #Parameter: {OwnerName}, {OwnerDisplayName}\n    PlayerBackpackClose: \"Backpack di {OwnerName} chiuso!\"\n    PlayerBackpackClose_SendMethod: \"action_bar\"\n    InvalidBackpack: \"Backpack invalido.\"\n    NotAllowedInBackpack: \"&c{ItemName} non può essere inserito nel backpack.\"\n    NotAllowedInBackpack_SendMethod: \"action_bar\"\n    DontRemoveShortcut: \"&cNon puoi rimuovere il backpack dalla hotbar o inventario!\"\n    DontRemoveShortcut_SendMethod: \"action_bar\"\n    BackpackShrunk: \"&cIl tuo zaino si è ristretto! Alcuni oggetti sono caduti a terra!\"\n    Open:\n      #Parameter: {TimeLeft} secondi per riaprire il backpack, {TimeSpanLeft} time formatted as string till the backpack can be reopened\n      Cooldown: \"[{\\\"text\\\":\\\"Perfavore aspettaret \\\",\\\"color\\\":\\\"dark_green\\\"},{\\\"text\\\":\\\"{TimeSpanLeft}\\\",\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"{TimeLeft} secondi\\\"}},{\\\"text\\\":\\\" per riaprire il backpack.\\\"}]\"\n      #Parameter: {CurrentGameMode}, {AllowedGameModes}\n      WrongGameMode: \"Non puoi aprire il backpack in questa game-mode.\"\n    Clean:\n      BackpackCleaned: \"Backpack svuotato.\"\n      BackpackCleanedBy: \"Il tuo backpack è stato svuotato da {DisplayName}&r.\"\n      BackpackCleanedOther: \"Il backpack di {DisplayName}&r è stato svuotato.\"\n    Sort:\n      Sorted: \"Backpack organizzato.\"\n    Help:\n      Header: \"&6###  Comandi Minepacks  ###\"\n      Footer: \"&6#############################\"\n    Reload:\n      Reloading: \"&1Ricaricando Minepacks ...\"\n      Reloaded: \"&1Minepacks ricaricati!\"\n    Update:\n      CheckingForUpdates: \"&1Cercando aggiornamenti ...\"\n      Updated: \"[\\\"\\\",{\\\"text\\\":\\\"Plugin aggiornato, sarà caricato al prossimo riavvio/reload.\\\",\\\"color\\\":\\\"yellow\\\"}]\"\n      NoUpdate: \"[\\\"\\\",{\\\"text\\\":\\\"Nessun aggiornamento disponibile.\\\",\\\"color\\\":\\\"gold\\\"}]\"\n      UpdateFail: \"[\\\"\\\",{\\\"text\\\":\\\"C'è stato un problema per trovare gli aggiornamenti! Perfavore controllare la console!\\\",\\\"color\\\":\\\"red\\\"}]\"\n      # You can change this message if you like to, but don't cry if the link isn't linking to the plugin anymore!\n      UpdateAvailable: \"[{\\\"text\\\":\\\"C'è un aggiornamento disponibile! Perfavore usa \\\\\\\"\\\",\\\"color\\\":\\\"green\\\"},{\\\"text\\\":\\\"${project.url}\\\",\\\"color\\\":\\\"yellow\\\",\\\"underlined\\\":true,\\\"clickEvent\\\":{\\\"action\\\":\\\"open_url\\\",\\\"value\\\":\\\"${project.url}\\\"}},{\\\"text\\\":\\\"\\\\\\\" per scaricarlo!\\\"}]\"\n    Backup:\n      Created: \"Backup del backpack eseguito con successo.\"\n      NoBackpack: \"Il giocatore non ha un backpack o è vuoto.\"\n    Restore:\n      BackupsPerPage: 10\n      Headline: \"[\\\"\\\",{\\\"text\\\":\\\"Backup\\\",\\\"color\\\":\\\"yellow\\\"},{\\\"text\\\":\\\" - \\\",\\\"color\\\":\\\"white\\\"},{\\\"text\\\":\\\"pagina {CurrentPage}/{MaxPage}\\\",\\\"color\\\":\\\"gold\\\"}]\"\n      Footer: \"[{\\\"text\\\":\\\"<<< Precedente <<<\\\",\\\"color\\\":\\\"gray\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"run_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}--\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}--\\\"}},{\\\"text\\\":\\\" Pagina {CurrentPage}/{MaxPage} \\\",\\\"color\\\":\\\"gold\\\"},{\\\"text\\\":\\\">>> Prossimo >>>\\\",\\\"color\\\":\\\"gray\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"run_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}++\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}++\\\"}}]\"\n      BackupEntry: \"[\\\"\\\",{\\\"text\\\":\\\"{BackupIdentifier}\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"suggest_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {BackupIdentifier}\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"Utente: {BackupPlayerName} ({BackupPlayerUUID})\\\\nData di creazione: {BackupDate}\\\"}}]\"\n      NoValidBackup: \"Nessun backup per {BackupIdentifier} trovato\"\n      NoUserToRestoreToFound: \"Nessun utente valido per il backup trovato\"\n      # No Json!!!\n      ParameterBackupName: \"backup_name\"\n      # No Json!!!\n      DateFormat: \"yyyy.MM.dd HH:mm:ss\"\n      Restored: \"Il backup è stato ripristinato con successo.\"\n    InventoryClear:\n      UnknownPlayer: \"&cImpossibile trovare l'utente {Name}!\"\n      Cleared: \"Inventario ripulito.\"\n      ClearedOther: \"L'inventario di {DisplayName}&r è stato ripulito.\"\n      ClearedOtherTarget: \"Il tuo inventario è stato ripulito da {DisplayName}&r.\"\n    Pickup:\n      ToggleOn: \"&7La raccolta automatica degli oggetti è stata &aATTIVATA&7.\"\n      ToggleOff: \"&7La raccolta automatica degli oggetti è stata &cDISATTIVATA&7.\"\n  Commands:\n    HelpFormat: \"[\\\"\\\",{\\\"text\\\":\\\"/{MainCommand} {SubCommand} {Parameters}\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"suggest_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand}\\\"}},{\\\"text\\\":\\\" - \\\",\\\"color\\\":\\\"white\\\"},{\\\"text\\\":\\\"{Description}\\\",\\\"color\\\":\\\"aqua\\\"}]\"\n    PlayerNameVariable: \"player_name\"\n    Description:\n      Backpack: \"Apre il tuo backpack.\"\n      Sort: \"Organizza il tuo backpack.\"\n      Clean: \"Ripulisce il tuo backpack.\"\n      CleanOthers: \"Ripulisce il backpack di un altro utente.\"\n      OpenOthers: \"Mostra il backpack di un altro utente.\"\n      Reload: \"Reicarica il plugin.\"\n      Update: \"Controlla per nuovi aggiornamenti.\"\n      Version: \"Mostra la versione del plugin e le sue relative dipendenze.\"\n      Backup: \"Crea un backup del backpack dell'utente.\"\n      BackupEveryone: \"Crea un backup di tutti gli utenti attualmente online.\"\n      Restore: \"Ripristina un backup.\"\n      RestoreList: \"Mostra tutti i backup disponibili.\"\n      Help: \"Mostra tutti i comandi disponibili e le loro descrizioni.\"\n      Migrate: \"Migra il database da un utente all'altro.\"\n      Pickup: \"Attiva/disattiva la raccolta automatica quando l'inventario è pieno.\"\n\nCommand:\n  Backpack:\n    - backpack\n    - bp\n  Open:\n    - open\n  Sort:\n    - sort\n  Clean:\n    - clean\n    - clear\n    - empty\n  Reload:\n    - reload\n    - restart\n  Update:\n    - update\n  Backup:\n    - backup\n  Restore:\n    - restore\n  ListBackups:\n    - listbackups\n  Version:\n    - version\n  Help:\n    - help\n  InventoryClear:\n    - clear\n    - inventoryclear\n    - clean\n  Pickup:\n    - pickup\n\n# Will be shown in the console during startup\nLanguageName: \"italiano\"\nAuthor: \"Mastory_Md5\"\n\n# Language file version. Don't touch it!\nVersion: 21\n"
  },
  {
    "path": "Minepacks/resources/lang/ja.yml",
    "content": "# To simplify the customisation and the translation process please check out the editor: https://ptp.pcgamingfreaks.at\n\nLanguage:\n  NotFromConsole: \"&cコマンドはコンソールから使用できません。\"\n  Ingame:\n    NoPermission: \"&cそれを実行する権限がありません。\"\n    WorldDisabled: \"&cこのワールドでバックパックの使用は許可されていません。\"\n    NaN: \"[\\\"\\\",{\\\"text\\\":\\\"入力された値は数値ではありません。\\\",\\\"color\\\":\\\"red\\\"}]\"\n    OwnBackpackClose: \"バックパックを閉じました！\"\n    OwnBackpackClose_SendMethod: \"action_bar\"\n    #Parameter: {OwnerName}, {OwnerDisplayName}\n    PlayerBackpackClose: \"{OwnerName}のバックパックを閉じました！\"\n    PlayerBackpackClose_SendMethod: \"action_bar\"\n    InvalidBackpack: \"バックパックが無効です。\"\n    NotAllowedInBackpack: \"&c{ItemName}はバックパックに入れることができません。\"\n    NotAllowedInBackpack_SendMethod: \"action_bar\"\n    DontRemoveShortcut: \"&cバックパックショートカットをインベントリから削除しないでください！\"\n    DontRemoveShortcut_SendMethod: \"action_bar\"\n    BackpackShrunk: \"&cバックパックが縮小しました！一部のアイテムが地面に落ちました！\"\n    Open:\n      #Parameter: {TimeLeft} time in seconds till the backpack can be reopened, {TimeSpanLeft} time formatted as string till the backpack can be reopened\n      Cooldown: \"&2バックパックを開くまで{TimeSpanLeft}秒待ってください。\"\n      #Parameter: {CurrentGameMode}, {AllowedGameModes}\n      WrongGameMode: \"現在のゲームモードでバックパックを開くことは許可されていません。\"\n    Clean:\n      BackpackCleaned: \"バックパックを削除しました。\"\n      BackpackCleanedBy: \"あなたのバックアップは{DisplayName}&rによって削除されました。\"\n      BackpackCleanedOther: \"{DisplayName}&rのバックパックは削除されました。\"\n    Sort:\n      Sorted: \"バックパックがソートされました。\"\n    Help:\n      Header: \"&6##### Minepacks コマンド #####\"\n      Footer: \"&6\"\n    Reload:\n      Reloading: \"&1リロード中...\"\n      Reloaded: \"&1リロード！\"\n    Update:\n      CheckingForUpdates: \"&1アップデートの確認中...\"\n      Updated: \"[\\\"\\\",{\\\"text\\\":\\\"更新されたプラグインは、次回の再起動/リロード時にロードされます。\\\",\\\"color\\\":\\\"yellow\\\"}]\"\n      NoUpdate: \"[\\\"\\\",{\\\"text\\\":\\\"利用可能なプラグインの更新はありません。\\\",\\\"color\\\":\\\"gold\\\"}]\"\n      UpdateFail: \"[\\\"\\\",{\\\"text\\\":\\\"アップデートの確認に問題がありました！コンソールを確認してください。\\\",\\\"color\\\":\\\"red\\\"}]\"\n      # You can change this message if you like to, but don't cry if the link isn't linking to the plugin anymore!\n      UpdateAvailable: \"[{\\\"text\\\":\\\"利用可能なアップデートがあります！\\\\\\\"\\\",\\\"color\\\":\\\"green\\\"},{\\\"text\\\":\\\"https://www.spigotmc.org/resources/19286/\\\",\\\"color\\\":\\\"yellow\\\",\\\"underlined\\\":true,\\\"clickEvent\\\":{\\\"action\\\":\\\"open_url\\\",\\\"value\\\":\\\"https://www.spigotmc.org/resources/19286/\\\"}},{\\\"text\\\":\\\"\\\\\\\" からダウンロードして下さい。\\\"}]\"\n    Backup:\n      Created: \"バックパックは正常にバックアップされました。\"\n      NoBackpack: \"プレイヤーはバックパックを持っていないか、バックパックが空です。\"\n    Restore:\n      BackupsPerPage: 10\n      Headline: \"[\\\"\\\",{\\\"text\\\":\\\"Backups\\\",\\\"color\\\":\\\"yellow\\\"},{\\\"text\\\":\\\" - \\\",\\\"color\\\":\\\"white\\\"},{\\\"text\\\":\\\"表示ページ {CurrentPage}/{MaxPage}\\\",\\\"color\\\":\\\"gold\\\"}]\"\n      Footer: \"[{\\\"text\\\":\\\"<<< 前 <<<\\\",\\\"color\\\":\\\"gray\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"run_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}--\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}--\\\"}},{\\\"text\\\":\\\" 表示ページ {CurrentPage}/{MaxPage} \\\",\\\"color\\\":\\\"gold\\\"},{\\\"text\\\":\\\">>> 次 >>>\\\",\\\"color\\\":\\\"gray\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"run_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}++\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}++\\\"}}]\"\n      BackupEntry: \"[\\\"\\\",{\\\"text\\\":\\\"{BackupIdentifier}\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"suggest_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {BackupIdentifier}\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"ユーザー：{BackupPlayerName} ({BackupPlayerUUID})\\\\n作成日：{BackupDate}\\\"}}]\"\n      NoValidBackup: \"{BackupIdentifier}に一致するバックアップが見つかりません\"\n      NoUserToRestoreToFound: \"バックアップを復元するための有効なユーザーが見つかりません\"\n      # No Json!!!\n      ParameterBackupName: \"backup_name\"\n      # No Json!!!\n      DateFormat: \"yyyy.MM.dd HH:mm:ss\"\n      Restored: \"バックアップは正常に復元されました。\"\n    InventoryClear:\n      UnknownPlayer: \"&c{Name}を見つけられませんでした！\"\n      Cleared: \"インベントリが削除されました。\"\n      ClearedOther: \"{DisplayName}&rのインベントリを削除しました。\"\n      ClearedOtherTarget: \"あなたのインベントリは{DisplayName}&rによって削除されました。\"\n    Pickup:\n      ToggleOn: \"&7自動アイテム収集が&aオン&7になりました。\"\n      ToggleOff: \"&7自動アイテム収集が&cオフ&7になりました。\"\n  Commands:\n    HelpFormat: \"[\\\"\\\",{\\\"text\\\":\\\"/{MainCommand} {SubCommand} {Parameters}\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"suggest_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand}\\\"}},{\\\"text\\\":\\\" - \\\",\\\"color\\\":\\\"white\\\"},{\\\"text\\\":\\\"{Description}\\\",\\\"color\\\":\\\"aqua\\\"}]\"\n    PlayerNameVariable: \"player_name\"\n    Description:\n      Backpack: \"バックパックを開く。\"\n      Sort: \"バックパックはソートされました。\"\n      Clean: \"バックパックを削除する。\"\n      CleanOthers: \"他のプレイヤーのバックパックを削除する。\"\n      OpenOthers: \"他のプレイヤーのバックパックを開く。\"\n      Reload: \"プラグインのコンフィグをリロードしました。\"\n      Update: \"新しいアップデートを確認します。\"\n      Version: \"プラグインと依存関係に関するバージョンの詳細を表示します。\"\n      Backup: \"プレイヤーのバックパックのバックアップを作成します。\"\n      BackupEveryone: \"現在オンラインの全員のバックアップを作成します。\"\n      Restore: \"バックアップから復元します。\"\n      RestoreList: \"利用可能なすべてのバックアップを一覧表示します。\"\n      Help: \"利用可能なすべてのコマンドとその説明を表示します。\"\n      Migrate: \"使用されているデータベースをあるタイプから別のタイプに移行しました。\"\n      Pickup: \"インベントリがいっぱいの時の自動ピックアップの状態を切り替えます。\"\n\nCommand:\n  Backpack:\n    - backpack\n    - bp\n  Open:\n    - open\n  Sort:\n    - sort\n  Clean:\n    - clean\n    - clear\n    - empty\n  Reload:\n    - reload\n    - restart\n  Update:\n    - update\n  Backup:\n    - backup\n  Restore:\n    - restore\n  ListBackups:\n    - listbackups\n  Version:\n    - version\n  Help:\n    - help\n  InventoryClear:\n    - clear\n    - inventoryclear\n    - clean\n  Pickup:\n    - pickup\n\n# Will be shown in the console during startup\nLanguageName: \"japanese\"\nAuthor: \"ethernetcat\"\n\n# Language file version. Don't touch it!\nVersion: 21"
  },
  {
    "path": "Minepacks/resources/lang/lt.yml",
    "content": "#Teisingam vertimui naudokite: https://ptp.pcgamingfreaks.at Use UTF8 instead\n\nLanguage:\n  NotFromConsole: \"&cKomanda negali būti naudojama konsolėje!\"\n  Ingame:\n    NoPermission: \"&cApgailestaujame, tačiau Jūs neturite tam leidimoĄ\"\n    WorldDisabled: \"&cKuprinė negali būti naudojama šiame pasaulyje!\"\n    NaN: \"[\\\"\\\",{\\\"text\\\":\\\"Įvestas skaičius nėra skaičius!\\\",\\\"color\\\":\\\"red\\\"}]\"\n    OwnBackpackClose: \"Kuprinė uždaryta!\"\n    OwnBackpackClose_SendMethod: \"action_bar\"\n    #Nustatymai: {OwnerName}, {OwnerDisplayName}\n    PlayerBackpackClose: \"{OwnerName} uždarė kuprinę!\"\n    PlayerBackpackClose_SendMethod: \"action_bar\"\n    InvalidBackpack: \"Kuprinės klaida!\"\n    NotAllowedInBackpack: \"&c{ItemName} draudžiama dėti į kuprinę!\"\n    NotAllowedInBackpack_SendMethod: \"action_bar\"\n    DontRemoveShortcut: \"&cPrašome neišesti kuprinės iš savo inventoriaus!\"\n    DontRemoveShortcut_SendMethod: \"action_bar\"\n    BackpackShrunk: \"&cTavo kuprinė susitraukė! Kai kurie daiktai nukrito ant žemės!\"\n    Open:\n      #Nustatymai: {TimeLeft} laikas kada vėl bus galima atidaryti, {TimeSpanLeft} laikas formatuotas kuprinės atidarymui\n      Cooldown: \"[{\\\"text\\\":\\\"Prašome palaukti \\\",\\\"color\\\":\\\"dark_green\\\"},{\\\"text\\\":\\\"{TimeSpanLeft}\\\",\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"{TimeLeft} s\\\"}},{\\\"text\\\":\\\" kol vėl galėsite naudoti kuprinę!\\\"}]\"\n      #Parameter: {CurrentGameMode}, {AllowedGameModes}\n      WrongGameMode: \"Najudojantis kūrybiniu rėžimu kuprine naudotis draudžiama!\"\n    Clean:\n      BackpackCleaned: \"Kuprinė išvalyta!\"\n      BackpackCleanedBy: \"Jūsų kuprinę išvalė: {DisplayName}&r.\"\n      BackpackCleanedOther: \"{DisplayName} &r išvalė kuprinę1\"\n    Sort:\n      Sorted: \"Kuprinėje esantys daiktai surūšiuoti sėkmingai!\"\n    Help:\n      Header: \"&6###   Kuprinių Komandos   ###\"\n      Footer: \"&6#############################\"\n    Reload:\n      Reloading: \"&1Perkraunamos kuprinės ...\"\n      Reloaded: \"&1Kuprinė perkrautos!\"\n    Update:\n      CheckingForUpdates: \"&1Tikrinami kuprinių sistemos atnaujinimai ...\"\n      Updated: \"[\\\"\\\",{\\\"text\\\":\\\"Kuprinių sistema atnaujinta, norint kad įsigaliotų sistemos pakeitimai privalote perkrauti serverį!\\\",\\\"color\\\":\\\"yellow\\\"}]\"\n      NoUpdate: \"[\\\"\\\",{\\\"text\\\":\\\"Nėra kuprinių sistemos atnaujinimų, Jūs naudojate naujausią kuprinių sistemos versiją!\\\",\\\"color\\\":\\\"gold\\\"}]\"\n      UpdateFail: \"[\\\"\\\",{\\\"text\\\":\\\"Iškilo problema gaunat kuprinių sistemos atnaujinimų informaciją! Serverio klaida!\\\",\\\"color\\\":\\\"red\\\"}]\"\n      #Prašome neištrinti plugino sisteminio linko kitu atveju negausite update!\n      UpdateAvailable: \"[{\\\"text\\\":\\\"Kuprinių sistema turi atnaujinimą! Prašome nueiti į \\\\\\\"\\\",\\\"color\\\":\\\"green\\\"},{\\\"text\\\":\\\"https://www.spigotmc.org/resources/19286/\\\",\\\"color\\\":\\\"yellow\\\",\\\"underlined\\\":true,\\\"clickEvent\\\":{\\\"action\\\":\\\"open_url\\\",\\\"value\\\":\\\"https://www.spigotmc.org/resources/19286/\\\"}},{\\\"text\\\":\\\"\\\\\\\" ir parsisiūsti atnaujinimą!\\\"}]\"\n    Backup:\n      Created: \"Kuprinė išsaugota!\"\n      NoBackpack: \"Žaidėjas neturi kuprinės, arba jo kuprinė tuščia!\"\n    Restore:\n      BackupsPerPage: 10\n      Headline: \"[\\\"\\\",{\\\"text\\\":\\\"Archyvas\\\",\\\"color\\\":\\\"yellow\\\"},{\\\"text\\\":\\\" - \\\",\\\"color\\\":\\\"white\\\"},{\\\"text\\\":\\\"showing page {CurrentPage}/{MaxPage}\\\",\\\"color\\\":\\\"gold\\\"}]\"\n      Footer: \"[{\\\"text\\\":\\\"<<< Ankst. <<<\\\",\\\"color\\\":\\\"gray\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"run_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}--\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}--\\\"}},{\\\"text\\\":\\\" Rodomas puslapis {CurrentPage}/{MaxPage} \\\",\\\"color\\\":\\\"gold\\\"},{\\\"text\\\":\\\">>> Kt. >>>\\\",\\\"color\\\":\\\"gray\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"run_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}++\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}++\\\"}}]\"\n      BackupEntry: \"[\\\"\\\",{\\\"text\\\":\\\"{BackupIdentifier}\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"suggest_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {BackupIdentifier}\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"Žaidėjas: {BackupPlayerName} ({BackupPlayerUUID})\\\\nPridėta: {BackupDate}\\\"}}]\"\n      NoValidBackup: \"No backup matching {BackupIdentifier} found\"\n      NoUserToRestoreToFound: \"Nėra galimo atstatymo archyvo įrašuose!\"\n      #Ne sisteminis!!!\n      ParameterBackupName: \"backup_name\"\n      #Ne sisteminis!!!\n      DateFormat: \"yyyy.MM.dd HH:mm:ss\"\n      Restored: \"Kuprinė buvo atstatyta iš archyvo!\"\n    InventoryClear:\n      UnknownPlayer: \"&cŽaidėjas: {Name} nerastas!\"\n      Cleared: \"Inventorius išvalytas!\"\n      ClearedOther: \"{DisplayName}&r išvalė inventorių!\"\n      ClearedOtherTarget: \"Jūsų inventorių išvalė: {DisplayName}&r.\"\n    Pickup:\n      ToggleOn: \"&7Automatinis daiktų rinkimas buvo &aĮJUNGTAS&7.\"\n      ToggleOff: \"&7Automatinis daiktų rinkimas buvo &cIŠJUNGTAS&7.\"\n  Commands:\n    HelpFormat: \"[\\\"\\\",{\\\"text\\\":\\\"/{MainCommand} {SubCommand} {Parameters}\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"suggest_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand}\\\"}},{\\\"text\\\":\\\" - \\\",\\\"color\\\":\\\"white\\\"},{\\\"text\\\":\\\"{Description}\\\",\\\"color\\\":\\\"aqua\\\"}]\"\n    PlayerNameVariable: \"player_name\"\n    Description:\n      Backpack: \"Atidarys kuprinę\"\n      Sort: \"Surūšiuos daiktus kuprinėje\"\n      Clean: \"Išvalys kuprinę\"\n      CleanOthers: \"Išvalys kuprinę kitam žaidėjui\"\n      OpenOthers: \"Atidarys kuprinę kitam žaidėjui\"\n      Reload: \"Perkraus kuprinių sistemos nustatymus\"\n      Update: \"Patikrins ar kuprinių sistema turi atnaujinimų\"\n      Version: \"Parodys kuprinių sistemos esamą versijos aprašą\"\n      Backup: \"Sukurs kuprinės įrašą archyve\"\n      BackupEveryone: \"Sukurs visų šiuo metu prisijungusių žaidėjų atsarginę kopiją.\"\n      Restore: \"Atsatys kuprinę pagal įrašą archyve\"\n      RestoreList: \"parodys archyvo įrašus\"\n      Help: \"Parodys visas galimas kuprinių sistemos komandas\"\n      Migrate: \"Perkels duomenų bazės įrašus nauju formatu\"\n      Pickup: \"Perjungti automatinio rinkimo būseną, kai inventoriuje pilna.\"\n\nCommand:\n  Backpack:\n    - backpack\n    - bp\n  Open:\n    - open\n  Sort:\n    - sort\n  Clean:\n    - clean\n    - clear\n    - empty\n  Reload:\n    - reload\n    - restart\n  Update:\n    - update\n  Backup:\n    - backup\n  Restore:\n    - restore\n  ListBackups:\n    - listbackups\n  Version:\n    - version\n  Help:\n    - help\n  InventoryClear:\n    - clear\n    - inventoryclear\n    - clean\n  Pickup:\n    - pickup\n\n#Bus rodoma konsolėje starto metu!\nLanguageName: \"lithuanian\"\nAuthor: \"Vyciokazz\"\n\n# Language file version. Don't touch it!\nVersion: 21"
  },
  {
    "path": "Minepacks/resources/lang/nl.yml",
    "content": "# To simplify the customisation and the translation process please check out the editor: https://ptp.pcgamingfreaks.at\nLanguage:\n  NotFromConsole: \"&cDit commando kan je niet vanuit de console gebruiken.\"\n  Ingame:\n    NoPermission: \"&cJe bent niet gemachtigd om dat te doen.\"\n    WorldDisabled: \"&cHet gebruik van de rugzak is niet toegestaan in deze wereld.\"\n    NaN: \"[\\\"\\\",{\\\"text\\\":\\\"De ingevoerde waarde moet een getal zijn!\\\",\\\"color\\\":\\\"red\\\"}]\"\n    OwnBackpackClose: \"Rugzak gesloten\"\n    OwnBackpackClose_SendMethod: \"action_bar\"\n    # Parameter: {OwnerName}, {OwnerDisplayName}\n    PlayerBackpackClose: \"{OwnerName}'s rugzak gesloten\"\n    PlayerBackpackClose_SendMethod: \"action_bar\"\n    InvalidBackpack: \"Ongeldige rugzak\"\n    NotAllowedInBackpack: \"&c{ItemName} mag je niet in de rugzak bewaren.\"\n    NotAllowedInBackpack_SendMethod: \"action_bar\"\n    DontRemoveShortcut: \"&cJe mag de rugzak niet uit je inventaris halen!\"\n    DontRemoveShortcut_SendMethod: \"action_bar\"\n    BackpackShrunk: \"&cJe rugzak is gekrompen! Sommige items zijn op de grond gevallen!\"\n    Open:\n      # Parameter: {TimeLeft} time in seconds till the backpack can be reopened, {TimeSpanLeft} time formatted as string till the backpack can be reopened\n      Cooldown: \"[{\\\"text\\\":\\\"Wacht \\\",\\\"color\\\":\\\"dark_green\\\"},{\\\"text\\\":\\\"{TimeSpanLeft}\\\",\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"{TimeLeft} seconds\\\"}},{\\\"text\\\":\\\" voordat je de rugzak heropent.\\\"}]\"\n      # Parameter: {CurrentGameMode}, {AllowedGameModes}\n      WrongGameMode: \"De rugzak mag in de huidige spelmodus niet worden geopend.\"\n    Clean:\n      BackpackCleaned: \"Rugzak geleegd\"\n      BackpackCleanedBy: \"Je rugzak is geleegd door {DisplayName}&r.\"\n      BackpackCleanedOther: \"{DisplayName}'s&r rugzak is geleegd.\"\n    Sort:\n      Sorted: \"Rugzak gesorteerd.\"\n    Help:\n      Header: \"&6### Minepacks Commando's ###\"\n      Footer: \"&6#############################\"\n    Reload:\n      Reloading: \"&1Minepacks opnieuw laden\"\n      Reloaded: \"&1Minepacks is herladen\"\n    Update:\n      CheckingForUpdates: \"&1Controleren op updates\"\n      Updated: \"[\\\"\\\",{\\\"text\\\":\\\"Plugin geüpdatet, veranderingen zijn van kracht na de volgende herstart.\\\",\\\"color\\\":\\\"yellow\\\"}]\"\n      NoUpdate: \"[\\\"\\\",{\\\"text\\\":\\\"Geen plugin update beschikbaar.\\\",\\\"color\\\":\\\"gold\\\"}]\"\n      UpdateFail: \"[\\\"\\\",{\\\"text\\\":\\\"Er was een probleem bij het zoeken naar updates. Bekijk  de console!\\\",\\\"color\\\":\\\"red\\\"}]\"\n      # You can change this message if you like to, but don't cry if the link isn't linking to the plugin anymore!\n      UpdateAvailable: \"[{\\\"text\\\":\\\"Er is een update beschikbaar! Ga naar \\\\\\\"\\\",\\\"color\\\":\\\"green\\\"},{\\\"text\\\":\\\"${project.url}\\\",\\\"color\\\":\\\"yellow\\\",\\\"underlined\\\":true,\\\"clickEvent\\\":{\\\"action\\\":\\\"open_url\\\",\\\"value\\\":\\\"${project.url}\\\"}},{\\\"text\\\":\\\"\\\\\\\" om hem te downloaden!\\\"}]\"\n    Backup:\n      Created: \"De rugzak is succesvol opgeslagen.\"\n      NoBackpack: \"De speler heeft geen rugzak of deze is leeg.\"\n    Restore:\n      BackupsPerPage: \"10\"\n      Headline: \"[\\\"\\\",{\\\"text\\\":\\\"Back-ups\\\",\\\"color\\\":\\\"yellow\\\"},{\\\"text\\\":\\\" - \\\",\\\"color\\\":\\\"white\\\"},{\\\"text\\\":\\\"Pagina {CurrentPage} van {MaxPage}\\\",\\\"color\\\":\\\"gold\\\"}]\"\n      Footer: \"[{\\\"text\\\":\\\"<<< Vorige <<<\\\",\\\"color\\\":\\\"gray\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"run_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}--\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}--\\\"}},{\\\"text\\\":\\\" Pagina {CurrentPage} van {MaxPage} \\\",\\\"color\\\":\\\"gold\\\"},{\\\"text\\\":\\\">>> Volgende >>>\\\",\\\"color\\\":\\\"gray\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"run_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}++\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}++\\\"}}]\"\n      BackupEntry: \"[\\\"\\\",{\\\"text\\\":\\\"{BackupIdentifier}\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"suggest_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {BackupIdentifier}\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"User: {BackupPlayerName} ({BackupPlayerUUID})\\\\nCreated: {BackupDate}\\\"}}]\"\n      NoValidBackup: \"Geen back-up gevonden die overeenkomt met {BackupIdentifier}.\"\n      NoUserToRestoreToFound: \"Geen geldige speler gevonden waarbij de back-up kan worden hersteld.\"\n      # No Json!!!\n      ParameterBackupName: \"backup_name\"\n      # No Json!!!\n      DateFormat: \"d MMMM yyyy HH:mm[:ss]\"\n      Restored: \"Back-up is succesvol hersteld.\"\n    InventoryClear:\n      UnknownPlayer: \"&cKan speler {Name} niet vinden!\"\n      Cleared: \"Inventaris geleegd\"\n      ClearedOther: \"{DisplayName}'s&r inventaris is geleegd.\"\n      ClearedOtherTarget: \"Je inventaris is geleegd door {DisplayName}&r.\"\n    Pickup:\n      ToggleOn: \"&7Automatische itemverzameling is &aAAN&7 gezet.\"\n      ToggleOff: \"&7Automatische itemverzameling is &cUIT&7 gezet.\"\n  Commands:\n    HelpFormat: \"[\\\"\\\",{\\\"text\\\":\\\"/{MainCommand} {SubCommand} {Parameters}\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"suggest_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand}\\\"}},{\\\"text\\\":\\\" - \\\",\\\"color\\\":\\\"white\\\"},{\\\"text\\\":\\\"{Description}\\\",\\\"color\\\":\\\"aqua\\\"}]\"\n    PlayerNameVariable: \"player_name\"\n    Description:\n      Backpack: \"Opent je rugzak.\"\n      Sort: \"Sorteert je rugzak.\"\n      Clean: \"Schoont je rugzak op.\"\n      CleanOthers: \"Schoont de rugzak op van andere spelers.\"\n      OpenOthers: \"Laat de rugzak zien van andere spelers.\"\n      Reload: \"Herlaadt de instellingen van de plugin.\"\n      Update: \"Controleert op nieuwe plugin updates.\"\n      Version: \"Geeft details weer over de versie de plugin en diens afhankelijkheden.\"\n      Backup: \"Creëert een back-up van de rugzakken van de spelers.\"\n      BackupEveryone: \"Maakt een back-up van iedereen die momenteel online is.\"\n      Restore: \"Herstelt een back-up.\"\n      RestoreList: \"Laat alle beschikbare back-ups zien.\"\n      Help: \"Laat alle commando's zien met hun beschrijving.\"\n      Migrate: \"Zet de database over naar een ander type.\"\n      Pickup: \"Schakel de status van automatische pickup wanneer de inventaris vol is.\"\n\nCommand:\n  Backpack:\n    - backpack\n    - bp\n    - rugzak\n    - rz\n  Open:\n    - open\n  Sort:\n    - sorteer\n    - sort\n  Clean:\n    - clean\n    - schoon\n  Reload:\n    - herlaad\n    - herstart\n    - reload\n    - restart\n  Update:\n    - update\n  Backup:\n    - backup\n  Restore:\n    - restore\n    - herstel\n  ListBackups:\n    - listbackups\n    - lijst\n    - backuplijst\n  Version:\n    - version\n    - versie\n  Help:\n    - help\n    - hulp\n  InventoryClear:\n    - clear\n    - inventoryclear\n    - wis\n    - verwijder\n  Pickup:\n    - pickup\n\n# Will be shown in the console during startup\nLanguageName: \"Nederlands\"\nAuthor: \"Le0ne_\"\n\n# Language file version. Don't touch it!\nVersion: 21"
  },
  {
    "path": "Minepacks/resources/lang/pl.yml",
    "content": "# To simplify the customisation and the translation process please check out the editor: https://ptp.pcgamingfreaks.at\n\nLanguage:\n  NotFromConsole: \"&cPolecenia nie można używać z konsoli.\"\n  Ingame:\n    NoPermission: \"&cNie masz na to pozwolenia.\"\n    WorldDisabled: \"&cKorzystanie z plecaka jest zabronione na tym świecie.\"\n    NaN: \"[\\\"\\\",{\\\"text\\\":\\\"Podana wartość nie jest liczbą\\\",\\\"color\\\":\\\"red\\\"}]\"\n    OwnBackpackClose: \"Plecak zamknięty!\"\n    OwnBackpackClose_SendMethod: \"action_bar\"\n    #Parameter: {OwnerName}, {OwnerDisplayName}\n    PlayerBackpackClose: \"{OwnerName} plecak zamknięty!\"\n    PlayerBackpackClose_SendMethod: \"action_bar\"\n    InvalidBackpack: \"Nieprawidłowy plecak.\"\n    NotAllowedInBackpack: \"&c{ItemName}nie jest dozwolone w plecaku.\"\n    NotAllowedInBackpack_SendMethod: \"action_bar\"\n    DontRemoveShortcut: \"&cNie wolno usuwać skrótu do plecaka z ekwipunku!\"\n    DontRemoveShortcut_SendMethod: \"action_bar\"\n    BackpackShrunk: \"&cTwój plecak się skurczył! Niektóre przedmioty spadły na ziemię!\"\n    Open:\n      #Parameter: {TimeLeft} time in seconds till the backpack can be reopened, {TimeSpanLeft} time formatted as string till the backpack can be reopened\n      Cooldown: \"[{\\\"text\\\":\\\"{TimeSpanLeft}\\\",\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"{TimeLeft} seconds\\\"}},{\\\"text\\\":\\\"Proszę czekać\\\",\\\"color\\\":\\\"dark_green\\\"},{\\\"text\\\":\\\" aż do ponownego otwarcia plecaka.\\\"}]\"\n      #Parameter: {CurrentGameMode}, {AllowedGameModes}\n      WrongGameMode: \"W bieżącym trybie gry nie wolno otwierać plecaka.\"\n    Clean:\n      BackpackCleaned: \"Plecak wyczyszczony.\"\n      BackpackCleanedBy: \"Twój plecak został wyczyszczony przez {DisplayName}&r.\"\n      BackpackCleanedOther: \"Plecak gracza {DisplayName}&r został wyczyszczony.\"\n    Sort:\n      Sorted: \"Plecak posortowany.\"\n    Help:\n      Header: \"&6### Paczka poleceń ###\"\n      Footer: \"&6#############################\"\n    Reload:\n      Reloading: \"&1Ponowne ładowanie...\"\n      Reloaded: \"&1Załadowano ponownie!\"\n    Update:\n      CheckingForUpdates: \"&1Checking for updates ...\"\n      Updated: \"[\\\"\\\",{\\\"text\\\":\\\"Wtyczka zaktualizowana, zostanie załadowana przy następnym restarcie / przeładowaniu\\\",\\\"color\\\":\\\"yellow\\\"}]\"\n      NoUpdate: \"[\\\"\\\",{\\\"text\\\":\\\"Brak aktualizacji wtyczki.\\\",\\\"color\\\":\\\"gold\\\"}]\"\n      UpdateFail: \"[\\\"\\\",{\\\"text\\\":\\\"Podczas wyszukiwania aktualizacji wystąpił problem! Sprawdź konsolę!\\\",\\\"color\\\":\\\"red\\\"}]\"\n      # You can change this message if you like to, but don't cry if the link isn't linking to the plugin anymore!\n      UpdateAvailable: \"[{\\\"text\\\":\\\"Dostępna jest aktualizacja! Proszę wejść na \\\\\\\"\\\",\\\"color\\\":\\\"green\\\"},{\\\"text\\\":\\\"https://www.spigotmc.org/resources/19286/\\\",\\\"color\\\":\\\"yellow\\\",\\\"underlined\\\":true,\\\"clickEvent\\\":{\\\"action\\\":\\\"open_url\\\",\\\"value\\\":\\\"https://www.spigotmc.org/resources/19286/\\\"}},{\\\"text\\\":\\\"\\\\\\\" aby go pobrać!\\\"}]\"\n    Backup:\n      Created: \"Utworzono kopię zapasową plecaka.\"\n      NoBackpack: \"Gracz nie ma plecaka lub jego plecak jest pusty.\"\n    Restore:\n      BackupsPerPage: 10\n      Headline: \"[\\\"\\\",{\\\"text\\\":\\\"Kopie zapasowe\\\",\\\"color\\\":\\\"yellow\\\"},{\\\"text\\\":\\\" - \\\",\\\"color\\\":\\\"white\\\"},{\\\"text\\\":\\\"wyświetlana strona {CurrentPage}/{MaxPage}\\\",\\\"color\\\":\\\"gold\\\"}]\"\n      Footer: \"[{\\\"text\\\":\\\"<<< Poprzednia <<<\\\",\\\"color\\\":\\\"gray\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"run_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}--\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}--\\\"}},{\\\"text\\\":\\\" Wyświetlana strona {CurrentPage}/{MaxPage} \\\",\\\"color\\\":\\\"gold\\\"},{\\\"text\\\":\\\">>> Następna >>>\\\",\\\"color\\\":\\\"gray\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"run_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}++\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}++\\\"}}]\"\n      BackupEntry: \"[\\\"\\\",{\\\"text\\\":\\\"{BackupIdentifier}\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"suggest_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {BackupIdentifier}\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"User: {BackupPlayerName} ({BackupPlayerUUID})\\\\nCreated: {BackupDate}\\\"}}]\"\n      NoValidBackup: \"Nie znaleziono kopii zapasowej pasującej{BackupIdentifier} \"\n      NoUserToRestoreToFound: \"Brak prawidłowego użytkownika do przywrócenia kopii zapasowej do znalezionej.\"\n      # No Json!!!\n      ParameterBackupName: \"backup_name\"\n      # No Json!!!\n      DateFormat: \"yyyy.MM.dd HH:mm:ss\"\n      Restored: \"Kopia zapasowa została pomyślnie przywrócona.\"\n    InventoryClear:\n      UnknownPlayer: \"&cNie można znaleźć gracza {Name}!\"\n      Cleared: \"Ekwipunek wyczyszczony.\"\n      ClearedOther: \"Ekwipunek gracza {DisplayName}&r został wyczyszczony.\"\n      ClearedOtherTarget: \"Twój ekwipunek został wyczyszczony przez {DisplayName}&r.\"\n    Pickup:\n      ToggleOn: \"&7Automatyczne zbieranie przedmiotów zostało &aWŁĄCZONE&7.\"\n      ToggleOff: \"&7Automatyczne zbieranie przedmiotów zostało &cWYŁĄCZONE&7.\"\n  Commands:\n    HelpFormat: \"[\\\"\\\",{\\\"text\\\":\\\"/{MainCommand} {SubCommand} {Parameters}\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"suggest_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand}\\\"}},{\\\"text\\\":\\\" - \\\",\\\"color\\\":\\\"white\\\"},{\\\"text\\\":\\\"{Description}\\\",\\\"color\\\":\\\"aqua\\\"}]\"\n    PlayerNameVariable: \"player_name\"\n    Description:\n      Backpack: \"Otwiera plecak.\"\n      Clean: \"Czyści plecak.\"\n      CleanOthers: \"Czyści plecak innych graczy.\"\n      OpenOthers: \"Otwiera plecak innych graczy.\"\n      Reload: \"Ponownie ładuje konfigurację wtyczki.\"\n      Update: \"Sprawdza dostępność nowych aktualizacji wtyczek.\"\n      Version: \"Wyświetla szczegóły wersji wtyczki i jej zależności.\"\n      Backup: \"Tworzy kopię zapasową plecaka gracza.\"\n      BackupEveryone: \"Tworzy kopię zapasową wszystkich obecnie online.\"\n      Restore: \"Przywraca kopię zapasową.\"\n      RestoreList: \"Wyświetla wszystkie dostępne kopie zapasowe.\"\n      Help: \"Pokazuje wszystkie dostępne polecenia i ich opis.\"\n      Migrate: \"Migruje używaną bazę danych z jednego typu na inny.\"\n      Pickup: \"Przełącz stan automatycznego zbierania gdy ekwipunek jest pełny.\"\n\nCommand:\n  Backpack:\n    - plecak\n    - pk\n  Open:\n    - \"otwórz\"\n  Sort:\n    - sort\n    - sortuj\n  Clean:\n    - \"wyczyść\"\n  Reload:\n    - reload\n    - restart\n  Update:\n    - aktualizacja\n  Backup:\n    - backup\n  Restore:\n    - restore\n  ListBackups:\n    - listbackups\n  Version:\n    - wersja\n  Help:\n    - pomoc\n  InventoryClear:\n    - clear\n    - inventoryclear\n    - clean\n  Pickup:\n    - pickup\n\n# Will be shown in the console during startup\nLanguageName: \"Polish\"\nAuthor: \"Lisheya\"\n\n# Language file version. Don't touch it!\nVersion: 21"
  },
  {
    "path": "Minepacks/resources/lang/pt.yml",
    "content": "# To simplify the customisation and the translation process please check out the editor: https://ptp.pcgamingfreaks.at\nLanguage:\n  NotFromConsole: \"&cO comando não pode ser usado no console.\"\n  Ingame:\n    NoPermission: \"&cVocê não tem permissão para isso.\"\n    WorldDisabled: \"&cVocê não pode usar a mochila nesse mundo.\"\n    NaN: \"[\\\"\\\",{\\\"text\\\":\\\"Isso não é um número!\\\",\\\"color\\\":\\\"red\\\"}]\"\n    OwnBackpackClose: \"Mochila fechada!\"\n    OwnBackpackClose_SendMethod: \"action_bar\"\n    # Parameter: {OwnerName}, {OwnerDisplayName}\n    PlayerBackpackClose: \"Mochila de {OwnerName} fechada!\"\n    PlayerBackpackClose_SendMethod: \"action_bar\"\n    InvalidBackpack: \"Mochila inválida.\"\n    NotAllowedInBackpack: \"&c{ItemName} não pode ficar na mochila.\"\n    NotAllowedInBackpack_SendMethod: \"action_bar\"\n    DontRemoveShortcut: \"&cVocê não deve remover o atalho da mochila do seu inventário!\"\n    DontRemoveShortcut_SendMethod: \"action_bar\"\n    BackpackShrunk: \"&cSua mochila encolheu! Alguns itens caíram no chão!\"\n    Open:\n      # Parameter: {TimeLeft} time in seconds till the backpack can be reopened, {TimeSpanLeft} time formatted as string till the backpack can be reopened\n      Cooldown: \"[{\\\"text\\\":\\\"Por favor, espere \\\",\\\"color\\\":\\\"dark_green\\\"},{\\\"text\\\":\\\"{TimeSpanLeft}\\\",\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"{TimeLeft} seconds\\\"}},{\\\"text\\\":\\\" para abrir a mochila novamente.\\\"}]\"\n      # Parameter: {CurrentGameMode}, {AllowedGameModes}\n      WrongGameMode: \"Você não pode abrir a mochila nesse modo de jogo.\"\n    Clean:\n      BackpackCleaned: \"Mochila limpa.\"\n      BackpackCleanedBy: \"Sua mochila foi limpa por {DisplayName}&r.\"\n      BackpackCleanedOther: \"A mochila de {DisplayName}&r foi limpa.\"\n    Sort:\n      Sorted: \"Mochila organizada.\"\n    Help:\n      Header: \"&6### Comandos Minepacks ###\"\n      Footer: \"&6#############################\"\n    Reload:\n      Reloading: \"&1Recarregando ...\"\n      Reloaded: \"&1Recarregado!\"\n    Update:\n      CheckingForUpdates: \"&1Procurando atualizações ...\"\n      Updated: \"[\\\"\\\",{\\\"text\\\":\\\"Plugin atualizado, será carregado no próximo restart/reload.\\\",\\\"color\\\":\\\"yellow\\\"}]\"\n      NoUpdate: \"[\\\"\\\",{\\\"text\\\":\\\"Plugin atualizado!\\\",\\\"color\\\":\\\"gold\\\"}]\"\n      UpdateFail: \"[\\\"\\\",{\\\"text\\\":\\\"Houve um problema ao procucurar atualizações, olhe o console!\\\",\\\"color\\\":\\\"red\\\"}]\"\n      # You can change this message if you like to, but don't cry if the link isn't linking to the plugin anymore!\n      UpdateAvailable: \"[{\\\"text\\\":\\\"Atualização disponível, vá até \\\\\\\"\\\",\\\"color\\\":\\\"green\\\"},{\\\"text\\\":\\\"${project.url}\\\",\\\"color\\\":\\\"yellow\\\",\\\"underlined\\\":true,\\\"clickEvent\\\":{\\\"action\\\":\\\"open_url\\\",\\\"value\\\":\\\"${project.url}\\\"}},{\\\"text\\\":\\\"\\\\\\\" para baixa-la!\\\"}]\"\n    Backup:\n      Created: \"Backup criado com sucesso.\"\n      NoBackpack: \"O jogador não tem um backup ou a mochila está vazia.\"\n    Restore:\n      BackupsPerPage: \"10\"\n      Headline: \"[\\\"\\\",{\\\"text\\\":\\\"Backups\\\",\\\"color\\\":\\\"yellow\\\"},{\\\"text\\\":\\\" - \\\",\\\"color\\\":\\\"white\\\"},{\\\"text\\\":\\\"página {CurrentPage}/{MaxPage}\\\",\\\"color\\\":\\\"gold\\\"}]\"\n      Footer: \"[{\\\"text\\\":\\\"<<< Anterior <<<\\\",\\\"color\\\":\\\"gray\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"run_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}--\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}--\\\"}},{\\\"text\\\":\\\" Página {CurrentPage}/{MaxPage} \\\",\\\"color\\\":\\\"gold\\\"},{\\\"text\\\":\\\">>> Próximo >>>\\\",\\\"color\\\":\\\"gray\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"run_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}++\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}++\\\"}}]\"\n      BackupEntry: \"[\\\"\\\",{\\\"text\\\":\\\"{BackupIdentifier}\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"suggest_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {BackupIdentifier}\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"User: {BackupPlayerName} ({BackupPlayerUUID})\\\\nCreated: {BackupDate}\\\"}}]\"\n      NoValidBackup: \"Nenhuma correspondência de backup {BackupIdentifier} encontrada\"\n      NoUserToRestoreToFound: \"Nenhum usuário válido para restaurar o backup encontrado\"\n      # No Json!!!\n      ParameterBackupName: \"backup_name\"\n      # No Json!!!\n      DateFormat: \"yyyy.MM.dd HH:mm:ss\"\n      Restored: \"Backup carregado com sucesso.\"\n    InventoryClear:\n      UnknownPlayer: \"&cNão foi possível encontrar o jogador {Name}!\"\n      Cleared: \"Inventário limpo.\"\n      ClearedOther: \"O inventário de {DisplayName}&r foi limpo.\"\n      ClearedOtherTarget: \"Seu inventário foi limpo por {DisplayName}&r.\"\n    Pickup:\n      ToggleOn: \"&7A coleta automática de itens foi &aATIVADA&7.\"\n      ToggleOff: \"&7A coleta automática de itens foi &cDESATIVADA&7.\"\n  Commands:\n    HelpFormat: \"[\\\"\\\",{\\\"text\\\":\\\"/{MainCommand} {SubCommand} {Parameters}\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"suggest_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand}\\\"}},{\\\"text\\\":\\\" - \\\",\\\"color\\\":\\\"white\\\"},{\\\"text\\\":\\\"{Description}\\\",\\\"color\\\":\\\"aqua\\\"}]\"\n    PlayerNameVariable: \"player_name\"\n    Description:\n      Backpack: \"Abre sua mochila.\"\n      Clean: \"Limpa sua mochila.\"\n      CleanOthers: \"Limpa a mochila de outros jogadores.\"\n      OpenOthers: \"Abre a mochila de outro jogador.\"\n      Reload: \"Recarrega a configuração do plugin.\"\n      Update: \"Procura por novas atualizações.\"\n      Version: \"Mostra detalhes da versão do plugin e suas dependências.\"\n      Backup: \"Cria um backup da mochila dos jogadores.\"\n      BackupEveryone: \"Cria um backup de todos que estão online no momento.\"\n      Restore: \"Restaura um backup.\"\n      RestoreList: \"Mostra todos os backups disponíveis.\"\n      Help: \"Mostra todos os comandos disponíveis e suas descrições.\"\n      Migrate: \"Migra o banco de dados usado de um tipo para outro.\"\n      Pickup: \"Alterna o estado da coleta automática quando o inventário está cheio.\"\n\nCommand:\n  Backpack:\n    - backpack\n    - bp\n    - mochila\n  Open:\n    - open\n    - abrir\n  Sort:\n    - sort\n    - organizar\n  Clean:\n    - clean\n    - clear\n    - empty\n    - limpar\n  Reload:\n    - reload\n    - restart\n    - recarregar\n  Update:\n    - update\n    - atualizar\n  Backup:\n    - backup\n  Restore:\n    - restore\n    - restaurar\n  ListBackups:\n    - listbackups\n    - listarbackups\n  Version:\n    - version\n    - versao\n  Help:\n    - help\n    - ajuda\n  InventoryClear:\n    - clear\n    - inventoryclear\n    - clean\n  Pickup:\n    - pickup\n\n# Will be shown in the console during startup\nLanguageName: \"Português\"\nAuthor: \"dotJunyo\"\n\n# Language file version. Don't touch it!\nVersion: 21"
  },
  {
    "path": "Minepacks/resources/lang/ru.yml",
    "content": "# To simplify the customisation and translation process please check out the editor: https://ptp.pcgamingfreaks.at\n\nLanguage:\n  NotFromConsole: \"&cЭту команду нельзя использовать в консоли.\"\n  Ingame:\n    NoPermission: \"&cУ вас недостаточно прав для этого.\"\n    WorldDisabled: \"&cИспользовать рюкзак не разрешено в этом мире.\"\n    NaN: \"[\\\"\\\",{\\\"text\\\":\\\"Введенное значение не является числом!\\\",\\\"color\\\":\\\"red\\\"}]\"\n    OwnBackpackClose: \"Рюкзак закрыт!\"\n    OwnBackpackClose_SendMethod: \"action_bar\"\n    #Parameter: {OwnerName}, {OwnerDisplayName}\n    PlayerBackpackClose: \"Рюкзак {OwnerName} закрыт!\"\n    PlayerBackpackClose_SendMethod: \"action_bar\"\n    InvalidBackpack: \"Недействительный рюкзак.\"\n    NotAllowedInBackpack: \"&c{ItemName} нельзя положить в рюкзак.\"\n    NotAllowedInBackpack_SendMethod: \"action_bar\"\n    DontRemoveShortcut: \"&cВы не можете удалить иконку рюкзака из своего инвентаря!\"\n    DontRemoveShortcut_SendMethod: \"action_bar\"\n    BackpackShrunk: \"&cВаш рюкзак уменьшился! Некоторые предметы выпали на землю!\"\n    Open:\n      #Parameter: {TimeLeft} time in seconds till the backpack can be reopened, {TimeSpanLeft} time formatted as string till the backpack can be reopened\n      Cooldown: \"[{\\\"text\\\":\\\"Пожалуйста подождите \\\",\\\"color\\\":\\\"dark_green\\\"},{\\\"text\\\":\\\"{TimeSpanLeft}\\\",\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"{TimeLeft} секунд\\\"}},{\\\"text\\\":\\\", перед тем как снова открыть свой рюкзак.\\\"}]\"\n      #Parameter: {CurrentGameMode}, {AllowedGameModes}\n      WrongGameMode: \"Вам не разрешено открывать рюкзак в текущем режиме игры.\"\n    Clean:\n      BackpackCleaned: \"Рюкзак очищен.\"\n      BackpackCleanedBy: \"Ваш рюкзак был очищен игроком {DisplayName}&r.\"\n      BackpackCleanedOther: \"{DisplayName}'s&r рюкзак был очищен.\"\n    Sort:\n      Sorted: \"Рюкзак отсортирован.\"\n    Help:\n      Header: \"&6### Команды Minepacks ###\"\n      Footer: \"&6#############################\"\n    Reload:\n      Reloading: \"&1Перезагрузка...\"\n      Reloaded: \"&1Плагин успешно перезагружен!\"\n    Update:\n      CheckingForUpdates: \"&1Проверка обновлений...\"\n      Updated: \"[\\\"\\\",{\\\"text\\\":\\\"Плагин обновлён и будет загружен после следующей перезагрузки.\\\",\\\"color\\\":\\\"yellow\\\"}]\"\n      NoUpdate: \"[\\\"\\\",{\\\"text\\\":\\\"Нет доступных обновлений.\\\",\\\"color\\\":\\\"gold\\\"}]\"\n      UpdateFail: \"[\\\"\\\",{\\\"text\\\":\\\"При проверке обновлений произошла ошибка! Пожалуйста проверьте консоль!\\\",\\\"color\\\":\\\"red\\\"}]\"\n      # You can change this message if you like to, but don't cry if the link isn't linking to the plugin anymore!\n      UpdateAvailable: \"[{\\\"text\\\":\\\"Доступно обновление! Пожалуйста, посетите сайт \\\\\\\"\\\",\\\"color\\\":\\\"green\\\"},{\\\"text\\\":\\\"https://www.spigotmc.org/resources/19286/\\\",\\\"color\\\":\\\"yellow\\\",\\\"underlined\\\":true,\\\"clickEvent\\\":{\\\"action\\\":\\\"open_url\\\",\\\"value\\\":\\\"https://www.spigotmc.org/resources/19286/\\\"}},{\\\"text\\\":\\\"\\\\\\\" чтобы скачать его!\\\"}]\"\n    Backup:\n      Created: \"Рюкзак был успешно скопирован.\"\n      NoBackpack: \"У игрока нет рюкзака, либо он пустой.\"\n    Restore:\n      BackupsPerPage: 10\n      Headline: \"[\\\"\\\",{\\\"text\\\":\\\"Резервные копии\\\",\\\"color\\\":\\\"yellow\\\"},{\\\"text\\\":\\\" - \\\",\\\"color\\\":\\\"white\\\"},{\\\"text\\\":\\\"страница {CurrentPage}/{MaxPage}\\\",\\\"color\\\":\\\"gold\\\"}]\"\n      Footer: \"[{\\\"text\\\":\\\"<<< Предыдущая <<<\\\",\\\"color\\\":\\\"gray\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"run_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}--\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}--\\\"}},{\\\"text\\\":\\\" Страница {CurrentPage}/{MaxPage} \\\",\\\"color\\\":\\\"gold\\\"},{\\\"text\\\":\\\">>> Следующая >>>\\\",\\\"color\\\":\\\"gray\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"run_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}++\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}++\\\"}}]\"\n      BackupEntry: \"[\\\"\\\",{\\\"text\\\":\\\"{BackupIdentifier}\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"suggest_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {BackupIdentifier}\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"Пользователь: {BackupPlayerName} ({BackupPlayerUUID})\\\\\\nСоздана: {BackupDate}\\\"}}]\"\n      NoValidBackup: \"Резервная копия {BackupIdentifier} не найдена\"\n      NoUserToRestoreToFound: \"Не найдено действительного пользователя или копии для восстановления\"\n      # No Json!!!\n      ParameterBackupName: \"backup_name\"\n      # No Json!!!\n      DateFormat: \"dd.MM.yy HH:mm:ss\"\n      Restored: \"Резервная копия успешно восстановлена.\"\n    InventoryClear:\n      UnknownPlayer: \"&cНе удалось найти игрока {Name}!\"\n      Cleared: \"Инвентарь очищен.\"\n      ClearedOther: \"{DisplayName}'s&r инвентарь был очищен.\"\n      ClearedOtherTarget: \"Ваш инвентарь был очищен игроком {DisplayName}&r.\"\n    Pickup:\n      ToggleOn: \"&7Автоматический сбор предметов был переключен на &aВКЛ&7.\"\n      ToggleOff: \"&7Автоматический сбор предметов был переключен на &cВЫКЛ&7.\"\n  Commands:\n    HelpFormat: \"[\\\"\\\",{\\\"text\\\":\\\"/{MainCommand} {SubCommand} {Parameters}\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"suggest_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand}\\\"}},{\\\"text\\\":\\\" - \\\",\\\"color\\\":\\\"white\\\"},{\\\"text\\\":\\\"{Description}\\\",\\\"color\\\":\\\"aqua\\\"}]\"\n    PlayerNameVariable: \"player_name\"\n    Description:\n      Backpack: \"Открыть ваш рюкзак.\"\n      Sort: \"Отсортировать ваш рюкзак.\"\n      Clean: \"Очистить ваш рюкзак.\"\n      CleanOthers: \"Очистить рюкзак другого игрока.\"\n      OpenOthers: \"Открыть рюкзак другого игрока.\"\n      Reload: \"Перезагрузить конфигурацию плагина.\"\n      Update: \"Проверить плагин на наличие новых версий.\"\n      Version: \"Посмотреть информацию о плагине и о его зависимостях.\"\n      Backup: \"Создать резервную копию рюкзака игрока.\"\n      BackupEveryone: \"Создает резервную копию всех, кто в данный момент находится в сети.\"\n      Restore: \"Восстановить резервную копию.\"\n      RestoreList: \"Посмотреть список всех доступных резервных копий.\"\n      Help: \"Посмотреть все команды и их описание.\"\n      Migrate: \"Изменить тип используемой базы данных.\"\n      Pickup: \"Переключить состояние автоматического подбора, когда инвентарь заполнен.\"\n\nCommand:\n  Backpack:\n    - backpack\n    - bp\n  Open:\n    - open\n  Sort:\n    - sort\n  Clean:\n    - clean\n    - clear\n    - empty\n  Reload:\n    - reload\n    - restart\n  Update:\n    - update\n  Backup:\n    - backup\n  Restore:\n    - restore\n  ListBackups:\n    - listbackups\n  Version:\n    - version\n  Help:\n    - help\n  InventoryClear:\n    - clear\n    - inventoryclear\n    - clean\n  Pickup:\n    - pickup\n\n# Will be shown in the console during startup\nLanguageName: \"russian\"\nAuthor: \"maz1lovo\"\n\n# Language file version. Don't touch it!\nVersion: 21\n"
  },
  {
    "path": "Minepacks/resources/lang/tr.yml",
    "content": "# To simplify the customisation and the translation process please check out the editor: https://ptp.pcgamingfreaks.at\nLanguage:\n  NotFromConsole: \"&cKomut konsoldan kullanılabilir değil.\"\n  Ingame:\n    NoPermission: \"&cBunu yapmak için iznin yok.\"\n    WorldDisabled: \"&cÇantaların kullanımı bu dünyada devredışı.\"\n    NaN: \"[\\\"\\\",{\\\"text\\\":\\\"Girilen değer sayı değil!\\\",\\\"color\\\":\\\"red\\\"}]\"\n    OwnBackpackClose: \"Çanta kapandı!\"\n    OwnBackpackClose_SendMethod: \"action_bar\"\n    # Parameter: {OwnerName}, {OwnerDisplayName}\n    PlayerBackpackClose: \"{OwnerName} adlı kişinin çantası kapandı!\"\n    PlayerBackpackClose_SendMethod: \"action_bar\"\n    InvalidBackpack: \"Geçersiz çanta.\"\n    NotAllowedInBackpack: \"&c{ItemName} çanta içinde bulundurulamaz.\"\n    NotAllowedInBackpack_SendMethod: \"action_bar\"\n    DontRemoveShortcut: \"&cÇanta kısayolunu envanterinizden kaldırmamalısınız!\"\n    DontRemoveShortcut_SendMethod: \"action_bar\"\n    BackpackShrunk: \"&cÇantanız küçüldü! Bazı eşyalar yere düştü!\"\n    Open:\n      # Parameter: {TimeLeft} time in seconds till the backpack can be reopened, {TimeSpanLeft} time formatted as string till the backpack can be reopened\n      Cooldown: \"[{\\\"text\\\":\\\"Çantanızı geri açana kadar lütfen \\\",\\\"color\\\":\\\"dark_green\\\"},{\\\"text\\\":\\\"{TimeSpanLeft}\\\",\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"{TimeLeft} seconds\\\"}},{\\\"text\\\":\\\" bekleyin.\\\"}]\"\n      # Parameter: {CurrentGameMode}, {AllowedGameModes}\n      WrongGameMode: \"Şu anki oyun modunda çantanızı açamazsınız.\"\n    Clean:\n      BackpackCleaned: \"Çanta temizlendi.\"\n      BackpackCleanedBy: \"Çantanız {DisplayName}&r tarafından temizlendi.\"\n      BackpackCleanedOther: \"{DisplayName}&r çantası temizlendi.\"\n    Sort:\n      Sorted: \"Çanta sıralandı.\"\n    Help:\n      Header: \"&6### Minepacks Komutları ###\"\n      Footer: \"&6#############################\"\n    Reload:\n      Reloading: \"&1Tekrar Yükleniyor ...\"\n      Reloaded: \"&1Tekrar Yüklendi!\"\n    Update:\n      CheckingForUpdates: \"&1Güncellemeler denetleniyor ...\"\n      Updated: \"[\\\"\\\",{\\\"text\\\":\\\"Eklenti güncellendi, diğer restart/reload işleminde yüklenecek.\\\",\\\"color\\\":\\\"yellow\\\"}]\"\n      NoUpdate: \"[\\\"\\\",{\\\"text\\\":\\\"Eklenti güncellemesi bulunmuyor.\\\",\\\"color\\\":\\\"gold\\\"}]\"\n      UpdateFail: \"[\\\"\\\",{\\\"text\\\":\\\"Güncelleme denetlenirken bir hata oluştu! Lütfen konsolu kontrol edin!\\\",\\\"color\\\":\\\"red\\\"}]\"\n      # You can change this message if you like to, but don't cry if the link isn't linking to the plugin anymore!\n      UpdateAvailable: \"[{\\\"text\\\":\\\"Güncelleme mevcut! Yüklemek için \\\\\\\"\\\",\\\"color\\\":\\\"green\\\"},{\\\"text\\\":\\\"${project.url}\\\",\\\"color\\\":\\\"yellow\\\",\\\"underlined\\\":true,\\\"clickEvent\\\":{\\\"action\\\":\\\"open_url\\\",\\\"value\\\":\\\"${project.url}\\\"}},{\\\"text\\\":\\\"\\\\\\\" adresini kullanın!\\\"}]\"\n    Backup:\n      Created: \"Çanta yedeklendi.\"\n      NoBackpack: \"Oyuncunun bir çantası yok ya da çantası boş.\"\n    Restore:\n      BackupsPerPage: \"10\"\n      Headline: \"[\\\"\\\",{\\\"text\\\":\\\"Yedeklemeler\\\",\\\"color\\\":\\\"yellow\\\"},{\\\"text\\\":\\\" - \\\",\\\"color\\\":\\\"white\\\"},{\\\"text\\\":\\\"Gösterilen sayfa {CurrentPage}/{MaxPage}\\\",\\\"color\\\":\\\"gold\\\"}]\"\n      Footer: \"[{\\\"text\\\":\\\"<<< Önceki <<<\\\",\\\"color\\\":\\\"gray\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"run_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}--\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}--\\\"}},{\\\"text\\\":\\\" Gösterilen Sayfa {CurrentPage}/{MaxPage} \\\",\\\"color\\\":\\\"gold\\\"},{\\\"text\\\":\\\">>> Sonraki >>>\\\",\\\"color\\\":\\\"gray\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"run_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}++\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}++\\\"}}]\"\n      BackupEntry: \"[\\\"\\\",{\\\"text\\\":\\\"{BackupIdentifier}\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"suggest_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {BackupIdentifier}\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"User: {BackupPlayerName} ({BackupPlayerUUID})\\\\nCreated: {BackupDate}\\\"}}]\"\n      NoValidBackup: \"Yedekleme eşleşmesi {BackupIdentifier} bulunamadı\"\n      NoUserToRestoreToFound: \"Yedekleme için geçerli oyuncu bulunamadı\"\n      # No Json!!!\n      ParameterBackupName: \"backup_name\"\n      # No Json!!!\n      DateFormat: \"yyyy.MM.dd HH:mm:ss\"\n      Restored: \"Yedek başarıyla geri getirildi.\"\n    InventoryClear:\n      UnknownPlayer: \"&cOyuncu {Name} bulunamadı!\"\n      Cleared: \"Envanter temizlendi.\"\n      ClearedOther: \"{DisplayName}&r envanteri temizlendi.\"\n      ClearedOtherTarget: \"Envanteriniz {DisplayName}&r tarafından temizlendi.\"\n    Pickup:\n      ToggleOn: \"&7Otomatik eşya toplama &aAÇIK&7 duruma getirildi.\"\n      ToggleOff: \"&7Otomatik eşya toplama &cKAPALI&7 duruma getirildi.\"\n  Commands:\n    HelpFormat: \"[\\\"\\\",{\\\"text\\\":\\\"/{MainCommand} {SubCommand} {Parameters}\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"suggest_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand}\\\"}},{\\\"text\\\":\\\" - \\\",\\\"color\\\":\\\"white\\\"},{\\\"text\\\":\\\"{Description}\\\",\\\"color\\\":\\\"aqua\\\"}]\"\n    PlayerNameVariable: \"player_name\"\n    Description:\n      Backpack: \"Çantanı açar.\"\n      Clean: \"Çantanı temizler.\"\n      CleanOthers: \"Başka bir oyuncunun çantasını temizler.\"\n      OpenOthers: \"Başkasının çantasını görüntüler.\"\n      Reload: \"Eklentinin config dosyasını tekrar yükler.\"\n      Update: \"Eklenti için yeni güncellemeleri denetler.\"\n      Version: \"Eklenti detaylarını ve gerekliliklerinin çıktısını verir.\"\n      Backup: \"Oyuncunun çantasını yedekler.\"\n      BackupEveryone: \"Şu anda çevrimiçi olan herkesin yedeğini oluşturur.\"\n      Restore: \"Yedeği yükler.\"\n      RestoreList: \"Mevcut tüm yedekleri listeler.\"\n      Help: \"Mevcut tüm komutları ve tanımlarını gösterir.\"\n      Migrate: \"Kullanılan veritabanını bir türden diğerine geçirir.\"\n      Pickup: \"Envanter doluyken otomatik toplama durumunu değiştirir.\"\n\nCommand:\n  Backpack:\n    - backpack\n    - bp\n  Open:\n    - open\n  Sort:\n    - sort\n  Clean:\n    - clean\n    - clear\n    - empty\n  Reload:\n    - reload\n    - restart\n  Update:\n    - update\n  Backup:\n    - backup\n  Restore:\n    - restore\n  ListBackups:\n    - listbackups\n  Version:\n    - version\n  Help:\n    - help\n  InventoryClear:\n    - clear\n    - inventoryclear\n    - clean\n  Pickup:\n    - pickup\n\n# Will be shown in the console during startup\nLanguageName: \"turkish\"\nAuthor: \"imZesha\"\n\n# Language file version. Don't touch it!\nVersion: 21"
  },
  {
    "path": "Minepacks/resources/lang/uk.yml",
    "content": "# To simplify the customisation and translation process please check out the editor: https://ptp.pcgamingfreaks.at\n\nLanguage:\n  NotFromConsole: \"&cКоманда не доступна з консолі.\"\n  Ingame:\n    NoPermission: \"&cВи не маєте прав, щоб зробити це.\"\n    WorldDisabled: \"&cВикористання рюкзака заборонено у цьому світі.\"\n    NaN: \"[\\\"\\\",{\\\"text\\\":\\\"Введене значення не є числом!\\\",\\\"color\\\":\\\"red\\\"}]\"\n    OwnBackpackClose: \"Рюкзак зачинен!\"\n    OwnBackpackClose_SendMethod: \"action_bar\"\n    #Parameter: {OwnerName}, {OwnerDisplayName}\n    PlayerBackpackClose: \"{OwnerName} рюкзак зачинен!\"\n    PlayerBackpackClose_SendMethod: \"action_bar\"\n    InvalidBackpack: \"Рюкзак недійсний.\"\n    NotAllowedInBackpack: \"&c{ItemName} не дозволяється носити в рюкзаку.\"\n    NotAllowedInBackpack_SendMethod: \"action_bar\"\n    DontRemoveShortcut: \"&cВи не можете прибрати рюкзак з інвентарю!\"\n    DontRemoveShortcut_SendMethod: \"action_bar\"\n    BackpackShrunk: \"&cВаш рюкзак зменшився! Деякі предмети впали на землю!\"\n    Open:\n      #Parameter: {TimeLeft} time in seconds till the backpack can be reopened, {TimeSpanLeft} time formatted as string till the backpack can be reopened\n      Cooldown: \"[{\\\"text\\\":\\\"Будь ласка, почекайте \\\",\\\"color\\\":\\\"dark_green\\\"},{\\\"text\\\":\\\"{TimeSpanLeft}\\\",\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"{TimeLeft} секунд\\\"}},{\\\"text\\\":\\\", перш ніж знову відкривати рюкзак.\\\"}]\"\n      #Parameter: {CurrentGameMode}, {AllowedGameModes}\n      WrongGameMode: \"Ви не маєте права відчиняти рюкзак у поточному режимі гри.\"\n    Clean:\n      BackpackCleaned: \"Рюкзак почищено\"\n      BackpackCleanedBy: \"Ваш рюкзак був почищен {DisplayName}&r.\"\n      BackpackCleanedOther: \"{DisplayName}&r Рюкзак був почищений.\"\n    Sort:\n      Sorted: \"Рюкзак відсортовано.\"\n    Help:\n      Header: \"&6### Minepacks Команди ###\"\n      Footer: \"&6#############################\"\n    Reload:\n      Reloading: \"&aПерезавантаження Minepacks...\"\n      Reloaded: \"&aMinepacks було перезавантажено!\"\n    Update:\n      CheckingForUpdates: \"&1Перевірка оновлень...\"\n      Updated: \"[\\\"\\\",{\\\"text\\\":\\\"Плагін було оновлено, він буде завантажен при наступному завантаженні.\\\",\\\"color\\\":\\\"yellow\\\"}]\"\n      NoUpdate: \"[\\\"\\\",{\\\"text\\\":\\\"Немає оновлень.\\\",\\\"color\\\":\\\"gold\\\"}]\"\n      UpdateFail: \"[\\\"\\\",{\\\"text\\\":\\\"Виникла проблема з пошуком оновлень! Будь ласка, перевірте консоль!\\\",\\\"color\\\":\\\"red\\\"}]\"\n      # You can change this message if you like to, but don't cry if the link isn't linking to the plugin anymore!\n      UpdateAvailable: \"[{\\\"text\\\":\\\"Доступно оновлення. Буль ласка, перейдіть по \\\\\\\"\\\",\\\"color\\\":\\\"green\\\"},{\\\"text\\\":\\\"https://www.spigotmc.org/resources/19286/\\\",\\\"color\\\":\\\"yellow\\\",\\\"underlined\\\":true,\\\"clickEvent\\\":{\\\"action\\\":\\\"open_url\\\",\\\"value\\\":\\\"https://www.spigotmc.org/resources/19286/\\\"}},{\\\"text\\\":\\\"\\\\\\\" цоб завантажити його!\\\"}]\"\n    Backup:\n      Created: \"Рюкзак успішно пройшов резервне копіювання.\"\n      NoBackpack: \"У гравця немає рюкзака або він порожній.\"\n    Restore:\n      BackupsPerPage: 10\n      Headline: \"[\\\"\\\",{\\\"text\\\":\\\"Бекапи\\\",\\\"color\\\":\\\"yellow\\\"},{\\\"text\\\":\\\" - \\\",\\\"color\\\":\\\"white\\\"},{\\\"text\\\":\\\"сторінка {CurrentPage}/{MaxPage}\\\",\\\"color\\\":\\\"gold\\\"}]\"\n      Footer: \"[{\\\"text\\\":\\\"<<< Попередня <<<\\\",\\\"color\\\":\\\"gray\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"run_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}--\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}--\\\"}},{\\\"text\\\":\\\" Показати сторінку {CurrentPage}/{MaxPage} \\\",\\\"color\\\":\\\"gold\\\"},{\\\"text\\\":\\\">>> Next >>>\\\",\\\"color\\\":\\\"gray\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"run_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}++\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}++\\\"}}]\"\n      BackupEntry: \"[\\\"\\\",{\\\"text\\\":\\\"{BackupIdentifier}\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"suggest_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {BackupIdentifier}\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"Користувач: {BackupPlayerName} ({BackupPlayerUUID})\\\\nСтворено: {BackupDate}\\\"}}]\"\n      NoValidBackup: \"Данного бекапа {BackupIdentifier}, не знайдено\"\n      NoUserToRestoreToFound: \"Не знайдено дійсного користувача для відновлення резервної копії\"\n      # No Json!!!\n      ParameterBackupName: \"backup_name\"\n      # No Json!!!\n      DateFormat: \"yyyy.MM.dd HH:mm:ss\"\n      Restored: \"Бекап успішно відновлено.\"\n    InventoryClear:\n      UnknownPlayer: \"&cНе вдалося дізнатися про {Name}!\"\n      Cleared: \"Інвентар відчищено.\"\n      ClearedOther: \"{DisplayName}&r інвентар був відчищен.\"\n      ClearedOtherTarget: \"Речі у вашому рюкзаку були вичищені {DisplayName}&r.\"\n    Pickup:\n      ToggleOn: \"&7Увімкнено автоматичний збір предметів було &aввімкнено&7.\"\n      ToggleOff: \"&7Увімкнено автоматичний збір предметів було &cвимкнено&7.\"\n  Commands:\n    HelpFormat: \"[\\\"\\\",{\\\"text\\\":\\\"/{MainCommand} {SubCommand} {Parameters}\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"suggest_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand}\\\"}},{\\\"text\\\":\\\" - \\\",\\\"color\\\":\\\"white\\\"},{\\\"text\\\":\\\"{Description}\\\",\\\"color\\\":\\\"aqua\\\"}]\"\n    PlayerNameVariable: \"player_name\"\n    Description:\n      Backpack: \"Відчинить рюкзак.\"\n      Sort: \"Відсортує рюкзак.\"\n      Clean: \"Відчистиь рюкзак.\"\n      CleanOthers: \"Відчистить рюкзак іншого гравця.\"\n      OpenOthers: \"Покаже рюкзак іншого гравця.\"\n      Reload: \"Перезавантажить налаштування.\"\n      Update: \"Перевіряє оновленя.\"\n      Version: \"Виводить інформацію про версію плагіна та його залежності.\"\n      Backup: \"Створює резервну копію рюкзака гравця.\"\n      BackupEveryone: \"Створює резервну копію всіх, хто зараз перебуває в мережі.\"\n      Restore: \"Відновлює резервну копію.\"\n      RestoreList: \"Показує всі доступні резервні копії.\"\n      Help: \"Показує всі доступні команди та їх опис.\"\n      Migrate: \"Переносить використовувану базу даних з одного типу в інший.\"\n      Pickup: \"Увімкнути стан автоматичного підбирання, коли інвентар буде заповнено.\"\n\nCommand:\n  Backpack:\n    - backpack\n    - bp\n  Open:\n    - open\n  Sort:\n    - sort\n  Clean:\n    - clean\n    - clear\n    - empty\n  Reload:\n    - reload\n    - restart\n  Update:\n    - update\n  Backup:\n    - backup\n  Restore:\n    - restore\n  ListBackups:\n    - listbackups\n  Version:\n    - version\n  Help:\n    - help\n  InventoryClear:\n    - clear\n    - inventoryclear\n    - clean\n  Pickup:\n    - pickup\n\n# Will be shown in the console during startup\nLanguageName: \"українська\"\nAuthor: \"Andrii(IsPlayer)\"\n\n# Language file version. Don't touch it!\nVersion: 21"
  },
  {
    "path": "Minepacks/resources/lang/vi.yml",
    "content": "# To simplify the customisation and translation process please check out the editor: https://ptp.pcgamingfreaks.at\nLanguage:\n  NotFromConsole: \"&cCommand không sử dụng được từ bảng điều khiển.\"\n  Ingame:\n    NoPermission: \"&cBạn không có quyền làm điều đó.\"\n    WorldDisabled: \"&cViệc sử dụng ba lô không được phép trong thế giới này.\"\n    NaN: \"[\\\"\\\",{\\\"text\\\":\\\"Giá trị đã nhập không phải là số!\\\",\\\"color\\\":\\\"red\\\"}]\"\n    OwnBackpackClose: \"Ba lô đóng lại!\"\n    OwnBackpackClose_SendMethod: \"action_bar\"\n    # Parameter: {OwnerName}, {OwnerDisplayName}\n    PlayerBackpackClose: \"Ba lô của {OwnerName} đã đóng!\"\n    PlayerBackpackClose_SendMethod: \"action_bar\"\n    InvalidBackpack: \"Ba lô không hợp lệ.\"\n    NotAllowedInBackpack: \"&c{ItemName} không được phép để trong ba lô.\"\n    NotAllowedInBackpack_SendMethod: \"action_bar\"\n    DontRemoveShortcut: \"&cBạn không được xóa phím tắt ba lô khỏi hành trang của mình!\"\n    DontRemoveShortcut_SendMethod: \"action_bar\"\n    BackpackShrunk: \"&cBa lô của bạn đã bị thu nhỏ! Một số vật phẩm đã rơi xuống đất!\"\n    Open:\n      # Parameter: {TimeLeft} time in seconds till the backpack can be reopened, {TimeSpanLeft} time formatted as string till the backpack can be reopened\n      Cooldown: \"[{\\\"text\\\":\\\"Vui lòng đợi \\\",\\\"color\\\":\\\"dark_green\\\"},{\\\"text\\\":\\\"{TimeSpanLeft}\\\",\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"{ TimeLeft} seconds\\\"}},{\\\"text\\\":\\\" cho đến khi bạn mở lại ba lô của mình.\\\"}]\"\n      # Parameter: {CurrentGameMode}, {AllowedGameModes}\n      WrongGameMode: \"Bạn không được phép mở ba lô trong chế độ trò chơi hiện tại.\"\n    Clean:\n      BackpackCleaned: \"Đã xóa ba lô.\"\n      BackpackCleanedBy: \"Ba lô của bạn đã bị xóa bởi {DisplayName}&r.\"\n      BackpackCleanedOther: \"Ba lô của {DisplayName} đã bị xóa.\"\n    Sort:\n      Sorted: \"Ba lô được sắp xếp.\"\n    Help:\n      Header: \"&6### Lệnh Minepacks ###\"\n      Footer: \"&6############################\"\n    Reload:\n      Reloading: \"&1Đang tải lại Minepack ...\"\n      Reloaded: \"&1Gói mỏ đã được tải lại!\"\n    Update:\n      CheckingForUpdates: \"&1Đang kiểm tra các bản cập nhật ...\"\n      Updated: \"[\\\"\\\",{\\\"text\\\":\\\"Plugin đã cập nhật, sẽ được tải vào lần khởi động lại/tải lại tiếp theo.\\\",\\\"color\\\":\\\"yellow\\\"}]\"\n      NoUpdate: \"[\\\"\\\",{\\\"text\\\":\\\"Không có bản cập nhật plugin.\\\",\\\"color\\\":\\\"gold\\\"}]\"\n      UpdateFail: \"[\\\"\\\",{\\\"text\\\":\\\"Đã xảy ra sự cố khi tìm kiếm bản cập nhật! Vui lòng kiểm tra bảng điều khiển!\\\",\\\"color\\\":\\\"red\\\"}]\"\n      # You can change this message if you like to, but don't cry if the link isn't linking to the plugin anymore!\n      UpdateAvailable: \"[{\\\"text\\\":\\\"Có bản cập nhật ! \\\\\\\"\\\",\\\"color\\\":\\\"green\\\"},{\\\"text\\\":\\\"https://www.spigotmc.org/resources/19286/\\\",\\\"color\\\":\\\"yellow\\\",\\\"underlined\\\":true,\\\"clickEvent\\\":{\\\"action\\\":\\\"open_url\\\",\\\"value\\\":\\\"https://www.spigotmc.org/resources/19286/\\\"}},{\\\"text\\\":\\\"\\\\\\\" để tải xuống!\\\"}]\"\n    Backup:\n      Created: \"Ba lô đã được sao lưu thành công.\"\n      NoBackpack: \"Người chơi không có ba lô hoặc ba lô của anh ta trống rỗng.\"\n    Restore:\n      BackupsPerPage: 10\n      Headline: \"[\\\"\\\",{\\\"text\\\":\\\"Sao lưu\\\",\\\"color\\\":\\\"yellow\\\"},{\\\"text\\\":\\\" - \\\",\\\"color\\\":\\\"white\\\"},{\\\"text\\\":\\\"hiển thị trang {Trang hiện tại }/{MaxPage}\\\",\\\"color\\\":\\\"gold\\\"}]\"\n      Footer: \"[{\\\"text\\\":\\\"<<< Trang sau <<<\\\",\\\"color\\\":\\\"gray\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"run_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}--\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}--\\\"}},{\\\"text\\\":\\\" Hiện trang {CurrentPage}/{MaxPage} \\\",\\\"color\\\":\\\"gold\\\"},{\\\"text\\\":\\\">>> Trang tiếp >>>\\\",\\\"color\\\":\\\"gray\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"run_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}++\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}++\\\"}}]\"\n      BackupEntry: \"[\\\"\\\",{\\\"text\\\":\\\"{BackupIdentifier}\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"suggest_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {BackupIdentifier}\\\"},\\\"hoverEvent\\\": {\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"Người dùng: {BackupPlayerName} ({BackupPlayerUUID})\\\\nĐã tạo: {BackupDate}\\\"}}]\"\n      NoValidBackup: \"Không tìm thấy bản sao lưu phù hợp {BackupIdentifier}\"\n      NoUserToRestoreToFound: \"Không có người dùng hợp lệ nào để khôi phục bản sao lưu vào tìm thấy\"\n      # No Json!!!\n      ParameterBackupName: \"backup_name\"\n      # No Json!!!\n      DateFormat: \"yyyy.MM.dd HH:mm:ss\"\n      Restored: \"Sao lưu đã được khôi phục thành công.\"\n    InventoryClear:\n      UnknownPlayer: \"&cKhông thể tìm thấy người chơi {Name}!\"\n      Cleared: \"Đã xóa hàng tồn kho.\"\n      ClearedOther: \"Khoảng không quảng cáo của {DisplayName} đã bị xóa.\"\n      ClearedOtherTarget: \"Khoảng không quảng cáo của bạn đã được xóa bởi {DisplayName}&r.\"\n    Pickup:\n      ToggleOn: \"&7Bộ sưu tập vật phẩm tự động đã được bật &bẬT&7.\"\n      ToggleOff: \"&7Tính năng thu thập vật phẩm tự động đã được bật &cTẮT&7.\"\n  Commands:\n    HelpFormat: \"[\\\"\\\",{\\\"text\\\":\\\"/{MainCommand} {SubCommand} {Parameters}\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"suggest_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand}\\\"}} ,{\\\"text\\\":\\\" - \\\",\\\"color\\\":\\\"white\\\"},{\\\"text\\\":\\\"{Description}\\\",\\\"color\\\":\\\"aqua\\\"}]\"\n    PlayerNameVariable: \"tên người chơi\"\n    Description:\n      Backpack: \"Mở ba lô của bạn.\"\n      Sort: \"Sắp xếp ba lô của bạn.\"\n      Clean: \"Làm sạch ba lô của bạn.\"\n      CleanOthers: \"Dọn dẹp ba lô của người chơi khác.\"\n      OpenOthers: \"Hiển thị ba lô của người chơi khác.\"\n      Reload: \"Tải lại cấu hình của plugin.\"\n      Update: \"Kiểm tra các bản cập nhật plugin mới.\"\n      Version: \"In chi tiết phiên bản về plugin và phần phụ thuộc của nó.\"\n      Backup: \"Tạo bản sao lưu ba lô của người chơi.\"\n      BackupEveryone: \"Tạo bản sao lưu của mọi người hiện đang trực tuyến.\"\n      Restore: \"Khôi phục một bản sao lưu.\"\n      RestoreList: \"Liệt kê tất cả các bản sao lưu có sẵn.\"\n      Help: \"Hiển thị tất cả các lệnh có sẵn và mô tả của chúng.\"\n      Migrate: \"Di chuyển cơ sở dữ liệu đã sử dụng từ loại này sang loại khác.\"\n      Pickup: \"Chuyển đổi trạng thái lấy hàng tự động khi kho đầy.\"\nCommand:\n  Backpack:\n    - backpack\n    - bp\n  Open:\n    - open\n  Sort:\n    - sort\n  Clean:\n    - clean\n    - clear\n    - empty\n  Reload:\n    - reload\n    - restart\n  Update:\n    - update\n  Backup:\n    - backup\n  Restore:\n    - restore\n  ListBackups:\n    - listbackups\n  Version:\n    - version\n  Help:\n    - help\n  InventoryClear:\n    - clear\n    - inventoryclear\n    - clean\n  Pickup:\n    - pickup\n# Will be shown in the console during startup\nLanguageName: \"Vietnamese\"\nAuthor: \"RageOfFire\"\n# Language file version. Don't touch it!\nVersion: 21\n"
  },
  {
    "path": "Minepacks/resources/lang/zh_cn.yml",
    "content": "# To simplify the customisation and translation process please check out the editor: https://ptp.pcgamingfreaks.at\n\nLanguage:\n  NotFromConsole: \"&c命令无法从控制台使用。\"\n  Ingame:\n    NoPermission: \"&c你没有权限这么做。\"\n    WorldDisabled: \"&c该世界不允许使用背包。\"\n    NaN: \"[\\\"\\\",{\\\"text\\\":\\\"输入的值不是数字！\\\",\\\"color\\\":\\\"red\\\"}]\"\n    OwnBackpackClose: \"背包关闭！\"\n    OwnBackpackClose_SendMethod: \"action_bar\"\n    # Parameter: {OwnerName}, {OwnerDisplayName}\n    PlayerBackpackClose: \"{OwnerName} 的背包已关闭！\"\n    PlayerBackpackClose_SendMethod: \"action_bar\"\n    InvalidBackpack: \"无效的背包。\"\n    NotAllowedInBackpack: \"&c{ItemName} 不允许放在背包里。\"\n    NotAllowedInBackpack_SendMethod: \"action_bar\"\n    DontRemoveShortcut: \"&c你不能从你的物品栏中删除背包快捷方式！\"\n    DontRemoveShortcut_SendMethod: \"action_bar\"\n    BackpackShrunk: \"&c你的背包缩小了！一些物品掉到了地上！\"\n    Open:\n      # Parameter: {TimeLeft} time in seconds till the backpack can be reopened, {TimeSpanLeft} time formatted as string till the backpack can be reopened\n      Cooldown: \"[{\\\"text\\\":\\\"请等待 \\\",\\\"color\\\":\\\"dark_green\\\"},{\\\"text\\\":\\\"{TimeSpanLeft}\\\",\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"{TimeLeft} 秒\\\"}},{\\\"text\\\":\\\" 才能重新打开背包。\\\"}]\"\n      # Parameter: {CurrentGameMode}, {AllowedGameModes}\n      WrongGameMode: \"在当前游戏模式下，你不允许打开背包。\"\n    Clean:\n      BackpackCleaned: \"背包已清空\"\n      BackpackCleanedBy: \"您的背包 {DisplayName} 已被清空&r。\"\n      BackpackCleanedOther: \"{DisplayName} &r的背包已经清除。\"\n    Sort:\n      Sorted: \"整理背包\"\n    Help:\n      Header: \"&6### Minepacks 指令 ###\"\n      Footer: \"&6#############################\"\n    Reload:\n      Reloading: \"&3重载 Minepacks 中……\"\n      Reloaded: \"&aMinepacks 已重载！\"\n    Update:\n      CheckingForUpdates: \"&3检查更新中…\"\n      Updated: \"[\\\"\\\",{\\\"text\\\":\\\"插件已更新，将在下次重启时加载.\\\",\\\"color\\\":\\\"yellow\\\"}]\"\n      NoUpdate: \"[\\\"\\\",{\\\"text\\\":\\\"没有更新的插件.\\\",\\\"color\\\":\\\"gold\\\"}]\"\n      UpdateFail: \"[\\\"\\\",{\\\"text\\\":\\\"在查找更新时出现了问题！请检查控制台！\\\",\\\"color\\\":\\\"red\\\"}]\"\n      # You can change this message if you like to, but don't cry if the link isn't linking to the plugin anymore!\n      UpdateAvailable: \"[{\\\"text\\\":\\\"有一个可用的更新！请浏览 \\\\\\\"\\\",\\\"color\\\":\\\"green\\\"},{\\\"text\\\":\\\"${project.url}\\\",\\\"color\\\":\\\"yellow\\\",\\\"underlined\\\":true,\\\"clickEvent\\\":{\\\"action\\\":\\\"open_url\\\",\\\"value\\\":\\\"${project.url}\\\"}},{\\\"text\\\":\\\"\\\\\\\" 去下载!\\\"}]\"\n    Backup:\n      Created: \"背包备份成功。\"\n      NoBackpack: \"玩家没有背包或者背包是空的。\"\n    Restore:\n      BackupsPerPage: \"10\"\n      Headline: \"[\\\"\\\",{\\\"text\\\":\\\"备份\\\",\\\"color\\\":\\\"yellow\\\"},{\\\"text\\\":\\\" - \\\",\\\"color\\\":\\\"white\\\"},{\\\"text\\\":\\\"页面 {CurrentPage}/{MaxPage}\\\",\\\"color\\\":\\\"gold\\\"}]\"\n      Footer: \"[{\\\"text\\\":\\\"<<< 上一页 <<<\\\",\\\"color\\\":\\\"gray\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"run_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}--\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}--\\\"}},{\\\"text\\\":\\\" 当前页面 {CurrentPage}/{MaxPage} \\\",\\\"color\\\":\\\"gold\\\"},{\\\"text\\\":\\\">>> 下一页 >>>\\\",\\\"color\\\":\\\"gray\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"run_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}++\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {CurrentPage}++\\\"}}]\"\n      BackupEntry: \"[\\\"\\\",{\\\"text\\\":\\\"{BackupIdentifier}\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"suggest_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand} {BackupIdentifier}\\\"},\\\"hoverEvent\\\":{\\\"action\\\":\\\"show_text\\\",\\\"value\\\":\\\"User: {BackupPlayerName} ({BackupPlayerUUID})\\\\nCreated: {BackupDate}\\\"}}]\"\n      NoValidBackup: \"没有找到匹配 {BackupIdentifier} 的备份\"\n      NoUserToRestoreToFound: \"没有有效用户可将备份恢复到已找到的位置\"\n      # No Json!!!\n      ParameterBackupName: \"backup_name\"\n      # No Json!!!\n      DateFormat: \"yyyy.MM.dd HH:mm:ss\"\n      Restored: \"备份已成功恢复。\"\n    InventoryClear:\n      UnknownPlayer: \"&c找不到玩家 {Name}！\"\n      Cleared: \"背包东西清空。\"\n      ClearedOther: \"{DisplayName} &r的背包东西已经清空。\"\n      ClearedOtherTarget: \"已经清空了 {DisplayName} 的背包&r。\"\n    Pickup:\n      ToggleOn: \"&7自动物品收集已&a开启&7。\"\n      ToggleOff: \"&7自动物品收集已&c关闭&7。\"\n  Commands:\n    HelpFormat: \"[\\\"\\\",{\\\"text\\\":\\\"/{MainCommand} {SubCommand} {Parameters}\\\",\\\"clickEvent\\\":{\\\"action\\\":\\\"suggest_command\\\",\\\"value\\\":\\\"/{MainCommand} {SubCommand}\\\"}},{\\\"text\\\":\\\" - \\\",\\\"color\\\":\\\"white\\\"},{\\\"text\\\":\\\"{Description}\\\",\\\"color\\\":\\\"aqua\\\"}]\"\n    PlayerNameVariable: \"player_name\"\n    Description:\n      Backpack: \"打开你的背包。\"\n      Sort: \"整理你的背包。\"\n      Clean: \"清空你的背包。\"\n      CleanOthers: \"清空其他玩家的背包。\"\n      OpenOthers: \"这是另一个玩家的背包。\"\n      Reload: \"重新加载插件的配置。\"\n      Update: \"检查新的插件更新。\"\n      Version: \"输出关于插件及其依赖项的版本详细信息。\"\n      Backup: \"创建玩家背包的备份。\"\n      BackupEveryone: \"创建当前在线的所有人的备份。\"\n      Restore: \"恢复备份。\"\n      RestoreList: \"列出所有可用的备份。\"\n      Help: \"显示所有可用命令及其描述。\"\n      Migrate: \"将使用的数据库从一种类型迁移到另一种类型。\"\n      Pickup: \"在物品栏已满时切换自动收集的状态。\"\nCommand:\n  Backpack:\n    - backpack\n    - bp\n  Open:\n    - open\n  Sort:\n    - sort\n  Clean:\n    - clean\n    - clear\n    - empty\n  Reload:\n    - reload\n    - restart\n  Update:\n    - update\n  Backup:\n    - backup\n  Restore:\n    - restore\n  ListBackups:\n    - listbackups\n  Version:\n    - version\n  Help:\n    - help\n  InventoryClear:\n    - clear\n    - inventoryclear\n    - clean\n  Pickup:\n    - pickup\n\n# Will be shown in the console during startup\nLanguageName: \"简体中文\"\nAuthor: \"YaoSiQian, Liou_Yang\"\n\n# Language file version. Don't touch it!\nVersion: 21\n"
  },
  {
    "path": "Minepacks/resources/lang/zh_tw.yml",
    "content": "Language:\n    NotFromConsole: \"&c指令不能從控制台使用\"\n    Ingame:\n        NoPermission: \"&c你沒有權限使用\"\n        WorldDisabled: \"&c這個世界不允許使用背包\"\n        NaN: '[\"\",{\"text\":\"輸入的值不是數字!\",\"color\":\"red\"}]'\n        OwnBackpackClose: 背包關閉!\n        OwnBackpackClose_SendMethod: action_bar\n        PlayerBackpackClose: \"{OwnerName} 關閉背包!\"\n        PlayerBackpackClose_SendMethod: action_bar\n        InvalidBackpack: 無效的背包。\n        NotAllowedInBackpack: \"&c{ItemName} 不允許放在背包裡。\"\n        NotAllowedInBackpack_SendMethod: action_bar\n        DontRemoveShortcut: \"&c您不得從庫存中刪除背包快捷方式!\"\n        DontRemoveShortcut_SendMethod: action_bar\n        BackpackShrunk: \"&c你的背包縮小了！一些物品掉到了地上！\"\n        Open:\n            Cooldown: '[{\"text\":\"請稍等\n                \",\"color\":\"dark_green\"},{\"text\":\"{TimeSpanLeft}\",\"hoverEvent\":{\"action\":\"show_text\",\"value\":\"{TimeLeft}\n                秒\"}},{\"text\":\" 直到你重新打開你的背包。\"}]'\n            WrongGameMode: 你不能在當前遊戲模式下打開背包。\n        Clean:\n            BackpackCleaned: 背包已清空\n            BackpackCleanedBy: 您的背包已被清空 {DisplayName}&r。\n            BackpackCleanedOther: \"{DisplayName}'s&r 背包已清空。\"\n        Sort:\n            Sorted: 整理背包。\n        Help:\n            Header: \"&6### 擴充背包 指令幫助 ###\"\n            Footer: \"&6#############################\"\n        Reload:\n            Reloading: \"&3正在重新讀取 Minepacks ...\"\n            Reloaded: \"&3Minepacks 重新讀取完畢! 翻譯版本 19 Specialbase#0428 & dirtTW\"\n        Update:\n            CheckingForUpdates: \"&1檢查更新 ...\"\n            Updated: '[\"\",{\"text\":\"插件已經更新，重新啟動伺服器後生效/reload。\",\"color\":\"yellow\"}]'\n            NoUpdate: '[\"\",{\"text\":\"沒有更新的版本。\",\"color\":\"gold\"}]'\n            UpdateFail: '[\"\",{\"text\":\"查找更新時出現問題！ 請檢查控制台!\",\"color\":\"red\"}]'\n            UpdateAvailable: '[{\"text\":\"有更新可用！ 請前往\n                \\\"\",\"color\":\"green\"},{\"text\":\"https://www.spigotmc.org/resources/19286/\",\"color\":\"yellow\",\"underlined\":true,\"clickEvent\":{\"action\":\"open_url\",\"value\":\"https://www.spigotmc.org/resources/19286/\"}},{\"text\":\"\\\"\n                to download it!\"}]'\n        Backup:\n            Created: 背包回復成功。\n            NoBackpack: 玩家沒有背包或他的背包是空的\n        Restore:\n            BackupsPerPage: 10\n            Headline: '[\"\",{\"text\":\"回復\",\"color\":\"yellow\"},{\"text\":\" -\n                \",\"color\":\"white\"},{\"text\":\"顯示頁面\n                {CurrentPage}/{MaxPage}\",\"color\":\"gold\"}]'\n            Footer: '[{\"text\":\"<<< 上一頁\n                <<<\",\"color\":\"gray\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/{MainCommand}\n                {SubCommand}\n                {CurrentPage}--\"},\"hoverEvent\":{\"action\":\"show_text\",\"value\":\"/{MainCommand}\n                {SubCommand} {CurrentPage}--\"}},{\"text\":\" Showing page\n                {CurrentPage}/{MaxPage} \",\"color\":\"gold\"},{\"text\":\">>> 下一頁\n                >>>\",\"color\":\"gray\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/{MainCommand}\n                {SubCommand}\n                {CurrentPage}++\"},\"hoverEvent\":{\"action\":\"show_text\",\"value\":\"/{MainCommand}\n                {SubCommand} {CurrentPage}++\"}}]'\n            BackupEntry:\n                '[\"\",{\"text\":\"{BackupIdentifier}\",\"clickEvent\":{\"action\":\"suggest_command\",\"value\":\"/{MainCommand}\n                {SubCommand}\n                {BackupIdentifier}\"},\"hoverEvent\":{\"action\":\"show_text\",\"value\":\"User:\n                {BackupPlayerName} ({BackupPlayerUUID})\\nCreated: {BackupDate}\"}}]'\n            NoValidBackup: \"無法尋找備份 {BackupIdentifier} \"\n            NoUserToRestoreToFound: 找不到可將備份還原到的有效用戶\n            ParameterBackupName: backup_name\n            DateFormat: yyyy.MM.dd HH:mm:ss\n            Restored: 還原備份成功\n        InventoryClear:\n            UnknownPlayer: \"&c找不到玩家 {Name}!\"\n            Cleared: 清空背包。\n            ClearedOther: \"{DisplayName}&r 已清空背包。\"\n            ClearedOtherTarget: \"你的背包已遭清空 {DisplayName}&r。\"\n        Pickup:\n            ToggleOn: \"&7自動物品收集已切換為 &a開&7。\"\n            ToggleOff: \"&7自動物品收集已切換為 &c關&7。\"\n    Commands:\n        HelpFormat: '[\"\",{\"text\":\"/{MainCommand} {SubCommand}\n            {Parameters}\",\"clickEvent\":{\"action\":\"suggest_command\",\"value\":\"/{MainCommand}\n            {SubCommand}\"}},{\"text\":\" -\n            \",\"color\":\"white\"},{\"text\":\"{Description}\",\"color\":\"aqua\"}]'\n        PlayerNameVariable: player_name\n        Description:\n            Backpack: 開啟你的背包\n            Sort: 整理你的背包\n            Clean: 清空你的背包\n            CleanOthers: 清理其他玩家的背包\n            OpenOthers: 看茶另一個玩家的背包\n            Reload: 重新整理這個插件\n            Update: 檢查更新\n            Version: 列出有關插件及其依賴項的版本詳細信息\n            Backup: 新增玩家背包的備份。\n            BackupEveryone: 建立目前在線所有人的備份。\n            Restore: 恢復備份。\n            RestoreList: 列出所有玩家的備份。\n            Help: 顯示此指令表。\n            Migrate: 將使用的數據庫從一種類型遷移到另一種類型。\n            Pickup: 切換背包庫存滿時的自動拾取狀態。\nCommand:\n    Backpack:\n        - backpack\n        - bp\n        - bag\n    Open:\n        - open\n    Sort:\n        - sort\n    Clean:\n        - clean\n        - clear\n        - empty\n    Reload:\n        - reload\n        - restart\n    Update:\n        - update\n    Backup:\n        - backup\n    Restore:\n        - restore\n    ListBackups:\n        - listbackups\n    Version:\n        - version\n    Help:\n        - help\n    InventoryClear:\n        - clear\n        - inventoryclear\n        - clean\n    Pickup:\n        - pickup\nLanguageName: 繁體中文\nAuthor: Specialbase#0428 & dirtTW\nVersion: 21"
  },
  {
    "path": "Minepacks/resources/plugin.yml",
    "content": "name: \"${project.name}\"\nauthor: \"${author}\"\nwebsite: \"${project.url}\"\nmain: \"${mainClass}\"\ndescription: \"${project.description}\"\nversion: \"${pluginVersion}\"\napi-version: \"1.13\"\ndepend: [${dependencies}]\nsoftdepend: [MVdWPlaceholderAPI, PlaceholderAPI ${soft-dependencies}]\nfolia-supported: true\n\npermissions:\n  backpack.*:\n    description: Gives access to the full Minepacks functionality.\n    children:\n      backpack.use: true\n      backpack.size.6: true\n      backpack.keepOnDeath: true\n      backpack.clean: true\n      backpack.fullpickup: true\n      backpack.fullpickup.toggle: true\n      backpack.bypass: true\n      backpack.admin: true\n  backpack.disable:\n    description: This permission group can be used to disable the plugin for certian users/groups/worlds.\n    default: false\n    children:\n      backpack.use: false\n      backpack.others: false\n      backpack.keepOnDeath: true\n      backpack.clean: false\n  backpack.user:\n    description: This permission can be used to give a user the basic backpack size and allow him to use the backpack.\n    children:\n      backpack.use: true\n      backpack.size.1: true\n      backpack.clean: true\n      backpack.sort: true\n  backpack.userBig:\n    description: This permission can be used to give a user the biggest backpack size and allow him to use the backpack.\n    children:\n      backpack.use: true\n      backpack.size.6: true\n      backpack.clean: true\n      backpack.sort: true\n  backpack.bypass:\n    children:\n      backpack.ignoreGameMode: true\n      backpack.ignoreWorldBlacklist: true\n      backpack.noCooldown: true\n  backpack.admin:\n    children:\n      backpack.others: true\n      backpack.others.edit: true\n      backpack.clean.others: true\n      backpack.update: true\n      backpack.reload: true\n      backpack.migrate: true\n  backpack.use:\n    description: Allows a player to open the backpack.\n    default: false\n  backpack.size.1:\n    description: Mini size for a backpack, if the player has backpack permission he will also have at least a backpack with the size 1.\n    default: false\n  backpack.size.2:\n    description: 2*9 backpack\n    default: false\n  backpack.size.3:\n    description: 3*9 backpack\n    default: false\n  backpack.size.4:\n    description: 4*9 backpack\n    default: false\n  backpack.size.5:\n    description: 5*9 backpack\n    default: false\n  backpack.size.6:\n    description: 6*9 backpack\n    default: false\n  backpack.sort:\n    description: Allows the player to sort their own backpack.\n    default: false\n  backpack.clean:\n    description: Allows the player to clean their own backpack.\n    default: false\n  backpack.fullpickup:\n    description: Allows the player to automatically pick up items when their inventory is full (function needs to be enabled in the config)\n    default: true\n  backpack.fullpickup.toggle:\n    description: Allows the player to toggle the automatic pickup feature.\n    default: true\n  backpack.clean.other:\n    description: Allows the player to clean other players backpacks.\n    default: op\n    children:\n      backpack.clean: true\n  backpack.others:\n    description: Allows the player open backpacks of other players.\n    default: op\n  backpack.others.edit:\n    description: Allows the player to edit backpacks of other players.\n    default: op\n    children:\n      backpack.others: true\n  backpack.keepOnDeath:\n    description: Allows the player to keep their items in their backpack on death.\n    default: op\n  backpack.noCooldown:\n    description: Allows to bypass the cooldown to open the backpack.\n    default: op\n  backpack.ignoreGameMode:\n    description: Allows to bypass the game-mode restriction.\n    default: op\n  backpack.ignoreWorldBlacklist:\n    description: Allows to bypass the world blacklist.\n    default: op\n  backpack.update:\n    description: Allows to update the plugin.\n    default: op\n  backpack.reload:\n    description: Allows to reload the config.\n    default: op\n  backpack.migrate:\n    description: Allows migrating data from one format to another.\n    default: op\n  backpack.backup:\n    description: Allows to create a backup of a backpack.\n    default: op\n  backpack.restore:\n    description: Allows to restore a backup of a backpack.\n    default: op\n  backpack.version:\n    description: Allows to print the version details of the plugin and it's dependencies.\n    default: op\n  clearInventory:\n    description: Allows the player to clear their own inventory.\n    default: op\n  clearInventory.other:\n    description: Allows the player to clear the inventory of other players.\n    default: op\n    children:\n      clearInventory: true\n"
  },
  {
    "path": "Minepacks/resources/update.yml",
    "content": "UpdateProviders:\n  Bukkit:\n    Type: Bukkit\n    ProjectId: 83445\n  Spigot:\n    Type: Spigot\n    ProjectId: 19286\n    Filename: \"minepacks.jar\"\n  GitHub:\n    Type: GitHub\n    Owner: GeorgH93\n    Repo: Minepacks\n  GitHubStandalone:\n    Type: GitHub\n    Owner: GeorgH93\n    Repo: Minepacks\n    JarSearch: \".*-Standalone\\\\.jar\"\n  GitHubRelease:\n    Type: GitHub\n    Owner: GeorgH93\n    Repo: Minepacks\n    JarSearch: \".*-Release\\\\.jar\"\n  JenkinsMaster:\n    Type: Jenkins\n    Server: \"https://ci.pcgamingfreaks.at\"\n    Job: \"Minepacks\"\n  JenkinsMasterStandalone:\n    Type: Jenkins\n    Server: \"https://ci.pcgamingfreaks.at\"\n    Job: \"Minepacks\"\n    Filter: \".*-Standalone.jar\"\n  JenkinsMasterRelease:\n    Type: Jenkins\n    Server: \"https://ci.pcgamingfreaks.at\"\n    Job: \"Minepacks\"\n    Filter: \".*-Release.jar\"\n  JenkinsDev:\n    Type: Jenkins\n    Server: \"https://ci.pcgamingfreaks.at\"\n    Job: \"Minepacks Dev\"\n\nUpdateChannels:\n  Release:\n    Release: [ Bukkit, Spigot, GitHubRelease ]\n    Standalone: [ GitHubStandalone ]\n    Normal: [ GitHub ]\n  Master:\n    Release: [ JenkinsMasterRelease ]\n    Standalone: [ JenkinsMasterStandalone ]\n    Normal: [ JenkinsMaster ]\n  Dev:\n    Normal: [ JenkinsDev ]\n\nDefaultChannel: \"${updateChannel}\"\nReleaseType: \"${releaseType}\""
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Backpack.java",
    "content": "/*\n *   Copyright (C) 2024 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit;\n\nimport at.pcgamingfreaks.Bukkit.MCVersion;\nimport at.pcgamingfreaks.Bukkit.Message.Message;\nimport at.pcgamingfreaks.Bukkit.Util.InventoryUtils;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Database.Helper.InventoryCompressor;\nimport at.pcgamingfreaks.Util.StringUtils;\n\nimport org.bukkit.Bukkit;\nimport org.bukkit.Location;\nimport org.bukkit.OfflinePlayer;\nimport org.bukkit.entity.Player;\nimport org.bukkit.inventory.Inventory;\nimport org.bukkit.inventory.ItemStack;\nimport org.jetbrains.annotations.NotNull;\nimport org.jetbrains.annotations.Nullable;\n\nimport lombok.AccessLevel;\nimport lombok.Getter;\nimport lombok.Setter;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.UUID;\nimport java.util.concurrent.ConcurrentHashMap;\n\npublic class Backpack implements at.pcgamingfreaks.Minepacks.Bukkit.API.Backpack\n{\n\t@Setter(AccessLevel.PACKAGE) private static ShrinkApproach shrinkApproach = ShrinkApproach.COMPRESS;\n\t@Setter(AccessLevel.PACKAGE) private static Message messageBackpackShrunk = new Message(\"Backpack shrunk!\");\n\tprivate static Object titleOwnGlobal;\n\tprivate static String titleFormat, titleOtherFormat;\n\tprivate static boolean useDynTitle;\n\tprivate final Object titleOwn;\n\tprivate final String titleOther;\n\t@Getter private final UUID ownerId;\n\tprivate final Map<Player, Boolean> opened = new ConcurrentHashMap<>(); //Thanks Minecraft 1.14\n\tprivate Inventory bp;\n\t@Getter private int size;\n\t@Getter @Setter private int ownerDatabaseId;\n\tprivate boolean hasChanged;\n\n\tpublic static void setTitle(final @NotNull String title, final @NotNull String titleOther)\n\t{\n\t\ttitleOwnGlobal = title.contains(\"%s\") ? null : InventoryUtils.prepareTitleForOpenInventoryWithCustomTitle(title);\n\t\ttitleFormat = title;\n\t\ttitleOtherFormat = titleOther;\n\t\tuseDynTitle = !title.equals(titleOther);\n\t}\n\n\tpublic Backpack(OfflinePlayer owner)\n\t{\n\t\tthis(owner, 9);\n\t}\n\t\n\tpublic Backpack(OfflinePlayer owner, int size)\n\t{\n\t\tthis(owner, size, -1);\n\t}\n\n\tpublic Backpack(OfflinePlayer owner, int size, int ID)\n\t{\n\t\tif(MCVersion.isNewerOrEqualThan(MCVersion.MC_1_14) && size > 54)\n\t\t{\n\t\t\tsize = 54;\n\t\t\tMinepacks.getInstance().getLogger().warning(\"Backpacks with more than 6 rows are no longer supported on Minecraft 1.14 and up!\");\n\t\t}\n\t\tthis.ownerId = owner.getUniqueId();\n\t\ttitleOther = StringUtils.limitLength(String.format(titleOtherFormat, owner.getName()), 32);\n\t\tbp = Bukkit.createInventory(this, size, titleOther);\n\t\tthis.size = size;\n\t\townerDatabaseId = ID;\n\n\t\tif (titleOwnGlobal != null) titleOwn = titleOwnGlobal;\n\t\telse titleOwn = InventoryUtils.prepareTitleForOpenInventoryWithCustomTitle(String.format(titleFormat, owner.getName()));\n\t}\n\t\n\tpublic Backpack(final OfflinePlayer owner, ItemStack[] backpack, final int ID)\n\t{\n\t\tthis(owner, backpack.length, ID);\n\t\tif(MCVersion.isNewerOrEqualThan(MCVersion.MC_1_14) && backpack.length > 54)\n\t\t{ // Try to optimize space usage to compress items into only 6 rows\n\t\t\tInventoryCompressor compressor = new InventoryCompressor(backpack, 54);\n\t\t\tfinal List<ItemStack> toMuch = compressor.compress();\n\t\t\tbackpack = compressor.getTargetStacks();\n\t\t\tif(!toMuch.isEmpty())\n\t\t\t{\n\t\t\t\tMinepacks.getInstance().getLogger().warning(owner.getName() + \"'s backpack has to many items.\");\n\t\t\t\tif(owner.isOnline())\n\t\t\t\t{\n\t\t\t\t\tMinepacks.getScheduler().runNextTick(task -> {\n\t\t\t\t\t\tif(owner.isOnline())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tPlayer player = owner.getPlayer();\n\t\t\t\t\t\t\tassert player != null;\n\t\t\t\t\t\t\tMinepacks.getScheduler().runAtEntity(player, task1 -> {\n\t\t\t\t\t\t\t\tMap<Integer, ItemStack> left = player.getInventory().addItem(toMuch.toArray(new ItemStack[0]));\n\t\t\t\t\t\t\t\tleft.forEach((id, stack) -> player.getWorld().dropItemNaturally(player.getLocation(), stack));\n\t\t\t\t\t\t\t\tthis.setChanged();\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\telse throw new RuntimeException(\"Backpack to big for MC 1.14 and up!\");\n\t\t\t}\n\t\t}\n\t\tbp.setContents(backpack);\n\t}\n\n\t@Override\n\t@Deprecated\n\tpublic @NotNull OfflinePlayer getOwner()\n\t{\n\t\treturn Bukkit.getServer().getOfflinePlayer(ownerId);\n\t}\n\n\t@Override\n\tpublic @Nullable Player getOwnerPlayer()\n\t{\n\t\treturn Bukkit.getServer().getPlayer(ownerId);\n\t}\n\n\tpublic void checkResize()\n\t{\n\t\tPlayer owner = Bukkit.getServer().getPlayer(this.ownerId);\n\t\tif(owner != null)\n\t\t{\n\t\t\tif(owner.hasPermission(Permissions.USE))\n\t\t\t{\n\t\t\t\tint size = Minepacks.getInstance().getBackpackPermSize(owner);\n\t\t\t\tif(size != bp.getSize())\n\t\t\t\t{\n\t\t\t\t\tboolean dropped = false;\n\t\t\t\t\tList<ItemStack> items = setSize(size);\n\t\t\t\t\tfor(ItemStack i : items)\n\t\t\t\t\t{\n\t\t\t\t\t\tif(i != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\towner.getWorld().dropItemNaturally(owner.getLocation(), i);\n\t\t\t\t\t\t\tdropped = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (dropped)\n\t\t\t\t\t{\n\t\t\t\t\t\tmessageBackpackShrunk.send(owner);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t@Override\n\tpublic void open(final @NotNull Player player, final boolean editable)\n\t{\n\t\tcheckResize();\n\t\topened.put(player, editable);\n\t\tif(useDynTitle && ownerId.equals(player.getUniqueId())) InventoryUtils.openInventoryWithCustomTitlePrepared(player, bp, titleOwn);\n\t\telse player.openInventory(bp);\n\t}\n\n\t@Override\n\tpublic void open(final @NotNull Player player, final boolean editable, final @Nullable String title)\n\t{\n\t\tif(title == null)\n\t\t{\n\t\t\topen(player, editable);\n\t\t\treturn;\n\t\t}\n\t\tcheckResize();\n\t\topened.put(player, editable);\n\t\tInventoryUtils.openInventoryWithCustomTitle(player, bp, title);\n\t}\n\n\tpublic void close(Player p)\n\t{\n\t\topened.remove(p);\n\t}\n\n\tpublic void closeAll()\n\t{\n\t\topened.forEach((key, value) -> key.closeInventory());\n\t\topened.clear();\n\t\tsave();\n\t}\n\n\t@Override\n\tpublic boolean isOpen()\n\t{\n\t\treturn !opened.isEmpty();\n\t}\n\n\t@Override\n\tpublic boolean canEdit(@NotNull Player player)\n\t{\n\t\treturn opened.containsKey(player) && opened.get(player);\n\t}\n\n\tpublic @NotNull List<ItemStack> setSize(int newSize)\n\t{\n\t\topened.forEach((key, value) -> key.closeInventory()); // Close all open views of the inventory\n\t\tList<ItemStack> removedItems;\n\t\tItemStack[] itemStackArray;\n\t\tif(bp.getSize() > newSize)\n\t\t{\n\t\t\tInventoryCompressor compressor = new InventoryCompressor(bp.getContents(), newSize);\n\t\t\tswitch(shrinkApproach)\n\t\t\t{\n\t\t\t\tcase FAST: compressor.fast(); break;\n\t\t\t\tcase COMPRESS: compressor.compress(); break;\n\t\t\t\tcase SORT: compressor.sort(); break;\n\t\t\t}\n\t\t\titemStackArray = compressor.getTargetStacks();\n\t\t\tremovedItems = compressor.getToMuch();\n\t\t}\n\t\telse\n\t\t{\n\t\t\titemStackArray = bp.getContents();\n\t\t\tremovedItems = new ArrayList<>(0);\n\t\t}\n\t\tbp = Bukkit.createInventory(bp.getHolder(), newSize, titleOther);\n\t\tfor(int i = 0; i < itemStackArray.length; i++)\n\t\t{\n\t\t\tbp.setItem(i, itemStackArray[i]);\n\t\t}\n\t\tsetChanged();\n\t\tsave(); // Make sure the new inventory is saved\n\t\tsize = newSize;\n\t\topened.forEach((key, value) -> key.openInventory(bp));\n\t\treturn removedItems;\n\t}\n\n\t@Override\n\tpublic @NotNull Inventory getInventory()\n\t{\n\t\treturn bp;\n\t}\n\n\t@Override\n\tpublic boolean hasChanged()\n\t{\n\t\treturn hasChanged;\n\t}\n\n\t@Override\n\tpublic void setChanged()\n\t{\n\t\thasChanged = true;\n\t}\n\n\t@Override\n\tpublic void save()\n\t{\n\t\tif(hasChanged())\n\t\t{\n\t\t\tMinepacks.getInstance().getDatabase().saveBackpack(this);\n\t\t\thasChanged = false;\n\t\t}\n\t}\n\n\tpublic void forceSave()\n\t{\n\t\thasChanged = true;\n\t\tsave();\n\t}\n\n\tpublic void backup()\n\t{\n\t\tMinepacks.getInstance().getDatabase().backup(this);\n\t}\n\n\t@Override\n\tpublic void clear()\n\t{\n\t\tbp.clear();\n\t\tsetChanged();\n\t\tsave();\n\t}\n\n\t@Override\n\tpublic void drop(final @NotNull Location location)\n\t{\n\t\tInventoryUtils.dropInventory(bp, location);\n\t\tsetChanged();\n\t\tsave();\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/CancellableRunnable.java",
    "content": "package at.pcgamingfreaks.Minepacks.Bukkit;\n\nimport at.pcgf.libs.com.tcoded.folialib.impl.PlatformScheduler;\nimport at.pcgf.libs.com.tcoded.folialib.wrapper.task.WrappedTask;\n\npublic abstract class CancellableRunnable {\n    protected WrappedTask task = null;\n\n    public abstract void run();\n    public abstract void schedule();\n\n    public void cancel() {\n        if (task != null) {\n            task.cancel();\n        }\n    }\n\n    protected PlatformScheduler getScheduler() {\n        return Minepacks.getScheduler();\n    }\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Command/BackupCommand.java",
    "content": "/*\n *   Copyright (C) 2021 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Command;\n\nimport at.pcgamingfreaks.Bukkit.Message.Message;\nimport at.pcgamingfreaks.Bukkit.Util.Utils;\nimport at.pcgamingfreaks.Command.HelpData;\nimport at.pcgamingfreaks.Minepacks.Bukkit.API.Backpack;\nimport at.pcgamingfreaks.Minepacks.Bukkit.API.Callback;\nimport at.pcgamingfreaks.Minepacks.Bukkit.API.MinepacksCommand;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Permissions;\nimport org.bukkit.OfflinePlayer;\nimport org.bukkit.command.CommandSender;\nimport org.bukkit.entity.Player;\nimport org.jetbrains.annotations.NotNull;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class BackupCommand extends MinepacksCommand\n{\n\tprivate final Message messageCreated, messageNoBackpack;\n\tprivate final String helpParam, helpParamEveryone, descriptionEveryone;\n\n\tpublic BackupCommand(Minepacks plugin)\n\t{\n\t\tsuper(plugin, \"backup\", plugin.getLanguage().getTranslated(\"Commands.Description.Backup\"), Permissions.BACKUP, plugin.getLanguage().getCommandAliases(\"Backup\"));\n\t\thelpParam = \"<\" + plugin.getLanguage().get(\"Commands.PlayerNameVariable\") + \">\";\n\t\thelpParamEveryone = \"!everyone!\";\n\t\tdescriptionEveryone = plugin.getLanguage().getTranslated(\"Commands.Description.BackupEveryone\");\n\t\tmessageCreated = plugin.getLanguage().getMessage(\"Ingame.Backup.Created\");\n\t\tmessageNoBackpack = plugin.getLanguage().getMessage(\"Ingame.Backup.NoBackpack\");\n\t}\n\n\t@Override\n\tpublic void execute(final @NotNull CommandSender sender, final @NotNull String mainCommandAlias, final @NotNull String alias, final @NotNull String[] args)\n\t{\n\t\tif(args.length == 1)\n\t\t{\n\t\t\tif(args[0].equalsIgnoreCase(\"!everyone!\"))\n\t\t\t{\n\t\t\t\tfor(Player player : plugin.getServer().getOnlinePlayers())\n\t\t\t\t{\n\t\t\t\t\tbackup(sender, player);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t//noinspection deprecation\n\t\t\t\tbackup(sender, plugin.getServer().getOfflinePlayer(args[0]));\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tshowHelp(sender, mainCommandAlias);\n\t\t}\n\t}\n\n\tprivate void backup(final @NotNull CommandSender sender, final @NotNull OfflinePlayer offlinePlayer)\n\t{\n\t\tgetMinepacksPlugin().getBackpack(offlinePlayer, new Callback<Backpack>() {\n\t\t\t@Override\n\t\t\tpublic void onResult(Backpack backpack)\n\t\t\t{\n\t\t\t\t((at.pcgamingfreaks.Minepacks.Bukkit.Backpack) backpack).backup();\n\t\t\t\tmessageCreated.send(sender);\n\t\t\t}\n\n\t\t\t@Override\n\t\t\tpublic void onFail()\n\t\t\t{\n\t\t\t\tmessageNoBackpack.send(sender);\n\t\t\t}\n\t\t}, false);\n\t}\n\n\t@Override\n\tpublic List<String> tabComplete(final @NotNull CommandSender sender, final @NotNull String mainCommandAlias, final @NotNull String alias, final @NotNull String[] args)\n\t{\n\t\treturn Utils.getPlayerNamesStartingWith(args[args.length - 1], sender);\n\t}\n\n\t@Override\n\tpublic List<HelpData> getHelp(final @NotNull CommandSender requester)\n\t{\n\t\tList<HelpData> help = new ArrayList<>(1);\n\t\thelp.add(new HelpData(getTranslatedName(), helpParam, getDescription()));\n\t\thelp.add(new HelpData(getTranslatedName(), helpParamEveryone, descriptionEveryone));\n\t\treturn help;\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Command/ClearCommand.java",
    "content": "/*\n *   Copyright (C) 2023 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Command;\n\nimport at.pcgamingfreaks.Bukkit.Message.Message;\nimport at.pcgamingfreaks.Bukkit.Util.Utils;\nimport at.pcgamingfreaks.Command.HelpData;\nimport at.pcgamingfreaks.Minepacks.Bukkit.API.Backpack;\nimport at.pcgamingfreaks.Minepacks.Bukkit.API.Callback;\nimport at.pcgamingfreaks.Minepacks.Bukkit.API.MinepacksCommand;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Permissions;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Placeholders;\nimport org.bukkit.Bukkit;\nimport org.bukkit.OfflinePlayer;\nimport org.bukkit.command.CommandSender;\nimport org.bukkit.entity.Player;\nimport org.jetbrains.annotations.NotNull;\n\nimport java.util.List;\n\npublic class ClearCommand extends MinepacksCommand\n{\n\tprivate final Message messageCleared, messageClearedOther, messageClearedBy;\n\tprivate final String helpParam, descriptionCleanOthers;\n\n\tpublic ClearCommand(Minepacks plugin)\n\t{\n\t\tsuper(plugin, \"clear\", plugin.getLanguage().getTranslated(\"Commands.Description.Clean\"), Permissions.CLEAN, plugin.getLanguage().getCommandAliases(\"Clean\"));\n\t\tdescriptionCleanOthers = plugin.getLanguage().getTranslated(\"Commands.Description.CleanOthers\");\n\t\thelpParam = \"<\" + plugin.getLanguage().get(\"Commands.PlayerNameVariable\") + \">\";\n\t\tmessageCleared = plugin.getLanguage().getMessage(\"Ingame.Clean.BackpackCleaned\");\n\t\tmessageClearedBy = plugin.getLanguage().getMessage(\"Ingame.Clean.BackpackCleanedBy\").placeholders(Placeholders.PLAYER_NAME);\n\t\tmessageClearedOther = plugin.getLanguage().getMessage(\"Ingame.Clean.BackpackCleanedOther\").placeholders(Placeholders.PLAYER_NAME);\n\t}\n\n\t@Override\n\tpublic void execute(final @NotNull CommandSender commandSender, @NotNull String mainCommandAlias, @NotNull String alias, @NotNull String[] args)\n\t{\n\t\tOfflinePlayer target = null;\n\t\tif(commandSender instanceof Player && args.length < 2)\n\t\t{\n\t\t\tPlayer player = (Player) commandSender;\n\t\t\ttarget = (args.length == 1 && player.hasPermission(Permissions.CLEAN_OTHER)) ? Bukkit.getOfflinePlayer(args[0]) : player;\n\t\t}\n\t\telse if(args.length == 1) target = Bukkit.getOfflinePlayer(args[0]);\n\t\tif(target != null)\n\t\t{\n\t\t\tgetMinepacksPlugin().getBackpack(target, new Callback<Backpack>()\n\t\t\t{\n\t\t\t\t@Override\n\t\t\t\tpublic void onResult(Backpack backpack)\n\t\t\t\t{\n\t\t\t\t\tif(backpack != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tbackpack.clear();\n\t\t\t\t\t\tif(commandSender instanceof Player && ((Player) commandSender).getUniqueId().equals(backpack.getOwnerId()))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tmessageCleared.send(commandSender);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tPlayer owner = backpack.getOwnerPlayer();\n\t\t\t\t\t\t\tif(owner != null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tmessageClearedOther.send(commandSender, owner);\n\t\t\t\t\t\t\t\tmessageClearedBy.send(owner, commandSender);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tmessageClearedOther.send(commandSender, backpack.getOwner());\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t((Minepacks) getMinepacksPlugin()).messageInvalidBackpack.send(commandSender);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t@Override\n\t\t\t\tpublic void onFail()\n\t\t\t\t{\n\t\t\t\t\t((Minepacks) getMinepacksPlugin()).messageInvalidBackpack.send(commandSender);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\telse\n\t\t{\n\t\t\tshowHelp(commandSender, mainCommandAlias);\n\t\t}\n\t}\n\n\t@Override\n\tpublic List<String> tabComplete(@NotNull CommandSender commandSender, @NotNull String mainCommandAlias, @NotNull String alias, @NotNull String[] args)\n\t{\n\t\tif(args.length > 0 && (!(commandSender instanceof Player) || commandSender.hasPermission(Permissions.CLEAN_OTHER)))\n\t\t{\n\t\t\treturn Utils.getPlayerNamesStartingWith(args[args.length - 1], commandSender);\n\t\t}\n\t\treturn null;\n\t}\n\n\t@Override\n\tpublic List<HelpData> getHelp(@NotNull CommandSender requester)\n\t{\n\t\tList<HelpData> help = super.getHelp(requester);\n\t\tif(!(requester instanceof Player) || requester.hasPermission(Permissions.CLEAN_OTHER))\n\t\t{\n\t\t\t//noinspection ConstantConditions\n\t\t\thelp.add(new HelpData(getTranslatedName(), helpParam, descriptionCleanOthers));\n\t\t}\n\t\treturn help;\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Command/CommandManager.java",
    "content": "/*\n *   Copyright (C) 2024 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Command;\n\nimport at.pcgamingfreaks.Bukkit.Command.CommandExecutorWithSubCommandsGeneric;\nimport at.pcgamingfreaks.Bukkit.Command.RegisterablePluginCommand;\nimport at.pcgamingfreaks.Bukkit.MCVersion;\nimport at.pcgamingfreaks.Bukkit.Message.Message;\nimport at.pcgamingfreaks.Command.HelpData;\nimport at.pcgamingfreaks.ConsoleColor;\nimport at.pcgamingfreaks.Minepacks.Bukkit.API.MinepacksCommand;\nimport at.pcgamingfreaks.Minepacks.Bukkit.API.MinepacksCommandManager;\nimport at.pcgamingfreaks.Minepacks.Bukkit.API.WorldBlacklistMode;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport at.pcgamingfreaks.Reflection;\n\nimport org.bukkit.command.Command;\nimport org.bukkit.command.CommandSender;\nimport org.bukkit.entity.Player;\nimport org.jetbrains.annotations.NotNull;\n\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.Locale;\nimport java.util.logging.Level;\n\npublic class CommandManager extends CommandExecutorWithSubCommandsGeneric<MinepacksCommand> /*if_not[STANDALONE]*/ implements MinepacksCommandManager /*end[STANDALONE]*/\n{\n\tprivate final Minepacks plugin;\n\tprivate final RegisterablePluginCommand backpackCommand;\n\tprivate final Message helpFormat;\n\n\tpublic CommandManager(@NotNull Minepacks plugin)\n\t{\n\t\tthis.plugin = plugin;\n\t\t// Registering the backpack command with the translated aliases\n\t\tbackpackCommand = new RegisterablePluginCommand(plugin, \"backpack\", plugin.getLanguage().getCommandAliases(\"Backpack\"));\n\t\tbackpackCommand.registerCommand();\n\t\tbackpackCommand.setExecutor(this);\n\t\tbackpackCommand.setTabCompleter(this);\n\n\t\t//TODO handle click action placeholder\n\t\thelpFormat = plugin.getLanguage().getMessage(\"Commands.HelpFormat\").placeholder(\"MainCommand\").placeholder(\"SubCommand\").placeholder(\"Parameters\").placeholder(\"Description\");//.placeholder(\"suggest_command\", \"%5\\\\$s\");\n\n\t\t// Setting the help format for the marry commands as well as the no permissions and not from console message\n\t\ttry\n\t\t{\n\t\t\t// Show help function\n\t\t\tReflection.setStaticField(MinepacksCommand.class, \"minepacksPlugin\", plugin); // Plugin instance\n\t\t\tReflection.setStaticField(MinepacksCommand.class, \"minepacksCommandManager\", this); // Command manager instance\n\t\t\tReflection.setStaticField(MinepacksCommand.class, \"showHelp\", this.getClass().getDeclaredMethod(\"sendHelp\", CommandSender.class, String.class, Collection.class));\n\t\t\tReflection.setStaticField(MinepacksCommand.class, \"messageNoPermission\", plugin.messageNoPermission); // No permission message\n\t\t\tReflection.setStaticField(MinepacksCommand.class, \"messageNotFromConsole\", plugin.messageNotFromConsole); // Not from console message\n\t\t}\n\t\tcatch(Exception e)\n\t\t{\n\t\t\tplugin.getLogger().log(Level.SEVERE, e, () -> ConsoleColor.RED + \"Unable to set the help format. Default format will be used.\\nMore details:\" + ConsoleColor.RESET);\n\t\t}\n\n\t\t// Init backpack commands\n\t\tdefaultSubCommand = new OpenCommand(plugin);\n\t\tregisterSubCommand(defaultSubCommand);\n\t\tif(MCVersion.isNewerOrEqualThan(MCVersion.MC_1_8)) registerSubCommand(new SortCommand(plugin));\n\t\tregisterSubCommand(new ClearCommand(plugin));\n\t\tregisterSubCommand(new ReloadCommand(plugin));\n\t\tregisterSubCommand(new UpdateCommand(plugin));\n\t\tregisterSubCommand(new BackupCommand(plugin));\n\t\tregisterSubCommand(new RestoreCommand(plugin));\n\t\tregisterSubCommand(new MigrateCommand(plugin));\n\t\tregisterSubCommand(new VersionCommand(plugin));\n\t\tif (plugin.getConfiguration().isFullInvToggleAllowed()) registerSubCommand(new PickupCommand(plugin));\n\t\tregisterSubCommand(new DebugCommand(plugin));\n\t\tregisterSubCommand(new HelpCommand(plugin, commands, this));\n\t}\n\n\t@Override\n\tpublic void close()\n\t{\n\t\tbackpackCommand.unregisterCommand();\n\t\tsuper.close();\n\t}\n\n\t@Override\n\tpublic boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args)\n\t{\n\t\tif(sender instanceof Player)\n\t\t{\n\t\t\tWorldBlacklistMode disabled = plugin.isDisabled((Player) sender);\n\t\t\tif(disabled != WorldBlacklistMode.None)\n\t\t\t{\n\t\t\t\tswitch(disabled)\n\t\t\t\t{\n\t\t\t\t\tcase Message: plugin.messageWorldDisabled.send(sender); break;\n\t\t\t\t\tcase MissingPermission: plugin.messageNoPermission.send(sender); break;\n\t\t\t\t\tcase NoPlugin: return false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\telse if(args.length == 0) // If the command was executed in the console without parameters\n\t\t{\n\t\t\targs = new String[]{\"help\"}; // Show help\n\t\t}\n\t\treturn super.onCommand(sender, command, alias, args);\n\t}\n\n\t@Override\n\tpublic List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args)\n\t{\n\t\tif(sender instanceof Player)\n\t\t{\n\t\t\tWorldBlacklistMode disabled = plugin.isDisabled((Player) sender);\n\t\t\tif(disabled != WorldBlacklistMode.None)\n\t\t\t{\n\t\t\t\tif (disabled == WorldBlacklistMode.Message) plugin.messageWorldDisabled.send(sender);\n\t\t\t\telse if (disabled == WorldBlacklistMode.MissingPermission) plugin.messageNoPermission.send(sender);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t\treturn super.onTabComplete(sender, command, alias, args);\n\t}\n\n\tpublic void sendHelp(CommandSender target, String mainCommandAlias, Collection<HelpData> data)\n\t{\n\t\tfor(HelpData d : data)\n\t\t{\n\t\t\thelpFormat.send(target, mainCommandAlias, d.getTranslatedSubCommand(), d.getParameter(), d.getDescription(), d.getClickAction().name().toLowerCase(Locale.ROOT));\n\t\t}\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Command/DebugCommand.java",
    "content": "/*\n *   Copyright (C) 2024 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Command;\n\nimport at.pcgamingfreaks.Bukkit.Message.Message;\nimport at.pcgamingfreaks.Bukkit.Message.MessageBuilder;\nimport at.pcgamingfreaks.Bukkit.Util.InventoryUtils;\nimport at.pcgamingfreaks.Bukkit.Util.Utils;\nimport at.pcgamingfreaks.Command.HelpData;\nimport at.pcgamingfreaks.Message.MessageClickEvent;\nimport at.pcgamingfreaks.Message.MessageColor;\nimport at.pcgamingfreaks.Message.MessageFormat;\nimport at.pcgamingfreaks.Minepacks.Bukkit.API.Backpack;\nimport at.pcgamingfreaks.Minepacks.Bukkit.API.MinepacksCommand;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Permissions;\n\nimport org.apache.commons.lang.exception.ExceptionUtils;\nimport org.bukkit.Bukkit;\nimport org.bukkit.Material;\nimport org.bukkit.command.CommandSender;\nimport org.bukkit.entity.Player;\nimport org.bukkit.event.inventory.ClickType;\nimport org.bukkit.event.inventory.InventoryAction;\nimport org.bukkit.event.inventory.InventoryClickEvent;\nimport org.bukkit.event.inventory.InventoryType;\nimport org.bukkit.inventory.InventoryView;\nimport org.bukkit.inventory.ItemStack;\nimport org.bukkit.plugin.Plugin;\nimport org.jetbrains.annotations.NotNull;\nimport org.jetbrains.annotations.Nullable;\n\nimport lombok.SneakyThrows;\n\nimport java.io.*;\nimport java.nio.charset.StandardCharsets;\nimport java.nio.file.Files;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.logging.Level;\n\npublic class DebugCommand extends MinepacksCommand\n{\n\tprivate final Message messageDone, messageStart;\n\tprivate BufferedWriter writer = null;\n\n\tpublic DebugCommand(final @NotNull Minepacks plugin)\n\t{\n\t\tsuper(plugin, \"debug\", \"Just for debug reasons\", Permissions.RELOAD, true);\n\t\tMessageBuilder builder = new MessageBuilder(\"Please do not interact with your game for the next minute!\", MessageColor.GOLD);\n\t\tbuilder.appendNewLine().append(\"The plugin will now collect data about your server and plugins.\").appendNewLine();\n\t\tbuilder.append(\"This will involve opening inventory's and your backpack.\").appendNewLine();\n\t\tbuilder.append(\"Please do not interact with your game till this is over!\", MessageColor.RED, MessageFormat.BOLD);\n\t\tmessageStart = builder.getMessage();\n\n\t\tbuilder = new MessageBuilder(\"All data has been collected!\", MessageColor.GREEN, MessageFormat.BOLD).appendNewLine();\n\t\tbuilder.append(\"You can now interact with your game again.\").appendNewLine();\n\t\tbuilder.append(\"The collected data can be found in your plugins directory inside the 'debug.txt' file.\").appendNewLine();\n\t\tbuilder.append(\"Please upload this file to \");\n\t\tbuilder.append(\"https://pastebin.com/\", MessageColor.YELLOW, MessageFormat.UNDERLINE).onClick(MessageClickEvent.ClickEventAction.OPEN_URL, \"https://pastebin.com/\");\n\t\tbuilder.append(\" and send the link to the developer.\");\n\t\tmessageDone = builder.getMessage();\n\t}\n\n\t@SneakyThrows\n\tprivate void debugSystem(final @NotNull CommandSender commandSender)\n\t{\n\t\tfinal Player sender = (Player) commandSender;\n\t\tmessageStart.send(sender);\n\n\t\tFile debugFile = new File(plugin.getDataFolder(), \"debug.txt\");\n\t\tif(debugFile.exists() && !debugFile.delete())\n\t\t{\n\t\t\tplugin.getLogger().warning(\"Unable to delete debug.txt file!\");\n\t\t}\n\t\twriter = new BufferedWriter(new OutputStreamWriter(Files.newOutputStream(debugFile.toPath()), StandardCharsets.UTF_8));\n\n\t\twriter.append(plugin.getDescription().getName()).append(\" Version: \").append(plugin.getDescription().getVersion());\n\t\twriter.append(\"\\nServer: \").append(Bukkit.getServer().getBukkitVersion()).append(\" (\").append(Bukkit.getServer().getVersion()).append(\")\");\n\t\twriter.append(\"\\nJava: \").append(System.getProperty(\"java.version\"));\n\t\twriter.append(\"\\nProxy: \").append(Utils.detectBungeeCord() ? \"Bungee\" : (Utils.detectVelocity() ? \"Velocity\" : \"None\"));\n\t\twriter.append(\"\\nOnline Mode: \").append(String.valueOf(Bukkit.getServer().getOnlineMode())).append(\" ; Proxy Online Mode: \").append(String.valueOf(Utils.getBungeeOrVelocityOnlineMode()));\n\t\twriter.append(\"\\n\\nPlugins:\\n\");\n\t\tfor(Plugin p : Bukkit.getServer().getPluginManager().getPlugins())\n\t\t{\n\t\t\twriter.append(p.getName()).append(' ').append(p.getDescription().getVersion()).append('\\n');\n\t\t}\n\t\twriter.append(\"\\nPlugin Config:\\n\");\n\t\ttry(BufferedReader configReader = new BufferedReader(new InputStreamReader(Files.newInputStream(new File(plugin.getDataFolder(), \"config.yml\").toPath()), StandardCharsets.UTF_8)))\n\t\t{\n\t\t\tString line;\n\t\t\twhile((line = configReader.readLine()) != null)\n\t\t\t{\n\t\t\t\tif(line.isEmpty()) continue;\n\t\t\t\tif(line.contains(\"Host\") || line.contains(\"Password\") || line.contains(\"User\")) line = line.replaceAll(\"^(\\\\s+\\\\w+):.*$\", \"$1: ********\");\n\t\t\t\twriter.append(line).append('\\n');\n\t\t\t}\n\t\t}\n\t\twriter.append(\"\\n\\n\\nSelf-test results:\\n\");\n\n\t\tItemStack slot = sender.getInventory().getItem(0);\n\t\tif(slot == null || slot.getAmount() == 0 || slot.getType() == Material.AIR) sender.getInventory().setItem(0, new ItemStack(Material.ACACIA_BOAT));\n\n\t\tMinepacks.getScheduler().runAtEntityLater(sender, () -> sender.performCommand(\"backpack\"), 5*20L);\n\t\tMinepacks.getScheduler().runAtEntityLater(sender, () -> Bukkit.getPluginManager().callEvent(new ClickEvent(sender.getOpenInventory(), InventoryType.SlotType.QUICKBAR, InventoryUtils.getPlayerTopInventory(sender).getSize() + 27, ClickType.LEFT, InventoryAction.PICKUP_ALL)), 10*20L);\n\t\tMinepacks.getScheduler().runAtEntityLater(sender, sender::closeInventory, 20*20L);\n\t\tMinepacks.getScheduler().runLater(() -> {\n\t\t\ttry\n\t\t\t{\n\t\t\t\twriter.flush();\n\t\t\t\twriter.close();\n\t\t\t\twriter = null;\n\t\t\t}\n\t\t\tcatch(Exception e) { plugin.getLogger().log(Level.SEVERE, \"Error while writing debug file.\", e);}\n\t\t\tsender.getInventory().setItem(0, slot);\n\t\t\tmessageDone.send(sender);\n\t\t}, 30*20L);\n\t}\n\n\t@SneakyThrows\n\t@Override\n\tpublic void execute(@NotNull CommandSender commandSender, @NotNull String mainCommandAlias, @NotNull String alias, @NotNull String[] args)\n\t{\n\t\tif(writer != null) return;\n\t\tif (args.length == 2 && args[0].equals(\"permissions\"))\n\t\t{\n\t\t\tPlayer player = Bukkit.getServer().getPlayer(args[1]);\n\t\t\tif (player == null)\n\t\t\t{\n\t\t\t\tcommandSender.sendMessage(\"Player \" + args[1] + \" is offline.\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcommandSender.sendMessage(\"### Permissions for \" + player.getName() + \" ###\");\n\t\t\tfor(String perm : Permissions.getPermissions())\n\t\t\t{\n\t\t\t\tcommandSender.sendMessage(perm + \": \" + player.hasPermission(perm));\n\t\t\t}\n\t\t\tcommandSender.sendMessage(\"###############################\");\n\t\t}\n\t\telse if (args.length == 2 && args[0].equals(\"size\"))\n\t\t{\n\t\t\texecuteSize(commandSender, args[1]);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tdebugSystem(commandSender);\n\t\t}\n\t}\n\n\tvoid executeSize(final @NotNull CommandSender commandSender, final @NotNull String playerName)\n\t{\n\t\tPlayer player = Bukkit.getServer().getPlayer(playerName);\n\t\tif (player == null)\n\t\t{\n\t\t\tcommandSender.sendMessage(\"Player \" + playerName + \" is offline.\");\n\t\t\treturn;\n\t\t}\n\t\tBackpack bp = Minepacks.getInstance().getBackpackCachedOnly(player);\n\t\tint bpSize = -1, bpInvSize = -1, sizeShouldBe = Minepacks.getInstance().getBackpackPermSize(player);\n\t\tString actualSize = \"backpack not loaded\", actualSizeInventory = \"backpack not loaded\";\n\t\tif (bp != null)\n\t\t{\n\t\t\tbpSize = bp.getSize();\n\t\t\tbpInvSize = bp.getInventory().getSize();\n\t\t\tactualSize = String.valueOf(bpSize);\n\t\t\tactualSizeInventory = String.valueOf(bpInvSize);\n\t\t}\n\t\tcommandSender.sendMessage(\"### Backpack size for \" + player.getName() + \" ###\");\n\t\tcommandSender.sendMessage(\"Size: \" + actualSize);\n\t\tcommandSender.sendMessage(\"Inventory Size: \" + actualSizeInventory);\n\t\tcommandSender.sendMessage(\"Should be: \" + sizeShouldBe);\n\t\tif (bpSize != sizeShouldBe && bp != null)\n\t\t{\n\t\t\tcommandSender.sendMessage(\"Size mismatch detected, attempt resize ...\");\n\t\t\t((at.pcgamingfreaks.Minepacks.Bukkit.Backpack) bp).checkResize();\n\t\t\tif (bp.getSize() != sizeShouldBe)\n\t\t\t{\n\t\t\t\tcommandSender.sendMessage(\"Failed to resize backpack.\");\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tcommandSender.sendMessage(\"Resized backpack successfully.\");\n\t\t\t}\n\t\t}\n\t\tif (bp != null && bp.getSize() != bp.getInventory().getSize())\n\t\t{\n\t\t\tcommandSender.sendMessage(\"Inventory size does not match backpack size!\");\n\t\t}\n\t\tcommandSender.sendMessage(\"Player class: \" + player.getClass().getName());\n\t\tcommandSender.sendMessage(\"###############################\");\n\t}\n\n\t@Override\n\tpublic List<String> tabComplete(@NotNull CommandSender commandSender, @NotNull String mainCommandAlias, @NotNull String alias, @NotNull String[] args)\n\t{\n\t\tif (args.length == 1)\n\t\t{\n\t\t\tList<String> completeList = new ArrayList<>(3);\n\t\t\tif (\"size\".startsWith(args[0])) { completeList.add(\"size\"); }\n\t\t\tif (\"system\".startsWith(args[0])) { completeList.add(\"system\"); }\n\t\t\tif (\"permissions\".startsWith(args[0])) { completeList.add(\"permissions\"); }\n\t\t\treturn completeList;\n\t\t}\n\t\telse if (args.length == 2)\n\t\t{\n\t\t\treturn Utils.getPlayerNamesStartingWith(args[args.length - 1], null);\n\t\t}\n\t\treturn null;\n\t}\n\n\t@Override\n\tpublic @Nullable List<HelpData> getHelp(@NotNull CommandSender requester)\n\t{\n\t\treturn null;\n\t}\n\n\tprivate class ClickEvent extends InventoryClickEvent\n\t{\n\t\tpublic ClickEvent(@NotNull InventoryView view, InventoryType.@NotNull SlotType type, int slot, @NotNull ClickType click, @NotNull InventoryAction action)\n\t\t{\n\t\t\tsuper(view, type, slot, click, action);\n\t\t}\n\n\t\t@SneakyThrows\n\t\t@Override\n\t\tpublic void setCancelled(boolean toCancel)\n\t\t{\n\t\t\tsuper.setCancelled(toCancel);\n\t\t\twriter.append(ExceptionUtils.getStackTrace(new Exception(\"Click event has been canceled!!!\")));\n\t\t\twriter.append(\"\\n\\n\");\n\t\t}\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Command/HelpCommand.java",
    "content": "/*\n *   Copyright (C) 2020 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Command;\n\nimport at.pcgamingfreaks.Bukkit.Message.Message;\nimport at.pcgamingfreaks.Command.HelpData;\nimport at.pcgamingfreaks.Minepacks.Bukkit.API.MinepacksCommand;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport org.bukkit.command.CommandSender;\nimport org.jetbrains.annotations.NotNull;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\n\npublic class HelpCommand extends MinepacksCommand\n{\n\tprivate final Collection<MinepacksCommand> commands;\n\tprivate final Message messageHeader, messageFooter;\n\tprivate final CommandManager commandManager;\n\n\tpublic HelpCommand(Minepacks plugin, Collection<MinepacksCommand> commands, CommandManager commandManager)\n\t{\n\t\tsuper(plugin, \"help\", plugin.getLanguage().getTranslated(\"Commands.Description.Help\"), plugin.getLanguage().getCommandAliases(\"Help\"));\n\t\tthis.commands = commands;\n\t\tthis.commandManager = commandManager;\n\n\t\tmessageHeader = plugin.getLanguage().getMessage(\"Ingame.Help.Header\");\n\t\tmessageFooter = plugin.getLanguage().getMessage(\"Ingame.Help.Footer\");\n\t}\n\n\t@Override\n\tpublic void execute(@NotNull CommandSender sender, @NotNull String mainCommandAlias, @NotNull String alias, @NotNull String[] args)\n\t{\n\t\tmessageHeader.send(sender);\n\t\tCollection<HelpData> help = new ArrayList<>(), temp;\n\t\tfor(MinepacksCommand cmd : commands)\n\t\t{\n\t\t\ttemp = cmd.doGetHelp(sender);\n\t\t\tif(temp != null) help.addAll(temp);\n\t\t}\n\t\tcommandManager.sendHelp(sender, mainCommandAlias, help);\n\t\tmessageFooter.send(sender);\n\t\t//TODO: pages\n\t}\n\n\t@Override\n\tpublic List<String> tabComplete(@NotNull CommandSender sender, @NotNull String mainCommandAlias, @NotNull String alias, @NotNull String[] args)\n\t{\n\t\treturn null;\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Command/InventoryClearCommand.java",
    "content": "/*\n *   Copyright (C) 2023 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Command;\n\nimport at.pcgamingfreaks.Bukkit.Command.RegisterablePluginCommand;\nimport at.pcgamingfreaks.Bukkit.Message.Message;\nimport at.pcgamingfreaks.Bukkit.Util.Utils;\nimport at.pcgamingfreaks.Minepacks.Bukkit.API.Events.InventoryClearEvent;\nimport at.pcgamingfreaks.Minepacks.Bukkit.API.Events.InventoryClearedEvent;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Permissions;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Placeholders;\nimport org.bukkit.Bukkit;\nimport org.bukkit.command.Command;\nimport org.bukkit.command.CommandExecutor;\nimport org.bukkit.command.CommandSender;\nimport org.bukkit.command.TabCompleter;\nimport org.bukkit.entity.Player;\nimport org.jetbrains.annotations.NotNull;\nimport org.jetbrains.annotations.Nullable;\n\nimport java.util.List;\n\npublic class InventoryClearCommand implements CommandExecutor, TabCompleter\n{\n\tprivate final Minepacks plugin;\n\tprivate final RegisterablePluginCommand command;\n\tprivate final Message messageUnknownPlayer, messageOwnInventoryCleared, messageOtherInventoryCleared, messageInventoryWasCleared;\n\n\tpublic InventoryClearCommand(final @NotNull Minepacks plugin)\n\t{\n\t\tthis.plugin = plugin;\n\t\tcommand = new RegisterablePluginCommand(plugin, \"clearinventory\", plugin.getLanguage().getCommandAliases(\"InventoryClear\"));\n\t\tcommand.registerCommand();\n\t\tcommand.setExecutor(this);\n\t\tcommand.setTabCompleter(this);\n\n\t\t// Load messages\n\t\tmessageUnknownPlayer = plugin.getLanguage().getMessage(\"Ingame.InventoryClear.UnknownPlayer\").placeholder(\"Name\");\n\t\tmessageOwnInventoryCleared = plugin.getLanguage().getMessage(\"Ingame.InventoryClear.Cleared\");\n\t\tmessageOtherInventoryCleared = plugin.getLanguage().getMessage(\"Ingame.InventoryClear.ClearedOther\").placeholders(Placeholders.PLAYER_NAME);\n\t\tmessageInventoryWasCleared = plugin.getLanguage().getMessage(\"Ingame.InventoryClear.ClearedOtherTarget\").placeholders(Placeholders.PLAYER_NAME);\n\t}\n\n\tpublic void close()\n\t{\n\t\tcommand.unregisterCommand();\n\t}\n\n\tprivate void clearInventory(Player player, CommandSender sender)\n\t{\n\t\tInventoryClearEvent clearEvent = new InventoryClearEvent(player, sender);\n\t\tBukkit.getPluginManager().callEvent(clearEvent);\n\t\tif(clearEvent.isCancelled()) return;\n\t\tplayer.getInventory().clear();\n\t\tif(sender.equals(player))\n\t\t{\n\t\t\tmessageOwnInventoryCleared.send(player);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tmessageInventoryWasCleared.send(player, sender);\n\t\t\tmessageOtherInventoryCleared.send(sender, player);\n\t\t}\n\t\tBukkit.getPluginManager().callEvent(new InventoryClearedEvent(player, sender));\n\t}\n\n\t@Override\n\tpublic boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args)\n\t{\n\t\tif(sender.hasPermission(Permissions.INVENTORY_CLEAR))\n\t\t{\n\t\t\tif(args.length > 0)\n\t\t\t{\n\t\t\t\tif(sender.hasPermission(Permissions.INVENTORY_CLEAR_OTHER))\n\t\t\t\t{\n\t\t\t\t\tfor(String name : args)\n\t\t\t\t\t{\n\t\t\t\t\t\tPlayer player = plugin.getServer().getPlayer(name);\n\t\t\t\t\t\tif(player == null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tmessageUnknownPlayer.send(sender, name);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tclearInventory(player, sender);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tplugin.messageNoPermission.send(sender);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if(sender instanceof Player)\n\t\t\t{\n\t\t\t\tclearInventory((Player) sender, sender);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tsender.sendMessage(\"/clear <player_name>\"); //TODO\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tplugin.messageNoPermission.send(sender);\n\t\t}\n\t\treturn true;\n\t}\n\n\t@Override\n\tpublic @Nullable List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args)\n\t{\n\t\tif(args.length > 0 && (!(sender instanceof Player) || sender.hasPermission(Permissions.INVENTORY_CLEAR_OTHER)))\n\t\t{\n\t\t\treturn Utils.getPlayerNamesStartingWith(args[args.length - 1], sender);\n\t\t}\n\t\treturn null;\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Command/MigrateCommand.java",
    "content": "/*\n *   Copyright (C) 2020 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Command;\n\nimport at.pcgamingfreaks.Command.HelpData;\nimport at.pcgamingfreaks.Minepacks.Bukkit.API.MinepacksCommand;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Database.Migration.MigrationManager;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Permissions;\nimport org.bukkit.command.CommandSender;\nimport org.jetbrains.annotations.NotNull;\n\nimport java.util.List;\nimport java.util.Locale;\n\npublic class MigrateCommand extends MinepacksCommand\n{\n\tpublic MigrateCommand(Minepacks plugin)\n\t{\n\t\tsuper(plugin, \"migrate\", plugin.getLanguage().getTranslated(\"Commands.Description.Migrate\"), Permissions.MIGRATE, plugin.getLanguage().getCommandAliases(\"migrate\"));\n\t}\n\n\t@Override\n\tpublic void execute(final @NotNull CommandSender sender, final @NotNull String mainCommandAlias, final @NotNull String alias, final @NotNull String[] args)\n\t{\n\t\tif(args.length >= 1)\n\t\t{\n\t\t\tswitch(args[0].toLowerCase(Locale.ROOT))\n\t\t\t{\n\t\t\t\tcase \"db\": case \"database\": case \"storage\": migrateDb(sender, args); break;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tsender.sendMessage(\"/\" + mainCommandAlias + ' ' + alias + \"database\");\n\t\t}\n\t}\n\n\tprivate void migrateDb(final @NotNull CommandSender sender, final @NotNull String[] args)\n\t{\n\t\tif(args.length >= 2)\n\t\t{\n\t\t\tif(args.length >= 3 && args[2].equalsIgnoreCase(\"start\"))\n\t\t\t{\n\t\t\t\tMigrationManager migrationManager = new MigrationManager((Minepacks) getMinepacksPlugin());\n\t\t\t\tmigrationManager.migrateDB(args[1], result -> {\n\t\t\t\t\tsender.sendMessage(\"Minepacks database migration result: \" + result.getType().name());\n\t\t\t\t\tsender.sendMessage(result.getMessage());\n\t\t\t\t});\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tsender.sendMessage(\"This process will convert your storage type from \" + ((Minepacks) getMinepacksPlugin()).getDatabase().getClass().getName() + \" to \" + args[1]);\n\t\t\t\tsender.sendMessage(\"Your old data will not be deleted and you can switch back any time in the \\\"config.yml\\\" file.\");\n\t\t\t\tif(args[1].equalsIgnoreCase(\"mysql\"))\n\t\t\t\t{\n\t\t\t\t\tsender.sendMessage(\"Please make sure that you have set the config options \\\"Host\\\", \\\"Database\\\", \\\"User\\\" and \\\"Password\\\" to the correct values.\");\n\t\t\t\t}\n\t\t\t\tsender.sendMessage(\"To start the migration please confirm with: /backpack migrate \" + args[0] + ' ' + args[1] + \" start\");\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tsender.sendMessage(\"/backpacks migrate \" + args[0] + \" <mysql/sqlite/files/shared>\");\n\t\t}\n\t}\n\n\t@Override\n\tpublic List<String> tabComplete(final @NotNull CommandSender sender, final @NotNull String mainCommandAlias, final @NotNull String alias, final @NotNull String[] args)\n\t{\n\t\treturn null;\n\t}\n\n\t@Override\n\tpublic List<HelpData> getHelp(final @NotNull CommandSender requester)\n\t{\n\t\treturn null;\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Command/OpenCommand.java",
    "content": "/*\n *   Copyright (C) 2023 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Command;\n\nimport at.pcgamingfreaks.Bukkit.Message.Message;\nimport at.pcgamingfreaks.Bukkit.Message.Placeholder.Processors.GameModePlaceholderProcessor;\nimport at.pcgamingfreaks.Bukkit.Util.Utils;\nimport at.pcgamingfreaks.Calendar.TimeSpan;\nimport at.pcgamingfreaks.Command.HelpData;\nimport at.pcgamingfreaks.Message.MessageClickEvent;\nimport at.pcgamingfreaks.Message.Placeholder.Processors.FloatPlaceholderProcessor;\nimport at.pcgamingfreaks.Minepacks.Bukkit.API.MinepacksCommand;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Permissions;\nimport org.bukkit.Bukkit;\nimport org.bukkit.OfflinePlayer;\nimport org.bukkit.command.CommandSender;\nimport org.bukkit.entity.Player;\nimport org.jetbrains.annotations.NotNull;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class OpenCommand extends MinepacksCommand\n{\n\tprivate final Message messageCooldown, messageWrongGameMode;\n\tprivate final String descriptionOpenOthers, helpParam;\n\tprivate final Minepacks plugin;\n\n\tpublic OpenCommand(Minepacks plugin)\n\t{\n\t\tsuper(plugin, \"open\", plugin.getLanguage().getTranslated(\"Commands.Description.Backpack\"), Permissions.USE, false, plugin.getLanguage().getCommandAliases(\"Open\"));\n\t\tthis.plugin = plugin;\n\n\t\tmessageCooldown       = plugin.getLanguage().getMessage(\"Ingame.Open.Cooldown\").placeholder(\"TimeLeft\", new FloatPlaceholderProcessor(1)).placeholder(\"TimeSpanLeft\");\n\t\tmessageWrongGameMode  = plugin.getLanguage().getMessage(\"Ingame.Open.WrongGameMode\").staticPlaceholder(\"AllowedGameModes\", new GameModePlaceholderProcessor(), plugin.getConfiguration().getAllowedGameModes()).placeholder(\"CurrentGameMode\", new GameModePlaceholderProcessor());\n\t\tdescriptionOpenOthers = plugin.getLanguage().getTranslated(\"Commands.Description.OpenOthers\");\n\t\thelpParam = \"<\" + plugin.getLanguage().get(\"Commands.PlayerNameVariable\") + \">\";\n\t}\n\n\t@Override\n\tpublic void execute(@NotNull CommandSender sender, @NotNull String main, @NotNull String s1, @NotNull String[] args)\n\t{\n\t\tif (!(sender instanceof Player))\n\t\t{\n\t\t\thandleOpenFromConsole(sender, args);\n\t\t\treturn;\n\t\t}\n\t\tPlayer player = (Player) sender;\n\t\tif(args.length == 0)\n\t\t{\n\t\t\texecuteSelf(player);\n\t\t}\n\t\telse\n\t\t{\n\t\t\texecuteOther(player, args[0]);\n\t\t}\n\t}\n\n\tvoid executeSelf(Player player)\n\t{\n\t\tif(getMinepacksPlugin().isPlayerGameModeAllowed(player))\n\t\t{\n\t\t\tif(plugin.getCooldownManager() != null && !player.hasPermission(Permissions.NO_COOLDOWN))\n\t\t\t{\n\t\t\t\tlong cd = plugin.getCooldownManager().getRemainingCooldown(player);\n\t\t\t\tif(cd > 0)\n\t\t\t\t{\n\t\t\t\t\tTimeSpan ts = TimeSpan.fromMilliseconds(cd);\n\t\t\t\t\tmessageCooldown.send(player, cd / 1000f, ts.toString());\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tplugin.getCooldownManager().setCooldown(player);\n\t\t\t}\n\t\t\tplugin.openBackpack(player, player, true);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tmessageWrongGameMode.send(player, player.getGameMode());\n\t\t}\n\t}\n\n\tvoid executeOther(Player player, String name)\n\t{\n\t\tif(player.hasPermission(Permissions.OTHERS))\n\t\t{\n\t\t\tOfflinePlayer target = Bukkit.getPlayer(name);\n\t\t\tif(target == null)\n\t\t\t{\n\t\t\t\t//noinspection deprecation\n\t\t\t\ttarget = Bukkit.getOfflinePlayer(name);\n\t\t\t}\n\t\t\tplugin.openBackpack(player, target, player.hasPermission(Permissions.OTHERS_EDIT));\n\t\t}\n\t\telse\n\t\t{\n\t\t\tplugin.messageNoPermission.send(player);\n\t\t}\n\t}\n\n\tvoid handleOpenFromConsole(final @NotNull CommandSender sender, final @NotNull String[] names)\n\t{\n\t\tint opened = 0;\n\t\tList<String> notOnline = new ArrayList<>(names.length);\n\t\tfor(String name : names)\n\t\t{\n\t\t\tPlayer target = Bukkit.getPlayer(name);\n\t\t\tif (target == null)\n\t\t\t{\n\t\t\t\tnotOnline.add(name);\n\t\t\t}\n\t\t\telse if (target.hasPermission(Permissions.USE))\n\t\t\t{\n\t\t\t\topened++;\n\t\t\t\tplugin.openBackpack(target, target, true);\n\t\t\t}\n\t\t}\n\t\tsender.sendMessage(\"Opened backpack of \" + opened + \" players.\" + (notOnline.isEmpty() ? \"\" : \" Not online: \" + String.join(\", \", notOnline)));\n\t}\n\n\t@Override\n\tpublic List<String> tabComplete(@NotNull CommandSender commandSender, @NotNull String mainCommandAlias, @NotNull String alias, @NotNull String[] args)\n\t{\n\t\tif(args.length > 0 && (!(commandSender instanceof Player) || commandSender.hasPermission(Permissions.OTHERS)))\n\t\t{\n\t\t\treturn Utils.getPlayerNamesStartingWith(args[args.length - 1], commandSender);\n\t\t}\n\t\treturn null;\n\t}\n\n\t@Override\n\tpublic List<HelpData> getHelp(@NotNull CommandSender requester)\n\t{\n\t\tList<HelpData> help = new ArrayList<>(2);\n\t\thelp.add(new HelpData(getTranslatedName(), null, getDescription(), MessageClickEvent.ClickEventAction.RUN_COMMAND));\n\t\tif(requester.hasPermission(Permissions.OTHERS))\n\t\t{\n\t\t\thelp.add(new HelpData(getTranslatedName(), helpParam, descriptionOpenOthers));\n\t\t}\n\t\treturn help;\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Command/PickupCommand.java",
    "content": "/*\n *   Copyright (C) 2022 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Command;\n\nimport at.pcgamingfreaks.Bukkit.Message.Message;\nimport at.pcgamingfreaks.Minepacks.Bukkit.API.MinepacksCommand;\nimport at.pcgamingfreaks.Minepacks.Bukkit.ItemsCollector;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Permissions;\nimport org.bukkit.command.CommandSender;\nimport org.bukkit.entity.Player;\nimport org.jetbrains.annotations.NotNull;\n\nimport java.util.List;\n\npublic class PickupCommand extends MinepacksCommand\n{\n    private final Minepacks plugin;\n    private final Message toggleOn, toggleOff;\n\n    public PickupCommand(Minepacks plugin)\n    {\n        super(plugin, \"pickup\", plugin.getLanguage().getTranslated(\"Commands.Description.Pickup\"), Permissions.PICKUP_TOGGLE, true, plugin.getLanguage().getCommandAliases(\"Pickup\"));\n\n        this.plugin = plugin;\n        toggleOn    = plugin.getLanguage().getMessage(\"Ingame.Pickup.ToggleOn\");\n        toggleOff   = plugin.getLanguage().getMessage(\"Ingame.Pickup.ToggleOff\");\n    }\n\n    @Override\n    public void execute(@NotNull CommandSender sender, @NotNull String s, @NotNull String s1, @NotNull String[] args)\n    {\n        Player player = (Player) sender;\n        ItemsCollector collector = plugin.getItemsCollector();\n\n        if (collector == null) return;\n\n        if (collector.toggleState(player.getUniqueId()))\n\t\t{\n            toggleOn.send(player);\n        }\n\t\telse\n        {\n\t        toggleOff.send(player);\n        }\n    }\n\n    @Override\n    public List<String> tabComplete(@NotNull CommandSender commandSender, @NotNull String s, @NotNull String s1, @NotNull String[] strings)\n    {\n        return null;\n    }\n\n\t@Override\n\tpublic boolean canUse(@NotNull CommandSender sender)\n\t{\n\t\treturn super.canUse(sender) && sender.hasPermission(Permissions.FULL_PICKUP) && sender.hasPermission(Permissions.USE);\n\t}\n}\n"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Command/ReloadCommand.java",
    "content": "/*\n *   Copyright (C) 2020 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Command;\n\nimport at.pcgamingfreaks.Bukkit.Message.Message;\nimport at.pcgamingfreaks.Minepacks.Bukkit.API.MinepacksCommand;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Permissions;\nimport org.bukkit.command.CommandSender;\nimport org.jetbrains.annotations.NotNull;\n\nimport java.util.List;\n\npublic class ReloadCommand extends MinepacksCommand\n{\n\tprivate final Message messageReloading, messageReloaded;\n\n\tpublic ReloadCommand(Minepacks plugin)\n\t{\n\t\tsuper(plugin, \"reload\", plugin.getLanguage().getTranslated(\"Commands.Description.Reload\"), Permissions.RELOAD, plugin.getLanguage().getCommandAliases(\"Reload\"));\n\n\t\t// Load messages\n\t\tmessageReloading = plugin.getLanguage().getMessage(\"Ingame.Reload.Reloading\");\n\t\tmessageReloaded  = plugin.getLanguage().getMessage(\"Ingame.Reload.Reloaded\");\n\t}\n\n\t@Override\n\tpublic void execute(@NotNull CommandSender sender, @NotNull String mainCommandAlias, @NotNull String alias, @NotNull String[] args)\n\t{\n\t\tmessageReloading.send(sender);\n\t\t((Minepacks) plugin).reload();\n\t\tmessageReloaded.send(sender);\n\t}\n\n\t@Override\n\tpublic List<String> tabComplete(@NotNull CommandSender sender, @NotNull String mainCommandAlias, @NotNull String alias, @NotNull String[] args)\n\t{\n\t\treturn null;\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Command/RestoreCommand.java",
    "content": "/*\n *   Copyright (C) 2024 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Command;\n\nimport at.pcgamingfreaks.Bukkit.Message.Message;\nimport at.pcgamingfreaks.Command.HelpData;\nimport at.pcgamingfreaks.Message.MessageClickEvent;\nimport at.pcgamingfreaks.Minepacks.Bukkit.API.MinepacksCommand;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Backpack;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Permissions;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Placeholders;\nimport at.pcgamingfreaks.Util.StringUtils;\n\nimport org.bukkit.Bukkit;\nimport org.bukkit.OfflinePlayer;\nimport org.bukkit.command.CommandSender;\nimport org.bukkit.entity.Player;\nimport org.bukkit.inventory.ItemStack;\nimport org.jetbrains.annotations.NotNull;\n\nimport java.text.SimpleDateFormat;\nimport java.util.*;\n\npublic class RestoreCommand extends MinepacksCommand\n{\n\tprivate final Message messageBackupsHeader, messageBackupsFooter, messageBackupEntry, messageUnableToLoadBackup, messageNoUserFound, messageRestored;\n\tprivate final String helpParam;\n\tprivate final SimpleDateFormat dateFormat;\n\tprivate final String[] listCommands;\n\tprivate final int elementsPerPage;\n\n\tpublic RestoreCommand(Minepacks plugin)\n\t{\n\t\tsuper(plugin, \"restore\", plugin.getLanguage().getTranslated(\"Commands.Description.Restore\"), Permissions.RESTORE, plugin.getLanguage().getCommandAliases(\"Restore\"));\n\t\thelpParam = \"<\" + plugin.getLanguage().get(\"Ingame.Restore.ParameterBackupName\") + \"> (\" + plugin.getLanguage().get(\"Commands.PlayerNameVariable\") + \")\";\n\t\tmessageBackupsHeader = plugin.getLanguage().getMessage(\"Ingame.Restore.Headline\").placeholders(Placeholders.PAGE_OPTIONS);\n\t\tmessageBackupsFooter = plugin.getLanguage().getMessage(\"Ingame.Restore.Footer\").placeholders(Placeholders.PAGE_OPTIONS);\n\t\tmessageBackupEntry = plugin.getLanguage().getMessage(\"Ingame.Restore.BackupEntry\").placeholder(\"BackupIdentifier\").placeholder(\"BackupDate\")\n\t\t\t\t.placeholder(\"BackupPlayerName\").placeholder(\"BackupPlayerUUID\").placeholder(\"MainCommand\").placeholder(\"SubCommand\");\n\t\tmessageUnableToLoadBackup = plugin.getLanguage().getMessage(\"Ingame.Restore.NoValidBackup\").placeholder(\"BackupIdentifier\");\n\t\tmessageNoUserFound = plugin.getLanguage().getMessage(\"Ingame.Restore.NoUserToRestoreToFound\");\n\t\tmessageRestored = plugin.getLanguage().getMessage(\"Ingame.Restore.Restored\");\n\t\tlistCommands = plugin.getLanguage().getCommandAliases(\"ListBackups\", \"list\");\n\t\t//noinspection ConstantConditions\n\t\telementsPerPage = plugin.getLanguage().getYaml().getInt(\"Ingame.Restore.BackupsPerPage\", 10);\n\t\tdateFormat = (plugin.getLanguage().get(\"Ingame.Restore.BackupEntry\").contains(\"{BackupDate}\")) ? new SimpleDateFormat(plugin.getLanguage().get(\"Ingame.Restore.DateFormat\")) : null;\n\t}\n\n\t@Override\n\tpublic void execute(final @NotNull CommandSender sender, final @NotNull String mainCommandAlias, final @NotNull String alias, final @NotNull String[] args)\n\t{\n\t\tif(args.length == 1 || args.length == 2)\n\t\t{\n\t\t\tif(StringUtils.arrayContainsIgnoreCase(listCommands, args[0]))\n\t\t\t{\n\t\t\t\tlistBackups(sender, mainCommandAlias, alias, args);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\trestore(sender, args);\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tshowHelp(sender, mainCommandAlias);\n\t\t}\n\t}\n\n\t@SuppressWarnings(\"deprecation\")\n\tprivate void restore(final @NotNull CommandSender sender, final @NotNull String[] args)\n\t{\n\t\tItemStack[] items = ((Minepacks) getMinepacksPlugin()).getDatabase().loadBackup(args[0]);\n\t\tif(items != null)\n\t\t{\n\t\t\tOfflinePlayer target = null;\n\t\t\tif(args.length == 2)\n\t\t\t{\n\t\t\t\ttarget = plugin.getServer().getOfflinePlayer(args[1]);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tString[] components = args[0].split(\"_\");\n\t\t\t\tif(components.length == 2)\n\t\t\t\t{\n\t\t\t\t\ttarget = plugin.getServer().getOfflinePlayer(components[0]);\n\t\t\t\t}\n\t\t\t\telse if(components.length == 3)\n\t\t\t\t{\n\t\t\t\t\tif(!components[1].contains(\"-\"))\n\t\t\t\t\t{\n\t\t\t\t\t\tcomponents[1] = components[1].replaceAll(\"(\\\\w{8})(\\\\w{4})(\\\\w{4})(\\\\w{4})(\\\\w{12})\", \"$1-$2-$3-$4-$5\");\n\t\t\t\t\t}\n\t\t\t\t\ttarget = plugin.getServer().getOfflinePlayer(UUID.fromString(components[1]));\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(target == null)\n\t\t\t{\n\t\t\t\tmessageNoUserFound.send(sender);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tgetMinepacksPlugin().getBackpack(target, backpack -> {\n\t\t\t\tif (backpack.getSize() != items.length)\n\t\t\t\t{\n\t\t\t\t\tbackpack.clear();\n\t\t\t\t\t((Backpack) backpack).setSize(items.length);\n\t\t\t\t}\n\t\t\t\tbackpack.getInventory().setContents(items);\n\t\t\t\tbackpack.setChanged();\n\t\t\t\tmessageRestored.send(sender);\n\t\t\t});\n\t\t}\n\t\telse\n\t\t{\n\t\t\tmessageUnableToLoadBackup.send(sender, args[0]);\n\t\t}\n\t}\n\n\tprivate int parsePageNr(final @NotNull CommandSender sender, final @NotNull String[] args)\n\t{\n\t\tif(args.length == 2)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\treturn StringUtils.parsePageNumber(args[1]);\n\t\t\t}\n\t\t\tcatch(NumberFormatException ignored)\n\t\t\t{\n\t\t\t\t((Minepacks) getMinepacksPlugin()).messageNotANumber.send(sender);\n\t\t\t}\n\t\t}\n\t\treturn 0;\n\t}\n\n\tprivate String formatUUID(final @NotNull String uuidString)\n\t{\n\t\tif (uuidString.contains(\"-\")) return uuidString;\n\t\treturn uuidString.replaceAll(\"(\\\\w{8})(\\\\w{4})(\\\\w{4})(\\\\w{4})(\\\\w{12})\", \"$1-$2-$3-$4-$5\");\n\t}\n\n\tprivate void listBackups(final @NotNull CommandSender sender, final @NotNull String mainCommandAlias, final @NotNull String alias, final @NotNull String[] args)\n\t{\n\t\tint page = parsePageNr(sender, args);\n\n\t\tArrayList<String> backups = ((Minepacks) getMinepacksPlugin()).getDatabase().getBackups();\n\t\tint pages = backups.size() / elementsPerPage + 1;\n\t\tpage = Math.min(page, pages - 1);\n\t\tint offset = page * elementsPerPage, end = Math.min(offset + elementsPerPage, backups.size());\n\t\tString subCom = alias + ' ' + args[0];\n\t\tmessageBackupsHeader.send(sender, page + 1, pages, mainCommandAlias, subCom, page, page + 2);\n\t\twhile(offset < end)\n\t\t{\n\t\t\tString backup = backups.get(offset++), uuid = \"No UUID\", date = \"Unknown\";\n\t\t\tString[] components = backup.split(\"_\");\n\t\t\tif(components.length == 3) uuid = formatUUID(components[1]);\n\t\t\tif(dateFormat != null && (components.length == 2 || components.length == 3))\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tdate = dateFormat.format(new Date(Long.parseLong(components[components.length - 1])));\n\t\t\t\t}\n\t\t\t\tcatch(NumberFormatException ignored) {}\n\t\t\t}\n\t\t\tmessageBackupEntry.send(sender, backup, date, components[0], uuid, mainCommandAlias, alias);\n\t\t}\n\t\tmessageBackupsFooter.send(sender, page + 1, pages, mainCommandAlias, subCom, page, page + 2);\n\t}\n\n\t@Override\n\tpublic List<String> tabComplete(final @NotNull CommandSender sender, final @NotNull String mainCommandAlias, final @NotNull String alias, final @NotNull String[] args)\n\t{\n\t\tfinal String arg = args[args.length - 1].toLowerCase(Locale.ROOT);\n\t\tList<String> autoComplete = null;\n\t\tif(args.length == 1)\n\t\t{\n\t\t\tList<String> backups = ((Minepacks) getMinepacksPlugin()).getDatabase().getBackups();\n\t\t\tautoComplete = new ArrayList<>();\n\t\t\tfor(String backupId : backups)\n\t\t\t{\n\t\t\t\tif(backupId.toLowerCase(Locale.ROOT).startsWith(arg)) autoComplete.add(backupId);\n\t\t\t}\n\t\t\tfor(String listCommand : listCommands)\n\t\t\t{\n\t\t\t\tif(listCommand.startsWith(arg)) autoComplete.add(listCommand);\n\t\t\t}\n\t\t}\n\t\telse if(args.length == 2)\n\t\t{\n\t\t\tautoComplete = new ArrayList<>();\n\t\t\tfor(Player player : Bukkit.getOnlinePlayers())\n\t\t\t{\n\t\t\t\tif(player.getName().toLowerCase(Locale.ROOT).startsWith(arg)) autoComplete.add(player.getName());\n\t\t\t}\n\t\t}\n\t\treturn autoComplete;\n\t}\n\n\t@Override\n\tpublic List<HelpData> getHelp(final @NotNull CommandSender requester)\n\t{\n\t\tList<HelpData> help = new ArrayList<>();\n\t\thelp.add(new HelpData(getTranslatedName() + \" \" + listCommands[0], null, ((Minepacks) getMinepacksPlugin()).getLanguage().getTranslated(\"Commands.Description.RestoreList\"), MessageClickEvent.ClickEventAction.RUN_COMMAND));\n\t\thelp.add(new HelpData(getTranslatedName(), helpParam, getDescription(), MessageClickEvent.ClickEventAction.SUGGEST_COMMAND));\n\t\treturn help;\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Command/ShortcutCommand.java",
    "content": "/*\n *   Copyright (C) 2023 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Command;\n\nimport at.pcgamingfreaks.Command.HelpData;\nimport at.pcgamingfreaks.Minepacks.Bukkit.API.MinepacksCommand;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Listener.ItemShortcut;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Permissions;\n\nimport org.bukkit.Bukkit;\nimport org.bukkit.command.CommandSender;\nimport org.bukkit.entity.Player;\nimport org.jetbrains.annotations.NotNull;\nimport org.jetbrains.annotations.Nullable;\n\nimport java.util.List;\n\npublic class ShortcutCommand extends MinepacksCommand\n{\n\tprivate final ItemShortcut itemShortcut;\n\n\tpublic ShortcutCommand(Minepacks plugin, final @NotNull ItemShortcut itemShortcut)\n\t{\n\t\tsuper(plugin, \"shortcut\", \"\"/*plugin.getLanguage().getTranslated(\"Commands.Description.Shortcut\")*/, Permissions.USE, true, plugin.getLanguage().getCommandAliases(\"Shortcut\"));\n\t\tthis.itemShortcut = itemShortcut;\n\t}\n\n\t@Override\n\tpublic void execute(@NotNull CommandSender sender, @NotNull String mainCommandAlias, @NotNull String alias, @NotNull String[] args)\n\t{\n\t\tif (args.length == 1 && sender.hasPermission(Permissions.OTHERS))\n\t\t{\n\t\t\tPlayer p = Bukkit.getPlayer(args[0]);\n\t\t\tif (p != null && p.hasPermission(Permissions.USE)) itemShortcut.addItem(p);\n\t\t}\n\t\telse\n\t\t{\n\t\t\titemShortcut.addItem((Player) sender);\n\t\t}\n\t}\n\n\t@Override\n\tpublic List<String> tabComplete(@NotNull CommandSender sender, @NotNull String mainCommandAlias, @NotNull String alias, @NotNull String[] args)\n\t{\n\t\treturn null;\n\t}\n\t@Override\n\tpublic @Nullable List<HelpData> getHelp(@NotNull CommandSender requester)\n\t{\n\t\treturn null;\n\t}\n}\n"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Command/SortCommand.java",
    "content": "/*\n *   Copyright (C) 2023 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Command;\n\nimport at.pcgamingfreaks.Bukkit.Message.Message;\nimport at.pcgamingfreaks.Minepacks.Bukkit.API.MinepacksCommand;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Database.Helper.InventoryCompressor;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Permissions;\nimport org.bukkit.command.CommandSender;\nimport org.bukkit.entity.Player;\nimport org.jetbrains.annotations.NotNull;\n\nimport java.util.List;\n\npublic class SortCommand extends MinepacksCommand\n{\n\tprivate final Message messageSorted;\n\n\tpublic SortCommand(Minepacks plugin)\n\t{\n\t\tsuper(plugin, \"sort\", plugin.getLanguage().getTranslated(\"Commands.Description.Sort\"), Permissions.SORT, true, plugin.getLanguage().getCommandAliases(\"Sort\"));\n\t\tmessageSorted = plugin.getLanguage().getMessage(\"Ingame.Sort.Sorted\");\n\t}\n\n\t@Override\n\tpublic void execute(final @NotNull CommandSender commandSender, @NotNull String mainCommandAlias, @NotNull String alias, @NotNull String[] args)\n\t{\n\t\tfinal Player player = (Player) commandSender;\n\t\tgetMinepacksPlugin().getBackpack(player, backpack -> {\n\t\t\tInventoryCompressor compressor = new InventoryCompressor(backpack.getInventory().getContents());\n\t\t\tif(!compressor.sort().isEmpty())\n\t\t\t{\n\t\t\t\tplugin.getLogger().warning(\"Failed to sort backpack!\"); //this should not happen\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tbackpack.getInventory().setContents(compressor.getTargetStacks());\n\t\t\tbackpack.setChanged();\n\t\t\tmessageSorted.send(player);\n\t\t});\n\t}\n\n\t@Override\n\tpublic List<String> tabComplete(@NotNull CommandSender commandSender, @NotNull String mainCommandAlias, @NotNull String alias, @NotNull String[] args)\n\t{\n\t\treturn null;\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Command/UpdateCommand.java",
    "content": "/*\n *   Copyright (C) 2020 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Command;\n\nimport at.pcgamingfreaks.Bukkit.MCVersion;\nimport at.pcgamingfreaks.Bukkit.Message.Message;\nimport at.pcgamingfreaks.Minepacks.Bukkit.API.MinepacksCommand;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Permissions;\nimport at.pcgamingfreaks.Minepacks.MagicValues;\nimport org.bukkit.ChatColor;\nimport org.bukkit.command.CommandSender;\nimport org.jetbrains.annotations.NotNull;\n\nimport java.util.List;\n\npublic class UpdateCommand extends MinepacksCommand\n{\n\tprivate final Message messageCheckingForUpdates, messageUpdated, messageNoUpdate, messageUpdateFail, messageUpdateAvailable;\n\n\tpublic UpdateCommand(Minepacks plugin)\n\t{\n\t\tsuper(plugin, \"update\", plugin.getLanguage().getTranslated(\"Commands.Description.Update\"), Permissions.UPDATE, plugin.getLanguage().getCommandAliases(\"Update\"));\n\n\t\tmessageCheckingForUpdates   = plugin.getLanguage().getMessage(\"Ingame.Update.CheckingForUpdates\");\n\t\tmessageUpdated              = plugin.getLanguage().getMessage(\"Ingame.Update.Updated\");\n\t\tmessageNoUpdate             = plugin.getLanguage().getMessage(\"Ingame.Update.NoUpdate\");\n\t\tmessageUpdateFail           = plugin.getLanguage().getMessage(\"Ingame.Update.UpdateFail\");\n\t\tmessageUpdateAvailable      = plugin.getLanguage().getMessage(\"Ingame.Update.UpdateAvailable\");\n\t}\n\n\t@Override\n\tpublic void execute(@NotNull final CommandSender sender, final @NotNull String mainCommandAlias, final @NotNull String alias, final @NotNull String[] args)\n\t{\n\t\tif(MCVersion.isNewerOrEqualThan(MCVersion.getFromVersionName(MagicValues.MIN_MC_VERSION_FOR_UPDATES)))\n\t\t{\n\t\t\tmessageCheckingForUpdates.send(sender);\n\t\t\t/*if_not[STANDALONE]*/\n\t\t\t((at.pcgamingfreaks.PluginLib.Bukkit.PluginLib) at.pcgamingfreaks.PluginLib.Bukkit.PluginLib.getInstance()).getUpdater().update(); // Make the PluginLib check for updates too\n\t\t\t/*end[STANDALONE]*/\n\t\t\t((Minepacks) plugin).update(result -> {\n\t\t\t\tswitch(result)\n\t\t\t\t{\n\t\t\t\t\tcase SUCCESS: messageUpdated.send(sender); break;\n\t\t\t\t\tcase NO_UPDATE: messageNoUpdate.send(sender); break;\n\t\t\t\t\tcase UPDATE_AVAILABLE: messageUpdateAvailable.send(sender); break;\n\t\t\t\t\tdefault: messageUpdateFail.send(sender); break;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\telse\n\t\t{\n\t\t\tsender.sendMessage(ChatColor.RED + \"There are no more updates for Minecraft 1.7. If you would like to use new features please update your Minecraft version.\");\n\t\t}\n\t}\n\n\t@Override\n\tpublic List<String> tabComplete(@NotNull CommandSender sender, @NotNull String mainCommandAlias, @NotNull String alias, @NotNull String[] args)\n\t{\n\t\treturn null;\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Command/VersionCommand.java",
    "content": "/*\n *   Copyright (C) 2020 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Command;\n\nimport at.pcgamingfreaks.Minepacks.Bukkit.API.MinepacksCommand;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Permissions;\nimport org.bukkit.command.CommandSender;\nimport org.jetbrains.annotations.NotNull;\n\nimport java.util.List;\n\npublic class VersionCommand extends MinepacksCommand\n{\n\tprivate final String minepacksVersion;\n\n\tpublic VersionCommand(Minepacks plugin)\n\t{\n\t\tsuper(plugin, \"version\", plugin.getLanguage().getTranslated(\"Commands.Description.Version\"), Permissions.VERSION, plugin.getLanguage().getCommandAliases(\"Version\"));\n\t\tminepacksVersion = plugin.getDescription().getName() + \": \" + plugin.getDescription().getVersion();\n\t}\n\n\t@Override\n\tpublic void execute(@NotNull CommandSender sender, @NotNull String mainCommandAlias, @NotNull String alias, @NotNull String[] args)\n\t{\n\t\tsender.sendMessage(\"##### Start Minepacks version info #####\");\n\t\tsender.sendMessage(minepacksVersion);\n\t\t/*if_not[STANDALONE]*/\n\t\tsender.sendMessage(\"PCGF PluginLib: \" + at.pcgamingfreaks.PluginLib.Bukkit.PluginLib.getInstance().getVersion());\n\t\t/*end[STANDALONE]*/\n\t\tsender.sendMessage(\"Server: \" +  plugin.getServer().getVersion());\n\t\tsender.sendMessage(\"Java: \" + System.getProperty(\"java.version\"));\n\t\tsender.sendMessage(\"#####  End Minepacks version info  #####\");\n\t}\n\n\t@Override\n\tpublic List<String> tabComplete(@NotNull CommandSender sender, @NotNull String mainCommandAlias, @NotNull String alias, @NotNull String[] args)\n\t{\n\t\treturn null;\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/CooldownManager.java",
    "content": "/*\n *   Copyright (C) 2023 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit;\n\nimport org.bukkit.entity.Player;\nimport org.bukkit.event.EventHandler;\nimport org.bukkit.event.EventPriority;\nimport org.bukkit.event.HandlerList;\nimport org.bukkit.event.Listener;\nimport org.bukkit.event.player.PlayerJoinEvent;\nimport org.bukkit.event.player.PlayerQuitEvent;\nimport org.jetbrains.annotations.NotNull;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.UUID;\n\npublic class CooldownManager extends CancellableRunnable implements Listener\n{\n\tprivate final Minepacks plugin;\n\tprivate final Map<UUID, Long> cooldowns = new HashMap<>();\n\tprivate final long cooldown;\n\tprivate final boolean syncCooldown, addOnJoin, clearOnLeave;\n\n\tpublic CooldownManager(Minepacks plugin)\n\t{\n\t\tthis.plugin = plugin;\n\n\t\tcooldown = plugin.getConfiguration().getCommandCooldown();\n\t\tsyncCooldown = plugin.getConfiguration().isCommandCooldownSyncEnabled();\n\t\taddOnJoin = plugin.getConfiguration().isCommandCooldownAddOnJoinEnabled();\n\t\tclearOnLeave = plugin.getConfiguration().isCommandCooldownClearOnLeaveEnabled();\n\t\tplugin.getServer().getPluginManager().registerEvents(this, plugin);\n\t\tschedule();\n\t}\n\n\tpublic void close()\n\t{\n\t\tcancel();\n\t\tHandlerList.unregisterAll(this);\n\t}\n\n\tpublic void setCooldown(@NotNull Player player)\n\t{\n\t\tfinal long cooldownTime = System.currentTimeMillis() + cooldown;\n\t\tif(syncCooldown)\n\t\t{\n\t\t\tplugin.getDatabase().syncCooldown(player, cooldownTime);\n\t\t}\n\t\tcooldowns.put(player.getUniqueId(), cooldownTime);\n\t}\n\n\t@SuppressWarnings(\"unused\")\n\tpublic boolean isInCooldown(@NotNull Player player)\n\t{\n\t\treturn cooldowns.getOrDefault(player.getUniqueId(), 0L) > System.currentTimeMillis();\n\t}\n\n\tpublic long getRemainingCooldown(@NotNull Player player)\n\t{\n\t\tlong cd = cooldowns.getOrDefault(player.getUniqueId(), 0L);\n\t\tif(cd > System.currentTimeMillis())\n\t\t{\n\t\t\treturn cd - System.currentTimeMillis();\n\t\t}\n\t\treturn 0;\n\t}\n\n\t@EventHandler(priority = EventPriority.MONITOR)\n\tpublic void onPlayerJoinEvent(PlayerJoinEvent event)\n\t{\n\t\tif(syncCooldown)\n\t\t{\n\t\t\tfinal UUID uuid = event.getPlayer().getUniqueId();\n\t\t\tcooldowns.put(uuid, System.currentTimeMillis() + cooldown); // Temporary cooldown till the data is loaded from the database\n\t\t\tplugin.getDatabase().getCooldown(event.getPlayer(), dbCooldownTime -> cooldowns.put(uuid, dbCooldownTime));\n\t\t}\n\t\telse if(addOnJoin)\n\t\t{\n\t\t\tsetCooldown(event.getPlayer());\n\t\t}\n\t}\n\n\t@EventHandler(priority = EventPriority.MONITOR)\n\tpublic void onPlayerLeaveEvent(PlayerQuitEvent event)\n\t{\n\t\tif(clearOnLeave) cooldowns.remove(event.getPlayer().getUniqueId());\n\t}\n\n\t@Override\n\tpublic void run()\n\t{\n\t\tcooldowns.entrySet().removeIf(entry -> entry.getValue() < System.currentTimeMillis());\n\t}\n\n\t@Override\n\tpublic void schedule() {\n\t\ttask = getScheduler().runTimer(this::run, plugin.getConfiguration().getCommandCooldownCleanupInterval(), plugin.getConfiguration().getCommandCooldownCleanupInterval());\n\t}\n}\n"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Config.java",
    "content": "/*\n *   Copyright (C) 2024 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Database;\n\nimport at.pcgamingfreaks.Bukkit.MCVersion;\nimport at.pcgamingfreaks.Bukkit.MinecraftMaterial;\nimport at.pcgamingfreaks.Bukkit.Util.Utils;\nimport at.pcgamingfreaks.Config.Configuration;\nimport at.pcgamingfreaks.Config.ILanguageConfiguration;\nimport at.pcgamingfreaks.Config.YamlFileManager;\nimport at.pcgamingfreaks.ConsoleColor;\nimport at.pcgamingfreaks.Database.DatabaseConnectionConfiguration;\nimport at.pcgamingfreaks.Minepacks.Bukkit.API.WorldBlacklistMode;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Database.Helper.OldFileUpdater;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport at.pcgamingfreaks.Minepacks.Bukkit.ShrinkApproach;\nimport at.pcgamingfreaks.Minepacks.MagicValues;\nimport at.pcgamingfreaks.Reflection;\nimport at.pcgamingfreaks.Version;\n\nimport org.bukkit.*;\nimport org.jetbrains.annotations.NotNull;\n\nimport java.io.FileNotFoundException;\nimport java.lang.reflect.Field;\nimport java.util.*;\nimport java.util.logging.Level;\n\npublic class Config extends Configuration implements DatabaseConnectionConfiguration, ILanguageConfiguration\n{\n\tprivate static final Version CONFIG_VERSION = new Version(MagicValues.CONFIG_VERSION), PRE_V2_VERSION = new Version(20);\n\n\tpublic Config(Minepacks plugin)\n\t{\n\t\tsuper(plugin, CONFIG_VERSION);\n\t}\n\n\t@Override\n\tprotected void doUpdate()\n\t{\n\t\t// Nothing to update yet\n\t}\n\n\t@Override\n\tprotected void doUpgrade(@NotNull YamlFileManager oldConfig)\n\t{\n\t\tif(oldConfig.getVersion().olderThan(PRE_V2_VERSION)) // Pre V2.0 config file\n\t\t{\n\t\t\tOldFileUpdater.updateConfig(oldConfig.getYamlE(), getConfigE());\n\t\t}\n\t\telse\n\t\t{\n\t\t\tMap<String, String> remappedKeys = new HashMap<>();\n\t\t\tif(oldConfig.getVersion().olderOrEqualThan(new Version(23))) remappedKeys.put(\"ItemFilter.Materials\", \"ItemFilter.Blacklist\");\n\t\t\tif(oldConfig.getVersion().olderOrEqualThan(new Version(28))) remappedKeys.put(\"Misc.AutoUpdate.Enabled\", \"Misc.AutoUpdate\");\n\t\t\tif(oldConfig.getVersion().olderOrEqualThan(new Version(30)))\n\t\t\t{\n\t\t\t\tremappedKeys.put(\"WorldSettings.FilteredWorlds\", \"WorldSettings.Blacklist\");\n\t\t\t\tremappedKeys.put(\"WorldSettings.BockMode\", \"WorldSettings.BlacklistMode\");\n\t\t\t}\n\t\t\tif(oldConfig.getVersion().olderOrEqualThan(new Version(33))) remappedKeys.put(\"Database.Cache.UnCache.Strategy\", \"Database.Cache.UnCache.Strategie\");\n\t\t\tCollection<String> keysToKeep = oldConfig.getYamlE().getKeysFiltered(\"Database\\\\.SQL\\\\.(MaxLifetime|IdleTimeout)\");\n\t\t\tkeysToKeep.addAll(oldConfig.getYamlE().getKeysFiltered(\"Database\\\\.Tables\\\\.Fields\\\\..+\"));\n\t\t\tdoUpgrade(oldConfig, remappedKeys, keysToKeep);\n\t\t}\n\t}\n\n\t//region getter\n\t//region Database getter\n\tpublic int getAutoCleanupMaxInactiveDays()\n\t{\n\t\treturn getConfigE().getInt(\"Database.AutoCleanup.MaxInactiveDays\", -1);\n\t}\n\n\tpublic String getDatabaseType()\n\t{\n\t\treturn getConfigE().getString(\"Database.Type\", \"sqlite\").toLowerCase(Locale.ENGLISH);\n\t}\n\n\tpublic void setDatabaseType(String type)\n\t{\n\t\tgetConfigE().set(\"Database.Type\", type);\n\t\ttry\n\t\t{\n\t\t\tsave();\n\t\t}\n\t\tcatch(FileNotFoundException e)\n\t\t{\n\t\t\tlogger.log(Level.SEVERE, \"Failed to set database type\", e);\n\t\t}\n\t}\n\n\tpublic String getUserTable()\n\t{\n\t\treturn getConfigE().getString(\"Database.Tables.User\", \"backpack_players\");\n\t}\n\n\tpublic String getBackpackTable()\n\t{\n\t\treturn getConfigE().getString(\"Database.Tables.Backpack\", \"backpacks\");\n\t}\n\n\tpublic String getCooldownTable()\n\t{\n\t\treturn getConfigE().getString(\"Database.Tables.Cooldown\", \"backpack_cooldowns\");\n\t}\n\n\tpublic String getDBFields(String sub, String def)\n\t{\n\t\treturn getConfigE().getString(\"Database.Tables.Fields.\" + sub, def);\n\t}\n\n\tpublic boolean useOnlineUUIDs()\n\t{\n\t\tString type = getConfigE().getString(\"Database.UUID_Type\", \"auto\").toLowerCase(Locale.ENGLISH);\n\t\tif(type.equals(\"auto\"))\n\t\t{\n\t\t\tif(isBungeeCordModeEnabled())\n\t\t\t{\n\t\t\t\tBoolean detectedOnlineMode = Utils.getBungeeOrVelocityOnlineMode();\n\t\t\t\tif (detectedOnlineMode != null)\n\t\t\t\t{\n\t\t\t\t\tlogger.log(Level.INFO, \"Detected online mode in paper config: {0}\", detectedOnlineMode);\n\t\t\t\t\treturn detectedOnlineMode;\n\t\t\t\t}\n\t\t\t\tlogger.warning(\"When using BungeeCord please make sure to set the UUID_Type config option explicitly!\");\n\t\t\t}\n\t\t\treturn Bukkit.getServer().getOnlineMode();\n\t\t}\n\t\treturn type.equals(\"online\");\n\t}\n\n\tpublic boolean getUseUUIDSeparators()\n\t{\n\t\treturn getConfigE().getBoolean(\"Database.UseUUIDSeparators\", false);\n\t}\n\n\tpublic boolean isForceSaveOnUnloadEnabled()\n\t{\n\t\treturn getConfigE().getBoolean(\"Database.ForceSaveOnUnload\", false);\n\t}\n\n\tpublic String getUnCacheStrategy()\n\t{\n\t\treturn getConfigE().getString(\"Database.Cache.UnCache.Strategy\", \"interval\").toLowerCase(Locale.ENGLISH);\n\t}\n\n\tpublic long getUnCacheInterval()\n\t{\n\t\treturn getConfigE().getLong(\"Database.Cache.UnCache.Interval\", 600) * 20L;\n\t}\n\n\tpublic long getUnCacheDelay()\n\t{\n\t\treturn getConfigE().getLong(\"Database.Cache.UnCache.Delay\", 600) * 20L;\n\t}\n\t//endregion\n\n\tpublic String getBPTitleOther()\n\t{\n\t\treturn ChatColor.translateAlternateColorCodes('&', getConfigE().getString(\"BackpackTitleOther\", \"{OwnerName} Backpack\").replace(\"%\", \"%%\").replace(\"{OwnerName}\", \"%s\"));\n\t}\n\n\tpublic String getBPTitle()\n\t{\n\t\treturn ChatColor.translateAlternateColorCodes('&', getConfigE().getString(\"BackpackTitle\", \"Backpack\").replace(\"%\", \"%%\").replace(\"{OwnerName}\", \"%s\"));\n\t}\n\n\tpublic boolean useDynamicBPTitle()\n\t{\n\t\treturn getConfigE().getBoolean(\"Database.UseDynamicTitle\", true);\n\t}\n\n\tpublic boolean getDropOnDeath()\n\t{\n\t\treturn getConfigE().getBoolean(\"DropOnDeath\", true);\n\t}\n\n\tpublic boolean getHonorKeepInventoryOnDeath()\n\t{\n\t\treturn getConfigE().getBoolean(\"HonorKeepInventoryOnDeath\", false);\n\t}\n\n\tpublic int getBackpackMaxSize()\n\t{\n\t\tint size = getConfigE().getInt(\"MaxSize\", 6);\n\t\tif(MCVersion.isNewerOrEqualThan(MCVersion.MC_1_14)) size = Math.min(6, size);\n\t\tif(size > 6)\n\t\t{\n\t\t\tlogger.info(\"Starting with MC 1.14 backpacks with more than 6 rows will no longer be possible. A feature to allow bigger backpacks through multiple pages is currently in development.\");\n\t\t}\n\t\treturn Math.max(1, size);\n\t}\n\n\tpublic ShrinkApproach getShrinkApproach()\n\t{\n\t\tif(MCVersion.isOlderThan(MCVersion.MC_1_8)) return ShrinkApproach.FAST;\n\t\tString approach = getConfigE().getString(\"ShrinkApproach\", \"SORT\");\n\t\ttry\n\t\t{\n\t\t\treturn ShrinkApproach.valueOf(approach.toUpperCase(Locale.ENGLISH));\n\t\t}\n\t\tcatch(IllegalArgumentException ignored)\n\t\t{\n\t\t\tlogger.log(Level.WARNING, \"Unknown ShrinkApproach \\\"{0}\\\"!\", approach);\n\t\t\treturn ShrinkApproach.SORT;\n\t\t}\n\t}\n\n\t//region Misc getters\n\tpublic boolean useUpdater()\n\t{\n\t\treturn (MCVersion.isNewerOrEqualThan(MCVersion.getFromVersionName(MagicValues.MIN_MC_VERSION_FOR_UPDATES))) && getConfigE().getBoolean(\"Misc.AutoUpdate.Enabled\", getConfigE().getBoolean(\"Misc.AutoUpdate\", true));\n\t}\n\n\tpublic String getUpdateChannel()\n\t{\n\t\tString channel = getConfigE().getString(\"Misc.AutoUpdate.Channel\", \"Release\");\n\t\tif(\"Release\".equals(channel) || \"Master\".equals(channel) || \"Dev\".equals(channel))\n\t\t{\n\t\t\treturn channel;\n\t\t}\n\t\telse logger.log(Level.INFO, \"Unknown update Channel: {0}\", channel);\n\t\treturn null;\n\t}\n\n\tpublic boolean isBungeeCordModeEnabled()\n\t{\n\t\tboolean useBungee = getConfigE().getBoolean(\"Misc.UseBungeeCord\", false);\n\t\tboolean runsProxy = Utils.detectBungeeCord() || Utils.detectVelocity();\n\t\tboolean shareableDB = getDatabaseType().equals(\"mysql\") || getDatabaseType().equals(\"global\");\n\t\tif(useBungee && !runsProxy)\n\t\t{\n\t\t\tlogger.warning(\"You have BungeeCord enabled for the plugin, but it looks like you have not enabled it in your spigot.yml! You probably should check your configuration.\");\n\t\t}\n\t\telse if(!useBungee && runsProxy && shareableDB)\n\t\t{\n\t\t\tlogger.warning(\"Your server is running behind a BungeeCord server. If you are using the plugin on more than one server with a shared database, please make sure to also enable the 'UseBungeeCord' config option.\");\n\t\t}\n\t\telse if(useBungee && !shareableDB)\n\t\t{\n\t\t\tlogger.info(\"You have enabled BungeeCord mode for the plugin, but are not using a shared MySQL database.\");\n\t\t\treturn false; // No need to enable BungeeCord mode if the database does not support it\n\t\t}\n\t\treturn useBungee;\n\t}\n\t//endregion\n\n\tpublic long getCommandCooldown()\n\t{\n\t\treturn getConfigE().getInt(\"Cooldown.Command\", -1) * 1000L;\n\t}\n\n\tpublic boolean isCommandCooldownSyncEnabled()\n\t{\n\t\treturn getConfigE().getBoolean(\"Cooldown.Sync\", false);\n\t}\n\n\tpublic boolean isCommandCooldownClearOnLeaveEnabled()\n\t{\n\t\treturn getConfigE().getBoolean(\"Cooldown.ClearOnLeave\", false);\n\t}\n\n\tpublic boolean isCommandCooldownAddOnJoinEnabled()\n\t{\n\t\treturn getConfigE().getBoolean(\"Cooldown.AddOnJoin\", true);\n\t}\n\n\tpublic long getCommandCooldownCleanupInterval()\n\t{\n\t\treturn getConfigE().getInt(\"Cooldown.CleanupInterval\", 600) * 20L;\n\t}\n\n\tpublic Collection<GameMode> getAllowedGameModes()\n\t{\n\t\tCollection<GameMode> gameModes = new HashSet<>();\n\t\tfor(String string : getConfigE().getStringList(\"AllowedGameModes\", new LinkedList<>()))\n\t\t{\n\t\t\tGameMode gm = null;\n\t\t\ttry\n\t\t\t{\n\t\t\t\t//noinspection deprecation\n\t\t\t\tgm = GameMode.getByValue(Integer.parseInt(string));\n\t\t\t}\n\t\t\tcatch(NumberFormatException ignored) {}\n\t\t\tif(gm == null)\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tgm = GameMode.valueOf(string.toUpperCase(Locale.ROOT));\n\t\t\t\t}\n\t\t\t\tcatch(IllegalArgumentException ignored)\n\t\t\t\t{\n\t\t\t\t\tlogger.warning(\"Unknown game-mode '\" + string + \"'\");\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(gm != null)\n\t\t\t{\n\t\t\t\tgameModes.add(gm);\n\t\t\t}\n\t\t}\n\t\tif(gameModes.isEmpty())\n\t\t{\n\t\t\tlogger.info(\"No game-mode's allowed, allowing: \" + GameMode.SURVIVAL.name());\n\t\t\tgameModes.add(GameMode.SURVIVAL);\n\t\t}\n\t\treturn gameModes;\n\t}\n\n\t//region Full inventory handling\n\tpublic boolean getFullInvCollect()\n\t{\n\t\treturn getConfigE().getBoolean(\"FullInventory.CollectItems\", false);\n\t}\n\n\tpublic long getFullInvCheckInterval()\n\t{\n\t\treturn getConfigE().getInt(\"FullInventory.CheckInterval\", 1) * 20L; // in seconds\n\t}\n\n\tpublic double getFullInvRadius()\n\t{\n\t\treturn getConfigE().getDouble(\"FullInventory.CollectRadius\", 1.5); // in blocks\n\t}\n\n\tpublic boolean isFullInvToggleAllowed()\n\t{\n\t\treturn getConfigE().getBoolean(\"FullInventory.IsToggleAllowed\", false);\n\t}\n\n\tpublic boolean isFullInvEnabledOnJoin()\n\t{\n\t\treturn getFullInvCollect();\n\t}\n\t//endregion\n\n\t//region Shulkerboxes\n\tpublic boolean isShulkerboxesPreventInBackpackEnabled()\n\t{ // Shulkerboxes are only available in MC 1.11 and newer\n\t\treturn MCVersion.isNewerOrEqualThan(MCVersion.MC_1_11) && getConfigE().getBoolean(\"Shulkerboxes.PreventInBackpack\", true);\n\t}\n\n\tpublic boolean isShulkerboxesDisable()\n\t{ // Shulkerboxes are only available in MC 1.11 and newer\n\t\treturn MCVersion.isNewerOrEqualThan(MCVersion.MC_1_11) && getConfigE().getBoolean(\"Shulkerboxes.DisableShulkerboxes\", false);\n\t}\n\n\tpublic boolean isShulkerboxesExistingDropEnabled()\n\t{\n\t\treturn getConfigE().getString(\"Shulkerboxes.Existing\", \"Ignore\").equalsIgnoreCase(\"Destroy\");\n\t}\n\n\tpublic boolean isShulkerboxesExistingDestroyEnabled()\n\t{\n\t\treturn getConfigE().getString(\"Shulkerboxes.Existing\", \"Ignore\").equalsIgnoreCase(\"Destroy\") || getConfigE().getString(\"Shulkerboxes.Existing\", \"Ignore\").equalsIgnoreCase(\"Remove\");\n\t}\n\t//endregion\n\n\t//region Item filter\n\tpublic boolean isItemFilterEnabledNoShulker()\n\t{\n\t\treturn getConfigE().getBoolean(\"ItemFilter.Enabled\", false);\n\t}\n\n\tpublic boolean isItemFilterEnabled()\n\t{\n\t\treturn isItemFilterEnabledNoShulker() || getConfigE().getBoolean(\"Shulkerboxes.PreventInBackpack\", true);\n\t}\n\n\tpublic Collection<MinecraftMaterial> getItemFilterMaterials()\n\t{\n\t\tif(!isItemFilterEnabledNoShulker()) return new LinkedList<>();\n\t\tList<String> stringMaterialList = getConfigE().getStringList(\"ItemFilter.Materials\", new LinkedList<>());\n\t\tif(isItemFilterModeWhitelist()) stringMaterialList.add(\"air\");\n\t\tCollection<MinecraftMaterial> blacklist = new LinkedList<>();\n\t\tfor(String item : stringMaterialList)\n\t\t{\n\t\t\tMinecraftMaterial mat = MinecraftMaterial.fromInput(item);\n\t\t\tif(mat != null) blacklist.add(mat);\n\t\t}\n\t\treturn blacklist;\n\t}\n\n\tpublic Set<String> getItemFilterNames()\n\t{\n\t\tif(!isItemFilterEnabledNoShulker()) return new HashSet<>();\n\t\tSet<String> names = new HashSet<>();\n\t\tgetConfigE().getStringList(\"ItemFilter.Names\", new LinkedList<>()).forEach(name -> names.add(ChatColor.translateAlternateColorCodes('&', name)));\n\t\treturn names;\n\t}\n\n\tpublic Set<String> getItemFilterLore()\n\t{\n\t\tif(!isItemFilterEnabledNoShulker()) return new HashSet<>();\n\t\tSet<String> loreSet = new HashSet<>();\n\t\tgetConfigE().getStringList(\"ItemFilter.Lore\", new LinkedList<>()).forEach(lore -> loreSet.add(ChatColor.translateAlternateColorCodes('&', lore)));\n\t\treturn loreSet;\n\t}\n\n\tpublic boolean isItemFilterModeWhitelist()\n\t{\n\t\treturn getConfigE().getString(\"ItemFilter.Mode\", \"blacklist\").toLowerCase(Locale.ENGLISH).equals(\"whitelist\") && isItemFilterEnabledNoShulker();\n\t}\n\t//endregion\n\n\t//region World settings\n\tpublic boolean isWorldWhitelistMode()\n\t{\n\t\treturn getConfigE().getString(\"WorldSettings.FilterType\", \"blacklist\").equalsIgnoreCase(\"whitelist\");\n\t}\n\n\tpublic Set<String> getWorldFilteredList()\n\t{\n\t\tSet<String> worldList = new HashSet<>();\n\t\tfor(String world : getConfigE().getStringList(\"WorldSettings.FilteredWorlds\", new ArrayList<>(0)))\n\t\t{\n\t\t\tworldList.add(world.toLowerCase(Locale.ROOT));\n\t\t}\n\t\treturn worldList;\n\t}\n\n\tpublic Set<String> getWorldBlacklist()\n\t{\n\t\tif(isWorldWhitelistMode())\n\t\t{\n\t\t\tSet<String> whitelist = getWorldFilteredList(), blacklist = new HashSet<>();\n\t\t\tfor(World world : Bukkit.getServer().getWorlds())\n\t\t\t{\n\t\t\t\tString worldName = world.getName().toLowerCase(Locale.ROOT);\n\t\t\t\tif(!whitelist.contains(worldName)) blacklist.add(worldName);\n\t\t\t}\n\t\t\treturn blacklist;\n\t\t}\n\t\telse return getWorldFilteredList();\n\t}\n\n\tpublic WorldBlacklistMode getWorldBlockMode()\n\t{\n\t\tString mode = getConfigE().getString(\"WorldSettings.BlockMode\", \"Message\");\n\t\tWorldBlacklistMode blacklistMode = WorldBlacklistMode.Message;\n\t\ttry\n\t\t{\n\t\t\tblacklistMode = WorldBlacklistMode.valueOf(mode);\n\t\t}\n\t\tcatch(IllegalArgumentException ignored)\n\t\t{\n\t\t\tlogger.warning(ConsoleColor.YELLOW + \"Unsupported mode \\\"\" + mode + \"\\\" for option \\\"WorldSettings.BlockMode\\\"\" + ConsoleColor.RESET);\n\t\t}\n\t\treturn blacklistMode;\n\t}\n\t//endregion\n\n\t//region ItemShortcut settings\n\tpublic boolean isItemShortcutEnabled()\n\t{\n\t\treturn MCVersion.isNewerOrEqualThan(MCVersion.MC_1_8) && getConfigE().getBoolean(\"ItemShortcut.Enabled\", true);\n\t}\n\n\tpublic String getItemShortcutItemName()\n\t{\n\t\treturn getConfigE().getString(\"ItemShortcut.ItemName\", \"&eBackpack\");\n\t}\n\n\tpublic String getItemShortcutHeadValue()\n\t{\n\t\treturn getConfigE().getString(\"ItemShortcut.HeadTextureValue\", \"eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvOGRjYzZlYjQwZjNiYWRhNDFlNDMzOTg4OGQ2ZDIwNzQzNzU5OGJkYmQxNzVjMmU3MzExOTFkNWE5YTQyZDNjOCJ9fX0=\");\n\t}\n\n\tpublic boolean isItemShortcutImproveDeathChestCompatibilityEnabled()\n\t{\n\t\treturn getConfigE().getBoolean(\"ItemShortcut.ImproveDeathChestCompatibility\", false);\n\t}\n\n\tpublic boolean isItemShortcutBlockAsHatEnabled()\n\t{\n\t\treturn getConfigE().getBoolean(\"ItemShortcut.BlockAsHat\", false);\n\t}\n\n\tpublic boolean isItemShortcutRightClickOnContainerAllowed()\n\t{\n\t\treturn getConfigE().getBoolean(\"ItemShortcut.OpenContainerOnRightClick\", false) && MCVersion.isNewerOrEqualThan(MCVersion.MC_1_13);\n\t}\n\n\tpublic int getItemShortcutPreferredSlotId()\n\t{\n\t\treturn getConfigE().getInt(\"ItemShortcut.PreferredSlotId\", -1);\n\t}\n\n\tpublic boolean getItemShortcutBlockItemFromMoving()\n\t{\n\t\treturn getConfigE().getBoolean(\"ItemShortcut.BlockItemFromMoving\", false);\n\t}\n\t//endregion\n\n\t//region Sound settings\n\tprivate Sound getSound(String option, String autoValue)\n\t{\n\t\tif(!getConfigE().getBoolean(\"Sound.Enabled\", true)) return null;\n\t\tString soundName = getConfigE().getString(\"Sound.\" + option, \"auto\").toUpperCase(Locale.ENGLISH);\n\t\tif(soundName.equals(\"AUTO\")) soundName = autoValue;\n\t\tif(soundName.equals(\"DISABLED\") || soundName.equals(\"FALSE\")) return null;\n\t\ttry\n\t\t{\n\t\t\tif (MCVersion.isNewerOrEqualThan(MCVersion.MC_1_21))\n\t\t\t{\n\t\t\t\tField f = Reflection.getField(Sound.class, soundName);\n\t\t\t\tif (f != null) return (Sound) f.get(null);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn Sound.valueOf(soundName);\n\t\t\t}\n\t\t}\n\t\tcatch(Exception ignored)\n\t\t{\n\t\t\tlogger.warning(\"Unknown sound: \" + soundName);\n\t\t}\n\t\treturn null;\n\t}\n\n\tprivate static final @NotNull String DEFAULT_SOUND_OPEN = MCVersion.isNewerOrEqualThan(MCVersion.MC_1_11) ? \"BLOCK_SHULKER_BOX_OPEN\" : (MCVersion.isNewerOrEqualThan(MCVersion.MC_1_9_2) ? \"BLOCK_CHEST_OPEN\" : \"CHEST_OPEN\");\n\tprivate static final @NotNull String DEFAULT_SOUND_CLOSE = MCVersion.isNewerOrEqualThan(MCVersion.MC_1_11) ? \"BLOCK_SHULKER_BOX_CLOSE\" : (MCVersion.isNewerOrEqualThan(MCVersion.MC_1_9_2) ? \"BLOCK_CHEST_CLOSE\" : \"CHEST_CLOSE\");\n\n\tpublic Sound getOpenSound()\n\t{\n\t\treturn getSound(\"OpenSound\", DEFAULT_SOUND_OPEN);\n\t}\n\n\tpublic Sound getCloseSound()\n\t{\n\t\treturn getSound(\"CloseSound\", DEFAULT_SOUND_CLOSE);\n\t}\n\t//endregion\n\n\t//region InventoryManagement settings\n\tpublic boolean isInventoryManagementClearCommandEnabled()\n\t{\n\t\treturn getConfigE().getBoolean(\"InventoryManagement.ClearCommand.Enabled\", true);\n\t}\n\t//endregion\n\t//endregion\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Database.java",
    "content": "/*\n *   Copyright (C) 2023 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Database;\n\nimport at.pcgamingfreaks.ConsoleColor;\nimport at.pcgamingfreaks.Database.ConnectionProvider.ConnectionProvider;\nimport at.pcgamingfreaks.Minepacks.Bukkit.API.Callback;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Backpack;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Database.UnCacheStrategies.OnDisconnect;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Database.UnCacheStrategies.UnCacheStrategy;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\n\nimport org.bukkit.OfflinePlayer;\nimport org.bukkit.entity.Player;\nimport org.bukkit.event.EventHandler;\nimport org.bukkit.event.HandlerList;\nimport org.bukkit.event.Listener;\nimport org.bukkit.event.player.PlayerJoinEvent;\nimport org.bukkit.inventory.ItemStack;\nimport org.jetbrains.annotations.NotNull;\nimport org.jetbrains.annotations.Nullable;\n\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.util.*;\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.logging.Level;\n\npublic abstract class Database implements Listener\n{\n\tpublic static final String MESSAGE_UNKNOWN_DB_TYPE = ConsoleColor.RED + \"Unknown database type \\\"%s\\\"!\" + ConsoleColor.RESET;\n\n\tprotected final Minepacks plugin;\n\tprotected final InventorySerializer itsSerializer;\n\tprotected final boolean onlineUUIDs, bungeeCordMode, forceSaveOnUnload;\n\tprotected boolean useUUIDSeparators, asyncSave = true;\n\tprotected long maxAge;\n\tprivate final Map<UUID, Backpack> backpacks = new ConcurrentHashMap<>();\n\tprivate final UnCacheStrategy unCacheStrategy;\n\tprivate final File backupFolder;\n\n\tpublic Database(Minepacks mp)\n\t{\n\t\tplugin = mp;\n\t\titsSerializer = new InventorySerializer(plugin.getLogger());\n\t\tuseUUIDSeparators = plugin.getConfiguration().getUseUUIDSeparators();\n\t\tonlineUUIDs = plugin.getConfiguration().useOnlineUUIDs();\n\t\tbungeeCordMode = plugin.getConfiguration().isBungeeCordModeEnabled();\n\t\tforceSaveOnUnload = plugin.getConfiguration().isForceSaveOnUnloadEnabled();\n\t\tmaxAge = plugin.getConfiguration().getAutoCleanupMaxInactiveDays();\n\t\tunCacheStrategy = bungeeCordMode ? new OnDisconnect(this) : UnCacheStrategy.getUnCacheStrategy(this);\n\t\tbackupFolder = new File(this.plugin.getDataFolder(), \"backups\");\n\t\tif(!backupFolder.exists() && !backupFolder.mkdirs()) mp.getLogger().info(\"Failed to create backups folder.\");\n\t}\n\n\tpublic void init()\n\t{\n\t\tplugin.getServer().getPluginManager().registerEvents(this, plugin);\n\t}\n\n\tpublic void close()\n\t{\n\t\tHandlerList.unregisterAll(this);\n\t\tasyncSave = false;\n\t\tbackpacks.forEach((key, value) -> { if (forceSaveOnUnload) { value.setChanged(); } value.closeAll(); });\n\t\tbackpacks.clear();\n\t\tunCacheStrategy.close();\n\t}\n\n\tpublic static @Nullable Database getDatabase(Minepacks plugin)\n\t{\n\t\ttry\n\t\t{\n\t\t\tString dbType = plugin.getConfiguration().getDatabaseType();\n\t\t\tConnectionProvider connectionProvider = null;\n\t\t\tif(dbType.equals(\"shared\") || dbType.equals(\"external\") || dbType.equals(\"global\"))\n\t\t\t{\n\t\t\t\t/*if[STANDALONE]\n\t\t\t\tplugin.getLogger().warning(ConsoleColor.RED + \"The shared database connection option is not available in standalone mode!\" + ConsoleColor.RESET);\n\t\t\t\treturn null;\n\t\t\t\telse[STANDALONE]*/\n\t\t\t\tat.pcgamingfreaks.PluginLib.Database.DatabaseConnectionPool pool = at.pcgamingfreaks.PluginLib.Bukkit.PluginLib.getInstance().getDatabaseConnectionPool();\n\t\t\t\tif(pool == null)\n\t\t\t\t{\n\t\t\t\t\tplugin.getLogger().warning(ConsoleColor.RED + \"The shared connection pool is not initialized correctly!\" + ConsoleColor.RESET);\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tdbType = pool.getDatabaseType().toLowerCase(Locale.ROOT);\n\t\t\t\tconnectionProvider = pool.getConnectionProvider();\n\t\t\t\t/*end[STANDALONE]*/\n\t\t\t}\n\t\t\tDatabase database;\n\t\t\tswitch(dbType)\n\t\t\t{\n\t\t\t\tcase \"mysql\": database = new MySQL(plugin, connectionProvider); break;\n\t\t\t\tcase \"sqlite\": database = new SQLite(plugin, connectionProvider); break;\n\t\t\t\tcase \"flat\":\n\t\t\t\tcase \"file\":\n\t\t\t\tcase \"files\":\n\t\t\t\t\tdatabase = new Files(plugin); break;\n\t\t\t\tdefault: plugin.getLogger().warning(String.format(MESSAGE_UNKNOWN_DB_TYPE,  plugin.getConfiguration().getDatabaseType())); return null;\n\t\t\t}\n\t\t\tdatabase.init();\n\t\t\treturn database;\n\t\t}\n\t\tcatch(IllegalStateException ignored) {}\n\t\tcatch(Exception e)\n\t\t{\n\t\t\tplugin.getLogger().log(Level.SEVERE, \"Failed to initialize database.\", e);\n\t\t}\n\t\treturn null;\n\t}\n\n\tpublic void backup(@NotNull Backpack backpack)\n\t{\n\t\twriteBackup(backpack.getOwner().getName(), getPlayerFormattedUUID(backpack.getOwnerId()), itsSerializer.getUsedSerializer(), itsSerializer.serialize(backpack.getInventory()));\n\t}\n\n\tprotected void writeBackup(@Nullable String userName, @NotNull String userIdentifier, final int usedSerializer, final byte[] data)\n\t{\n\t\tif(userIdentifier.equalsIgnoreCase(userName)) userName = null;\n\t\tif(userName != null) userIdentifier = userName + \"_\" + userIdentifier;\n\t\tfinal File save = new File(backupFolder, userIdentifier + \"_\" + System.currentTimeMillis() + Files.EXT);\n\t\ttry(FileOutputStream fos = new FileOutputStream(save))\n\t\t{\n\t\t\tfos.write(usedSerializer);\n\t\t\tfos.write(data);\n\t\t\tplugin.getLogger().info(\"Backup of the backpack has been created: \" + save.getAbsolutePath());\n\t\t}\n\t\tcatch(Exception e)\n\t\t{\n\t\t\tplugin.getLogger().warning(ConsoleColor.RED + \"Failed to write backup! Error: \" + e.getMessage() + ConsoleColor.RESET);\n\t\t}\n\t}\n\n\tpublic @Nullable ItemStack[] loadBackup(final String backupName)\n\t{\n\t\tFile backup = new File(backupFolder, backupName + Files.EXT);\n\t\treturn Files.readFile(itsSerializer, backup, plugin.getLogger());\n\t}\n\n\tpublic ArrayList<String> getBackups()\n\t{\n\t\tFile[] files = backupFolder.listFiles((dir, name) -> name.endsWith(Files.EXT));\n\t\tif(files != null)\n\t\t{\n\t\t\tArrayList<String> backups = new ArrayList<>(files.length);\n\t\t\tfor(File file : files)\n\t\t\t{\n\t\t\t\tif(!file.isFile()) continue;\n\t\t\t\tbackups.add(file.getName().replaceAll(Files.EXT_REGEX, \"\"));\n\t\t\t}\n\t\t\treturn backups;\n\t\t}\n\t\treturn new ArrayList<>();\n\t}\n\n\tprotected String getPlayerFormattedUUID(OfflinePlayer player)\n\t{\n\t\treturn getPlayerFormattedUUID(player.getUniqueId());\n\t}\n\n\tprotected String getPlayerFormattedUUID(UUID uuid)\n\t{\n\t\treturn (useUUIDSeparators) ? uuid.toString() : uuid.toString().replace(\"-\", \"\");\n\t}\n\n\tpublic @NotNull Collection<Backpack> getLoadedBackpacks()\n\t{\n\t\treturn backpacks.values();\n\t}\n\n\t/**\n\t * Gets a backpack for a player. This only includes backpacks that are cached! Do not use it unless you are sure that you only want to use cached data!\n\t *\n\t * @param player The player whose backpack should be retrieved.\n\t * @return The backpack for the player. null if the backpack is not in the cache.\n\t */\n\tpublic @Nullable Backpack getBackpack(@Nullable OfflinePlayer player)\n\t{\n\t\treturn (player == null) ? null : backpacks.get(player.getUniqueId());\n\t}\n\n\tpublic void getBackpack(final OfflinePlayer player, final Callback<at.pcgamingfreaks.Minepacks.Bukkit.API.Backpack> callback, final boolean createNewOnFail)\n\t{\n\t\tif(player == null || player.getClass().getName().contains(\"NPC\"))\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\tBackpack lbp = backpacks.get(player.getUniqueId());\n\t\tif(lbp == null)\n\t\t{\n\t\t\tloadBackpack(player, new Callback<Backpack>()\n\t\t\t{\n\t\t\t\t@Override\n\t\t\t\tpublic void onResult(Backpack backpack)\n\t\t\t\t{\n\t\t\t\t\tbackpacks.put(player.getUniqueId(), backpack);\n\t\t\t\t\tcallback.onResult(backpack);\n\t\t\t\t}\n\n\t\t\t\t@Override\n\t\t\t\tpublic void onFail()\n\t\t\t\t{\n\t\t\t\t\tif(createNewOnFail)\n\t\t\t\t\t{\n\t\t\t\t\t\tBackpack backpack = new Backpack(player);\n\t\t\t\t\t\tbackpacks.put(player.getUniqueId(), backpack);\n\t\t\t\t\t\tcallback.onResult(backpack);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tcallback.onFail();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\telse\n\t\t{\n\t\t\tcallback.onResult(lbp);\n\t\t}\n\t}\n\n\tpublic void getBackpack(final OfflinePlayer player, final Callback<at.pcgamingfreaks.Minepacks.Bukkit.API.Backpack> callback)\n\t{\n\t\tgetBackpack(player, callback, true);\n\t}\n\n\tpublic void unloadBackpack(Backpack backpack)\n\t{\n\t\tif (forceSaveOnUnload)\n\t\t{\n\t\t\tbackpack.forceSave();\n\t\t}\n\t\telse\n\t\t{\n\t\t\tbackpack.save();\n\t\t}\n\t\tbackpacks.remove(backpack.getOwnerId());\n\t}\n\n\tpublic void asyncLoadBackpack(final OfflinePlayer player)\n\t{\n\t\tif(player != null && backpacks.get(player.getUniqueId()) == null)\n\t\t{\n\t\t\tloadBackpack(player, new Callback<Backpack>()\n\t\t\t{\n\t\t\t\t@Override\n\t\t\t\tpublic void onResult(Backpack backpack)\n\t\t\t\t{\n\t\t\t\t\tbackpacks.put(player.getUniqueId(), backpack);\n\t\t\t\t}\n\n\t\t\t\t@Override\n\t\t\t\tpublic void onFail()\n\t\t\t\t{\n\t\t\t\t\tbackpacks.put(player.getUniqueId(), new Backpack(player));\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\t@EventHandler\n\tpublic void onPlayerLoginEvent(PlayerJoinEvent event)\n\t{\n\t\tupdatePlayerAndLoadBackpack(event.getPlayer());\n\t}\n\n\t// DB Functions\n\tpublic void updatePlayerAndLoadBackpack(Player player)\n\t{\n\t\tupdatePlayer(player);\n\t\tif(!bungeeCordMode) asyncLoadBackpack(player);\n\t}\n\n\tpublic abstract void updatePlayer(Player player);\n\n\tpublic abstract void saveBackpack(Backpack backpack);\n\n\tpublic void syncCooldown(Player player, long time) {}\n\n\tpublic void getCooldown(final Player player, final Callback<Long> callback) {}\n\n\tprotected abstract void loadBackpack(final OfflinePlayer player, final Callback<Backpack> callback);\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Files.java",
    "content": "/*\n *   Copyright (C) 2024 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Database;\n\nimport at.pcgamingfreaks.Minepacks.Bukkit.API.Callback;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Backpack;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport at.pcgamingfreaks.UUID.UuidConverter;\n\nimport org.bukkit.OfflinePlayer;\nimport org.bukkit.entity.Player;\nimport org.bukkit.inventory.ItemStack;\nimport org.jetbrains.annotations.NotNull;\nimport org.jetbrains.annotations.Nullable;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.util.UUID;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\npublic class Files extends Database\n{\n\tpublic static final String EXT = \".backpack\", EXT_REGEX = \"\\\\.backpack\", FOLDER_NAME = \"backpacks\";\n\n\tprivate final File saveFolder;\n\tprivate final UuidConverter converter;\n\t\n\tpublic Files(Minepacks plugin)\n\t{\n\t\tsuper(plugin);\n\t\tconverter = new UuidConverter(plugin.getLogger());\n\t\tmaxAge *= 24 * 3600000L;\n\t\tsaveFolder = new File(this.plugin.getDataFolder(), FOLDER_NAME);\n\t\tif(!saveFolder.exists())\n\t\t{\n\t\t\tif(!saveFolder.mkdirs())\n\t\t\t{\n\t\t\t\tplugin.getLogger().warning(\"Failed to create save folder (\" + saveFolder.getAbsolutePath() + \").\");\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tcheckFiles();\n\t\t}\n\t}\n\n\t@Override\n\tpublic void updatePlayer(Player player)\n\t{\n\t\t// Files are stored with the users name or the uuid, there is no reason to update anything\n\t}\n\n\tprivate String getUuidFromFileName(String fileName)\n\t{\n\t\tString name = fileName.substring(0, fileName.length() - EXT.length());\n\t\tUUID uuid = (onlineUUIDs) ? converter.getUUID(name, true) : UuidConverter.getOfflineModeUUID(name);\n\t\treturn getPlayerFormattedUUID(uuid);\n\t}\n\n\tprivate void tryRename(File file, File newFileName)\n\t{\n\t\tif (!file.renameTo(newFileName))\n\t\t{\n\t\t\tplugin.getLogger().log(Level.WARNING, () -> \"Failed to rename file (\" + file.getAbsolutePath() + \" to \" + newFileName.getAbsolutePath() + \").\");\n\t\t}\n\t}\n\n\tprivate void checkFiles()\n\t{\n\t\tFile[] allFiles = saveFolder.listFiles((dir, name) -> name.endsWith(EXT));\n\t\tif(allFiles == null) return;\n\t\tfor (File file : allFiles)\n\t\t{\n\t\t\tif(maxAge > 0 && System.currentTimeMillis() - file.lastModified() > maxAge) // Check if the file is older than x days\n\t\t\t{\n\t\t\t\tif(!file.delete())\n\t\t\t\t{\n\t\t\t\t\tplugin.getLogger().warning(\"Failed to delete file (\" + file.getAbsolutePath() + \").\");\n\t\t\t\t}\n\t\t\t\tcontinue; // We don't have to check if the file name is correct because we have the deleted the file\n\t\t\t}\n\t\t\tint len = file.getName().length() - EXT.length();\n\t\t\tif(len <= 16) // It's a player name\n\t\t\t{\n\t\t\t\ttryRename(file, new File(saveFolder, getUuidFromFileName(file.getName()) + EXT));\n\t\t\t}\n\t\t\telse // It's a UUID\n\t\t\t{\n\t\t\t\tif(file.getName().contains(\"-\"))\n\t\t\t\t{\n\t\t\t\t\tif(!useUUIDSeparators)\n\t\t\t\t\t{\n\t\t\t\t\t\ttryRename(file, new File(saveFolder, file.getName().replaceAll(\"-\", \"\")));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if(useUUIDSeparators)\n\t\t\t\t{\n\t\t\t\t\ttryRename(file, new File(saveFolder, file.getName().replaceAll(\"(\\\\w{8})(\\\\w{4})(\\\\w{4})(\\\\w{4})(\\\\w{12})\" + EXT_REGEX, \"$1-$2-$3-$4-$5\" + EXT)));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t\n\tprivate String getFileName(UUID uuid)\n\t{\n\t\treturn getPlayerFormattedUUID(uuid) + EXT;\n\t}\n\t\n\t// DB Functions\n\t@Override\n\tpublic void saveBackpack(Backpack backpack)\n\t{\n\t\tFile save = new File(saveFolder, getFileName(backpack.getOwnerId()));\n\t\ttry(FileOutputStream fos = new FileOutputStream(save))\n\t\t{\n\t\t\tfos.write(itsSerializer.getUsedSerializer());\n\t\t\tfos.write(itsSerializer.serialize(backpack.getInventory()));\n\t\t\tfos.flush();\n\t\t}\n\t\tcatch(Exception e)\n\t\t{\n\t\t\tplugin.getLogger().log(Level.SEVERE, \"Failed to save backpack.\", e);\n\t\t}\n\t}\n\n\t@Override\n\tprotected void loadBackpack(final OfflinePlayer player, final Callback<Backpack> callback)\n\t{ //TODO this needs to be done async!\n\t\tFile save = new File(saveFolder, getFileName(player.getUniqueId()));\n\t\tItemStack[] itemStacks = readFile(itsSerializer, save, plugin.getLogger());\n\t\tif(itemStacks != null)\n\t\t{\n\t\t\tcallback.onResult(new Backpack(player, itemStacks, -1));\n\t\t}\n\t\telse\n\t\t{\n\t\t\tcallback.onFail();\n\t\t}\n\t}\n\n\tprotected static @Nullable ItemStack[] readFile(@NotNull InventorySerializer itsSerializer, @NotNull File file, @NotNull Logger logger)\n\t{\n\t\tif(file.exists())\n\t\t{\n\t\t\ttry(FileInputStream fis = new FileInputStream(file))\n\t\t\t{\n\t\t\t\tint version = fis.read();\n\t\t\t\tbyte[] out = new byte[(int) (file.length() - 1)];\n\t\t\t\tint readCount = fis.read(out);\n\t\t\t\tif(file.length() - 1 != readCount) logger.warning(\"Problem reading file, read \" + readCount + \" of \" + (file.length() - 1) + \" bytes.\");\n\t\t\t\treturn itsSerializer.deserialize(out, version);\n\t\t\t}\n\t\t\tcatch(Exception e)\n\t\t\t{\n\t\t\t\tlogger.log(Level.WARNING, \"Failed to read backpack.\", e);\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Helper/InventoryCompressor.java",
    "content": "/*\n *   Copyright (C) 2020 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Database.Helper;\n\nimport lombok.Getter;\nimport org.bukkit.Material;\nimport org.bukkit.inventory.ItemStack;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class InventoryCompressor\n{\n\t@Getter private ItemStack[] targetStacks, inputStacks;\n\tprivate int filled = 0;\n\tprivate ItemStack lastStack = null;\n\t@Getter private List<ItemStack> toMuch;\n\n\tpublic InventoryCompressor(ItemStack[] stacks)\n\t{\n\t\tthis(stacks, stacks.length);\n\t}\n\n\tpublic InventoryCompressor(ItemStack[] stacks, int targetSize)\n\t{\n\t\tinputStacks = stacks;\n\t\ttargetStacks = new ItemStack[targetSize];\n\t\ttoMuch = new ArrayList<>(inputStacks.length - targetStacks.length);\n\t}\n\n\tpublic InventoryCompressor(ItemStack[] input, ItemStack[] output)\n\t{\n\t\tinputStacks = input;\n\t\ttargetStacks = output;\n\t\ttoMuch = new ArrayList<>(inputStacks.length - targetStacks.length);\n\t}\n\n\tpublic List<ItemStack> sort()\n\t{\n\t\tfor(int i = 0; i < inputStacks.length; i++)\n\t\t{\n\t\t\tItemStack stack  = inputStacks[i];\n\t\t\tif(stack == null || stack.getType() == Material.AIR || stack.getAmount() < 1) continue;\n\t\t\tadd(stack);\n\t\t\tmove(stack, i+1);\n\t\t}\n\t\treturn toMuch;\n\t}\n\n\tprivate void move(ItemStack stack, int start)\n\t{ // Search items that are the same\n\t\tint differentMetaStart = -1;\n\t\tfor(int i = start; i < inputStacks.length; i++)\n\t\t{\n\t\t\tItemStack stack2 = inputStacks[i];\n\t\t\tif(stack2 == null || stack2.getType() == Material.AIR || stack2.getAmount() < 1) continue;\n\t\t\tif(stack.isSimilar(stack2))\n\t\t\t{\n\t\t\t\tadd(stack2); // Add item to sorted array\n\t\t\t\tinputStacks[i] = null; // Remove item from input\n\t\t\t}\n\t\t\telse if(differentMetaStart == -1 && stack.getType() == stack2.getType())\n\t\t\t{ // Same material but different meta\n\t\t\t\tdifferentMetaStart = i;\n\t\t\t}\n\t\t}\n\t\tif(differentMetaStart >= 0)\n\t\t\tmove(inputStacks[differentMetaStart], differentMetaStart);\n\t}\n\n\tprivate void add(ItemStack stack)\n\t{\n\t\tif(stack.isSimilar(lastStack) && lastStack.getAmount() < lastStack.getMaxStackSize())\n\t\t{ // There is still space on the last stack, try to add it\n\t\t\tint free = lastStack.getMaxStackSize() - lastStack.getAmount();\n\t\t\tint place = Math.min(free, stack.getAmount());\n\t\t\tlastStack.setAmount(lastStack.getAmount()  + place);\n\t\t\tstack.setAmount(stack.getAmount() - place);\n\t\t}\n\t\tif(stack.getAmount() < 1) return;\n\t\tif(filled == targetStacks.length)\n\t\t{ // The new item stack is full, add it to overfill list\n\t\t\ttoMuch.add(stack);\n\t\t}\n\t\telse\n\t\t{ // Add the rest to the new inventory\n\t\t\ttargetStacks[filled++] = stack;\n\t\t\tlastStack = stack;\n\t\t}\n\t}\n\n\tpublic List<ItemStack> compress()\n\t{\n\t\tfor(ItemStack stack : inputStacks)\n\t\t{\n\t\t\tif(stack == null || stack.getType() == Material.AIR || stack.getAmount() < 1) continue;\n\t\t\ttryToStack(stack);\n\t\t\tif(stack.getAmount() == 0) continue;\n\t\t\tif(filled == targetStacks.length)\n\t\t\t{\n\t\t\t\ttoMuch.add(stack);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\ttargetStacks[filled++] = stack;\n\t\t\t}\n\t\t}\n\t\treturn toMuch;\n\t}\n\n\tprivate void tryToStack(ItemStack stack)\n\t{\n\t\tif(stack.getAmount() >= stack.getMaxStackSize()) return;\n\t\tfor(int i = 0; i < filled && stack.getAmount() > 0; i++)\n\t\t{\n\t\t\tif(stack.isSimilar(targetStacks[i]) && targetStacks[i].getAmount() < targetStacks[i].getMaxStackSize())\n\t\t\t{ // Same material and none full stack\n\t\t\t\tint move = targetStacks[i].getMaxStackSize() - targetStacks[i].getAmount();\n\t\t\t\tmove = Math.min(stack.getAmount(), move);\n\t\t\t\ttargetStacks[i].setAmount(targetStacks[i].getAmount() + move);\n\t\t\t\tstack.setAmount(stack.getAmount() - move);\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic List<ItemStack> fast()\n\t{\n\t\tfor(ItemStack stack : inputStacks)\n\t\t{\n\t\t\tif(stack == null || stack.getType() == Material.AIR || stack.getAmount() < 1) continue;\n\t\t\tif(filled == targetStacks.length)\n\t\t\t{\n\t\t\t\ttoMuch.add(stack);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\ttargetStacks[filled++] = stack;\n\t\t\t}\n\t\t}\n\t\treturn toMuch;\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Helper/OldFileUpdater.java",
    "content": "/*\n *   Copyright (C) 2019 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Database.Helper;\n\nimport at.pcgamingfreaks.yaml.YAML;\n\nimport java.util.LinkedHashMap;\nimport java.util.Map;\nimport java.util.logging.Logger;\n\npublic class OldFileUpdater\n{\n\tpublic static void updateConfig(YAML oldYAML, YAML newYAML)\n\t{\n\t\tint oldVersion = oldYAML.getInt(\"Version\", -1);\n\t\tfor(String key : newYAML.getKeys())\n\t\t{\n\t\t\tString oldKey = key;\n\t\t\tif(key.equals(\"Version\")) continue;\n\t\t\tif(oldVersion < 11)\n\t\t\t{\n\t\t\t\tif(key.equals(\"BackpackTitle\") || key.equals(\"BackpackTitleOther\")) continue;\n\t\t\t\toldKey = key.replace(\".SQL.\", \".MySQL.\");\n\t\t\t}\n\t\t\tswitch(key)\n\t\t\t{\n\t\t\t\tcase \"Cooldown.Command\": oldKey = \"command_cooldown\"; break;\n\t\t\t\tcase \"Cooldown.Sync\": oldKey = \"sync_cooldown\"; break;\n\t\t\t\tcase \"DropOnDeath\": oldKey = \"drop_on_death\"; break;\n\t\t\t\tcase \"MaxSize\": oldKey = \"max_size\"; break;\n\t\t\t\tcase \"AllowedGameModes\": oldKey = \"allowed_game_modes\"; break;\n\t\t\t\tcase \"FullInventory.CollectItems\": oldKey = \"full_inventory.collect_items\"; break;\n\t\t\t\tcase \"FullInventory.CheckInterval\": oldKey = \"full_inventory.check_interval\"; break;\n\t\t\t\tcase \"FullInventory.CollectRadius\": oldKey = \"full_inventory.collect_radius\"; break;\n\t\t\t\tcase \"Misc.AutoUpdate\": oldKey = \"auto-update\"; break;\n\t\t\t\tcase \"Misc.UseBungeeCord\": oldKey = \"BungeeCordMode\"; break;\n\t\t\t\tcase \"Language.Language\": oldKey = \"Language\"; break;\n\t\t\t\tcase \"Database.UseUUIDs\":\n\t\t\t\tcase \"UseUUIDs\":\n\t\t\t\t\tcontinue;\n\t\t\t}\n\t\t\ttry\n\t\t\t{\n\t\t\t\tif(oldYAML.isSet(oldKey)) newYAML.set(key, oldYAML.getString(oldKey));\n\t\t\t}\n\t\t\tcatch(Exception e)\n\t\t\t{\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t}\n\t\tif(oldVersion < 11)\n\t\t{\n\t\t\tnewYAML.set(\"BackpackTitleOther\", oldYAML.getString(\"BackpackTitle\", \"&b{OwnerName} Backpack\").replaceAll(\"%s\", \"{OwnerName}\"));\n\t\t}\n\t}\n\n\tpublic static void updateLanguage(YAML oldYAML, YAML newYAML, Logger logger)\n\t{\n\t\tMap<String, String> simpleConverter = new LinkedHashMap<>(), advancedConverter = new LinkedHashMap<>();\n\t\tString[] keys;\n\t\tString helper;\n\t\tfor(String key : oldYAML.getKeys(true))\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tkeys = key.split(\"\\\\.\");\n\t\t\t\tif(keys.length == 3 && keys[0].equals(\"Language\"))\n\t\t\t\t{\n\t\t\t\t\tswitch(keys[1])\n\t\t\t\t\t{\n\t\t\t\t\t\tcase \"Console\":\n\t\t\t\t\t\t\tif(\"NotFromConsole\".equals(keys[2]))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tadvancedConverter.put(\"Language.NotFromConsole\", \"&c\" + oldYAML.getString(key));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"Ingame\":\n\t\t\t\t\t\t\thelper = keys[0] + \".\" + keys[1] + \".\";\n\t\t\t\t\t\t\tswitch(keys[2])\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcase \"NoPermission\": advancedConverter.put(key, \"&c\" + oldYAML.getString(key)); break;\n\t\t\t\t\t\t\t\tcase \"OwnBackPackClose\": simpleConverter.put(helper + \"OwnBackpackClose\", key); break;\n\t\t\t\t\t\t\t\tcase \"PlayerBackPackClose\": advancedConverter.put(helper + \"PlayerBackpackClose\", oldYAML.getString(key).replace(\"%s\", \"{OwnerName}\")); break;\n\t\t\t\t\t\t\t\tcase \"InvalidBackpack\": simpleConverter.put(key, key); break;\n\t\t\t\t\t\t\t\tcase \"BackpackCleaned\": simpleConverter.put(\"Language.Ingame.Clean.BackpackCleaned\", key); break;\n\t\t\t\t\t\t\t\tcase \"Cooldown\": advancedConverter.put(\"Language.Ingame.Open.Cooldown\", \"&2\" + oldYAML.getString(key)); break;\n\t\t\t\t\t\t\t\tcase \"WrongGameMode\": simpleConverter.put(\"Language.Ingame.Open.WrongGameMode\", key); break;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"Description\":\n\t\t\t\t\t\t\thelper = \"Language.Commands.Description.\";\n\t\t\t\t\t\t\tsimpleConverter.put(helper + keys[2], key);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif(keys.length == 1)\n\t\t\t\t{\n\t\t\t\t\tswitch(keys[0])\n\t\t\t\t\t{\n\t\t\t\t\t\tcase \"LanguageName\":\n\t\t\t\t\t\tcase \"Author\":\n\t\t\t\t\t\t\tsimpleConverter.put(key, key);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch(Exception e)\n\t\t\t{\n\t\t\t\tlogger.warning(\"Failed to convert the old \\\"\" + key + \"\\\" language value into the corresponding new one.\");\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t}\n\n\t\t// Patch them into the lang file\n\t\ttry\n\t\t{\n\t\t\tfor(Map.Entry<String, String> entry : advancedConverter.entrySet())\n\t\t\t{\n\t\t\t\tnewYAML.set(entry.getKey(), entry.getValue());\n\t\t\t}\n\t\t\tfor(Map.Entry<String, String> entry : simpleConverter.entrySet())\n\t\t\t{\n\t\t\t\tnewYAML.set(entry.getKey(), oldYAML.getString(entry.getValue()));\n\t\t\t}\n\t\t}\n\t\tcatch(Exception e)\n\t\t{\n\t\t\tlogger.warning(\"Failed to write the old language values into the new language file.\");\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/InventorySerializer.java",
    "content": "/*\n *   Copyright (C) 2020 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Database;\n\nimport at.pcgamingfreaks.Bukkit.ItemStackSerializer.ItemStackSerializer;\nimport at.pcgamingfreaks.Bukkit.MCVersion;\nimport at.pcgamingfreaks.ConsoleColor;\n\nimport lombok.Getter;\nimport org.bukkit.inventory.Inventory;\nimport org.bukkit.inventory.ItemStack;\n\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\npublic class InventorySerializer\n{\n\t@SuppressWarnings(\"deprecation\")\n\tprivate static final ItemStackSerializer BUKKIT_ITEM_STACK_SERIALIZER = ItemStackSerializer.makeBukkitItemStackSerializer();\n\n\tprivate final Logger logger;\n\tprivate final ItemStackSerializer serializer;\n\t@Getter private final int usedSerializer;\n\t\n\tpublic InventorySerializer(Logger logger)\n\t{\n\t\tthis.logger = logger;\n\t\tItemStackSerializer serializer = null;\n\t\tint usedSerializer = 2;\n\t\ttry\n\t\t{\n\t\t\tif(ItemStackSerializer.isNBTItemStackSerializerAvailable())\n\t\t\t{\n\t\t\t\tserializer = ItemStackSerializer.makeNBTItemStackSerializer(logger);\n\t\t\t}\n\t\t}\n\t\tcatch(Exception e)\n\t\t{\n\t\t\tlogger.log(Level.SEVERE, \"Failed to produce serializer!\", e);\n\t\t}\n\t\tif(serializer == null)\n\t\t{\n\t\t\tlogger.severe(\"NBTItemStackSerializer does not support your Minecraft version!\\nFalling back to BukkitItemStackSerializer! This most likely is wrong!\");\n\t\t\tif (MCVersion.isOlderThan(MCVersion.MC_NMS_1_8_R1))\n\t\t\t{\n\t\t\t\tusedSerializer = 0;\n\t\t\t\tserializer = BUKKIT_ITEM_STACK_SERIALIZER;\n\t\t\t}\n\t\t}\n\t\tthis.serializer = serializer;\n\t\tthis.usedSerializer = usedSerializer;\n\t}\n\t\n\tpublic byte[] serialize(Inventory inv)\n\t{\n\t\treturn serializer.serialize(inv.getContents());\n\t}\n\n\tpublic ItemStack[] deserialize(byte[] data, int usedSerializer)\n\t{\n\t\tif(data == null) return null;\n\t\tswitch(usedSerializer)\n\t\t{\n\t\t\tcase 0: return BUKKIT_ITEM_STACK_SERIALIZER.deserialize(data);\n\t\t\tcase 1: if(MCVersion.isNewerOrEqualThan(MCVersion.MC_1_13)) logger.warning(ConsoleColor.YELLOW + \"Backpack was created with an old version of minepacks and minecraft. There is the chance that some items will disappear from it.\" + ConsoleColor.RESET);\n\t\t\tcase 2: return serializer.deserialize(data);\n\t\t\tdefault: logger.warning(ConsoleColor.RED + \"No compatible deserializer for backpack format available!\" + ConsoleColor.RESET);\n\t\t}\n\t\treturn null;\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Language.java",
    "content": "/*\n *   Copyright (C) 2023 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Database;\n\nimport at.pcgamingfreaks.Bukkit.Message.Message;\nimport at.pcgamingfreaks.Config.YamlFileManager;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Database.Helper.OldFileUpdater;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport at.pcgamingfreaks.Minepacks.MagicValues;\nimport at.pcgamingfreaks.Version;\nimport org.jetbrains.annotations.NotNull;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class Language extends at.pcgamingfreaks.Bukkit.Config.Language\n{\n\tprivate static final Version LANG_VERSION = new Version(MagicValues.LANG_VERSION);\n\n\tpublic Language(Minepacks plugin)\n\t{\n\t\tsuper(plugin, LANG_VERSION);\n\t}\n\n\t@Override\n\tprotected void doUpgrade(@NotNull YamlFileManager oldLang)\n\t{\n\t\tif(oldLang.getVersion().olderThan(new Version(10))) // Pre v2.0 versions\n\t\t{\n\t\t\tOldFileUpdater.updateLanguage(oldLang.getYamlE(), getYaml(), getLogger());\n\t\t}\n\t\telse\n\t\t{\n\t\t\tsuper.doUpgrade(oldLang);\n\t\t}\n\t}\n\n\tpublic String[] getCommandAliases(final String command)\n\t{\n\t\treturn getCommandAliases(command, new String[0]);\n\t}\n\n\tpublic String[] getCommandAliases(final String command, final @NotNull String... defaults)\n\t{\n\t\tList<String> aliases = getLangE().getStringList(\"Command.\" + command, new ArrayList<>(0));\n\t\treturn (aliases.size() > 0) ? aliases.toArray(new String[0]) : defaults;\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Migration/FilesToSQLMigration.java",
    "content": "/*\n *   Copyright (C) 2018 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Database.Migration;\n\nimport at.pcgamingfreaks.Minepacks.Bukkit.Database.Files;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport org.intellij.lang.annotations.Language;\nimport org.jetbrains.annotations.NotNull;\nimport org.jetbrains.annotations.Nullable;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.sql.Connection;\nimport java.sql.PreparedStatement;\nimport java.sql.ResultSet;\n\npublic class FilesToSQLMigration extends ToSQLMigration\n{\n\tprivate final @Language(\"SQL\") String queryInsertUsers, queryInsertBackpacks;\n\tprivate final File saveFolder;\n\n\tprotected FilesToSQLMigration(@NotNull Minepacks plugin, @NotNull Files oldDb, @NotNull String dbType, boolean global) throws Exception\n\t{\n\t\tsuper(plugin, oldDb, dbType, global);\n\t\tsaveFolder = new File(this.plugin.getDataFolder(), Files.FOLDER_NAME);\n\n\t\tqueryInsertUsers = replacePlaceholders(newDb, \"INSERT INTO {TablePlayers} ({FieldUUID},{FieldName}) VALUES (?,?);\");\n\t\tqueryInsertBackpacks = replacePlaceholders(newDb, \"INSERT INTO {TableBackpacks} ({FieldBPOwner},{FieldBPITS},{FieldBPVersion}) VALUES (?,?,?);\");\n\t}\n\n\t@Override\n\tpublic @Nullable MigrationResult migrate() throws Exception\n\t{\n\t\tFile[] allFiles = saveFolder.listFiles((dir, name) -> name.endsWith(Files.EXT));\n\t\tif(allFiles == null) return null;\n\t\ttry(Connection connection = newDb.getConnection(); PreparedStatement statementInsertUser = connection.prepareStatement(queryInsertUsers, PreparedStatement.RETURN_GENERATED_KEYS);\n\t\t    PreparedStatement statementInsertBackpack = connection.prepareStatement(queryInsertBackpacks))\n\t\t{\n\t\t\tint migrated = 0;\n\t\t\tfor(File file : allFiles)\n\t\t\t{\n\t\t\t\tString name = file.getName().substring(0, file.getName().length() - Files.EXT.length());\n\t\t\t\tstatementInsertUser.setString(1, name);\n\t\t\t\tstatementInsertUser.setString(2, \"UNKNOWN\");\n\t\t\t\tstatementInsertUser.executeUpdate();\n\t\t\t\ttry(ResultSet rs = statementInsertUser.getGeneratedKeys())\n\t\t\t\t{\n\t\t\t\t\tif(rs.next())\n\t\t\t\t\t{\n\t\t\t\t\t\ttry(FileInputStream fis = new FileInputStream(file))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tint version = fis.read();\n\t\t\t\t\t\t\tbyte[] data = new byte[(int) (file.length() - 1)];\n\t\t\t\t\t\t\tint readCount = fis.read(data);\n\t\t\t\t\t\t\tif(file.length() - 1 != readCount) plugin.getLogger().warning(\"Problem reading file, read \" + readCount + \" of \" + (file.length() - 1) + \" bytes.\");\n\t\t\t\t\t\t\tstatementInsertBackpack.setInt(1, rs.getInt(1));\n\t\t\t\t\t\t\tstatementInsertBackpack.setBytes(2, data);\n\t\t\t\t\t\t\tstatementInsertBackpack.setInt(3, version);\n\t\t\t\t\t\t\tstatementInsertBackpack.executeUpdate();\n\t\t\t\t\t\t\tmigrated++;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t}\n\t\t\treturn new MigrationResult(\"Migrated \" + migrated + \" backpacks from Files to \" + newDb.getClass().getSimpleName(), MigrationResult.MigrationResultType.SUCCESS);\n\t\t}\n\t\tfinally\n\t\t{\n\t\t\tnewDb.close();\n\t\t}\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Migration/Migration.java",
    "content": "/*\n *   Copyright (C) 2018 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Database.Migration;\n\nimport at.pcgamingfreaks.Minepacks.Bukkit.Database.Database;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport org.jetbrains.annotations.NotNull;\nimport org.jetbrains.annotations.Nullable;\n\npublic abstract class Migration\n{\n\tprotected final Minepacks plugin;\n\tprotected final Database oldDb;\n\n\tprotected Migration(@NotNull Minepacks plugin, @NotNull Database oldDb)\n\t{\n\t\tthis.plugin = plugin;\n\t\tthis.oldDb = oldDb;\n\t}\n\n\tpublic abstract @Nullable MigrationResult migrate() throws Exception;\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Migration/MigrationCallback.java",
    "content": "/*\n *   Copyright (C) 2018 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Database.Migration;\n\npublic interface MigrationCallback\n{\n\tvoid onResult(MigrationResult result);\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Migration/MigrationManager.java",
    "content": "/*\n *   Copyright (C) 2019 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Database.Migration;\n\nimport at.pcgamingfreaks.ConsoleColor;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Database.*;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport at.pcgamingfreaks.Reflection;\nimport org.bukkit.event.HandlerList;\n\nimport java.util.Locale;\n\npublic class MigrationManager\n{\n\tprivate final Minepacks plugin;\n\n\tpublic MigrationManager(final Minepacks plugin)\n\t{\n\t\tthis.plugin = plugin;\n\t}\n\n\tpublic void migrateDB(final String targetDatabaseType, final MigrationCallback callback)\n\t{\n\t\tfinal Migration migration = getMigrationPerformer(targetDatabaseType);\n\t\tif(migration == null)\n\t\t{\n\t\t\tcallback.onResult(new MigrationResult(\"There is no need to migrate the database.\", MigrationResult.MigrationResultType.NOT_NEEDED));\n\t\t\treturn;\n\t\t}\n\t\tfinal Database db = plugin.getDatabase();\n\n\t\t//region Disable the plugin except for the database\n\t\ttry\n\t\t{\n\t\t\tplugin.getLogger().info(\"Unloading plugin for migration\");\n\t\t\tReflection.setValue(plugin, \"database\", null); // Hack to prevent the unload of the database\n\t\t\t//noinspection ConstantConditions\n\t\t\tReflection.getMethod(Minepacks.class, \"unload\").invoke(plugin); // Unload plugin\n\t\t\tHandlerList.unregisterAll(db); // Disable events for database\n\t\t\tReflection.setValue(plugin, \"database\", db);\n\t\t}\n\t\tcatch(Exception e)\n\t\t{\n\t\t\tplugin.getLogger().warning(ConsoleColor.RED + \"Failed to unload plugin! Please restart your server!\" + ConsoleColor.RESET);\n\t\t\te.printStackTrace();\n\t\t\tcallback.onResult(new MigrationResult(\"Failed to unload plugin! Please restart your server!\", MigrationResult.MigrationResultType.ERROR));\n\t\t\treturn;\n\t\t}\n\t\t//endregion\n\t\t//region Migrate data\n\t\tMinepacks.getScheduler().runAsync(task -> {\n\t\t\tMigrationResult migrationResult = null;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tplugin.getLogger().info(\"Start migrating data to new database\");\n\t\t\t\tmigrationResult = migration.migrate();\n\t\t\t\tplugin.getConfiguration().setDatabaseType(targetDatabaseType);\n\t\t\t}\n\t\t\tcatch(Exception e)\n\t\t\t{\n\t\t\t\te.printStackTrace();\n\t\t\t\tplugin.getLogger().warning(ConsoleColor.RED + \"There was a problem migrating from \" + db.getClass().getName() + \" to \" + targetDatabaseType + ConsoleColor.RESET);\n\t\t\t\tcallback.onResult(new MigrationResult(\"There was a problem migrating from \" + db.getClass().getName() + \" to \" + targetDatabaseType + \". Please check the console for details.\", MigrationResult.MigrationResultType.ERROR));\n\t\t\t}\n\n\t\t\t//region Start the plugin again\n\t\t\tfinal MigrationResult migrationResultFinal = migrationResult;\n\t\t\tMinepacks.getScheduler().runNextTick(task1 -> {\n\t\t\t\tdb.close();\n\t\t\t\t// No need to reload the config\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tplugin.getLogger().info(\"Migration is done, loading the plugin again.\");\n\t\t\t\t\t//noinspection ConstantConditions\n\t\t\t\t\tReflection.getMethod(Minepacks.class, \"load\").invoke(plugin); // load the plugin again\n\t\t\t\t\tplugin.getLogger().info(ConsoleColor.GREEN + \"Plugin loaded successful and is ready to use again.\" + ConsoleColor.RESET);\n\t\t\t\t\tif(migrationResultFinal != null) callback.onResult(migrationResultFinal);\n\t\t\t\t}\n\t\t\t\tcatch(Exception e)\n\t\t\t\t{\n\t\t\t\t\tplugin.getLogger().warning(ConsoleColor.RED + \"Failed to start plugin again!\" + ConsoleColor.RESET);\n\t\t\t\t\te.printStackTrace();\n\t\t\t\t}\n\t\t\t});\n\t\t\t//endregion\n\t\t});\n\t\t//endregion\n\t}\n\n\tpublic Migration getMigrationPerformer(String targetDatabaseType)\n\t{\n\t\ttry\n\t\t{\n\t\t\tboolean global = false;\n\t\t\tif(targetDatabaseType.toLowerCase(Locale.ROOT).equals(\"external\") || targetDatabaseType.toLowerCase(Locale.ROOT).equals(\"global\") || targetDatabaseType.toLowerCase(Locale.ROOT).equals(\"shared\"))\n\t\t\t{\n\t\t\t\t/*if[STANDALONE]\n\t\t\t\tplugin.getLogger().warning(ConsoleColor.RED + \"The shared database connection option is not available in standalone mode!\" + ConsoleColor.RESET);\n\t\t\t\treturn null;\n\t\t\t\telse[STANDALONE]*/\n\t\t\t\tat.pcgamingfreaks.PluginLib.Database.DatabaseConnectionPool pool = at.pcgamingfreaks.PluginLib.Bukkit.PluginLib.getInstance().getDatabaseConnectionPool();\n\t\t\t\tif(pool == null)\n\t\t\t\t{\n\t\t\t\t\tplugin.getLogger().warning(ConsoleColor.RED + \"The shared connection pool is not initialized correctly!\" + ConsoleColor.RESET);\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\ttargetDatabaseType = pool.getDatabaseType().toLowerCase(Locale.ROOT);\n\t\t\t\tglobal = true;\n\t\t\t\t/*end[STANDALONE]*/\n\t\t\t}\n\t\t\tswitch(targetDatabaseType.toLowerCase(Locale.ROOT))\n\t\t\t{\n\t\t\t\tcase \"flat\":\n\t\t\t\tcase \"file\":\n\t\t\t\tcase \"files\":\n\t\t\t\t\tif(!(plugin.getDatabase() instanceof SQL)) return null;\n\t\t\t\t\treturn new SQLtoFilesMigration(plugin, (SQL) plugin.getDatabase());\n\t\t\t\tcase \"mysql\":\n\t\t\t\t\tif(plugin.getDatabase() instanceof MySQL) return null;\n\t\t\t\t\tif(plugin.getDatabase() instanceof SQL) return new SQLtoSQLMigration(plugin, (SQL) plugin.getDatabase(), \"mysql\", global);\n\t\t\t\t\telse return new FilesToSQLMigration(plugin, (Files) plugin.getDatabase(), \"mysql\", global);\n\t\t\t\tcase \"sqlite\":\n\t\t\t\t\tif(plugin.getDatabase() instanceof SQLite) return null;\n\t\t\t\t\tif(plugin.getDatabase() instanceof SQL) return new SQLtoSQLMigration(plugin, (SQL) plugin.getDatabase(), \"sqlite\", global);\n\t\t\t\t\telse return new FilesToSQLMigration(plugin, (Files) plugin.getDatabase(), \"sqlite\", global);\n\t\t\t\tdefault: plugin.getLogger().warning(String.format(Database.MESSAGE_UNKNOWN_DB_TYPE,  plugin.getConfiguration().getDatabaseType())); return null;\n\t\t\t}\n\t\t}\n\t\tcatch(Exception e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t}\n\t\treturn null;\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Migration/MigrationResult.java",
    "content": "/*\n *   Copyright (C) 2018 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Database.Migration;\n\nimport org.jetbrains.annotations.NotNull;\n\npublic class MigrationResult\n{\n\tpublic enum MigrationResultType { SUCCESS, ERROR, NOT_NEEDED }\n\n\tprivate final String message;\n\tprivate final MigrationResultType type;\n\n\tpublic MigrationResult(@NotNull String message, @NotNull MigrationResultType type) {\n\t\tthis.message = message;\n\t\tthis.type = type;\n\t}\n\n\tpublic @NotNull MigrationResultType getType()\n\t{\n\t\treturn type;\n\t}\n\n\tpublic @NotNull String getMessage()\n\t{\n\t\treturn message;\n\t}\n\n\t@Override\n\tpublic String toString()\n\t{\n\t\treturn getType().name() + \": \" + getMessage();\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Migration/SQLtoFilesMigration.java",
    "content": "/*\n *   Copyright (C) 2018 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Database.Migration;\n\nimport at.pcgamingfreaks.Minepacks.Bukkit.Database.Files;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Database.SQL;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport at.pcgamingfreaks.Reflection;\nimport org.intellij.lang.annotations.Language;\nimport org.jetbrains.annotations.NotNull;\nimport org.jetbrains.annotations.Nullable;\n\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.lang.reflect.InvocationTargetException;\nimport java.sql.Connection;\nimport java.sql.ResultSet;\nimport java.sql.Statement;\n\npublic class SQLtoFilesMigration extends Migration\n{\n\tprivate final String sqlQuery;\n\tprivate final File saveFolder;\n\n\tprotected SQLtoFilesMigration(@NotNull Minepacks plugin, @NotNull SQL oldDb) throws InvocationTargetException, IllegalAccessException\n\t{\n\t\tsuper(plugin, oldDb);\n\t\t@Language(\"SQL\") String query = \"SELECT {FieldUUID},{FieldBPITS},{FieldBPVersion} FROM {TablePlayers} INNER JOIN {TableBackpacks} ON {FieldPlayerID}={FieldBPOwner};\";\n\t\t//noinspection ConstantConditions\n\t\tsqlQuery = (String) Reflection.getMethod(SQL.class, \"replacePlaceholders\", String.class).invoke(oldDb, query);\n\t\tsaveFolder = new File(this.plugin.getDataFolder(), Files.FOLDER_NAME);\n\t\tif(!saveFolder.exists() && !saveFolder.mkdirs()) plugin.getLogger().warning(\"Failed to create save folder (\" + saveFolder.getAbsolutePath() + \").\");\n\t}\n\n\t@Override\n\tpublic @Nullable MigrationResult migrate() throws Exception\n\t{\n\t\tint migrated = 0;\n\t\ttry(Connection connection = ((SQL) oldDb).getConnection(); Statement st = connection.createStatement(); ResultSet rs = st.executeQuery(sqlQuery))\n\t\t{\n\t\t\twhile(rs.next())\n\t\t\t{\n\t\t\t\ttry(FileOutputStream fos = new FileOutputStream(new File(saveFolder, rs.getString(1) + Files.EXT)))\n\t\t\t\t{\n\t\t\t\t\tfos.write(rs.getInt(3));\n\t\t\t\t\tfos.write(rs.getBytes(2));\n\t\t\t\t}\n\t\t\t\tmigrated++;\n\t\t\t}\n\t\t}\n\t\treturn new MigrationResult(\"Migrated \" + migrated + \" backpacks from \" + oldDb.getClass().getSimpleName() + \" to Files.\", MigrationResult.MigrationResultType.SUCCESS);\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Migration/SQLtoSQLMigration.java",
    "content": "/*\n *   Copyright (C) 2022 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Database.Migration;\n\nimport at.pcgamingfreaks.Minepacks.Bukkit.Database.SQL;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Database.SQLite;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport org.intellij.lang.annotations.Language;\nimport org.jetbrains.annotations.NotNull;\nimport org.jetbrains.annotations.Nullable;\n\nimport java.sql.*;\nimport java.text.DateFormat;\nimport java.text.SimpleDateFormat;\nimport java.util.Date;\n\n@SuppressWarnings(\"ConstantConditions\")\npublic class SQLtoSQLMigration extends ToSQLMigration\n{\n\tprivate final @Language(\"SQL\") String queryInsertUsers, queryInsertBackpacks;\n\n\tprotected SQLtoSQLMigration(@NotNull Minepacks plugin, @NotNull SQL oldDb, @NotNull String dbType, boolean global) throws Exception\n\t{\n\t\tsuper(plugin, oldDb, dbType, global);\n\n\t\tqueryInsertUsers = replacePlaceholders(newDb, \"INSERT INTO {TablePlayers} ({FieldPlayerID},{FieldName},{FieldUUID}) VALUES (?,?,?);\");\n\t\tqueryInsertBackpacks = replacePlaceholders(newDb, \"INSERT INTO {TableBackpacks} ({FieldBPOwner},{FieldBPITS},{FieldBPVersion},{FieldBPLastUpdate}) VALUES (?,?,?,?);\");\n\t}\n\n\t@Override\n\tpublic @Nullable MigrationResult migrate() throws Exception\n\t{\n\t\ttry(Connection readConnection = ((SQL) oldDb).getConnection(); Connection writeConnection = newDb.getConnection(); Statement readStatement = readConnection.createStatement())\n\t\t{\n\t\t\tint users = migrate(\"users\", writeConnection, readStatement, \"SELECT * FROM {TablePlayers};\", queryInsertUsers);\n\t\t\tint backpacks = migrate(\"backpacks\", writeConnection, readStatement, \"SELECT * FROM {TableBackpacks};\", queryInsertBackpacks);\n\t\t\treturn new MigrationResult(\"Migrated \" + users + \" users and \" + backpacks + \" backpacks from \" + oldDb.getClass().getSimpleName() + \" to \" + newDb.getClass().getSimpleName() + \".\", MigrationResult.MigrationResultType.SUCCESS);\n\t\t}\n\t\tfinally\n\t\t{\n\t\t\tnewDb.close();\n\t\t}\n\t}\n\n\tprivate int migrate(@NotNull String type, @NotNull Connection writeConnection, @NotNull Statement readStatement, @Language(\"SQL\") String readQuery, @Language(\"SQL\") String insertQuery) throws Exception\n\t{\n\t\tint count = 0;\n\t\tbyte mode = (byte) ((type.equals(\"users\")) ? 0 : 1);\n\t\tplugin.getLogger().info(\"Migrate \" + type + \" ...\");\n\t\ttry(ResultSet resultSet = readStatement.executeQuery(replacePlaceholders((SQL) oldDb, readQuery));\n\t\t    PreparedStatement preparedStatement = writeConnection.prepareStatement(replacePlaceholders(newDb, insertQuery)))\n\t\t{\n\t\t\twhile(resultSet.next())\n\t\t\t{\n\t\t\t\tswitch(mode)\n\t\t\t\t{\n\t\t\t\t\tcase 0: migrateUser(resultSet, preparedStatement); break;\n\t\t\t\t\tcase 1: migrateBackpack(resultSet, preparedStatement); break;\n\t\t\t\t}\n\t\t\t\tpreparedStatement.addBatch();\n\t\t\t\tcount++;\n\t\t\t}\n\t\t\tpreparedStatement.executeBatch();\n\t\t}\n\t\tplugin.getLogger().info(\"Migrated \" + count + \" \" + type + \".\");\n\t\treturn count;\n\t}\n\n\tprivate void migrateUser(@NotNull ResultSet usersResultSet, @NotNull PreparedStatement preparedStatement) throws Exception\n\t{\n\t\tint userId = usersResultSet.getInt((String) FIELD_PLAYER_ID.get(oldDb));\n\t\tpreparedStatement.setInt(1, userId);\n\t\tpreparedStatement.setString(2, usersResultSet.getString((String) FIELD_PLAYER_NAME.get(oldDb)));\n\t\tpreparedStatement.setString(3, usersResultSet.getString((String) FIELD_PLAYER_UUID.get(oldDb)));\n\t}\n\n\tprivate void migrateBackpack(@NotNull ResultSet backpacksResultSet, @NotNull PreparedStatement preparedStatement) throws Exception\n\t{\n\t\tpreparedStatement.setInt(1, backpacksResultSet.getInt((String) FIELD_BP_OWNER.get(oldDb)));\n\t\tpreparedStatement.setBytes(2, backpacksResultSet.getBytes((String) FIELD_BP_ITS.get(oldDb)));\n\t\tpreparedStatement.setInt(3, backpacksResultSet.getInt((String) FIELD_BP_VERSION.get(oldDb)));\n\t\tfinal DateFormat sqliteDateFormat = new SimpleDateFormat(\"yyyy-MM-dd\");\n\t\tif(oldDb instanceof SQLite)\n\t\t{\n\t\t\tpreparedStatement.setTimestamp(4, new Timestamp(sqliteDateFormat.parse(backpacksResultSet.getString((String) FIELD_BP_LAST_UPDATE.get(oldDb))).getTime()));\n\t\t}\n\t\telse\n\t\t{\n\t\t\tpreparedStatement.setString(4, sqliteDateFormat.format(new Date(backpacksResultSet.getTimestamp((String) FIELD_BP_LAST_UPDATE.get(oldDb)).getTime())));\n\t\t}\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Migration/ToSQLMigration.java",
    "content": "/*\n *   Copyright (C) 2022 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Database.Migration;\n\nimport at.pcgamingfreaks.Database.ConnectionProvider.ConnectionProvider;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Database.Database;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Database.MySQL;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Database.SQL;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Database.SQLite;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport at.pcgamingfreaks.Reflection;\nimport org.intellij.lang.annotations.Language;\nimport org.jetbrains.annotations.NotNull;\n\nimport java.io.File;\nimport java.lang.reflect.Field;\nimport java.lang.reflect.Method;\n\n@SuppressWarnings(\"ConstantConditions\")\npublic abstract class ToSQLMigration extends Migration\n{\n\tprotected static final Method METHOD_REPLACE_PLACEHOLDERS = Reflection.getMethod(SQL.class, \"replacePlaceholders\", String.class);\n\tprotected static final Field FIELD_PLAYER_ID   = Reflection.getField(SQL.class, \"fieldPlayerID\");\n\tprotected static final Field FIELD_PLAYER_UUID = Reflection.getField(SQL.class, \"fieldPlayerUUID\");\n\tprotected static final Field FIELD_PLAYER_NAME = Reflection.getField(SQL.class, \"fieldPlayerName\");\n\tprotected static final Field FIELD_BP_OWNER       = Reflection.getField(SQL.class, \"fieldBpOwner\");\n\tprotected static final Field FIELD_BP_ITS         = Reflection.getField(SQL.class, \"fieldBpIts\");\n\tprotected static final Field FIELD_BP_VERSION     = Reflection.getField(SQL.class, \"fieldBpVersion\");\n\tprotected static final Field FIELD_BP_LAST_UPDATE = Reflection.getField(SQL.class, \"fieldBpLastUpdate\");\n\n\tprotected final SQL newDb;\n\n\tprotected ToSQLMigration(@NotNull Minepacks plugin, @NotNull Database oldDb, @NotNull String dbType, boolean global)\n\t{\n\t\tsuper(plugin, oldDb);\n\t\t/*if[STANDALONE]\n\t\tConnectionProvider connectionProvider = null;\n\t\telse[STANDALONE]*/\n\t\tConnectionProvider connectionProvider = (global) ? at.pcgamingfreaks.PluginLib.Bukkit.PluginLib.getInstance().getDatabaseConnectionPool().getConnectionProvider() : null;\n\t\t/*end[STANDALONE]*/\n\t\tswitch(dbType)\n\t\t{\n\t\t\tcase \"mysql\": newDb = new MySQL(plugin, connectionProvider); break;\n\t\t\tcase \"sqlite\":\n\t\t\t\tfinal File dbFile = new File(SQLite.getDbFile(plugin));\n\t\t\t\tif(dbFile.exists() && !dbFile.renameTo(new File(SQLite.getDbFile(plugin) + \".old_\" + System.currentTimeMillis())))\n\t\t\t\t{\n\t\t\t\t\tplugin.getLogger().warning(\"Failed to rename old database file.\");\n\t\t\t\t}\n\t\t\t\tnewDb = new SQLite(plugin, connectionProvider);\n\t\t\t\tbreak;\n\t\t\tdefault: newDb = null;\n\t\t}\n\t}\n\n\tprotected  @Language(\"SQL\") String replacePlaceholders(SQL database, @Language(\"SQL\") String query) throws Exception\n\t{\n\t\treturn (String) METHOD_REPLACE_PLACEHOLDERS.invoke(database, query);\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/MySQL.java",
    "content": "/*\n *   Copyright (C) 2023 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Database;\n\nimport at.pcgamingfreaks.Database.ConnectionProvider.ConnectionProvider;\nimport at.pcgamingfreaks.Database.ConnectionProvider.MySQLConnectionProvider;\nimport at.pcgamingfreaks.Database.DBTools;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport org.jetbrains.annotations.NotNull;\nimport org.jetbrains.annotations.Nullable;\n\nimport java.sql.Connection;\nimport java.sql.SQLException;\n\npublic class MySQL extends SQL\n{\n\tpublic MySQL(@NotNull Minepacks plugin, @Nullable ConnectionProvider connectionProvider)\n\t{\n\t\tsuper(plugin, (connectionProvider == null) ? new MySQLConnectionProvider(plugin.getLogger(), plugin.getDescription().getName(), plugin.getConfiguration()) : connectionProvider);\n\t}\n\n\t@Override\n\tprotected void updateQueriesForDialect()\n\t{\n\t\tqueryDeleteOldBackpacks = \"DELETE FROM {TableBackpacks} WHERE {FieldBPLastUpdate} + INTERVAL {VarMaxAge} day < NOW()\";\n\t\tqueryUpdateBp = queryUpdateBp.replace(\"{NOW}\", \"NOW()\");\n\t}\n\n\t@Override\n\tprotected void checkDB()\n\t{\n\t\ttry(Connection connection = getConnection())\n\t\t{\n\t\t\tDBTools.updateDB(connection, replacePlaceholders(\"CREATE TABLE IF NOT EXISTS {TablePlayers} (\\n{FieldPlayerID} INT UNSIGNED NOT NULL AUTO_INCREMENT,\\n{FieldName} VARCHAR(16) NOT NULL,\\n\" +\n\t\t\t\t\t                                                 \"{FieldUUID} CHAR(\" +  ((useUUIDSeparators) ? \"36\" : \"32\") + \") DEFAULT NULL,\" + \"\\nPRIMARY KEY ({FieldPlayerID}),\\n\" +\n\t\t\t\t\t                                                 \"UNIQUE INDEX {FieldUUID}_UNIQUE ({FieldUUID})\\n);\"));\n\t\t\tDBTools.updateDB(connection, replacePlaceholders(\"CREATE TABLE IF NOT EXISTS {TableBackpacks} (\\n{FieldBPOwner} INT UNSIGNED NOT NULL,\\n{FieldBPITS} MEDIUMBLOB,\\n{FieldBPVersion} INT DEFAULT 0,\\n\" +\n\t\t\t\t\t                                                 \"{FieldBPLastUpdate} TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\\n\" +\n\t\t\t\t\t                                                 \"PRIMARY KEY ({FieldBPOwner}),\\nCONSTRAINT fk_{TableBackpacks}_{TablePlayers}_{FieldBPOwner} FOREIGN KEY ({FieldBPOwner}) \" +\n\t\t\t\t\t                                                 \"REFERENCES {TablePlayers} ({FieldPlayerID}) ON DELETE CASCADE ON UPDATE CASCADE\\n);\"));\n\t\t\tif(syncCooldown)\n\t\t\t{\n\t\t\t\tDBTools.updateDB(connection, replacePlaceholders(\"CREATE TABLE IF NOT EXISTS {TableCooldowns} (\\n{FieldCDPlayer} INT UNSIGNED NOT NULL,\\n{FieldCDTime} DATETIME NOT NULL,\\nPRIMARY KEY ({FieldCDPlayer}),\\n\" +\n\t\t\t\t\t\t                                                 \"CONSTRAINT fk_{TableCooldowns}_{TablePlayers}_{FieldCDPlayer} FOREIGN KEY ({FieldCDPlayer}) \" +\n\t\t\t\t\t\t                                                 \"REFERENCES {TablePlayers} ({FieldPlayerID}) ON DELETE CASCADE ON UPDATE CASCADE\\n);\"));\n\t\t\t}\n\t\t}\n\t\tcatch (SQLException e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/SQL.java",
    "content": "/*\n *   Copyright (C) 2024 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Database;\n\nimport at.pcgamingfreaks.Database.ConnectionProvider.ConnectionProvider;\nimport at.pcgamingfreaks.Database.DBTools;\nimport at.pcgamingfreaks.Minepacks.Bukkit.API.Callback;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Backpack;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport at.pcgamingfreaks.Utils;\n\nimport org.bukkit.OfflinePlayer;\nimport org.bukkit.entity.Player;\nimport org.bukkit.inventory.ItemStack;\nimport org.intellij.lang.annotations.Language;\nimport org.jetbrains.annotations.NotNull;\n\nimport java.sql.*;\nimport java.util.logging.Level;\n\npublic abstract class SQL extends Database\n{\n\tprivate final ConnectionProvider dataSource;\n\n\tprotected String tablePlayers, tableBackpacks, tableCooldowns; // Table Names\n\tprotected String fieldPlayerName, fieldPlayerID, fieldPlayerUUID, fieldBpOwner, fieldBpIts, fieldBpVersion, fieldBpLastUpdate, fieldCdPlayer, fieldCdTime; // Table Fields\n\t@Language(\"SQL\") protected String queryUpdatePlayerAdd, queryGetPlayerID, queryInsertBp, queryUpdateBp, queryGetBP, queryDeleteOldBackpacks; // DB Queries\n\t@Language(\"SQL\") protected String queryDeleteOldCooldowns, querySyncCooldown, queryGetCooldown; // DB Queries\n\tprotected boolean syncCooldown;\n\n\tpublic SQL(@NotNull Minepacks plugin, @NotNull ConnectionProvider connectionProvider)\n\t{\n\t\tsuper(plugin);\n\n\t\tdataSource = connectionProvider;\n\t\tif(!dataSource.isAvailable()) throw new IllegalStateException(\"Failed to initialize database connection!\");\n\n\t\tloadSettings();\n\t\tbuildQueries();\n\t\tcheckDB();\n\t\tcheckUUIDs(); // Check if there are user accounts without UUID\n\n\t\t// Delete old backpacks\n\t\tif(maxAge > 0)\n\t\t{\n\t\t\ttry(Connection connection = getConnection(); Statement statement = connection.createStatement())\n\t\t\t{\n\t\t\t\tstatement.execute(queryDeleteOldBackpacks);\n\t\t\t}\n\t\t\tcatch(SQLException e)\n\t\t\t{\n\t\t\t\tplugin.getLogger().log(Level.SEVERE, \"Failed to delete old backpacks! Error: {0}\", e.getMessage());\n\t\t\t}\n\t\t}\n\t\t// Delete old cooldowns\n\t\tif(syncCooldown)\n\t\t{\n\t\t\ttry(Connection connection = getConnection())\n\t\t\t{\n\t\t\t\tDBTools.runStatement(connection, queryDeleteOldCooldowns, new Timestamp(System.currentTimeMillis()));\n\t\t\t}\n\t\t\tcatch(SQLException e)\n\t\t\t{\n\t\t\t\tplugin.getLogger().log(Level.SEVERE, \"Failed to delete cooldowns! Error: {0}\", e.getMessage());\n\t\t\t}\n\t\t}\n\t}\n\n\tprotected void loadSettings()\n\t{\n\t\t// Load table and field names\n\t\ttablePlayers      = plugin.getConfiguration().getUserTable();\n\t\ttableBackpacks    = plugin.getConfiguration().getBackpackTable();\n\t\ttableCooldowns    = plugin.getConfiguration().getCooldownTable();\n\t\tfieldPlayerID     = plugin.getConfiguration().getDBFields(\"User.Player_ID\", \"id\");\n\t\tfieldPlayerName   = plugin.getConfiguration().getDBFields(\"User.Name\", \"name\");\n\t\tfieldPlayerUUID   = plugin.getConfiguration().getDBFields(\"User.UUID\", \"uuid\");\n\t\tfieldBpOwner      = plugin.getConfiguration().getDBFields(\"Backpack.Owner_ID\", \"owner\");\n\t\tfieldBpIts        = plugin.getConfiguration().getDBFields(\"Backpack.ItemStacks\", \"its\");\n\t\tfieldBpVersion    = plugin.getConfiguration().getDBFields(\"Backpack.Version\", \"version\");\n\t\tfieldBpLastUpdate = plugin.getConfiguration().getDBFields(\"Backpack.LastUpdate\", \"lastUpdate\");\n\t\tfieldCdPlayer     = plugin.getConfiguration().getDBFields(\"Cooldown.Player_ID\", \"id\");\n\t\tfieldCdTime       = plugin.getConfiguration().getDBFields(\"Cooldown.Time\", \"time\");\n\t\tsyncCooldown      = plugin.getConfiguration().isCommandCooldownSyncEnabled();\n\t}\n\n\t@Override\n\tpublic void close()\n\t{\n\t\tsuper.close();\n\t\tUtils.blockThread(1); // Give the database some time to perform async operations\n\t\tdataSource.close();\n\t}\n\n\tprotected void checkUUIDs()\n\t{\n\t\ttry(Connection connection = getConnection())\n\t\t{\n\t\t\tDBTools.validateUUIDs(plugin.getLogger(), connection, tablePlayers, fieldPlayerName, fieldPlayerUUID, fieldPlayerID, useUUIDSeparators, onlineUUIDs);\n\t\t}\n\t\tcatch(SQLException e)\n\t\t{\n\t\t\tplugin.getLogger().log(Level.SEVERE, \"Failed to check UUIDs! Error: {0}\", e.getMessage());\n\t\t}\n\t}\n\n\tpublic Connection getConnection() throws SQLException\n\t{\n\t\treturn dataSource.getConnection();\n\t}\n\n\tprotected abstract void checkDB();\n\n\tprotected final void buildQueries()\n\t{\n\t\t// Build the SQL queries with placeholders for the table and field names\n\t\tqueryGetBP = \"SELECT {FieldBPOwner},{FieldBPITS},{FieldBPVersion} FROM {TableBackpacks} INNER JOIN {TablePlayers} ON {TableBackpacks}.{FieldBPOwner}={TablePlayers}.{FieldPlayerID} WHERE {FieldUUID}=?;\";\n\t\tquerySyncCooldown = \"INSERT INTO {TableCooldowns} ({FieldCDPlayer},{FieldCDTime}) SELECT {FieldPlayerID},? FROM {TablePlayers} WHERE {FieldUUID}=? ON DUPLICATE KEY UPDATE {FieldCDTime}=?;\";\n\t\tqueryUpdatePlayerAdd = \"INSERT INTO {TablePlayers} ({FieldName},{FieldUUID}) VALUES (?,?) ON DUPLICATE KEY UPDATE {FieldName}=?;\";\n\t\tqueryGetPlayerID = \"SELECT {FieldPlayerID} FROM {TablePlayers} WHERE {FieldUUID}=?;\";\n\t\tqueryGetCooldown = \"SELECT * FROM {TableCooldowns} WHERE {FieldCDPlayer} IN (SELECT {FieldPlayerID} FROM {TablePlayers} WHERE {FieldUUID}=?);\";\n\t\tqueryInsertBp = \"REPLACE INTO {TableBackpacks} ({FieldBPOwner},{FieldBPITS},{FieldBPVersion}) VALUES (?,?,?);\";\n\t\tqueryUpdateBp = \"UPDATE {TableBackpacks} SET {FieldBPITS}=?,{FieldBPVersion}=?,{FieldBPLastUpdate}={NOW} WHERE {FieldBPOwner}=?;\";\n\t\tqueryDeleteOldBackpacks = \"DELETE FROM {TableBackpacks} WHERE {FieldBPLastUpdate} < DATE('now', '-{VarMaxAge} days')\";\n\t\tqueryDeleteOldCooldowns = \"DELETE FROM {TableCooldowns} WHERE {FieldCDTime}<?;\";\n\n\t\tupdateQueriesForDialect();\n\n\t\tsetTableAndFieldNames();\n\t}\n\n\tprotected void setTableAndFieldNames()\n\t{\n\t\t// Replace the table and filed names with the names from the config\n\t\tqueryUpdatePlayerAdd        = replacePlaceholders(queryUpdatePlayerAdd);\n\t\tqueryGetPlayerID            = replacePlaceholders(queryGetPlayerID);\n\t\tqueryGetBP                  = replacePlaceholders(queryGetBP);\n\t\tqueryInsertBp               = replacePlaceholders(queryInsertBp);\n\t\tqueryUpdateBp               = replacePlaceholders(queryUpdateBp);\n\t\tqueryDeleteOldBackpacks     = replacePlaceholders(queryDeleteOldBackpacks.replace(\"{VarMaxAge}\", String.valueOf(maxAge)));\n\t\tquerySyncCooldown           = replacePlaceholders(querySyncCooldown);\n\t\tqueryGetCooldown            = replacePlaceholders(queryGetCooldown);\n\t\tqueryDeleteOldCooldowns     = replacePlaceholders(queryDeleteOldCooldowns);\n\t}\n\n\tprotected abstract void updateQueriesForDialect();\n\n\tprotected String replacePlaceholders(@Language(\"SQL\") String query)\n\t{\n\t\treturn query.replaceAll(\"(\\\\{\\\\w+})\", \"`$1`\").replaceAll(\"`(\\\\{\\\\w+})`_(\\\\w+)\", \"`$1_$2`\").replaceAll(\"fk_`(\\\\{\\\\w+})`_`(\\\\{\\\\w+})`_`(\\\\{\\\\w+})`\", \"`fk_$1_$2_$3`\") // Fix name formatting\n\t\t\t\t.replace(\"{TablePlayers}\", tablePlayers).replace(\"{FieldName}\", fieldPlayerName).replace(\"{FieldUUID}\", fieldPlayerUUID).replace(\"{FieldPlayerID}\", fieldPlayerID) // Players\n\t\t\t\t.replace(\"{TableBackpacks}\", tableBackpacks).replace(\"{FieldBPOwner}\", fieldBpOwner).replace(\"{FieldBPITS}\", fieldBpIts) // Backpacks\n\t\t\t\t.replace(\"{FieldBPVersion}\", fieldBpVersion).replace(\"{FieldBPLastUpdate}\", fieldBpLastUpdate) // Backpacks\n\t\t\t\t.replace(\"{TableCooldowns}\", tableCooldowns).replace(\"{FieldCDPlayer}\", fieldCdPlayer).replace(\"{FieldCDTime}\", fieldCdTime); // Cooldowns\n\t}\n\n\tprotected void runStatementAsync(final String query, final Object... args)\n\t{\n\t\tMinepacks.getScheduler().runAsync(task -> runStatement(query, args));\n\t}\n\n\tprotected void runStatement(final String query, final Object... args)\n\t{\n\t\ttry(Connection connection = getConnection(); PreparedStatement preparedStatement = connection.prepareStatement(query))\n\t\t{\n\t\t\tfor(int i = 0; args != null && i < args.length; i++)\n\t\t\t{\n\t\t\t\tpreparedStatement.setObject(i + 1, args[i]);\n\t\t\t}\n\t\t\tpreparedStatement.execute();\n\t\t}\n\t\tcatch(SQLException e)\n\t\t{\n\t\t\tplugin.getLogger().log(Level.SEVERE, e, () -> \"Query: \" + query);\n\t\t}\n\t}\n\n\t// Plugin Functions\n\t@Override\n\tpublic void updatePlayer(final Player player)\n\t{\n\t\trunStatementAsync(queryUpdatePlayerAdd, player.getName(), getPlayerFormattedUUID(player), player.getName());\n\t}\n\n\t@Override\n\tpublic void saveBackpack(final Backpack backpack)\n\t{\n\t\tfinal byte[] data = itsSerializer.serialize(backpack.getInventory());\n\t\tfinal int id = backpack.getOwnerDatabaseId(), usedSerializer = itsSerializer.getUsedSerializer();\n\t\tfinal String nameOrUUID = getPlayerFormattedUUID(backpack.getOwnerId()), name = backpack.getOwner().getName();\n\n\t\tRunnable runnable = () -> {\n\t\t\ttry(Connection connection = getConnection())\n\t\t\t{\n\t\t\t\tif(id <= 0)\n\t\t\t\t{\n\t\t\t\t\ttry(PreparedStatement ps = connection.prepareStatement(queryGetPlayerID))\n\t\t\t\t\t{\n\t\t\t\t\t\tps.setString(1, nameOrUUID);\n\t\t\t\t\t\ttry(ResultSet rs = ps.executeQuery())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(rs.next())\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfinal int newID = rs.getInt(fieldPlayerID);\n\t\t\t\t\t\t\t\tDBTools.runStatement(connection, queryInsertBp, newID, data, usedSerializer);\n\t\t\t\t\t\t\t\tMinepacks.getScheduler().runNextTick(task -> backpack.setOwnerDatabaseId(newID));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tplugin.getLogger().warning(\"Failed saving backpack for: \" + name + \" (Unable to get players ID from database)\");\n\t\t\t\t\t\t\t\twriteBackup(name, nameOrUUID, usedSerializer, data);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tDBTools.runStatement(connection, queryUpdateBp, data, usedSerializer, id);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch(SQLException e)\n\t\t\t{\n\t\t\t\tplugin.getLogger().log(Level.SEVERE, \"Failed to save backpack in database! Error: {0}\", e.getMessage());\n\t\t\t\twriteBackup(name, nameOrUUID, usedSerializer, data);\n\t\t\t}\n\t\t};\n\t\tif(asyncSave) Minepacks.getScheduler().runAsync(task -> runnable.run()); else runnable.run();\n\t}\n\n\t@Override\n\tprotected void loadBackpack(final OfflinePlayer player, final Callback<Backpack> callback)\n\t{\n\t\tMinepacks.getScheduler().runAsync(task -> {\n\t\t\ttry(Connection conn = getConnection(); PreparedStatement ps = conn.prepareStatement(queryGetBP))\n\t\t\t{\n\t\t\t\tfinal String playerUUID = getPlayerFormattedUUID(player);\n\t\t\t\tps.setString(1, playerUUID);\n\t\t\t\tfinal int bpID, version;\n\t\t\t\tfinal byte[] data;\n\t\t\t\ttry(ResultSet rs = ps.executeQuery())\n\t\t\t\t{\n\t\t\t\t\tif(rs.next())\n\t\t\t\t\t{\n\t\t\t\t\t\tbpID = rs.getInt(fieldBpOwner);\n\t\t\t\t\t\tversion = rs.getInt(fieldBpVersion);\n\t\t\t\t\t\tdata = rs.getBytes(fieldBpIts);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tbpID = -1;\n\t\t\t\t\t\tversion = 0;\n\t\t\t\t\t\tdata = null;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tItemStack[] its = itsSerializer.deserialize(data, version);\n\t\t\t\tif (data != null && data.length != 0 && its == null)\n\t\t\t\t{\n\t\t\t\t\twriteBackup(player.getName(), playerUUID, version, data);\n\t\t\t\t}\n\t\t\t\tfinal Backpack backpack = (its != null) ? new Backpack(player, its, bpID) : null;\n\t\t\t\tMinepacks.getScheduler().runNextTick(task1 -> {\n\t\t\t\t\tif(backpack != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tcallback.onResult(backpack);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tcallback.onFail();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\tcatch(SQLException e)\n\t\t\t{\n\t\t\t\tplugin.getLogger().log(Level.SEVERE, \"Failed to load backpack! Error: {0}\", e.getMessage());\n\t\t\t\tMinepacks.getScheduler().runNextTick(task1 -> callback.onFail());\n\t\t\t}\n\t\t});\n\t}\n\t\n\t@Override\n\tpublic void syncCooldown(Player player, long cooldownTime)\n\t{\n\t\tTimestamp ts = new Timestamp(cooldownTime);\n\t\trunStatementAsync(querySyncCooldown, ts, getPlayerFormattedUUID(player), ts);\n\t}\n\n\t@Override\n\tpublic void getCooldown(final Player player, final Callback<Long> callback)\n\t{\n\t\tMinepacks.getScheduler().runAsync(asyncTask -> {\n\t\t\ttry(Connection conn = getConnection(); PreparedStatement ps = conn.prepareStatement(queryGetCooldown))\n\t\t\t{\n\t\t\t\tps.setString(1, getPlayerFormattedUUID(player));\n\t\t\t\ttry(ResultSet rs = ps.executeQuery())\n\t\t\t\t{\n\t\t\t\t\tfinal long time = (rs.next()) ? rs.getTimestamp(fieldCdTime).getTime() : 0;\n\t\t\t\t\tMinepacks.getScheduler().runNextTick(task -> callback.onResult(time));\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch(SQLException e)\n\t\t\t{\n\t\t\t\tplugin.getLogger().log(Level.SEVERE, \"Failed to load cooldown! Error: {0}\", e.getMessage());\n\t\t\t\tMinepacks.getScheduler().runNextTick(task -> callback.onResult(0L));\n\t\t\t}\n\t\t});\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/SQLite.java",
    "content": "/*\n *   Copyright (C) 2023 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Database;\n\nimport at.pcgamingfreaks.Database.ConnectionProvider.ConnectionProvider;\nimport at.pcgamingfreaks.Database.ConnectionProvider.SQLiteConnectionProvider;\nimport at.pcgamingfreaks.Database.DBTools;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport at.pcgamingfreaks.Version;\nimport org.bukkit.entity.Player;\nimport org.jetbrains.annotations.NotNull;\nimport org.jetbrains.annotations.Nullable;\n\nimport java.io.File;\nimport java.sql.Connection;\nimport java.sql.ResultSet;\nimport java.sql.SQLException;\nimport java.sql.Statement;\n\npublic class SQLite extends SQL\n{\n\tpublic static String getDbFile(final @NotNull Minepacks plugin)\n\t{\n\t\treturn plugin.getDataFolder().getAbsolutePath() + File.separator + \"backpack.db\";\n\t}\n\n\t//TODO add cooldown sync table\n\tpublic SQLite(final @NotNull Minepacks plugin, final @Nullable ConnectionProvider connectionProvider)\n\t{\n\t\tsuper(plugin, (connectionProvider == null) ? new SQLiteConnectionProvider(plugin.getLogger(), plugin.getDescription().getName(), getDbFile(plugin)) : connectionProvider);\n\t}\n\n\t@Override\n\tprotected void loadSettings()\n\t{\n\t\t// Set table and field names to fixed values to prevent users from destroying old databases.\n\t\tfieldPlayerID     = \"player_id\";\n\t\tfieldPlayerName   = \"name\";\n\t\tfieldPlayerUUID   = \"uuid\";\n\t\tfieldBpOwner      = \"owner\";\n\t\t//noinspection SpellCheckingInspection\n\t\tfieldBpIts        = \"itemstacks\";\n\t\tfieldBpVersion    = \"version\";\n\t\tfieldBpLastUpdate = \"lastupdate\";\n\t\ttablePlayers      = \"backpack_players\";\n\t\ttableBackpacks    = \"backpacks\";\n\t\ttableCooldowns    = \"backpack_cooldowns\";\n\t\tfieldCdPlayer     = \"player_id\";\n\t\tfieldCdTime       = \"time\";\n\t\t// Set fixed settings\n\t\tuseUUIDSeparators = false;\n\t\tsyncCooldown = false;\n\t}\n\n\t@Override\n\tprotected void updateQueriesForDialect()\n\t{\n\t\tqueryInsertBp = queryInsertBp.replaceAll(\"\\\\) VALUES \\\\(\\\\?,\\\\?,\\\\?\", \",{FieldBPLastUpdate}) VALUES (?,?,?,DATE('now')\");\n\t\tqueryDeleteOldBackpacks = \"DELETE FROM {TableBackpacks} WHERE {FieldBPLastUpdate} < DATE('now', '-{VarMaxAge} days')\";\n\t\tqueryUpdateBp = queryUpdateBp.replaceAll(\"\\\\{NOW}\", \"DATE('now')\");\n\t\tqueryUpdatePlayerAdd = \"INSERT OR IGNORE INTO {TablePlayers} ({FieldName},{FieldUUID}) VALUES (?,?);\";\n\t}\n\n\t@SuppressWarnings(\"SqlResolve\")\n\t@Override\n\tprotected void checkDB()\n\t{\n\t\ttry(Connection connection = getConnection(); Statement stmt = connection.createStatement())\n\t\t{\n\t\t\tVersion dbVersion = getDatabaseVersion(stmt);\n\n\t\t\tstmt.execute(\"CREATE TABLE IF NOT EXISTS `backpack_players` (`player_id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` CHAR(16) NOT NULL , `uuid` CHAR(32) UNIQUE);\");\n\t\t\ttry\n\t\t\t{\n\t\t\t\tstmt.execute(\"ALTER TABLE `backpack_players` ADD COLUMN `uuid` CHAR(32);\");\n\t\t\t}\n\t\t\tcatch(SQLException ignored) {}\n\t\t\tstmt.execute(\"CREATE TABLE IF NOT EXISTS `backpacks` (`owner` INT UNSIGNED PRIMARY KEY, `itemstacks` BLOB, `version` INT DEFAULT 0, `lastupdate` DATE);\");\n\t\t\ttry\n\t\t\t{\n\t\t\t\tstmt.execute(\"ALTER TABLE `backpacks` ADD COLUMN `version` INT DEFAULT 0;\");\n\t\t\t}\n\t\t\tcatch(SQLException ignored) {}\n\t\t\ttry\n\t\t\t{\n\t\t\t\tstmt.execute(\"ALTER TABLE `backpacks` ADD COLUMN `lastupdate` DATE DEFAULT '2020-09-24';\");\n\t\t\t}\n\t\t\tcatch(SQLException ignored) {}\n\n\t\t\tDBTools.runStatement(connection, \"INSERT OR REPLACE INTO `minepacks_metadata` (`key`, `value`) VALUES ('db_version',?);\", plugin.getDescription().getVersion());\n\t\t}\n\t\tcatch(SQLException e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n\n\tprivate @NotNull Version getDatabaseVersion(final @NotNull Statement stmt) throws SQLException\n\t{\n\t\tstmt.execute(\"CREATE TABLE IF NOT EXISTS `minepacks_metadata` (`key` CHAR(32) PRIMARY KEY NOT NULL, `value` TEXT);\");\n\t\ttry(ResultSet rs = stmt.executeQuery(\"SELECT `value` FROM `minepacks_metadata` WHERE `key`='db_version';\"))\n\t\t{\n\t\t\tif(rs.next()) return new Version(rs.getString(\"value\"));\n\t\t}\n\t\treturn new Version(\"0\");\n\t}\n\n\t@Override\n\tpublic void updatePlayer(final Player player)\n\t{\n\t\tMinepacks.getScheduler().runAsync(task -> {\n\t\t\trunStatement(queryUpdatePlayerAdd, player.getName(), getPlayerFormattedUUID(player));\n\t\t\trunStatement(\"UPDATE `\" + tablePlayers + \"` SET `\" + fieldPlayerName + \"`=? WHERE `\" + fieldPlayerUUID + \"`=?;\", player.getName(), getPlayerFormattedUUID(player));\n\t\t});\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/UnCacheStrategies/Interval.java",
    "content": "/*\n *   Copyright (C) 2023 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Database.UnCacheStrategies;\n\nimport at.pcgamingfreaks.Minepacks.Bukkit.Backpack;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Database.Database;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport at.pcgf.libs.com.tcoded.folialib.wrapper.task.WrappedTask;\n\npublic class Interval extends UnCacheStrategy implements Runnable\n{\n\tprivate final WrappedTask task;\n\n\tpublic Interval(Database cache)\n\t{\n\t\tsuper(cache);\n\t\ttask = Minepacks.getScheduler().runTimer(this, Minepacks.getInstance().getConfiguration().getUnCacheDelay(), Minepacks.getInstance().getConfiguration().getUnCacheInterval());\n\t}\n\n\t@Override\n\tpublic void run()\n\t{\n\t\tfor(Backpack backpack : cache.getLoadedBackpacks())\n\t\t{\n\t\t\tif(backpack.getOwnerPlayer() == null && !backpack.isOpen())\n\t\t\t{\n\t\t\t\tthis.cache.unloadBackpack(backpack);\n\t\t\t}\n\t\t}\n\t}\n\n\t@Override\n\tpublic void close()\n\t{\n\t\tMinepacks.getScheduler().cancelTask(task);\n\t\tsuper.close();\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/UnCacheStrategies/IntervalChecked.java",
    "content": "/*\n *   Copyright (C) 2023 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Database.UnCacheStrategies;\n\nimport at.pcgamingfreaks.Minepacks.Bukkit.Backpack;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Database.Database;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport at.pcgf.libs.com.tcoded.folialib.wrapper.task.WrappedTask;\nimport org.bukkit.OfflinePlayer;\n\npublic class IntervalChecked extends UnCacheStrategy implements Runnable\n{\n\tprivate final long delay;\n\tprivate final WrappedTask task;\n\n\tpublic IntervalChecked(Database cache)\n\t{\n\t\tsuper(cache);\n\t\tlong delayTicks = Minepacks.getInstance().getConfiguration().getUnCacheDelay();\n\t\ttask = Minepacks.getScheduler().runTimer(this, delayTicks, Minepacks.getInstance().getConfiguration().getUnCacheInterval());\n\t\tthis.delay = delayTicks * 50L;\n\t}\n\n\t@Override\n\tpublic void run()\n\t{\n\t\tlong currentTime = System.currentTimeMillis() - delay;\n\t\tfor(Backpack backpack : cache.getLoadedBackpacks())\n\t\t{\n\t\t\tOfflinePlayer owner = backpack.getOwner();\n\t\t\tif(!owner.isOnline() && owner.getLastPlayed() < currentTime && !backpack.isOpen())\n\t\t\t{\n\t\t\t\tthis.cache.unloadBackpack(backpack);\n\t\t\t}\n\t\t}\n\t}\n\n\t@Override\n\tpublic void close()\n\t{\n\t\tMinepacks.getScheduler().cancelTask(task);\n\t\tsuper.close();\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/UnCacheStrategies/OnDisconnect.java",
    "content": "/*\n *   Copyright (C) 2023 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Database.UnCacheStrategies;\n\nimport at.pcgamingfreaks.Minepacks.Bukkit.Backpack;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Database.Database;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport org.bukkit.Bukkit;\nimport org.bukkit.event.EventHandler;\nimport org.bukkit.event.EventPriority;\nimport org.bukkit.event.HandlerList;\nimport org.bukkit.event.Listener;\nimport org.bukkit.event.player.PlayerQuitEvent;\n\npublic class OnDisconnect extends UnCacheStrategy implements Listener\n{\n\tpublic OnDisconnect(Database cache)\n\t{\n\t\tsuper(cache);\n\t\tBukkit.getPluginManager().registerEvents(this, Minepacks.getInstance());\n\t}\n\n\t@EventHandler(priority = EventPriority.MONITOR)\n\tpublic void playerLeaveEvent(PlayerQuitEvent event)\n\t{\n\t\tBackpack backpack = cache.getBackpack(event.getPlayer());\n\t\tif(backpack != null && !backpack.isOpen())\n\t\t{\n\t\t\tcache.unloadBackpack(backpack);\n\t\t}\n\t}\n\n\t@Override\n\tpublic void close()\n\t{\n\t\tHandlerList.unregisterAll(this);\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/UnCacheStrategies/OnDisconnectDelayed.java",
    "content": "/*\n *   Copyright (C) 2023 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Database.UnCacheStrategies;\n\nimport at.pcgamingfreaks.Minepacks.Bukkit.Backpack;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Database.Database;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport org.bukkit.Bukkit;\nimport org.bukkit.event.EventHandler;\nimport org.bukkit.event.EventPriority;\nimport org.bukkit.event.HandlerList;\nimport org.bukkit.event.Listener;\nimport org.bukkit.event.player.PlayerQuitEvent;\n\npublic class OnDisconnectDelayed extends UnCacheStrategy implements Listener\n{\n\tprivate final long delay;\n\n\tpublic OnDisconnectDelayed(Database cache)\n\t{\n\t\tsuper(cache);\n\t\tdelay = Minepacks.getInstance().getConfiguration().getUnCacheDelay();\n\t\tBukkit.getPluginManager().registerEvents(this, Minepacks.getInstance());\n\t}\n\n\t@EventHandler(priority = EventPriority.MONITOR)\n\tpublic void playerLeaveEvent(PlayerQuitEvent event)\n\t{\n\t\tfinal Backpack backpack = cache.getBackpack(event.getPlayer());\n\t\tif(backpack != null) // We only uncache unmarried player.\n\t\t{\n\t\t\tMinepacks.getScheduler().runLater(() -> {\n\t\t\t\tif (!backpack.isOpen())\n\t\t\t\t{\n\t\t\t\t\tcache.unloadBackpack(backpack);\n\t\t\t\t} else {\n\t\t\t\t\tMinepacks.getScheduler().runLater(() ->\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!backpack.isOpen())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcache.unloadBackpack(backpack);\n\t\t\t\t\t\t}\n\t\t\t\t\t}, delay);\n\t\t\t\t}\n\t\t\t}, delay);\n\t\t}\n\t}\n\n\t@Override\n\tpublic void close()\n\t{\n\t\tHandlerList.unregisterAll(this);\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/UnCacheStrategies/UnCacheStrategy.java",
    "content": "/*\n *   Copyright (C) 2023 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Database.UnCacheStrategies;\n\nimport at.pcgamingfreaks.Minepacks.Bukkit.Database.Database;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\n\npublic abstract class UnCacheStrategy\n{\n\tprotected Database cache;\n\n\tprotected UnCacheStrategy(Database cache)\n\t{\n\t\tthis.cache = cache;\n\t}\n\n\tpublic static UnCacheStrategy getUnCacheStrategy(Database cache)\n\t{\n\t\tswitch(Minepacks.getInstance().getConfiguration().getUnCacheStrategy())\n\t\t{\n\t\t\tcase \"ondisconnect\": return new OnDisconnect(cache);\n\t\t\tcase \"ondisconnectdelayed\": return new OnDisconnectDelayed(cache);\n\t\t\tcase \"intervalchecked\": return new IntervalChecked(cache);\n\t\t\tcase \"interval\": default: return new Interval(cache);\n\t\t}\n\t}\n\n\tpublic void close()\n\t{\n\t\tcache = null;\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/ItemsCollector.java",
    "content": "/*\n *   Copyright (C) 2023 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit;\n\nimport at.pcgamingfreaks.Minepacks.Bukkit.API.WorldBlacklistMode;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Listener.ItemFilter;\nimport org.bukkit.Bukkit;\nimport org.bukkit.entity.Entity;\nimport org.bukkit.entity.Item;\nimport org.bukkit.entity.Player;\nimport org.bukkit.inventory.ItemStack;\n\nimport java.util.*;\n\npublic class ItemsCollector extends CancellableRunnable {\n\tprivate final Minepacks plugin;\n\tprivate final double radius;\n\tprivate final ItemFilter itemFilter;\n\n\t/**\n\t * Is the feature enabled?\n\t */\n\tprivate final boolean isToggleable;\n\n\t/**\n\t * Default on join?\n\t */\n\tprivate final boolean enabledOnJoin;\n\n\t/**\n\t * List of players that toggled the feature.\n\t */\n\tprivate final Set<UUID> toggleList;\n\n\tpublic ItemsCollector(Minepacks plugin)\n\t{\n\t\tthis.plugin = plugin;\n\t\tthis.radius = plugin.getConfiguration().getFullInvRadius();\n\n\t\tthis.isToggleable = plugin.getConfiguration().isFullInvToggleAllowed();\n\t\tthis.enabledOnJoin = plugin.getConfiguration().isFullInvEnabledOnJoin();\n\t\tthis.toggleList = new HashSet<>();\n\t\tschedule();\n\t\titemFilter = plugin.getItemFilter();\n\t}\n\n\tpublic boolean canUseAutoPickup(Player player)\n\t{\n\t\t// Check if player can use in world\n\t\tif(plugin.isDisabled(player) != WorldBlacklistMode.None) return false;\n\n\t\t// Check if toggle is enabled AND player has been disabled, return.\n\t\tif (isToggleable && !isPickupEnabled(player.getUniqueId())) return false;\n\n\t\t// Check permission\n\t\treturn (player.hasPermission(Permissions.USE) && player.hasPermission(Permissions.FULL_PICKUP));\n\t}\n\n\t@Override\n\tpublic void run()\n\t{\n\t\tfor(Player player : Bukkit.getServer().getOnlinePlayers())\n\t\t{\n\t\t\tMinepacks.getScheduler().runAtEntity(player, entityTask -> {\n\t\t\t\tif (!canUseAutoPickup(player)) return;\n\n\t\t\t\t// Inventory is full\n\t\t\t\tif (player.getInventory().firstEmpty() != -1) return;\n\n\t\t\t\t// Only check loaded backpacks (loading them would take too much time for a repeating task, the backpack will be loaded async soon enough)\n\t\t\t\tBackpack backpack = (Backpack) plugin.getBackpackCachedOnly(player);\n\t\t\t\tif (backpack == null) return;\n\n\t\t\t\tList<Entity> entities = player.getNearbyEntities(radius, radius, radius);\n\t\t\t\tfor(Entity entity : entities)\n\t\t\t\t{\n\t\t\t\t\tif(entity instanceof Item)\n\t\t\t\t\t{\n\t\t\t\t\t\tItem item = (Item) entity;\n\t\t\t\t\t\tif (!item.isDead() && item.getPickupDelay() <= 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tMap<Integer, ItemStack> leftover = player.getInventory().addItem(item.getItemStack());\n\t\t\t\t\t\t\tif (!leftover.isEmpty())\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tItemStack itemStack = leftover.get(0);\n\t\t\t\t\t\t\t\tif (itemStack == null || itemStack.getAmount() == 0 || (itemFilter != null && itemFilter.isItemBlocked(itemStack)))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tleftover = backpack.addItems(itemStack);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (!leftover.isEmpty())\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\titem.setItemStack(leftover.get(0));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\titem.remove();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\t@Override\n\tpublic void schedule() {\n\t\ttask = getScheduler().runTimer(this::run, plugin.getConfiguration().getFullInvCheckInterval(), plugin.getConfiguration().getFullInvCheckInterval());\n\t}\n\n\tpublic void close() {\n\t\tcancel();\n\t}\n\n\t/**\n\t * Toggles the automatic collection for the player.\n\t * @param uuid The players UUID\n\t * @return The new state. True = collection enabled.\n\t */\n\tpublic boolean toggleState(UUID uuid)\n\t{\n\t\tboolean removed = toggleList.remove(uuid);\n\t\tif (!removed)\n\t\t{\n\t\t\ttoggleList.add(uuid);\n\t\t}\n\t\treturn isPickupEnabled(uuid);\n\t}\n\n\t/**\n\t * The item pickup state for a certain player.\n\t * @param uuid The player uuid\n\t * @return true if enabled\n\t */\n\tpublic boolean isPickupEnabled(UUID uuid)\n\t{\n\t\treturn enabledOnJoin ^ toggleList.contains(uuid);\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Listener/BackpackEventListener.java",
    "content": "/*\n *   Copyright (C) 2023 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Listener;\n\nimport at.pcgamingfreaks.Bukkit.Message.Message;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Backpack;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Placeholders;\nimport org.bukkit.OfflinePlayer;\nimport org.bukkit.Sound;\nimport org.bukkit.entity.Player;\nimport org.bukkit.event.EventHandler;\nimport org.bukkit.event.EventPriority;\nimport org.bukkit.event.inventory.InventoryClickEvent;\nimport org.bukkit.event.inventory.InventoryCloseEvent;\nimport org.bukkit.event.player.PlayerQuitEvent;\n\npublic class BackpackEventListener extends MinepacksListener\n{\n\tprivate final Message messageOwnBackpackClose, messageOtherBackpackClose;\n\tprivate final Sound closeSound;\n\t\n\tpublic BackpackEventListener(Minepacks plugin)\n\t{\n\t\tsuper(plugin);\n\t\tmessageOwnBackpackClose = plugin.getLanguage().getMessage(\"Ingame.OwnBackpackClose\");\n\t\tmessageOtherBackpackClose = plugin.getLanguage().getMessage(\"Ingame.PlayerBackpackClose\").placeholders(Placeholders.mkPlayerName(\"Owner\"));\n\t\tcloseSound = plugin.getConfiguration().getCloseSound();\n\t}\n\t\n\t@EventHandler(priority = EventPriority.MONITOR)\n\tpublic void onClose(InventoryCloseEvent event)\n\t{\n\t\tif (event.getInventory() != null && event.getInventory().getHolder() instanceof Backpack && event.getPlayer() instanceof Player)\n\t\t{\n\t\t\tBackpack backpack = (Backpack)event.getInventory().getHolder();\n\t\t\tPlayer closer = (Player)event.getPlayer();\n\t\t\tif(backpack.canEdit(closer))\n\t\t\t{\n\t\t\t\tbackpack.save();\n\t\t\t}\n\t\t\tbackpack.close(closer);\n\t\t\tif(event.getPlayer().getUniqueId().equals(backpack.getOwnerId()))\n\t\t\t{\n\t\t\t\tmessageOwnBackpackClose.send(closer);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tmessageOtherBackpackClose.send(closer, backpack.getOwner());\n\t\t\t}\n\t\t\tif(closeSound != null)\n\t\t\t{\n\t\t\t\tcloser.playSound(closer.getLocation(), closeSound, 1, 0);\n\t\t\t}\n\t\t}\n\t}\n\t\n\t@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)\n\tpublic void onClick(InventoryClickEvent event)\n\t{\n\t\tif (event.getInventory() != null && event.getInventory().getHolder() instanceof Backpack && event.getWhoClicked() instanceof Player)\n\t\t{\n\t\t\tBackpack backpack = (Backpack) event.getInventory().getHolder();\n\t\t\tif(!backpack.canEdit((Player)event.getWhoClicked()))\n\t\t\t{\n\t\t\t\tevent.setCancelled(true);\n\t\t\t}\n\t\t    else\n\t\t\t{\n\t\t\t\tbackpack.setChanged();\n\t\t\t}\n\t\t}\n\t}\n\t\n\t@EventHandler(priority = EventPriority.MONITOR)\n\tpublic void onPlayerLeaveEvent(PlayerQuitEvent event)\n\t{\n\t\tBackpack backpack = plugin.getDatabase().getBackpack(event.getPlayer());\n\t\tif(backpack != null) backpack.save();\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Listener/DisableShulkerboxes.java",
    "content": "/*\n *   Copyright (C) 2020 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Listener;\n\nimport at.pcgamingfreaks.Bukkit.MCVersion;\nimport at.pcgamingfreaks.Bukkit.Util.InventoryUtils;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport org.bukkit.Material;\nimport org.bukkit.block.Block;\nimport org.bukkit.block.ShulkerBox;\nimport org.bukkit.event.EventHandler;\nimport org.bukkit.event.EventPriority;\nimport org.bukkit.event.block.*;\nimport org.bukkit.event.entity.EntityDeathEvent;\nimport org.bukkit.event.entity.ItemSpawnEvent;\nimport org.bukkit.event.inventory.*;\nimport org.bukkit.event.player.PlayerDropItemEvent;\nimport org.bukkit.inventory.ItemStack;\n\nimport java.util.Collection;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.Locale;\n\npublic class DisableShulkerboxes extends MinepacksListener\n{ //TODO handle existing shulkerboxes in inventory\n\tprotected static final Collection<Material> SHULKER_BOX_MATERIALS = new HashSet<>();\n\n\tstatic\n\t{\n\t\tif(MCVersion.isNewerOrEqualThan(MCVersion.MC_1_11))\n\t\t{\n\t\t\tSHULKER_BOX_MATERIALS.add(Material.BLACK_SHULKER_BOX);\n\t\t\tSHULKER_BOX_MATERIALS.add(Material.BLUE_SHULKER_BOX);\n\t\t\tSHULKER_BOX_MATERIALS.add(Material.BROWN_SHULKER_BOX);\n\t\t\tSHULKER_BOX_MATERIALS.add(Material.CYAN_SHULKER_BOX);\n\t\t\tSHULKER_BOX_MATERIALS.add(Material.GREEN_SHULKER_BOX);\n\t\t\tSHULKER_BOX_MATERIALS.add(Material.GRAY_SHULKER_BOX);\n\t\t\tSHULKER_BOX_MATERIALS.add(Material.LIGHT_BLUE_SHULKER_BOX);\n\t\t\tSHULKER_BOX_MATERIALS.add(Material.LIME_SHULKER_BOX);\n\t\t\tSHULKER_BOX_MATERIALS.add(Material.MAGENTA_SHULKER_BOX);\n\t\t\tSHULKER_BOX_MATERIALS.add(Material.ORANGE_SHULKER_BOX);\n\t\t\tSHULKER_BOX_MATERIALS.add(Material.PINK_SHULKER_BOX);\n\t\t\tSHULKER_BOX_MATERIALS.add(Material.PURPLE_SHULKER_BOX);\n\t\t\tSHULKER_BOX_MATERIALS.add(Material.RED_SHULKER_BOX);\n\t\t\tSHULKER_BOX_MATERIALS.add(Material.WHITE_SHULKER_BOX);\n\t\t\tSHULKER_BOX_MATERIALS.add(Material.YELLOW_SHULKER_BOX);\n\t\t\tif(MCVersion.isOlderThan(MCVersion.MC_1_13))\n\t\t\t{\n\t\t\t\tSHULKER_BOX_MATERIALS.add(Material.valueOf(\"SILVER_SHULKER_BOX\"));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tSHULKER_BOX_MATERIALS.add(Material.LIGHT_GRAY_SHULKER_BOX);\n\t\t\t\tSHULKER_BOX_MATERIALS.add(Material.SHULKER_BOX);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate boolean removeExisting, dropExistingContent;\n\n\tpublic DisableShulkerboxes(final Minepacks plugin)\n\t{\n\t\tsuper(plugin);\n\t\tremoveExisting = plugin.getConfiguration().isShulkerboxesExistingDestroyEnabled();\n\t\tdropExistingContent = plugin.getConfiguration().isShulkerboxesExistingDropEnabled();\n\t}\n\n\t@EventHandler(ignoreCancelled = true)\n\tpublic void onCraft(CraftItemEvent event)\n\t{\n\t\tif(event.getCurrentItem() != null && SHULKER_BOX_MATERIALS.contains(event.getCurrentItem().getType()))\n\t\t{\n\t\t\tevent.setCancelled(true);\n\t\t}\n\t}\n\n\t@EventHandler(ignoreCancelled = true)\n\tpublic void onInventoryClick(InventoryClickEvent event)\n\t{\n\t\tif(event.getCurrentItem() != null && SHULKER_BOX_MATERIALS.contains(event.getCurrentItem().getType()))\n\t\t{\n\t\t\tevent.setCancelled(true);\n\t\t}\n\t}\n\n\t@EventHandler(ignoreCancelled = true)\n\tpublic void onInventoryOpen(InventoryOpenEvent event)\n\t{\n\t\tif(event.getInventory().getHolder() != null && event.getInventory().getHolder().getClass().getName().toLowerCase(Locale.ROOT).contains(\"shulker\"))\n\t\t{\n\t\t\tif(removeExisting)\n\t\t\t{\n\t\t\t\tBlock shulkerBlock = ((ShulkerBox) event.getInventory().getHolder()).getBlock();\n\t\t\t\tif(dropExistingContent)\n\t\t\t\t{\n\t\t\t\t\tInventoryUtils.dropInventory(event.getInventory(), shulkerBlock.getLocation());\n\t\t\t\t}\n\t\t\t\tevent.getInventory().clear();\n\t\t\t\tshulkerBlock.setType(Material.AIR);\n\t\t\t}\n\t\t\tevent.setCancelled(true);\n\t\t}\n\t}\n\n\t@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)\n\tpublic void onItemMove(InventoryMoveItemEvent event)\n\t{\n\t\tif(event.getItem() != null && SHULKER_BOX_MATERIALS.contains(event.getItem().getType()))\n\t\t{\n\t\t\tevent.setCancelled(true);\n\t\t}\n\t}\n\n\t@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)\n\tpublic void onItemMove(InventoryDragEvent event)\n\t{\n\t\tif(event.getCursor() != null && SHULKER_BOX_MATERIALS.contains(event.getCursor().getType()))\n\t\t{\n\t\t\tevent.setCancelled(true);\n\t\t}\n\t\telse if(event.getOldCursor() != null && SHULKER_BOX_MATERIALS.contains(event.getOldCursor().getType()))\n\t\t{\n\t\t\tevent.setCancelled(true);\n\t\t}\n\t}\n\n\t@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)\n\tpublic void onPickup(InventoryPickupItemEvent event)\n\t{\n\t\tif(SHULKER_BOX_MATERIALS.contains(event.getItem().getItemStack().getType()))\n\t\t{\n\t\t\tevent.setCancelled(true);\n\t\t}\n\t}\n\n\t@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)\n\tpublic void onItemSpawn(ItemSpawnEvent event)\n\t{\n\t\tif(SHULKER_BOX_MATERIALS.contains(event.getEntity().getItemStack().getType()))\n\t\t{\n\t\t\tevent.setCancelled(true);\n\t\t}\n\t}\n\n\t@EventHandler(ignoreCancelled = true)\n\tpublic void onBlockPlace(BlockPlaceEvent event)\n\t{\n\t\tif(SHULKER_BOX_MATERIALS.contains(event.getBlockPlaced().getType()))\n\t\t{\n\t\t\tevent.getItemInHand().setType(Material.AIR);\n\t\t\tevent.setCancelled(true);\n\t\t}\n\t}\n\n\t@EventHandler(ignoreCancelled = true)\n\tpublic void onBlockMultiPlace(BlockMultiPlaceEvent event)\n\t{\n\t\tif(SHULKER_BOX_MATERIALS.contains(event.getBlock().getType()))\n\t\t{\n\t\t\tevent.getItemInHand().setType(Material.AIR);\n\t\t\tevent.setCancelled(true);\n\t\t}\n\t}\n\n\t@EventHandler(ignoreCancelled = true)\n\tpublic void onBlockBreak(BlockBreakEvent event)\n\t{\n\t\tif(handleShulkerBlock(event.getBlock())) event.setCancelled(true);\n\t}\n\n\t@EventHandler(ignoreCancelled = true)\n\tpublic void onBlockDamage(BlockDamageEvent event)\n\t{\n\t\tif(handleShulkerBlock(event.getBlock())) event.setCancelled(true);\n\t}\n\n\tprivate boolean handleShulkerBlock(Block block)\n\t{\n\t\tif(SHULKER_BOX_MATERIALS.contains(block.getType()))\n\t\t{\n\t\t\tif(removeExisting)\n\t\t\t{\n\t\t\t\tShulkerBox shulkerBox = (ShulkerBox) block.getState();\n\t\t\t\tif(dropExistingContent) InventoryUtils.dropInventory(shulkerBox.getInventory(), shulkerBox.getLocation());\n\t\t\t\tshulkerBox.getInventory().clear();\n\t\t\t\tblock.setType(Material.AIR);\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\t@EventHandler(ignoreCancelled = true)\n\tpublic void onBlockIgnite(BlockIgniteEvent event)\n\t{\n\t\tif(SHULKER_BOX_MATERIALS.contains(event.getBlock().getType()))\n\t\t{\n\t\t\tevent.setCancelled(true);\n\t\t}\n\t}\n\n\t@EventHandler(ignoreCancelled = true)\n\tpublic void onBlockCanBuild(BlockCanBuildEvent event)\n\t{\n\t\tif(SHULKER_BOX_MATERIALS.contains(event.getBlock().getType()))\n\t\t{\n\t\t\tevent.setBuildable(false);\n\t\t}\n\t}\n\n\t@EventHandler(ignoreCancelled = true)\n\tpublic void onBlockDispense(BlockDispenseEvent event)\n\t{\n\t\tif(SHULKER_BOX_MATERIALS.contains(event.getBlock().getType()))\n\t\t{\n\t\t\tevent.setCancelled(true);\n\t\t}\n\t}\n\n\t@EventHandler(ignoreCancelled = true)\n\tpublic void onPrepareItemCraftEvent(PrepareItemCraftEvent event)\n\t{\n\t\tif(event.getRecipe() == null) return;\n\t\tMaterial itemType = event.getRecipe().getResult().getType();\n\t\tif(itemType == Material.SHULKER_SHELL || SHULKER_BOX_MATERIALS.contains(itemType))\n\t\t{\n\t\t\tevent.getInventory().setResult(new ItemStack(Material.AIR));\n\t\t\t//TODO message\n\t\t}\n\t}\n\n\t@EventHandler(ignoreCancelled = true)\n\tpublic void onDrop(PlayerDropItemEvent event)\n\t{\n\t\tMaterial itemType = event.getItemDrop().getItemStack().getType();\n\t\tif(itemType == Material.SHULKER_SHELL || SHULKER_BOX_MATERIALS.contains(itemType))\n\t\t{\n\t\t\tevent.setCancelled(true);\n\t\t}\n\t}\n\n\t@EventHandler(ignoreCancelled = true)\n\tpublic void onDrop(EntityDeathEvent event)\n\t{\n\t\tIterator<ItemStack> it = event.getDrops().iterator();\n\t\twhile(it.hasNext())\n\t\t{\n\t\t\tMaterial itemType = it.next().getType();\n\t\t\tif(itemType == Material.SHULKER_SHELL || SHULKER_BOX_MATERIALS.contains(itemType))\n\t\t\t{\n\t\t\t\tit.remove();\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Listener/DropOnDeath.java",
    "content": "/*\n *   Copyright (C) 2023 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Listener;\n\nimport at.pcgamingfreaks.Minepacks.Bukkit.API.Events.BackpackDropOnDeathEvent;\nimport at.pcgamingfreaks.Minepacks.Bukkit.API.WorldBlacklistMode;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Permissions;\nimport org.bukkit.Location;\nimport org.bukkit.entity.Player;\nimport org.bukkit.event.EventHandler;\nimport org.bukkit.event.EventPriority;\nimport org.bukkit.event.entity.PlayerDeathEvent;\n\npublic class DropOnDeath extends MinepacksListener\n{\n\tprivate final boolean honorKeepOnDeath;\n\n\tpublic DropOnDeath(Minepacks plugin)\n\t{\n\t\tsuper(plugin);\n\t\thonorKeepOnDeath = plugin.getConfiguration().getHonorKeepInventoryOnDeath();\n\t}\n\n\t@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)\n\tpublic void onDeath(PlayerDeathEvent event)\n\t{\n\t\tif(honorKeepOnDeath && event.getKeepInventory()) return;\n\t\tfinal Player player = event.getEntity();\n\t\tif(plugin.isDisabled(player) != WorldBlacklistMode.None) return;\n\t\tif (!player.hasPermission(Permissions.KEEP_ON_DEATH))\n\t\t{\n\t\t\tfinal Location location = player.getLocation();\n\t\t\tplugin.getBackpack(player, backpack -> {\n\t\t\t\tBackpackDropOnDeathEvent event1 = new BackpackDropOnDeathEvent(player, backpack);\n\t\t\t\tplugin.getServer().getPluginManager().callEvent(event1);\n\t\t\t\tif(!event1.isCancelled())\n\t\t\t\t{\n\t\t\t\t\tbackpack.drop(location);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Listener/ItemFilter.java",
    "content": "/*\n *   Copyright (C) 2024 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Listener;\n\nimport at.pcgamingfreaks.Bukkit.ItemNameResolver;\nimport at.pcgamingfreaks.Bukkit.Message.Message;\nimport at.pcgamingfreaks.Bukkit.Message.Placeholder.Processors.ItemDisplayNamePlaceholderProcessor;\nimport at.pcgamingfreaks.Bukkit.Message.Placeholder.Processors.ItemNamePlaceholderProcessor;\nimport at.pcgamingfreaks.Bukkit.MinecraftMaterial;\nimport at.pcgamingfreaks.Message.Placeholder.Placeholder;\nimport at.pcgamingfreaks.Minepacks.Bukkit.API.Backpack;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\n\nimport org.bukkit.Material;\nimport org.bukkit.entity.Player;\nimport org.bukkit.event.EventHandler;\nimport org.bukkit.event.EventPriority;\nimport org.bukkit.event.inventory.*;\nimport org.bukkit.inventory.ItemStack;\nimport org.jetbrains.annotations.NotNull;\nimport org.jetbrains.annotations.Nullable;\n\nimport java.util.Collection;\n\npublic class ItemFilter extends MinepacksListener implements at.pcgamingfreaks.Minepacks.Bukkit.API.ItemFilter\n{\n\tpublic final Message messageNotAllowedInBackpack;\n\tpublic final ItemNameResolver itemNameResolver;\n\tprivate final at.pcgamingfreaks.Bukkit.ItemFilter filter;\n\n\tpublic ItemFilter(final Minepacks plugin)\n\t{\n\t\tsuper(plugin);\n\n\t\tboolean whitelistMode = plugin.getConfiguration().isItemFilterModeWhitelist();\n\t\tfilter = new at.pcgamingfreaks.Bukkit.ItemFilter(whitelistMode);\n\t\tCollection<MinecraftMaterial> filteredMaterials = plugin.getConfiguration().getItemFilterMaterials();\n\t\tif(plugin.getConfiguration().isShulkerboxesPreventInBackpackEnabled() && !whitelistMode)\n\t\t{\n\t\t\tfor(Material mat : DisableShulkerboxes.SHULKER_BOX_MATERIALS)\n\t\t\t{\n\t\t\t\tfilteredMaterials.add(new MinecraftMaterial(mat, (short) -1));\n\t\t\t}\n\t\t}\n\t\tfilter.addFilteredMaterials(filteredMaterials);\n\t\tfilter.addFilteredNames(plugin.getConfiguration().getItemFilterNames());\n\t\tfilter.addFilteredLore(plugin.getConfiguration().getItemFilterLore());\n\n\t\t/*if[STANDALONE]\n\t\titemNameResolver = new ItemNameResolver();\n\t\titemNameResolver.load(plugin, plugin.getConfiguration());\n\t\telse[STANDALONE]*/\n\t\titemNameResolver = at.pcgamingfreaks.PluginLib.Bukkit.ItemNameResolver.getInstance();\n\t\t/*end[STANDALONE]*/\n\n\t\tmessageNotAllowedInBackpack = plugin.getLanguage().getMessage(\"Ingame.NotAllowedInBackpack\").placeholders(new Placeholder(\"ItemName\", new ItemNamePlaceholderProcessor(itemNameResolver)), new Placeholder(\"ItemDisplayName\", new ItemDisplayNamePlaceholderProcessor(itemNameResolver)));\n\t}\n\n\t@Override\n\tpublic boolean isItemBlocked(final @Nullable ItemStack item)\n\t{\n\t\treturn filter.isItemBlocked(item);\n\t}\n\n\t@Override\n\tpublic void sendNotAllowedMessage(@NotNull Player player, @NotNull ItemStack itemStack)\n\t{\n\t\tmessageNotAllowedInBackpack.send(player, itemStack);\n\t}\n\n\t@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)\n\tpublic void onItemMove(InventoryMoveItemEvent event)\n\t{\n\t\tif(event.getDestination().getType() == InventoryType.CHEST && event.getDestination().getHolder() instanceof Backpack && isItemBlocked(event.getItem()))\n\t\t{\n\t\t\tif(event.getSource().getHolder() instanceof Player)\n\t\t\t{\n\t\t\t\tsendNotAllowedMessage((Player) event.getSource().getHolder(), event.getItem());\n\t\t\t}\n\t\t\tevent.setCancelled(true);\n\t\t}\n\t}\n\n\t@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)\n\tpublic void onItemClick(InventoryClickEvent event)\n\t{\n\t\tif(!(event.getWhoClicked() instanceof Player)) return;\n\t\tif(event.getInventory().getType() == InventoryType.CHEST && event.getInventory().getHolder() instanceof Backpack)\n\t\t{\n\t\t\tPlayer player = (Player) event.getWhoClicked();\n\t\t\tif(event.getAction() == InventoryAction.MOVE_TO_OTHER_INVENTORY && checkIsBlockedAndShowMessage(player, event.getCurrentItem()))\n\t\t\t{\n\t\t\t\tevent.setCancelled(true);\n\t\t\t}\n\t\t\telse if((event.getAction() == InventoryAction.HOTBAR_MOVE_AND_READD || event.getAction() == InventoryAction.HOTBAR_SWAP) && event.getHotbarButton() != -1)\n\t\t\t{\n\t\t\t\tItemStack item = event.getWhoClicked().getInventory().getItem(event.getHotbarButton());\n\t\t\t\tif(checkIsBlockedAndShowMessage(player, item))\n\t\t\t\t{\n\t\t\t\t\tevent.setCancelled(true);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if((event.getAction() == InventoryAction.HOTBAR_MOVE_AND_READD || event.getAction() == InventoryAction.HOTBAR_SWAP) && event.getClick().name().equals(\"SWAP_OFFHAND\"))\n\t\t\t{\n\t\t\t\tif(checkIsBlockedAndShowMessage(player, player.getInventory().getItemInOffHand()))\n\t\t\t\t{\n\t\t\t\t\tevent.setCancelled(true);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if(!player.getInventory().equals(event.getClickedInventory()) && checkIsBlockedAndShowMessage(player, event.getCursor()))\n\t\t\t{\n\t\t\t\tevent.setCancelled(true);\n\t\t\t}\n\t\t}\n\t}\n\n\t@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)\n\tpublic void onItemDrag(InventoryDragEvent event)\n\t{\n\t\tif(event.getInventory().getType() == InventoryType.CHEST && event.getInventory().getHolder() instanceof Backpack && (isItemBlocked(event.getOldCursor()) || isItemBlocked(event.getCursor())) && event.getRawSlots().containsAll(event.getInventorySlots()))\n\t\t{\n\t\t\tsendNotAllowedMessage((Player) event.getView().getPlayer(), event.getOldCursor());\n\t\t\tevent.setCancelled(true);\n\t\t}\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Listener/ItemShortcut.java",
    "content": "/*\n *   Copyright (C) 2025 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Listener;\n\nimport at.pcgamingfreaks.Bukkit.MCVersion;\nimport at.pcgamingfreaks.Bukkit.Message.Message;\nimport at.pcgamingfreaks.Bukkit.Util.HeadUtils;\nimport at.pcgamingfreaks.Minepacks.Bukkit.API.Backpack;\nimport at.pcgamingfreaks.Minepacks.Bukkit.API.Events.InventoryClearedEvent;\nimport at.pcgamingfreaks.Minepacks.Bukkit.API.WorldBlacklistMode;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Permissions;\n\nimport org.bukkit.ChatColor;\nimport org.bukkit.Material;\nimport org.bukkit.entity.Player;\nimport org.bukkit.event.EventHandler;\nimport org.bukkit.event.EventPriority;\nimport org.bukkit.event.block.Action;\nimport org.bukkit.event.block.BlockPlaceEvent;\nimport org.bukkit.event.entity.PlayerDeathEvent;\nimport org.bukkit.event.inventory.*;\nimport org.bukkit.event.player.*;\nimport org.bukkit.inventory.EquipmentSlot;\nimport org.bukkit.inventory.ItemStack;\nimport org.jetbrains.annotations.NotNull;\nimport org.jetbrains.annotations.Nullable;\n\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.Set;\nimport java.util.UUID;\n\npublic class ItemShortcut extends MinepacksListener\n{\n\tprivate static final UUID MINEPACKS_UUID = UUID.nameUUIDFromBytes(\"Minepacks\".getBytes());\n\tprivate final String itemName, itemNameNoReset, value, openCommand;\n\tprivate final Message messageDoNotRemoveItem;\n\tprivate final boolean improveDeathChestCompatibility, blockAsHat, allowRightClickOnContainers, blockItemFromMoving;\n\tprivate final int preferredSlotId;\n\tprivate final Set<Material> containerMaterials = new HashSet<>();\n\n\tpublic ItemShortcut(final @NotNull Minepacks plugin)\n\t{\n\t\tsuper(plugin);\n\t\titemName = ChatColor.translateAlternateColorCodes('&', plugin.getConfiguration().getItemShortcutItemName());\n\t\titemNameNoReset = itemName.replace(ChatColor.RESET.toString(), \"\");\n\t\tvalue = plugin.getConfiguration().getItemShortcutHeadValue();\n\t\timproveDeathChestCompatibility = plugin.getConfiguration().isItemShortcutImproveDeathChestCompatibilityEnabled();\n\t\tblockAsHat = plugin.getConfiguration().isItemShortcutBlockAsHatEnabled();\n\t\tallowRightClickOnContainers = plugin.getConfiguration().isItemShortcutRightClickOnContainerAllowed();\n\t\tpreferredSlotId = plugin.getConfiguration().getItemShortcutPreferredSlotId();\n\t\tblockItemFromMoving = plugin.getConfiguration().getItemShortcutBlockItemFromMoving();\n\t\topenCommand = plugin.getLanguage().getCommandAliases(\"Backpack\", \"backpack\")[0] + ' ' + plugin.getLanguage().getCommandAliases(\"Open\", \"open\")[0];\n\t\tmessageDoNotRemoveItem = plugin.getLanguage().getMessage(\"Ingame.DontRemoveShortcut\");\n\n\t\tif(allowRightClickOnContainers)\n\t\t{\n\t\t\tcontainerMaterials.add(Material.CHEST);\n\t\t\tcontainerMaterials.add(Material.TRAPPED_CHEST);\n\t\t\tcontainerMaterials.add(Material.ENDER_CHEST);\n\t\t\tcontainerMaterials.add(Material.CRAFTING_TABLE);\n\t\t\tcontainerMaterials.add(Material.FURNACE);\n\t\t\tcontainerMaterials.add(Material.BLAST_FURNACE);\n\t\t\tcontainerMaterials.add(Material.DISPENSER);\n\t\t\tcontainerMaterials.add(Material.DROPPER);\n\t\t\tcontainerMaterials.add(Material.HOPPER);\n\t\t\tif(MCVersion.isNewerOrEqualThan(MCVersion.MC_1_11)) containerMaterials.addAll(DisableShulkerboxes.SHULKER_BOX_MATERIALS);\n\t\t}\n\t}\n\n\tpublic boolean isItemShortcut(final @Nullable ItemStack stack)\n\t{\n\t\tif(stack == null || stack.getType() != HeadUtils.HEAD_MATERIAL || !stack.hasItemMeta()) return false;\n\t\tString itemDisplayName = stack.getItemMeta().getDisplayName();\n\t\treturn itemDisplayName != null && itemNameNoReset.equals(itemDisplayName.replace(ChatColor.RESET.toString(), \"\"));\n\t}\n\n\tpublic void addItem(Player player)\n\t{\n\t\tif(player.hasPermission(Permissions.USE))\n\t\t{\n\t\t\tboolean empty = false, item = false;\n\t\t\tfor(ItemStack itemStack : player.getInventory())\n\t\t\t{\n\t\t\t\tif(itemStack == null || itemStack.getType() == Material.AIR) empty = true;\n\t\t\t\telse if(isItemShortcut(itemStack))\n\t\t\t\t{\n\t\t\t\t\titem = true;\n\t\t\t\t\tif(itemStack.getAmount() > 1) itemStack.setAmount(1);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(!item && empty)\n\t\t\t{\n\t\t\t\tif(preferredSlotId >= 0 && preferredSlotId < 36)\n\t\t\t\t{\n\t\t\t\t\tItemStack stack = player.getInventory().getItem(preferredSlotId);\n\t\t\t\t\tif(stack == null || stack.getType() == Material.AIR)\n\t\t\t\t\t{\n\t\t\t\t\t\tplayer.getInventory().setItem(preferredSlotId, HeadUtils.fromBase64(value, itemName, MINEPACKS_UUID));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tplayer.getInventory().addItem(HeadUtils.fromBase64(value, itemName, MINEPACKS_UUID));\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tfor(ItemStack itemStack : player.getInventory())\n\t\t\t{\n\t\t\t\tif(isItemShortcut(itemStack))\n\t\t\t\t{\n\t\t\t\t\tplayer.getInventory().remove(itemStack);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate void removeItem(Player player)\n\t{\n\t\tfor(ItemStack itemStack : player.getInventory())\n\t\t{\n\t\t\tif(isItemShortcut(itemStack))\n\t\t\t{\n\t\t\t\titemStack.setAmount(0);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\t//region Add backpack item\n\t@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)\n\tpublic void onJoin(PlayerJoinEvent event)\n\t{\n\t\tif(plugin.isDisabled(event.getPlayer()) != WorldBlacklistMode.None) return;\n\t\tMinepacks.getScheduler().runLater(() -> Minepacks.getScheduler().runAtEntity(event.getPlayer(), task -> addItem(event.getPlayer())), 2L);\n\t}\n\n\t@EventHandler(priority = EventPriority.MONITOR)\n\tpublic void onSpawn(PlayerRespawnEvent event)\n\t{\n\t\tif(plugin.isDisabled(event.getPlayer()) != WorldBlacklistMode.None) return;\n\t\tMinepacks.getScheduler().runAtEntityLater(event.getPlayer(), task -> addItem(event.getPlayer()), 2L);\n\t}\n\n\t@EventHandler(priority = EventPriority.MONITOR)\n\tpublic void onWorldChange(final PlayerChangedWorldEvent event)\n\t{\n\t\tPlayer player = event.getPlayer();\n\n\t\tMinepacks.getScheduler().runAtEntityLater(player, () -> {\n\t\t\t\tif(!player.isOnline()) return;\n\t\t\t\tif(player.hasPermission(Permissions.USE) && plugin.isDisabled(player) == WorldBlacklistMode.None)\n\t\t\t\t\taddItem(player);\n\t\t\t\telse\n\t\t\t\t\tremoveItem(player);\n\t\t\t}, 2L);\n\t}\n\n\t@EventHandler(priority = EventPriority.MONITOR)\n\tpublic void onInventoryClear(InventoryClearedEvent event)\n\t{\n\t\tif(plugin.isDisabled(event.getPlayer()) != WorldBlacklistMode.None) return;\n\t\taddItem(event.getPlayer());\n\t}\n\t//endregion\n\n\t//region Prevent placing of backpack item\n\t@EventHandler(priority = EventPriority.LOWEST)\n\tpublic void onItemInteract(PlayerInteractEvent event)\n\t{\n\t\tif ((event.getAction() != Action.RIGHT_CLICK_AIR && event.getAction() != Action.RIGHT_CLICK_BLOCK)) return;\n\t\tif(isItemShortcut(event.getItem()))\n\t\t{\n\t\t\tif(allowRightClickOnContainers && event.getAction() == Action.RIGHT_CLICK_BLOCK)\n\t\t\t{\n\t\t\t\t//noinspection ConstantConditions\n\t\t\t\tif(containerMaterials.contains(event.getClickedBlock().getType())) return;\n\t\t\t}\n\t\t\tevent.getPlayer().performCommand(openCommand);\n\t\t\tevent.setCancelled(true);\n\t\t}\n\t}\n\n\t@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)\n\tpublic void onArmorStandManipulation(PlayerArmorStandManipulateEvent event)\n\t{\n\t\tif(isItemShortcut(event.getPlayerItem()))\n\t\t{\n\t\t\tevent.getPlayer().performCommand(openCommand);\n\t\t\tevent.setCancelled(true);\n\t\t}\n\t}\n\n\t@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)\n\tpublic void onItemFrameInteract(PlayerInteractEntityEvent event)\n\t{\n\t\tPlayer player = event.getPlayer();\n\t\tItemStack item;\n\t\tif(MCVersion.isDualWieldingMC())\n\t\t{\n\t\t\titem = (event.getHand() == EquipmentSlot.HAND) ? player.getInventory().getItemInMainHand() : player.getInventory().getItemInOffHand();\n\t\t}\n\t\telse\n\t\t{\n\t\t\titem = player.getItemInHand();\n\t\t}\n\t\tif(isItemShortcut(item))\n\t\t{\n\t\t\tevent.getPlayer().performCommand(openCommand);\n\t\t\tevent.setCancelled(true);\n\t\t}\n\t}\n\n\t@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)\n\tpublic void onBlockPlace(BlockPlaceEvent event)\n\t{\n\t\tif(isItemShortcut(event.getItemInHand()))\n\t\t{\n\t\t\tevent.getPlayer().performCommand(openCommand);\n\t\t\tevent.setCancelled(true);\n\t\t}\n\t}\n\t//endregion\n\n\t//region Handle inventory actions\n\t@EventHandler(priority = EventPriority.LOWEST)\n\tpublic void onItemClick(InventoryClickEvent event)\n\t{\n\t\tif(event.getWhoClicked() instanceof Player)\n\t\t{\n\t\t\tfinal Player player = (Player) event.getWhoClicked();\n\t\t\tif(isItemShortcut(event.getCurrentItem()))\n\t\t\t{\n\t\t\t\tif(event.getAction() == InventoryAction.SWAP_WITH_CURSOR)\n\t\t\t\t{\n\t\t\t\t\tif(plugin.isDisabled(player) != WorldBlacklistMode.None || !player.hasPermission(Permissions.USE) || !plugin.isPlayerGameModeAllowed(player)) return;\n\t\t\t\t\tBackpack backpack = plugin.getBackpackCachedOnly(player);\n\t\t\t\t\tif(backpack != null)\n\t\t\t\t\t{\n\t\t\t\t\t\t//TODO right click should place only one\n\t\t\t\t\t\tfinal ItemStack stack = event.getCursor();\n\t\t\t\t\t\tif(plugin.getItemFilter() == null || !plugin.getItemFilter().isItemBlocked(stack))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tItemStack full = backpack.addItem(stack);\n\t\t\t\t\t\t\tstack.setAmount((full == null) ? 0 : full.getAmount());\n\t\t\t\t\t\t\tevent.setCursor(full);\n\t\t\t\t\t\t\tevent.setCancelled(true);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tplugin.getItemFilter().messageNotAllowedInBackpack.send(player, plugin.getItemFilter().itemNameResolver.getName(stack));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if(event.getClick() == ClickType.RIGHT || event.getClick() == ClickType.SHIFT_RIGHT)\n\t\t\t\t{\n\t\t\t\t\tMinepacks.getScheduler().runAtEntity(player, task -> player.performCommand(openCommand));\n\t\t\t\t\tevent.setCancelled(true);\n\t\t\t\t}\n\t\t\t\telse if(event.getAction() == InventoryAction.MOVE_TO_OTHER_INVENTORY)\n\t\t\t\t{\n\t\t\t\t\tevent.setCancelled(true);\n\t\t\t\t\tmessageDoNotRemoveItem.send(player);\n\t\t\t\t}\n\t\t\t\tif(blockItemFromMoving) event.setCancelled(true);\n\t\t\t}\n\t\t\telse if((event.getAction() == InventoryAction.HOTBAR_MOVE_AND_READD || event.getAction() == InventoryAction.HOTBAR_SWAP) && event.getHotbarButton() != -1)\n\t\t\t{\n\t\t\t\tItemStack item = player.getInventory().getItem(event.getHotbarButton());\n\t\t\t\tif(isItemShortcut(item))\n\t\t\t\t{\n\t\t\t\t\tevent.setCancelled(true);\n\t\t\t\t\tmessageDoNotRemoveItem.send(player);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if((event.getAction() == InventoryAction.HOTBAR_MOVE_AND_READD || event.getAction() == InventoryAction.HOTBAR_SWAP) && event.getClick().name().equals(\"SWAP_OFFHAND\"))\n\t\t\t{\n\t\t\t\tif(isItemShortcut(player.getInventory().getItemInOffHand()))\n\t\t\t\t{\n\t\t\t\t\tevent.setCancelled(true);\n\t\t\t\t\tmessageDoNotRemoveItem.send(player);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if(isItemShortcut(event.getCursor()))\n\t\t\t{\n\t\t\t\tif(!player.getInventory().equals(event.getClickedInventory()))\n\t\t\t\t{\n\t\t\t\t\tevent.setCancelled(true);\n\t\t\t\t\tmessageDoNotRemoveItem.send(player);\n\t\t\t\t}\n\t\t\t\telse if(event.getSlotType() == InventoryType.SlotType.ARMOR && blockAsHat)\n\t\t\t\t{\n\t\t\t\t\tevent.setCancelled(true);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)\n\tpublic void onItemDrag(InventoryDragEvent event)\n\t{\n\t\tif(!event.getInventory().equals(event.getWhoClicked().getInventory()) && event.getRawSlots().containsAll(event.getInventorySlots()))\n\t\t{\n\t\t\tif(isItemShortcut(event.getCursor()) || isItemShortcut(event.getOldCursor()))\n\t\t\t{\n\t\t\t\tevent.setCancelled(true);\n\t\t\t\tmessageDoNotRemoveItem.send(event.getWhoClicked());\n\t\t\t}\n\t\t}\n\t}\n\n\t@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)\n\tpublic void onDropItem(PlayerDropItemEvent event)\n\t{\n\t\tif(isItemShortcut(event.getItemDrop().getItemStack()))\n\t\t{\n\t\t\tevent.setCancelled(true);\n\t\t\tmessageDoNotRemoveItem.send(event.getPlayer());\n\t\t}\n\t}\n\t//endregion\n\n\t/**\n\t * Removes the backpack item form the drops on death\n\t */\n\t@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)\n\tpublic void onDeath(PlayerDeathEvent event)\n\t{\n\t\t//region prevent drop\n\t\tIterator<ItemStack> itemStackIterator = event.getDrops().iterator();\n\t\twhile(itemStackIterator.hasNext())\n\t\t{\n\t\t\tif(isItemShortcut(itemStackIterator.next()))\n\t\t\t{\n\t\t\t\titemStackIterator.remove();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\t//endregion\n\t\tif(improveDeathChestCompatibility)\n\t\t{ // improveDeathChestCompatibility\n\t\t\tfor(ItemStack itemStack : event.getEntity().getInventory())\n\t\t\t{\n\t\t\t\tif(isItemShortcut(itemStack))\n\t\t\t\t{\n\t\t\t\t\titemStack.setAmount(0);\n\t\t\t\t\titemStack.setType(Material.AIR);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Listener/MinepacksListener.java",
    "content": "/*\n *   Copyright (C) 2017 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Listener;\n\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport lombok.AllArgsConstructor;\nimport org.bukkit.event.Listener;\n\n@AllArgsConstructor\nabstract class MinepacksListener implements Listener\n{\n\tprotected final Minepacks plugin;\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Listener/WorldBlacklistUpdater.java",
    "content": "/*\n *   Copyright (C) 2020 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Listener;\n\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport org.bukkit.event.EventHandler;\nimport org.bukkit.event.world.WorldInitEvent;\nimport org.jetbrains.annotations.NotNull;\n\nimport java.util.Locale;\n\npublic class WorldBlacklistUpdater extends MinepacksListener\n{\n\tpublic WorldBlacklistUpdater(final @NotNull Minepacks plugin)\n\t{\n\t\tsuper(plugin);\n\t}\n\n\t@EventHandler\n\tpublic void onWorldInit(final WorldInitEvent event)\n\t{\n\t\tString worldName = event.getWorld().getName().toLowerCase(Locale.ROOT);\n\t\tif(!plugin.getConfiguration().getWorldFilteredList().contains(worldName))\n\t\t{\n\t\t\tplugin.getWorldBlacklist().add(worldName);\n\t\t}\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Minepacks.java",
    "content": "/*\n *   Copyright (C) 2025 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit;\n\nimport at.pcgamingfreaks.Bukkit.Config.PermissionLoader;\nimport at.pcgamingfreaks.Bukkit.MCVersion;\nimport at.pcgamingfreaks.Bukkit.ManagedUpdater;\nimport at.pcgamingfreaks.Bukkit.Message.Message;\nimport at.pcgamingfreaks.Bukkit.Util.InventoryUtils;\nimport at.pcgamingfreaks.Bukkit.Util.Utils;\nimport at.pcgamingfreaks.ConsoleColor;\nimport at.pcgamingfreaks.Minepacks.Bukkit.API.*;\nimport at.pcgamingfreaks.Minepacks.Bukkit.API.Backpack;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Command.CommandManager;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Command.InventoryClearCommand;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Command.ShortcutCommand;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Database.Config;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Database.Database;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Database.Language;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Listener.*;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Listener.ItemFilter;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Placeholder.PlaceholderManager;\nimport at.pcgamingfreaks.Minepacks.Bukkit.SpecialInfoWorker.NoDatabaseWorker;\nimport at.pcgamingfreaks.Minepacks.MagicValues;\nimport at.pcgamingfreaks.Plugin.IPlugin;\nimport at.pcgamingfreaks.ServerType;\nimport at.pcgamingfreaks.Updater.UpdateResponseCallback;\nimport at.pcgamingfreaks.Util.StringUtils;\nimport at.pcgamingfreaks.Version;\nimport at.pcgf.libs.com.tcoded.folialib.FoliaLib;\nimport at.pcgf.libs.com.tcoded.folialib.impl.PlatformScheduler;\n\nimport org.bukkit.Bukkit;\nimport org.bukkit.GameMode;\nimport org.bukkit.OfflinePlayer;\nimport org.bukkit.Sound;\nimport org.bukkit.entity.Player;\nimport org.bukkit.event.HandlerList;\nimport org.bukkit.inventory.ItemStack;\nimport org.bukkit.plugin.PluginManager;\nimport org.bukkit.plugin.java.JavaPlugin;\nimport org.jetbrains.annotations.NotNull;\nimport org.jetbrains.annotations.Nullable;\n\nimport lombok.Getter;\n\nimport java.io.File;\nimport java.util.Collection;\nimport java.util.Locale;\nimport java.util.Set;\n\npublic class Minepacks extends JavaPlugin implements MinepacksPlugin, IPlugin\n{\n\t@Getter private static Minepacks instance = null;\n\t@Getter private static FoliaLib foliaLib = null;\n\n\tprivate ManagedUpdater updater = null;\n\tprivate Config config;\n\tprivate Language lang;\n\t@Getter private Database database;\n\n\tpublic Message messageNoPermission, messageInvalidBackpack, messageWorldDisabled, messageNotFromConsole, messageNotANumber;\n\n\tprivate int maxSize;\n\t@Getter private Set<String> worldBlacklist;\n\tprivate WorldBlacklistMode worldBlacklistMode;\n\tprivate ItemsCollector collector;\n\tprivate CommandManager commandManager;\n\tprivate InventoryClearCommand inventoryClearCommand;\n\tprivate Collection<GameMode> gameModes;\n\tprivate CooldownManager cooldownManager = null;\n\tprivate ItemFilter itemFilter = null;\n\tprivate Sound openSound = null;\n\tprivate ItemShortcut shortcut = null;\n\t@Getter private PlaceholderManager placeholderManager = null;\n\n\t@Override\n\tpublic boolean isRunningInStandaloneMode()\n\t{\n\t\t/*if[STANDALONE]\n\t\treturn true;\n\t\telse[STANDALONE]*/\n\t\treturn false;\n\t\t/*end[STANDALONE]*/\n\t}\n\n\t@Override\n\tpublic void onEnable()\n\t{\n\t\tcheckOldDataFolder();\n\n\t\tif(!checkPCGF_PluginLib()) return;\n\n\t\tif (MCVersion.isNewerOrEqualThan(MCVersion.MC_1_19_3) && ServerType.isPaperCompatible())\n\t\t{\n\t\t\tPermissionLoader.loadPermissionsFromPlugin(this);\n\t\t}\n\n\t\tupdater = new ManagedUpdater(this);\n\t\tinstance = this;\n\t\tfoliaLib = new FoliaLib(this);\n\t\tconfig = new Config(this);\n\t\tupdater.setChannel(config.getUpdateChannel());\n\t\tif(config.useUpdater()) updater.update();\n\n\t\tif(!checkMcVersion()) return;\n\n\t\tlang = new Language(this);\n\t\tload();\n\n\t\tgetLogger().info(StringUtils.getPluginEnabledMessage(getDescription().getName()));\n\t}\n\n\tprivate boolean checkMcVersion()\n\t{\n\t\tif (MCVersion.isNewerThan(MCVersion.MC_NMS_1_20_R3) && ServerType.isPaperCompatible())\n\t\t{\n\t\t\tgetLogger().warning(\"Paper support is experimental! Use at your own risk!\");\n\t\t\tgetLogger().warning(\"No guarantee for data integrity! Backup constantly!\");\n\t\t}\n\t\t// DO NOT REMOVE THIS! This is protecting your data! To add support for a new version, update PCGF PluginLib and then update the last version check!\n\t\tif (MCVersion.is(MCVersion.UNKNOWN) || !MCVersion.isUUIDsSupportAvailable() || MCVersion.isNewerThan(MCVersion.MC_NMS_26_1_R1))\n\t\t{\n\t\t\tthis.warnOnVersionIncompatibility();\n\t\t\tthis.setEnabled(false);\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\tprivate boolean checkPCGF_PluginLib()\n\t{\n\t\t// Check if running as standalone edition\n\t\t/*if[STANDALONE]\n\t\tgetLogger().info(\"Starting Minepacks in standalone mode!\");\n\t\tif(getServer().getPluginManager().isPluginEnabled(\"PCGF_PluginLib\"))\n\t\t{\n\t\t\tgetLogger().info(\"You do have the PCGF_PluginLib installed. You may consider switching to the default version of the plugin to reduce memory load and unlock additional features.\");\n\t\t}\n\t\telse[STANDALONE]*/\n\t\t// Not standalone so we should check the version of the PluginLib\n\t\tif(at.pcgamingfreaks.PluginLib.Bukkit.PluginLib.getInstance().getVersion().olderThan(new Version(MagicValues.MIN_PCGF_PLUGIN_LIB_VERSION)))\n\t\t{\n\t\t\tgetLogger().warning(\"You are using an outdated version of the PCGF PluginLib! Please update it!\");\n\t\t\tsetEnabled(false);\n\t\t\treturn false;\n\t\t}\n\t\t/*end[STANDALONE]*/\n\t\treturn true;\n\t}\n\n\tprivate void checkOldDataFolder()\n\t{\n\t\tif(!getDataFolder().exists())\n\t\t{\n\t\t\tFile oldPluginFolder = new File(getDataFolder().getParentFile(), \"MinePacks\");\n\t\t\tif(oldPluginFolder.exists() && !oldPluginFolder.renameTo(getDataFolder()))\n\t\t\t{\n\t\t\t\tgetLogger().warning(\"Failed to rename the plugins data-folder.\\n\" +\n\t\t\t\t\t\t                    \"Please rename the \\\"MinePacks\\\" folder to \\\"Minepacks\\\" and restart the server, to move your data from Minepacks V1.X to Minepacks V2.X!\");\n\t\t\t}\n\t\t}\n\t}\n\n\t@Override\n\tpublic void onDisable()\n\t{\n\t\tif(config == null) return;\n\t\tif(config.useUpdater()) updater.update();\n\t\tunload();\n\t\tupdater.waitForAsyncOperation(); // Wait for an update to finish\n\t\tgetLogger().info(StringUtils.getPluginDisabledMessage(getDescription().getName()));\n\t\tinstance = null;\n\t}\n\n\tpublic void update(final @Nullable UpdateResponseCallback updateResponseCallback)\n\t{\n\t\tupdater.update(updateResponseCallback);\n\t}\n\n\tprivate void load()\n\t{\n\t\tupdater.setChannel(config.getUpdateChannel());\n\t\tlang.load(config);\n\t\tdatabase = Database.getDatabase(this);\n\t\tif(database == null)\n\t\t{\n\t\t\tnew NoDatabaseWorker(this);\n\t\t\treturn;\n\t\t}\n\t\tmaxSize = config.getBackpackMaxSize();\n\t\tat.pcgamingfreaks.Minepacks.Bukkit.Backpack.setShrinkApproach(config.getShrinkApproach());\n\t\tat.pcgamingfreaks.Minepacks.Bukkit.Backpack.setTitle(config.useDynamicBPTitle() ? config.getBPTitle() : config.getBPTitleOther(), config.getBPTitleOther());\n\t\tat.pcgamingfreaks.Minepacks.Bukkit.Backpack.setMessageBackpackShrunk(lang.getMessage(\"Ingame.BackpackShrunk\"));\n\t\tmessageNotFromConsole  = lang.getMessage(\"NotFromConsole\");\n\t\tmessageNoPermission    = lang.getMessage(\"Ingame.NoPermission\");\n\t\tmessageInvalidBackpack = lang.getMessage(\"Ingame.InvalidBackpack\");\n\t\tmessageWorldDisabled   = lang.getMessage(\"Ingame.WorldDisabled\");\n\t\tmessageNotANumber      = lang.getMessage(\"Ingame.NaN\");\n\n\t\tcommandManager = new CommandManager(this);\n\t\tif(config.isInventoryManagementClearCommandEnabled()) inventoryClearCommand = new InventoryClearCommand(this);\n\n\t\t//region register events\n\t\tPluginManager pluginManager = getServer().getPluginManager();\n\t\tpluginManager.registerEvents(new BackpackEventListener(this), this);\n\t\tif(config.getDropOnDeath()) pluginManager.registerEvents(new DropOnDeath(this), this);\n\t\tif(config.isItemFilterEnabled())\n\t\t{\n\t\t\titemFilter = new ItemFilter(this);\n\t\t\tpluginManager.registerEvents(itemFilter, this);\n\t\t}\n\t\tif(config.isShulkerboxesDisable()) pluginManager.registerEvents(new DisableShulkerboxes(this), this);\n\t\tif(config.isItemShortcutEnabled())\n\t\t{\n\t\t\tshortcut = new ItemShortcut(this);\n\t\t\tpluginManager.registerEvents(shortcut, this);\n\t\t\tcommandManager.registerSubCommand(new ShortcutCommand(this, shortcut));\n\t\t}\n\t\telse shortcut = null;\n\t\tif(config.isWorldWhitelistMode()) pluginManager.registerEvents(new WorldBlacklistUpdater(this), this);\n\t\t//endregion\n\t\tif(config.getFullInvCollect() || config.isFullInvToggleAllowed()) collector = new ItemsCollector(this);\n\t\tworldBlacklist = config.getWorldBlacklist();\n\t\tworldBlacklistMode = (worldBlacklist.isEmpty()) ? WorldBlacklistMode.None : config.getWorldBlockMode();\n\n\t\tgameModes = config.getAllowedGameModes();\n\t\tif(config.getCommandCooldown() > 0) cooldownManager = new CooldownManager(this);\n\n\t\topenSound = config.getOpenSound();\n\n\t\tplaceholderManager = new PlaceholderManager(this);\n\t}\n\n\tprivate void unload()\n\t{\n\t\tif(lang == null) return;\n\t\tif(inventoryClearCommand != null)\n\t\t{\n\t\t\tinventoryClearCommand.close();\n\t\t\tinventoryClearCommand = null;\n\t\t}\n\t\tif (placeholderManager != null) { placeholderManager.close(); placeholderManager = null; }\n\t\tif(collector != null) collector.close();\n\t\tif(commandManager != null) commandManager.close();\n\t\tif(collector != null) collector.cancel();\n\t\tif(database != null) database.close(); // Close the DB connection, we won't need them any longer\n\t\tHandlerList.unregisterAll(this); // Stop the listeners\n\t\tif(cooldownManager != null) cooldownManager.close();\n\t\tcooldownManager = null;\n\t\tgetScheduler().cancelAllTasks(); // Kill all running task\n\t\titemFilter = null;\n\t}\n\n\tpublic void reload()\n\t{\n\t\tunload();\n\t\tconfig.reload();\n\t\tload();\n\t}\n\n\tpublic void warnOnVersionIncompatibility()\n\t{\n\t\tgetLogger().warning(ConsoleColor.RED + \"################################\" + ConsoleColor.RESET);\n\t\tgetLogger().warning(ConsoleColor.RED + String.format(\"Your minecraft version (MC %1$s) is currently not compatible with this plugins version (%2$s). \" +\n\t\t\t\t                                                     \"Please check for updates!\", Bukkit.getServer().getVersion(), getDescription().getVersion()) + ConsoleColor.RESET);\n\t\tgetLogger().warning(ConsoleColor.RED + \"################################\" + ConsoleColor.RESET);\n\t\tUtils.blockThread(5);\n\t}\n\n\tpublic Config getConfiguration()\n\t{\n\t\treturn config;\n\t}\n\n\tpublic Language getLanguage()\n\t{\n\t\treturn lang;\n\t}\n\n\t@Override\n\tpublic void openBackpack(@NotNull final Player opener, @NotNull final OfflinePlayer owner, final boolean editable)\n\t{\n\t\topenBackpack(opener, owner, editable, null);\n\t}\n\n\t@Override\n\tpublic void openBackpack(@NotNull final Player opener, @Nullable final Backpack backpack, boolean editable)\n\t{\n\t\topenBackpack(opener, backpack, editable, null);\n\t}\n\n\t@Override\n\tpublic void openBackpack(@NotNull Player opener, @NotNull OfflinePlayer owner, boolean editable, @Nullable String title)\n\t{\n\t\tdatabase.getBackpack(owner, backpack -> openBackpack(opener, backpack, editable, title));\n\t}\n\n\t@Override\n\tpublic void openBackpack(@NotNull Player opener, @Nullable Backpack backpack, boolean editable, @Nullable String title)\n\t{\n\t\tWorldBlacklistMode disabled = isDisabled(opener);\n\t\tif(disabled != WorldBlacklistMode.None)\n\t\t{\n\t\t\tif (disabled == WorldBlacklistMode.Message) messageWorldDisabled.send(opener);\n\t\t\telse if (disabled == WorldBlacklistMode.MissingPermission) messageNoPermission.send(opener);\n\t\t\treturn;\n\t\t}\n\t\tif(backpack == null)\n\t\t{\n\t\t\tmessageInvalidBackpack.send(opener);\n\t\t\treturn;\n\t\t}\n\t\t//noinspection ObjectEquality\n\t\tif(InventoryUtils.getPlayerTopInventory(opener).getHolder() == backpack) return; // == is fine as there is only one instance of each backpack\n\t\tif(openSound != null)\n\t\t{\n\t\t\topener.playSound(opener.getLocation(), openSound, 1, 0);\n\t\t}\n\t\tbackpack.open(opener, editable);\n\t}\n\n\t@Override\n\tpublic @Nullable Backpack getBackpackCachedOnly(@NotNull OfflinePlayer owner)\n\t{\n\t\treturn database.getBackpack(owner);\n\t}\n\n\t@Override\n\tpublic void getBackpack(@NotNull OfflinePlayer owner, @NotNull Callback<Backpack> callback)\n\t{\n\t\tdatabase.getBackpack(owner, callback);\n\t}\n\n\t@Override\n\tpublic void getBackpack(@NotNull final OfflinePlayer owner, @NotNull final Callback<Backpack> callback, boolean createNewIfNotExists)\n\t{\n\t\tdatabase.getBackpack(owner, callback, createNewIfNotExists);\n\t}\n\n\t@Override\n\tpublic MinepacksCommandManager getCommandManager()\n\t{\n\t\t/*if[STANDALONE]\n\t\treturn null;\n\t\telse[STANDALONE]*/\n\t\treturn commandManager;\n\t\t/*end[STANDALONE]*/\n\t}\n\n\tpublic int getBackpackPermSize(Player player)\n\t{\n\t\tfor(int i = maxSize; i > 1; i--)\n\t\t{\n\t\t\tif(player.hasPermission(\"backpack.size.\" + i)) return i * 9;\n\t\t}\n\t\treturn 9;\n\t}\n\n\t@Override\n\tpublic @NotNull WorldBlacklistMode isDisabled(final @NotNull Player player)\n\t{\n\t\tif(worldBlacklistMode == WorldBlacklistMode.None || (worldBlacklistMode != WorldBlacklistMode.NoPlugin && player.hasPermission(Permissions.IGNORE_WORLD_BLACKLIST))) return WorldBlacklistMode.None;\n\t\tif(worldBlacklist.contains(player.getWorld().getName().toLowerCase(Locale.ROOT))) return worldBlacklistMode;\n\t\treturn WorldBlacklistMode.None;\n\t}\n\n\t@Override\n\tpublic boolean isPlayerGameModeAllowed(final @NotNull Player player)\n\t{\n\t\treturn gameModes.contains(player.getGameMode()) || player.hasPermission(Permissions.IGNORE_GAME_MODE);\n\t}\n\n\tpublic @Nullable CooldownManager getCooldownManager()\n\t{\n\t\treturn cooldownManager;\n\t}\n\n\t@Override\n\tpublic @Nullable ItemFilter getItemFilter()\n\t{\n\t\treturn itemFilter;\n\t}\n\n\t@Override\n\tpublic boolean isBackpackItem(final @Nullable ItemStack itemStack)\n\t{\n\t\tif(shortcut == null) return false;\n\t\treturn shortcut.isItemShortcut(itemStack);\n\t}\n\n\tpublic ItemsCollector getItemsCollector()\n\t{\n\t\treturn collector;\n\t}\n\n\tpublic static PlatformScheduler getScheduler()\n\t{\n\t\treturn foliaLib.getScheduler();\n\t}\n\n\t@Override\n\tpublic @NotNull Version getVersion()\n\t{\n\t\treturn new Version(getDescription().getVersion());\n\t}\n}\n"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Permissions.java",
    "content": "/*\n *   Copyright (C) 2020 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit;\n\nimport lombok.SneakyThrows;\n\nimport java.lang.reflect.Field;\nimport java.lang.reflect.Modifier;\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class Permissions\n{\n\tpublic static final String BASE = \"backpack.\";\n\tpublic static final String USE = BASE + \"use\";\n\tpublic static final String SORT = BASE + \"sort\";\n\tpublic static final String CLEAN = BASE + \"clean\";\n\tpublic static final String CLEAN_OTHER = BASE + \"clean.other\";\n\tpublic static final String FULL_PICKUP = BASE + \"fullpickup\";\n\tpublic static final String PICKUP_TOGGLE = BASE + \"fullpickup.toggle\";\n\tpublic static final String OTHERS = BASE + \"others\";\n\tpublic static final String OTHERS_EDIT = BASE + \"others.edit\";\n\tpublic static final String KEEP_ON_DEATH = BASE + \"keepOnDeath\";\n\tpublic static final String NO_COOLDOWN = BASE + \"noCooldown\";\n\tpublic static final String IGNORE_GAME_MODE = BASE + \"ignoreGameMode\";\n\tpublic static final String IGNORE_WORLD_BLACKLIST = BASE + \"ignoreWorldBlacklist\";\n\tpublic static final String UPDATE = BASE + \"update\";\n\tpublic static final String RELOAD = BASE + \"reload\";\n\tpublic static final String MIGRATE = BASE + \"migrate\";\n\tpublic static final String BACKUP = BASE + \"backup\";\n\tpublic static final String RESTORE = BASE + \"restore\";\n\tpublic static final String VERSION = BASE + \"version\";\n\n\tpublic static final String INVENTORY_CLEAR = \"clearInventory\";\n\tpublic static final String INVENTORY_CLEAR_OTHER = \"clearInventory.other\";\n\n\t@SneakyThrows\n\tpublic static List<String> getPermissions()\n\t{\n\t\tField[] fields = Permissions.class.getDeclaredFields();\n\t\tList<String> permissions = new ArrayList<>(fields.length);\n\t\tfor(Field field : fields)\n\t\t{\n\t\t\tif (field.getType().equals(String.class) && Modifier.isStatic(field.getModifiers()))\n\t\t\t{\n\t\t\t\tString val = ((String) field.get(null));\n\t\t\t\tif (!val.endsWith(\".\"))\n\t\t\t\t{\n\t\t\t\t\tpermissions.add(val);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor (int i = 1; i < 10; i++)\n\t\t{\n\t\t\tpermissions.add(\"backpack.size.\" + i);\n\t\t}\n\t\treturn permissions;\n\t}\n\n\tprivate Permissions() {}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Placeholder/PlaceholderManager.java",
    "content": "/*\n *   Copyright (C) 2023 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Placeholder;\n\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Placeholder.Replacer.AutoPickupEnabled;\n\npublic final class PlaceholderManager extends at.pcgamingfreaks.Bukkit.Placeholder.PlaceholderManager\n{\n\tpublic PlaceholderManager(Minepacks plugin)\n\t{\n\t\tsuper(plugin);\n\t}\n\n\t@Override\n\tprotected void generatePlaceholdersMap()\n\t{\n\t\tMinepacks plugin = (Minepacks) getPlugin();\n\t\tregisterPlaceholder(new AutoPickupEnabled(plugin));\n\t}\n}\n"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Placeholder/Replacer/AutoPickupEnabled.java",
    "content": "/*\n *   Copyright (C) 2023 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.Placeholder.Replacer;\n\nimport at.pcgamingfreaks.Bukkit.Placeholder.PlaceholderName;\nimport at.pcgamingfreaks.Bukkit.Placeholder.PlaceholderReplacerBase;\nimport at.pcgamingfreaks.Minepacks.Bukkit.ItemsCollector;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\n\nimport org.bukkit.OfflinePlayer;\nimport org.bukkit.entity.Player;\nimport org.jetbrains.annotations.Nullable;\n\n@PlaceholderName(aliases = \"IsAutoPickupEnabled\")\npublic class AutoPickupEnabled extends PlaceholderReplacerBase\n{\n\tprivate final Minepacks plugin;\n\n\tpublic AutoPickupEnabled(Minepacks mp)\n\t{\n\t\tthis.plugin = mp;\n\t}\n\n\t@Override\n\tpublic @Nullable String replace(OfflinePlayer player)\n\t{\n\t\tItemsCollector collector = plugin.getItemsCollector();\n\t\tif (collector != null)\n\t\t{\n\t\t\tif (player instanceof Player)\n\t\t\t{\n\t\t\t\treturn collector.canUseAutoPickup((Player) player) ? \"true\" : \"false\";\n\t\t\t}\n\t\t\treturn \"offline\";\n\t\t}\n\t\treturn \"disabled\";\n\t}\n}\n"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Placeholders.java",
    "content": "/*\n *   Copyright (C) 2022 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit;\n\nimport at.pcgamingfreaks.Bukkit.Message.Placeholder.Processors.PlayerDisplayNamePlaceholderProcessor;\nimport at.pcgamingfreaks.Bukkit.Message.Placeholder.Processors.PlayerNamePlaceholderProcessor;\nimport at.pcgamingfreaks.Message.Placeholder.Placeholder;\n\nimport org.jetbrains.annotations.NotNull;\n\npublic class Placeholders\n{\n\tprivate Placeholders(){}\n\n\tpublic static final @NotNull String[] PAGE_OPTIONS = { \"CurrentPage\", \"MaxPage\", \"MainCommand\", \"SubCommand\", \"PrevPage\", \"NextPage\" };\n\tpublic static final @NotNull Placeholder[] PLAYER_NAME = mkPlayerName(\"\");\n\n\tpublic static @NotNull Placeholder[] mkPlayerName(final @NotNull String prefix)\n\t{\n\t\treturn mkPlayerName(prefix, \"\", false);\n\t}\n\n\tpublic static @NotNull Placeholder[] mkPlayerName(final @NotNull String prefix, final @NotNull String suffix)\n\t{\n\t\treturn mkPlayerName(prefix, suffix, false);\n\t}\n\n\tpublic static @NotNull Placeholder[] mkPlayerName(final @NotNull String prefix, final @NotNull String suffix, final boolean regex)\n\t{\n\t\treturn new Placeholder[]{\n\t\t\t\tnew Placeholder(prefix + \"Name\" + suffix, PlayerNamePlaceholderProcessor.INSTANCE, regex),\n\t\t\t\tnew Placeholder(prefix + \"DisplayName\" + suffix, PlayerDisplayNamePlaceholderProcessor.INSTANCE, regex)\n\t\t};\n\t}\n\n\tpublic static @NotNull Placeholder[] mkPlayerNameRegex(final @NotNull String prefix)\n\t{\n\t\treturn mkPlayerName(prefix, \"\", true);\n\t}\n\n\tpublic static @NotNull Placeholder[] mkPlayerNameRegex(final @NotNull String prefix, final @NotNull String suffix)\n\t{\n\t\treturn mkPlayerName(prefix, suffix, true);\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/ShrinkApproach.java",
    "content": "/*\n *   Copyright (C) 2020 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit;\n\npublic enum ShrinkApproach\n{\n\tFAST,\n\tCOMPRESS,\n\tSORT;\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/SpecialInfoWorker/NoDatabaseWorker.java",
    "content": "/*\n *   Copyright (C) 2020 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.SpecialInfoWorker;\n\nimport at.pcgamingfreaks.Bukkit.Command.RegisterablePluginCommand;\nimport at.pcgamingfreaks.Bukkit.Message.Message;\nimport at.pcgamingfreaks.Bukkit.Message.MessageBuilder;\nimport at.pcgamingfreaks.Message.MessageColor;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\nimport at.pcgamingfreaks.Minepacks.Bukkit.Permissions;\nimport at.pcgamingfreaks.Reflection;\nimport org.bukkit.Bukkit;\nimport org.bukkit.command.Command;\nimport org.bukkit.command.CommandExecutor;\nimport org.bukkit.command.CommandSender;\nimport org.bukkit.entity.Player;\nimport org.bukkit.event.HandlerList;\nimport org.jetbrains.annotations.NotNull;\n\n/**\n * This worker will inform the admin that the plugin failed to connect to the database, he hopefully is able to solve the problem.\n * It registers a new command that only allows to reload the plugin to prevent unnecessary downtime for the server cause of restarts.\n */\npublic class NoDatabaseWorker extends SpecialInfoBase implements CommandExecutor\n{\n\tprivate final Minepacks plugin;\n\tprivate final RegisterablePluginCommand command;\n\tprivate final Message messageDBProblem;\n\n\tpublic NoDatabaseWorker(final @NotNull Minepacks plugin)\n\t{\n\t\tsuper(plugin, Permissions.RELOAD);\n\t\tthis.plugin = plugin;\n\t\tBukkit.getPluginManager().registerEvents(this, plugin);\n\t\tcommand = new RegisterablePluginCommand(plugin, \"backpack\");\n\t\tcommand.registerCommand();\n\t\tcommand.setExecutor(this);\n\t\tmessageDBProblem = new MessageBuilder(\"Minepacks\", MessageColor.GOLD).append(\" failed to connect to its database!\", MessageColor.RED).appendNewLine()\n\t\t\t\t.append(\"Please check your configuration and reload the plugin (\", MessageColor.RED).append(\"/backpack reload\", MessageColor.BLUE).command(\"/backpack reload\").append(\")!\", MessageColor.RED).getMessage();\n\t}\n\n\t@Override\n\tprotected void sendMessage(Player player)\n\t{\n\t\tmessageDBProblem.send(player);\n\t}\n\n\t@Override\n\tpublic boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command cmd, @NotNull String s, String[] strings)\n\t{\n\t\tif(strings.length != 1 || !strings[0].equalsIgnoreCase(\"reload\"))\n\t\t{\n\t\t\tcommandSender.sendMessage(MessageColor.RED + \"Only \\\"/backpack reload\\\" is available at the moment!\");\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif(commandSender.hasPermission(Permissions.RELOAD))\n\t\t\t{\n\t\t\t\tcommand.unregisterCommand();\n\t\t\t\tHandlerList.unregisterAll(this);\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tplugin.getConfiguration().reload();\n\t\t\t\t\tReflection.getMethod(plugin.getClass(), \"load\").invoke(plugin);\n\t\t\t\t}\n\t\t\t\tcatch(Exception e)\n\t\t\t\t{\n\t\t\t\t\te.printStackTrace();\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tcommandSender.sendMessage(MessageColor.RED + \"You don't have the permission to do that!\");\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n}"
  },
  {
    "path": "Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/SpecialInfoWorker/SpecialInfoBase.java",
    "content": "/*\n *   Copyright (C) 2025 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.SpecialInfoWorker;\n\nimport at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;\n\nimport org.bukkit.entity.Player;\nimport org.bukkit.event.EventHandler;\nimport org.bukkit.event.Listener;\nimport org.bukkit.event.player.PlayerJoinEvent;\nimport org.bukkit.plugin.java.JavaPlugin;\n\npublic abstract class SpecialInfoBase implements Listener\n{\n\tprivate final JavaPlugin plugin;\n\tprivate final String permission;\n\n\tprotected SpecialInfoBase(final JavaPlugin plugin, final String permission)\n\t{\n\t\tthis.plugin = plugin;\n\t\tthis.permission = permission;\n\t}\n\n\t@EventHandler\n\tpublic void onJoin(final PlayerJoinEvent event)\n\t{\n\t\tif(event.getPlayer().hasPermission(permission))\n\t\t{\n\t\t\tMinepacks.getScheduler().runLater(() ->\n\t\t\t\tMinepacks.getScheduler().runAtEntity(event.getPlayer(), task -> {\n\t\t\t\t\tif(event.getPlayer().isOnline())\n\t\t\t\t\t{\n\t\t\t\t\t\tsendMessage(event.getPlayer());\n\t\t\t\t\t}\n\t\t\t\t}), 3 * 20L); // Run with a 3 seconds delay\n\t\t}\n\t}\n\n\tprotected abstract void sendMessage(final Player player);\n}"
  },
  {
    "path": "Minepacks/test/src/at/pcgamingfreaks/Minepacks/Bukkit/PermissionsTest.java",
    "content": "/*\n *   Copyright (C) 2020 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit;\n\nimport at.pcgamingfreaks.yaml.YAML;\nimport at.pcgamingfreaks.yaml.YamlInvalidContentException;\nimport at.pcgamingfreaks.yaml.YamlKeyNotFoundException;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.Test;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.lang.reflect.Field;\nimport java.util.Collection;\nimport java.util.HashSet;\n\nimport static org.junit.jupiter.api.Assertions.assertTrue;\n\npublic class PermissionsTest\n{\n\tprivate static Collection<String> permissions;\n\n\t@BeforeAll\n\tpublic static void setup() throws IllegalAccessException\n\t{ // Collect all permissions defined in the Permissions class\n\t\tpermissions = new HashSet<>();\n\t\tfor(Field declaredField : Permissions.class.getDeclaredFields())\n\t\t{\n\t\t\tif(declaredField.getName().equals(\"BASE\") || declaredField.getName().equals(\"SIZE_BASE\")) continue;\n\t\t\tpermissions.add((String) declaredField.get(null));\n\t\t}\n\t}\n\n\tprivate int countKeysStartingWith(Collection<String> keys, String startsWith)\n\t{\n\t\tint count = 0;\n\t\tfor(String key : keys)\n\t\t{\n\t\t\tif(key.startsWith(startsWith)) count++;\n\t\t}\n\t\treturn count;\n\t}\n\n\t@Test\n\tpublic void testPermissionsInPluginYaml() throws IOException, YamlInvalidContentException, YamlKeyNotFoundException\n\t{\n\t\tYAML pluginYaml = new YAML(new File(\"resources/plugin.yml\"));\n\t\tYAML permissionsYaml = pluginYaml.getSection(\"permissions\");\n\t\t// Check if all permissions are defined in the plugin.yml\n\t\tfor(String permission : permissions)\n\t\t{\n\t\t\tassertTrue(permissionsYaml.isSet(permission + \".description\"), \"The plugin.yml should contain the permission \" + permission);\n\t\t}\n\t\t// Check if all the permissions defined in the plugin.yml are also defined in the Permissions class\n\t\tCollection<String> keys = permissionsYaml.getKeys(true);\n\t\tfor(String key : keys)\n\t\t{\n\t\t\tif(!key.endsWith(\"description\")) continue;\n\t\t\tString perm = key.substring(0, key.length() - 12);\n\t\t\tif(perm.contains(\".size.\")) continue; // Ignore size permissions\n\t\t\tif(countKeysStartingWith(keys, perm + \".children\") > 1) continue; // Skip all the permissions that are just for permission grouping\n\t\t\tassertTrue(permissions.contains(perm), \"The plugin.yml should not contain the permission \" + perm);\n\t\t}\n\t}\n}"
  },
  {
    "path": "Minepacks-API/README.md",
    "content": "<!-- Variables (this block will not be visible in the readme -->\n[banner]: https://pcgamingfreaks.at/images/minepacks.png\n[spigot]: https://www.spigotmc.org/resources/minepacks.19286/\n[license]: https://github.com/GeorgH93/Minepacks/blob/master/LICENSE\n[licenseImg]: https://img.shields.io/github/license/GeorgH93/Minepacks.svg\n[ci]: https://ci.pcgamingfreaks.at/job/Minepacks%20API/\n[ciImg]: https://ci.pcgamingfreaks.at/job/Minepacks%20API/badge/icon\n[apiVersionImg]: https://img.shields.io/badge/dynamic/xml.svg?label=api-version&query=%2F%2Frelease[1]&url=https%3A%2F%2Frepo.pcgamingfreaks.at%2Frepository%2Fmaven-releases%2Fat%2Fpcgamingfreaks%2FMinepacks-API%2Fmaven-metadata.xml\n[apiJavaDoc]: https://ci.pcgamingfreaks.at/job/Minepacks%20API/javadoc/\n[apiBuilds]: https://ci.pcgamingfreaks.at/job/Minepacks%20API/\n<!-- End of variables block -->\n\n[![Logo][banner]][spigot]\n\nThis branch holds the API for the Minepacks plugin.\n\n[![ciImg]][ci] [![apiVersionImg]][apiJavaDoc] [![licenseImg]][license]\n\n## Adding it to your plugin:\n### Maven:\nThe API is available through maven.\n#### Repository:\n```\n<repository>\n\t<id>pcgf-repo</id>\n\t<url>https://repo.pcgamingfreaks.at/repository/maven-everything</url>\n</repository>\n```\n#### Dependency:\n```\n<!-- Minepacks API -->\n<dependency>\n    <groupId>at.pcgamingfreaks</groupId>\n    <artifactId>Minepacks-API</artifactId>\n    <version>2.2</version><!-- Check api-version shield for newest version -->\n</dependency>\n```\n\n### Build from source:\n```\ngit clone https://github.com/GeorgH93/Minepacks.git\ncd Minepacks\nmvn -pl Minepacks-API\n```\n\n## Usage:\n### Get access to the API:\n```java\npublic static MinepacksPlugin getMinepacks() {\n    Plugin bukkitPlugin = Bukkit.getPluginManager().getPlugin(\"Minepacks\");\n    if(!(bukkitPlugin instanceof MinepacksPlugin)) {\n    \t// Do something if Minepacks is not available\n        return null;\n    }\n    return (MinepacksPlugin) bukkitPlugin;\n}\n```\nYou can now use the returned `MinepacksPlugin` object to interact with the Minepacks plugin.\n\n### Access a players backpack inventory:\n```java\npublic static Inventory getPlayerBackpackInventory(Player player) {\n    Backpack bp = getMinepacks().getBackpackCachedOnly(player);\n    if(bp == null) return null; //Backpack not loaded (retry later)\n    return bp.getInventory();\n}\n```\nThis will return null if the backpack is not loaded or the inventory of the backpack if the backpack is already loaded.\n\n## Links:\n* [JavaDoc][apiJavaDoc]\n* [API Build Server][apiBuilds]\n"
  },
  {
    "path": "Minepacks-API/pom.xml",
    "content": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\t\t xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\t<artifactId>Minepacks-API</artifactId>\n\t<parent>\n\t\t<artifactId>Minepacks-Parent</artifactId>\n\t\t<groupId>at.pcgamingfreaks</groupId>\n\t\t<version>${revision}</version>\n\t\t<relativePath>..</relativePath>\n\t</parent>\n\t<version>${revision}</version>\n\t<packaging>jar</packaging>\n\n\t<name>Minepacks-API</name>\n\t<description>API for the Bukkit/Spigot plugin Minepacks.</description>\n\n\t<dependencies>\n\t\t<dependency>\n\t\t\t<groupId>at.pcgamingfreaks</groupId>\n\t\t\t<artifactId>PluginLib</artifactId>\n\t\t\t<version>${pcgfPluginLibVersion}</version>\n\t\t\t<scope>provided</scope>\n\t\t</dependency>\n\t</dependencies>\n\n\t<build>\n\t\t<defaultGoal>clean install</defaultGoal>\n\t\t<sourceDirectory>src</sourceDirectory>\n\t\t<plugins>\n\t\t\t<!-- Creates a jar with the sources (for maven repo) -->\n\t\t\t<plugin>\n\t\t\t\t<groupId>org.apache.maven.plugins</groupId>\n\t\t\t\t<artifactId>maven-source-plugin</artifactId>\n\t\t\t\t<version>2.2.1</version>\n\t\t\t\t<executions>\n\t\t\t\t\t<execution>\n\t\t\t\t\t\t<id>attach-sources</id>\n\t\t\t\t\t\t<goals>\n\t\t\t\t\t\t\t<goal>jar</goal>\n\t\t\t\t\t\t</goals>\n\t\t\t\t\t</execution>\n\t\t\t\t</executions>\n\t\t\t</plugin>\n\t\t\t<!-- Creates a jar with the javadoc (for maven repo) -->\n\t\t\t<plugin>\n\t\t\t\t<groupId>org.apache.maven.plugins</groupId>\n\t\t\t\t<artifactId>maven-javadoc-plugin</artifactId>\n\t\t\t\t<version>3.1.1</version>\n\t\t\t\t<executions>\n\t\t\t\t\t<execution>\n\t\t\t\t\t\t<id>attach-javadocs</id>\n\t\t\t\t\t\t<goals>\n\t\t\t\t\t\t\t<goal>jar</goal>\n\t\t\t\t\t\t</goals>\n\t\t\t\t\t\t<configuration>\n\t\t\t\t\t\t\t<additionalparam>-Xdoclint:none</additionalparam>\n\t\t\t\t\t\t\t<source>8</source>\n\t\t\t\t\t\t</configuration>\n\t\t\t\t\t</execution>\n\t\t\t\t</executions>\n\t\t\t</plugin>\n\t\t</plugins>\n\t</build>\n</project>"
  },
  {
    "path": "Minepacks-API/src/at/pcgamingfreaks/Minepacks/Bukkit/API/Backpack.java",
    "content": "/*\n *   Copyright (C) 2020 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.API;\n\nimport org.bukkit.Location;\nimport org.bukkit.OfflinePlayer;\nimport org.bukkit.entity.Player;\nimport org.bukkit.inventory.Inventory;\nimport org.bukkit.inventory.InventoryHolder;\nimport org.bukkit.inventory.ItemStack;\nimport org.jetbrains.annotations.NotNull;\nimport org.jetbrains.annotations.Nullable;\n\nimport java.util.Map;\nimport java.util.UUID;\n\n@SuppressWarnings(\"unused\")\npublic interface Backpack extends InventoryHolder\n{\n\t/**\n\t * Gets the owner of the backpack.\n\t *\n\t * @return The owner of the backpack;\n\t * @deprecated Use the {@link Backpack#getOwnerId()} function instead.\n\t */\n\t@Deprecated\n\t@NotNull OfflinePlayer getOwner();\n\n\t/**\n\t * Gets the id of the player owning the backpack.\n\t *\n\t * @return The uuid of the owning player.\n\t */\n\tUUID getOwnerId();\n\n\t@Nullable Player getOwnerPlayer();\n\n\t/**\n\t * Let a given player open this backpack.\n\t *\n\t * @param player   The player who opens the backpack.\n\t * @param editable Defines if the player who has opened the backpack can change the items inside.\n\t */\n\tvoid open(@NotNull Player player, boolean editable);\n\n\t/**\n\t * Let a given player open this backpack.\n\t *\n\t * @param player   The player who opens the backpack.\n\t * @param editable Defines if the player who has opened the backpack can change the items inside.\n\t * @param title    Custom title for the backpack (will be shown to the player who opened the backpack.\n\t */\n\tvoid open(@NotNull Player player, boolean editable, @Nullable String title);\n\n\t/**\n\t * Checks if the backpack is currently opened by a player.\n\t *\n\t * @return True if the backpack is open, false if not.\n\t */\n\tboolean isOpen();\n\n\t/**\n\t * Checks if a player can change the content of the backpack.\n\t *\n\t * @param player The player to be checked.\n\t * @return True if he can change the content, false if not.\n\t */\n\tboolean canEdit(@NotNull Player player);\n\n\t/**\n\t * Gets the size of the backpack.\n\t *\n\t * @return The size of the backpack.\n\t */\n\tint getSize();\n\n\t/**\n\t * Checks if the backpack has changed since it was last saved.\n\t *\n\t * @return True if it has been changed, false if not.\n\t */\n\tboolean hasChanged();\n\n\t/**\n\t * Marks that the content of the backpack a changed. It will be saved when the next player closes the backpack or before it gets removed from the cache.\n\t */\n\tvoid setChanged();\n\n\t/**\n\t * Forces the backpack to be saved\n\t */\n\tvoid save();\n\n\t/**\n\t * Removes all items from the backpack.\n\t */\n\tvoid clear();\n\n\t/**\n\t * Drops the content of the backpack to the ground on a given location.\n\t *\n\t * @param location The location the content of the backpack should be dropped to.\n\t */\n\tvoid drop(Location location);\n\n\t/**\n\t * @param stack The item stack that should be added to the backpack.\n\t * @return null if the entire item stack has been added. An item stack containing the items that did not fit into the backpack.\n\t */\n\tdefault @Nullable ItemStack addItem(ItemStack stack)\n\t{\n\t\tMap<Integer, ItemStack> left = addItems(stack);\n\t\tif(left.isEmpty()) return null;\n\t\treturn left.get(0);\n\t}\n\n\t/**\n\t * @param itemStacks The item that should be added to the backpack.\n\t * @return A HashMap containing items that didn't fit. The key is the number of the added item\n\t */\n\tdefault @NotNull Map<Integer, ItemStack> addItems(ItemStack... itemStacks)\n\t{\n\t\tsetChanged();\n\t\treturn getInventory().addItem(itemStacks);\n\t}\n\n\tstatic boolean isBackpack(@Nullable Inventory inventory)\n\t{\n\t\treturn inventory instanceof Backpack;\n\t}\n}"
  },
  {
    "path": "Minepacks-API/src/at/pcgamingfreaks/Minepacks/Bukkit/API/Callback.java",
    "content": "/*\n *   Copyright (C) 2019 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.API;\n\npublic interface Callback<T>\n{\n\tvoid onResult(T done);\n\n\tdefault void onFail() { /* In most cases this can be ignored since it will not happen with most db queries used */ }\n}"
  },
  {
    "path": "Minepacks-API/src/at/pcgamingfreaks/Minepacks/Bukkit/API/Events/BackpackDropOnDeathEvent.java",
    "content": "/*\n *   Copyright (C) 2022 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.API.Events;\n\nimport at.pcgamingfreaks.Minepacks.Bukkit.API.Backpack;\nimport lombok.Getter;\nimport lombok.Setter;\nimport org.bukkit.entity.Player;\nimport org.bukkit.event.Cancellable;\nimport org.bukkit.event.Event;\nimport org.bukkit.event.HandlerList;\nimport org.jetbrains.annotations.NotNull;\n\n/**\n * Event is triggered bevor the backpacks content is dropped to the ground!\n */\npublic class BackpackDropOnDeathEvent extends Event implements Cancellable\n{\n\t@Getter @Setter private boolean cancelled = false;\n\t@Getter private final Player owner;\n\t@Getter private final Backpack backpack;\n\n\tpublic BackpackDropOnDeathEvent(final @NotNull Player owner, final @NotNull Backpack backpack)\n\t{\n\t\tthis.owner = owner;\n\t\tthis.backpack = backpack;\n\t}\n\n\t// Bukkit handler stuff\n\tprivate static final HandlerList handlers = new HandlerList();\n\n\t@Override\n\tpublic @NotNull HandlerList getHandlers()\n\t{\n\t\treturn getHandlerList();\n\t}\n\n\tpublic static HandlerList getHandlerList()\n\t{\n\t\treturn handlers;\n\t}\n}"
  },
  {
    "path": "Minepacks-API/src/at/pcgamingfreaks/Minepacks/Bukkit/API/Events/InventoryClearEvent.java",
    "content": "/*\n *   Copyright (C) 2022 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.API.Events;\n\nimport lombok.Getter;\nimport lombok.RequiredArgsConstructor;\nimport lombok.Setter;\nimport org.bukkit.command.CommandSender;\nimport org.bukkit.entity.Player;\nimport org.bukkit.event.Cancellable;\nimport org.bukkit.event.Event;\nimport org.bukkit.event.HandlerList;\nimport org.jetbrains.annotations.NotNull;\n\n@RequiredArgsConstructor()\npublic class InventoryClearEvent extends Event implements Cancellable\n{\n\t@Getter @Setter private boolean cancelled = false;\n\n\t/**\n\t * The player whose inventory should be cleared.\n\t */\n\t@Getter private final Player player;\n\n\t/**\n\t * The command sender who has requested the inventory to be cleared.\n\t */\n\t@Getter private final CommandSender sender;\n\n\t// Bukkit handler stuff\n\tprivate static final HandlerList handlers = new HandlerList();\n\n\t@Override\n\tpublic @NotNull HandlerList getHandlers()\n\t{\n\t\treturn getHandlerList();\n\t}\n\n\tpublic static HandlerList getHandlerList()\n\t{\n\t\treturn handlers;\n\t}\n}"
  },
  {
    "path": "Minepacks-API/src/at/pcgamingfreaks/Minepacks/Bukkit/API/Events/InventoryClearedEvent.java",
    "content": "/*\n *   Copyright (C) 2022 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.API.Events;\n\nimport lombok.Getter;\nimport lombok.RequiredArgsConstructor;\nimport org.bukkit.command.CommandSender;\nimport org.bukkit.entity.Player;\nimport org.bukkit.event.Event;\nimport org.bukkit.event.HandlerList;\nimport org.jetbrains.annotations.NotNull;\n\n@RequiredArgsConstructor()\npublic class InventoryClearedEvent extends Event\n{\n\t/**\n\t * The player whose inventory has been cleared.\n\t */\n\t@Getter private final Player player;\n\n\t/**\n\t * The command sender who has requested the inventory to be cleared.\n\t */\n\t@Getter private final CommandSender sender;\n\n\t// Bukkit handler stuff\n\tprivate static final HandlerList handlers = new HandlerList();\n\n\t@Override\n\tpublic @NotNull HandlerList getHandlers()\n\t{\n\t\treturn getHandlerList();\n\t}\n\n\tpublic static HandlerList getHandlerList()\n\t{\n\t\treturn handlers;\n\t}\n}"
  },
  {
    "path": "Minepacks-API/src/at/pcgamingfreaks/Minepacks/Bukkit/API/ItemFilter.java",
    "content": "/*\n *   Copyright (C) 2019 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.API;\n\nimport org.bukkit.entity.Player;\nimport org.bukkit.inventory.ItemStack;\nimport org.jetbrains.annotations.Contract;\nimport org.jetbrains.annotations.NotNull;\nimport org.jetbrains.annotations.Nullable;\n\n@SuppressWarnings(\"unused\")\npublic interface ItemFilter\n{\n\t/**\n\t * @param item The item that should be checked.\n\t * @return True if the item is not allowed. False if the item is allowed.\n\t */\n\t@Contract(\"null->false\")\n\tboolean isItemBlocked(@Nullable ItemStack item);\n\n\t/**\n\t * @param player The player that should receive the message that the item is not allowed.\n\t * @param itemStack The item that is not allowed. Will be used for the name.\n\t */\n\tvoid sendNotAllowedMessage(@NotNull Player player, @NotNull ItemStack itemStack);\n\n\t/**\n\t * @param player The player that should receive the message if the item is not allowed.\n\t * @param itemStack The item that should be checked.\n\t * @return True if the item is not allowed. False if the item is allowed.\n\t */\n\tdefault boolean checkIsBlockedAndShowMessage(@NotNull Player player, @Nullable ItemStack itemStack)\n\t{\n\t\tif(isItemBlocked(itemStack))\n\t\t{\n\t\t\tsendNotAllowedMessage(player, itemStack);\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n}"
  },
  {
    "path": "Minepacks-API/src/at/pcgamingfreaks/Minepacks/Bukkit/API/MinepacksCommand.java",
    "content": "/*\n *   Copyright (C) 2024 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.API;\n\nimport at.pcgamingfreaks.Bukkit.Command.SubCommand;\nimport at.pcgamingfreaks.Bukkit.Message.Message;\nimport at.pcgamingfreaks.Command.HelpData;\n\nimport org.bukkit.ChatColor;\nimport org.bukkit.command.CommandSender;\nimport org.bukkit.entity.Player;\nimport org.bukkit.plugin.java.JavaPlugin;\nimport org.jetbrains.annotations.NotNull;\nimport org.jetbrains.annotations.Nullable;\n\nimport java.lang.reflect.Method;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.logging.Level;\n\n/**\n * Only available if the plugin is not running in standalone mode!\n */\npublic abstract class MinepacksCommand extends SubCommand\n{\n\t@SuppressWarnings(\"FieldMayBeFinal\")\n\tprivate static MinepacksPlugin minepacksPlugin = null; // Will be set by reflection\n\t@SuppressWarnings(\"FieldMayBeFinal\")\n\tprivate static Object minepacksCommandManager = null;\n\t@SuppressWarnings(\"FieldMayBeFinal\")\n\tprivate static Method showHelp = null; // Will be set by reflection\n\t@SuppressWarnings(\"FieldMayBeFinal\") // Will be overwritten by reflection\n\tprivate static Message messageNoPermission   = new Message(ChatColor.RED + \"You don't have the permission to do that.\");\n\t@SuppressWarnings(\"FieldMayBeFinal\") // Will be overwritten by reflection\n\tprivate static Message messageNotFromConsole = new Message(ChatColor.RED + \"This command can't be used from console!\");\n\tprotected final JavaPlugin plugin;\n\tprivate final boolean playerOnly;\n\n\t//region Constructors\n\t/**\n\t * Creates a new command instance.\n\t *\n\t * @param plugin      The plugin owning the command.\n\t * @param name        The command used.\n\t * @param description The description of the command.\n\t * @param aliases     List of aliases for that command.\n\t */\n\tprotected MinepacksCommand(@NotNull JavaPlugin plugin, @NotNull String name, @NotNull String description, @Nullable String... aliases)\n\t{\n\t\tthis(plugin, name, description, null, aliases);\n\t}\n\n\t/**\n\t * Creates a new command instance.\n\t *\n\t * @param plugin      The plugin owning the command.\n\t * @param name        The command used.\n\t * @param description The description of the command.\n\t * @param permission  The permission to be checked for this command. Players without the permission neither can use the command nor will they see it in help.\n\t * @param aliases     List of aliases for that command.\n\t */\n\tprotected MinepacksCommand(@NotNull JavaPlugin plugin, @NotNull String name, @NotNull String description, @Nullable String permission, @Nullable String... aliases)\n\t{\n\t\tthis(plugin, name, description, permission, false, aliases);\n\t}\n\n\t/**\n\t * Creates a new command instance.\n\t *\n\t * @param plugin      The plugin owning the command.\n\t * @param name        The command used.\n\t * @param description The description of the command.\n\t * @param permission  The permission to be checked for this command. Players without the permission neither can use the command nor will they see it in help.\n\t * @param playerOnly  Limits the command to players, console can't use and can't see the command.\n\t * @param aliases     List of aliases for that command.\n\t */\n\tprotected MinepacksCommand(@NotNull JavaPlugin plugin, @NotNull String name, @NotNull String description, @Nullable String permission, boolean playerOnly, @Nullable String... aliases)\n\t{\n\t\tsuper(name, description, permission, aliases);\n\t\tthis.plugin = plugin;\n\t\tthis.playerOnly = playerOnly;\n\t}\n\t//endregion\n\n\t/**\n\t * Gets the instance of the marriage master plugin.\n\t *\n\t * @return The instance of the marriage master plugin.\n\t */\n\tprotected @NotNull MinepacksPlugin getMinepacksPlugin()\n\t{\n\t\treturn minepacksPlugin;\n\t}\n\n\t//region Command Stuff\n\t/**\n\t * Executes some basic checks and runs the command afterwards.\n\t *\n\t * @param sender           Source of the command.\n\t * @param mainCommandAlias Alias of the plugins main command which was used.\n\t * @param alias            Alias of the command which has been used.\n\t * @param args             Passed command arguments.\n\t */\n\t@Override\n\tpublic void doExecute(@NotNull CommandSender sender, @NotNull String mainCommandAlias, @NotNull String alias, @NotNull String... args)\n\t{\n\t\tif(playerOnly && !(sender instanceof Player))\n\t\t{\n\t\t\tmessageNotFromConsole.send(sender);\n\t\t}\n\t\telse if(getPermission() != null && !sender.hasPermission(getPermission()))\n\t\t{\n\t\t\tmessageNoPermission.send(sender);\n\t\t}\n\t\telse\n\t\t{\n\t\t\texecute(sender, mainCommandAlias, alias, args);\n\t\t}\n\t}\n\n\t/**\n\t * Executes some basic checks and generates list for tab completion.\n\t *\n\t * @param sender           Source of the command.\n\t * @param mainCommandAlias Alias of the plugins main command which has been used.\n\t * @param alias            The alias used.\n\t * @param args             The arguments passed to the command, including final partial argument to be completed and command label.\n\t * @return A List of possible completions for the final argument, or null to default to the command executor.\n\t */\n\t@Override\n\tpublic List<String> doTabComplete(@NotNull CommandSender sender, @NotNull String mainCommandAlias, @NotNull String alias, @NotNull String... args)\n\t{\n\t\tif(playerOnly && !(sender instanceof Player))\n\t\t{\n\t\t\tmessageNotFromConsole.send(sender);\n\t\t}\n\t\telse if(getPermission() != null && !sender.hasPermission(getPermission()))\n\t\t{\n\t\t\tmessageNoPermission.send(sender);\n\t\t}\n\t\telse\n\t\t{\n\t\t\treturn tabComplete(sender, mainCommandAlias, alias, args);\n\t\t}\n\t\treturn null;\n\t}\n\n\t/**\n\t * Gets the help for a given {@link CommandSender}.\n\t *\n\t * @param requester The {@link CommandSender} that requested help.\n\t * @return All the help data for this command.\n\t */\n\t@Override\n\tpublic @Nullable List<HelpData> getHelp(@NotNull CommandSender requester)\n\t{\n\t\tList<HelpData> help = new ArrayList<>(1);\n\t\thelp.add(new HelpData(getTranslatedName(), null, getDescription()));\n\t\treturn help;\n\t}\n\n\t/**\n\t * Shows the help to a given command sender.\n\t *\n\t * @param sendTo               The command sender that requested help.\n\t * @param usedMainCommandAlias The used backpack alias to replace the /backpack with the used alias.\n\t */\n\t@Override\n\tpublic void showHelp(final @NotNull CommandSender sendTo, final @NotNull String usedMainCommandAlias)\n\t{\n\t\ttry\n\t\t{\n\t\t\tshowHelp.invoke(minepacksCommandManager, sendTo, usedMainCommandAlias, doGetHelp(sendTo));\n\t\t}\n\t\tcatch(Exception e)\n\t\t{\n\t\t\tplugin.getLogger().log(Level.SEVERE, e, () -> \"Failed to show help for command \" + usedMainCommandAlias);\n\t\t}\n\t}\n\n\t/**\n\t * Checks if a user can use the command. Checks permission, marriage status and player/console.\n\t *\n\t * @param sender The player/console that should be checked.\n\t * @return True if it can use the command, false if not.\n\t */\n\t@Override\n\tpublic boolean canUse(@NotNull CommandSender sender)\n\t{\n\t\treturn (!playerOnly || sender instanceof Player) && (getPermission() == null || sender.hasPermission(getPermission()));\n\t}\n\t//endregion\n}"
  },
  {
    "path": "Minepacks-API/src/at/pcgamingfreaks/Minepacks/Bukkit/API/MinepacksCommandManager.java",
    "content": "/*\n *   Copyright (C) 2019 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.API;\n\nimport org.jetbrains.annotations.NotNull;\n\n@SuppressWarnings(\"unused\")\npublic interface MinepacksCommandManager\n{\n\t/**\n\t * Registers a new sub-command for /backpack.\n\t * This function is only available if the plugin is not running in standalone mode!\n\t *\n\t * @param command The command that should be registered.\n\t */\n\tvoid registerSubCommand(@NotNull MinepacksCommand command);\n\n\t/**\n\t * Unregisters a sub-command for /backpack.\n\t * This function is only available if the plugin is not running in standalone mode!\n\t *\n\t * @param command The command that should be unregistered.\n\t */\n\tvoid unRegisterSubCommand(@NotNull MinepacksCommand command);\n}"
  },
  {
    "path": "Minepacks-API/src/at/pcgamingfreaks/Minepacks/Bukkit/API/MinepacksPlugin.java",
    "content": "/*\n *   Copyright (C) 2020 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.API;\n\nimport org.bukkit.Bukkit;\nimport org.bukkit.OfflinePlayer;\nimport org.bukkit.entity.Player;\nimport org.bukkit.inventory.ItemStack;\nimport org.bukkit.plugin.Plugin;\nimport org.jetbrains.annotations.NotNull;\nimport org.jetbrains.annotations.Nullable;\n\n@SuppressWarnings(\"unused\")\npublic interface MinepacksPlugin\n{\n\t/**\n\t * Gets the instance of the minepacks plugin.\n\t * WARNING use this function at your own risk! If the plugin is not installed the MinepacksPlugin class will be unknown!\n\t *\n\t * @return The instance of the minepacks plugin.\n\t */\n\tstatic @Nullable MinepacksPlugin getInstance()\n\t{\n\t\tPlugin plugin = Bukkit.getServer().getPluginManager().getPlugin(\"Minepacks\");\n\t\treturn (plugin instanceof MinepacksPlugin && plugin.isEnabled()) ? (MinepacksPlugin) plugin : null;\n\t}\n\n\t/**\n\t * Checks if the plugin is running in standalone mode. Some features and API functions are not available in standalone mode!\n\t *\n\t * @return True if the plugin is running in standalone mode.\n\t */\n\tboolean isRunningInStandaloneMode();\n\n\t/**\n\t * Let a given player open the backpack of an other player.\n\t *\n\t * @param opener   The player who opens the backpack.\n\t * @param owner    The owner of the backpack that should be opened.\n\t * @param editable Defines if the player who has opened the backpack can change the items inside.\n\t */\n\tvoid openBackpack(@NotNull final Player opener, @NotNull final OfflinePlayer owner, final boolean editable);\n\n\t/**\n\t * Let a given player open a given {@link Backpack}.\n\t *\n\t * @param opener   The player who opens the backpack.\n\t * @param backpack The backpack to be opened. null will result in an error message for the player.\n\t * @param editable Defines if the player who has opened the backpack can change the items inside.\n\t */\n\tvoid openBackpack(@NotNull final Player opener, @Nullable final Backpack backpack, boolean editable);\n\n\t/**\n\t * Let a given player open the backpack of an other player.\n\t *\n\t * @param opener   The player who opens the backpack.\n\t * @param owner    The owner of the backpack that should be opened.\n\t * @param editable Defines if the player who has opened the backpack can change the items inside.\n\t * @param title    Custom title for the backpack (will be shown to the player who opened the backpack.\n\t */\n\tvoid openBackpack(@NotNull final Player opener, @NotNull final OfflinePlayer owner, final boolean editable, @Nullable String title);\n\n\t/**\n\t * Let a given player open a given {@link Backpack}.\n\t *\n\t * @param opener   The player who opens the backpack.\n\t * @param backpack The backpack to be opened. null will result in an error message for the player.\n\t * @param editable Defines if the player who has opened the backpack can change the items inside.\n\t * @param title    Custom title for the backpack (will be shown to the player who opened the backpack.\n\t */\n\tvoid openBackpack(@NotNull final Player opener, @Nullable final Backpack backpack, boolean editable, @Nullable String title);\n\n\t/**\n\t * Retrieves the backpack for a given player.\n\t * This method only returns a backpack if it is in the cache.\n\t *\n\t * @param owner The player who's backpack should be retrieved.\n\t * @return The backpack of the given player. null if the backpack is in the cache.\n\t */\n\t@Nullable Backpack getBackpackCachedOnly(@NotNull final OfflinePlayer owner);\n\n\t/**\n\t * Retrieves the backpack for a given player.\n\t * This method runs async! The result will be delivered with a callback.\n\t * If no backpack exists a new one will be created.\n\t *\n\t * @param owner The player who's backpack should be retrieved.\n\t * @param callback The callback delivering the result of the request.\n\t */\n\tvoid getBackpack(@NotNull final OfflinePlayer owner, @NotNull final Callback<Backpack> callback);\n\n\t/**\n\t * Retrieves the backpack for a given player.\n\t * This method runs async! The result will be delivered with a callback.\n\t *\n\t * @param owner The player who's backpack should be retrieved.\n\t * @param callback The callback delivering the result of the request.\n\t * @param createNewIfNotExists If set to true, a new backpack will be created if there currently is no backpack for this player.\n\t */\n\tvoid getBackpack(@NotNull final OfflinePlayer owner, @NotNull final Callback<Backpack> callback, boolean createNewIfNotExists);\n\n\t/**\n\t * Gets the command manager of the Minepacks plugin.\n\t *\n\t * @return The command manager instance. null if the plugin is running in standalone mode\n\t */\n\t@Nullable MinepacksCommandManager getCommandManager();\n\n\t/**\n\t * Checks if the player is allowed to open a backpack based on is permissions and current game-mode.\n\t *\n\t * @param player The player to be checked.\n\t * @return True if the player can use a backpack. False if not.\n\t */\n\tboolean isPlayerGameModeAllowed(final @NotNull Player player);\n\n\t/**\n\t * Gets the item filter.\n\t *\n\t * @return The item filter. Null if item filter is disabled\n\t */\n\t@Nullable ItemFilter getItemFilter();\n\n\t/**\n\t * Checks if an item is a backpack shortcut item.\n\t *\n\t * @param itemStack item to check.\n\t * @return true if the item is a backpack shortcut item, false if not.\n\t */\n\tboolean isBackpackItem(final @Nullable ItemStack itemStack);\n\n\t/**\n\t * Checks if a player can use the backpack at its current location (or if the world is disabled in the config).\n\t * <b>Does not check if the player has the permission to use the backpack!!!</b>\n\t *\n\t * @param player The player that should be checked.\n\t * @return The configured reason why the player can not access at its current location. {@link WorldBlacklistMode#None} if the player can use the backpack.\n\t */\n\t@NotNull WorldBlacklistMode isDisabled(Player player);\n}"
  },
  {
    "path": "Minepacks-API/src/at/pcgamingfreaks/Minepacks/Bukkit/API/WorldBlacklistMode.java",
    "content": "/*\n *   Copyright (C) 2020 GeorgH93\n *\n *   This program is free software: you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation, either version 3 of the License, or\n *   (at your option) any later version.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\npackage at.pcgamingfreaks.Minepacks.Bukkit.API;\n\npublic enum WorldBlacklistMode\n{\n\tMessage, MissingPermission, NoPlugin, None\n}"
  },
  {
    "path": "README.md",
    "content": "<!-- Variables (this block will not be visible in the readme -->\n[banner]: https://pcgamingfreaks.at/images/minepacks.png\n[spigot]: https://www.spigotmc.org/resources/19286/\n[spigotRatingImg]: https://img.shields.io/badge/dynamic/json.svg?color=brightgreen&label=rating&query=%24.rating.average&suffix=%20%2F%205&url=https%3A%2F%2Fapi.spiget.org%2Fv2%2Fresources%2F19286\n[spigotDownloadsImg]: https://img.shields.io/badge/dynamic/json.svg?color=brightgreen&label=downloads%20%28spigotmc.org%29&query=%24.downloads&url=https%3A%2F%2Fapi.spiget.org%2Fv2%2Fresources%2F19286\n[bukkit]: https://dev.bukkit.org/projects/minepacks\n[bukkitDownloadsImg]: https://cf.way2muchnoise.eu/full_minepacks_downloads.svg\n[versionsImg]: https://cf.way2muchnoise.eu/versions/minepacks.svg\n[issues]: https://github.com/GeorgH93/Minepacks/issues\n[wiki]: https://github.com/GeorgH93/Minepacks/wiki\n[wikiFAQ]: https://github.com/GeorgH93/Minepacks/wiki/FAQ\n[wikiPermissions]: https://github.com/GeorgH93/Minepacks/wiki/Permissions\n[release]: https://github.com/GeorgH93/Minepacks/releases/latest\n[releaseImg]: https://img.shields.io/github/release/GeorgH93/Minepacks.svg?label=github%20release\n[license]: https://github.com/GeorgH93/Minepacks/blob/master/LICENSE\n[licenseImg]: https://img.shields.io/github/license/GeorgH93/Minepacks.svg\n[ci]: https://ci.pcgamingfreaks.at/job/Minepacks/\n[ciImg]: https://ci.pcgamingfreaks.at/job/Minepacks/badge/icon\n[ciDev]: https://ci.pcgamingfreaks.at/job/Minepacks%20Dev/\n[ciDevImg]: https://ci.pcgamingfreaks.at/job/Minepacks%20Dev/badge/icon\n[apiVersionImg]: https://img.shields.io/badge/dynamic/xml.svg?label=api-version&query=%2F%2Frelease[1]&url=https%3A%2F%2Frepo.pcgamingfreaks.at%2Frepository%2Fmaven-releases%2Fat%2Fpcgamingfreaks%2FMinepacks-API%2Fmaven-metadata.xml\n[api]: https://github.com/GeorgH93/Minepacks/tree/master/Minepacks-API\n[apiJavaDoc]: https://ci.pcgamingfreaks.at/job/Minepacks%20API/javadoc/\n[apiBuilds]: https://ci.pcgamingfreaks.at/job/Minepacks%20API/\n[bugReports]: https://github.com/GeorgH93/Minepacks/issues?q=is%3Aissue+is%3Aopen+label%3Abug\n[bugReportsImg]: https://img.shields.io/github/issues/GeorgH93/Minepacks/bug.svg?label=bug%20reports\n[reportBug]: https://github.com/GeorgH93/Minepacks/issues/new?labels=bug&template=bug.md\n[featureRequests]: https://github.com/GeorgH93/Minepacks/issues?q=is%3Aissue+is%3Aopen+label%3Aenhancement\n[featureRequestsImg]: https://img.shields.io/github/issues/GeorgH93/Minepacks/enhancement.svg?label=feature%20requests&color=informational\n[requestFeature]: https://github.com/GeorgH93/Minepacks/issues/new?labels=enhancement&template=feature.md\n[config]: https://github.com/GeorgH93/Minepacks/blob/master/Minepacks/resources/config.yml\n[pcgfPluginLib]: https://github.com/GeorgH93/PCGF_PluginLib\n[pcgfPluginLibAdvantages]: https://github.com/GeorgH93/Minepacks/wiki/Build-and-Mode-comparison#Advantages-of-using-the-PCGF-PluginLib\n[languages]: https://github.com/GeorgH93/Minepacks/tree/master/Minepacks/resources/lang\n<!-- End of variables block -->\n\n[![Logo][banner]][spigot]\n\nMinepacks is a free and reliable backpack plugin for minecraft server running bukkit or spigot.\n\n[![ciImg]][ci] [![releaseImg]][release]\n[![apiVersionImg]][api] [![licenseImg]][license] [![spigotRatingImg]][spigot]\n\n[![featureRequestsImg]][featureRequests] [![bugReportsImg]][bugReports]\n[![spigotDownloadsImg]][spigot] [![bukkitDownloadsImg]][bukkit]\n\n## Features:\n* [Configuration][config]\n* Backpack size controlled by [permissions][wikiPermissions]\n* Auto item-collect on full inventory (can be enabled in the config)\n* Multiple storage back-ends (Files, SQLite, MySQL)\n* Multi language support ([multiple language file included][languages])\n* Item filter (block items from being stored in the backpack)\n* Preserves the NBT data of items (everything that can be stored in a chest can be stored in the backpack)\n* Support for name changing / UUIDs\n* Auto-updater\n* [API][api] for developers\n\n## Requirements:\n### Runtime requirements:\n* Java 8\n* Bukkit, Spigot or Paper for Minecraft 1.8 or newer ![versionsImg]\n* (Optional) [PCGF PluginLib][pcgfPluginLib] ([Advantages of using the PCGF PluginLib][pcgfPluginLibAdvantages])\n\n### Build requirements:\n\n* JDK for Java 8\n* Maven 3\n* git\n\n## Build from source:\nThe plugin can be build in 3 different configurations.  \nAll the details about the different build configs and runtime modes can be found [here](https://github.com/GeorgH93/Minepacks/wiki/Build-and-Mode-comparison).\n\n### Normal version:\n```\ngit clone https://github.com/GeorgH93/Minepacks.git\ncd Minepacks\nmvn package\n```\nThe final file will be in the `Minepacks/target` folder, named `Minepacks-<CurrentVersion>.jar`.\n\n### Standalone version:\nThis version works without the PCGF-PluginLib, however some API features are not available.\n```\ngit clone https://github.com/GeorgH93/Minepacks.git\ncd Minepacks\nmvn package -P Standalone\n```\nThe final file will be in the `Minepacks/target` folder, named `Minepacks-<CurrentVersion>-Standalone.jar`.\n\n### Release version:\nThis is the version of the plugin published on dev.bukkit.org and spigotmc.org.\n```\ngit clone https://github.com/GeorgH93/Minepacks.git\ncd Minepacks\nmvn clean install -P Standalone\nmvn clean package -P Release\n```\nThe final file will be in the `Minepacks/target` folder, named `Minepacks-<CurrentVersion>-Release.jar`.\n\n## API:\nMinepacks V2 comes with an API that allows you to interact with this plugin.\nIf you think there is something missing in the API feel free to open a [feature request][requestFeature].\nPlease do not access data of the plugin in any other way than through the provided API, the inner workings will change and I won't keep track of what you are using in your plugin.\nFor more details about the API please check the following links:\n\n[Source Code & Details][api] ⚫ [JavaDoc][apiJavaDoc] ⚫ [Build Server][apiBuilds]\n\n## Support:\n* [Wiki][wiki]\n* [Issue tracker][issues]\n  * [new feature request][requestFeature]\n  * [new bug report][reportBug]\n* [Faq][wikiFAQ]\n\n## Links:\n* [Spigot][spigot] - [![spigotDownloadsImg]][spigot]\n* [CurseForge][bukkit] - [![bukkitDownloadsImg]][bukkit]\n* [Build Server - Release Builds ![ciImg]][ci]\n* [Build Server - Dev Builds ![ciDevImg]][ciDev]\n"
  },
  {
    "path": "pom.xml",
    "content": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\t\t xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\t<groupId>at.pcgamingfreaks</groupId>\n\t<artifactId>Minepacks-Parent</artifactId>\n\t<version>${revision}</version>\n\t<packaging>pom</packaging>\n\n\t<properties>\n\t\t<revision>2.5.7</revision>\n\t\t<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\n\t\t<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>\n\n\t\t<configFileVersion>35</configFileVersion>\n\t\t<languageFileVersion>21</languageFileVersion>\n\t\t<pcgfPluginLibVersion>1.0.40.7-SNAPSHOT</pcgfPluginLibVersion>\n\n\t\t<bukkitVersion>1.15.2-R0.1-SNAPSHOT</bukkitVersion>\n\t\t<mavenShade.version>3.6.2</mavenShade.version>\n\t\t<lombok.version>1.18.42</lombok.version>\n\n\t\t<author>GeorgH93</author>\n\t\t<maven.build.timestamp.format>yyyyMMddHHmmss</maven.build.timestamp.format>\n\t\t<timestamp>${maven.build.timestamp}</timestamp>\n\t\t<pluginVersion>${project.version}-T${timestamp}</pluginVersion>\n\n\t\t<sonar.organization>georgh93</sonar.organization>\n\t\t<sonar.host.url>https://sonarcloud.io</sonar.host.url>\n\t</properties>\n\n\t<scm>\n\t\t<connection>scm:git:git@github.com:GeorgH93/Minepacks.git</connection>\n\t\t<developerConnection>scm:git:git@github.com:GeorgH93/Minepacks.git</developerConnection>\n\t\t<url>git@github.com:GeorgH93/Minepacks.git</url>\n\t</scm>\n\t<issueManagement>\n\t\t<system>GitHub</system>\n\t\t<url>https://github.com/GeorgH93/Minepacks/issues</url>\n\t</issueManagement>\n\t<ciManagement>\n\t\t<system>jenkins</system>\n\t\t<url>https://ci.pcgamingfreaks.at/job/Minepacks/</url>\n\t</ciManagement>\n\n\t<name>Minepacks-Parent</name>\n\t<description>Minepacks is a backpack plugin with different backpack sizes, multi-language support and SQLite and MySQL storage support.</description>\n\t<url>https://www.spigotmc.org/resources/19286/</url>\n\t<inceptionYear>2014</inceptionYear>\n\t<licenses>\n\t\t<license>\n\t\t\t<name>GNU General Public License (GPL) v3</name>\n\t\t\t<url>https://www.gnu.org/licenses/gpl-3.0.txt</url>\n\t\t\t<distribution>repo</distribution>\n\t\t</license>\n\t</licenses>\n\n\t<repositories>\n\t\t<repository>\n\t\t\t<id>pcgf-repo</id>\n\t\t\t<url>https://repo.pcgamingfreaks.at/repository/maven-everything/</url>\n\t\t</repository>\n\t\t<repository>\n\t\t\t<id>spigot-nexus</id>\n\t\t\t<url>https://hub.spigotmc.org/nexus/content/groups/public/</url>\n\t\t</repository>\n\t</repositories>\n\n\t<dependencies>\n\t\t<dependency>\n\t\t\t<groupId>org.jetbrains</groupId>\n\t\t\t<artifactId>annotations</artifactId>\n\t\t\t<version>23.1.0</version>\n\t\t</dependency>\n\t\t<!-- Bukkit -->\n\t\t<dependency>\n\t\t\t<groupId>org.bukkit</groupId>\n\t\t\t<artifactId>bukkit</artifactId>\n\t\t\t<version>${bukkitVersion}</version>\n\t\t\t<scope>provided</scope>\n\t\t</dependency>\n\t\t<!-- Lombok -->\n\t\t<dependency>\n\t\t\t<groupId>org.projectlombok</groupId>\n\t\t\t<artifactId>lombok</artifactId>\n\t\t\t<version>${lombok.version}</version>\n\t\t\t<scope>provided</scope>\n\t\t</dependency>\n\t</dependencies>\n\n\t<build>\n\t\t<defaultGoal>clean package</defaultGoal>\n\t\t<sourceDirectory>src</sourceDirectory>\n\t\t<plugins>\n\t\t\t<plugin>\n\t\t\t\t<artifactId>maven-compiler-plugin</artifactId>\n\t\t\t\t<version>3.8.1</version>\n\t\t\t\t<configuration>\n\t\t\t\t\t<source>1.8</source>\n\t\t\t\t\t<target>1.8</target>\n\t\t\t\t\t<encoding>UTF-8</encoding>\n\t\t\t\t\t<annotationProcessorPaths>\n\t\t\t\t\t\t<path>\n\t\t\t\t\t\t\t<groupId>org.projectlombok</groupId>\n\t\t\t\t\t\t\t<artifactId>lombok</artifactId>\n\t\t\t\t\t\t\t<version>${lombok.version}</version>\n\t\t\t\t\t\t</path>\n\t\t\t\t\t</annotationProcessorPaths>\n\t\t\t\t</configuration>\n\t\t\t</plugin>\n\t\t\t<!-- Resolve lombok -->\n\t\t\t<plugin>\n\t\t\t\t<groupId>org.projectlombok</groupId>\n\t\t\t\t<artifactId>lombok-maven-plugin</artifactId>\n\t\t\t\t<version>1.18.10.0</version>\n\t\t\t\t<executions>\n\t\t\t\t\t<execution>\n\t\t\t\t\t\t<phase>generate-sources</phase>\n\t\t\t\t\t\t<goals>\n\t\t\t\t\t\t\t<goal>delombok</goal>\n\t\t\t\t\t\t</goals>\n\t\t\t\t\t</execution>\n\t\t\t\t</executions>\n\t\t\t</plugin>\n\t\t\t<!-- Flatten pom for deployment -->\n\t\t\t<plugin>\n\t\t\t\t<groupId>org.codehaus.mojo</groupId>\n\t\t\t\t<artifactId>flatten-maven-plugin</artifactId>\n\t\t\t\t<version>1.2.1</version>\n\t\t\t\t<configuration>\n\t\t\t\t\t<updatePomFile>true</updatePomFile>\n\t\t\t\t\t<pomElements>\n\t\t\t\t\t\t<description/>\n\t\t\t\t\t\t<inceptionYear/>\n\t\t\t\t\t\t<organization/>\n\t\t\t\t\t\t<scm/>\n\t\t\t\t\t\t<developers/>\n\t\t\t\t\t\t<contributors/>\n\t\t\t\t\t\t<mailingLists/>\n\t\t\t\t\t\t<issueManagement/>\n\t\t\t\t\t\t<repositories/>\n\t\t\t\t\t\t<ciManagement/>\n\t\t\t\t\t\t<!--<url/><pluginRepositories/><distributionManagement/>-->\n\t\t\t\t\t</pomElements>\n\t\t\t\t</configuration>\n\t\t\t\t<executions>\n\t\t\t\t\t<execution>\n\t\t\t\t\t\t<id>flatten</id>\n\t\t\t\t\t\t<phase>process-resources</phase>\n\t\t\t\t\t\t<goals>\n\t\t\t\t\t\t\t<goal>flatten</goal>\n\t\t\t\t\t\t</goals>\n\t\t\t\t\t</execution>\n\t\t\t\t\t<execution>\n\t\t\t\t\t\t<id>flatten.clean</id>\n\t\t\t\t\t\t<phase>clean</phase>\n\t\t\t\t\t\t<goals>\n\t\t\t\t\t\t\t<goal>clean</goal>\n\t\t\t\t\t\t</goals>\n\t\t\t\t\t</execution>\n\t\t\t\t</executions>\n\t\t\t</plugin>\n\t\t</plugins>\n\t</build>\n\n\t<modules>\n\t\t<module>Minepacks-API</module>\n\t\t<module>Components/Minepacks-MagicValues</module>\n\t\t<module>Minepacks</module>\n\t</modules>\n\n\t<profiles>\n\t\t<profile>\n\t\t\t<id>Release</id>\n\t\t\t<activation>\n\t\t\t\t<activeByDefault>false</activeByDefault>\n\t\t\t</activation>\n\n\t\t\t<modules>\n\t\t\t\t<module>Components/Minepacks-BadRabbit-Bukkit</module>\n\t\t\t\t<module>Components/Minepacks-Bootstrap-Paper</module>\n\t\t\t</modules>\n\t\t</profile>\n\t</profiles>\n\n\t<distributionManagement>\n\t\t<repository>\n\t\t\t<id>releases</id>\n\t\t\t<url>https://repo.pcgamingfreaks.at/repository/maven-releases/</url>\n\t\t</repository>\n\t\t<snapshotRepository>\n\t\t\t<id>snapshots</id>\n\t\t\t<url>https://repo.pcgamingfreaks.at/repository/maven-snapshots/</url>\n\t\t</snapshotRepository>\n\t</distributionManagement>\n</project>\n"
  }
]